From 4dde3cdd1e518b9c3c41b87fca77248851b51ba5 Mon Sep 17 00:00:00 2001 From: hopefully2333 <787016457@qq.com> Date: Thu, 11 Jan 2018 15:02:29 +0800 Subject: [PATCH 001/272] Rename sources/tech/20180106 Meltdown and Spectre Linux Kernel Status.md to translated/tech/20180106 Meltdown and Spectre Linux Kernel Status.md translated done --- .../tech/20180106 Meltdown and Spectre Linux Kernel Status.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename {sources => translated}/tech/20180106 Meltdown and Spectre Linux Kernel Status.md (100%) diff --git a/sources/tech/20180106 Meltdown and Spectre Linux Kernel Status.md b/translated/tech/20180106 Meltdown and Spectre Linux Kernel Status.md similarity index 100% rename from sources/tech/20180106 Meltdown and Spectre Linux Kernel Status.md rename to translated/tech/20180106 Meltdown and Spectre Linux Kernel Status.md From efd3675f821780bd16f7519c9ff0d4cd602aae79 Mon Sep 17 00:00:00 2001 From: Yinr Date: Mon, 15 Jan 2018 19:54:38 +0800 Subject: [PATCH 002/272] translated part 1 --- .../tech/20180111 Multimedia Apps for the Linux Console.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/sources/tech/20180111 Multimedia Apps for the Linux Console.md b/sources/tech/20180111 Multimedia Apps for the Linux Console.md index 6cdd3ef857..2df430f499 100644 --- a/sources/tech/20180111 Multimedia Apps for the Linux Console.md +++ b/sources/tech/20180111 Multimedia Apps for the Linux Console.md @@ -1,14 +1,18 @@ Translating by Yinr Multimedia Apps for the Linux Console +Linux 终端下的多媒体应用 ====== ![](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/multimedia.jpg?itok=v-XrnKRB) The Linux console supports multimedia, so you can enjoy music, movies, photos, and even read PDF files. +Linux 终端是支持多媒体的,所以你可以在终端听音乐,看电影,看图片,甚至是阅读 PDF。 When last we met, we learned that the Linux console supports multimedia. Yes, really! You can enjoy music, movies, photos, and even read PDF files without being in an X session with MPlayer, fbi, and fbgs. And, as a bonus, you can enjoy a Matrix-style screensaver for the console, CMatrix. +在我们上次见面时(?),我们了解到 Linux 终端可以支持多媒体。是的,这是真的!你可以使用 Mplayer、fbi 和 fbgs 来实现不打开 X 进程就听音乐、看电影、看照片,甚至阅读 PDF。此外,你还可以通过 CMatrix 来体验黑客帝国(Matrix)风格的屏幕保护。 You will probably have make some tweaks to your system to make this work. The examples used here are for Ubuntu Linux 16.04. +不过你可能需要对系统进行一些修改才能达到前面这些目的。以下的操作都是在 Ubuntu 16.04 上演示的。 ### MPlayer @@ -100,7 +104,7 @@ Learn more about Linux through the free ["Introduction to Linux" ][4]course from via: https://www.linux.com/learn/intro-to-linux/2018/1/multimedia-apps-linux-console 作者:[Carla Schroder][a] -译者:[译者ID](https://github.com/译者ID) +译者:[Yinr](https://github.com/Yinr) 校对:[校对者ID](https://github.com/校对者ID) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 From 2a38731d59fb9596f02bca6789497dfbeec8e9e0 Mon Sep 17 00:00:00 2001 From: Yinr Date: Fri, 26 Jan 2018 02:46:46 +0800 Subject: [PATCH 003/272] translated part 2 --- ...1 Multimedia Apps for the Linux Console.md | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/sources/tech/20180111 Multimedia Apps for the Linux Console.md b/sources/tech/20180111 Multimedia Apps for the Linux Console.md index 2df430f499..15dc5f2979 100644 --- a/sources/tech/20180111 Multimedia Apps for the Linux Console.md +++ b/sources/tech/20180111 Multimedia Apps for the Linux Console.md @@ -17,18 +17,25 @@ You will probably have make some tweaks to your system to make this work. The ex ### MPlayer You're probably familiar with the amazing and versatile MPlayer, which supports almost every video and audio format, and runs on nearly everything, including Linux, Android, Windows, Mac, Kindle, OS/2, and AmigaOS. Using MPLayer in your console will probably require some tweaking, depending on your Linux distribution. To start, try playing a video: +你可能会比较熟悉功能丰富的 MPlayer。它支持几乎所有的视频与音频格式,并且能在绝大部分现有平台上运行,像 Linux,Android,Windows,Mac,Kindle,OS/2 甚至是 AmigaOS。不过要在你的终端运行 MPlayer 可能需要多做一点工作,这些工作与你使用的 Linux 发行版有关。来,我们试着播放一个视频: + ``` -$ mplayer [video name] +$ mplayer [视频文件名] ``` If it works, then hurrah, and you can invest your time in learning useful MPlayer options, such as controlling the size of the video screen. However, some Linux distributions are managing the framebuffer differently than in the olden days, and you may have to adjust some settings to make it work. This is how to make it work on recent Ubuntu releases. +如果上面的命令正常执行了,那么很好,接下来你可以把时间放在了解 MPlayer 的常用选项上了,譬如设定视频大小等。但是,有些 Linux 发行版在对帧缓冲(framebuffer)的处理方式上可能会与早期的不同,那么你就需要进行一些设置才能让其正常工作了。下面是在最近的 Ubuntu 发行版上需要做的一些操作。 First, add yourself to the video group. +首先,将你添加到 video 用户组。 Second, verify that `/etc/modprobe.d/blacklist-framebuffer.conf` has this line: `#blacklist vesafb`. It should already be commented out, and if it isn't then comment it. All the other module lines should be un-commented, which prevents them from loading. Side note: if you want to dig more deeply into managing your framebuffer, the module for your video card may give better performance. +其次,确认 `/etc/modprobe.d/blacklist-framebuffer.conf` 文件中包含这样一行:`#blacklist vesafb`。这一行应该默认被注释掉了,如果不是的话,那就手动把它注释掉。此外的其他模块行需要确认没有被注释,这样设置才能保证那些模块不会被载入。注:如果你想要对控制帧缓冲(framebuffer)有更深入的了解,针对你的显卡的这些模块将给你提供更深入的认识。 Add these two modules to the end of `/etc/initramfs-tools/modules`, `vesafb` and `fbcon`, then rebuild the initramfs image: +在 `/etc/initramfs-tools/modules` 的结尾增加两个模块:`vesafb` 和 `fbcon`,然后更新 iniramfs 镜像: + ``` $ sudo nano /etc/initramfs-tools/modules # List of modules that you want to include in your initramfs. @@ -41,29 +48,39 @@ $ sudo update-initramfs -u ``` [fbcon][1] is the Linux framebuffer console. It runs on top of the framebuffer and adds graphical features. It requires a framebuffer device, which is supplied by the `vesafb` module. +[fbcon][1] 是 Linux 帧缓冲(framebuffer)终端,它运行在帧缓冲(framebuffer)之上并为其增加图形功能。[fbcon][1] 需要一个帧缓冲(framebuffer)设备,这则是由 `vesafb` 模块来提供的。 Now you must edit your GRUB2 configuration. In `/etc/default/grub` you should see a line like this: +接下来,你需要修改你的 GRUB2 配置。在 `/etc/default/grub` 中你将会看到类似下面的一行: + ``` GRUB_CMDLINE_LINUX_DEFAULT="quiet splash" ``` It may have some other options, but it should be there. Add `vga=789`: +它也可能还会有一些别的参数,不用管它,在其后加上 `vga=789`: + ``` GRUB_CMDLINE_LINUX_DEFAULT="quiet splash vga=789" ``` Reboot and enter your console (Ctrl+Alt+F1), and try playing a video. This command selects the `fbdev2` video device; I haven't learned yet how to know which one to use, but I had to use it to play the video. The default screen size is 320x240, so I scaled it to 960: +重启之后进入你的终端(Ctrl+Alt+F1)(LCTT 译注:在某些发行版中 Ctrl+Alt+F1 默认为图形界面,可以尝试 Ctrl+Alt+F2),然后就可以尝试播放一个视频了。下面的命令指定了 `fbdev2` 为视频输出设备,虽然我还没弄明白如何去选择用哪个输入设备,但是我用它成功过。默认的视频大小是 320x240,在此我给缩放到了 960: + ``` $ mplayer -vo fbdev2 -vf scale -zoom -xy 960 AlienSong_mp4.mov ``` And behold Figure 1. It's grainy because I have a low-fi copy of this video, not because MPlayer is making it grainy. +来看图1。粗糙的画面是由于我原视频的质量不高,而不是 MPlayer 的显示问题。 MPLayer plays CDs, DVDs, network streams, and has a giant batch of playback options, which I shall leave as your homework to explore. +MPlayer 可以播放 CD、DVD 以及网络视频流,并且还有一系列的回放选项,这些将作为作业让大家自己去发现。 ### fbi Image Viewer +### fbi 图片查看器 `fbi`, the framebuffer image viewer, comes in the [fbida][2] package on most Linuxes. It has native support for the common image file formats, and uses `convert` (from Image Magick), if it is installed, for other formats. Its simplest use is to view a single image file: ``` From e8bbdbf482d9ed5987cd13d9a05ff1b9c3daae4b Mon Sep 17 00:00:00 2001 From: wenwensnow <963555237@qq.com> Date: Fri, 26 Jan 2018 20:44:45 +0800 Subject: [PATCH 004/272] Update 20180121 Shell Scripting a Bunco Game.md --- .../tech/20180121 Shell Scripting a Bunco Game.md | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/sources/tech/20180121 Shell Scripting a Bunco Game.md b/sources/tech/20180121 Shell Scripting a Bunco Game.md index 4d5113ec74..71daf547a7 100644 --- a/sources/tech/20180121 Shell Scripting a Bunco Game.md +++ b/sources/tech/20180121 Shell Scripting a Bunco Game.md @@ -1,22 +1,32 @@ translating by wenwensnow -Shell Scripting a Bunco Game +Shell Scripting a Bunco Game  脚本编程之骰子游戏 ====== +我已经有段时间没有编写游戏了,所以我觉得现在正是做一些这方面事情的时候。起初,我想 " 用脚本编一个Halo? " (Halo:微软的光晕系列游戏),但我后来意识到这不太可能。来编一个叫Bunco的简单骰子游戏。你也许没有听说过,不过你母亲绝对知道 - 当一群年轻女孩聚在当地的酒吧或者小酒馆的时候,这是个很受欢迎的游戏。 + I haven't dug into any game programming for a while, so I thought it was high time to do something in that realm. At first, I thought "Halo as a shell script?", but then I came to my senses. Instead, let's look at a simple dice game called Bunco. You may not have heard of it, but I bet your Mom has—it's a quite popular game for groups of gals at a local pub or tavern. +游戏一共六轮,有三个骰子,规则很简单。每次投三个骰子,投出的点数要和当前的轮数数字一致。如果三个骰子都和当前的轮数一致,(比如,在第三轮三个骰子都是3),你这一轮的分数就是21。 如果三个骰子点数都相同但和轮数数字不同,你会得到最低的Bunco分数,只有5分。如果你投出的点数两者都不是,每一个和当前轮数相同的骰子得1分。 Played in six rounds with three dice, the game is simple. You roll all three dice and have to match the current round number. If all three dice match the current round number (for example, three 3s in round three), you score 21\. If all three match but aren't the current round number, it's a Mini Bunco and worth five points. Failing both of those, each die with the same value as the round number is worth one point. +要想玩这个游戏,它还涉及到团队,每一队(包括赢得那队),每个人都付5美元现金,或为赢家设立其他类似现金奖励,并规定什么样的情况下才是赢了,例如"most Buncos" or "most points"。在这里我会跳过这些,只关注投骰子这一部分。 Played properly, the game also involves teams, multiple tables including a winner's table, and usually cash prizes funded by everyone paying $5 or similar to play and based on specific winning scenarios like "most Buncos" or "most points". I'll skip that part here, however, and just focus on the dice part. -### Let's Do the Math +### Let's Do the Math +在专注于编程这方面的事之前,我先简单说说游戏背后的数学逻辑。要是有一个适当重量的骰子投骰子会变得很容易,任意一个值出现概率都是 1/6。 Before I go too far into the programming side of things, let me talk briefly about the math behind the game. Dice are easy to work with because on a properly weighted die, the chance of a particular value coming up is 1:6. +完全随机小提示:不确定你的骰子是否每个面都是一样重量? 把它们扔进盐水里然后转一下。YouTube上,有很多科学界的有趣视频向你展示怎么来做这个测试。 Random tip: not sure whether your dice are balanced? Toss them in salty water and spin them. There are some really interesting YouTube videos from the D&D world showing how to do this test. +所以三个骰子点数一样的几率有多大? 第一个骰子100%会有一个值 (这儿没什么可说的),所以很简单。第二个则有16.66%的概率和第一个骰子的值一样,接下来第三个骰子也是一样。 但当然,总概率是三个概率相乘的结果,所以最后,三个骰子值相等的概率是2.7%。 + So what are the odds of three dice having the same value? The first die has a 100% chance of having a value (no leaners here), so that's easy. The second die has a 16.66% chance of being any particular value, and then the third die has the same chance of being that value, but of course, they multiply, so three dice have about a 2.7% chance of all having the same value. +接下来,每个骰子和当前轮数数字相同的概率都是16.66%。从数学角度来说:0.166 * 0.166 * 0.166 = 0.00462。 Then, it's a 16.66% chance that those three dice would be the current round's number—or, in mathematical terms: 0.166 * 0.166 * 0.166 = 0.00462. +换句话说,你有0.46%的可能性投出Bunco In other words, you have a 0.46% chance of rolling a Bunco, which is a bit less than once out of every 200 rolls of three dice. It could be tougher though. If you were playing with five dice, the chance of rolling a Mini Bunco (or Yahtzee) is 0.077%, and if you were trying to accomplish a specific value, say just sixes, then it's 0.00012% likely on any given roll—which is to say, not bloody likely! From 0021217015d758d213f9171574c1482dfd1cf9d6 Mon Sep 17 00:00:00 2001 From: ChenYi <31087327+cyleft@users.noreply.github.com> Date: Sun, 28 Jan 2018 21:43:43 +0800 Subject: [PATCH 005/272] Delete 20180117 How To Manage Vim Plugins Using Vundle On Linux.md --- ...anage Vim Plugins Using Vundle On Linux.md | 252 ------------------ 1 file changed, 252 deletions(-) delete mode 100644 sources/tech/20180117 How To Manage Vim Plugins Using Vundle On Linux.md diff --git a/sources/tech/20180117 How To Manage Vim Plugins Using Vundle On Linux.md b/sources/tech/20180117 How To Manage Vim Plugins Using Vundle On Linux.md deleted file mode 100644 index 40f6c926f1..0000000000 --- a/sources/tech/20180117 How To Manage Vim Plugins Using Vundle On Linux.md +++ /dev/null @@ -1,252 +0,0 @@ -translated by cyleft - -How To Manage Vim Plugins Using Vundle On Linux -====== -![](https://www.ostechnix.com/wp-content/uploads/2018/01/Vundle-4-720x340.png) - -**Vim** , undoubtedly, is one of the powerful and versatile tool to manipulate text files, manage the system configuration files and writing code. The functionality of Vim can be extended to different levels using plugins. Usually, all plugins and additional configuration files will be stored in **~/.vim** directory. Since all plugin files are stored in a single directory, the files from different plugins are mixed up together as you install more plugins. Hence, it is going to be a daunting task to track and manage all of them. This is where Vundle comes in help. Vundle, acronym of **V** im B **undle** , is an extremely useful plug-in to manage Vim plugins. - -Vundle creates a separate directory tree for each plugin you install and stores the additional configuration files in the respective plugin directory. Therefore, there is no mix up files with one another. In a nutshell, Vundle allows you to install new plugins, configure existing plugins, update configured plugins, search for installed plugins and clean up unused plugins. All actions can be done in a single keypress with interactive mode. In this brief tutorial, let me show you how to install Vundle and how to manage Vim plugins using Vundle in GNU/Linux. - -### Installing Vundle - -If you need Vundle, I assume you have already installed **vim** on your system. If not, install vim and **git** (to download vundle). Both packages are available in the official repositories of most GNU/Linux distributions.For instance, you can use the following command to install these packages on Debian based systems. -``` -sudo apt-get install vim git -``` - -**Download Vundle** - -Clone Vundle GitHub repository: -``` -git clone https://github.com/VundleVim/Vundle.vim.git ~/.vim/bundle/Vundle.vim -``` - -**Configure Vundle** - -To tell vim to use the new plugin manager, we need to create **~/.vimrc** file. This file is required to install, update, configure and remove plugins. -``` -vim ~/.vimrc -``` - -Put the following lines on the top of this file: -``` -set nocompatible " be iMproved, required -filetype off " required - -" set the runtime path to include Vundle and initialize -set rtp+=~/.vim/bundle/Vundle.vim -call vundle#begin() -" alternatively, pass a path where Vundle should install plugins -"call vundle#begin('~/some/path/here') - -" let Vundle manage Vundle, required -Plugin 'VundleVim/Vundle.vim' - -" The following are examples of different formats supported. -" Keep Plugin commands between vundle#begin/end. -" plugin on GitHub repo -Plugin 'tpope/vim-fugitive' -" plugin from http://vim-scripts.org/vim/scripts.html -" Plugin 'L9' -" Git plugin not hosted on GitHub -Plugin 'git://git.wincent.com/command-t.git' -" git repos on your local machine (i.e. when working on your own plugin) -Plugin 'file:///home/gmarik/path/to/plugin' -" The sparkup vim script is in a subdirectory of this repo called vim. -" Pass the path to set the runtimepath properly. -Plugin 'rstacruz/sparkup', {'rtp': 'vim/'} -" Install L9 and avoid a Naming conflict if you've already installed a -" different version somewhere else. -" Plugin 'ascenator/L9', {'name': 'newL9'} - -" All of your Plugins must be added before the following line -call vundle#end() " required -filetype plugin indent on " required -" To ignore plugin indent changes, instead use: -"filetype plugin on -" -" Brief help -" :PluginList - lists configured plugins -" :PluginInstall - installs plugins; append `!` to update or just :PluginUpdate -" :PluginSearch foo - searches for foo; append `!` to refresh local cache -" :PluginClean - confirms removal of unused plugins; append `!` to auto-approve removal -" -" see :h vundle for more details or wiki for FAQ -" Put your non-Plugin stuff after this line -``` - -The lines which are marked as "required" are Vundle's requirement. The rest of the lines are just examples. You can remove those lines if you don't want to install that specified plugins. Once you finished, type **:wq** to save and close file. - -Finally, open vim: -``` -vim -``` - -And type the following to install the plugins. -``` -:PluginInstall -``` - -[![][1]][2] - -A new split window will open and all the plugins which we added in the .vimrc file will be installed automatically. - -[![][1]][3] - -When the installation is completed, you can delete the buffer cache and close the split window by typing the following command: -``` -:bdelete -``` - -You can also install the plugins without opening vim using the following command from the Terminal: -``` -vim +PluginInstall +qall -``` - -For those using the [**fish shell**][4], add the following line to your **.vimrc** file.`` -``` -set shell=/bin/bash -``` - -### Manage Vim Plugins Using Vundle - -**Add New Plugins** - -First, search for the available plugins using command: -``` -:PluginSearch -``` - -To refresh the local list from the from the vimscripts site, add **"! "** at the end. -``` -:PluginSearch! -``` - -A new split window will open list all available plugins. - -[![][1]][5] - -You can also narrow down your search by using directly specifying the name of the plugin like below. -``` -:PluginSearch vim -``` - -This will list the plugin(s) that contains the words "vim" - -You can, of course, specify the exact plugin name like below. -``` -:PluginSearch vim-dasm -``` - -To install a plugin, move the cursor to the correct line and hit **" i"**. Now, the selected plugin will be installed. - -[![][1]][6] - -Similarly, install all plugins you wanted to have in your system. Once installed, delete the Vundle buffer cache using command: -``` -:bdelete -``` - -Now the plugin is installed. To make it autoload correctly, we need to add the installed plugin name to .vimrc file. - -To do so, type: -``` -:e ~/.vimrc -``` - -Add the following line. -``` -[...] -Plugin 'vim-dasm' -[...] -``` - -Replace vim-dasm with your plugin name. Then, hit ESC key and type **:wq** to save the changes and close the file. - -Please note that all of your Plugins must be added before the following line in your .vimrc file. -``` -[...] -filetype plugin indent on -``` - -**List installed Plugins** - -To list installed plugins, type the following from the vim editor: -``` -:PluginList -``` - -[![][1]][7] - -**Update plugins** - -To update the all installed plugins, type: -``` -:PluginUpdate -``` - -To reinstall all plugins, type: -``` -:PluginInstall! -``` - -**Uninstall plugins** - -First, list out all installed plugins: -``` -:PluginList -``` - -Then place the cursor to the correct line, and press **" SHITF+d"**. - -[![][1]][8] - -Then, edit your .vimrc file: -``` -:e ~/.vimrc -``` - -And delete the Plugin entry. Finally, type **:wq** to save the changes and exit from vim editor. - -Alternatively, you can uninstall a plugin by removing its line from .vimrc file and run: -``` -:PluginClean -``` - -This command will remove all plugins which are no longer present in your .vimrc but still present the bundle directory. - -At this point, you should have learned the basic usage about managing plugins using Vundle. For details, refer the help section by typing the following in your vim editor. -``` -:h vundle -``` - -**Also Read:** - -And, that's all for now. I will be soon here with another useful guide. Until then, stay tuned with OSTechNix! - -Cheers! - -**Resource:** - - - --------------------------------------------------------------------------------- - -via: https://www.ostechnix.com/manage-vim-plugins-using-vundle-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/ -[1]:data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7 -[2]:http://www.ostechnix.com/wp-content/uploads/2018/01/Vundle-1.png () -[3]:http://www.ostechnix.com/wp-content/uploads/2018/01/Vundle-2.png () -[4]:https://www.ostechnix.com/install-fish-friendly-interactive-shell-linux/ -[5]:http://www.ostechnix.com/wp-content/uploads/2018/01/Vundle-3.png () -[6]:http://www.ostechnix.com/wp-content/uploads/2018/01/Vundle-4-2.png () -[7]:http://www.ostechnix.com/wp-content/uploads/2018/01/Vundle-5-1.png () -[8]:http://www.ostechnix.com/wp-content/uploads/2018/01/Vundle-6.png () From 13088502f3d9fc93ef61e2ade3d0c91fcc005110 Mon Sep 17 00:00:00 2001 From: ChenYi <31087327+cyleft@users.noreply.github.com> Date: Sun, 28 Jan 2018 21:44:53 +0800 Subject: [PATCH 006/272] translated by cyleft MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 20180117 How To Manage Vim Plugins Using Vundle On Linux.md 备注:图片链接出了问题 --- ...anage Vim Plugins Using Vundle On Linux.md | 251 ++++++++++++++++++ 1 file changed, 251 insertions(+) create mode 100644 translated/tech/20180117 How To Manage Vim Plugins Using Vundle On Linux.md diff --git a/translated/tech/20180117 How To Manage Vim Plugins Using Vundle On Linux.md b/translated/tech/20180117 How To Manage Vim Plugins Using Vundle On Linux.md new file mode 100644 index 0000000000..d3f79742ec --- /dev/null +++ b/translated/tech/20180117 How To Manage Vim Plugins Using Vundle On Linux.md @@ -0,0 +1,251 @@ +如何在 Linux 上使用 Vundle 管理 Vim 插件 +====== +![](https://www.ostechnix.com/wp-content/uploads/2018/01/Vundle-4-720x340.png) + +毋庸置疑,**Vim** 是一款强大的文本文件处理的通用工具,能够管理系统配置文件,编写代码。通过插件,vim 可以被拓展出不同层次的功能。通常,所有的插件和附属的配置文件都会存放在 **~/.vim** 目录中。由于所有的插件文件都被存储在同一个目录下,所以当你安装更多插件时,不同的插件文件之间相互混淆。因而,跟踪和管理它们将是一个恐怖的任务。然而,这正是 Vundle 所能处理的。Vundle,分别是 **V** im 和 B **undle** 的缩写,它是一款能够管理 Vim 插件的极其实用的工具。 + +Vundle 为每一个你安装和存储的拓展配置文件创建各自独立的目录树。因此,相互之间没有混淆的文件。简言之,Vundle 允许你安装新的插件、配置已存在的插件、更新插件配置、搜索安装插件和清理不使用的插件。所有的操作都可以在单一按键的交互模式下完成。在这个简易的教程中,让我告诉你如何安装 Vundle,如何在 GNU/Linux 中使用它来管理 Vim 插件。 + +### Vundle 安装 + +如果你需要 Vundle,那我就当作你的系统中,已将安装好了 **vim**。如果没有,安装 vim,尽情 **git**(下载 vundle)去吧。在大部分 GNU/Linux 发行版中的官方仓库中都可以获取到这两个包。比如,在 Debian 系列系统中,你可以使用下面的命令安装这两个包。 + +``` +sudo apt-get install vim git +``` + +**下载 Vundle** + +复制 Vundle 的 GitHub 仓库地址: +``` +git clone https://github.com/VundleVim/Vundle.vim.git ~/.vim/bundle/Vundle.vim +``` + +**配置 Vundle** + +创建 **~/.vimrc** 文件,通知 vim 使用新的插件管理器。这个文件获得有安装、更新、配置和移除插件的权限。 + +``` +vim ~/.vimrc +``` + +在此文件顶部,加入如下若干行内容: +``` +set nocompatible " be iMproved, required +filetype off " required + +" set the runtime path to include Vundle and initialize +set rtp+=~/.vim/bundle/Vundle.vim +call vundle#begin() +" alternatively, pass a path where Vundle should install plugins +"call vundle#begin('~/some/path/here') + +" let Vundle manage Vundle, required +Plugin 'VundleVim/Vundle.vim' + +" The following are examples of different formats supported. +" Keep Plugin commands between vundle#begin/end. +" plugin on GitHub repo +Plugin 'tpope/vim-fugitive' +" plugin from http://vim-scripts.org/vim/scripts.html +" Plugin 'L9' +" Git plugin not hosted on GitHub +Plugin 'git://git.wincent.com/command-t.git' +" git repos on your local machine (i.e. when working on your own plugin) +Plugin 'file:///home/gmarik/path/to/plugin' +" The sparkup vim script is in a subdirectory of this repo called vim. +" Pass the path to set the runtimepath properly. +Plugin 'rstacruz/sparkup', {'rtp': 'vim/'} +" Install L9 and avoid a Naming conflict if you've already installed a +" different version somewhere else. +" Plugin 'ascenator/L9', {'name': 'newL9'} + +" All of your Plugins must be added before the following line +call vundle#end() " required +filetype plugin indent on " required +" To ignore plugin indent changes, instead use: +"filetype plugin on +" +" Brief help +" :PluginList - lists configured plugins +" :PluginInstall - installs plugins; append `!` to update or just :PluginUpdate +" :PluginSearch foo - searches for foo; append `!` to refresh local cache +" :PluginClean - confirms removal of unused plugins; append `!` to auto-approve removal +" +" see :h vundle for more details or wiki for FAQ +" Put your non-Plugin stuff after this line +``` + +被标记的行中,是 Vundle 的请求项。其余行仅是一些例子。如果你不想安装那些特定的插件,可以移除它们。一旦你安装过,键入 **:wq** 保存退出。 + +最后,打开 vim +``` +vim +``` + +然后键入下列命令安装插件。 +``` +:PluginInstall +``` + +[![][1]][2] + +将会弹出一个新的分窗口,.vimrc 中陈列的项目都会自动安装。 + +[![][1]][3] + +安装完毕之后,键入下列命令,可以删除高速缓存区缓存并关闭窗口。 +``` +:bdelete +``` + +在终端上使用下面命令,规避使用 vim 安装插件 +``` +vim +PluginInstall +qall +``` + +使用 [**fish shell**][4] 的朋友,添加下面这行到你的 **.vimrc** 文件中。 + +``` +set shell=/bin/bash +``` + +### 使用 Vundle 管理 Vim 插件 + +**添加新的插件** + +首先,使用下面的命令搜索可以使用的插件。 +``` +:PluginSearch +``` + +命令之后添加 **"! "**,刷新 vimscripts 网站内容到本地。 +``` +:PluginSearch! +``` + +一个陈列可用插件列表的新分窗口将会被弹出。 + +[![][1]][5] + +你还可以通过直接指定插件名的方式,缩小搜索范围。 +``` +:PluginSearch vim +``` + +这样将会列出包含关键词“vim”的插件。 + +当然你也可以指定确切的插件名,比如: +``` +:PluginSearch vim-dasm +``` + +移动焦点到正确的一行上,点击 **" i"** 来安装插件。现在,被选择的插件将会被安装。 + +[![][1]][6] + +在你的系统中,所有想要的的插件都以类似的方式安装。一旦安装成功,使用下列命令删除 Vundle 缓存: +``` +:bdelete +``` + +现在,插件已经安装完成。在 .vimrc 文件中添加安装好的插件名,让插件正确加载。 + +这样做: +``` +:e ~/.vimrc +``` + +添加这一行: +``` +[...] +Plugin 'vim-dasm' +[...] +``` + +用自己的插件名替换 vim-dasm。然后,敲击 ESC,键入 **:wq** 保存退出。 + +请注意,所有插件都必须在 .vimrc 文件中追加如下内容。 +``` +[...] +filetype plugin indent on +``` + +**列出已安装的插件** + +键入下面命令列出所有已安装的插件: +``` +:PluginList +``` + +[![][1]][7] + +**更新插件** + +键入下列命令更新插件: +``` +:PluginUpdate +``` + +键入下列命令重新安装所有插件 +``` +:PluginInstall! +``` + +**卸载插件** + +首先,列出所有已安装的插件: +``` +:PluginList +``` + +之后将焦点置于正确的一行上,敲 **" SHITF+d"** 组合键。 + +[![][1]][8] + +然后编辑你的 .vimrc 文件: +``` +:e ~/.vimrc +``` + +再然后删除插件入口。最后,键入 **:wq** 保存退出。 + +或者,你可以通过移除插件所在 .vimrc 文件行,并且执行下列命令,卸载插件: +``` +:PluginClean +``` + +这个命令将会移除所有不在你的 .vimrc 文件中但是存在于 bundle 目录中的插件。 + +你应该已经掌握了 Vundle 管理插件的基本方法了。在 vim 中使用下列命令,查询帮助文档,获取更多细节。 +``` +:h vundle +``` + +**捎带看看:** + +现在我已经把所有内容都告诉你了。很快,我就会出下一篇教程。保持关注 OSTechNix! + +干杯! + +**来源:** + +-------------------------------------------------------------------------------- + +via: https://www.ostechnix.com/manage-vim-plugins-using-vundle-linux/ + +作者:[SK][a] +译者:[CYLeft](https://github.com/CYLeft) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://www.ostechnix.com/author/sk/ +[1]:data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7 +[2]:http://www.ostechnix.com/wp-content/uploads/2018/01/Vundle-1.png () +[3]:http://www.ostechnix.com/wp-content/uploads/2018/01/Vundle-2.png () +[4]:https://www.ostechnix.com/install-fish-friendly-interactive-shell-linux/ +[5]:http://www.ostechnix.com/wp-content/uploads/2018/01/Vundle-3.png () +[6]:http://www.ostechnix.com/wp-content/uploads/2018/01/Vundle-4-2.png () +[7]:http://www.ostechnix.com/wp-content/uploads/2018/01/Vundle-5-1.png () +[8]:http://www.ostechnix.com/wp-content/uploads/2018/01/Vundle-6.png () From 33d945df1bc24afec0bc036a444bffa584fd4ea0 Mon Sep 17 00:00:00 2001 From: ChenYi <31087327+cyleft@users.noreply.github.com> Date: Sun, 28 Jan 2018 21:50:50 +0800 Subject: [PATCH 007/272] apply for translation --- sources/tech/20180125 A step-by-step guide to Git.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sources/tech/20180125 A step-by-step guide to Git.md b/sources/tech/20180125 A step-by-step guide to Git.md index cf43f625ce..823e730a0f 100644 --- a/sources/tech/20180125 A step-by-step guide to Git.md +++ b/sources/tech/20180125 A step-by-step guide to Git.md @@ -1,3 +1,7 @@ +# translated by cyleft +# translated by cyleft +# translated by cyleft + A step-by-step guide to Git ====== From f767f81139975b0ad97ab05f9a12ad41b724e31d Mon Sep 17 00:00:00 2001 From: wxy Date: Sun, 28 Jan 2018 22:23:01 +0800 Subject: [PATCH 008/272] PRF:20111124 How to find hidden processes and ports on Linux-Unix-Windows.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @ljgibbs 恭喜你完成了第一篇翻译(我校对晚了),你可以对比下我的校对,了解下丢失的格式。 --- ...ocesses and ports on Linux-Unix-Windows.md | 320 +++++++++++------- 1 file changed, 190 insertions(+), 130 deletions(-) diff --git a/translated/tech/20111124 How to find hidden processes and ports on Linux-Unix-Windows.md b/translated/tech/20111124 How to find hidden processes and ports on Linux-Unix-Windows.md index dd834e3a53..b670472ce3 100644 --- a/translated/tech/20111124 How to find hidden processes and ports on Linux-Unix-Windows.md +++ b/translated/tech/20111124 How to find hidden processes and ports on Linux-Unix-Windows.md @@ -1,183 +1,243 @@ -# 如何在 Linux/Unix/Windows 中发现隐藏的进程和端口 +如何在 Linux/Unix/Windows 中发现隐藏的进程和端口 +============== - -unhide 是一个小巧的网络取证工具,能够发现那些借助 rootkits,LKM 等其他技术隐藏的进程和 TCP/UDP 端口。这个工具在 Linux,unix-like,Windows 等操作系统下都可以工作。根据其 man 页面的说明: +`unhide` 是一个小巧的网络取证工具,能够发现那些借助 rootkit、LKM 及其它技术隐藏的进程和 TCP/UDP 端口。这个工具在 Linux、UNIX 类、MS-Windows 等操作系统下都可以工作。根据其 man 页面的说明: > Unhide 通过下述三项技术来发现隐藏的进程。 -> 1. 进程相关的技术,包括将 /proc 目录与 /bin/ps 命令的输出进行比较。 -> 2. 系统相关的技术,包括将 ps 命令的输出结果同从系统调用方面得到的信息进行比较。 +> 1. 进程相关的技术,包括将 `/proc` 目录与 [/bin/ps][1] 命令的输出进行比较。 +> 2. 系统相关的技术,包括将 [/bin/ps][1] 命令的输出结果同从系统调用方面得到的信息进行比较。 > 3. 穷举法相关的技术,包括对所有的进程 ID 进行暴力求解,该技术仅限于在基于 Linux2.6 内核的系统中使用。 -绝大多数的 Rootkits 工具或者恶意软件借助内核来实现进程隐藏,这些进程只在内核内部可见。你可以使用 unhide 或者诸如 rkhunter 等工具,扫描 rootkit 程序,后门程序以及一些可能存在的本地漏洞。 +绝大多数的 Rootkit 工具或者恶意软件借助内核来实现进程隐藏,这些进程只在内核内部可见。你可以使用 `unhide` 或者诸如 [rkhunter 等工具,扫描 rootkit 程序 、后门程序以及一些可能存在的本地漏洞][2]。 -![本文讲解如何在多个操作系统下安装和使用unhide][1] -如何安装 unhide ------------ +![本文讲解如何在多个操作系统下安装和使用unhide][3] -这里首先建议你在只读介质上运行这个工具。如果使用的是 Ubuntu 或者 Debian 发行版,输入下述的 apt-get/apt 命令以安装 Unhide:`$ sudo apt-get install unhide` 一切顺利的话你的命令行会输出以下内容: +这篇文章描述了如何安装 unhide 并搜索隐藏的进程和 TCP/UDP 端口。 - [sudo] password for vivek: - Reading package lists... Done - Building dependency tree - Reading state information... Done - Suggested packages: - rkhunter - The following NEW packages will be installed: - unhide - 0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded. - Need to get 46.6 kB of archives. - After this operation, 136 kB of additional disk space will be used. - Get:1 http://in.archive.ubuntu.com/ubuntu artful/universe amd64 unhide amd64 20130526-1 [46.6 kB] - Fetched 46.6 kB in 0s (49.0 kB/s) - Selecting previously unselected package unhide. - (Reading database ... 205367 files and directories currently installed.) - Preparing to unpack .../unhide_20130526-1_amd64.deb ... - Unpacking unhide (20130526-1) ... - Setting up unhide (20130526-1) ... - Processing triggers for man-db (2.7.6.1-2) ... +### 如何安装 unhide -如何在RHEL/CentOS/Oracle/Scientific/Fedora上安装 unhide ------------------------------------------------------------------- +首先建议你在只读介质上运行这个工具。如果使用的是 Ubuntu 或者 Debian 发行版,输入下述的 [apt-get][4]/[apt][5] 命令以安装 Unhide: -你可以使用以下的 yum 命令: +``` +$ sudo apt-get install unhide +``` - `Sudo yum install unhide` +一切顺利的话你的命令行会输出以下内容: + +``` +[sudo] password for vivek: +Reading package lists... Done +Building dependency tree +Reading state information... Done +Suggested packages: + rkhunter +The following NEW packages will be installed: + unhide +0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded. +Need to get 46.6 kB of archives. +After this operation, 136 kB of additional disk space will be used. +Get:1 http://in.archive.ubuntu.com/ubuntu artful/universe amd64 unhide amd64 20130526-1 [46.6 kB] +Fetched 46.6 kB in 0s (49.0 kB/s) +Selecting previously unselected package unhide. +(Reading database ... 205367 files and directories currently installed.) +Preparing to unpack .../unhide_20130526-1_amd64.deb ... +Unpacking unhide (20130526-1) ... +Setting up unhide (20130526-1) ... +Processing triggers for man-db (2.7.6.1-2) ... +``` + +### 如何在 RHEL/CentOS/Oracle/Scientific/Fedora 上安装 unhide + +输入下列 yum Type the following yum command (first turn on EPLE repo on a CentOS/RHEL version 6.x or version 7.x): + +输入以下的 [yum][6] 命令(CentOS/RHEL [6.x][7] 或 [7.x][8] 上首先打开 EPEL 仓库): + +``` +$ sudo yum install unhide +``` 在 Fedora 上则使用以下 dnf 命令: - Sudo dnf install unhide. +``` +$ sudo dnf install unhide +``` -如何在 Arch 上安装 unhide -------------------- +### 如何在 Arch 上安装 unhide - 键入以下 pacman 命令安装 $ sudo pacman -S unhide +键入以下 pacman 命令安装: -如何在 FreeBSD 上安装 unhide ----------------------- +``` +$ sudo pacman -S unhide +``` -可以通过以下的命令使用 port 来安装 unhide +### 如何在 FreeBSD 上安装 unhide - # cd /usr/ports/security/unhide/ - # make install clean +可以通过以下的命令使用 port 来安装 unhide: -或者可以通过二进制文件安装hide,使用 pkg 命令安装 +``` +# cd /usr/ports/security/unhide/ +# make install clean +``` - # pkg install unhide +或者可以通过二进制文件安装 hide,使用 pkg 命令安装: -Unhide-tcp 取证工具通过对所有可用的 TCP/IP 端口进行暴力求解的方式,辨别所有正在监听,却没有列入 /bin/netstat 或者 /bin/ss command 目录的 TCP/IP 端口身份。 +``` +# pkg install unhide +``` -如何使用 unhide 工具? ---------------- +### 如何使用 unhide 工具? -Unhide 的语法是 `unhide [options] test_list` test_list 参数可以是以下测试列表中的一个或者多个标准测试: +unhide 的语法是: + +``` +unhide [options] test_list +``` + +`test_list` 参数可以是以下测试列表中的一个或者多个标准测试: - 1. Brute - 2. proc - 3. procall - 4. procfs - 5. quick - 6. reverse - 7. sys +1. brute +2. proc +3. procall +4. procfs +5. quick +6. reverse +7. sys -基本测试: +或基本测试: - 1. checkbrute - 2. checkchdir - 3. checkgetaffinity - 4. checkgetparam - 5. checkgetpgid - 6. checkgetprio - 7. checkRRgetinterval - 8. checkgetsched - 9. checkgetsid - 10. checkkill - 11. checknoprocps - 12. checkopendir - 13. checkproc - 14. checkquick - 15. checkreaddir - 16. checkreverse - 17. checksysinfo - 18. checksysinfo2 - 19. checksysinfo3 +1. checkbrute +2. checkchdir +3. checkgetaffinity +4. checkgetparam +5. checkgetpgid +6. checkgetprio +7. checkRRgetinterval +8. checkgetsched +9. checkgetsid +10. checkkill +11. checknoprocps +12. checkopendir +13. checkproc +14. checkquick +15. checkreaddir +16. checkreverse +17. checksysinfo +18. checksysinfo2 +19. checksysinfo3 -你可以通过以下示例命令使用 unhide: +你可以通过以下示例命令使用 `unhide`: - # unhide proc - # unhide sys - # unhide quick +``` +# unhide proc +# unhide sys +# unhide quick +``` 示例输出: - Unhide 20130526 - Copyright © 2013 Yago Jesus & Patrick Gouin - License GPLv3+ : GNU GPL version 3 or later - http://www.unhide-forensics.info - - NOTE : This version of unhide is for systems using Linux >= 2.6 - - Used options: - [*]Searching for Hidden processes through comparison of results of system calls, proc, dir and ps +``` +Unhide 20130526 +Copyright © 2013 Yago Jesus & Patrick Gouin +License GPLv3+ : GNU GPL version 3 or later +http://www.unhide-forensics.info + +NOTE : This version of unhide is for systems using Linux >= 2.6 + +Used options: +[*]Searching for Hidden processes through comparison of results of system calls, proc, dir and ps +``` -如何使用 unhide-tcp 工具辨明 TCP/UDP 端口的身份 ----------------------------------- +### 如何使用 unhide-tcp 工具辨明 TCP/UDP 端口的身份 -以下是来自 man 页面的介绍 +以下是来自 man 页面的介绍: -> unhide-tcp is a forensic tool that identifies TCP/UDP ports that are -> listening but are not listed by /sbin/ss (or alternatively by -> /bin/netstat) through brute forcing of all TCP/UDP ports available. -> Note1 : On FreeBSD ans OpenBSD, netstat is allways used as iproute2 -> doesn't exist on these OS. In addition, on FreeBSD, sockstat is used -> instead of fuser. Note2 : If iproute2 is not available on the system, -> option -n or -s SHOULD be given on the command line. +> `unhide-tcp` 取证工具通过对所有可用的 TCP/IP 端口进行暴力求解的方式,辨别所有正在监听,却没有列入 [/bin/netstat][9] 或者 [/bin/ss][10] 命令输出的 TCP/IP 端口身份。 -Unhide-tcp 取证工具,通过对所有可用的 TCP/IP 端口进行暴力求解的方式,辨别所有正在监听,却没有列入 /bin/netstat 或者 /bin/ss command 目录的 TCP/IP 端口身份。请注意:对于 FreeBSD,OpenBSD系统,一般使用 iproute2,fuser 命令取代在这些操作系统上不存在的 netstat,sockstat 命令。请注意 2:如果操作系统不支持 iproute2 命令,在使用 unhide 时需要在命令上加上 -n 或者 -s 选项。 +> 注一:对于 FreeBSD、OpenBSD系统,一般使用 netstat 命令取代在这些操作系统上不存在的 iproute2,此外,sockstat 命令也用于替代 fuser。 - # `unhide-tcp` +> 注二:如果操作系统不支持 iproute2 命令,在使用 `unhide` 时需要在命令上加上 `-n` 或者 `-s` 选项。 -示例输出: +``` +# unhide-tcp +``` - Unhide 20100201 - http://www.security-projects.com/?Unhide - Starting TCP checking - Starting UDP checking +示例输出: -上述操作中,没有发现隐藏的端口。但在下述示例中,我展示了一些有趣的事。 +``` +Unhide 20100201 +http://www.security-projects.com/?Unhide - # `unhide-tcp` +Starting TCP checking -示例输出: +Starting UDP checking +``` - Unhide 20100201 - http://www.security-projects.com/?Unhide - Starting TCP checking - Found Hidden port that not appears in netstat: 1048 - Found Hidden port that not appears in netstat: 1049 - Found Hidden port that not appears in netstat: 1050 - Starting UDP checking +上述操作中,没有发现隐藏的端口。 -可以看到 netstat -tulpn 和 ss commands 命令确实没有反映出这三个隐藏的端口 +但在下述示例中,我展示了一些有趣的事。 - # netstat -tulpn | grep 1048 - # ss -lp - # ss -l | grep 1048 +``` +# unhide-tcp +``` -通过下述的 man 命令可以更多地了解unhide +示例输出: - $ man unhide - $ man unhide-tcp +``` +Unhide 20100201 +http://www.security-projects.com/?Unhide -Windows 用户如何安装使用 unhide ---------------------- -你可以通过这个[页面][2]获取 Windows 版本的 unhide + +Starting TCP checking + +Found Hidden port that not appears in netstat: 1048 +Found Hidden port that not appears in netstat: 1049 +Found Hidden port that not appears in netstat: 1050 +Starting UDP checking +``` + +可以看到 `netstat -tulpn` 和 `ss` 命令确实没有反映出这三个隐藏的端口: + +``` +# netstat -tulpn | grep 1048 +# ss -lp +# ss -l | grep 1048 +``` + +通过下述的 man 命令可以更多地了解 `unhide`: + +``` +$ man unhide +$ man unhide-tcp +``` + +### Windows 用户如何安装使用 unhide + +你可以通过这个[页面][13]获取 Windows 版本的 unhide。 + +---- via: https://www.cyberciti.biz/tips/linux-unix-windows-find-hidden-processes-tcp-udp-ports.html -作者:Vivek Gite 译者:[ljgibbs][3] 校对:校对者ID -本文由 LCTT 原创编译,Linux中国 荣誉推出! +作者:[Vivek Gite][a] +译者:[ljgibbs](https://github.com/ljgibbs) +校对:[wxy](https://github.com/wxy) - [1]: https://camo.githubusercontent.com/51ee31c20a799512dcd09d88cacbe8dd04731529/68747470733a2f2f7777772e6379626572636974692e62697a2f746970732f77702d636f6e74656e742f75706c6f6164732f323031312f31312f4c696e75782d467265654253442d556e69782d57696e646f77732d46696e642d48696464656e2d50726f636573732d506f7274732e6a7067 - [2]: http://www.unhide-forensics.info/?Windows:Download - [3]: https://github.com/ljgibbslf +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://www.cyberciti.biz +[1]:https://www.cyberciti.biz/faq/show-all-running-processes-in-linux/ (Linux / Unix ps command) +[2]:https://www.cyberciti.biz/faq/howto-check-linux-rootkist-with-detectors-software/ +[3]:https://www.cyberciti.biz/tips/wp-content/uploads/2011/11/Linux-FreeBSD-Unix-Windows-Find-Hidden-Process-Ports.jpg +[4]:https://www.cyberciti.biz/tips/linux-debian-package-management-cheat-sheet.html (See Linux/Unix apt-get command examples for more info) +[5]://www.cyberciti.biz/faq/ubuntu-lts-debian-linux-apt-command-examples/ (See Linux/Unix apt command examples for more info) +[6]:https://www.cyberciti.biz/faq/rhel-centos-fedora-linux-yum-command-howto/ (See Linux/Unix yum command examples for more info) +[7]:https://www.cyberciti.biz/faq/fedora-sl-centos-redhat6-enable-epel-repo/ +[8]:https://www.cyberciti.biz/faq/installing-rhel-epel-repo-on-centos-redhat-7-x/ +[9]:https://www.cyberciti.biz/tips/linux-display-open-ports-owner.html (Linux netstat command) +[10]:https://www.cyberciti.biz/tips/linux-investigate-sockets-network-connections.html +[11]:https://www.cyberciti.biz/tips/netstat-command-tutorial-examples.html +[12]:https://www.cyberciti.biz/tips/linux-investigate-sockets-network-connections.html +[13]:http://www.unhide-forensics.info/?Windows:Download From a4a7560d94515c938f961f56c15ea0b4812922ef Mon Sep 17 00:00:00 2001 From: wxy Date: Sun, 28 Jan 2018 22:29:58 +0800 Subject: [PATCH 009/272] PUB:20111124 How to find hidden processes and ports on Linux-Unix-Windows.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @ljgibbslf 首发地址:https://linux.cn/article-9288-1.html 你的 LCTT 专页地址: https://linux.cn/lctt/ljgibbslf 还有,你写译者 id 时千万别写错! --- ... to find hidden processes and ports on Linux-Unix-Windows.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename {translated/tech => published}/20111124 How to find hidden processes and ports on Linux-Unix-Windows.md (99%) diff --git a/translated/tech/20111124 How to find hidden processes and ports on Linux-Unix-Windows.md b/published/20111124 How to find hidden processes and ports on Linux-Unix-Windows.md similarity index 99% rename from translated/tech/20111124 How to find hidden processes and ports on Linux-Unix-Windows.md rename to published/20111124 How to find hidden processes and ports on Linux-Unix-Windows.md index b670472ce3..4bdf16485c 100644 --- a/translated/tech/20111124 How to find hidden processes and ports on Linux-Unix-Windows.md +++ b/published/20111124 How to find hidden processes and ports on Linux-Unix-Windows.md @@ -220,7 +220,7 @@ $ man unhide-tcp via: https://www.cyberciti.biz/tips/linux-unix-windows-find-hidden-processes-tcp-udp-ports.html 作者:[Vivek Gite][a] -译者:[ljgibbs](https://github.com/ljgibbs) +译者:[ljgibbslf](https://github.com/ljgibbslf) 校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 From c8a2e7d78a6c91460a778cc59820be5f84f6c6a3 Mon Sep 17 00:00:00 2001 From: Sun Yongfei Date: Sun, 28 Jan 2018 23:31:13 +0800 Subject: [PATCH 010/272] translating --- .../tech/20180123 What Is bashrc and Why Should You Edit It.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sources/tech/20180123 What Is bashrc and Why Should You Edit It.md b/sources/tech/20180123 What Is bashrc and Why Should You Edit It.md index 93b8b5dc7f..16d56f64bb 100644 --- a/sources/tech/20180123 What Is bashrc and Why Should You Edit It.md +++ b/sources/tech/20180123 What Is bashrc and Why Should You Edit It.md @@ -1,3 +1,5 @@ +heart4lor translating + What Is bashrc and Why Should You Edit It ====== From 5a4b810921936e1942ee89642ca21d3424c3b977 Mon Sep 17 00:00:00 2001 From: wenwensnow <963555237@qq.com> Date: Sun, 28 Jan 2018 23:32:53 +0800 Subject: [PATCH 011/272] Update 20180121 Shell Scripting a Bunco Game.md --- .../20180121 Shell Scripting a Bunco Game.md | 83 +++++++++++-------- 1 file changed, 50 insertions(+), 33 deletions(-) diff --git a/sources/tech/20180121 Shell Scripting a Bunco Game.md b/sources/tech/20180121 Shell Scripting a Bunco Game.md index 71daf547a7..ca70dbc7ec 100644 --- a/sources/tech/20180121 Shell Scripting a Bunco Game.md +++ b/sources/tech/20180121 Shell Scripting a Bunco Game.md @@ -1,4 +1,4 @@ -translating by wenwensnow + Shell Scripting a Bunco Game  脚本编程之骰子游戏 ====== 我已经有段时间没有编写游戏了,所以我觉得现在正是做一些这方面事情的时候。起初,我想 " 用脚本编一个Halo? " (Halo:微软的光晕系列游戏),但我后来意识到这不太可能。来编一个叫Bunco的简单骰子游戏。你也许没有听说过,不过你母亲绝对知道 - 当一群年轻女孩聚在当地的酒吧或者小酒馆的时候,这是个很受欢迎的游戏。 @@ -6,36 +6,37 @@ Shell Scripting a Bunco Game  脚本编程之骰子游戏 I haven't dug into any game programming for a while, so I thought it was high time to do something in that realm. At first, I thought "Halo as a shell script?", but then I came to my senses. Instead, let's look at a simple dice game called Bunco. You may not have heard of it, but I bet your Mom has—it's a quite popular game for groups of gals at a local pub or tavern. 游戏一共六轮,有三个骰子,规则很简单。每次投三个骰子,投出的点数要和当前的轮数数字一致。如果三个骰子都和当前的轮数一致,(比如,在第三轮三个骰子都是3),你这一轮的分数就是21。 如果三个骰子点数都相同但和轮数数字不同,你会得到最低的Bunco分数,只有5分。如果你投出的点数两者都不是,每一个和当前轮数相同的骰子得1分。 -Played in six rounds with three dice, the game is simple. You roll all three dice and have to match the current round number. If all three dice match the current round number (for example, three 3s in round three), you score 21\. If all three match but aren't the current round number, it's a Mini Bunco and worth five points. Failing both of those, each die with the same value as the round number is worth one point. -要想玩这个游戏,它还涉及到团队,每一队(包括赢得那队),每个人都付5美元现金,或为赢家设立其他类似现金奖励,并规定什么样的情况下才是赢了,例如"most Buncos" or "most points"。在这里我会跳过这些,只关注投骰子这一部分。 -Played properly, the game also involves teams, multiple tables including a winner's table, and usually cash prizes funded by everyone paying $5 or similar to play and based on specific winning scenarios like "most Buncos" or "most points". I'll skip that part here, however, and just focus on the dice part. -### Let's Do the Math +要想玩这个游戏,它还涉及到团队合作,每一队(包括赢得那队),每人付5美元现金,或赢家得到其他类似现金奖励,并规定什么样的情况下才是赢家,例如"most Buncos" or "most points"胜利。在这里我会跳过这些,而只关注投骰子这一部分。 + + +### 关于数学逻辑部分 在专注于编程这方面的事之前,我先简单说说游戏背后的数学逻辑。要是有一个适当重量的骰子投骰子会变得很容易,任意一个值出现概率都是 1/6。 -Before I go too far into the programming side of things, let me talk briefly about the math behind the game. Dice are easy to work with because on a properly weighted die, the chance of a particular value coming up is 1:6. + 完全随机小提示:不确定你的骰子是否每个面都是一样重量? 把它们扔进盐水里然后转一下。YouTube上,有很多科学界的有趣视频向你展示怎么来做这个测试。 -Random tip: not sure whether your dice are balanced? Toss them in salty water and spin them. There are some really interesting YouTube videos from the D&D world showing how to do this test. + 所以三个骰子点数一样的几率有多大? 第一个骰子100%会有一个值 (这儿没什么可说的),所以很简单。第二个则有16.66%的概率和第一个骰子的值一样,接下来第三个骰子也是一样。 但当然,总概率是三个概率相乘的结果,所以最后,三个骰子值相等的概率是2.7%。 -So what are the odds of three dice having the same value? The first die has a 100% chance of having a value (no leaners here), so that's easy. The second die has a 16.66% chance of being any particular value, and then the third die has the same chance of being that value, but of course, they multiply, so three dice have about a 2.7% chance of all having the same value. + 接下来,每个骰子和当前轮数数字相同的概率都是16.66%。从数学角度来说:0.166 * 0.166 * 0.166 = 0.00462。 -Then, it's a 16.66% chance that those three dice would be the current round's number—or, in mathematical terms: 0.166 * 0.166 * 0.166 = 0.00462. -换句话说,你有0.46%的可能性投出Bunco -In other words, you have a 0.46% chance of rolling a Bunco, which is a bit less than once out of every 200 rolls of three dice. -It could be tougher though. If you were playing with five dice, the chance of rolling a Mini Bunco (or Yahtzee) is 0.077%, and if you were trying to accomplish a specific value, say just sixes, then it's 0.00012% likely on any given roll—which is to say, not bloody likely! +换句话说,你有0.46%的可能性投出Bunco,比200次中出现一次的可能性还小一点。 -### And So into the Coding -As with every game, the hardest part is really having a good random number generator that generates truly random values. That's actually hard to affect in a shell script though, so I'm going to sidestep this entire issue and assume that the shell's built-in random number generator will be sufficient. +实际上还可以更难。如果你有5个骰子,投出 Mini Bunco (也可以叫做Yahtzee) 的概率为0.077%,如果你想所有的骰子的值都相同,假设都是6,那概率就是0.00012%,那就基本上没什么可能了。 -What's nice is that it's super easy to work with. Just reference $RANDOM, and you'll have a random value between 0 and MAXINT (32767): + +### 开始编程吧 + +和所有游戏一样,最难的部分是有一个能生成随机数的随机数发生器。这一部分在shell 脚本中还是很难实现的,所以我需要一步步来,并假设shell内置的随机数发生器就够用了 + +不过好在内置的随机数发生器很好用。用 $RANDOM 就能得到一个0到MAXINT(32767)之间的随机值: ``` @@ -44,7 +45,8 @@ $ echo $RANDOM $RANDOM $RANDOM ``` -To constrain that to values between 1–6 use the modulus function: +为了确保产生的值一定是 1-6之中的某个值,使用取余函数: + ``` @@ -55,7 +57,8 @@ $ echo $(( $RANDOM % 6 )) ``` -Oops! I forgot to shift it one. Here's another try: +哦!我忘了要加1,下面是另一次尝试: + ``` @@ -64,7 +67,8 @@ $ echo $(( ( $RANDOM % 6 ) + 1 )) ``` -That's the dice-rolling feature. Let's make it a function where you can specify the variable you'd like to have the generated value as part of the invocation: +下面要实现投骰子这一功能。这个函数中你可以声明一个局部变量来存储生成的随机值: + ``` @@ -77,7 +81,7 @@ rolldie() ``` -The use of the eval is to ensure that the variable specified in the invocation is actually assigned the calculated value. It's easy to work with: +使用 eval 确保生成的随机数被实际存储在变量中。这一部分也很容易: ``` @@ -85,7 +89,8 @@ rolldie die1 ``` -That will load a random value between 1–6 into the variable die1. To roll your three dice, it's straightforward: +这会为第一个骰子生成一个1-6之中的值。要为3个骰子都生成值,执行3次上面的函数: + ``` @@ -93,7 +98,8 @@ rolldie die1 ; rolldie die2 ; rolldie die3 ``` -Now to test the values. First, let's test for a Bunco where all three dice have the same value, and it's the value of the current round too: +现在判断下生成的值。首先,判断是不是Bunco(3个骰子值相同),然后是不是和当前轮数值也相同: + ``` @@ -108,9 +114,11 @@ if [ $die1 -eq $die2 ] && [ $die2 -eq $die3 ] ; then ``` -That's probably the hardest of the tests, and notice the unusual use of test in the first conditional: [ cond1 ] && [ cond2 ]. If you're thinking that you could also write it as cond1 -a cond2, you're right. As with so much in the shell, there's more than one way to get to the solution. +这可能是所有判断语句中最难的部分了,注意第一个条件语句中这种不常用的写法 : [ cond1 ] && [ cond2 ]。如果你想写成 cond1 -a cond2 ,这样也可以。在shell编程中,解决问题的方法往往不止一种。 + + +代码剩下的部分很直白,你只需要判断每个骰子的值是不是和本轮数字相同: -The remainder of the code is straightforward; you just need to test for whether the die matches the current round value: ``` @@ -126,9 +134,12 @@ fi ``` -The only thing to consider here is that you don't want to score die value vs. round if you've also scored a Bunco or Mini Bunco, so the entire second set of tests needs to be within the else clause of the first conditional (to see if all three dice have the same value). +唯一要注意的是当出现 Bunco/Mini Bunco 就不需要再统计本轮分数了。所以整个第二部分的判断语句都要写在第一个条件语句的else中(为了判断3个骰子值是否都相同)。 + + + +把所有的综合起来,然后在命令行中输入轮数,下面是现在的脚本执行后的结果: -Put it together and specify the round number on the command line, and here's what you have at this point: ``` @@ -145,11 +156,15 @@ score = 25 ``` -A Bunco so quickly? Well, as I said, there might be a slight issue with the randomness of the random number generator in the shell. +竟然这么快就出现 Bunco 了? 好吧,就像我说的,shell内置的随机数发生器在随机数产生这方面可能有些问题。 -You can test it once you have the script working by running it a few hundred times and then checking to see what percentage are Bunco or Mini Bunco, but I'll leave that as an exercise for you, dear reader. Well, maybe I'll come back to it another time. -Let's finish up this script by having it accumulate score and run for all six rounds instead of specifying a round on the command line. That's easily done, because it's just a wrapper around the entire script, or, better, the big conditional statement becomes a function all its own: + +你可以执行脚本几百次,从而让你的脚本得以正确运行,然后看看Bunco/Mini Bunco出现次数所占的百分比。但是我想把这部分作为练习,留给亲爱的读者你们。不过,也许我下次会抽时间完成剩下的部分。 + + +让我们完成这一脚本吧,还有分数统计和一次性执行6次投骰子(这次不用再在命令行中手动输入当前轮数了)这两个功能。这也很容易,因为只是将上面的内容整个嵌套在里面,换句话说,就是将一个复杂的条件嵌套结构全部写在了一个函数中: + ``` @@ -194,9 +209,10 @@ BuncoRound() ``` -I admit, I couldn't resist a few improvements as I went along, including the addition of it showing either Bunco, Mini Bunco or a score value (that's what $hidescore does). +我承认,我忍不住自己做了一点改进,包括判断当前是Bunco, Mini Bunco 还是其他需要计算分数的情况这一部分 (这就是$hidescore这一变量的作用). -Invoking it is a breeze, and you'll use a for loop: + +实现这个简直是小菜一碟,只要一个循环就好了: ``` @@ -206,7 +222,7 @@ done ``` -That's about the entire program at this point. Let's run it once and see what happens: +这就是现在所写的整个程序。让我们执行一下看看结果: ``` @@ -227,9 +243,10 @@ Game over. Your total score was 4 ``` -Ugh. Not too impressive, but it's probably a typical round. Again, you can run it a few hundred—or thousand—times, just save the "Game over" line, then do some quick statistical analysis to see how often you score more than 3 points in six rounds. (With three dice to roll a given value, you should hit that 50% of the time.) +嗯。并不是很令人满意,可能是因为它只是游戏的一次完整执行。不过,你可以将脚本执行几百几千次,记下"Game over"出现的位置,然后用一些快速分析工具来看看你在每6轮中有几次得分超过3分。(要让3个骰子值相同,这个概率大概在50%左右)。 + +无论怎么说,这都不是一个复杂的游戏,但是它是一个很有意思的小程序项目。现在,如果有一个20面的骰子,每一轮游戏有好几十轮,每轮都掷同一个骰子,情况又会发生什么变化呢? -It's not a complicated game by any means, but it makes for an interesting little programming project. Now, what if they used 20-sided die and let you re-roll one die per round and had a dozen rounds? -------------------------------------------------------------------------------- From e2592138dcc30b8a8f268b3c10ffcfd6f43d260b Mon Sep 17 00:00:00 2001 From: wenwensnow <963555237@qq.com> Date: Sun, 28 Jan 2018 23:39:01 +0800 Subject: [PATCH 012/272] Create 20180121 Shell Scripting a Bunco Game.md --- .../20180121 Shell Scripting a Bunco Game.md | 262 ++++++++++++++++++ 1 file changed, 262 insertions(+) create mode 100644 translated/tech/20180121 Shell Scripting a Bunco Game.md diff --git a/translated/tech/20180121 Shell Scripting a Bunco Game.md b/translated/tech/20180121 Shell Scripting a Bunco Game.md new file mode 100644 index 0000000000..ca70dbc7ec --- /dev/null +++ b/translated/tech/20180121 Shell Scripting a Bunco Game.md @@ -0,0 +1,262 @@ + +Shell Scripting a Bunco Game  脚本编程之骰子游戏 +====== +我已经有段时间没有编写游戏了,所以我觉得现在正是做一些这方面事情的时候。起初,我想 " 用脚本编一个Halo? " (Halo:微软的光晕系列游戏),但我后来意识到这不太可能。来编一个叫Bunco的简单骰子游戏。你也许没有听说过,不过你母亲绝对知道 - 当一群年轻女孩聚在当地的酒吧或者小酒馆的时候,这是个很受欢迎的游戏。 + +I haven't dug into any game programming for a while, so I thought it was high time to do something in that realm. At first, I thought "Halo as a shell script?", but then I came to my senses. Instead, let's look at a simple dice game called Bunco. You may not have heard of it, but I bet your Mom has—it's a quite popular game for groups of gals at a local pub or tavern. + +游戏一共六轮,有三个骰子,规则很简单。每次投三个骰子,投出的点数要和当前的轮数数字一致。如果三个骰子都和当前的轮数一致,(比如,在第三轮三个骰子都是3),你这一轮的分数就是21。 如果三个骰子点数都相同但和轮数数字不同,你会得到最低的Bunco分数,只有5分。如果你投出的点数两者都不是,每一个和当前轮数相同的骰子得1分。 + + +要想玩这个游戏,它还涉及到团队合作,每一队(包括赢得那队),每人付5美元现金,或赢家得到其他类似现金奖励,并规定什么样的情况下才是赢家,例如"most Buncos" or "most points"胜利。在这里我会跳过这些,而只关注投骰子这一部分。 + + +### 关于数学逻辑部分 + +在专注于编程这方面的事之前,我先简单说说游戏背后的数学逻辑。要是有一个适当重量的骰子投骰子会变得很容易,任意一个值出现概率都是 1/6。 + + +完全随机小提示:不确定你的骰子是否每个面都是一样重量? 把它们扔进盐水里然后转一下。YouTube上,有很多科学界的有趣视频向你展示怎么来做这个测试。 + + +所以三个骰子点数一样的几率有多大? 第一个骰子100%会有一个值 (这儿没什么可说的),所以很简单。第二个则有16.66%的概率和第一个骰子的值一样,接下来第三个骰子也是一样。 但当然,总概率是三个概率相乘的结果,所以最后,三个骰子值相等的概率是2.7%。 + + + +接下来,每个骰子和当前轮数数字相同的概率都是16.66%。从数学角度来说:0.166 * 0.166 * 0.166 = 0.00462。 + + +换句话说,你有0.46%的可能性投出Bunco,比200次中出现一次的可能性还小一点。 + + +实际上还可以更难。如果你有5个骰子,投出 Mini Bunco (也可以叫做Yahtzee) 的概率为0.077%,如果你想所有的骰子的值都相同,假设都是6,那概率就是0.00012%,那就基本上没什么可能了。 + + +### 开始编程吧 + +和所有游戏一样,最难的部分是有一个能生成随机数的随机数发生器。这一部分在shell 脚本中还是很难实现的,所以我需要一步步来,并假设shell内置的随机数发生器就够用了 + +不过好在内置的随机数发生器很好用。用 $RANDOM 就能得到一个0到MAXINT(32767)之间的随机值: + +``` + +$ echo $RANDOM $RANDOM $RANDOM +10252 22142 14863 + +``` + +为了确保产生的值一定是 1-6之中的某个值,使用取余函数: + + +``` + +$ echo $(( $RANDOM % 6 )) +3 +$ echo $(( $RANDOM % 6 )) +0 + +``` + +哦!我忘了要加1,下面是另一次尝试: + + +``` + +$ echo $(( ( $RANDOM % 6 ) + 1 )) +6 + +``` + +下面要实现投骰子这一功能。这个函数中你可以声明一个局部变量来存储生成的随机值: + + +``` + +rolldie() +{ + local result=$1 + rolled=$(( ( $RANDOM % 6 ) + 1 )) + eval $result=$rolled +} + +``` + +使用 eval 确保生成的随机数被实际存储在变量中。这一部分也很容易: + +``` + +rolldie die1 + +``` + +这会为第一个骰子生成一个1-6之中的值。要为3个骰子都生成值,执行3次上面的函数: + + +``` + +rolldie die1 ; rolldie die2 ; rolldie die3 + +``` + +现在判断下生成的值。首先,判断是不是Bunco(3个骰子值相同),然后是不是和当前轮数值也相同: + + +``` + +if [ $die1 -eq $die2 ] && [ $die2 -eq $die3 ] ; then + if [ $die1 -eq $round ] ; then + echo "BUNCO!" + score=25 + else + echo "Mini Bunco!" + score=5 + fi + +``` + +这可能是所有判断语句中最难的部分了,注意第一个条件语句中这种不常用的写法 : [ cond1 ] && [ cond2 ]。如果你想写成 cond1 -a cond2 ,这样也可以。在shell编程中,解决问题的方法往往不止一种。 + + +代码剩下的部分很直白,你只需要判断每个骰子的值是不是和本轮数字相同: + + +``` + +if [ $die1 -eq $round ] ; then + score=1 +fi +if [ $die2 -eq $round ] ; then + score=$(( $score + 1 )) +fi +if [ $die3 -eq $round ] ; then + score=$(( $score + 1 )) +fi + +``` + +唯一要注意的是当出现 Bunco/Mini Bunco 就不需要再统计本轮分数了。所以整个第二部分的判断语句都要写在第一个条件语句的else中(为了判断3个骰子值是否都相同)。 + + + +把所有的综合起来,然后在命令行中输入轮数,下面是现在的脚本执行后的结果: + + +``` + +$ sh bunco.sh 5 +You rolled: 1 1 5 +score = 1 +$ sh bunco.sh 2 +You rolled: 6 4 3 +score = 0 +$ sh bunco.sh 1 +You rolled: 1 1 1 +BUNCO! +score = 25 + +``` + +竟然这么快就出现 Bunco 了? 好吧,就像我说的,shell内置的随机数发生器在随机数产生这方面可能有些问题。 + + + +你可以执行脚本几百次,从而让你的脚本得以正确运行,然后看看Bunco/Mini Bunco出现次数所占的百分比。但是我想把这部分作为练习,留给亲爱的读者你们。不过,也许我下次会抽时间完成剩下的部分。 + + +让我们完成这一脚本吧,还有分数统计和一次性执行6次投骰子(这次不用再在命令行中手动输入当前轮数了)这两个功能。这也很容易,因为只是将上面的内容整个嵌套在里面,换句话说,就是将一个复杂的条件嵌套结构全部写在了一个函数中: + + +``` + +BuncoRound() +{ + # roll, display, and score a round of bunco! + # round is specified when invoked, score added to totalscore + + local score=0 ; local round=$1 ; local hidescore=0 + + rolldie die1 ; rolldie die2 ; rolldie die3 + echo Round $round. You rolled: $die1 $die2 $die3 + + if [ $die1 -eq $die2 ] && [ $die2 -eq $die3 ] ; then + if [ $die1 -eq $round ] ; then + echo " BUNCO!" + score=25 + hidescore=1 + else + echo " Mini Bunco!" + score=5 + hidescore=1 + fi + else + if [ $die1 -eq $round ] ; then + score=1 + fi + if [ $die2 -eq $round ] ; then + score=$(( $score + 1 )) + fi + if [ $die3 -eq $round ] ; then + score=$(( $score + 1 )) + fi + fi + + if [ $hidescore -eq 0 ] ; then + echo " score this round: $score" + fi + + totalscore=$(( $totalscore + $score )) +} + +``` + +我承认,我忍不住自己做了一点改进,包括判断当前是Bunco, Mini Bunco 还是其他需要计算分数的情况这一部分 (这就是$hidescore这一变量的作用). + + +实现这个简直是小菜一碟,只要一个循环就好了: + +``` + +for round in {1..6} ; do + BuncoRound $round +done + +``` + +这就是现在所写的整个程序。让我们执行一下看看结果: + +``` + +$ sh bunco.sh 1 +Round 1\. You rolled: 2 3 3 + score this round: 0 +Round 2\. You rolled: 2 6 6 + score this round: 1 +Round 3\. You rolled: 1 2 4 + score this round: 0 +Round 4\. You rolled: 2 1 4 + score this round: 1 +Round 5\. You rolled: 5 5 6 + score this round: 2 +Round 6\. You rolled: 2 1 3 + score this round: 0 +Game over. Your total score was 4 + +``` + +嗯。并不是很令人满意,可能是因为它只是游戏的一次完整执行。不过,你可以将脚本执行几百几千次,记下"Game over"出现的位置,然后用一些快速分析工具来看看你在每6轮中有几次得分超过3分。(要让3个骰子值相同,这个概率大概在50%左右)。 + +无论怎么说,这都不是一个复杂的游戏,但是它是一个很有意思的小程序项目。现在,如果有一个20面的骰子,每一轮游戏有好几十轮,每轮都掷同一个骰子,情况又会发生什么变化呢? + + + +-------------------------------------------------------------------------------- + +via: http://www.linuxjournal.com/content/shell-scripting-bunco-game + +作者:[Dave Taylor][a] +译者:[译者ID](https://github.com/译者ID) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:http://www.linuxjournal.com/users/dave-taylor From 90306c0eb193c6a462b1ca6d0fb557679f726410 Mon Sep 17 00:00:00 2001 From: wenwensnow <963555237@qq.com> Date: Sun, 28 Jan 2018 23:41:07 +0800 Subject: [PATCH 013/272] Update 20180121 Shell Scripting a Bunco Game.md --- translated/tech/20180121 Shell Scripting a Bunco Game.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/translated/tech/20180121 Shell Scripting a Bunco Game.md b/translated/tech/20180121 Shell Scripting a Bunco Game.md index ca70dbc7ec..c12e9f2315 100644 --- a/translated/tech/20180121 Shell Scripting a Bunco Game.md +++ b/translated/tech/20180121 Shell Scripting a Bunco Game.md @@ -1,9 +1,8 @@ Shell Scripting a Bunco Game  脚本编程之骰子游戏 ====== -我已经有段时间没有编写游戏了,所以我觉得现在正是做一些这方面事情的时候。起初,我想 " 用脚本编一个Halo? " (Halo:微软的光晕系列游戏),但我后来意识到这不太可能。来编一个叫Bunco的简单骰子游戏。你也许没有听说过,不过你母亲绝对知道 - 当一群年轻女孩聚在当地的酒吧或者小酒馆的时候,这是个很受欢迎的游戏。 +我已经有段时间没有编写游戏了,所以我觉得现在正是做一些这方面事情的时候。起初,我想 " 用脚本编一个Halo? " (Halo:光晕系列游戏),但我后来意识到这不太可能。来编一个叫Bunco的简单骰子游戏。你也许没有听说过,不过你母亲绝对知道 - 当一群年轻女孩聚在当地的酒吧或者小酒馆的时候,这是个很受欢迎的游戏。 -I haven't dug into any game programming for a while, so I thought it was high time to do something in that realm. At first, I thought "Halo as a shell script?", but then I came to my senses. Instead, let's look at a simple dice game called Bunco. You may not have heard of it, but I bet your Mom has—it's a quite popular game for groups of gals at a local pub or tavern. 游戏一共六轮,有三个骰子,规则很简单。每次投三个骰子,投出的点数要和当前的轮数数字一致。如果三个骰子都和当前的轮数一致,(比如,在第三轮三个骰子都是3),你这一轮的分数就是21。 如果三个骰子点数都相同但和轮数数字不同,你会得到最低的Bunco分数,只有5分。如果你投出的点数两者都不是,每一个和当前轮数相同的骰子得1分。 From d4583c407c5c4052e8648abde4d2fded56b5f3a7 Mon Sep 17 00:00:00 2001 From: wenwensnow <963555237@qq.com> Date: Sun, 28 Jan 2018 23:41:58 +0800 Subject: [PATCH 014/272] Update 20180121 Shell Scripting a Bunco Game.md --- translated/tech/20180121 Shell Scripting a Bunco Game.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/translated/tech/20180121 Shell Scripting a Bunco Game.md b/translated/tech/20180121 Shell Scripting a Bunco Game.md index c12e9f2315..4e6401eca1 100644 --- a/translated/tech/20180121 Shell Scripting a Bunco Game.md +++ b/translated/tech/20180121 Shell Scripting a Bunco Game.md @@ -1,5 +1,4 @@ - -Shell Scripting a Bunco Game  脚本编程之骰子游戏 + 脚本编程之骰子游戏 ====== 我已经有段时间没有编写游戏了,所以我觉得现在正是做一些这方面事情的时候。起初,我想 " 用脚本编一个Halo? " (Halo:光晕系列游戏),但我后来意识到这不太可能。来编一个叫Bunco的简单骰子游戏。你也许没有听说过,不过你母亲绝对知道 - 当一群年轻女孩聚在当地的酒吧或者小酒馆的时候,这是个很受欢迎的游戏。 @@ -7,7 +6,7 @@ Shell Scripting a Bunco Game  脚本编程之骰子游戏 游戏一共六轮,有三个骰子,规则很简单。每次投三个骰子,投出的点数要和当前的轮数数字一致。如果三个骰子都和当前的轮数一致,(比如,在第三轮三个骰子都是3),你这一轮的分数就是21。 如果三个骰子点数都相同但和轮数数字不同,你会得到最低的Bunco分数,只有5分。如果你投出的点数两者都不是,每一个和当前轮数相同的骰子得1分。 -要想玩这个游戏,它还涉及到团队合作,每一队(包括赢得那队),每人付5美元现金,或赢家得到其他类似现金奖励,并规定什么样的情况下才是赢家,例如"most Buncos" or "most points"胜利。在这里我会跳过这些,而只关注投骰子这一部分。 +要想玩这个游戏,它还涉及到团队合作,每一队(包括赢得那队),每人付5美元现金,或赢家得到其他类似现金奖励,并规定什么样的情况下才是赢家,例如"most Buncos" or "most points"的情况下胜利。在这里我会跳过这些,而只关注投骰子这一部分。 ### 关于数学逻辑部分 From a044c85beddfd36ddba6843c74e7f4a8d28d0908 Mon Sep 17 00:00:00 2001 From: wenwensnow <963555237@qq.com> Date: Sun, 28 Jan 2018 23:44:04 +0800 Subject: [PATCH 015/272] Delete 20180121 Shell Scripting a Bunco Game.md --- .../20180121 Shell Scripting a Bunco Game.md | 262 ------------------ 1 file changed, 262 deletions(-) delete mode 100644 sources/tech/20180121 Shell Scripting a Bunco Game.md diff --git a/sources/tech/20180121 Shell Scripting a Bunco Game.md b/sources/tech/20180121 Shell Scripting a Bunco Game.md deleted file mode 100644 index ca70dbc7ec..0000000000 --- a/sources/tech/20180121 Shell Scripting a Bunco Game.md +++ /dev/null @@ -1,262 +0,0 @@ - -Shell Scripting a Bunco Game  脚本编程之骰子游戏 -====== -我已经有段时间没有编写游戏了,所以我觉得现在正是做一些这方面事情的时候。起初,我想 " 用脚本编一个Halo? " (Halo:微软的光晕系列游戏),但我后来意识到这不太可能。来编一个叫Bunco的简单骰子游戏。你也许没有听说过,不过你母亲绝对知道 - 当一群年轻女孩聚在当地的酒吧或者小酒馆的时候,这是个很受欢迎的游戏。 - -I haven't dug into any game programming for a while, so I thought it was high time to do something in that realm. At first, I thought "Halo as a shell script?", but then I came to my senses. Instead, let's look at a simple dice game called Bunco. You may not have heard of it, but I bet your Mom has—it's a quite popular game for groups of gals at a local pub or tavern. - -游戏一共六轮,有三个骰子,规则很简单。每次投三个骰子,投出的点数要和当前的轮数数字一致。如果三个骰子都和当前的轮数一致,(比如,在第三轮三个骰子都是3),你这一轮的分数就是21。 如果三个骰子点数都相同但和轮数数字不同,你会得到最低的Bunco分数,只有5分。如果你投出的点数两者都不是,每一个和当前轮数相同的骰子得1分。 - - -要想玩这个游戏,它还涉及到团队合作,每一队(包括赢得那队),每人付5美元现金,或赢家得到其他类似现金奖励,并规定什么样的情况下才是赢家,例如"most Buncos" or "most points"胜利。在这里我会跳过这些,而只关注投骰子这一部分。 - - -### 关于数学逻辑部分 - -在专注于编程这方面的事之前,我先简单说说游戏背后的数学逻辑。要是有一个适当重量的骰子投骰子会变得很容易,任意一个值出现概率都是 1/6。 - - -完全随机小提示:不确定你的骰子是否每个面都是一样重量? 把它们扔进盐水里然后转一下。YouTube上,有很多科学界的有趣视频向你展示怎么来做这个测试。 - - -所以三个骰子点数一样的几率有多大? 第一个骰子100%会有一个值 (这儿没什么可说的),所以很简单。第二个则有16.66%的概率和第一个骰子的值一样,接下来第三个骰子也是一样。 但当然,总概率是三个概率相乘的结果,所以最后,三个骰子值相等的概率是2.7%。 - - - -接下来,每个骰子和当前轮数数字相同的概率都是16.66%。从数学角度来说:0.166 * 0.166 * 0.166 = 0.00462。 - - -换句话说,你有0.46%的可能性投出Bunco,比200次中出现一次的可能性还小一点。 - - -实际上还可以更难。如果你有5个骰子,投出 Mini Bunco (也可以叫做Yahtzee) 的概率为0.077%,如果你想所有的骰子的值都相同,假设都是6,那概率就是0.00012%,那就基本上没什么可能了。 - - -### 开始编程吧 - -和所有游戏一样,最难的部分是有一个能生成随机数的随机数发生器。这一部分在shell 脚本中还是很难实现的,所以我需要一步步来,并假设shell内置的随机数发生器就够用了 - -不过好在内置的随机数发生器很好用。用 $RANDOM 就能得到一个0到MAXINT(32767)之间的随机值: - -``` - -$ echo $RANDOM $RANDOM $RANDOM -10252 22142 14863 - -``` - -为了确保产生的值一定是 1-6之中的某个值,使用取余函数: - - -``` - -$ echo $(( $RANDOM % 6 )) -3 -$ echo $(( $RANDOM % 6 )) -0 - -``` - -哦!我忘了要加1,下面是另一次尝试: - - -``` - -$ echo $(( ( $RANDOM % 6 ) + 1 )) -6 - -``` - -下面要实现投骰子这一功能。这个函数中你可以声明一个局部变量来存储生成的随机值: - - -``` - -rolldie() -{ - local result=$1 - rolled=$(( ( $RANDOM % 6 ) + 1 )) - eval $result=$rolled -} - -``` - -使用 eval 确保生成的随机数被实际存储在变量中。这一部分也很容易: - -``` - -rolldie die1 - -``` - -这会为第一个骰子生成一个1-6之中的值。要为3个骰子都生成值,执行3次上面的函数: - - -``` - -rolldie die1 ; rolldie die2 ; rolldie die3 - -``` - -现在判断下生成的值。首先,判断是不是Bunco(3个骰子值相同),然后是不是和当前轮数值也相同: - - -``` - -if [ $die1 -eq $die2 ] && [ $die2 -eq $die3 ] ; then - if [ $die1 -eq $round ] ; then - echo "BUNCO!" - score=25 - else - echo "Mini Bunco!" - score=5 - fi - -``` - -这可能是所有判断语句中最难的部分了,注意第一个条件语句中这种不常用的写法 : [ cond1 ] && [ cond2 ]。如果你想写成 cond1 -a cond2 ,这样也可以。在shell编程中,解决问题的方法往往不止一种。 - - -代码剩下的部分很直白,你只需要判断每个骰子的值是不是和本轮数字相同: - - -``` - -if [ $die1 -eq $round ] ; then - score=1 -fi -if [ $die2 -eq $round ] ; then - score=$(( $score + 1 )) -fi -if [ $die3 -eq $round ] ; then - score=$(( $score + 1 )) -fi - -``` - -唯一要注意的是当出现 Bunco/Mini Bunco 就不需要再统计本轮分数了。所以整个第二部分的判断语句都要写在第一个条件语句的else中(为了判断3个骰子值是否都相同)。 - - - -把所有的综合起来,然后在命令行中输入轮数,下面是现在的脚本执行后的结果: - - -``` - -$ sh bunco.sh 5 -You rolled: 1 1 5 -score = 1 -$ sh bunco.sh 2 -You rolled: 6 4 3 -score = 0 -$ sh bunco.sh 1 -You rolled: 1 1 1 -BUNCO! -score = 25 - -``` - -竟然这么快就出现 Bunco 了? 好吧,就像我说的,shell内置的随机数发生器在随机数产生这方面可能有些问题。 - - - -你可以执行脚本几百次,从而让你的脚本得以正确运行,然后看看Bunco/Mini Bunco出现次数所占的百分比。但是我想把这部分作为练习,留给亲爱的读者你们。不过,也许我下次会抽时间完成剩下的部分。 - - -让我们完成这一脚本吧,还有分数统计和一次性执行6次投骰子(这次不用再在命令行中手动输入当前轮数了)这两个功能。这也很容易,因为只是将上面的内容整个嵌套在里面,换句话说,就是将一个复杂的条件嵌套结构全部写在了一个函数中: - - -``` - -BuncoRound() -{ - # roll, display, and score a round of bunco! - # round is specified when invoked, score added to totalscore - - local score=0 ; local round=$1 ; local hidescore=0 - - rolldie die1 ; rolldie die2 ; rolldie die3 - echo Round $round. You rolled: $die1 $die2 $die3 - - if [ $die1 -eq $die2 ] && [ $die2 -eq $die3 ] ; then - if [ $die1 -eq $round ] ; then - echo " BUNCO!" - score=25 - hidescore=1 - else - echo " Mini Bunco!" - score=5 - hidescore=1 - fi - else - if [ $die1 -eq $round ] ; then - score=1 - fi - if [ $die2 -eq $round ] ; then - score=$(( $score + 1 )) - fi - if [ $die3 -eq $round ] ; then - score=$(( $score + 1 )) - fi - fi - - if [ $hidescore -eq 0 ] ; then - echo " score this round: $score" - fi - - totalscore=$(( $totalscore + $score )) -} - -``` - -我承认,我忍不住自己做了一点改进,包括判断当前是Bunco, Mini Bunco 还是其他需要计算分数的情况这一部分 (这就是$hidescore这一变量的作用). - - -实现这个简直是小菜一碟,只要一个循环就好了: - -``` - -for round in {1..6} ; do - BuncoRound $round -done - -``` - -这就是现在所写的整个程序。让我们执行一下看看结果: - -``` - -$ sh bunco.sh 1 -Round 1\. You rolled: 2 3 3 - score this round: 0 -Round 2\. You rolled: 2 6 6 - score this round: 1 -Round 3\. You rolled: 1 2 4 - score this round: 0 -Round 4\. You rolled: 2 1 4 - score this round: 1 -Round 5\. You rolled: 5 5 6 - score this round: 2 -Round 6\. You rolled: 2 1 3 - score this round: 0 -Game over. Your total score was 4 - -``` - -嗯。并不是很令人满意,可能是因为它只是游戏的一次完整执行。不过,你可以将脚本执行几百几千次,记下"Game over"出现的位置,然后用一些快速分析工具来看看你在每6轮中有几次得分超过3分。(要让3个骰子值相同,这个概率大概在50%左右)。 - -无论怎么说,这都不是一个复杂的游戏,但是它是一个很有意思的小程序项目。现在,如果有一个20面的骰子,每一轮游戏有好几十轮,每轮都掷同一个骰子,情况又会发生什么变化呢? - - - --------------------------------------------------------------------------------- - -via: http://www.linuxjournal.com/content/shell-scripting-bunco-game - -作者:[Dave Taylor][a] -译者:[译者ID](https://github.com/译者ID) -校对:[校对者ID](https://github.com/校对者ID) - -本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 - -[a]:http://www.linuxjournal.com/users/dave-taylor From e3c2adcdb4c1c08ac9aa4bf7ab5f6584a04f28b5 Mon Sep 17 00:00:00 2001 From: wxy Date: Sun, 28 Jan 2018 23:51:57 +0800 Subject: [PATCH 016/272] PRF&PUB:20171112 Love Your Bugs.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @yixunx 翻译的很棒!https://linux.cn/article-9289-1.html --- .../20171112 Love Your Bugs.md | 52 ++++++++----------- 1 file changed, 21 insertions(+), 31 deletions(-) rename {translated/tech => published}/20171112 Love Your Bugs.md (97%) diff --git a/translated/tech/20171112 Love Your Bugs.md b/published/20171112 Love Your Bugs.md similarity index 97% rename from translated/tech/20171112 Love Your Bugs.md rename to published/20171112 Love Your Bugs.md index 9203cf52bb..acc421da53 100644 --- a/translated/tech/20171112 Love Your Bugs.md +++ b/published/20171112 Love Your Bugs.md @@ -15,19 +15,17 @@ 好,让我们直接来看第一个 bug。这是我在 Dropbox 工作时遇到的一个 bug。你们或许听说过,Dropbox 是一个将你的文件从一个电脑上同步到云端和其他电脑上的应用。 - - ``` +--------------+ +---------------+ | | | | - | METASERVER | | BLOCKSERVER | + | 元数据服务器 | | 块服务器 | | | | | +-+--+---------+ +---------+-----+ ^ | ^ | | | | | +----------+ | | +---> | | | - | | CLIENT +--------+ + | | 客户端 +--------+ +--------+ | +----------+ ``` @@ -79,7 +77,7 @@ l \x0c < $ ( . - ``` -英文逗号的 ASCII 码是44。`l` 的 ASCII 码是 108。它们的二进制表示如下: +英文逗号的 ASCII 码是 44。`l` 的 ASCII 码是 108。它们的二进制表示如下: ``` bin(ord(',')): 0101100 @@ -101,8 +99,7 @@ $ : 0100100 - : 0101101 ``` - -### 位反转是真的! +#### 位反转是真的! 我爱这个 bug 因为它证明了位反转是可能真实发生的事情,而不只是一个理论上的问题。实际上,它在某些情况下会比平时更容易发生。其中一种情况是用户使用的是低配或者老旧的硬件,而运行 Dropbox 的电脑很多都是这样。另外一种会造成很多位反转的地方是外太空——在太空中没有大气层来保护你的内存不受高能粒子和辐射的影响,所以位反转会十分常见。 @@ -110,31 +107,31 @@ $ : 0100100 在刚才那种情况下,Dropbox 并不需要处理位反转。出现内存损坏的是用户的电脑,所以即使我们可以检测到逗号字符的位反转,但如果这发生在其他字符上我们就不一定能检测到了,而且如果从硬盘中读取的文件本身发生了位反转,那我们根本无从得知。我们能改进的地方很少,于是我们决定无视这个异常并继续程序的运行。这种 bug 一般都会在客户端重启之后自动解决。 -### 不常见的 bug 并非不可能发生 +#### 不常见的 bug 并非不可能发生 这是我最喜欢的 bug 之一,有几个原因。第一,它提醒我注意不常见和不可能之间的区别。当规模足够大的时候,不常见的现象会以值得注意的频率发生。 -### 覆盖面广的 bug +#### 覆盖面广的 bug 这个 bug 第二个让我喜欢的地方是它覆盖面非常广。每当桌面客户端和服务器交流的时候,这个 bug 都可能悄然出现,而这可能会发生在系统里很多不同的端点和组件当中。这意味着许多不同的 Dropbox 工程师会看到这个 bug 的各种版本。你第一次看到它的时候,你 _真的_ 会满头雾水,但在那之后诊断这个 bug 就变得很容易了,而调查过程也非常简短:你只需找到中间的字母,看它是不是个 `l`。 -### 文化差异 +#### 文化差异 这个 bug 的一个有趣的副作用是它展示了服务器组和客户端组之间的文化差异。有时候这个 bug 会被服务器组的成员发现并展开调查。如果你的 _服务器_ 上发生了位反转,那应该不是个偶然——这很可能是内存损坏,你需要找到受影响的主机并尽快把它从集群中移除,不然就会有损坏大量用户数据的风险。这是个事故,而你必须迅速做出反应。但如果是用户的电脑在破坏数据,你并没有什么可以做的。 -### 分享你的 bug +#### 分享你的 bug 如果你在调试一个难搞的 bug,特别是在大型系统中,不要忘记跟别人讨论。也许你的同事以前就遇到过类似的 bug。若是如此,你可能会节省很多时间。就算他们没有见过,也不要忘记在你解决了问题之后告诉他们解决方法——写下来或者在组会中分享。这样下次你们组遇到类似的问题时,你们都会早有准备。 ### Bug 如何帮助你进步 -### Recurse Center +#### Recurse Center 在加入 Dropbox 之前,我曾在 Recurse Center 工作。它的理念是建立一个社区让正在自学的程序员们聚到一起来提高能力。这就是 Recurse Center 的全部了:我们没有大纲、作业、截止日期等等。唯一的前提条件是我们都想要成为更好的程序员。参与者中有的人有计算机学位但对自己的实际编程能力不够自信,有的人已经写了十年 Java 但想学 Clojure 或者 Haskell,还有各式各样有着其他的背景的参与者。 我在那里是一位导师,帮助人们更好地利用这个自由的环境,并参考我们从以前的参与者那里学到的东西来提供指导。所以我的同事们和我本人都非常热衷于寻找对成年自学者最有帮助的学习方法。 -### 刻意练习 +#### 刻意练习 在学习方法这个领域有很多不同的研究,其中我觉得最有意思的研究之一是刻意练习的概念。刻意练习理论意在解释专业人士和业余爱好者的表现的差距。它的基本思想是如果你只看内在的特征——不论先天与否——它们都无法非常好地解释这种差距。于是研究者们,包括最初的 Ericsson、Krampe 和 Tesch-Romer,开始寻找能够解释这种差距的理论。他们最终的答案是在刻意练习上所花的时间。 @@ -189,18 +186,15 @@ $ : 0100100 所有这些 bug 都很容易修复。前两个 bug 出在客户端上,所以我们在 alpha 版本修复了它们,但大部分的客户端还没有获得这些改动。我们在服务器代码中修复了第三个 bug 并部署了新版的服务器。 -### 📈 +#### 📈 突然日志服务器集群的流量开始激增。客服团队找到我们并问我们是否知道原因。我花了点时间把所有的部分拼到一起。 在修复之前,这四件事情会发生: 1. 日志文件从最早的开始发送 - 2. 日志文件从最新的开始删除 - 3. 如果服务器无法解码日志文件,它会返回 500 - 4. 如果客户端收到 500,它会停止发送日志 一个存有损坏的日志文件的客户端会试着发送这个文件,服务器会返回 500,客户端会放弃发送日志。在下一次运行时,它会尝试再次发送同样的文件,再次失败,并再次放弃。最终日志目录会被填满,然后客户端会开始删除最新的日志文件,而把损坏的文件继续保留在硬盘上。 @@ -209,27 +203,27 @@ $ : 0100100 问题是,处于这种状态的客户端比我们想象的要多很多。任何有一个损坏文件的客户端都会像被关在堤坝里一样,无法再发送日志。现在这个堤坝被清除了,所有这些客户端都开始发送它们的日志目录的剩余内容。 -### 我们的选择 +#### 我们的选择 -好的,现在文件从世界各地的电脑如洪水般涌来。我们能做什么?(当你在一个有 Dropbox 这种规模,尤其是这种桌面客户端的规模的公司工作时,会遇到这种有趣的事情:你可以非常轻易地对自己造成 DDOS 攻击)。 +好的,现在文件从世界各地的电脑如洪水般涌来。我们能做什么?(当你在一个有 Dropbox 这种规模,尤其是这种桌面客户端的规模的公司工作时,会遇到这种有趣的事情:你可以非常轻易地对自己造成 DDoS 攻击)。 当你部署的新版本发生问题时,第一个选项是回滚。这是非常合理的选择,但对于这个问题,它无法帮助我们。我们改变的不是服务器的状态而是客户端的——我们删除了那些出错文件。将服务器回滚可以防止更多客户端进入这种状态,但它并不能解决根本问题。 -那扩大日志集群的规模呢?我们试过了——然后因为处理能力增加了,我们开始收到更多的请求。我们又扩大了一次,但你不可能一直这么下去。为什么不能?因为这个集群并不是独立的。它会向另一个集群发送请求,在这里是为了处理异常。如果你的一个集群正在被 DDOS,而你持续扩大那个集群,你最终会把它依赖的集群也弄坏,然后你就有两个问题了。 +那扩大日志集群的规模呢?我们试过了——然后因为处理能力增加了,我们开始收到更多的请求。我们又扩大了一次,但你不可能一直这么下去。为什么不能?因为这个集群并不是独立的。它会向另一个集群发送请求,在这里是为了处理异常。如果你的一个集群正在被 DDoS,而你持续扩大那个集群,你最终会把它依赖的集群也弄坏,然后你就有两个问题了。 我们考虑过的另一个选择是减低负载——你不需要每一个日志文件,所以我们可以直接无视一些请求。一个难点是我们并没有一个很好的方法来区分好的请求和坏的请求。我们无法快速地判断哪些日志文件是旧的,哪些是新的。 我们最终使用的是一个 Dropbox 里许多不同场合都用过的一个解决方法:我们有一个自定义的头字段,`chillout`,全世界所有的客户端都遵守它。如果客户端收到一个有这个头字段的响应,它将在字段所标注的时间内不再发送任何请求。很早以前一个英明的程序员把它加到了 Dropbox 客户端里,在之后这些年中它已经不止一次地起了作用。 -### 了解你的系统 +#### 了解你的系统 这个 bug 的第一个教训是要了解你的系统。我对于客户端和服务器之间的交互有不错的理解,但我并没有考虑到当服务器和所有这些客户端同时交互的时候会发生什么。这是一个我没有完全搞懂的层面。 -### 了解你的工具 +#### 了解你的工具 第二个教训是要了解你的工具。如果出了差错,你有哪些选项?你能撤销你做的迁移吗?你如何知道事情出了差错,你又如何发现更多信息?所有这些事情都应该在危机发生之前就了解好——但如果你没有,你会在危机发生时学到它们并不会再忘记。 -### 功能开关 & 服务器端功能控制 +#### 功能开关 & 服务器端功能控制 第三个教训是专门针对移动端和桌面应用开发者的:_你需要服务器端功能控制和功能开关_。当你发现一个问题时如果你没有服务器端的功能控制,你可能需要几天或几星期来推送新版本或者提交新版本到应用商店中,然后问题才能得到解决。这是个很糟糕的处境。Dropbox 桌面客户端不需要经过应用商店的审查过程,但光是把一个版本推送给上千万的用户就已经要花很多时间。相比之下,如果你能在新功能遇到问题的时候在服务器上翻转一个开关:十分钟之后你的问题就已经解决了。 @@ -237,7 +231,7 @@ $ : 0100100 但是它的好处——啊,当你需要它的时候,你真的是很需要它。 -# 如何去爱 bug +### 如何去爱 bug 我讲了几个我爱的 bug,也讲了为什么要爱 bug。现在我想告诉你如何去爱 bug。如果你现在还不爱 bug,我知道唯一一种改变的方法,那就是要有成长型心态。 @@ -261,7 +255,7 @@ Dweck 发现一个人看待智力的方式——固定型还是成长型心态 这些发现表明成长型心态对 debug 至关重要。我们必须从从困惑中重整旗鼓,诚实地面对我们理解上的不足,并时不时地在寻找答案的路上努力奋斗——成长型心态会让这些都变得更简单而且不那么痛苦。 -### 热爱你的 bug +#### 热爱你的 bug 我在 Recurse Center 工作时会直白地欢迎挑战,我就是这样学会热爱我的 bug 的。有时参与者会坐到我身边说“唉,我觉得我遇到了个奇怪的 Python bug”,然后我会说“太棒了,我 _爱_ 奇怪的 Python bug!” 首先,这百分之百是真的,但更重要的是,我这样是在对参与者强调,找到让自己觉得困难的事情是一种成就,而他们做到了这一点,这是件好事。 @@ -274,22 +268,18 @@ Dweck 发现一个人看待智力的方式——固定型还是成长型心态 在此向给我的演讲提出反馈以及给我的演讲提供其他帮助的人士表示感谢: * Sasha Laundy - * Amy Hanlon - * Julia Evans - * Julian Cooper - * Raphael Passini Diniz 以及其他的 Python Brasil 组织团队成员 -------------------------------------------------------------------------------- via: http://akaptur.com/blog/2017/11/12/love-your-bugs/ -作者:[Allison Kaptur ][a] +作者:[Allison Kaptur][a] 译者:[yixunx](https://github.com/yixunx) -校对:[校对者ID](https://github.com/校对者ID) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 From 1951913c045c8f740abdb74ba4cd3ed0750bf87d Mon Sep 17 00:00:00 2001 From: hopefully2333 <787016457@qq.com> Date: Mon, 29 Jan 2018 01:04:32 +0800 Subject: [PATCH 017/272] Update 20180106 Meltdown and Spectre Linux Kernel Status.md --- ...eltdown and Spectre Linux Kernel Status.md | 73 +++++++++---------- 1 file changed, 36 insertions(+), 37 deletions(-) diff --git a/translated/tech/20180106 Meltdown and Spectre Linux Kernel Status.md b/translated/tech/20180106 Meltdown and Spectre Linux Kernel Status.md index d98fddad78..b261ff85c9 100644 --- a/translated/tech/20180106 Meltdown and Spectre Linux Kernel Status.md +++ b/translated/tech/20180106 Meltdown and Spectre Linux Kernel Status.md @@ -1,89 +1,88 @@ -translated by hopefully2333 -Meltdown and Spectre Linux Kernel Status +meltdown 和 spectre 影响下的 Linux 内核状况 ============================================================ -By now, everyone knows that something “big” just got announced regarding computer security. Heck, when the [Daily Mail does a report on it][1] , you know something is bad… +截止到目前为止,每个人都知道一件关乎电脑安全的“大事”发生了,真见鬼,等每日邮报报道的时候,你就知道什么是糟糕了... -Anyway, I’m not going to go into the details about the problems being reported, other than to point you at the wonderfully written [Project Zero paper on the issues involved here][2]. They should just give out the 2018 [Pwnie][3] award right now, it’s that amazingly good. +不管怎样,我不打算去跟进这个问题被报道出来的细节,除了告诉你问题涉及范围内的精彩的零日文章,他们应该直接发布 2018 的 Pwnie award 奖,这非常好。 -If you do want technical details for how we are resolving those issues in the kernel, see the always awesome [lwn.net writeup for the details][4]. +如果你想了解我们如何在内核中解决这些问题的技术细节,你可以持续关注了不起的 lwn.net,他们会把这些细节写成文章。 -Also, here’s a good summary of [lots of other postings][5] that includes announcements from various vendors. +以此同时,很多的厂商发出了相关的公告,这有一条很好的关于这些公告的摘要。 -As for how this was all handled by the companies involved, well this could be described as a textbook example of how  _NOT_  to interact with the Linux kernel community properly. The people and companies involved know what happened, and I’m sure it will all come out eventually, but right now we need to focus on fixing the issues involved, and not pointing blame, no matter how much we want to. +至于这些涉及的公司是如何处理这些问题的,这可以说是如何适当的与 Linux 内核社区保持距离的教科书般的例子。这件事涉及到的人和公司都知道发生了什么,我确定这件事最终会出现,但是目前我需要去关注的是如何修复这些涉及到的问题,然后不要去点名指责,不管我有多么的想去这么做。 -### What you can do right now +### 你现在能做什么 -If your Linux systems are running a normal Linux distribution, go update your kernel. They should all have the updates in them already. And then keep updating them over the next few weeks, we are still working out lots of corner case bugs given that the testing involved here is complex given the huge variety of systems and workloads this affects. If your distro does not have kernel updates, then I strongly suggest changing distros right now. +如果你的 Linux 系统正在运行一个正常的 Linux 分布式系统,那么升级你的内核。它们都应该已经更新了,然后在接下来的几个星期里保持更新。我们会统计大量在极端情况下出现的 bug ,这个情况的测试范围是复杂的,包括庞大的受影响的各种各样的系统和工作量。如果你的 Linux 发行版没有内核升级,我坚决的建议你马上更换你使用的 Linux 发行版。 -However there are lots of systems out there that are not running “normal” Linux distributions for various reasons (rumor has it that it is way more than the “traditional” corporate distros). They rely on the LTS kernel updates, or the normal stable kernel updates, or they are in-house franken-kernels. For those people here’s the status of what is going on regarding all of this mess in the upstream kernels you can use. +然而有很多的系统因为各种各样的原因(它们比起相对“传统”的公司的分布式系统更加特殊)不是在运行“正常的”Linux 分布式系统。它们依靠长期支持版本的内核升级,或者是正常稳定的内核升级,或者是内部的 franken-kernels。对于这部分人,这个状况是在你能使用的上游的内核中关于这个混乱正在发生的。 ### Meltdown – x86 -Right now, Linus’s kernel tree contains all of the fixes we currently know about to handle the Meltdown vulnerability for the x86 architecture. Go enable the CONFIG_PAGE_TABLE_ISOLATION kernel build option, and rebuild and reboot and all should be fine. +现在,Linux 内核树包含所有我们当前知道的为 x86 架构解决 meltdown 漏洞的修复。去开启 CONFIG_PAGE_TABLE_ISOLATION 这个内核构建选项,然后进行重构和重启,所有的设备应该就安全了。 -However, Linus’s tree is currently at 4.15-rc6 + some outstanding patches. 4.15-rc7 should be out tomorrow, with those outstanding patches to resolve some issues, but most people do not run a -rc kernel in a “normal” environment. +然而,Linux 的代码树分支在 4.15-rc6 这个版本加上一些出色的补丁。4.15-rc7 版本要明天才会推出,里面的一些补丁会解决一些问题。但是大部分的人不会运行 -rc kernel 在一个“正常”的环境里。 -Because of this, the x86 kernel developers have done a wonderful job in their development of the page table isolation code, so much so that the backport to the latest stable kernel, 4.14, has been almost trivial for me to do. This means that the latest 4.14 release (4.14.12 at this moment in time), is what you should be running. 4.14.13 will be out in a few more days, with some additional fixes in it that are needed for some systems that have boot-time problems with 4.14.12 (it’s an obvious problem, if it does not boot, just add the patches now queued up.) +因为这个原因,x86 内核开发者在页表隔离代码开发过程中做了一个非常好的工作,好到以至于移植到了最新推出的稳定内核,4.14,对我们要做的事而言几乎是微不足道的了。这意味着最新的 4.14版本(现在是 4.14.12 版本),是你应该正在运行的版本,4.14.13 会在接下来的几天里推出,这个更新里有一些额外的修复补丁,这些补丁是一些运行 4.14.12 内核且有启动时间问题(这是一个显而易见的问题,如果它不启动,手动把这些补丁加入更新排队中)的系统所需要的。 -I would personally like to thank Andy Lutomirski, Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, Peter Zijlstra, Josh Poimboeuf, Juergen Gross, and Linus Torvalds for all of the work they have done in getting these fixes developed and merged upstream in a form that was so easy for me to consume to allow the stable releases to work properly. Without that effort, I don’t even want to think about what would have happened. +我个人要去感谢 Andy Lutomirski, Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, Peter Zijlstra, Josh Poimboeuf, Juergen Gross, 和 Linus Torvalds。他们开发出了这些修复补丁,并且为了让我们能简单地更新到稳定版本来正常工作,还把这些补丁用一张表单融合到了上游分支里。没有这些工作,我甚至不会想要去思考到底发生了什么。 -For the older long term stable (LTS) kernels, I have leaned heavily on the wonderful work of Hugh Dickins, Dave Hansen, Jiri Kosina and Borislav Petkov to bring the same functionality to the 4.4 and 4.9 stable kernel trees. I had also had immense help from Guenter Roeck, Kees Cook, Jamie Iles, and many others in tracking down nasty bugs and missing patches. I want to also call out David Woodhouse, Eduardo Valentin, Laura Abbott, and Rik van Riel for their help with the backporting and integration as well, their help was essential in numerous tricky places. +对于老的长期支持内核,我大量地依靠 Hugh Dickins, Dave Hansen, Jiri Kosina 和 Borislav Petkov 优秀的工作所带来的针对 4.4 到 4.9 稳定内核代码树分支的相同功能。我同样在追踪讨厌的bug和缺失的补丁方面从 Guenter Roeck, Kees Cook, Jamie Iles,以及其他很多人那里得到了极大的帮助。我要感谢 David Woodhouse, Eduardo Valentin, Laura Abbott, 和 Rik van Riel 在反向移植和集成方面的帮助,他们的帮助在许多棘手的地方是必不可少的。 -These LTS kernels also have the CONFIG_PAGE_TABLE_ISOLATION build option that should be enabled to get complete protection. +这些长期支持版本的内核同样有 CONFIG_PAGE_TABLE_ISOLATION 这个内核构建选项,你应该开启它来获得全方面的保护。 -As this backport is very different from the mainline version that is in 4.14 and 4.15, there are different bugs happening, right now we know of some VDSO issues that are getting worked on, and some odd virtual machine setups are reporting strange errors, but those are the minority at the moment, and should not stop you from upgrading at all right now. If you do run into problems with these releases, please let us know on the stable kernel mailing list. +主要版本 4.14 和 4.15 的移植是非常不一样的,他们会出现不同的 bug,我们现在知道了一些在工作中遇见的 VDSO 上的问题。一些特殊的虚拟机安装的时候会报一些奇怪的错,但这是只是现在出现的少部分情况,这中情况不会阻止你进行全部的升级,请让我们在稳定内核邮件列表中知道这件事。 -If you rely on any other kernel tree other than 4.4, 4.9, or 4.14 right now, and you do not have a distribution supporting you, you are out of luck. The lack of patches to resolve the Meltdown problem is so minor compared to the hundreds of other known exploits and bugs that your kernel version currently contains. You need to worry about that more than anything else at this moment, and get your systems up to date first. +如果你依赖 4.4 和 4.9 以外的内核代码树分支或是现在的 4.14,并且没有分布式支持你的话,你就太不幸了。比起你当前版本内核包含的上百个已知的漏洞和 bug,缺少补丁去解决 meltdown 问题算是一个小问题了。你现在最需要考虑的就是马上把你的系统升级到最新。 -Also, go yell at the people who forced you to run an obsoleted and insecure kernel version, they are the ones that need to learn that doing so is a totally reckless act. +以此同时,臭骂那些强迫你运行一个已被废弃且不安全的内核版本的人,他们是那些需要知道这是完全不顾后果的行为的人中的一份子。 ### Meltdown – ARM64 -Right now the ARM64 set of patches for the Meltdown issue are not merged into Linus’s tree. They are [staged and ready to be merged][6] into 4.16-rc1 once 4.15 is released in a few weeks. Because these patches are not in a released kernel from Linus yet, I can not backport them into the stable kernel releases (hey, we have [rules][7] for a reason…) +现在 ARM64 为解决 Meltdown 问题而开发的补丁还没有并入 Linux 的代码树分支,一旦 4.15 在接下来的几周里成功发布,他们就准备阶段式地并入 4.16-rc1,因为这些补丁还没有在一个已发布的 Linux 内核中,我不能把它们移植进一个稳定的内核版本里(额。。我们有这个规矩是有原因的) -Due to them not being in a released kernel, if you rely on ARM64 for your systems (i.e. Android), I point you at the [Android Common Kernel tree][8] All of the ARM64 fixes have been merged into the [3.18,][9] [4.4,][10] and [4.9 branches][11] as of this point in time. +由于它们还没有在一个已发布的内核版本中,如果你的系统是用的 ARM64 的芯片(例如 Android ),我建议你在现在所有并入 3.18,4.4 和 4.9 分支的 ARM64 补丁中选择 Android 公共内核代码树分支。 -I would strongly recommend just tracking those branches as more fixes get added over time due to testing and things catch up with what gets merged into the upstream kernel releases over time, especially as I do not know when these patches will land in the stable and LTS kernel releases at this point in time. +我强烈建议你关注这些分支,看随着时间的过去,由于测试了已并入补丁的已发布的上游内核版本,会不会有更多的修复补丁被补充进来,特别是我不知道这些补丁会在什么时候加进稳定的长期支持内核版本里。 -For the 4.4 and 4.9 LTS kernels, odds are these patches will never get merged into them, due to the large number of prerequisite patches required. All of those prerequisite patches have been long merged and tested in the android-common kernels, so I think it is a better idea to just rely on those kernel branches instead of the LTS release for ARM systems at this point in time. +对于 4.4 到 4.9 的长期支持内核版本,这些补丁有很大概率永远不会并入它们,因为需要大量的依赖性补丁。而所有的这些依赖性补丁长期以来都一直在 Android 公共内核版本中测试和合并,所以我认为现在对于 ARM 系统来说,仅仅依赖这些内核分支而不是长期支持的发行版是一个更好的主意。 -Also note, I merge all of the LTS kernel updates into those branches usually within a day or so of being released, so you should be following those branches no matter what, to ensure your ARM systems are up to date and secure. +同样需要注意的是,我合并所有的长期支持内核版本的更新到这些分支后通常会在一天之内或者这个时间点左右进行发布,所以你无论如何都要关注这些分支,来确保你的 ARM 系统是最新且安全的。 ### Spectre -Now things get “interesting”… +现在,事情变得“有趣”了... -Again, if you are running a distro kernel, you  _might_  be covered as some of the distros have merged various patches into them that they claim mitigate most of the problems here. I suggest updating and testing for yourself to see if you are worried about this attack vector +再一次,如果你正在运行一个发行版的内核。一些内核融入了各种各样的声称能缓解目前大部分问题的补丁,你的内核可能就被包含在其中。如果你担心这一类的攻击的话,我建议你更新并测试看看。 -For upstream, well, the status is there is no fixes merged into any upstream tree for these types of issues yet. There are numerous patches floating around on the different mailing lists that are proposing solutions for how to resolve them, but they are under heavy development, some of the patch series do not even build or apply to any known trees, the series conflict with each other, and it’s a general mess. +对于上游来说,很好,现状就是仍然没有任何的上游代码树分支有合并这些类型的问题相关的修复补丁。有很多的邮件列表在讨论如何去解决这些问题的解决方案,大量的补丁在这些邮件列表中广为流传,但是它们被压在了沉重的开发下,一些补丁系列甚至没有被构建或者应用到任何已知的代码树,这些系列彼此之间相互冲突,这是常见的混乱。 -This is due to the fact that the Spectre issues were the last to be addressed by the kernel developers. All of us were working on the Meltdown issue, and we had no real information on exactly what the Spectre problem was at all, and what patches were floating around were in even worse shape than what have been publicly posted. +这是由于 Spectre 问题是最近被内核开发者解决的。我们所有人都在 Meltdown 问题上工作,我们没有精确的 Spectre 问题全部的真实信息,也没有比公开发布更糟糕的情形下什么补丁会广为流传的的真实信息。 -Because of all of this, it is going to take us in the kernel community a few weeks to resolve these issues and get them merged upstream. The fixes are coming in to various subsystems all over the kernel, and will be collected and released in the stable kernel updates as they are merged, so again, you are best off just staying up to date with either your distribution’s kernel releases, or the LTS and stable kernel releases. +因为所有的这些原因,我们打算在内核社区里花上几个星期去解决这些问题并把它们合并到内核中去。修复补丁会进入到所有内核的各种各样的子系统中,而且在它们被合并后,会集成并在稳定内核的更新中发布,所以再次提醒,你最好是在你使用的内核发行版和长期支持稳定的内核发行版中选择一个并保持更新到最新版。 -It’s not the best news, I know, but it’s reality. If it’s any consolation, it does not seem that any other operating system has full solutions for these issues either, the whole industry is in the same boat right now, and we just need to wait and let the developers solve the problem as quickly as they can. +这不是最好的新闻,我知道,但是这就是现实。如果它是任意的安慰的话,它就不会显得其他的操作系统也为这些问题准备了完整的解决方案,现在整个产业都在同一条船上,我们只需要等待,并让开发者尽他们所能快地解决这些问题。 -The proposed solutions are not trivial, but some of them are amazingly good. The [Retpoline][12] post from Paul Turner is an example of some of the new concepts being created to help resolve these issues. This is going to be an area of lots of research over the next years to come up with ways to mitigate the potential problems involved in hardware that wants to try to predict the future before it happens. +计划解决方案已经不重要了,但是它们中的一些还是非常好的。一些新概念会被创造出来来帮助解决这些问题,Paul Turner 提出的 Retpoline 方法就是其中的一个例子。这将是未来大量研究的一个领域,想出方法去减轻硬件中涉及的潜在问题,想在它发生前就去预言它。 -### Other arches +### 其他的 arches 芯片 -Right now, I have not seen patches for any other architectures than x86 and arm64\. There are rumors of patches floating around in some of the enterprise distributions for some of the other processor types, and hopefully they will surface in the weeks to come to get merged properly upstream. I have no idea when that will happen, if you are dependant on a specific architecture, I suggest asking on the arch-specific mailing list about this to get a straight answer. +现在,我没有看见任何 x86 和 arm64 架构以外的芯片架构的补丁,有一些谣传的补丁在一些企业为其他类型的处理器准备的分配方案中广为流传。希望他们在这几周里能在表面上适当地合并到开发者那里,这件事发生的时候我不知道,如果你使用着一个特殊的架构,我建议在 arch-specific 邮件列表上问这件事来得到一个直接的回答。 -### Conclusion +### 结论 -Again, update your kernels, don’t delay, and don’t stop. The updates to resolve these problems will be continuing to come for a long period of time. Also, there are still lots of other bugs and security issues being resolved in the stable and LTS kernel releases that are totally independent of these types of issues, so keeping up to date is always a good idea. +再次,更新你的内核,不要耽搁,不要停止。更新会在很长的一段时间里持续地解决这些问题。同样的,稳定和长期支持内核发行版里仍然有很多其他的bug和安全问题,他们和问题的类型无关,所以一直保持更新始终是一个好主意。 -Right now, there are a lot of very overworked, grumpy, sleepless, and just generally pissed off kernel developers working as hard as they can to resolve these issues that they themselves did not cause at all. Please be considerate of their situation right now. They need all the love and support and free supply of their favorite beverage that we can provide them to ensure that we all end up with fixed systems as soon as possible. +现在,这里有很多非常劳累、坏脾气、缺少睡眠的人,他们通常会生气地让内核开发人员竭尽全力地解决这些问题,即使这些问题完全不是他们自己造成的。请关爱这些可怜的程序猿。他们需要爱、支持和我们可以为他们免费提供的他们最爱的饮料,以此来确保我们都可以尽可能快地结束修补系统。 -------------------------------------------------------------------------------- via: http://kroah.com/log/blog/2018/01/06/meltdown-status/ 作者:[Greg Kroah-Hartman ][a] -译者:[译者ID](https://github.com/译者ID) +译者:[hopefully2333](https://github.com/hopefully2333) 校对:[校对者ID](https://github.com/校对者ID) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 From ab4252f9cec6676f68cab37c383e9f2bad62077c Mon Sep 17 00:00:00 2001 From: geekpi Date: Mon, 29 Jan 2018 09:44:30 +0800 Subject: [PATCH 018/272] translated --- ...to install Spotify application on Linux.md | 103 ------------------ ...to install Spotify application on Linux.md | 101 +++++++++++++++++ 2 files changed, 101 insertions(+), 103 deletions(-) delete mode 100644 sources/tech/20180119 How to install Spotify application on Linux.md create mode 100644 translated/tech/20180119 How to install Spotify application on Linux.md diff --git a/sources/tech/20180119 How to install Spotify application on Linux.md b/sources/tech/20180119 How to install Spotify application on Linux.md deleted file mode 100644 index 3050e36199..0000000000 --- a/sources/tech/20180119 How to install Spotify application on Linux.md +++ /dev/null @@ -1,103 +0,0 @@ -translating---geekpi - -How to install Spotify application on Linux -====== - -How do I install Spotify app on Ubuntu Linux desktop to stream music? - -Spotify is a digital music stream service that provides you access to tons of songs. You can stream for free or buy a subscription. Creating a playlist is possible. A subscriber can listen music ad-free. You get better sound quality. This page **shows how to install Spotify on Linux using a snap package manager that works on Ubuntu, Mint, Debian, Fedora, Arch and many other distros**. - -### Installing spotify application on Linux - -The procedure to install spotify on Linux is as follows: - -1. Install snapd -2. Turn on snapd -3. Find Spotify snap: -``` -snap find spotify -``` -4. Install spotify music app: -``` -do snap install spotify -``` -5. Run it: -``` -spotify & -``` - -Let us see all steps and examples in details. - -### Step 1 - Install Snapd - -You need to install snapd package. It is daemon (service) and tooling that enable snap packages on Linux operating system. - -#### Snapd on a Debian/Ubuntu/Mint Linux - -Type the following [apt command][1]/[apt-get command][2] as follows: -`$ sudo apt install snapd` - -#### Install snapd on an Arch Linux - -snapd is available in the Arch User Repository (AUR) only. Run yaourt command (see [how to install yaourt on Archlinux][3]): -``` -$ sudo yaourt -S snapd -$ sudo systemctl enable --now snapd.socket -``` - -#### Get snapd on a Fedora Linux - -Run snapd command -``` -sudo dnf install snapd -sudo ln -s /var/lib/snapd/snap /snap -``` - -#### OpenSUSE install snapd - -Execute the snap command: -`$ snap find spotify` -[![snap search for spotify app command][4]][4] -Install it: -`$ sudo snap install spotify` -[![How to install Spotify application on Linux using snap command][5]][5] - -### Step 3 - Run spotify and enjoy it(译注:原博客中就是这么直接跳到step3的) - -Run it from GUI or simply type: -`$ spotify` -Automatically sign in to your account on startup: -``` -$ spotify --username vivek@nixcraft.com -$ spotify --username vivek@nixcraft.com --password 'myPasswordHere' -``` -Start spotify client with given URI when initialized: -`$ spotify--uri=` -Start with the specified URL: -`$ spotify--url=` -[![Spotify client app running on my Ubuntu Linux desktop][6]][6] - -### About the author - -The author is the creator of nixCraft and a seasoned sysadmin and a trainer for the Linux operating system/Unix shell scripting. He has worked with global clients and in various industries, including IT, education, defense and space research, and the nonprofit sector. Follow him on [Twitter][7], [Facebook][8], [Google+][9]. - --------------------------------------------------------------------------------- - -via: https://www.cyberciti.biz/faq/how-to-install-spotify-application-on-linux/ - -作者:[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/ubuntu-lts-debian-linux-apt-command-examples/ (See Linux/Unix apt command examples for more info) -[2]:https://www.cyberciti.biz/tips/linux-debian-package-management-cheat-sheet.html (See Linux/Unix apt-get command examples for more info) -[3]:https://www.cyberciti.biz/faq/how-to-install-yaourt-in-arch-linux/ -[4]:https://www.cyberciti.biz/media/new/faq/2018/01/snap-search-for-spotify-app-command.jpg -[5]:https://www.cyberciti.biz/media/new/faq/2018/01/How-to-install-Spotify-application-on-Linux-using-snap-command.jpg -[6]:https://www.cyberciti.biz/media/new/faq/2018/01/Spotify-client-app-running-on-my-Ubuntu-Linux-desktop.jpg -[7]:https://twitter.com/nixcraft -[8]:https://facebook.com/nixcraft -[9]:https://plus.google.com/+CybercitiBiz diff --git a/translated/tech/20180119 How to install Spotify application on Linux.md b/translated/tech/20180119 How to install Spotify application on Linux.md new file mode 100644 index 0000000000..9b348401c1 --- /dev/null +++ b/translated/tech/20180119 How to install Spotify application on Linux.md @@ -0,0 +1,101 @@ +如何在 Linux 上安装 Spotify +====== + +如何在 Ubuntu Linux 桌面上安装 Spotify 来在线听音乐? + +Spotify 是一个可让你访问大量歌曲的数字音乐流服务。你可以免费收听或者购买订阅。可以创建播放列表。订阅用户可以免广告收听音乐。你会得到更好的音质。本教程**展示如何使用在 Ubuntu、Mint、Debian、Fedora、Arch 和其他更多发行版**上的 snap 包管理器安装 Spotify。 + +### 在 Linux 上安装 spotify + +在 Linux 上安装 spotify 的步骤如下: + +1. 安装 snapd +2. 打开 snapd +3. 找到 Spotify snap: +``` +snap find spotify +``` +4. 安装 spotify: +``` +do snap install spotify +``` +5. 运行: +``` +spotify & +``` + +让我们详细看看所有的步骤和例子。 + +### 步骤 1 - 安装 Snapd + +你需要安装 snapd 包。它是一个守护进程(服务),并能在 Linux 系统上启用 snap 包管理。 + +#### Debian/Ubuntu/Mint Linux 上的 Snapd + +输入以下[ apt 命令][1]/ [apt-get 命令][2]: +`$ sudo apt install snapd` + +#### 在 Arch Linux 上安装 snapd + +snapd 只包含在 Arch User Repository(AUR)中。运行 yaourt 命令(参见[如何在 Archlinux 上安装 yaourt][3]): +``` +$ sudo yaourt -S snapd +$ sudo systemctl enable --now snapd.socket +``` + +#### 在 Fedora 上获取 snapd + +运行 snapd 命令 +``` +sudo dnf install snapd +sudo ln -s /var/lib/snapd/snap /snap +``` + +#### OpenSUSE 安装 snapd + +执行 snap 命令: +`$ snap find spotify` +[![snap search for spotify app command][4]][4] +安装它: +`$ sudo snap install spotify` +[![How to install Spotify application on Linux using snap command][5]][5] + +### 步骤 3 - 运行 spotify 并享受它(译注:原博客中就是这么直接跳到 step3 的) + +从 GUI 运行它,或者只需输入: +`$ spotify` +在启动时自动登录你的帐户: +``` +$ spotify --username vivek@nixcraft.com +$ spotify --username vivek@nixcraft.com --password 'myPasswordHere' +``` +在初始化时使用给定的 URI 启动 Spotify 客户端: +`$ spotify--uri=` +以指定的网址启动: +`$ spotify--url=` +[![Spotify client app running on my Ubuntu Linux desktop][6]][6] + +### 关于作者 + +作者是 nixCraft 的创建者,是经验丰富的系统管理员,也是 Linux 操作系统/Unix shell 脚本的培训师。他曾与全球客户以及 IT、教育、国防和太空研究以及非营利部门等多个行业合作。在 [Twitter][7]、[Facebook][8]、[Google +][9] 上关注他。 + +-------------------------------------------------------------------------------- + +via: https://www.cyberciti.biz/faq/how-to-install-spotify-application-on-linux/ + +作者:[Vivek Gite][a] +译者:[geekpi](https://github.com/geekpi) +校对:[校对者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/ubuntu-lts-debian-linux-apt-command-examples/ (See Linux/Unix apt command examples for more info) +[2]:https://www.cyberciti.biz/tips/linux-debian-package-management-cheat-sheet.html (See Linux/Unix apt-get command examples for more info) +[3]:https://www.cyberciti.biz/faq/how-to-install-yaourt-in-arch-linux/ +[4]:https://www.cyberciti.biz/media/new/faq/2018/01/snap-search-for-spotify-app-command.jpg +[5]:https://www.cyberciti.biz/media/new/faq/2018/01/How-to-install-Spotify-application-on-Linux-using-snap-command.jpg +[6]:https://www.cyberciti.biz/media/new/faq/2018/01/Spotify-client-app-running-on-my-Ubuntu-Linux-desktop.jpg +[7]:https://twitter.com/nixcraft +[8]:https://facebook.com/nixcraft +[9]:https://plus.google.com/+CybercitiBiz From 262e56979d729df2ceef859e30f764215e3500d9 Mon Sep 17 00:00:00 2001 From: geekpi Date: Mon, 29 Jan 2018 09:50:23 +0800 Subject: [PATCH 019/272] translating --- ... 3 Essential Questions to Ask at Your Next Tech Interview.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sources/tech/20171203 3 Essential Questions to Ask at Your Next Tech Interview.md b/sources/tech/20171203 3 Essential Questions to Ask at Your Next Tech Interview.md index 891ef48948..174d6cd9d3 100644 --- a/sources/tech/20171203 3 Essential Questions to Ask at Your Next Tech Interview.md +++ b/sources/tech/20171203 3 Essential Questions to Ask at Your Next Tech Interview.md @@ -1,3 +1,5 @@ +translating-----geekpi + 3 Essential Questions to Ask at Your Next Tech Interview ====== ![](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/os-jobs_0.jpg?itok=nDf5j7xC) From c912fb40d1be6fb5e416f8f4e9fb242c6c7cc63b Mon Sep 17 00:00:00 2001 From: qhwdw Date: Mon, 29 Jan 2018 10:22:20 +0800 Subject: [PATCH 020/272] Translating by qhwdw --- .../tech/20170111 When Does Your OS Run.md | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 sources/tech/20170111 When Does Your OS Run.md diff --git a/sources/tech/20170111 When Does Your OS Run.md b/sources/tech/20170111 When Does Your OS Run.md new file mode 100644 index 0000000000..10d0801b14 --- /dev/null +++ b/sources/tech/20170111 When Does Your OS Run.md @@ -0,0 +1,51 @@ +Translating by qhwdw [When Does Your OS Run?][1] +============================================================ + +Here's a question: in the time it takes you to read this sentence, has your OS been running? Or was it only your browser? Or were they perhaps both idle, just waiting for you to do something already? + +These questions are simple but they cut through the essence of how software works. To answer them accurately we need a good mental model of OS behavior, which in turn informs performance, security, and troubleshooting decisions. We'll build such a model in this post series using Linux as the primary OS, with guest appearances by OS X and Windows. I'll link to the Linux kernel sources for those who want to delve deeper. + +The fundamental axiom here is that at any given moment, exactly one task is active on a CPU. The task is normally a program, like your browser or music player, or it could be an operating system thread, but it is one task. Not two or more. Never zero, either. One. Always. + +This sounds like trouble. For what if, say, your music player hogs the CPU and doesn't let any other tasks run? You would not be able to open a tool to kill it, and even mouse clicks would be futile as the OS wouldn't process them. You could be stuck blaring "What does the fox say?" and incite a workplace riot. + +That's where interrupts come in. Much as the nervous system interrupts the brain to bring in external stimuli - a loud noise, a touch on the shoulder - the [chipset][2] in a computer's motherboard interrupts the CPU to deliver news of outside events - key presses, the arrival of network packets, the completion of a hard drive read, and so on. Hardware peripherals, the interrupt controller on the motherboard, and the CPU itself all work together to implement these interruptions, called interrupts for short. + +Interrupts are also essential in tracking that which we hold dearest: time. During the [boot process][3] the kernel programs a hardware timer to issue timer interrupts at a periodic interval, for example every 10 milliseconds. When the timer goes off, the kernel gets a shot at the CPU to update system statistics and take stock of things: has the current program been running for too long? Has a TCP timeout expired? Interrupts give the kernel a chance to both ponder these questions and take appropriate actions. It's as if you set periodic alarms throughout the day and used them as checkpoints: should I be doing what I'm doing right now? Is there anything more pressing? One day you find ten years have got behind you. + +These periodic hijackings of the CPU by the kernel are called ticks, so interrupts quite literally make your OS tick. But there's more: interrupts are also used to handle some software events like integer overflows and page faults, which involve no external hardware. Interrupts are the most frequent and crucial entry point into the OS kernel. They're not some oddity for the EE people to worry about, they're the mechanism whereby your OS runs. + +Enough talk, let's see some action. Below is a network card interrupt in an Intel Core i5 system. The diagrams now have image maps, so you can click on juicy bits for more information. For example, each device links to its Linux driver. + +![](https://manybutfinite.com/img/os/hardware-interrupt.png) + +Let's take a look at this. First off, since there are many sources of interrupts, it wouldn't be very helpful if the hardware simply told the CPU "hey, something happened!" and left it at that. The suspense would be unbearable. So each device is assigned an interrupt request line, or IRQ, during power up. These IRQs are in turn mapped into interrupt vectors, a number between 0 and 255, by the interrupt controller. By the time an interrupt reaches the CPU it has a nice, well-defined number insulated from the vagaries of hardware. + +The CPU in turn has a pointer to what's essentially an array of 255 functions, supplied by the kernel, where each function is the handler for that particular interrupt vector. We'll look at this array, the Interrupt Descriptor Table (IDT), in more detail later on. + +Whenever an interrupt arrives, the CPU uses its vector as an index into the IDT and runs the appropriate handler. This happens as a special function call that takes place in the context of the currently running task, allowing the OS to respond to external events quickly and with minimal overhead. So web servers out there indirectly call a function in your CPU when they send you data, which is either pretty cool or terrifying. Below we show a situation where a CPU is busy running a Vim command when an interrupt arrives: + +![](https://manybutfinite.com/img/os/vim-interrupted.png) + +Notice how the interrupt's arrival causes a switch to kernel mode and [ring zero][4] but it does not change the active task. It's as if Vim made a magic function call straight into the kernel, but Vim is still there, its [address space][5] intact, waiting for that call to return. + +Exciting stuff! Alas, I need to keep this post-sized, so let's finish up for now. I understand we have not answered the opening question and have in fact opened up new questions, but you now suspect ticks were taking place while you read that sentence. We'll find the answers as we flesh out our model of dynamic OS behavior, and the browser scenario will become clear. If you have questions, especially as the posts come out, fire away and I'll try to answer them in the posts themselves or as comments. Next installment is tomorrow on [RSS][6] and [Twitter][7]. + +-------------------------------------------------------------------------------- + +via:https://manybutfinite.com/post/when-does-your-os-run/ + +作者:[Gustavo Duarte][a] +译者:[译者ID](https://github.com/译者ID) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://manybutfinite.com/about/ +[1]:https://manybutfinite.com/post/when-does-your-os-run/ +[2]:https://manybutfinite.com/post/motherboard-chipsets-memory-map +[3]:https://manybutfinite.com/post/kernel-boot-process +[4]:https://manybutfinite.com/post/cpu-rings-privilege-and-protection +[5]:https://manybutfinite.com/post/anatomy-of-a-program-in-memory +[6]:https://manybutfinite.com/feed.xml +[7]:http://twitter.com/manybutfinite \ No newline at end of file From b733767b55b2dd676019479bbf01001b32a3a63f Mon Sep 17 00:00:00 2001 From: yizhuyan Date: Mon, 29 Jan 2018 14:44:50 +0800 Subject: [PATCH 021/272] Update 20180122 Linux rm Command Explained for Beginners (8 Examples).md Translating by yizhuoyan --- ...122 Linux rm Command Explained for Beginners (8 Examples).md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sources/tech/20180122 Linux rm Command Explained for Beginners (8 Examples).md b/sources/tech/20180122 Linux rm Command Explained for Beginners (8 Examples).md index 5ba87a1b7e..4e5e002754 100644 --- a/sources/tech/20180122 Linux rm Command Explained for Beginners (8 Examples).md +++ b/sources/tech/20180122 Linux rm Command Explained for Beginners (8 Examples).md @@ -1,3 +1,5 @@ +Translating by yizhuoyan + Linux rm Command Explained for Beginners (8 Examples) ====== From c457bbe55375da0838c93de4085eb9a56f206ddb Mon Sep 17 00:00:00 2001 From: Sun Yongfei Date: Mon, 29 Jan 2018 20:22:20 +0800 Subject: [PATCH 022/272] Delete 20180123 What Is bashrc and Why Should You Edit It.md --- ...at Is bashrc and Why Should You Edit It.md | 110 ------------------ 1 file changed, 110 deletions(-) delete mode 100644 sources/tech/20180123 What Is bashrc and Why Should You Edit It.md diff --git a/sources/tech/20180123 What Is bashrc and Why Should You Edit It.md b/sources/tech/20180123 What Is bashrc and Why Should You Edit It.md deleted file mode 100644 index 16d56f64bb..0000000000 --- a/sources/tech/20180123 What Is bashrc and Why Should You Edit It.md +++ /dev/null @@ -1,110 +0,0 @@ -heart4lor translating - -What Is bashrc and Why Should You Edit It -====== - -![](https://www.maketecheasier.com/assets/uploads/2018/01/what-is-bashrc-hero.png) - -There are a number of hidden files tucked away in your home directory. If you run macOS or a popular Linux distribution, you'll see a file named ".bashrc" up near the top of your hidden files. What is bashrc, and why is editing bashrc useful? - -![finder-find-bashrc][1] - -If you run a Unix-based or Unix-like operating system, you likely have bash installed as your default terminal. While many [different shells][2] exist, bash is both the most common and, likely, the most popular. If you don't know what that means, bash interprets your typed input in the Terminal program and runs commands based on your input. It allows for some degree of customization using scripting, which is where bashrc comes in. - -In order to load your preferences, bash runs the contents of the bashrc file at each launch. This shell script is found in each user's home directory. It's used to save and load your terminal preferences and environmental variables. - -Terminal preferences can contain a number of different things. Most commonly, the bashrc file contains aliases that the user always wants available. Aliases allow the user to refer to commands by shorter or alternative names, and can be a huge time-saver for those that work in a terminal regularly. - -![terminal-edit-bashrc-1][3] - -You can edit bashrc in any terminal text editor. We will use `nano` in the following examples. - -To edit bashrc using `nano`, invoke the following command in Terminal: -``` -nano ~/.bashrc -``` - -If you've never edited your bashrc file before, you might find that it's empty. That's fine! If not, you can feel free to put your additions on any line. - -Any changes you make to bashrc will be applied next time you launch terminal. If you want to apply them immediately, run the command below: -``` -source ~/.bashrc -``` - -You can add to bashrc where ever you like, but feel free to use command (proceeded by `#`) to organize your code. - -Edits in bashrc have to follow [bash's scripting format][4]. If you don't know how to script with bash, there are a number of resources you can use online. This guide represents a fairly [comprehensive introduction][5] into the aspects of bashrc that we couldn't mention here. - - **Related** : [How to Run Bash Script as Root During Startup on Linux][6] - -There's a couple of useful tricks you can do to make your terminal experience more efficient and user-friendly. - -### Why should I edit bashrc? - -#### Bash Prompt - -The bash prompt allows you to style up your terminal and have it to show prompts when you run a command. A customized bash prompt can indeed make your work on the terminal more productive and efficient. - -Check out some of the [useful][7] and [interesting][8] bash prompts you can add to your bashrc. - -#### Aliases - -![terminal-edit-bashrc-3][9] - -Aliases can also allow you to access a favored form of a command with a shorthand code. Let's take the command `ls` as an example. By default, `ls` displays the contents of your directory. That's useful, but it's often more useful to know more about the directory, or know the hidden contents of the directory. As such, a common alias is `ll`, which is set to run `ls -lha` or something similar. That will display the most details about files, revealing hidden files and showing file sizes in "human readable" units instead of blocks. - -You'll need to format your aliases like so: -``` -alias ll = "ls -lha" -``` - -Type the text you want to replace on the left, and the command on the right between quotes. You can use to this to create shorter versions of command, guard against common typos, or force a command to always run with your favored flags. You can also circumvent annoying or easy-to-forget syntax with your own preferred shorthand. Here are some of the [commonly used aliases][10] you can add to your bashrc. - -#### Functions - -![terminal-edit-bashrc-2][11] - -In addition to shorthand command names, you can combine multiple commands into a single operation using bash functions. They can get pretty complicated, but they generally follow this syntax: -``` -function_name () { - command_1 - command_2 -} -``` - -The command below combines `mkdir` and `cd`. Typing `md folder_name` creates a directory named "folder_name" in your working directory and navigates into it immediately. -``` -md () { - mkdir -p $1 - cd $1 -} -``` - -The `$1` you see in the function represents the first argument, which is the text you type immediately after the function name. - -### Conclusion - -Unlike some terminal customization tricks, messing with bashrc is fairly straight-forward and low risk. If you mess anything up, you can always delete the bashrc file completely and start over again. Try it out now and you will be amazed at your improved productivity. - --------------------------------------------------------------------------------- - -via: https://www.maketecheasier.com/what-is-bashrc/ - -作者:[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/2018/01/finder-find-bashrc.png (finder-find-bashrc) -[2]:https://www.maketecheasier.com/alternative-linux-shells/ -[3]:https://www.maketecheasier.com/assets/uploads/2018/01/terminal-edit-bashrc-1.png (terminal-edit-bashrc-1) -[4]:http://tldp.org/HOWTO/Bash-Prog-Intro-HOWTO.html -[5]:https://www.digitalocean.com/community/tutorials/an-introduction-to-useful-bash-aliases-and-functions -[6]:https://www.maketecheasier.com/run-bash-script-as-root-during-startup-linux/ (How to Run Bash Script as Root During Startup on Linux) -[7]:https://www.maketecheasier.com/8-useful-and-interesting-bash-prompts/ -[8]:https://www.maketecheasier.com/more-useful-and-interesting-bash-prompts/ -[9]:https://www.maketecheasier.com/assets/uploads/2018/01/terminal-edit-bashrc-3.png (terminal-edit-bashrc-3) -[10]:https://www.maketecheasier.com/install-software-in-various-linux-distros/#aliases -[11]:https://www.maketecheasier.com/assets/uploads/2018/01/terminal-edit-bashrc-2.png (terminal-edit-bashrc-2) From 94255650d3add134630569bf9708e9d3aa30280e Mon Sep 17 00:00:00 2001 From: Sun Yongfei Date: Mon, 29 Jan 2018 20:23:35 +0800 Subject: [PATCH 023/272] translated --- ...at Is bashrc and Why Should You Edit It.md | 110 ++++++++++++++++++ 1 file changed, 110 insertions(+) create mode 100644 translated/tech/20180123 What Is bashrc and Why Should You Edit It.md diff --git a/translated/tech/20180123 What Is bashrc and Why Should You Edit It.md b/translated/tech/20180123 What Is bashrc and Why Should You Edit It.md new file mode 100644 index 0000000000..2e1487bbf7 --- /dev/null +++ b/translated/tech/20180123 What Is bashrc and Why Should You Edit It.md @@ -0,0 +1,110 @@ +什么是 bashrc,为什么要编辑 bashrc +====== + +![](https://www.maketecheasier.com/assets/uploads/2018/01/what-is-bashrc-hero.png) + +你的 home 目录下藏着很多隐藏文件。如果你在运行 macOS 或者主流的 Linux 发行版的话,你就会看见一个名为“.bashrc”的文件靠近隐藏文件列表的上方。那么什么是 bashrc,编辑 bashrc 又有什么用呢? + +![finder-find-bashrc][1] + +如果你运行一个基于 Unix 或者类 Unix 的操作系统,bash 很有可能是作为默认终端被安装的。虽然存在很多[不同的 shell][2],bash 却是最常见或许也是最主流的。如果你不明白那意味着什么,bash 能解释你输入进终端程序的东西,并且基于你的输入来运行命令。它在一定程度上支持使用脚本来定制功能,这时候就要用到 bashrc 了。 + +为了加载你的配置,bash 在每次启动时都会加载 bashrc 文件的内容。每个用户的 home 目录都能有这个 shell 脚本。它用来存储并加载你的终端配置和环境变量。 + +终端配置可以包含很多不同的东西。最常见的,bashrc 文件包含用户想要用的别名。别名允许用户通过更短的名字来指向命令,对于经常在终端下工作的人来说这可是一个省时利器。 + +![terminal-edit-bashrc-1][3] + +你可以在任何终端文本编辑器上编辑 bashrc。在接下来的例子中我们将使用 `nano`。 + +要使用 `nano` 来编辑 bashrc,在终端中调用以下命令: +```bash +nano ~/.bashrc +``` + +如果你之前从没有编辑过 bashrc 的话,你也许会发现它是空的。这没关系!如果不是的话,你可以随意在任一行添加你的配置。 + +你对 bashrc 所做的任何修改将在下一次启动终端时生效。如果你想立刻生效的话,运行下面的命令: + +```bash +source ~/.bashrc +``` + +你可以添加到任何 bashrc 的位置,随意使用命令(通过 `#`)来组织你的代码。 + +编辑 bashrc 需要遵循 [bash 脚本格式][4]。如果你不知道如何用 bash 编写脚本的话,有很多在线资料可供查阅。这是一本相当全面的[介绍指南][5],包含一些我们没能在这里提及的 bashrc 的方面。 + + **相关**: [如何在 Linux 启动时以 root 权限运行 bash 脚本][6] + +有一些有用的小技巧能使你的终端体验将更高效,也更用户友好。 + +### 为什么我要编辑 bashrc ? + +#### Bash 提示符 + +bash 提示符允许你自定义你的终端,并让它在你运行命令时显示提示。自定义的 bash 提示符着实能提高你在终端的工作效率。 + +看看这些即[有用][7]又[有趣][8]的 bash 提示符,你可以把它们添加到你的 bashrc 里。 + +#### 别名 + +![terminal-edit-bashrc-3][9] + +别名也允许你使用简写的代码来执行你想要的某个命令的某种格式。让我们用 `ls` 命令来举个例子吧。`ls` 命令默认显示你目录里的内容。这挺有用的,不过显示目录的更多信息,或者显示目录下的隐藏内容,往往更加有用。因此,有个常见的别名就是 `ll`,用来运行 `ls -lha` 或者其他类似的命令。这样就能显示文件的大部分信息,找出隐藏的文件,并能以“能被人类阅读”的单位显示文件大小,而不是用“块”作为单位。 + +你需要按照下面这样的格式书写别名: + +```bash +alias ll = "ls -lha" +``` + +左边输入你想设置的别名,右边引号里是要执行的命令。你可以用这种方法来创建命令的短版本,防止出现常见的拼写错误,或者让一个命令总是带上你想要的参数来运行。你也可以用你喜欢的缩写来规避讨厌或容易忘记的语法。这是一些[常见的别名的用法][10],你可以添加到你的 bashrc 里。 + +#### 函数 + +![terminal-edit-bashrc-2][11] + +除了缩短命令名,你也可以用 bash 函数组合多个命令到一个操作。这些命令可以很复杂,但是它们大多遵循这种语法: +```bash +function_name () { + command_1 + command_2 +} +``` + +下面的命令组合了 `mkdir` 和 `cd` 命令。输入 `md folder_name` 可以在你的工作目录创建一个名为“folder_name”的目录并立刻导航进入。 +```bash +md () { + mkdir -p $1 + cd $1 +} +``` + +如你所见,函数中的 `$1` 代表第一个参数,就是你在函数名后紧跟着输入的文本。 + +### 总结 + +不像某些自定义终端的方法,变动 bashrc 是非常直接且低风险的。即使你一不小心全搞砸了,你也可以随时删掉 bashrc 文件然后重新来一遍。试试看吧,你会惊叹于你提高的生产力的。 + +-------------------------------------------------------------------------------- + +via: https://www.maketecheasier.com/what-is-bashrc/ + +作者:[Alexander Fox][a] +译者:[heart4lor](https://github.com/heart4lor) +校对:[校对者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/2018/01/finder-find-bashrc.png "finder-find-bashrc" +[2]:https://www.maketecheasier.com/alternative-linux-shells/ +[3]:https://www.maketecheasier.com/assets/uploads/2018/01/terminal-edit-bashrc-1.png "terminal-edit-bashrc-1" +[4]:http://tldp.org/HOWTO/Bash-Prog-Intro-HOWTO.html +[5]:https://www.digitalocean.com/community/tutorials/an-introduction-to-useful-bash-aliases-and-functions +[6]:https://www.maketecheasier.com/run-bash-script-as-root-during-startup-linux/ "How to Run Bash Script as Root During Startup on Linux" +[7]:https://www.maketecheasier.com/8-useful-and-interesting-bash-prompts/ +[8]:https://www.maketecheasier.com/more-useful-and-interesting-bash-prompts/ +[9]:https://www.maketecheasier.com/assets/uploads/2018/01/terminal-edit-bashrc-3.png "terminal-edit-bashrc-3" +[10]:https://www.maketecheasier.com/install-software-in-various-linux-distros/#aliases +[11]:https://www.maketecheasier.com/assets/uploads/2018/01/terminal-edit-bashrc-2.png "terminal-edit-bashrc-2" From 70b050d503d2cfbc10de9735e0b74d75a6f2a7be Mon Sep 17 00:00:00 2001 From: wxy Date: Mon, 29 Jan 2018 20:42:53 +0800 Subject: [PATCH 024/272] =?UTF-8?q?=E6=9B=B4=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- published/20171112 Love Your Bugs.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/published/20171112 Love Your Bugs.md b/published/20171112 Love Your Bugs.md index acc421da53..b983fae177 100644 --- a/published/20171112 Love Your Bugs.md +++ b/published/20171112 Love Your Bugs.md @@ -186,7 +186,7 @@ $ : 0100100 所有这些 bug 都很容易修复。前两个 bug 出在客户端上,所以我们在 alpha 版本修复了它们,但大部分的客户端还没有获得这些改动。我们在服务器代码中修复了第三个 bug 并部署了新版的服务器。 -#### 📈 +#### 激增 突然日志服务器集群的流量开始激增。客服团队找到我们并问我们是否知道原因。我花了点时间把所有的部分拼到一起。 @@ -203,7 +203,7 @@ $ : 0100100 问题是,处于这种状态的客户端比我们想象的要多很多。任何有一个损坏文件的客户端都会像被关在堤坝里一样,无法再发送日志。现在这个堤坝被清除了,所有这些客户端都开始发送它们的日志目录的剩余内容。 -#### 我们的选择 +#### 我们的选择 好的,现在文件从世界各地的电脑如洪水般涌来。我们能做什么?(当你在一个有 Dropbox 这种规模,尤其是这种桌面客户端的规模的公司工作时,会遇到这种有趣的事情:你可以非常轻易地对自己造成 DDoS 攻击)。 From c8913fbbf22a1c62bb712d9b045f11c880be4d14 Mon Sep 17 00:00:00 2001 From: "Xingyu.Wang" Date: Mon, 29 Jan 2018 20:59:10 +0800 Subject: [PATCH 025/272] Revert "Translating by qhwdw" --- .../tech/20170111 When Does Your OS Run.md | 51 ------------------- 1 file changed, 51 deletions(-) delete mode 100644 sources/tech/20170111 When Does Your OS Run.md diff --git a/sources/tech/20170111 When Does Your OS Run.md b/sources/tech/20170111 When Does Your OS Run.md deleted file mode 100644 index 10d0801b14..0000000000 --- a/sources/tech/20170111 When Does Your OS Run.md +++ /dev/null @@ -1,51 +0,0 @@ -Translating by qhwdw [When Does Your OS Run?][1] -============================================================ - -Here's a question: in the time it takes you to read this sentence, has your OS been running? Or was it only your browser? Or were they perhaps both idle, just waiting for you to do something already? - -These questions are simple but they cut through the essence of how software works. To answer them accurately we need a good mental model of OS behavior, which in turn informs performance, security, and troubleshooting decisions. We'll build such a model in this post series using Linux as the primary OS, with guest appearances by OS X and Windows. I'll link to the Linux kernel sources for those who want to delve deeper. - -The fundamental axiom here is that at any given moment, exactly one task is active on a CPU. The task is normally a program, like your browser or music player, or it could be an operating system thread, but it is one task. Not two or more. Never zero, either. One. Always. - -This sounds like trouble. For what if, say, your music player hogs the CPU and doesn't let any other tasks run? You would not be able to open a tool to kill it, and even mouse clicks would be futile as the OS wouldn't process them. You could be stuck blaring "What does the fox say?" and incite a workplace riot. - -That's where interrupts come in. Much as the nervous system interrupts the brain to bring in external stimuli - a loud noise, a touch on the shoulder - the [chipset][2] in a computer's motherboard interrupts the CPU to deliver news of outside events - key presses, the arrival of network packets, the completion of a hard drive read, and so on. Hardware peripherals, the interrupt controller on the motherboard, and the CPU itself all work together to implement these interruptions, called interrupts for short. - -Interrupts are also essential in tracking that which we hold dearest: time. During the [boot process][3] the kernel programs a hardware timer to issue timer interrupts at a periodic interval, for example every 10 milliseconds. When the timer goes off, the kernel gets a shot at the CPU to update system statistics and take stock of things: has the current program been running for too long? Has a TCP timeout expired? Interrupts give the kernel a chance to both ponder these questions and take appropriate actions. It's as if you set periodic alarms throughout the day and used them as checkpoints: should I be doing what I'm doing right now? Is there anything more pressing? One day you find ten years have got behind you. - -These periodic hijackings of the CPU by the kernel are called ticks, so interrupts quite literally make your OS tick. But there's more: interrupts are also used to handle some software events like integer overflows and page faults, which involve no external hardware. Interrupts are the most frequent and crucial entry point into the OS kernel. They're not some oddity for the EE people to worry about, they're the mechanism whereby your OS runs. - -Enough talk, let's see some action. Below is a network card interrupt in an Intel Core i5 system. The diagrams now have image maps, so you can click on juicy bits for more information. For example, each device links to its Linux driver. - -![](https://manybutfinite.com/img/os/hardware-interrupt.png) - -Let's take a look at this. First off, since there are many sources of interrupts, it wouldn't be very helpful if the hardware simply told the CPU "hey, something happened!" and left it at that. The suspense would be unbearable. So each device is assigned an interrupt request line, or IRQ, during power up. These IRQs are in turn mapped into interrupt vectors, a number between 0 and 255, by the interrupt controller. By the time an interrupt reaches the CPU it has a nice, well-defined number insulated from the vagaries of hardware. - -The CPU in turn has a pointer to what's essentially an array of 255 functions, supplied by the kernel, where each function is the handler for that particular interrupt vector. We'll look at this array, the Interrupt Descriptor Table (IDT), in more detail later on. - -Whenever an interrupt arrives, the CPU uses its vector as an index into the IDT and runs the appropriate handler. This happens as a special function call that takes place in the context of the currently running task, allowing the OS to respond to external events quickly and with minimal overhead. So web servers out there indirectly call a function in your CPU when they send you data, which is either pretty cool or terrifying. Below we show a situation where a CPU is busy running a Vim command when an interrupt arrives: - -![](https://manybutfinite.com/img/os/vim-interrupted.png) - -Notice how the interrupt's arrival causes a switch to kernel mode and [ring zero][4] but it does not change the active task. It's as if Vim made a magic function call straight into the kernel, but Vim is still there, its [address space][5] intact, waiting for that call to return. - -Exciting stuff! Alas, I need to keep this post-sized, so let's finish up for now. I understand we have not answered the opening question and have in fact opened up new questions, but you now suspect ticks were taking place while you read that sentence. We'll find the answers as we flesh out our model of dynamic OS behavior, and the browser scenario will become clear. If you have questions, especially as the posts come out, fire away and I'll try to answer them in the posts themselves or as comments. Next installment is tomorrow on [RSS][6] and [Twitter][7]. - --------------------------------------------------------------------------------- - -via:https://manybutfinite.com/post/when-does-your-os-run/ - -作者:[Gustavo Duarte][a] -译者:[译者ID](https://github.com/译者ID) -校对:[校对者ID](https://github.com/校对者ID) - -本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 - -[a]:https://manybutfinite.com/about/ -[1]:https://manybutfinite.com/post/when-does-your-os-run/ -[2]:https://manybutfinite.com/post/motherboard-chipsets-memory-map -[3]:https://manybutfinite.com/post/kernel-boot-process -[4]:https://manybutfinite.com/post/cpu-rings-privilege-and-protection -[5]:https://manybutfinite.com/post/anatomy-of-a-program-in-memory -[6]:https://manybutfinite.com/feed.xml -[7]:http://twitter.com/manybutfinite \ No newline at end of file From 9e1cb763b36a3831bd1da0ed59f7f6901a32fa4d Mon Sep 17 00:00:00 2001 From: wxy Date: Mon, 29 Jan 2018 22:10:42 +0800 Subject: [PATCH 026/272] PRF&PUB:20171114 Restore Corrupted USB Drive To Original State In Linux.md @Drshu https://linux.cn/article-9290-1.html --- ...ed USB Drive To Original State In Linux.md | 52 ++++++++----------- 1 file changed, 21 insertions(+), 31 deletions(-) rename {translated/tech => published}/20171114 Restore Corrupted USB Drive To Original State In Linux.md (72%) diff --git a/translated/tech/20171114 Restore Corrupted USB Drive To Original State In Linux.md b/published/20171114 Restore Corrupted USB Drive To Original State In Linux.md similarity index 72% rename from translated/tech/20171114 Restore Corrupted USB Drive To Original State In Linux.md rename to published/20171114 Restore Corrupted USB Drive To Original State In Linux.md index 71aa6d05ec..fd6422e2b9 100644 --- a/translated/tech/20171114 Restore Corrupted USB Drive To Original State In Linux.md +++ b/published/20171114 Restore Corrupted USB Drive To Original State In Linux.md @@ -1,8 +1,6 @@ 在 Linux 上恢复一个损坏的 USB 设备至初始状态 ====== - - ![](http://www.linuxandubuntu.com/uploads/2/1/1/5/21152474/restore-corrupted-usb-drive-to-original-state-in-linux_orig.jpg) 很多时候我们诸如 SD 卡和 U 盘这样的储存器可能会被损坏,并且因此或其他原因不能继续使用。 @@ -13,56 +11,52 @@ [![Linux 系统磁盘管理器](http://www.linuxandubuntu.com/uploads/2/1/1/5/21152474/published/usb.png?1510665746)][1] -警告:接下来的操作会将你设备上的所有数据格式化 +**警告:接下来的操作会将你设备上的所有数据格式化。** +无论是上面提及的什么原因,最终的结果是我们无法继续使用这个设备。 - -无论什么原因,最终的结果是我们无法继续使用这个设备。 - -所以这里是一个恢复一个 USB 设备或者是 SD 卡到出厂状态的方法。 +所以这里有一个恢复 USB 设备或者是 SD 卡到出厂状态的方法。 大多数时候通过文件浏览器进行一次简单格式化可以解决问题,但是在一些极端情况下,比如文件管理器没有作用,而你又需要你的设备可以继续工作时,你可以使用下面的指导: -我们将会使用一个叫做 mkusb 的小工具来实现目标,这个工具的安装非常简单。 +我们将会使用一个叫做 `mkusb` 的小工具来实现目标,这个工具的安装非常简单。 +添加 mkusb 的仓库: +``` +sudo apt add repository ppa:mkusb/ppa +``` +现在更新你的包列表: +``` +sudo apt-get update +``` -1. 添加 mkusb 的仓库 +安装 `mkusb: -`sudo apt add repository ppa:mkusb/ppa` +``` +sudo apt-get install mkusb +``` -2. 现在更新你的包列表 - -`sudo apt-get update` - -3. 安装 mkusb - -`sudo apt-get install mkusb` - -现在运行 mkusb 你将会看到这个提示,点击 ‘Yes’。 +现在运行 `mkusb` 你将会看到这个提示,点击 ‘Yes’。 [![运行 mkusb dus](http://www.linuxandubuntu.com/uploads/2/1/1/5/21152474/editor/run-mkusb.png?1510498592)][2] -现在 mkusb 将会最后一次询问你是否希望继续格式化你的数据,‘Stop’是被默认选择的,你现在选择 ‘Go’并点击‘OK’。 +现在 `mkusb` 将会最后一次询问你是否希望继续格式化你的数据,‘Stop’是被默认选择的,你现在选择 ‘Go’ 并点击 ‘OK’。 [![Linux mkusb](http://www.linuxandubuntu.com/uploads/2/1/1/5/21152474/editor/final-checkpoint_1.png?1510499627)][3] -窗口将会关闭,摒弃人此时你的终端看起来是这样的。 +窗口将会关闭,此时你的终端看起来是这样的。 [![mkusb usb 控制台](http://www.linuxandubuntu.com/uploads/2/1/1/5/21152474/editor/mkusb.png?1510499982)][4] 在几秒钟之后,整个过程将会完成,并且你将看到一个这样的弹出窗口。 - - [![恢复损坏的 USB 设备](http://www.linuxandubuntu.com/uploads/2/1/1/5/21152474/editor/usb_1.png?1510500412)][5] 你现在需要把你的设备从系统推出,然后再重新插进去。你的设备将被恢复成为一个普通设备而且还能像原来一样的工作。 - - [![Linux 磁盘管理器](http://www.linuxandubuntu.com/uploads/2/1/1/5/21152474/editor/usb_2.png?1510500457)][6] 我们现在所做的操作本可以通过终端命令或是 gparted 或者其他的软件来完成,但是那将会需要一些关于分区管理的知识。 @@ -71,23 +65,19 @@ ### 结论 -**mkusb** - -是一个很容易使用的程序,它可以修复你的 USB 储存设备和 SD 卡。mkusb通过 mkusb 的 PPA 来下载。所有在 mkusb 上的操作都需要超级管理员的权限,并且你在这个设备上的所有数据将会被格式化。 +`mkusb` 是一个很容易使用的程序,它可以修复你的 USB 储存设备和 SD 卡。`mkusb` 通过 mkusb 的 PPA 来下载。所有在 `mkusb` 上的操作都需要超级管理员的权限,并且你在这个设备上的所有数据将会被格式化。 一旦操作完成,你将会重置这个设备并让它继续工作。 如果你感到任何疑惑,你可以在下面的评论栏里免费发表。 - - -------------------------------------------------------------------------------- via: http://www.linuxandubuntu.com/home/restore-corrupted-usb-drive-to-original-state-in-linux 作者:[LINUXANDUBUNTU][a] 译者:[Drshu](https://github.com/Drshu) -校对:[校对者ID](https://github.com/校对者ID) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 From c1e54257e5712d31e33cd153916b7a0ffffb9804 Mon Sep 17 00:00:00 2001 From: wxy Date: Mon, 29 Jan 2018 22:25:36 +0800 Subject: [PATCH 027/272] PRF&PUB:20180103 Linux-Unix desktop fun- Simulates the display from -The Matrix.md @CYLeft https://linux.cn/article-9291-1.html --- ... Simulates the display from -The Matrix.md | 139 ++++++++++++++++++ ... Simulates the display from -The Matrix.md | 111 -------------- 2 files changed, 139 insertions(+), 111 deletions(-) create mode 100644 published/20180103 Linux-Unix desktop fun- Simulates the display from -The Matrix.md delete mode 100644 translated/tech/20180103 Linux-Unix desktop fun- Simulates the display from -The Matrix.md diff --git a/published/20180103 Linux-Unix desktop fun- Simulates the display from -The Matrix.md b/published/20180103 Linux-Unix desktop fun- Simulates the display from -The Matrix.md new file mode 100644 index 0000000000..14efe969de --- /dev/null +++ b/published/20180103 Linux-Unix desktop fun- Simulates the display from -The Matrix.md @@ -0,0 +1,139 @@ +Linux/Unix 桌面盛典:模仿 “黑客帝国” 界面! +====== + +《黑客帝国》是 1999 年,由 Wachowki 兄弟编导的科幻动作片。这部电影的荧屏里有无尽的绿色字符降落。数字雨模拟着《黑客帝国》中的虚拟现实活动。现在,Linux 和 Unix 终端上,你也可以通过 CMatrix 模仿出矩阵数字雨。 + +### 安装 cmatrix + +根据你的 Linux/Unix 发行版或操作系统安装并且设置 CMatrix。 + +#### 如何在 Debian/Ubuntu Linux 发行版中安装 cmatrix + +在 Debian/Ubuntu/Mint 系统中键入以下命令 [apt-get 命令][1]/[apt 命令][2]: + +``` +$ sudo apt install cmatrix +``` + +示例输出: + +``` +[sudo] password for vivek: +Reading package lists... Done +Building dependency tree +Reading state information... Done +Suggested packages: + cmatrix-xfont +The following NEW packages will be installed: + cmatrix +0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded. +Need to get 15.8 kB of archives. +After this operation, 50.2 kB of additional disk space will be used. +Get:1 http://in.archive.ubuntu.com/ubuntu artful/universe amd64 cmatrix amd64 1.2a-5build2 [15.8 kB] +Fetched 15.8 kB in 0s (19.7 kB/s) +Selecting previously unselected package cmatrix. +(Reading database ... 205388 files and directories currently installed.) +Preparing to unpack .../cmatrix_1.2a-5build2_amd64.deb ... +Unpacking cmatrix (1.2a-5build2) ... +Setting up cmatrix (1.2a-5build2) ... +Processing triggers for man-db (2.7.6.1-2) ... +``` + +#### 如何在 Arch Linux 发行版安装 cmatrix + +键入 pacman 命令: + +``` +$ sudo pacman -S cmatrix +``` + +#### 如何在 FreeBCD 系统中安装 cmatrix + +运行如下命令安装 port: + +``` +# cd /usr/ports/misc/cmatrix/ && make install clean +``` + +或者使用 pkg 命令添加二进制包: + +``` +# pkg install cmatrix +``` + +#### 如何在 macOS Unix 发行版中安装 cmatrix + +键入下列命令: + +``` +$ brew install cmatrix +``` + +#### 如何在 OpenBSD 系统中安装 cmatrix + +键入 pkg_add 命令: + +``` +# pkg_add cmatrix +``` + +### 使用 cmatrix + +简单键入命令: + +``` +$ cmatrix +``` + +[![cmtarix 运转中][3]][3] + +#### 使用键盘 + +在执行期间,下列按键有效(`-s` 模式下,按键无效): + +| 按键 | 说明 | +|---|---| +| `a` | 切换异步滚动 | +| `b` | 随机字符加粗 | +| `B` | 全部字符加粗 | +| `n` | 关闭字符加粗 | +| `0`-`9` | 调整更新时间 | +| `!` `@` `#` `$` `%` `^` `&` `)` | 改变对应的矩阵颜色: `!` – 红、`@` – 绿、`#` – 黄、`$` – 蓝、`%` – 洋红、`^` – 青、 `&` – 白、 `)` – 黑。 | +| `q` | 退出程序 | + +你可以通过以下命令获取 cmatrix 选项: + +``` +$ cmatrix -h +``` + +- `-a`: 异步滚动 +- `-b`: 开启字符加粗 +- `-B`: 所有字符加粗(优先于 -b 选项) +- `-f`: 强制开启 Linux $TERM 模式 +- `-l`: Linux 模式(使用 matrix 控制台字体) +- `-o`: 启用旧式滚动 +- `-h`: 输出使用说明并退出 +- `-n`: 关闭字符加粗 (优先于 -b and -B,默认) +- `-s`: “屏保”模式, 第一次按键时退出 +- `-x`: X 窗口模式,如果你使用的时 mtx.pcf 终端 +- `-V`: 输出版本信息并且退出 +- `-u delay` (0 - 10,默认 4): 屏幕更新延时 +- `-C [color]`: 调整 matrix 颜色(默认绿色) + +现在,你拥有了一款最炫酷的终端应用! + +-------------------------------------------------------------------------------- + +via: https://www.cyberciti.biz/open-source/command-line-hacks/matrix-digital-rain-on-linux-macos-unix-terminal/ + +作者:[nixCraft][a] +译者:[CYLeft](https://github.com/CYLeft) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://www.cyberciti.biz +[1]:https://www.cyberciti.biz/tips/linux-debian-package-management-cheat-sheet.html (See Linux/Unix apt-get command examples for more info) +[2]:https://www.cyberciti.biz/faq/ubuntu-lts-debian-linux-apt-command-examples/ (See Linux/Unix apt command examples for more info) +[3]:https://www.cyberciti.biz/media/new/cms/2018/01/small-cmtarix-file.gif diff --git a/translated/tech/20180103 Linux-Unix desktop fun- Simulates the display from -The Matrix.md b/translated/tech/20180103 Linux-Unix desktop fun- Simulates the display from -The Matrix.md deleted file mode 100644 index 7a3a6b6207..0000000000 --- a/translated/tech/20180103 Linux-Unix desktop fun- Simulates the display from -The Matrix.md +++ /dev/null @@ -1,111 +0,0 @@ -Linux/Unix 桌面盛典:伪造“黑客帝国”界面! -====== -《黑客帝国》是 1999 年,由 Wachowki 兄弟撰写的的科幻动作片。这部电影的荧屏里有无尽的绿色字符降落。《黑客帝国》的数字雨模拟着虚拟现实活动。现在,Linux 和 Unix 终端上,你也可以通过 CMatrix 模仿出矩阵数字雨。 - -## 安装 cmatrix - -在你的每一台 Linux/Unix 发行版上安装并且设置 CMatrix。 - -### 如何在 Debian/Ubuntu Linux 发行版中安装 cmatrix - -在 Debian/Ubuntu/Mint 系统中键入以下命令 [apt-get 命令][1]/[apt 命令][2]: -`$ sudo apt install cmatrix` -示例输出: -``` -[sudo] password for vivek: -Reading package lists... Done -Building dependency tree -Reading state information... Done -Suggested packages: - cmatrix-xfont -The following NEW packages will be installed: - cmatrix -0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded. -Need to get 15.8 kB of archives. -After this operation, 50.2 kB of additional disk space will be used. -Get:1 http://in.archive.ubuntu.com/ubuntu artful/universe amd64 cmatrix amd64 1.2a-5build2 [15.8 kB] -Fetched 15.8 kB in 0s (19.7 kB/s) -Selecting previously unselected package cmatrix. -(Reading database ... 205388 files and directories currently installed.) -Preparing to unpack .../cmatrix_1.2a-5build2_amd64.deb ... -Unpacking cmatrix (1.2a-5build2) ... -Setting up cmatrix (1.2a-5build2) ... -Processing triggers for man-db (2.7.6.1-2) ... -``` - -### 如何在 Arch Linux 发行版安装 cmatrix - -键入 pacman 命令: -`$ sudo pacman -S cmatrix` - -### 如何在 FreeBCD 系统中安装 cmatrix - -安装运行端口: -`# cd /usr/ports/misc/cmatrix/ && make install clean` -或者使用 pkg 命令添加二进制包 -`# pkg install cmatrix` - -### 如何在 macOS Unix 发行版中安装 cmatrix - -键入下列命令: -`$ brew install cmatrix` - -### 如何在 OpenBSD 系统中安装 cmatrix - -键入 pkg_add 命令: -`# pkg_add cmatrix` - -## 使用 cmatrix - -简单模式下,命令: -`$ cmatrix` -[![cmtarix 运转中][3]][3] - -### 使用键盘 - -在执行期间,下列按键有效(-s 模式下,按键无效): -| 按键 | 说明 | -| a | 切换异步滚动 | -| b | 随机字符加粗 | -| B | 字符加粗 | -| n | 关闭字符加粗 | -| 0-9 | 调整更新时间 | -| ! @ # $ % ^ & ) | 改变对应的矩阵颜色: ! – 红, @ – -绿, # – 黄, $ – 蓝, % – 洋红, ^ – 青, & – 白, ) – 黑. | -| q | 退出程序 | - -你可以通过以下命令获取 cmatrix 选项: -`$ cmatrix -h` -示例输出: -``` --a: 异步滚动 - -b: 开启字符加粗 - -B: 所有字符加粗(优先于 -b 选项) - -f: 强制开启 Linux $TERM 模式 - -l: Linux 模式(使用 matrix 控制台字体) - -o: 启用旧式滚动 - -h: 输出使用说明并退出 - -n: 关闭字符加粗 (优先于 -b and -B,默认) - -s: “屏保”模式,, 第一次按键时退出 - -x: X 窗口模式,如果你使用的时 mtx.pcf 终端 - -V: 输出版本信息并且退出 - -u delay (0 - 10, default 4): 屏幕更新延时 - -C [color]: 调整 matrix 颜色(默认绿色) -``` - -现在,你拥有了一款最炫酷的终端软件! - --------------------------------------------------------------------------------- - -via: https://www.cyberciti.biz/open-source/command-line-hacks/matrix-digital-rain-on-linux-macos-unix-terminal/ - -作者:[][a] -译者:[CYLeft](https://github.com/CYLeft) -校对:[校对者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/tips/linux-debian-package-management-cheat-sheet.html (See Linux/Unix apt-get command examples for more info) -[2]:https://www.cyberciti.biz/faq/ubuntu-lts-debian-linux-apt-command-examples/ (See Linux/Unix apt command examples for more info) -[3]:https://www.cyberciti.biz/media/new/cms/2018/01/small-cmtarix-file.gif From 1c930cdae85bab068ad1ab6acd42d00a9621650e Mon Sep 17 00:00:00 2001 From: wenwensnow <963555237@qq.com> Date: Mon, 29 Jan 2018 22:42:07 +0800 Subject: [PATCH 028/272] Update 20180125 Linux whereis Command Explained for Beginners (5 Examples).md --- ...Linux whereis Command Explained for Beginners (5 Examples).md | 1 + 1 file changed, 1 insertion(+) diff --git a/sources/tech/20180125 Linux whereis Command Explained for Beginners (5 Examples).md b/sources/tech/20180125 Linux whereis Command Explained for Beginners (5 Examples).md index 45107b050c..2c07001623 100644 --- a/sources/tech/20180125 Linux whereis Command Explained for Beginners (5 Examples).md +++ b/sources/tech/20180125 Linux whereis Command Explained for Beginners (5 Examples).md @@ -1,3 +1,4 @@ +translating by wenwensnow Linux whereis Command Explained for Beginners (5 Examples) ====== From 4bf0d03ac67ca6c0d0819f7e2faf730e6861131a Mon Sep 17 00:00:00 2001 From: wxy Date: Mon, 29 Jan 2018 22:43:11 +0800 Subject: [PATCH 029/272] PRF&PUB:20171228 How to exclude file when using scp command recursively.md @geekpi --- ...file when using scp command recursively.md | 102 ++++++++++++++++++ ...file when using scp command recursively.md | 86 --------------- 2 files changed, 102 insertions(+), 86 deletions(-) create mode 100644 published/20171228 How to exclude file when using scp command recursively.md delete mode 100644 translated/tech/20171228 How to exclude file when using scp command recursively.md diff --git a/published/20171228 How to exclude file when using scp command recursively.md b/published/20171228 How to exclude file when using scp command recursively.md new file mode 100644 index 0000000000..20523b6c7c --- /dev/null +++ b/published/20171228 How to exclude file when using scp command recursively.md @@ -0,0 +1,102 @@ +如何在使用 scp 命令时递归地排除文件 +====== + +Q:我需要将所有包含 *.c 文件的文件夹从名为 hostA 的本地笔记本复制到 hostB。我使用的是下面的 `scp` 命令,但不知道如何排除特定的文件(如 *.out): + +``` +$ scp -r ~/projects/ user@hostB:/home/delta/projects/ +``` + +如何告诉 `scp` 命令在 Linux/Unix 命令行中排除特定的文件或目录? + +人们可以使用 `scp` 命令在网络主机之间安全地复制文件。它使用 ssh 进行数据传输和身份验证。典型的语法是: + +``` +scp file1 user@host:/path/to/dest/ +scp -r /path/to/source/ user@host:/path/to/dest/ +``` + +### scp 排除文件 + +我不认为你可以在使用 scp 命令时过滤或排除文件。但是,有一个很好的解决方法来排除文件并使用 ssh 安全地复制它。本页面说明如何在使用 `scp` 递归复制目录时过滤或排除文件。 + +### 如何使用 rsync 命令排除文件 + +语法是: + +``` +rsync av -e ssh --exclude='*.out' /path/to/source/ user@hostB:/path/to/dest/ +``` + +这里: + +1. `-a` :递归到目录,即复制所有文件和子目录。另外,打开归档模式和所有其他选项(相当于 `-rlptgoD`) +2. `-v` :详细输出 +3. `-e ssh` :使用 ssh 作为远程 shell,这样所有的东西都被加密 +4. `--exclude='*.out'` :排除匹配模式的文件,例如 *.out 或 *.c 等。 + + +### rsync 命令的例子 + +在这个例子中,从 `~/virt/` 目录递归地复制所有文件,但排除所有 *.new 文件: + +``` +$ rsync -av -e ssh --exclude='*.new' ~/virt/ root@centos7:/tmp +``` + +示例输出: + +[![Scp exclude files but using rsync exclude command][2]][2] + +如果远程服务器上找不到 `rsync`,那么 `rsync` 命令将失败。在这种情况下,请尝试使用以下 `scp` 命令,该命令在当前目录中使用 [bash shell 模式匹配] [3] (它不能与 `-r` 选项一起使用): + +``` +$ ls +``` + +示例输出: + +``` +centos71.log centos71.qcow2 centos71.qcow2.new centos71.v2.qcow2.new meta-data user-data +``` + +复制除 .new 之外的当前目录中的所有内容: + +``` +$ shopt -s extglob +$ scp !(*.new) root@centos7:/tmp/ +``` + +示例输出: + +``` +centos71.log 100 % 4262 1.3MB/s 00:00 +centos71.qcow2 100 % 836MB 32.7MB/s 00: 25 +meta-data 100 % 47 18.5KB/s 00:00 +user-data 100 % 1543 569.7KB/s 00:00 +``` + +有关更多信息,请参阅以下手册页: + +``` +$ man rsync +$ man bash +$ man scp +``` + +-------------------------------------------------------------------------------- + +via: https://www.cyberciti.biz/faq/scp-exclude-files-when-using-command-recursively-on-unix-linux/ + +作者:[Vivek Gite][a] +译者:[geekpi](https://github.com/geekpi) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://www.cyberciti.biz +[1]:https://www.cyberciti.biz/cdn-cgi/l/email-protection +[2]:https://www.cyberciti.biz/media/new/faq/2017/12/scp-exclude-files-on-linux-unix-macos-bash-shell-command-line.jpg +[3]:https://www.gnu.org/software/bash/manual/html_node/Pattern-Matching.html#Pattern-Matching +[4]:https://www.samba.org/ftp/rsync/rsync.html +[5]:https://man.openbsd.org/scp diff --git a/translated/tech/20171228 How to exclude file when using scp command recursively.md b/translated/tech/20171228 How to exclude file when using scp command recursively.md deleted file mode 100644 index e8623baa02..0000000000 --- a/translated/tech/20171228 How to exclude file when using scp command recursively.md +++ /dev/null @@ -1,86 +0,0 @@ -如何在递归地使用 scp 命令时排除文件 -====== - -我需要将所有包含 *.c 文件的文件夹从名为 hostA 的本地笔记本复制到 hostB。我使用的是下面的 scp 命令,但不知道如何排除特定的文件(如 \*.out): -``` -$ scp -r ~/projects/ user@hostB:/home/delta/projects/ -``` -如何告诉 scp 命令在 Linux/Unix 命令行中排除特定的文件或目录? - -人们可以使用 scp 命令在网络主机之间安全地复制文件。它使用 ssh 进行数据传输和身份验证。典型的语法是: - -``` -scp file1 user@host:/path/to/dest/ -scp -r /path/to/source/ user@host:/path/to/dest/ -``` - -## Scp 排除文件 - -我不认为你可以在使用 scp 命令时过滤或排除文件。但是,有一个很好的解决方法来排除文件并使用 ssh 安全地复制它。本页面说明如何在使用 scp 递归复制目录时过滤或排除文件。 - -## 如何使用 rsync 命令排除文件 - -语法是: -`rsync av -e ssh --exclude='*.out' /path/to/source/ [[email protected]][1]:/path/to/dest/` -这里: - - 1. **-a** :递归到目录,即复制所有文件和子目录。另外,打开归档模式和所有其他选项(-rlptgoD) - 2. **-v** :详细输出 - 3. **-e ssh** :使用 ssh 作为远程 shell,这样所有的东西都被加密 - 4. **\--exclude='*.out'** :排除匹配模式的文件,例如 \*.out 或 \*.c 等。 - - -### rsync 命令的例子 - -在这个例子中,从 ~/virt/ 目录递归地复制所有文件,但排除所有 \*.new 文件: -`$ rsync -av -e ssh --exclude='*.new' ~/virt/ [[email protected]][1]:/tmp` -示例输出: -[![Scp exclude files but using rsync exclude command][2]][2] - -如果远程服务器上找不到 rsync,那么 rsync 命令将失败。在这种情况下,请尝试使用以下 scp 命令,该命令在当前目录中使用[ bash shell 模式匹配] [3](它不与 -r 选项一起使用): -`$ ls ` -示例输出: -``` -centos71.log centos71.qcow2 centos71.qcow2.new centos71.v2.qcow2.new meta-data user-data -``` - -centos71.log centos71.qcow2 centos71.qcow2.new centos71.v2.qcow2.new meta-data user-data - -复制除 .new 之外的当前目录中的所有内容: -``` -$ shopt -s extglob -$ scp !(.new)* [[email protected]][1]:/tmp/ -``` -示例输出: -``` -centos71.log 100 % 4262 1.3MB/s 00:00 -centos71.qcow2 100 % 836MB 32.7MB/s 00: 25 -meta-data 100 % 47 18.5KB/s 00:00 -user-data 100 % 1543 569.7KB/s 00:00 -``` - - -有关更多信息,请参阅以下手册页: -``` -$ [man rsync][4] -$ man bash -$ [man scp][5] -``` - - --------------------------------------------------------------------------------- - -via: https://www.cyberciti.biz/faq/scp-exclude-files-when-using-command-recursively-on-unix-linux/ - -作者:[Vivek Gite][a] -译者:[geekpi](https://github.com/geekpi) -校对:[校对者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/cdn-cgi/l/email-protection -[2]:https://www.cyberciti.biz/media/new/faq/2017/12/scp-exclude-files-on-linux-unix-macos-bash-shell-command-line.jpg -[3]:https://www.gnu.org/software/bash/manual/html_node/Pattern-Matching.html#Pattern-Matching -[4]:https://www.samba.org/ftp/rsync/rsync.html -[5]:https://man.openbsd.org/scp From 66da7baac7d6909e11e5f407a9cbbe0a5b4f9ca4 Mon Sep 17 00:00:00 2001 From: Wuod3n <33994335+Wuod3n@users.noreply.github.com> Date: Mon, 29 Jan 2018 22:50:32 +0800 Subject: [PATCH 030/272] Delete 20170915 Deep learning wars- Facebook-backed PyTorch vs Google-s TensorFlow.md --- ...k-backed PyTorch vs Google-s TensorFlow.md | 77 ------------------- 1 file changed, 77 deletions(-) delete mode 100644 sources/talk/20170915 Deep learning wars- Facebook-backed PyTorch vs Google-s TensorFlow.md diff --git a/sources/talk/20170915 Deep learning wars- Facebook-backed PyTorch vs Google-s TensorFlow.md b/sources/talk/20170915 Deep learning wars- Facebook-backed PyTorch vs Google-s TensorFlow.md deleted file mode 100644 index 31dbeb394b..0000000000 --- a/sources/talk/20170915 Deep learning wars- Facebook-backed PyTorch vs Google-s TensorFlow.md +++ /dev/null @@ -1,77 +0,0 @@ -Translating by Wuod3n -Deep learning wars: Facebook-backed PyTorch vs Google's TensorFlow -====== -The rapid rise of tools and techniques in Artificial Intelligence and Machine learning of late has been astounding. Deep Learning, or "Machine learning on steroids" as some say, is one area where data scientists and machine learning experts are spoilt for choice in terms of the libraries and frameworks available. A lot of these frameworks are Python-based, as Python is a more general-purpose and a relatively easier language to work with. [Theano][1], [Keras][2] [TensorFlow][3] are a few of the popular deep learning libraries built on Python, developed with an aim to make the life of machine learning experts easier. - -Google's TensorFlow is a widely used machine learning and deep learning framework. Open sourced in 2015 and backed by a huge community of machine learning experts, TensorFlow has quickly grown to be THE framework of choice by many organizations for their machine learning and deep learning needs. PyTorch, on the other hand, a recently developed Python package by Facebook for training neural networks is adapted from the Lua-based deep learning library Torch. PyTorch is one of the few available DL frameworks that uses tape-based autograd system to allow building dynamic neural networks in a fast and flexible manner. - -In this article, we pit PyTorch against TensorFlow and compare different aspects where one edges the other out. - -Let's get started! - -### What programming languages support PyTorch and TensorFlow? - -Although primarily written in C++ and CUDA, Tensorflow contains a Python API sitting over the core engine, making it easier for Pythonistas to use. Additional APIs for C++, Haskell, Java, Go, and Rust are also included which means developers can code in their preferred language. - -Although PyTorch is a Python package, there's provision for you to code using the basic C/ C++ languages using the APIs provided. If you are comfortable using Lua programming language, you can code neural network models in PyTorch using the Torch API. - -### How easy are PyTorch and TensorFlow to use? - -TensorFlow can be a bit complex to use if used as a standalone framework, and can pose some difficulty in training Deep Learning models. To reduce this complexity, one can use the Keras wrapper which sits on top of TensorFlow's complex engine and simplifies the development and training of deep learning models. TensorFlow also supports [Distributed training][4], which PyTorch currently doesn't. Due to the inclusion of Python API, TensorFlow is also production-ready i.e., it can be used to train and deploy enterprise-level deep learning models. - -PyTorch was rewritten in Python due to the complexities of Torch. This makes PyTorch more native to developers. It has an easy to use framework that provides maximum flexibility and speed. It also allows quick changes within the code during training without hampering its performance. If you already have some experience with deep learning and have used Torch before, you will like PyTorch even more, because of its speed, efficiency, and ease of use. PyTorch includes custom-made GPU allocator, which makes deep learning models highly memory efficient. Due to this, training large deep learning models becomes easier. Hence, large organizations such as Facebook, Twitter, Salesforce, and many more are embracing Pytorch. - -### Training Deep Learning models with PyTorch and TensorFlow - -Both TensorFlow and PyTorch are used to build and train Neural Network models. - -TensorFlow works on SCG (Static Computational Graph) that includes defining the graph statically before the model starts execution. However, once the execution starts the only way to tweak changes within the model is using [tf.session and tf.placeholder tensors][5]. - -PyTorch is well suited to train RNNs( Recursive Neural Networks) as they run faster in [PyTorch ][6]than in TensorFlow. It works on DCG (Dynamic Computational Graph) and one can define and make changes within the model on the go. In a DCG, each block can be debugged separately, which makes training of neural networks easier. - -TensorFlow has recently come up with TensorFlow Fold, a library designed to create TensorFlow models that works on structured data. Like PyTorch, it implements the DCGs and gives massive computational speeds of up to 10x on CPU and more than 100x on GPU! With the help of [Dynamic Batching][7], you can now implement deep learning models which vary in size as well as structure. - -### Comparing GPU and CPU optimizations - -TensorFlow has faster compile times than PyTorch and provides flexibility for building real-world applications. It can run on literally any kind of processor from a CPU, GPU, TPU, mobile devices, to a Raspberry Pi (IoT Devices). - -PyTorch, on the other hand, includes Tensor computations which can speed up deep neural network models upto [50x or more][8] using GPUs. These tensors can dwell on CPU or GPU. Both CPU and GPU are written as independent libraries; making PyTorch efficient to use, irrespective of the Neural Network size. - -### Community Support - -TensorFlow is one of the most popular Deep Learning frameworks today, and with this comes a huge community support. It has great documentation, and an eloquent set of online tutorials. TensorFlow also includes numerous pre-trained models which are hosted and available on [github][9]. These models aid developers and researchers who are keen to work with TensorFlow with some ready-made material to save their time and efforts. - -PyTorch, on the other hand, has a relatively smaller community since it has been developed fairly recently. As compared to TensorFlow, the documentation isn't that great, and codes are not readily available. However, PyTorch does allow individuals to share their pre-trained models with others. - -### PyTorch and TensorFlow - A David & Goliath story - -As it stands, Tensorflow is clearly favoured and used more than PyTorch for a variety of reasons. - -Tensorflow is vast, experienced, and best suited for practical purposes. It is easily the obvious choice of most of the machine learning and deep learning experts because of the vast array of features it offers, and most importantly, its maturity in the market. It has a better community support along with multiple language APIs available. It has a good documentation and is production-ready due to the availability of ready-to-use code. Hence, it is better suited for someone who wants to get started with Deep Learning, or for organizations wanting to productize their Deep Learning models. - -Although PyTorch is relatively newer and has a smaller community, it is fast and efficient. In short, it gives you all the power of Torch wrapped in the usefulness and ease of Python. Because of its efficiency and speed, it is a good option to have for small, research based projects. As mentioned earlier, companies such as Facebook, Twitter, and many others are using Pytorch to train deep learning models. However, its adoption is yet to go mainstream. The potential is evident, PyTorch is just not ready yet to challenge the beast that is TensorFlow. However considering its growth, the day is not far when PyTorch is further optimized and offers more functionalities - to the point that it becomes the David to TensorFlow's Goliath. - -### Savia Lobo -A Data science fanatic. Loves to be updated with the tech happenings around the globe. Loves singing and composing songs. Believes in putting the art in smart. - - --------------------------------------------------------------------------------- - -via: https://datahub.packtpub.com/deep-learning/dl-wars-pytorch-vs-tensorflow/ - -作者:[Savia Lobo][a] -译者:[译者ID](https://github.com/译者ID) -校对:[校对者ID](https://github.com/校对者ID) - -本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 - -[a]:https://datahub.packtpub.com/author/savial/ -[1]:https://www.packtpub.com/web-development/deep-learning-theano -[2]:https://www.packtpub.com/big-data-and-business-intelligence/deep-learning-keras -[3]:https://www.packtpub.com/big-data-and-business-intelligence/deep-learning-tensorflow -[4]:https://www.tensorflow.org/deploy/distributed -[5]:https://www.tensorflow.org/versions/r0.12/get_started/basic_usage -[6]:https://www.reddit.com/r/MachineLearning/comments/66rriz/d_rnns_are_much_faster_in_pytorch_than_tensorflow/ -[7]:https://arxiv.org/abs/1702.02181 -[8]:https://github.com/jcjohnson/pytorch-examples#pytorch-tensors -[9]:https://github.com/tensorflow/models From b4df0ad86f0c4a828ed9866e12f10f2e0e8ab659 Mon Sep 17 00:00:00 2001 From: Wuod3n <33994335+Wuod3n@users.noreply.github.com> Date: Mon, 29 Jan 2018 22:53:30 +0800 Subject: [PATCH 031/272] Create 20170915 Deep learning wars: Facebook-backed PyTorch vs Google's TensorFlow --- ...book-backed PyTorch vs Google's TensorFlow | 109 ++++++++++++++++++ 1 file changed, 109 insertions(+) create mode 100644 translated/talk/20170915 Deep learning wars: Facebook-backed PyTorch vs Google's TensorFlow diff --git a/translated/talk/20170915 Deep learning wars: Facebook-backed PyTorch vs Google's TensorFlow b/translated/talk/20170915 Deep learning wars: Facebook-backed PyTorch vs Google's TensorFlow new file mode 100644 index 0000000000..a47aadcc9d --- /dev/null +++ b/translated/talk/20170915 Deep learning wars: Facebook-backed PyTorch vs Google's TensorFlow @@ -0,0 +1,109 @@ +深度学习战争:Facebook支持的PyTorch与Google的TensorFlow +====== +有一个令人震惊的事实,即人工智能和机器学习的工具和技术在近期迅速兴起。深度学习,或者说“注射了激素的机器学习”是数据科学家和机器学习专家在可用的库和框架方面被宠坏的一个领域。很多这样的框架都是基于Python的,因为Python是一个更通用,相对简单的语言。[Theano] [1],[Keras] [2] [TensorFlow] [3]是一些基于Python构建的流行的深度学习库,目的是使机器学习专家更轻松。 + +Google的TensorFlow是一个广泛使用的机器学习和深度学习框架。 TensorFlow开源于2015年,得到了机器学习专家的广泛支持,TensorFlow已经迅速成长为许多机构为其机器学习和深度学习需求所选择的框架。 另一方面,PyTorch最近开发的用于训练神经网络的Python包被改编自基于Lua的深度学习库Torch。 PyTorch是少数可用的DL框架之一,它使用基于磁带的autograd系统(tape-based autograd system),以快速和灵活的方式构建动态神经网络。 + +在这篇文章中,我们将PyTorch与TensorFlow进行不同方面的比较。 + +让我们开始吧! + +###什么编程语言支持 PyTorch和TensorFlow? + +虽然主要是用C ++和CUDA编写的,但Tensorflow包含一个位于核心引擎上的Python API,使得更便于被Pythonistas使用。 除了Python,它还包括C ++,Haskell,Java,Go和Rust等其他API,这意味着开发人员可以用他们的首选语言进行编码。 + +虽然PyTorch是一个Python软件包,但你也可以提供使用基本的C / C ++语言的API进行编码。 如果你习惯使用Lua编程语言,你也可以使用Torch API在PyTorch中编写神经网络模型。 + +###PyTorch和TensorFlow有多么易于使用? + +如果将TensorFlow作为一个独立的框架使用,它可能会有点复杂,并且会给深度学习模型的训练带来一些困难。 为了减少这种复杂性,可以使用位于TensorFlow复杂引擎之上的Keras封装,简化深度学习模型的开发和训练。 TensorFlow也支持PyTorch目前没有的[分布式培训] [4]。 由于包含Python API,TensorFlow也可以在生产环境中使用,即可用于培训练和部署企业级深度学习模型。 + +PyTorch由于Torch的复杂而被Python重写。 这使得PyTorch对于开发人员更为原生。 它有一个易于使用的框架,提供最大化的灵活和速度。 它还允许在训练过程中快速更改代码而不妨碍其性能。 如果你已经有了一些深度学习的经验,并且以前使用过Torch,那么基于它的速度,效率和易用性,你会更喜欢PyTorch。 PyTorch包含定制的GPU分配器,这使得深度学习模型具有高度的内存效率。 由此,训练大型深度学习模型变得更容易。 因此,Pytorch +在Facebook,Twitter,Salesforce等大型组织广受欢迎。 + +###用PyTorch和TensorFlow训练深度学习模型 + +PyTorch和TensorFlow都可以用来建立和训练神经网络模型。 + +TensorFlow在SCG(静态计算图)上工作,包括在模型开始执行之前定义静态图形。 但是,一旦开始执行,在模型内的调整更改的唯一方法是使用[tf.session and tf.placeholder tensors][5]。 + +PyTorch非常适合训练RNNs(递归神经网络),因为它们在[PyTorch] [6]中比在TensorFlow中运行得更快。 它适用于DCG(动态计算图),可以随时在模型中定义和更改。 在DCG中,每个模块可以单独调试,这使得神经网络的训练更简单。 + +TensorFlow最近提出了TensorFlow Fold,这是一个旨在创建TensorFlow模型的库,用于处理结构化数据。 像PyTorch一样,它实现了DCGs,在CPU上提供高达10倍的计算速度,在GPU上提供超过100倍的计算速度! 在[Dynamic Batching] [7]的帮助下,你现在可以执行尺寸和结构都不相同的深度学习模型。 + +###GPU和CPU优化的比较 + +TensorFlow的编译时间比PyTorch短,为构建真实世界的应用程序提供了灵活性。 它可以从CPU,GPU,TPU,移动设备到Raspberry Pi(物联网设备)等各种处理器上运行。 + +另一方面,PyTorch包括张量(tensor)计算,可以使用GPU将深度神经网络模型加速到[50倍或更多] [8]。 这些张量可以停留在CPU或GPU上。 CPU和GPU都是独立的库, 无论神经网络大小如何,PyTorch都可以高效地利用。 + +###社区支持 + +TensorFlow是当今最流行的深度学习框架之一,由此也给它带来了庞大的社区支持。 它有很好的文档和一套详细的在线教程。 TensorFlow还包括许多预先训练过的模型,这些模型在[github] [9]上托管和提供。 这些模型提供给热衷于使用TensorFlow开发者和研究人员一些现成的材料来节省他们的时间和精力。 + +另一方面,PyTorch的社区相对较小,因为它最近才发展起来。 与TensorFlow相比,文档并不是很好,代码也不是很容易获得。 然而,PyTorch确实允许个人与他人分享他们的预训练模型。 + +### PyTorch和TensorFlow-力量悬殊的故事 + +就目前而言,由于各种原因,Tensorflow显然比PyTorch更受青睐。 + +Tensorflow很大,经验丰富,最适合实际应用。 是大多数机器学习和深度学习专家明显的选择,因为它提供了大量的功能,最重要的是它在市场上的成熟应用。 它具有更好的社区支持以及多语言API可用。 它有一个很好的文档库,由于从准备到使用的代码使之易于生产。 因此,它更适合想要开始深度学习的人,或者希望开发深度学习模型的组织。 + +虽然PyTorch相对较新,社区较小,但它速度快,效率高。 总之,它给你所有的优势在于Python的有用性和易用性。 由于其效率和速度,对于基于研究的小型项目来说,这是一个很好的选择。 如前所述,Facebook,Twitter等公司正在使用Pytorch来训练深度学习模型。 但是,使用它尚未成为主流。 PyTorch的潜力是显而易见的,但它还没有准备好去挑战这个TensorFlow的野兽。 然而,考虑到它的增长,PyTorch进一步优化并提供更多功能的日子并不遥远,直到与TensorFlow可以比较。 + +###Savia Lobo +非常喜欢数据科学。 喜欢更新世界各地的科技事件。 喜欢歌唱和创作歌曲。 相信才智上的艺术。 + +-------------------------------------------------------------------------------- + +via: https://datahub.packtpub.com/deep-learning/dl-wars-pytorch-vs-tensorflow/ + +作者:[Savia Lobo][a] +译者:[Wuod3n](https://github.com/Wuod3n) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://datahub.packtpub.com/author/savial/ +[1]:https://www.packtpub.com/web-development/deep-learning-theano +[2]:https://www.packtpub.com/big-data-and-business-intelligence/deep-learning-keras +[3]:https://www.packtpub.com/big-data-and-business-intelligence/deep-learning-tensorflow +[4]:https://www.tensorflow.org/deploy/distributed +[5]:https://www.tensorflow.org/versions/r0.12/get_started/basic_usage +[6]:https://www.reddit.com/r/MachineLearning/comments/66rriz/d_rnns_are_much_faster_in_pytorch_than_tensorflow/ +[7]:https://arxiv.org/abs/1702.02181 +[8]:https://github.com/jcjohnson/pytorch-examples#pytorch-tensors +[9]:https://github.com/tensorflow/models + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 529ccdb5a97fadaeca213a91450c2b47243eab5b Mon Sep 17 00:00:00 2001 From: "Xingyu.Wang" Date: Mon, 29 Jan 2018 22:58:47 +0800 Subject: [PATCH 032/272] Rename 20170915 Deep learning wars: Facebook-backed PyTorch vs Google's TensorFlow to 20170915 Deep learning wars- Facebook-backed PyTorch vs Google-s TensorFlow.md --- ...rning wars- Facebook-backed PyTorch vs Google-s TensorFlow.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename translated/talk/{20170915 Deep learning wars: Facebook-backed PyTorch vs Google's TensorFlow => 20170915 Deep learning wars- Facebook-backed PyTorch vs Google-s TensorFlow.md} (100%) diff --git a/translated/talk/20170915 Deep learning wars: Facebook-backed PyTorch vs Google's TensorFlow b/translated/talk/20170915 Deep learning wars- Facebook-backed PyTorch vs Google-s TensorFlow.md similarity index 100% rename from translated/talk/20170915 Deep learning wars: Facebook-backed PyTorch vs Google's TensorFlow rename to translated/talk/20170915 Deep learning wars- Facebook-backed PyTorch vs Google-s TensorFlow.md From ff8ccce38b1ce40855f671466f7bd9b508e53e80 Mon Sep 17 00:00:00 2001 From: wxy Date: Mon, 29 Jan 2018 23:32:20 +0800 Subject: [PATCH 033/272] PRF:20171219 Migrating to Linux- Graphical Environments.md @CYLeft --- ...rating to Linux- Graphical Environments.md | 89 ++++++++++--------- 1 file changed, 49 insertions(+), 40 deletions(-) diff --git a/translated/tech/20171219 Migrating to Linux- Graphical Environments.md b/translated/tech/20171219 Migrating to Linux- Graphical Environments.md index c4450237a8..2a8991b8bf 100644 --- a/translated/tech/20171219 Migrating to Linux- Graphical Environments.md +++ b/translated/tech/20171219 Migrating to Linux- Graphical Environments.md @@ -1,108 +1,117 @@ -迁移到 Linux 系统:图形操作环境 +迁移到 Linux:图形操作环境 ====== -这是我们迁移到 Linux 系统系列的第三篇文章。如果你错过了先前的两篇,这里供有两文的链接 [Linux 新手指导][1] 和 [Linux 文件及文件系统][2]。本文中,我们将讨论图形操作环境。在 Linux 系统中,你可以依照喜好选择并且定制一个图形界面,你有很大的选择余地,这也是 Linux 优越的体验之一。 +![](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/linux-migration_0.jpg?itok=0tviWTqd) + +> 这篇文章对 Linux 图形环境做了一番介绍,展示了在不同的 Linux 发行版上的各种选择。 + +这是我们迁移到 Linux 系统系列的第三篇文章。如果你错过了先前的两篇,这里有两文的链接《[入门介绍][1]》 和 《[磁盘、文件、和文件系统][2]》。本文中,我们将讨论图形操作环境。在 Linux 系统中,你可以依照喜好选择并且定制一个图形界面,你有很大的选择余地,这也是 Linux 优越的体验之一。 一些主流的 Linux 图形界面包括:Cinnamon、Gnome、KDE Plasma、Xfce 和 MATE,总之这里有很多选择。 -有一点经常混淆 Linux 新手,虽然特定的 Linux 系统分配了一个缺省的图形环境,但是一般你可以随时更换这个图形接口。这和 Windows 或 Mac OS 的惯用者的定势思维不同。安装图形环境是一件独立的事情,很多时候,Linux 和其图形环境连接地并不紧密。此外,你在一个图形环境构建运行的程序同样适用于另一个图形环境。比如说一个为 KDE Plasma 图形环境编写的应用程序完全适用于 Gnome 桌面图形环境。 +有一点经常混淆 Linux 新手,虽然某个 Linux 系统分配了一个缺省的图形环境,但是一般你可以随时更换这个图形界面。这和 Windows 或 Mac OS 的惯用者的定势思维不同。安装图形环境是一件独立的事情,很多时候,Linux 和其图形环境的连接并不紧密。此外,你在一个图形环境构建运行的程序同样适用于另一个图形环境。比如说一个为 KDE Plasma 图形环境编写的应用程序完全适用于 Gnome 桌面图形环境。 -由于人们熟悉 Windwos 和 MacOS 系统,部分 Linux 操作系统的图形环境在一定程度上尝试着去模仿它们。但是另一些 Linux 图形界面是独特的。 +由于人们熟悉 Windows 和 MacOS 系统,部分 Linux 操作系统的图形环境在一定程度上尝试着去模仿它们,但另一些 Linux 图形界面则是独特的。 -下面,我将就一些不同的 Linux 发行版,展示几个 Linux 图形环境。如果你不确定应该采用那个 Linux 发行版,那我建议你使用有长期支持(LTS)的版本,[Ubuntu][3](Ubuntu 16.04 正在开发)。Ubuntu 稳定且真的非常好用。 +下面,我将就一些不同的 Linux 发行版,展示几个 Linux 图形环境。如果你不确定应该采用那个 Linux 发行版,那我建议你从 [Ubuntu][3] 开始,获取其长期支持(LTS)的版本(Ubuntu 16.04.3 LTS 正在开发)。Ubuntu 稳定且真的非常好用。 ### 由 Mac 过渡 -Elementary OS 发行版提供了和 Mac 系统风格很接近的界面。它的默认图形环境被称作 Pantheon,是一款很适合 Mac 用户过渡使用的图形环境。这款图形界面发行版的屏幕底部有一个停靠栏,专为极简者使用。为了保持简约的风格,很多默认的应用程序甚至都不会有自己的菜单。相反,它们的按钮和控件在应用程序的标题栏上(图 1)。 - +Elementary OS 发行版提供了和 Mac 系统风格很接近的界面。它的默认图形环境被称作 Pantheon,是一款很适合 Mac 用户过渡使用的图形环境。这款图形界面发行版的屏幕底部有一个停靠栏,专为极简者使用而设计。为了保持简约的风格,很多默认的应用程序甚至都不会有自己的菜单。相反,它们的按钮和控件在应用程序的标题栏上(图 1)。 ![Elementary OS][5] -图 1: Elementary OS Pantheon. +*图 1: Elementary OS Pantheon.* Ubuntu 发行版提供的一个默认的图形界面,也和 Mac 相似。Ubuntu 17.04 或者更老的版本都使用 Unity 图形环境,Unity 停靠栏的默认位置在屏幕的左边,屏幕顶部有一个全局应用程序共享的菜单栏。 ### 由 Windows 过渡 -在 Windows 之后,ChaletOS 界面模块帮助 Windows 用户轻松的过渡到 Linux。ChaletOS 使用的图形环境是 Xfce(图 2)。在屏幕的左下角有一个开始按钮,主页目录里有一个搜索栏。屏幕的右下角是一个桌面图标和一些通知信息。这看起来和 Windows 非常像,乍一看,可能都会以为桌面跑的是 Windows。 +ChaletOS 亦步亦趋模仿 Windows 界面,可以帮助 Windows 用户轻松的过渡到 Linux。ChaletOS 使用的图形环境是 Xfce(图 2)。在屏幕的左下角有一个开始(主)菜单和搜索栏。屏幕的右下角是一个桌面图标和一些通知信息。这看起来和 Windows 非常像,乍一看,可能都会以为桌面跑的是 Windows。 -Zorin OS 发行版同样尝试模仿 Windows。 Zorin OS 使用的 Dnome 的改进桌面工作起来和 Windows 的图形界面很相似。左下角的开始按钮、右下角的通知栏和信息通知栏。开始按钮会弹出一个和 Windows无异的应用程序列表和搜索框。 +![ChaletOS][6] -### 独特的图形环境 +*图 2: ChaletOS with Xfce.* + +Zorin OS 发行版同样尝试模仿 Windows。 Zorin OS 使用的 Gnome 的改进桌面,工作起来和 Windows 的图形界面很相似。左下角的开始按钮、右下角的通知栏和信息通知栏。开始按钮会弹出一个和 Windows 无异的应用程序列表和搜索框。 + +### 独有的图形环境 Gnome 桌面(图 3)是最常用的图形环境之一。许多发行版将 Gnome 作为默认的图形环境。Gnome 并不打算模仿 Windows 或是 MacOS,而是以其自身的优雅和易用为目标。 -Cinnamon 环境为摆脱 Gnome 桌面环境消极的一面而被创造,在版本 2 到 版本 3 有彻底的改变。尽管 Cinnamon 和前辈 Gnome version 2 外观不相似,但是它依旧尝试提供一个简约的界面,而且它的功能和 Windows XP 类似。 +![][7] -MATE 图形环境在 Gnome version 2 之后直接建模,在它的屏幕顶部有一个用作设置和存放应用的菜单栏,底部提供了一个应用程序运行选项卡和一些其他组件。 +*图 3:openSUSE with Gnome.* -KDE plasma 是一个为了可以在桌面或是面板上安装组件而建立(图 4)。 +Gnome 桌面环境从版本 2 到 版本 3 发生了巨变,Cinnamon 环境为消除该改变带来的不利影响而创造。尽管 Cinnamon 和前辈 Gnome 2 外观不相似,但是它依旧尝试提供一个简约的界面,而且它的功能和 Windows XP 类似。 + +MATE 图形环境直接模仿于 Gnome 2,在它的屏幕顶部有一个用作设置和存放应用的菜单栏,底部提供了一个应用程序运行选项卡和一些其他组件。 + +KDE plasma 围绕组件界面而构建,组件可以安装在桌面或是面板上(图 4)。 ![KDE Plasma][8] -图 4: 安装了 KDE Plasma 的 Kubuntu 操作系统。 +*图 4: 安装了 KDE Plasma 的 Kubuntu 操作系统。* -[使用许可][6] - -没有图形环境本身就是一个很好的图形环境。不同的风格适用不同的用户风格。另外,似乎从 [Ubuntu][3] 开始有繁多的选项。 +没有那个图形环境比另外一个更好。不同的风格适用不同的用户风格。另外,如果选择太多无从下手,那就从 [Ubuntu][3] 开始吧。 ### 相似与不同 -不同的操作系统处理事务方式不同,这会给使用者的过渡带来挑战。比如说,菜单栏可能出现在不同的位置,然后设置有可能用不同的选项入口路径。我列举了一些相似或不同地方来帮助减少 Linux 调整。 +不同的操作系统处理方式不同,这会给使用者的过渡带来挑战。比如说,菜单栏可能出现在不同的位置,然后设置有可能用不同的选项入口路径。我列举了一些相似或不同地方来帮助减少 Linux 调整。 -### 鼠标 +#### 鼠标 Linux 的鼠标通常和 Windows 与 MacOS 的工作方式有所差异。在 Windows 或 Mac,双击标签,你几乎可以打开任何事物,而这在 Linux 图形界面中很多都被设置为单击。 -此外在 Windows 系统中,你通常通过单机窗口获取焦点。在 Linux,很多窗口的焦点获取被设置为鼠标悬浮,即便鼠标悬浮下的窗口并不在屏幕顶端。这种微妙的差异有时候会让人很吃惊。比如说,在 Windows 中,假如有一个后台应用(不在屏幕顶层),你移动鼠标到它的上面,不点击鼠标仅仅转动鼠标滚轮,顶层窗口不会滚动。而在 Linux 中,后台窗口(鼠标悬停的那个窗口)会滚动。 +此外在 Windows 系统中,你通常通过单击窗口获取焦点。在 Linux,很多窗口的焦点获取方式被设置为鼠标悬停,即便鼠标悬停下的窗口并不在屏幕顶端。这种微妙的差异有时候会让人很吃惊。比如说,在 Windows 中,假如有一个后台应用(不在屏幕顶层),你移动鼠标到它的上面,不点击鼠标仅仅转动鼠标滚轮,顶层窗口会滚动。而在 Linux 中,后台窗口(鼠标悬停的那个窗口)会滚动。 -### 菜单 +#### 菜单 -应用菜单是电脑程序的一个基本部件,最近似乎可以调整移动菜单栏到不碍事的地方,甚至干脆完全删除。大概,当你迁移到 Linux,你可能找不到你期待的菜单。应用程序菜单会像 MacOS一样出现在全局共享菜单栏内。和很多移动应用程序一样,菜单可能在“更多选项”的图标里。或者,这个菜单干脆被完全移除被一个按钮取代,正如在 Elementary OS Pantheon 环境里的一些程序一样。 +应用菜单是电脑程序的一个主要集中位置,最近似乎可以调整移动菜单栏到不碍事的地方,甚至干脆完全删除。大概,当你迁移到 Linux,你可能找不到你期待的菜单。应用程序菜单会像 MacOS一样出现在全局共享菜单栏内。和很多移动应用程序一样,该菜单可能在“更多选项”的图标里。或者,这个菜单干脆被完全移除被一个按钮取代,正如在 Elementary OS Pantheon 环境里的一些程序一样。 -### 工作空间 +#### 工作空间 -很多 Linux 图形环境提供了多个工作空间。一个工作空间包含的正在运行的程序窗口充盈了整个屏幕。切换到不同的工作空间将会该片程序的可见性。这个概念是把当前工程运行使用的全部应用程序分组到一个工作空间,而一些为另一个工程使用的应用程序会被分组到不同的工作空间。 +很多 Linux 图形环境提供了多个工作空间。一个工作空间包含的正在运行的程序窗口充盈了整个屏幕。切换到不同的工作空间将会改变程序的可见性。这个概念是把当前项目运行使用的全部应用程序分组到一个工作空间,而一些为另一个项目使用的应用程序会被分组到不同的工作空间。 -不是每一个人都需要甚至是喜欢工作空间,但是我提到它是因为,作为一个新手,你可能无意间通过一个组合键切换了工作空间,然后,“喂!我的应用程序哪去了?”如果你看到的还是你熟悉的煮面壁纸,那你可能只是切换了工作空间,你所有的应用程序还在一个工作空间运行,只是现在不可见。在很多 Linux 环境中,通过敲击 Alt-Ctrl 和一个箭头(上、下、左或右)可以切换工作空间。发现你的应用程序一直都在另一个工作空间里运行还是很有很可能的。 +不是每一个人都需要甚至是喜欢工作空间,但是我提到它是因为,作为一个新手,你可能无意间通过一个组合键切换了工作空间,然后,“喂!我的应用程序哪去了?” 如果你看到的还是你熟悉的桌面壁纸,那你可能只是切换了工作空间,你所有的应用程序还在一个工作空间运行,只是现在不可见而已。在很多 Linux 环境中,通过敲击 `Alt+Ctrl` 和一个箭头(上、下、左或右)可以切换工作空间。很有可能发现你的应用程序一直都在另一个工作空间里运行。 当然,如果你刚好喜欢工作空间(很多人都喜欢),然后你就发现了一个 Linux 很有用的默认功能。 -### 设置 +#### 设置 -许多 Linux 图形环境提供一些类型的设置程序或是面板让你在机器上配置设置。值得注意的是类似 Windows 和 MacOS,Linux 可以配置好很多细节,但不是所有的详细设置都可以在设置程序上找到。但是这些设置项已经足够满足大部分典型的桌面系统,比如选择桌面壁纸,改变息屏时间,连接打印机等其他一些设置。 +许多 Linux 图形环境提供一些类型的设置程序或是面板让你在机器上配置设置。值得注意的是类似 Windows 和 MacOS,Linux 可以配置好很多细节,但不是所有的详细设置都可以在设置程序上找到。但是这些设置项已经足够满足大部分典型的桌面系统,比如选择桌面壁纸,改变熄屏时间,连接打印机等其他一些设置。 -和 Windows 或者 MacOS 相比,Linux 的应用程序设置的分组或是命名都有不同的方式。甚至同是 Linux 系统,不同的图形界面也会出现不同的设置,这可能需要时间适应。当然,在你的图形环境中设置配置的问题可以通过在线查询这样一个不错的方法解决。 +和 Windows 或者 MacOS 相比,Linux 的应用程序设置的分组或是命名都有不同的方式。甚至同是 Linux 系统,不同的图形界面也会出现不同的设置,这可能需要时间适应。当然,在你的图形环境中设置配置的问题可以通过在线查询这样不错的方法解决。 -### 应用程序 +#### 应用程序 -最后,Linux 的应用程序也可能不同。你可能会发现一些熟悉的应用程序,但是对你来说更多的将会是崭新的应用。比如说,你能在 Linux 上找到 Firefox、Chrome和 Skype。如果不能找到特定的应用程序,通常你能使用一些替代程序。如果还是不能,那你可以使用 WINE 这样的兼容层来运行 Windows 的应用程序。 +最后,Linux 的应用程序也可能不同。你可能会发现一些熟悉的应用程序,但是对你来说更多的将会是崭新的应用。比如说,你能在 Linux 上找到 Firefox、Chrome 和 Skype。如果不能找到特定的应用程序,通常你能使用一些替代程序。如果还是不能,那你可以使用 WINE 这样的兼容层来运行 Windows 的应用程序。 -在很多 Linux 图形环境中,你可以通过敲击 Windows 的标志键来打开应用程序菜单栏。在其他一些情况中,你不都不点击开始或家按钮俩启动应用程序菜单。很多图形环境中,你可以通过分类搜索到应用程序而不一定需要它的特定程序名。比如说,你要使用你不清除名字编辑器程序,这时候,你可以在应用程序菜单栏键的搜索框中键入“editor”字样,他将为你展示一个甚至更多的被认为是编辑器类的应用程序。 +在很多 Linux 图形环境中,你可以通过敲击 Windows 的标志键来打开应用程序菜单栏。在其他一些情况中,你不得不点击开始(主)按钮或应用程序菜单。很多图形环境中,你可以通过分类搜索到应用程序而不一定需要它的特定程序名。比如说,你要使用一个你不清楚名字的编辑器程序,这时候,你可以在应用程序菜单栏键的搜索框中键入“editor”字样,它将为你展示一个甚至更多的被认为是编辑器类的应用程序。 -帮你开个头,这里列举了一点可能成为 Linux 系统使用的替代程序。 +为帮你起步,这里列举了一点可能成为 Linux 系统使用的替代程序。 -[linux][10] +![linux][10] 请注意,Linux 提供了大量的满足你需求的选择,这张表里列举的一点也不完整。 -通过 [“Linux 指导”][9] Linux 基金会的免费在线课程,了解更多关于 Linux 内容。 - -------------------------------------------------------------------------------- via: https://www.linux.com/blog/learn/2017/12/migrating-linux-graphical-environments 作者:[John Bonesio][a] -译者:[译者ID](https://github.com/CYLeft) -校对:[校对者ID](https://github.com/校对者ID) +译者:[CYLeft](https://github.com/CYLeft) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 [a]:https://www.linux.com/users/johnbonesio -[1]:https://www.linux.com/blog/learn/intro-to-linux/2017/10/migrating-linux-introduction -[2]:https://www.linux.com/blog/learn/intro-to-linux/2017/11/migrating-linux-disks-files-and-filesystems +[1]:https://linux.cn/article-9212-1.html +[2]:https://linux.cn/article-9213-1.html [3]:https://www.evernote.com/OutboundRedirect.action?dest=https%3A%2F%2Fwww.ubuntu.com%2Fdownload%2Fdesktop [5]:https://www.linux.com/sites/lcom/files/styles/rendered_file/public/elementaryos.png?itok=kJk2-BsL (Elementary OS) +[6]:https://www.linux.com/sites/lcom/files/styles/rendered_file/public/chaletos.png?itok=Zdm2rRgu +[7]:https://www.linux.com/sites/lcom/files/styles/rendered_file/public/opensuse.png?itok=TM0Q9AyH [8]:https://www.linux.com/sites/lcom/files/styles/rendered_file/public/kubuntu.png?itok=a2E7ttaa (KDE Plasma) [9]:https://training.linuxfoundation.org/linux-courses/system-administration-training/introduction-to-linux From 402c9ef25d3a7efede9426352598f505322ea039 Mon Sep 17 00:00:00 2001 From: wxy Date: Mon, 29 Jan 2018 23:32:52 +0800 Subject: [PATCH 034/272] PUB:20171219 Migrating to Linux- Graphical Environments.md @CYLeft https://linux.cn/article-9293-1.html --- .../20171219 Migrating to Linux- Graphical Environments.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename {translated/tech => published}/20171219 Migrating to Linux- Graphical Environments.md (100%) diff --git a/translated/tech/20171219 Migrating to Linux- Graphical Environments.md b/published/20171219 Migrating to Linux- Graphical Environments.md similarity index 100% rename from translated/tech/20171219 Migrating to Linux- Graphical Environments.md rename to published/20171219 Migrating to Linux- Graphical Environments.md From a68a148304d65abde1bde924233bfa72f6631cc1 Mon Sep 17 00:00:00 2001 From: Sun Yongfei Date: Tue, 30 Jan 2018 00:39:23 +0800 Subject: [PATCH 035/272] translating by heart4lor --- .../20180124 8 ways to generate random password in Linux.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sources/tech/20180124 8 ways to generate random password in Linux.md b/sources/tech/20180124 8 ways to generate random password in Linux.md index ee60df826b..499aa5f2c1 100644 --- a/sources/tech/20180124 8 ways to generate random password in Linux.md +++ b/sources/tech/20180124 8 ways to generate random password in Linux.md @@ -1,3 +1,5 @@ +translating by heart4lor + 8 ways to generate random password in Linux ====== Learn 8 different ways to generate random password in Linux using Linux native commands or third party utilities. From 0e36b718f983fbf7fbe062cf57c7ad2a7e5f8a6f Mon Sep 17 00:00:00 2001 From: geekpi Date: Tue, 30 Jan 2018 09:29:29 +0800 Subject: [PATCH 036/272] translated --- ...115 How To Boot Into Linux Command Line.md | 63 ------------------- ...115 How To Boot Into Linux Command Line.md | 61 ++++++++++++++++++ 2 files changed, 61 insertions(+), 63 deletions(-) delete mode 100644 sources/tech/20180115 How To Boot Into Linux Command Line.md create mode 100644 translated/tech/20180115 How To Boot Into Linux Command Line.md diff --git a/sources/tech/20180115 How To Boot Into Linux Command Line.md b/sources/tech/20180115 How To Boot Into Linux Command Line.md deleted file mode 100644 index 00649cc678..0000000000 --- a/sources/tech/20180115 How To Boot Into Linux Command Line.md +++ /dev/null @@ -1,63 +0,0 @@ -translating---geekpi - -How To Boot Into Linux Command Line -====== -![](http://www.linuxandubuntu.com/uploads/2/1/1/5/21152474/how-to-boot-into-linux-command-line_orig.jpg) - -There may be times where you need or want to boot up a [Linux][1] system without using a GUI, that is with no X, but rather opt for the command line. Whatever the reason, fortunately, booting straight into the Linux **command-line** is very simple. It requires a simple change to the boot parameter after the other kernel options. This change specifies the runlevel to boot the system into. - -### ​Why Do This? - -If your system does not run Xorg because the configuration is invalid, or if the display manager is broken, or whatever may prevent the GUI from starting properly, booting into the command-line will allow you to troubleshoot by logging into a terminal (assuming you know what you’re doing to start with) and do whatever you need to do. Booting into the command-line is also a great way to become more familiar with the terminal, otherwise, you can do it just for fun. - -### ​Accessing GRUB Menu - -On startup, you will need access to the GRUB boot menu. You may need to hold the SHIFT key down before the system boots if the menu isn’t set to display every time the computer is started. In the menu, the [Linux distribution][2] entry must be selected. Once highlighted, press ‘e’ to edit the boot parameters. - - [![zorin os grub menu](http://www.linuxandubuntu.com/uploads/2/1/1/5/21152474/gnu-grub_orig.png)][3] - - Older GRUB versions follow a similar mechanism. The boot manager should provide instructions on how to edit the boot parameters. - -### ​​Specify the Runlevel - -​An editor will appear and you will see the options that GRUB parses to the kernel. Navigate to the line that starts with ‘linux’ (older GRUB versions may be ‘kernel’; select that and follow the instructions). This specifies parameters to parse into the kernel. At the end of that line (may appear to span multiple lines, depending on resolution), you simply specify the runlevel to boot into, which is 3 (multi-user mode, text-only). - - [![customize grub menu](http://www.linuxandubuntu.com/uploads/2/1/1/5/21152474/runlevel_orig.png)][4] - -Pressing Ctrl-X or F10 will boot the system using those parameters. Boot-up will continue as normal. The only thing that has changed is the runlevel to boot into. - -​ - -This is what was started up: - - [![boot linux in command line](http://www.linuxandubuntu.com/uploads/2/1/1/5/21152474/runlevel_1_orig.png)][5] - -### Runlevels - -You can specify different runlevels to boot into with runlevel 5 being the default one. 1 boots into “single-user” mode, which boots into a root shell. 3 provides a multi-user, command-line only system. - -### Switch From Command-Line - -At some point, you may want to run the display manager again to use a GUI, and the quickest way to do that is running this: -``` -$ sudo init 5 -``` - -And it is as simple as that. Personally, I find the command-line much more exciting and hands-on than using GUI tools; however, that’s just my preference. - --------------------------------------------------------------------------------- - -via: http://www.linuxandubuntu.com/home/how-to-boot-into-linux-command-line - -作者:[LinuxAndUbuntu][a] -译者:[译者ID](https://github.com/译者ID) -校对:[校对者ID](https://github.com/校对者ID) - -本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 - -[a]:http://www.linuxandubuntu.com -[1]:http://www.linuxandubuntu.com/home/category/linux -[2]:http://www.linuxandubuntu.com/home/category/distros -[3]:http://www.linuxandubuntu.com/uploads/2/1/1/5/21152474/gnu-grub_orig.png -[4]:http://www.linuxandubuntu.com/uploads/2/1/1/5/21152474/runlevel_orig.png -[5]:http://www.linuxandubuntu.com/uploads/2/1/1/5/21152474/runlevel_1_orig.png diff --git a/translated/tech/20180115 How To Boot Into Linux Command Line.md b/translated/tech/20180115 How To Boot Into Linux Command Line.md new file mode 100644 index 0000000000..85aa06a78c --- /dev/null +++ b/translated/tech/20180115 How To Boot Into Linux Command Line.md @@ -0,0 +1,61 @@ +如何启动进入 Linux 命令行 +====== +![](http://www.linuxandubuntu.com/uploads/2/1/1/5/21152474/how-to-boot-into-linux-command-line_orig.jpg) + +可能有时候你需要或者不想使用 GUI,也就是没有 X,而是选择命令行启动 [Linux][1]。不管是什么原因,幸运的是,直接启动进入 Linux **命令行** 非常简单。在其他内核选项之后,它需要对引导参数进行简单的更改。此更改将系统引导到指定的运行级别。 + +### ​为什么要这样做? + +如果你的系统由于无效配置或者显示管理器损坏或任何可能导致 GUI 无法正常启动的情况而无法运行 Xorg,那么启动到命令行将允许你通过登录到终端进行故障排除(假设你知道要怎么开始),并能做任何你需要做的东西。引导到命令行也是一个很好的熟悉终端的方式,不然,你也可以为了好玩这么做。 + +### ​访问 GRUB 菜单 + +在启动时,你需要访问 GRUB 启动菜单。如果在每次启动计算机时菜单未设置为显示,那么可能需要在系统启动之前按住 SHIFT 键。在菜单中,需要选择 [Linux 发行版][2]条目。高亮显示后,按下 “e” 编辑引导参数。 + + [![zorin os grub menu](http://www.linuxandubuntu.com/uploads/2/1/1/5/21152474/gnu-grub_orig.png)][3] + + 较老的 GRUB 版本遵循类似的机制。启动管理器应提供有关如何编辑启动参数的说明。 + +### ​​指定运行级别 + +​编辑器将出现,你将看到 GRUB 解析到内核的选项。移动到以 “linux” 开头的行(旧的 GRUB 版本可能是 “kernel”,选择它并按照说明操作)。这指定了解析到内核的参数。在该行的末尾(可能会出现跨越多行,具体取决于分辨率),只需指定要引导的运行级别,即 3(多用户模式,纯文本)。 + + [![customize grub menu](http://www.linuxandubuntu.com/uploads/2/1/1/5/21152474/runlevel_orig.png)][4] + +按下 Ctrl-X 或 F10 将使用这些参数启动系统。开机和以前一样。唯一改变的是启动的运行级别。 + +​ + +这是启动后的页面: + + [![boot linux in command line](http://www.linuxandubuntu.com/uploads/2/1/1/5/21152474/runlevel_1_orig.png)][5] + +### 运行级别 + +你可以指定不同的运行级别,默认运行级别是 5。1 启动到“单用户”模式,它会启动进入 root shell。3 提供了一个多用户命令行系统。 + +### 从命令行切换 + +在某个时候,你可能想要再次运行显示管理器来使用 GUI,最快的方法是运行这个: +``` +$ sudo init 5 +``` + +就这么简单。就我个人而言,我发现命令行比使用 GUI 工具更令人兴奋和上手。不过,这只是我的个人偏好。 + +-------------------------------------------------------------------------------- + +via: http://www.linuxandubuntu.com/home/how-to-boot-into-linux-command-line + +作者:[LinuxAndUbuntu][a] +译者:[geekpi](https://github.com/geekpi) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:http://www.linuxandubuntu.com +[1]:http://www.linuxandubuntu.com/home/category/linux +[2]:http://www.linuxandubuntu.com/home/category/distros +[3]:http://www.linuxandubuntu.com/uploads/2/1/1/5/21152474/gnu-grub_orig.png +[4]:http://www.linuxandubuntu.com/uploads/2/1/1/5/21152474/runlevel_orig.png +[5]:http://www.linuxandubuntu.com/uploads/2/1/1/5/21152474/runlevel_1_orig.png From 6ec8d08f4dc718b50cad906c4de9ccefdc75d94e Mon Sep 17 00:00:00 2001 From: qhwdw Date: Tue, 30 Jan 2018 10:09:00 +0800 Subject: [PATCH 037/272] Translating by qhwdw --- .../tech/20141029 What does an idle CPU do.md | 91 +++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 sources/tech/20141029 What does an idle CPU do.md diff --git a/sources/tech/20141029 What does an idle CPU do.md b/sources/tech/20141029 What does an idle CPU do.md new file mode 100644 index 0000000000..98bb495634 --- /dev/null +++ b/sources/tech/20141029 What does an idle CPU do.md @@ -0,0 +1,91 @@ +[What does an idle CPU do?][1] +============================================================ + +In the [last post][2] I said the fundamental axiom of OS behavior is that at any given time, exactly one and only one task is active on a CPU. But if there's absolutely nothing to do, then what? + +It turns out that this situation is extremely common, and for most personal computers it's actually the norm: an ocean of sleeping processes, all waiting on some condition to wake up, while nearly 100% of CPU time is going into the mythical "idle task." In fact, if the CPU is consistently busy for a normal user, it's often a misconfiguration, bug, or malware. + +Since we can't violate our axiom, some task needs to be active on a CPU. First because it's good design: it would be unwise to spread special cases all over the kernel checking whether there is in fact an active task. A design is far better when there are no exceptions. Whenever you write an if statement, Nyan Cat cries. And second, we need to do something with all those idle CPUs, lest they get spunky and, you know, create Skynet. + +So to keep design consistency and be one step ahead of the devil, OS developers create an idle task that gets scheduled to run when there's no other work. We have seen in the Linux [boot process][3] that the idle task is process 0, a direct descendent of the very first instruction that runs when a computer is first turned on. It is initialized in [rest_init][4], where [init_idle_bootup_task][5] initializes the idle scheduling class. + +Briefly, Linux supports different scheduling classes for things like real-time processes, regular user processes, and so on. When it's time to choose a process to become the active task, these classes are queried in order of priority. That way, the nuclear reactor control code always gets to run before the web browser. Often, though, these classes return NULL, meaning they don't have a suitable process to run - they're all sleeping. But the idle scheduling class, which runs last, never fails: it always returns the idle task. + +That's all good, but let's get down to just what exactly this idle task is doing. So here is [cpu_idle_loop][6], courtesy of open source: + +cpu_idle_loop + +``` +while (1) { + while(!need_resched()) { + cpuidle_idle_call(); + } + + /* + [Note: Switch to a different task. We will return to this loop when the idle task is again selected to run.] + */ + schedule_preempt_disabled(); +} +``` + +I've omitted many details, and we'll look at task switching closely later on, but if you read the code you'll get the gist of it: as long as there's no need to reschedule, meaning change the active task, stay idle. Measured in elapsed time, this loop and its cousins in other OSes are probably the most executed pieces of code in computing history. For Intel processors, staying idle traditionally meant running the [halt][7] instruction: + +native_halt + +``` +static inline void native_halt(void) + { + asm volatile("hlt": : :"memory"); + } +``` + +hlt stops code execution in the processor and puts it in a halted state. It's weird to think that across the world millions and millions of Intel-like CPUs are spending the majority of their time halted, even while they're powered up. It's also not terribly efficient, energy wise, which led chip makers to develop deeper sleep states for processors, which trade off less power consumption for longer wake-up latency. The kernel's [cpuidle subsystem][8] is responsible for taking advantage of these power-saving modes. + +Now once we tell the CPU to halt, or sleep, we need to somehow bring it back to life. If you've read the [last post][9], you might suspect interrupts are involved, and indeed they are. Interrupts spur the CPU out of its halted state and back into action. So putting this all together, here's what your system mostly does as you read a fully rendered web page: + +![](https://manybutfinite.com/img/os/idle.png) + + + +Other interrupts besides the timer interrupt also get the processor moving again. That's what happens if you click on a web page, for example: your mouse issues an interrupt, its driver processes it, and suddenly a process is runnable because it has fresh input. At that point need_resched() returns true, and the idle task is booted out in favor of your browser. + +But let's stick to idleness in this post. Here's the idle loop over time: + +![](https://manybutfinite.com/img/os/idleCycles.png) + +In this example the timer interrupt was programmed by the kernel to happen every 4 milliseconds (ms). This is the tick period. That means we get 250 ticks per second, so the tick rate or tick frequency is 250 Hz. That's a typical value for Linux running on Intel processors, with 100 Hz being another crowd favorite. This is defined in the CONFIG_HZ option when you build the kernel. + +Now that looks like an awful lot of pointless work for an idle CPU, and it is. Without fresh input from the outside world, the CPU will remain stuck in this hellish nap getting woken up 250 times a second while your laptop battery is drained. If this is running in a virtual machine, we're burning both power and valuable cycles from the host CPU. + +The solution here is to have a [dynamic tick][10] so that when the CPU is idle, the timer interrupt is either [deactivated or reprogrammed][11] to happen at a point where the kernel knows there will be work to do (for example, a process might have a timer expiring in 5 seconds, so we must not sleep past that). This is also called tickless mode. + +Finally, suppose you have one active process in a system, for example a long-running CPU-intensive task. That's nearly identical to an idle system: these diagrams remain about the same, just substitute the one process for the idle task and the pictures are accurate. In that case it's still pointless to interrupt the task every 4 ms for no good reason: it's merely OS jitter slowing your work ever so slightly. Linux can also stop the fixed-rate tick in this one-process scenario, in what's called [adaptive-tick][12] mode. Eventually, a fixed-rate tick may be gone [altogether][13]. + +That's enough idleness for one post. The kernel's idle behavior is an important part of the OS puzzle, and it's very similar to other situations we'll see, so this helps us build the picture of a running kernel. More next week, [RSS][14] and [Twitter][15]. + +-------------------------------------------------------------------------------- + +via:https://manybutfinite.com/post/what-does-an-idle-cpu-do/ + +作者:[Gustavo Duarte][a] +译者:[译者ID](https://github.com/译者ID) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:http://duartes.org/gustavo/blog/about/ +[1]:https://manybutfinite.com/post/what-does-an-idle-cpu-do/ +[2]:https://manybutfinite.com/post/when-does-your-os-run +[3]:https://manybutfinite.com/post/kernel-boot-process +[4]:https://github.com/torvalds/linux/blob/v3.17/init/main.c#L393 +[5]:https://github.com/torvalds/linux/blob/v3.17/kernel/sched/core.c#L4538 +[6]:https://github.com/torvalds/linux/blob/v3.17/kernel/sched/idle.c#L183 +[7]:https://github.com/torvalds/linux/blob/v3.17/arch/x86/include/asm/irqflags.h#L52 +[8]:http://lwn.net/Articles/384146/ +[9]:https://manybutfinite.com/post/when-does-your-os-run +[10]:https://github.com/torvalds/linux/blob/v3.17/Documentation/timers/NO_HZ.txt#L17 +[11]:https://github.com/torvalds/linux/blob/v3.17/Documentation/timers/highres.txt#L215 +[12]:https://github.com/torvalds/linux/blob/v3.17/Documentation/timers/NO_HZ.txt#L100 +[13]:http://lwn.net/Articles/549580/ +[14]:https://manybutfinite.com/feed.xml +[15]:http://twitter.com/manybutfinite \ No newline at end of file From 93db9973e4e5a8b31669cc96e080670ae283312d Mon Sep 17 00:00:00 2001 From: qhwdw Date: Tue, 30 Jan 2018 10:10:07 +0800 Subject: [PATCH 038/272] Translating by qhwdw --- sources/tech/20141029 What does an idle CPU do.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sources/tech/20141029 What does an idle CPU do.md b/sources/tech/20141029 What does an idle CPU do.md index 98bb495634..991f40d6c0 100644 --- a/sources/tech/20141029 What does an idle CPU do.md +++ b/sources/tech/20141029 What does an idle CPU do.md @@ -1,4 +1,4 @@ -[What does an idle CPU do?][1] +Translating by qhwdw [What does an idle CPU do?][1] ============================================================ In the [last post][2] I said the fundamental axiom of OS behavior is that at any given time, exactly one and only one task is active on a CPU. But if there's absolutely nothing to do, then what? From 4679b4cf2b97a80f67ed36e71b4dd5f9c76ac3ff Mon Sep 17 00:00:00 2001 From: wxy Date: Tue, 30 Jan 2018 11:29:53 +0800 Subject: [PATCH 039/272] =?UTF-8?q?=E5=88=A0=E9=99=A4=E9=94=99=E8=AF=AF?= =?UTF-8?q?=E4=BF=9D=E7=95=99=E7=9A=84=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...0140523 Tail Calls Optimization and ES6.md | 173 ------------------ 1 file changed, 173 deletions(-) delete mode 100644 sources/tech/20140523 Tail Calls Optimization and ES6.md diff --git a/sources/tech/20140523 Tail Calls Optimization and ES6.md b/sources/tech/20140523 Tail Calls Optimization and ES6.md deleted file mode 100644 index 2999c606d2..0000000000 --- a/sources/tech/20140523 Tail Calls Optimization and ES6.md +++ /dev/null @@ -1,173 +0,0 @@ -#Translating by qhwdw [Tail Calls, Optimization, and ES6][1] - - -In this penultimate post about the stack, we take a quick look at tail calls, compiler optimizations, and the proper tail calls landing in the newest version of JavaScript. - -A tail call happens when a function F makes a function call as its final action. At that point F will do absolutely no more work: it passes the ball to whatever function is being called and vanishes from the game. This is notable because it opens up the possibility of tail call optimization: instead of [creating a new stack frame][6] for the function call, we can simply reuse F's stack frame, thereby saving stack space and avoiding the work involved in setting up a new frame. Here are some examples in C and their results compiled with [mild optimization][7]: - -Simple Tail Calls[download][2] - -``` -int add5(int a) -{ - return a + 5; -} - -int add10(int a) -{ - int b = add5(a); // not tail - return add5(b); // tail -} - -int add5AndTriple(int a){ - int b = add5(a); // not tail - return 3 * add5(a); // not tail, doing work after the call -} - -int finicky(int a){ - if (a > 10){ - return add5AndTriple(a); // tail - } - - if (a > 5){ - int b = add5(a); // not tail - return finicky(b); // tail - } - - return add10(a); // tail -} -``` - -You can normally spot tail call optimization (hereafter, TCO) in compiler output by seeing a [jump][8] instruction where a [call][9] would have been expected. At runtime TCO leads to a reduced call stack. - -A common misconception is that tail calls are necessarily [recursive][10]. That's not the case: a tail call may be recursive, such as in finicky() above, but it need not be. As long as caller F is completely done at the call site, we've got ourselves a tail call. Whether it can be optimized is a different question whose answer depends on your programming environment. - -"Yes, it can, always!" is the best answer we can hope for, which is famously the case for Scheme, as discussed in [SICP][11] (by the way, if when you program you don't feel like "a Sorcerer conjuring the spirits of the computer with your spells," I urge you to read that book). It's also the case for [Lua][12]. And most importantly, it is the case for the next version of JavaScript, ES6, whose spec does a good job defining [tail position][13] and clarifying the few conditions required for optimization, such as [strict mode][14]. When a language guarantees TCO, it supports proper tail calls. - -Now some of us can't kick that C habit, heart bleed and all, and the answer there is a more complicated "sometimes" that takes us into compiler optimization territory. We've seen the [simple examples][15] above; now let's resurrect our factorial from [last post][16]: - -Recursive Factorial[download][3] - -``` -#include - -int factorial(int n) -{ - int previous = 0xdeadbeef; - - if (n == 0 || n == 1) { - return 1; - } - - previous = factorial(n-1); - return n * previous; -} - -int main(int argc) -{ - int answer = factorial(5); - printf("%d\n", answer); -} -``` - -So, is line 11 a tail call? It's not, because of the multiplication by n afterwards. But if you're not used to optimizations, gcc's [result][17] with [O2 optimization][18] might shock you: not only it transforms factorial into a [recursion-free loop][19], but the factorial(5) call is eliminated entirely and replaced by a [compile-time constant][20] of 120 (5! == 120). This is why debugging optimized code can be hard sometimes. On the plus side, if you call this function it will use a single stack frame regardless of n's initial value. Compiler algorithms are pretty fun, and if you're interested I suggest you check out [Building an Optimizing Compiler][21] and [ACDI][22]. - -However, what happened here was not tail call optimization, since there was no tail call to begin with. gcc outsmarted us by analyzing what the function does and optimizing away the needless recursion. The task was made easier by the simple, deterministic nature of the operations being done. By adding a dash of chaos (e.g., getpid()) we can throw gcc off: - -Recursive PID Factorial[download][4] - -``` -#include -#include -#include - -int pidFactorial(int n) -{ - if (1 == n) { - return getpid(); // tail - } - - return n * pidFactorial(n-1) * getpid(); // not tail -} - -int main(int argc) -{ - int answer = pidFactorial(5); - printf("%d\n", answer); -} -``` - -Optimize that, unix fairies! So now we have a regular [recursive call][23] and this function allocates O(n) stack frames to do its work. Heroically, gcc still does [TCO for getpid][24] in the recursion base case. If we now wished to make this function tail recursive, we'd need a slight change: - -tailPidFactorial.c[download][5] - -``` -#include -#include -#include - -int tailPidFactorial(int n, int acc) -{ - if (1 == n) { - return acc * getpid(); // not tail - } - - acc = (acc * getpid() * n); - return tailPidFactorial(n-1, acc); // tail -} - -int main(int argc) -{ - int answer = tailPidFactorial(5, 1); - printf("%d\n", answer); -} -``` - -The accumulation of the result is now [a loop][25] and we've achieved true TCO. But before you go out partying, what can we say about the general case in C? Sadly, while good C compilers do TCO in a number of cases, there are many situations where they cannot do it. For example, as we saw in our [function epilogues][26], the caller is responsible for cleaning up the stack after a function call using the standard C calling convention. So if function F takes two arguments, it can only make TCO calls to functions taking two or fewer arguments. This is one among many restrictions. Mark Probst wrote an excellent thesis discussing [Proper Tail Recursion in C][27] where he discusses these issues along with C stack behavior. He also does [insanely cool juggling][28]. - -"Sometimes" is a rocky foundation for any relationship, so you can't rely on TCO in C. It's a discrete optimization that may or may not take place, rather than a language feature like proper tail calls, though in practice the compiler will optimize the vast majority of cases. But if you must have it, say for transpiling Scheme into C, you will [suffer][29]. - -Since JavaScript is now the most popular transpilation target, proper tail calls become even more important there. So kudos to ES6 for delivering it along with many other significant improvements. It's like Christmas for JS programmers. - -This concludes our brief tour of tail calls and compiler optimization. Thanks for reading and see you next time. - --------------------------------------------------------------------------------- - -via:https://manybutfinite.com/post/tail-calls-optimization-es6/ - -作者:[Gustavo Duarte][a] -译者:[译者ID](https://github.com/译者ID) -校对:[校对者ID](https://github.com/校对者ID) - -本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 - -[a]:http://duartes.org/gustavo/blog/about/ -[1]:https://manybutfinite.com/post/tail-calls-optimization-es6/ -[2]:https://manybutfinite.com/code/x86-stack/tail.c -[3]:https://manybutfinite.com/code/x86-stack/factorial.c -[4]:https://manybutfinite.com/code/x86-stack/pidFactorial.c -[5]:https://manybutfinite.com/code/x86-stack/tailPidFactorial.c -[6]:https://manybutfinite.com/post/journey-to-the-stack -[7]:https://github.com/gduarte/blog/blob/master/code/x86-stack/asm-tco.sh -[8]:https://github.com/gduarte/blog/blob/master/code/x86-stack/tail-tco.s#L27 -[9]:https://github.com/gduarte/blog/blob/master/code/x86-stack/tail.s#L37-L39 -[10]:https://manybutfinite.com/post/recursion/ -[11]:http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-11.html -[12]:http://www.lua.org/pil/6.3.html -[13]:https://people.mozilla.org/~jorendorff/es6-draft.html#sec-tail-position-calls -[14]:https://people.mozilla.org/~jorendorff/es6-draft.html#sec-strict-mode-code -[15]:https://github.com/gduarte/blog/blob/master/code/x86-stack/tail.c -[16]:https://manybutfinite.com/post/recursion/ -[17]:https://github.com/gduarte/blog/blob/master/code/x86-stack/factorial-o2.s -[18]:https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html -[19]:https://github.com/gduarte/blog/blob/master/code/x86-stack/factorial-o2.s#L16-L19 -[20]:https://github.com/gduarte/blog/blob/master/code/x86-stack/factorial-o2.s#L38 -[21]:http://www.amazon.com/Building-Optimizing-Compiler-Bob-Morgan-ebook/dp/B008COCE9G/ -[22]:http://www.amazon.com/Advanced-Compiler-Design-Implementation-Muchnick-ebook/dp/B003VM7GGK/ -[23]:https://github.com/gduarte/blog/blob/master/code/x86-stack/pidFactorial-o2.s#L20 -[24]:https://github.com/gduarte/blog/blob/master/code/x86-stack/pidFactorial-o2.s#L43 -[25]:https://github.com/gduarte/blog/blob/master/code/x86-stack/tailPidFactorial-o2.s#L22-L27 -[26]:https://manybutfinite.com/post/epilogues-canaries-buffer-overflows/ -[27]:http://www.complang.tuwien.ac.at/schani/diplarb.ps -[28]:http://www.complang.tuwien.ac.at/schani/jugglevids/index.html -[29]:http://en.wikipedia.org/wiki/Tail_call#Through_trampolining \ No newline at end of file From 19e569c1fadb3f30b7d9f4cbd44fc7ceb7d17bb8 Mon Sep 17 00:00:00 2001 From: wxy Date: Tue, 30 Jan 2018 12:17:20 +0800 Subject: [PATCH 040/272] PRF:20121211 Python Nmon Analyzer- moving away from excel macros.md @lujun9972 --- ...Analyzer- moving away from excel macros.md | 63 ++++++++++--------- 1 file changed, 33 insertions(+), 30 deletions(-) diff --git a/translated/tech/20121211 Python Nmon Analyzer- moving away from excel macros.md b/translated/tech/20121211 Python Nmon Analyzer- moving away from excel macros.md index c772ceff73..351c9c1f75 100644 --- a/translated/tech/20121211 Python Nmon Analyzer- moving away from excel macros.md +++ b/translated/tech/20121211 Python Nmon Analyzer- moving away from excel macros.md @@ -1,36 +1,40 @@ Python 版的 Nmon 分析器:让你远离 excel 宏 ====== -[Nigel's monitor][1],也叫做 "Nmon",是一个很好的监控,记录和分析 Linux/*nix 系统性能随时间变化的工具。Nmon 最初由 IBM 开发并于 2009 年夏天开源。时至今日 Nmon 已经在所有 linux 平台和架构上都可用了。它提供了大量的实时工具来可视化当前系统统计信息,这些统计信息包括 CPU,RAM,网络和磁盘 I/O。然而,Nmon 最棒的特性是可以随着时间的推移记录系统性能快照。 -比如:`nmon -f -s 1`。 -![nmon CPU and Disk utilization][2] -会创建一个日志文件,该日志文件最开头是一些系统的元数据 T( 章节 AAA - BBBV),后面是定时抓取的监控系统属性的快照,比如 CPU 和内存的使用情况。这个文件很难直接由电子表格应用来处理,因此诞生了 [Nmon_Analyzer][3] excel 宏。如果你用的是 Windows/Mac 并安装了 Microsoft Office,那么这个工具非常不错。如果没有这个环境那也可以使用 Nmon2rrd 工具,这个工具能将日志文件转换 RRD 输入文件,进而生成图形。这个过程很死板而且有点麻烦。现在出现了一个更灵活的工具,像你们介绍一下 pyNmonAnalyzer,它一个可定制化的解决方案来生成结构化的 CSV 文件和基于 [matplotlib][4] 生成图片的简单 HTML 报告。 -### 入门介绍: +[Nigel's monitor][1],也叫做 “Nmon”,是一个很好的监控、记录和分析 Linux/*nix 系统性能随时间变化的工具。Nmon 最初由 IBM 开发并于 2009 年夏天开源。时至今日 Nmon 已经在所有 Linux 平台和架构上都可用了。它提供了很棒的当前系统统计信息的基于命令行的实时可视化报告,这些统计信息包括 CPU、RAM、网络和磁盘 I/O。然而,Nmon 最棒的特性是可以随着时间的推移记录系统性能快照。 + +比如:`nmon -f -s 1`。 + +![nmon CPU and Disk utilization][2] + +会创建一个日志文件,该日志文件最开头是一些系统的元数据(AAA - BBBV 部分),后面是所监控的系统属性的定时快照,比如 CPU 和内存的使用情况。这个输出的文件很难直接由电子表格应用来处理,因此诞生了 [Nmon_Analyzer][3] excel 宏。如果你用的是 Windows/Mac 并安装了 Microsoft Office,那么这个工具非常不错。如果没有这个环境那也可以使用 Nmon2rrd 工具,这个工具能将日志文件转换 RRD 输入文件,进而生成图形。这个过程很死板而且有点麻烦。现在出现了一个更灵活的工具,我向你们介绍一下 pyNmonAnalyzer,它提供了一个可定制化的解决方案来生成结构化的 CSV 文件和带有用 [matplotlib][4] 生成的图片的简单 HTML 报告。 + +### 入门介绍 系统需求: + 从名字中就能看出我们需要有 python。此外 pyNmonAnalyzer 还依赖于 matplotlib 和 numpy。若你使用的是 debian 衍生的系统,则你需要先安装这些包: -``` -$> sudo apt-get install python-numpy python-matplotlib ``` - -##### 获取 pyNmonAnalyzer: - -你可页克隆 git 仓库: -``` -$> git clone git@github.com:madmaze/pyNmonAnalyzer.git - +$ sudo apt-get install python-numpy python-matplotlib ``` -或者 +#### 获取 pyNmonAnalyzer: -直接从这里下载:[pyNmonAnalyzer-0.1.zip][5] +你可以克隆 git 仓库: -接下来我们需要一个 Nmon 文件,如果没有的话,可以使用发行版中提供的实例或者自己录制一个样本:`nmon -F test.nmon -s 1 -c 120`,会录制每个 1 秒录制一次,供录制 120 个快照道 test.nmon 文件中 .nmon。 +``` +$ git clone git@github.com:madmaze/pyNmonAnalyzer.git +``` + +或者,直接从这里下载:[pyNmonAnalyzer-0.1.zip][5] 。 + +接下来我们需要一个 Nmon 文件,如果没有的话,可以使用发行版中提供的实例或者自己录制一个样本:`nmon -F test.nmon -s 1 -c 120`,会录制 120 个快照,每秒一个,存储到 test.nmon 文件中。 让我们来看看基本的帮助信息: + ``` -$> ./pyNmonAnalyzer.py -h +$ ./pyNmonAnalyzer.py -h usage: pyNmonAnalyzer.py [-h] [-x] [-d] [-o OUTDIR] [-c] [-b] [-r CONFFNAME] input_file @@ -53,30 +57,29 @@ optional arguments: -r CONFFNAME, --reportConfig CONFFNAME Report config file, if none exists: we will write the default config file out (Default: ./report.config) - ``` 该工具有两个主要的选项 - 1。将 nmon 文件传唤成一系列独立的 CSV 文件 - 2。使用 matplotlib 生成带图形的 HTML 报告 - +1. 将 nmon 文件传唤成一系列独立的 CSV 文件 +2. 使用 matplotlib 生成带图形的 HTML 报告 下面命令既会生成 CSV 文件,也会生成 HTML 报告: -``` -$> ./pyNmonAnalyzer.py -c -b test.nmon +``` +$ ./pyNmonAnalyzer.py -c -b test.nmon ``` -这会常见一个 `。/data` 目录,其中有一个存放 CSV 文件的目录 ("。/data/csv/"),一个存放 PNG 图片的目录 ("。/data/img/") 以及一个 HTML 报告 ("。/data/report.html")。 +这会创建一个 `./data` 目录,其中有一个存放 CSV 文件的目录 (`./data/csv/`),一个存放 PNG 图片的目录 (`./data/img/`) 以及一个 HTML 报告 (`./data/report.html`)。 -默认情况下,HTML 报告中会用图片展示 CPU,磁盘繁忙度,内存使用情况和网络传输情况。所有这些都定义在一个自解释的配置文件中 ("report.config")。目前这个工具 h 那不是特别的灵活,因为 CPU 和 MEM 除了 on 和 off 外,无法做其他的配置。不过下一步将会改进作图的方法并允许用户灵活地指定针对哪些数据使用哪种作图方法。 +默认情况下,HTML 报告中会用图片展示 CPU、磁盘繁忙程度、内存使用情况和网络传输情况。所有这些都定义在一个不言自明的配置文件中 (`report.config`)。目前这个工具还不是特别的灵活,因为 CPU 和 MEM 除了 `on` 和 `off` 外,无法做其他的配置。不过下一步将会改进作图的方法并允许用户灵活地指定针对哪些数据使用哪种作图方法。 -### 报告的例子: +### 报告的例子 -[![pyNmonAnalyzer Graph output][6] -**Click to see the full Report**][7] +![pyNmonAnalyzer Graph output][6] + +[点击查看完整报告][7] 目前这些报告还十分的枯燥而且只能打印出基本的几种标记图表,不过它的功能还在不断的完善中。目前在开发的是一个向导来让配置调整变得更容易。如果有任何建议,找到任何 bug 或者有任何功能需求,欢迎与我交流。 @@ -86,7 +89,7 @@ via: https://matthiaslee.com/python-nmon-analyzer-moving-away-from-excel-macros/ 作者:[Matthias Lee][a] 译者:[lujun9972](https://github.com/lujun9972) -校对:[校对者ID](https://github.com/校对者ID) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 From c8e79867806b38fc2e1a5276b7b9cee709e8e4ca Mon Sep 17 00:00:00 2001 From: wxy Date: Tue, 30 Jan 2018 12:17:42 +0800 Subject: [PATCH 041/272] PUB:20121211 Python Nmon Analyzer- moving away from excel macros.md @lujun9972 https://linux.cn/article-9294-1.html --- ...0121211 Python Nmon Analyzer- moving away from excel macros.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename {translated/tech => published}/20121211 Python Nmon Analyzer- moving away from excel macros.md (100%) diff --git a/translated/tech/20121211 Python Nmon Analyzer- moving away from excel macros.md b/published/20121211 Python Nmon Analyzer- moving away from excel macros.md similarity index 100% rename from translated/tech/20121211 Python Nmon Analyzer- moving away from excel macros.md rename to published/20121211 Python Nmon Analyzer- moving away from excel macros.md From 3d66743cf801d8b49afab12d59c3b3a582d86b6f Mon Sep 17 00:00:00 2001 From: darksun Date: Tue, 30 Jan 2018 13:04:57 +0800 Subject: [PATCH 042/272] =?UTF-8?q?=E9=80=89=E9=A2=98:=20Advanced=20Python?= =?UTF-8?q?=20Debugging=20with=20pdb?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...0129 Advanced Python Debugging with pdb.md | 363 ++++++++++++++++++ 1 file changed, 363 insertions(+) create mode 100644 sources/tech/20180129 Advanced Python Debugging with pdb.md diff --git a/sources/tech/20180129 Advanced Python Debugging with pdb.md b/sources/tech/20180129 Advanced Python Debugging with pdb.md new file mode 100644 index 0000000000..80f17e23a3 --- /dev/null +++ b/sources/tech/20180129 Advanced Python Debugging with pdb.md @@ -0,0 +1,363 @@ +translating by lujun9972 +Advanced Python Debugging with pdb +====== + +![](https://process.filestackapi.com/cache=expiry:max/resize=width:700/compress/nygTCcWMQuyCFaOrlEnh) + +Python's built-in [`pdb`][1] module is extremely useful for interactive debugging, but has a bit of a learning curve. For a long time, I stuck to basic `print`-debugging and used `pdb` on a limited basis, which meant I missed out on a lot of features that would have made debugging faster and easier. + +In this post I will show you a few tips I've picked up over the years to level up my interactive debugging skills. + +## Print debugging vs. interactive debugging + +First, why would you want to use an interactive debugger instead of inserting `print` or `logging` statements into your code? + +With `pdb`, you have a lot more flexibility to run, resume, and alter the execution of your program without touching the underlying source. Once you get good at this, it means more time spent diving into issues and less time context switching back and forth between your editor and the command line. + +Also, by not touching the underlying source code, you will have the ability to step into third party code (e.g. modules installed from PyPI) and the standard library. + +## Post-mortem debugging + +The first workflow I used after moving away from `print` debugging was `pdb`'s "post-mortem debugging" mode. This is where you run your program as usual, but whenever an unhandled exception is thrown, you drop down into the debugger to poke around in the program state. After that, you attempt to make a fix and repeat the process until the problem is resolved. + +You can run an existing script with the post-mortem debugger by using Python's `-mpdb` option: +``` +python3 -mpdb path/to/script.py + +``` + +From here, you are dropped into a `(Pdb)` prompt. To start execution, you use the `continue` or `c` command. If the program executes successfully, you will be taken back to the `(Pdb)` prompt where you can restart the execution again. At this point, you can use `quit` / `q` or Ctrl+D to exit the debugger. + +If the program throws an unhandled exception, you'll also see a `(Pdb)` prompt, but with the program execution stopped at the line that threw the exception. From here, you can run Python code and debugger commands at the prompt to inspect the current program state. + +## Testing our basic workflow + +To see how these basic debugging steps work, I'll be using this (buggy) program: +``` +import random + +MAX = 100 + +def main(num_loops=1000): + for i in range(num_loops): + num = random.randint(0, MAX) + denom = random.randint(0, MAX) + result = num / denom + print("{} divided by {} is {:.2f}".format(num, denom, result)) + +if __name__ == "__main__": + import sys + arg = sys.argv[-1] + if arg.isdigit(): + main(arg) + else: + main() + +``` + +We're expecting the program to do some basic math operations on random numbers in a loop and print the result. Try running it normally and you will see one of the bugs: +``` +$ python3 script.py +2 divided by 30 is 0.07 +65 divided by 41 is 1.59 +0 divided by 70 is 0.00 +... +38 divided by 26 is 1.46 +Traceback (most recent call last): + File "script.py", line 16, in + main() + File "script.py", line 7, in main + result = num / denom +ZeroDivisionError: division by zero + +``` + +Let's try post-mortem debugging this error: +``` +$ python3 -mpdb script.py +> ./src/script.py(1)() +-> import random +(Pdb) c +49 divided by 46 is 1.07 +... +Traceback (most recent call last): + File "/usr/lib/python3.4/pdb.py", line 1661, in main + pdb._runscript(mainpyfile) + File "/usr/lib/python3.4/pdb.py", line 1542, in _runscript + self.run(statement) + File "/usr/lib/python3.4/bdb.py", line 431, in run + exec(cmd, globals, locals) + File "", line 1, in + File "./src/script.py", line 1, in + import random + File "./src/script.py", line 7, in main + result = num / denom +ZeroDivisionError: division by zero +Uncaught exception. Entering post mortem debugging +Running 'cont' or 'step' will restart the program +> ./src/script.py(7)main() +-> result = num / denom +(Pdb) num +76 +(Pdb) denom +0 +(Pdb) random.randint(0, MAX) +56 +(Pdb) random.randint(0, MAX) +79 +(Pdb) random.randint(0, 1) +0 +(Pdb) random.randint(1, 1) +1 + +``` + +Once the post-mortem debugger kicks in, we can inspect all of the variables in the current frame and even run new code to help us figure out what's wrong and attempt to make a fix. + +## Dropping into the debugger from Python code using `pdb.set_trace` + +Another technique that I used early on, after starting to use `pdb`, was forcing the debugger to run at a certain line of code before an error occurred. This is a common next step after learning post-mortem debugging because it feels similar to debugging with `print` statements. + +For example, in the above code, if we want to stop execution before the division operation, we could add a `pdb.set_trace` call to our program here: +``` + import pdb; pdb.set_trace() + result = num / denom + +``` + +And then run our program without `-mpdb`: +``` +$ python3 script.py +> ./src/script.py(10)main() +-> result = num / denom +(Pdb) num +94 +(Pdb) denom +19 + +``` + +The problem with this method is that you have to constantly drop these statements into your source code, remember to remove them afterwards, and switch between running your code with `python` vs. `python -mpdb`. + +Using `pdb.set_trace` gets the job done, but **breakpoints** are an even more flexible way to stop the debugger at any line (even third party or standard library code), without needing to modify any source code. Let's learn about breakpoints and a few other useful commands. + +## Debugger commands + +There are over 30 commands you can give to the interactive debugger, a list that can be seen by using the `help` command when at the `(Pdb)` prompt: +``` +(Pdb) help + +Documented commands (type help ): +======================================== +EOF c d h list q rv undisplay +a cl debug help ll quit s unt +alias clear disable ignore longlist r source until +args commands display interact n restart step up +b condition down j next return tbreak w +break cont enable jump p retval u whatis +bt continue exit l pp run unalias where + +``` + +You can use `help ` for more information on a given command. + +Instead of walking through each command, I'll list out the ones I've found most useful and what arguments they take. + +**Setting breakpoints** : + + * `l(ist)`: displays the source code of the currently running program, with line numbers, for the 10 lines around the current statement. + * `l 1,999`: displays the source code of lines 1-999. I regularly use this to see the source for the entire program. If your program only has 20 lines, it'll just show all 20 lines. + * `b(reakpoint)`: displays a list of current breakpoints. + * `b 10`: set a breakpoint at line 10. Breakpoints are referred to by a numeric ID, starting at 1. + * `b main`: set a breakpoint at the function named `main`. The function name must be in the current scope. You can also set breakpoints on functions in other modules in the current scope, e.g. `b random.randint`. + * `b script.py:10`: sets a breakpoint at line 10 in `script.py`. This gives you another way to set breakpoints in another module. + * `clear`: clears all breakpoints. + * `clear 1`: clear breakpoint 1. + + + +**Stepping through execution** : + + * `c(ontinue)`: execute until the program finishes, an exception is thrown, or a breakpoint is hit. + * `s(tep)`: execute the next line, whatever it is (your code, stdlib, third party code, etc.). Use this when you want to step down into function calls you're interested in. + * `n(ext)`: execute the next line in the current function (will not step into downstream function calls). Use this when you're only interested in the current function. + * `r(eturn)`: execute the remaining lines in the current function until it returns. Use this to skip over the rest of the function and go up a level. For example, if you've stepped down into a function by mistake. + * `unt(il) [lineno]`: execute until the current line exceeds the current line number. This is useful when you've stepped into a loop but want to let the loop continue executing without having to manually step through every iteration. Without any argument, this command behaves like `next` (with the loop skipping behavior, once you've stepped through the loop body once). + + + +**Moving up and down the stack** : + + * `w(here)`: shows an annotated view of the stack trace, with your current frame marked by `>`. + * `u(p)`: move up one frame in the current stack trace. For example, when post-mortem debugging, you'll start off on the lowest level of the stack and typically want to move `up` a few times to help figure out what went wrong. + * `d(own)`: move down one frame in the current stack trace. + + + +**Additional commands and tips** : + + * `pp `: This will "pretty print" the result of the given expression using the [`pprint`][2] module. Example: + + +``` +(Pdb) stuff = "testing the pp command in pdb with a big list of strings" +(Pdb) pp [(i, x) for (i, x) in enumerate(stuff.split())] +[(0, 'testing'), + (1, 'the'), + (2, 'pp'), + (3, 'command'), + (4, 'in'), + (5, 'pdb'), + (6, 'with'), + (7, 'a'), + (8, 'big'), + (9, 'list'), + (10, 'of'), + (11, 'strings')] + +``` + + * `!`: sometimes the Python code you run in the debugger will be confused for a command. For example `c = 1` will trigger the `continue` command. To force the debugger to execute Python code, prefix the line with `!`, e.g. `!c = 1`. + + * Pressing the Enter key at the `(Pdb)` prompt will execute the previous command again. This is most useful after the `s`/`n`/`r`/`unt` commands to quickly step through execution line-by-line. + + * You can run multiple commands on one line by separating them with `;;`, e.g. `b 8 ;; c`. + + * The `pdb` module can take multiple `-c` arguments on the command line to execute commands as soon as the debugger starts. + + + + +Example: +``` +python3 -mpdb -cc script.py # run the program without you having to enter an initial "c" at the prompt +python3 -mpdb -c "b 8" -cc script.py # sets a breakpoint on line 8 and runs the program + +``` + +## Restart behavior + +Another thing that can shave time off debugging is understanding how `pdb`'s restart behavior works. You may have noticed that after execution stops, `pdb` will give a message like, "The program finished and will be restarted," or "The script will be restarted." When I first started using `pdb`, I would always quit and re-run `python -mpdb ...` to make sure that my code changes were getting picked up, which was unnecessary in most cases. + +When `pdb` says it will restart the program, or when you use the `restart` command, code changes to the script you're debugging will be reloaded automatically. Breakpoints will still be set after reloading, but may need to be cleared and re-set due to line numbers shifting. Code changes to other imported modules will not be reloaded -- you will need to `quit` and re-run the `-mpdb` command to pick those up. + +## Watches + +One feature you may miss from other interactive debuggers is the ability to "watch" a variable change throughout the program's execution. `pdb` does not include a watch command by default, but you can get something similar by using `commands`, which lets you run arbitrary Python code whenever a breakpoint is hit. + +To watch what happens to the `denom` variable in our example program: +``` +$ python3 -mpdb script.py +> ./src/script.py(1)() +-> import random +(Pdb) b 9 +Breakpoint 1 at ./src/script.py:9 +(Pdb) commands +(com) silent +(com) print("DENOM: {}".format(denom)) +(com) c +(Pdb) c +DENOM: 77 +71 divided by 77 is 0.92 +DENOM: 27 +100 divided by 27 is 3.70 +DENOM: 10 +82 divided by 10 is 8.20 +DENOM: 20 +... + +``` + +We first set a breakpoint (which is assigned ID 1), then use `commands` to start entering a block of commands. These commands function as if you had typed them at the `(Pdb)` prompt. They can be either Python code or additional `pdb` commands. + +Once we start the `commands` block, the prompt changes to `(com)`. The `silent` command means the following commands will not be echoed back to the screen every time they're executed, which makes reading the output a little easier. + +After that, we run a `print` statement to inspect the variable, similar to what we might do when `print` debugging. Finally, we end with a `c` to continue execution, which ends the command block. Typing `c` again at the `(Pdb)` prompt starts execution and we see our new `print` statement running. + +If you'd rather stop execution instead of continuing, you can use `end` instead of `c` in the command block. + +## Running pdb from the interpreter + +Another way to run `pdb` is via the interpreter, which is useful when you're experimenting interactively and would like to drop into `pdb` without running a standalone script. + +For post-mortem debugging, all you need is a call to `pdb.pm()` after an exception has occurred: +``` +$ python3 +>>> import script +>>> script.main() +17 divided by 60 is 0.28 +... +56 divided by 94 is 0.60 +Traceback (most recent call last): + File "", line 1, in + File "./src/script.py", line 9, in main + result = num / denom +ZeroDivisionError: division by zero +>>> import pdb +>>> pdb.pm() +> ./src/script.py(9)main() +-> result = num / denom +(Pdb) num +4 +(Pdb) denom +0 + +``` + +If you want to step through normal execution instead, use the `pdb.run()` function: +``` +$ python3 +>>> import script +>>> import pdb +>>> pdb.run("script.main()") +> (1)() +(Pdb) b script:6 +Breakpoint 1 at ./src/script.py:6 +(Pdb) c +> ./src/script.py(6)main() +-> for i in range(num_loops): +(Pdb) n +> ./src/script.py(7)main() +-> num = random.randint(0, MAX) +(Pdb) n +> ./src/script.py(8)main() +-> denom = random.randint(0, MAX) +(Pdb) n +> ./src/script.py(9)main() +-> result = num / denom +(Pdb) n +> ./src/script.py(10)main() +-> print("{} divided by {} is {:.2f}".format(num, denom, result)) +(Pdb) n +66 divided by 70 is 0.94 +> ./src/script.py(6)main() +-> for i in range(num_loops): + +``` + +This one is a little trickier than `-mpdb` because you don't have the ability to step through an entire program. Instead, you'll need to manually set a breakpoint, e.g. on the first statement of the function you're trying to execute. + +## Conclusion + +Hopefully these tips have given you a few new ideas on how to use `pdb` more effectively. After getting a handle on these, you should be able to pick up the [other commands][3] and start customizing `pdb` via a `.pdbrc` file ([example][4]). + +You can also look into other front-ends for debugging, like [pdbpp][5], [pudb][6], and [ipdb][7], or GUI debuggers like the one included in PyCharm. Happy debugging! + +-------------------------------------------------------------------------------- + +via: https://www.codementor.io/stevek/advanced-python-debugging-with-pdb-g56gvmpfa + +作者:[Steven Kryskalla][a] +译者:[lujun9972](https://github.com/lujun9972) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://www.codementor.io/stevek +[1]:https://docs.python.org/3/library/pdb.html +[2]:https://docs.python.org/3/library/pprint.html +[3]:https://docs.python.org/3/library/pdb.html#debugger-commands +[4]:https://nedbatchelder.com/blog/200704/my_pdbrc.html +[5]:https://pypi.python.org/pypi/pdbpp/ +[6]:https://pypi.python.org/pypi/pudb/ +[7]:https://pypi.python.org/pypi/ipdb From 2d9c866005ac9cc6c5df90965694d129640cb3bf Mon Sep 17 00:00:00 2001 From: darksun Date: Tue, 30 Jan 2018 13:08:27 +0800 Subject: [PATCH 043/272] =?UTF-8?q?=E9=80=89=E9=A2=98:=20How=20to=20use=20?= =?UTF-8?q?LXD=20instance=20types?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../20180129 How to use LXD instance types.md | 225 ++++++++++++++++++ 1 file changed, 225 insertions(+) create mode 100644 sources/tech/20180129 How to use LXD instance types.md diff --git a/sources/tech/20180129 How to use LXD instance types.md b/sources/tech/20180129 How to use LXD instance types.md new file mode 100644 index 0000000000..028c87ec4e --- /dev/null +++ b/sources/tech/20180129 How to use LXD instance types.md @@ -0,0 +1,225 @@ +How to use LXD instance types +====== +**Background** : LXD is a hypervisor that manages machine containers on Linux distributions. You install LXD on your Linux distribution and then you can launch machine containers into your distribution running all sort of (other) Linux distributions. + +When you launch a new LXD container, there is a parameter for an instance type. Here it is, +``` +$ lxc launch --help +Usage: lxc launch [ :] [:][] [--ephemeral|-e] [--profile|-p ...] [--config|-c ...] [--type|-t ] + +Create and start containers from images. + +Not specifying -p will result in the default profile. +Specifying "-p" with no argument will result in no profile. + +Examples: + lxc launch ubuntu:16.04 u1 + +Options: + -c, --config (= map[]) Config key/value to apply to the new container + --debug (= false) Enable debug mode + -e, --ephemeral (= false) Ephemeral container + --force-local (= false) Force using the local unix socket + --no-alias (= false) Ignore aliases when determining what command to run + -p, --profile (= []) Profile to apply to the new container +**-t (= "") Instance type** + --verbose (= false) Enable verbose mode +``` + +What do we put for Instance type? Here is the documentation, + + + +Simply put, an instance type is just a mnemonic shortcut for specific pair of CPU cores and RAM memory settings. For CPU you specify the number of cores and for RAM memory the amount in GB (assuming your own computer has enough cores and RAM so that LXD can allocate them to the newly created container). + +You would need an instance type if you want to create a machine container that resembles in the specs as close as possible what you will be installing later on, on AWS (Amazon), Azure (Microsoft) or GCE (Google). + +The instance type can have any of the following forms, + + * `` for example: **t2.micro** (LXD figures out that this refers to AWS t2.micro, therefore 1 core, 1GB RAM). + * `:` for example, **aws:t2.micro** (LXD quickly looks into the AWS types, therefore 1core, 1GB RAM). + * `c-m` for example, **c1-m1** (LXD explicitly allocates one core, and 1GB RAM). + + + +Where do these mnemonics like **t2.micro** come from? The documentation says from + +[![][1]][2] + +There are three sets of instance types, **aws** , **azure** and **gce**. Their names are listed in [the LXD instance type index file ][3]**.yaml,** +``` +aws: "aws.yaml" +gce: "gce.yaml" +azure: "azure.yaml" + +``` + +Over there, there are YAML configuration files for each of AWS, Azure and GCE, and in them there are settings for CPU cores and RAM memory. + +The actual URLs that the LXD client will be using, are + + + +Sample for AWS: +``` +t2.large: + cpu: 2.0 + mem: 8.0 +t2.medium: + cpu: 2.0 + mem: 4.0 +t2.micro: + cpu: 1.0 + mem: 1.0 +t2.nano: + cpu: 1.0 + mem: 0.5 +t2.small: + cpu: 1.0 + mem: 2.0 +``` + + + +Sample for Azure: +``` +ExtraSmall: + cpu: 1.0 + mem: 0.768 +Large: + cpu: 4.0 + mem: 7.0 +Medium: + cpu: 2.0 + mem: 3.5 +Small: + cpu: 1.0 + mem: 1.75 +Standard_A1_v2: + cpu: 1.0 + mem: 2.0 +``` + + + +Sample for GCE: +``` +f1-micro: + cpu: 0.2 + mem: 0.6 +g1-small: + cpu: 0.5 + mem: 1.7 +n1-highcpu-16: + cpu: 16.0 + mem: 14.4 +n1-highcpu-2: + cpu: 2.0 + mem: 1.8 +n1-highcpu-32: + cpu: 32.0 + mem: 28.8 +``` + +Let's see an example. Here, all of the following are all equivalent! Just run one of them to get a 1 CPU core/1GB RAM container. +``` +$ lxc launch ubuntu:x -t t2.micro aws-t2-micro + +$ lxc launch ubuntu:x -t aws:t2.micro aws-t2-micro + +$ lxc launch ubuntu:x -t c1-m1 aws-t2-micro +``` + +Let's verify that the constraints have been actually set for the container. +``` +$ lxc config get aws-t2-micro limits.cpu +1 + +$ lxc config get aws-t2-micro limits.cpu.allowance + + +$ lxc config get aws-t2-micro limits.memory +1024MB + +$ lxc config get aws-t2-micro limits.memory.enforce + + +``` + +There are generic limits for 1 CPU core and 1024MB/1GB RAM. For more, see [LXD resource control][4]. + +If you already have a running container and you wanted to set limits live (no need to restart it), here is how you would do that. +``` +$ lxc launch ubuntu:x mycontainer +Creating mycontainer +Starting mycontainer + +$ lxc config set mycontainer limits.cpu 1 +$ lxc config set mycontainer limits.memory 1GB +``` + +Let's see the config with the limits, +``` +$ lxc config show mycontainer +architecture: x86_64 +config: + image.architecture: amd64 + image.description: ubuntu 16.04 LTS amd64 (release) (20180126) + image.label: release + image.os: ubuntu + image.release: xenial + image.serial: "20180126" + image.version: "16.04" + limits.cpu: "1" + limits.memory: 1GB +... +``` + +### Troubleshooting + +#### I tried to the the memory limit but I get an error! + +I got this error, +``` +$ lxc config set mycontainer limits.memory 1 +error: Failed to set cgroup memory.limit_in_bytes="1": setting cgroup item for the container failed +Exit 1 +``` + +When you set the memory limit ( **limits.memory** ), you need to append a specifier like **GB** (as in 1GB). Because the number there is in bytes if no specifier is present, and one byte of memory is not going to work. + +#### I cannot set the limits in lxc launch -config! + +How do I use **lxc launch -config ConfigurationGoesHere**? + +Here is the documentation: +``` +$ lxc launch --help +Usage: lxc launch [ :] ... [--config|-c ...] +``` + +Here it is, +``` +$ lxc launch ubuntu:x --config limits.cpu=1 --config limits.memory=1GB mycontainer +Creating mycontainer +Starting mycontainer +``` + +That is, use multiple **- config** parameters. + + +-------------------------------------------------------------------------------- + +via: https://blog.simos.info/how-to-use-lxd-instance-types/ + +作者:[Simos Xenitellis][a] +译者:[译者ID](https://github.com/译者ID) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://blog.simos.info/author/simos/ +[1]:https://i1.wp.com/blog.simos.info/wp-content/uploads/2018/01/lxd-instance-types.png?resize=750%2C277&ssl=1 +[2]:https://i1.wp.com/blog.simos.info/wp-content/uploads/2018/01/lxd-instance-types.png?ssl=1 +[3]:https://uk.images.linuxcontainers.org/meta/instance-types/.yaml +[4]:https://stgraber.org/2016/03/26/lxd-2-0-resource-control-412/ From 6b1922cbd29b0ac11313cd832874e3a951381dd6 Mon Sep 17 00:00:00 2001 From: qhwdw Date: Tue, 30 Jan 2018 13:57:32 +0800 Subject: [PATCH 044/272] Translated by qhwdw --- .../tech/20141029 What does an idle CPU do.md | 91 ------------------- .../tech/20141029 What does an idle CPU do.md | 91 +++++++++++++++++++ 2 files changed, 91 insertions(+), 91 deletions(-) delete mode 100644 sources/tech/20141029 What does an idle CPU do.md create mode 100644 translated/tech/20141029 What does an idle CPU do.md diff --git a/sources/tech/20141029 What does an idle CPU do.md b/sources/tech/20141029 What does an idle CPU do.md deleted file mode 100644 index 991f40d6c0..0000000000 --- a/sources/tech/20141029 What does an idle CPU do.md +++ /dev/null @@ -1,91 +0,0 @@ -Translating by qhwdw [What does an idle CPU do?][1] -============================================================ - -In the [last post][2] I said the fundamental axiom of OS behavior is that at any given time, exactly one and only one task is active on a CPU. But if there's absolutely nothing to do, then what? - -It turns out that this situation is extremely common, and for most personal computers it's actually the norm: an ocean of sleeping processes, all waiting on some condition to wake up, while nearly 100% of CPU time is going into the mythical "idle task." In fact, if the CPU is consistently busy for a normal user, it's often a misconfiguration, bug, or malware. - -Since we can't violate our axiom, some task needs to be active on a CPU. First because it's good design: it would be unwise to spread special cases all over the kernel checking whether there is in fact an active task. A design is far better when there are no exceptions. Whenever you write an if statement, Nyan Cat cries. And second, we need to do something with all those idle CPUs, lest they get spunky and, you know, create Skynet. - -So to keep design consistency and be one step ahead of the devil, OS developers create an idle task that gets scheduled to run when there's no other work. We have seen in the Linux [boot process][3] that the idle task is process 0, a direct descendent of the very first instruction that runs when a computer is first turned on. It is initialized in [rest_init][4], where [init_idle_bootup_task][5] initializes the idle scheduling class. - -Briefly, Linux supports different scheduling classes for things like real-time processes, regular user processes, and so on. When it's time to choose a process to become the active task, these classes are queried in order of priority. That way, the nuclear reactor control code always gets to run before the web browser. Often, though, these classes return NULL, meaning they don't have a suitable process to run - they're all sleeping. But the idle scheduling class, which runs last, never fails: it always returns the idle task. - -That's all good, but let's get down to just what exactly this idle task is doing. So here is [cpu_idle_loop][6], courtesy of open source: - -cpu_idle_loop - -``` -while (1) { - while(!need_resched()) { - cpuidle_idle_call(); - } - - /* - [Note: Switch to a different task. We will return to this loop when the idle task is again selected to run.] - */ - schedule_preempt_disabled(); -} -``` - -I've omitted many details, and we'll look at task switching closely later on, but if you read the code you'll get the gist of it: as long as there's no need to reschedule, meaning change the active task, stay idle. Measured in elapsed time, this loop and its cousins in other OSes are probably the most executed pieces of code in computing history. For Intel processors, staying idle traditionally meant running the [halt][7] instruction: - -native_halt - -``` -static inline void native_halt(void) - { - asm volatile("hlt": : :"memory"); - } -``` - -hlt stops code execution in the processor and puts it in a halted state. It's weird to think that across the world millions and millions of Intel-like CPUs are spending the majority of their time halted, even while they're powered up. It's also not terribly efficient, energy wise, which led chip makers to develop deeper sleep states for processors, which trade off less power consumption for longer wake-up latency. The kernel's [cpuidle subsystem][8] is responsible for taking advantage of these power-saving modes. - -Now once we tell the CPU to halt, or sleep, we need to somehow bring it back to life. If you've read the [last post][9], you might suspect interrupts are involved, and indeed they are. Interrupts spur the CPU out of its halted state and back into action. So putting this all together, here's what your system mostly does as you read a fully rendered web page: - -![](https://manybutfinite.com/img/os/idle.png) - - - -Other interrupts besides the timer interrupt also get the processor moving again. That's what happens if you click on a web page, for example: your mouse issues an interrupt, its driver processes it, and suddenly a process is runnable because it has fresh input. At that point need_resched() returns true, and the idle task is booted out in favor of your browser. - -But let's stick to idleness in this post. Here's the idle loop over time: - -![](https://manybutfinite.com/img/os/idleCycles.png) - -In this example the timer interrupt was programmed by the kernel to happen every 4 milliseconds (ms). This is the tick period. That means we get 250 ticks per second, so the tick rate or tick frequency is 250 Hz. That's a typical value for Linux running on Intel processors, with 100 Hz being another crowd favorite. This is defined in the CONFIG_HZ option when you build the kernel. - -Now that looks like an awful lot of pointless work for an idle CPU, and it is. Without fresh input from the outside world, the CPU will remain stuck in this hellish nap getting woken up 250 times a second while your laptop battery is drained. If this is running in a virtual machine, we're burning both power and valuable cycles from the host CPU. - -The solution here is to have a [dynamic tick][10] so that when the CPU is idle, the timer interrupt is either [deactivated or reprogrammed][11] to happen at a point where the kernel knows there will be work to do (for example, a process might have a timer expiring in 5 seconds, so we must not sleep past that). This is also called tickless mode. - -Finally, suppose you have one active process in a system, for example a long-running CPU-intensive task. That's nearly identical to an idle system: these diagrams remain about the same, just substitute the one process for the idle task and the pictures are accurate. In that case it's still pointless to interrupt the task every 4 ms for no good reason: it's merely OS jitter slowing your work ever so slightly. Linux can also stop the fixed-rate tick in this one-process scenario, in what's called [adaptive-tick][12] mode. Eventually, a fixed-rate tick may be gone [altogether][13]. - -That's enough idleness for one post. The kernel's idle behavior is an important part of the OS puzzle, and it's very similar to other situations we'll see, so this helps us build the picture of a running kernel. More next week, [RSS][14] and [Twitter][15]. - --------------------------------------------------------------------------------- - -via:https://manybutfinite.com/post/what-does-an-idle-cpu-do/ - -作者:[Gustavo Duarte][a] -译者:[译者ID](https://github.com/译者ID) -校对:[校对者ID](https://github.com/校对者ID) - -本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 - -[a]:http://duartes.org/gustavo/blog/about/ -[1]:https://manybutfinite.com/post/what-does-an-idle-cpu-do/ -[2]:https://manybutfinite.com/post/when-does-your-os-run -[3]:https://manybutfinite.com/post/kernel-boot-process -[4]:https://github.com/torvalds/linux/blob/v3.17/init/main.c#L393 -[5]:https://github.com/torvalds/linux/blob/v3.17/kernel/sched/core.c#L4538 -[6]:https://github.com/torvalds/linux/blob/v3.17/kernel/sched/idle.c#L183 -[7]:https://github.com/torvalds/linux/blob/v3.17/arch/x86/include/asm/irqflags.h#L52 -[8]:http://lwn.net/Articles/384146/ -[9]:https://manybutfinite.com/post/when-does-your-os-run -[10]:https://github.com/torvalds/linux/blob/v3.17/Documentation/timers/NO_HZ.txt#L17 -[11]:https://github.com/torvalds/linux/blob/v3.17/Documentation/timers/highres.txt#L215 -[12]:https://github.com/torvalds/linux/blob/v3.17/Documentation/timers/NO_HZ.txt#L100 -[13]:http://lwn.net/Articles/549580/ -[14]:https://manybutfinite.com/feed.xml -[15]:http://twitter.com/manybutfinite \ No newline at end of file diff --git a/translated/tech/20141029 What does an idle CPU do.md b/translated/tech/20141029 What does an idle CPU do.md new file mode 100644 index 0000000000..dad24ae0be --- /dev/null +++ b/translated/tech/20141029 What does an idle CPU do.md @@ -0,0 +1,91 @@ +[当 CPU 空闲时它都在做什么?][1] +============================================================ + +在 [上篇文章中][2] 我说了操作系统行为的基本原理是,在任何一个给定的时刻,在一个 CPU 上有且只有一个任务是活动的。但是,如果 CPU 无事可做的时候,又会是什么样的呢? + +事实证明,这种情况是非常普遍的,对于绝大多数的个人电脑来说,这确实是一种常态:大量的睡眠进程,它们都在等待某种情况下被唤醒,差不多在 100% 的 CPU 时间中,它们都处于虚构的“空闲任务”中。事实上,如果一个普通用户的 CPU 处于持续的繁忙中,它可能意味着有一个错误、bug、或者运行了恶意软件。 + +因为我们不能违反我们的原理,一些任务需要在一个 CPU 上激活。首先是因为,这是一个良好的设计:持续很长时间去遍历内核,检查是否有一个活动任务,这种特殊情况是不明智的做法。最好的设计是没有任何例外的情况。无论何时,你写一个 `if` 语句,Nyan 猫就会叫。其次,我们需要使用空闲的 CPU 去做一些事情,让它们充满活力,并且,你懂得,创建天网卫星计划。 + +因此,保持这种设计的连续性,并领先于恶魔(devil)一步,操作系统开发者创建了一个空闲任务,当没有其它任务可做时就调度它去运行。我们可以在 Linux 的 [引导进程][3] 中看到,这个空闲任务就是进程 0,它是由计算机打开电源时运行的第一个指令直接派生出来的。它在 [rest_init][4] 中初始化,在 [init_idle_bootup_task][5] 中初始化空闲调度类。 + +简而言之,Linux 支持像实时进程、普通用户进程、等等的不同调度类。当选择一个进程变成活动任务时,这些类是被优先询问的。通过这种方式,核反应堆的控制代码总是优先于 web 浏览器运行。尽管在通常情况下,这些类返回 `NULL`,意味着它们没有合适的任务需要去运行 —— 它们总是处于睡眠状态。但是空闲调度类,它是持续运行的,从不会失败:它总是返回空闲任务。 + +好吧,我们来看一下这个空闲任务到底做了些什么。下面是 [cpu_idle_loop][6],感谢开源能让我们看到它的代码: + +cpu_idle_loop + +``` +while (1) { + while(!need_resched()) { + cpuidle_idle_call(); + } + + /* + [Note: Switch to a different task. We will return to this loop when the idle task is again selected to run.] + */ + schedule_preempt_disabled(); +} +``` + +我省略了很多的细节,稍后我们将去了解任务切换,但是,如果你阅读了源代码,你就会找到它的要点:由于这里不需要重新调度 —— 改变活动任务,它一直处于空闲状态。以经过的时间来计算,这个循环和操作系统中它的“堂兄弟们”相比,在计算的历史上它是运行的最多的代码片段。对于 Intel 处理器来说,处于空闲状态意味着运行着一个 [halt][7] 指令: + +native_halt + +``` +static inline void native_halt(void) + { + asm volatile("hlt": : :"memory"); + } +``` + +`halt` 指令停止处理器中运行的代码,并将它置于 `halt` 的状态。奇怪的是,全世界各地数以百万计的像 Intel 这样的 CPU 们花费大量的时间让它们处于 `halt` 的状态,直到它们被激活。这并不是高效、节能的做法,这促使芯片制造商们去开发处理器的深度睡眠状态,它意味着更少的功耗和更长的唤醒延迟。内核的 [cpuidle 子系统][8] 是这些节能模式能够产生好处的原因。 + +现在,一旦我们告诉 CPU 去 `halt` 或者睡眠之后,我们需要以某种方式去将它t重新带回(back to life)。如果你读过 [上篇文章][9],(译者注:指的是《你的操作系统什么时候运行?》) 你可能会猜到中断会参与其中,而事实确实如此。中断促使 CPU 离开 `halt` 状态返回到激活状态。因此,将这些拼到一起,下图是当你阅读一个完全呈现的 web 网页时,你的系统主要做的事情: + +![](https://manybutfinite.com/img/os/idle.png) + + + +除定时器中断外的其它中断也会使处理器再次发生变化。如果你再次点击一个 web 页面就会产生这种变化,例如:你的鼠标发出一个中断,它会导致系统去处理它,并且使处理器因为它产生了一个新的输入而突然地可运行。在那个时刻, `need_resched()` 返回 `true`,然后空闲任务因你的浏览器而被踢出终止运行。 + +如果我们阅读这篇文章,而不做任何事情。那么随着时间的推移,这个空闲循环就像下图一样: + +![](https://manybutfinite.com/img/os/idleCycles.png) + +在这个示例中,由内核计划的定时器中断会每 4 毫秒发生一次。这就是滴答周期。也就是说每秒钟将有 250 个滴答,因此,这个滴答速率或者频率是 250 Hz。这是运行在 Intel 处理器上的 Linux 的典型值,而很多人喜欢使用 100 Hz。这是由你构建内核时在 `CONFIG_HZ` 选项中定义的。 + +对于一个空闲 CPU 来说,它看起来似乎是个无意义的工作。如果外部世界没有新的输入,在你的笔记本电脑的电池耗尽之前,CPU 将始终处于这种每秒钟被唤醒 250 次的地狱般折磨的小憩中。如果它运行在一个虚拟机中,那我们正在消耗着宿主机 CPU 的性能和宝贵的时钟周期。 + +在这里的解决方案是拥有一个 [动态滴答][10] ,因此,当 CPU 处于空闲状态时,定时器中断要么被 [暂停要么被重计划][11],直到内核知道将有事情要做时(例如,一个进程的定时器可能要在 5 秒内过期,因此,我们不能再继续睡眠了),定时器中断才会重新发出。这也被称为无滴答模式。 + +最后,假设在一个系统中你有一个活动进程,例如,一个长周期运行的 CPU 密集型任务。那样几乎就和一个空闲系统是相同的:这些示意图仍然是相同的,只是将空闲任务替换为这个进程,并且描述也是准确的。在那种情况下,每 4 毫秒去中断一次任务仍然是无意义的:它只是操作系统的抖动,甚至会使你的工作变得更慢而已。Linux 也可以在这种单一进程的场景中停止这种固定速率的滴答,这被称为 [adaptive-tick][12] 模式。最终,这种固定速率的滴答可能会 [完全消失][13]。 + +对于阅读一篇文章来说,CPU 基本是无事可做的。内核的这种空闲行为是操作系统难题的一个重要部分,并且它与我们看到的其它情况非常相似,因此,这将帮助我们构建一个运行中的内核的蓝图。更多的内容将发布在下周的 [RSS][14] 和 [Twitter][15] 上。 + +-------------------------------------------------------------------------------- + +via:https://manybutfinite.com/post/what-does-an-idle-cpu-do/ + +作者:[Gustavo Duarte][a] +译者:[qhwdw](https://github.com/qhwdw) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:http://duartes.org/gustavo/blog/about/ +[1]:https://manybutfinite.com/post/what-does-an-idle-cpu-do/ +[2]:https://manybutfinite.com/post/when-does-your-os-run +[3]:https://manybutfinite.com/post/kernel-boot-process +[4]:https://github.com/torvalds/linux/blob/v3.17/init/main.c#L393 +[5]:https://github.com/torvalds/linux/blob/v3.17/kernel/sched/core.c#L4538 +[6]:https://github.com/torvalds/linux/blob/v3.17/kernel/sched/idle.c#L183 +[7]:https://github.com/torvalds/linux/blob/v3.17/arch/x86/include/asm/irqflags.h#L52 +[8]:http://lwn.net/Articles/384146/ +[9]:https://manybutfinite.com/post/when-does-your-os-run +[10]:https://github.com/torvalds/linux/blob/v3.17/Documentation/timers/NO_HZ.txt#L17 +[11]:https://github.com/torvalds/linux/blob/v3.17/Documentation/timers/highres.txt#L215 +[12]:https://github.com/torvalds/linux/blob/v3.17/Documentation/timers/NO_HZ.txt#L100 +[13]:http://lwn.net/Articles/549580/ +[14]:https://manybutfinite.com/feed.xml +[15]:http://twitter.com/manybutfinite \ No newline at end of file From 18fd999f94f206d0357192f24541c26b21931b9e Mon Sep 17 00:00:00 2001 From: darksun Date: Tue, 30 Jan 2018 14:20:48 +0800 Subject: [PATCH 045/272] =?UTF-8?q?=E9=80=89=E9=A2=98:=20Create=20your=20o?= =?UTF-8?q?wn=20personal=20Cloud:=20Install=20OwnCloud?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...ur own personal Cloud- Install OwnCloud.md | 115 ++++++++++++++++++ 1 file changed, 115 insertions(+) create mode 100644 sources/tech/20180129 Create your own personal Cloud- Install OwnCloud.md diff --git a/sources/tech/20180129 Create your own personal Cloud- Install OwnCloud.md b/sources/tech/20180129 Create your own personal Cloud- Install OwnCloud.md new file mode 100644 index 0000000000..de2fccaed8 --- /dev/null +++ b/sources/tech/20180129 Create your own personal Cloud- Install OwnCloud.md @@ -0,0 +1,115 @@ +Create your own personal Cloud: Install OwnCloud +====== +Cloud is what everyone is talking about. We have a number of major players in the market that are offering cloud storage as well as other cloud based services. But we can also create a personal cloud for ourselves. + +In this tutorial we are going to discuss how to create a personal cloud using OwnCloud. OwnCloud is a web application, that we can install on our Linux machines, to store & serve data. It can be used for sharing calender, Contacts and Bookmark sharing and Personal Audio/Video Streaming etc. + +For this tutorial, we will be using CentOS 7 machine but this tutorial can also be used to install ownCloud on other Linux distributions as well. Let's start with pre-requisites for installing ownCloud, + + **(Recommended Read:[How to use Apache as Reverse Proxy on CentOS & RHEL][1])** + + **(Also Read:[Real Time Linux server monitoring with GLANCES monitoring tool][2])** + +### Pre-requisites + + * We need to have LAMP stack configured on our machines. Please go through our articles '[ Easiest guide for setting up LAMP server for CentOS/RHEL ][3] & [Create LAMP stack on Ubuntu][4]. + + * We will also need the following php packages installed on our machines,' php-mysql php-json php-xml php-mbstring php-zip php-gd curl php-curl php-pdo'. Install them using the package manager. + +``` +$ sudo yum install php-mysql php-json php-xml php-mbstring php-zip php-gd curl php-curl php-pdo +``` + +### Installation + +To install owncloud, we will now download the ownCloud package on our server. Use the following command to download the latest package (10.0.4-1) from ownCloud official website, + +``` + $ wget https://download.owncloud.org/community/owncloud-10.0.4.tar.bz2 +``` + +Extract it using the following command, + +``` + $ tar -xvf owncloud-10.0.4.tar.bz2 +``` + +Now move all the contents of extracted folder to '/var/www/html' + +``` + $ mv owncloud/* /var/www/html +``` + +Next thing we need to do is to make a change in apache configuration file 'httpd.conf', + +``` + $ sudo vim /etc/httpd/conf/httpd.com +``` + +& change the following option, + +``` + AllowOverride All +``` + +Now save the file & change the permissions for owncloud folder, + +``` + $ sudo chown -R apache:apache /var/www/html/ + $ sudo chmod 777 /var/www/html/config/ +``` + +Now restart the apache service to implement the changes made, + +``` + $ sudo systemctl restart httpd +``` + +Now we need to create a database on mariadb to store all the data from owncloud. Create a database & a db user with the following commands, + +``` + $ mysql -u root -p + MariaDB [(none)] > create database owncloud; + MariaDB [(none)] > GRANT ALL ON owncloud.* TO ocuser@localhost IDENTIFIED BY 'owncloud'; + MariaDB [(none)] > flush privileges; + MariaDB [(none)] > exit +``` + +Configuration part on server is completed, we can now access the owncloud from a web browser. Open a browser of your choosing & enter the IP address of the server, which in our case is 10.20.30.100, + +![install owncloud][7] + +As soon as the URL loads, we will be presented with the above mentioned page. Here we will create our admin user & will also provide our database information. Once all the information has been provided, click on 'Finish setup'. + +We will than be redirected to login page, where we need to enter the credentials we created in previous step, + +![install owncloud][9] + +Upon successful authentication, we will enter into the ownCloud dashboard, + +![install owncloud][11] + +We can than use mobile apps or can also upload our data using the web interface. We now have our own personal cloud ready. We now end this tutorial on how to install ownCloud to create your own cloud. Please do leave your questions or suggestions in the comment box below. + + +-------------------------------------------------------------------------------- + +via: http://linuxtechlab.com/create-personal-cloud-install-owncloud/ + +作者:[SHUSAIN][a] +译者:[译者ID](https://github.com/译者ID) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:http://linuxtechlab.com/author/shsuain/ +[1]:http://linuxtechlab.com/apache-as-reverse-proxy-centos-rhel/ +[2]:http://linuxtechlab.com/linux-server-glances-monitoring-tool/ +[3]:http://linuxtechlab.com/easiest-guide-creating-lamp-server/ +[4]:http://linuxtechlab.com/install-lamp-stack-on-ubuntu/ +[6]:https://i1.wp.com/linuxtechlab.com/wp-content/plugins/a3-lazy-load/assets/images/lazy_placeholder.gif?resize=400%2C647 +[7]:https://i1.wp.com/linuxtechlab.com/wp-content/uploads/2018/01/owncloud1-compressor.jpg?resize=400%2C647 +[8]:https://i1.wp.com/linuxtechlab.com/wp-content/plugins/a3-lazy-load/assets/images/lazy_placeholder.gif?resize=876%2C541 +[9]:https://i1.wp.com/linuxtechlab.com/wp-content/uploads/2018/01/owncloud2-compressor1.jpg?resize=876%2C541 +[10]:https://i1.wp.com/linuxtechlab.com/wp-content/plugins/a3-lazy-load/assets/images/lazy_placeholder.gif?resize=981%2C474 +[11]:https://i0.wp.com/linuxtechlab.com/wp-content/uploads/2018/01/owncloud3-compressor1.jpg?resize=981%2C474 From 39a8f2a0bff41036451e47b9c1a2376f9007c33d Mon Sep 17 00:00:00 2001 From: darksun Date: Tue, 30 Jan 2018 14:26:39 +0800 Subject: [PATCH 046/272] =?UTF-8?q?=E9=80=89=E9=A2=98:=20Parsing=20HTML=20?= =?UTF-8?q?with=20Python?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../tech/20180129 Parsing HTML with Python.md | 205 ++++++++++++++++++ 1 file changed, 205 insertions(+) create mode 100644 sources/tech/20180129 Parsing HTML with Python.md diff --git a/sources/tech/20180129 Parsing HTML with Python.md b/sources/tech/20180129 Parsing HTML with Python.md new file mode 100644 index 0000000000..c81c1f8c24 --- /dev/null +++ b/sources/tech/20180129 Parsing HTML with Python.md @@ -0,0 +1,205 @@ +Parsing HTML with Python +====== + +![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/bus_html_code.png?itok=VjUmGsnl) + +Image by : Jason Baker for Opensource.com. + +As a long-time member of the documentation team at Scribus, I keep up-to-date with the latest updates of the source so I can help make updates and additions to the documentation. When I recently did a "checkout" using Subversion on a computer I had just upgraded to Fedora 27, I was amazed at how long it took to download the documentation, which consists of HTML pages and associated images. I became concerned that the project's documentation seemed much larger than it should be and suspected that some of the content was "zombie" documentation--HTML files that aren't used anymore and images that have lost all references in the currently used HTML. + +I decided to create a project for myself to figure this out. One way to do this is to search for existing image files that aren't used. If I could scan through all the HTML files for image references, then compare that list to the actual image files, chances are I would see a mismatch. + +Here is a typical image tag: +``` +Edit examples +``` + +I'm interested in the part between the first set of quotation marks, after `src=`. After some searching for a solution, I found a Python module called [BeautifulSoup][1]. The tasty part of the script I wrote looks like this: +``` +soup = BeautifulSoup(all_text, 'html.parser') +match = soup.findAll("img") +if len(match) > 0: + for m in match: + imagelist.append(str(m)) +``` + +We can use this `findAll` method to pluck out the image tags. Here is a tiny piece of the output: +``` + + +GSview - Advanced Options PanelScribus External Tools Preferences +``` + +So far, so good. I thought that the next step might be to just carve this down, but when I tried some string methods in the script, it returned errors about this being tags and not strings. I saved the output to a file and went through the process of editing in [KWrite][2]. One nice thing about KWrite is that you can do a "find & replace" using regular expressions (regex), so I could replace `', all_text) +if len(match)>0: + for m in match: + imagelist.append(m) +``` + +And a tiny piece of its output looks like this: +``` +images/cmcanvas.png" title="Context Menu for the document canvas" alt="Context Menu for the document canvas" />
+``` + +I decided to home in on the `src=` piece. One way would be to wait for an occurrence of `s`, then see if the next character is `r`, the next `c`, and the next `=`. If so, bingo! Then what follows between two sets of double quotation marks is what I need. The problem with this is the structure it takes to hang onto these. One way of looking at a string of characters representing a line of HTML text would be: +``` +for c in all_text: +``` + +But the logic was just too messy to hang onto the previous `c`, and the one before that, the one before that, and the one before that. + +In the end, I decided to focus on the `=` and to use an indexing method whereby I could easily reference any prior or future character in the string. Here is the searching part: +``` + index = 3 + while index < linelength: + if (all_text[index] == '='): + if (all_text[index-3] == 's') and (all_text[index-2] == 'r') and (all_text[index-1] == 'c'): + imagefound(all_text, imagelist, index) + index += 1 + else: + index += 1 + else: + index += 1 +``` + +I start the search with the fourth character (indexing starts at 0), so I don't get an indexing error down below, and realistically, there will not be an equal sign before the fourth character of a line. The first test is to see if we find `=` as we're marching through the string, and if not, we march on. If we do see one, then we ask if the three previous characters were `s`, `r`, and `c`, in that order. If that happens, we call the function `imagefound`: +``` +def imagefound(all_text, imagelist, index): + end = 0 + index += 2 + newimage = '' + while end == 0: + if (all_text[index] != '"'): + newimage = newimage + all_text[index] + index += 1 + else: + newimage = newimage + '\n' + imagelist.append(newimage) + end = 1 + return +``` + +We're sending the function the current index, which represents the `=`. We know the next character will be `"`, so we jump two characters and begin adding characters to a holding string named `newimage`, until we reach the following `"`, at which point we're done. We add the string plus a `newline` character to our list `imagelist` and `return`, keeping in mind there may be more image tags in this remaining string of HTML, so we're right back in the middle of our searching loop. + +Here's what our output looks like now: +``` +images/text-frame-link.png +images/text-frame-unlink.png +images/gimpoptions1.png +images/gimpoptions3.png +images/gimpoptions2.png +images/fontpref3.png +images/font-subst.png +images/fontpref2.png +images/fontpref1.png +images/dtp-studio.png +``` + +Ahhh, much cleaner, and this only took a few seconds to run. I could have jumped seven more index spots to cut out the `images/` part, but I like having it there to make sure I haven't chopped off the first letter of the image filename, and this is so easy to edit out with KWrite--you don't even need regex. After doing that and saving the file, the next step was to run another script I wrote called `sortlist.py`: +``` +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# sortlist.py + +import os + +imagelist = [] +for line in open('/tmp/imagelist_parse4.txt').xreadlines(): + imagelist.append(line) + +imagelist.sort() + +outfile = open('/tmp/imagelist_parse4_sorted.txt', 'w') +outfile.writelines(imagelist) +outfile.close() +``` + +This pulls in the file contents as a list, sorts it, then saves it as another file. After that I could just do the following: +``` +ls /home/gregp/development/Scribus15x/doc/en/images/*.png > '/tmp/actual_images.txt' +``` + +Then I need to run `sortlist.py` on that file too, since the method `ls` uses to sort is different from Python. I could have run a comparison script on these files, but I preferred to do this visually. In the end, I ended up with 42 images that had no HTML reference from the documentation. + +Here is my parsing script in its entirety: +``` +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# parseimg4.py + +import os + +def imagefound(all_text, imagelist, index): + end = 0 + index += 2 + newimage = '' + while end == 0: + if (all_text[index] != '"'): + newimage = newimage + all_text[index] + index += 1 + else: + newimage = newimage + '\n' + imagelist.append(newimage) + end = 1 + return + +htmlnames = [] +imagelist = [] +tempstring = '' +filenames = os.listdir('/home/gregp/development/Scribus15x/doc/en/') +for name in filenames: + if name.endswith('.html'): + htmlnames.append(name) +#print htmlnames +for htmlfile in htmlnames: + all_text = open('/home/gregp/development/Scribus15x/doc/en/' + htmlfile).read() + linelength = len(all_text) + index = 3 + while index < linelength: + if (all_text[index] == '='): + if (all_text[index-3] == 's') and (all_text[index-2] == 'r') and +(all_text[index-1] == 'c'): + imagefound(all_text, imagelist, index) + index += 1 + else: + index += 1 + else: + index += 1 + +outfile = open('/tmp/imagelist_parse4.txt', 'w') +outfile.writelines(imagelist) +outfile.close() +imageno = len(imagelist) +print str(imageno) + " images were found and saved" +``` + +Its name, `parseimg4.py`, doesn't really reflect the number of scripts I wrote along the way, with both minor and major rewrites, plus discards and starting over. Notice that I've hardcoded these directory and filenames, but it would be easy enough to generalize, asking for user input for these pieces of information. Also as they were working scripts, I sent the output to `/tmp`, so they disappear once I reboot my system. + +This wasn't the end of the story, since the next question was: What about zombie HTML files? Any of these files that are not used might reference images not picked up by the previous method. We have a `menu.xml` file that serves as the table of contents for the online manual, but I also needed to consider that some files listed in the TOC might reference files not in the TOC, and yes, I did find some. + +I'll conclude by saying that this was a simpler task than this image search, and it was greatly helped by the processes I had already developed. + +-------------------------------------------------------------------------------- + +via: https://opensource.com/article/18/1/parsing-html-python + +作者:[Greg Pittman][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/greg-p +[1]:https://www.crummy.com/software/BeautifulSoup/ +[2]:https://www.kde.org/applications/utilities/kwrite/ From 5bcf96647170231752bc0ef8513fc98075126883 Mon Sep 17 00:00:00 2001 From: darksun Date: Tue, 30 Jan 2018 14:34:46 +0800 Subject: [PATCH 047/272] =?UTF-8?q?=E9=80=89=E9=A2=98:=20Install=20Zabbix?= =?UTF-8?q?=20Monitoring=20Server=20and=20Agent=20on=20Debian=209?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...Monitoring Server and Agent on Debian 9.md | 401 ++++++++++++++++++ 1 file changed, 401 insertions(+) create mode 100644 sources/tech/20180129 Install Zabbix Monitoring Server and Agent on Debian 9.md diff --git a/sources/tech/20180129 Install Zabbix Monitoring Server and Agent on Debian 9.md b/sources/tech/20180129 Install Zabbix Monitoring Server and Agent on Debian 9.md new file mode 100644 index 0000000000..308b6f1341 --- /dev/null +++ b/sources/tech/20180129 Install Zabbix Monitoring Server and Agent on Debian 9.md @@ -0,0 +1,401 @@ +Install Zabbix Monitoring Server and Agent on Debian 9 +====== + +Monitoring tools are used to continuously keep track of the status of the system and send out alerts and notifications if anything goes wrong. Also, monitoring tools help you to ensure that your critical systems, applications and services are always up and running. Monitoring tools are a supplement for your network security, allowing you to detect malicious traffic, where it's coming from and how to cancel it. + +Zabbix is a free, open source and the ultimate enterprise-level monitoring tool designed for real-time monitoring of millions of metrics collected from tens of thousands of servers, virtual machines and network devices. Zabbix has been designed to skill from small environment to large environment. Its web front-end is written in PHP, backend is written in C and uses MySQL, PostgreSQL, SQLite, Oracle or IBM DB2 to store data. Zabbix provides graphing functionality that allows you to get an overview of the current state of specific nodes and the network + +Some of the major features of the Zabbix are listed below: + + * Monitoring Servers, Databases, Applications, Network Devices, Vmware hypervisor, Virtual Machines and much more. + * Special designed to support small to large environments to improve the quality of your services and reduce operating costs by avoiding downtime. + * Fully open source, so you don't need to pay anything. + * Provide user friendly web interface to do everything from a central location. + * Comes with SNMP to monitor Network device and IPMI to monitor Hardware device. + * Web-based front end that allows full system control from a browser. + +This tutorial will walk you through the step by step instruction of how to install Zabbix Server and Zabbix agent on Debian 9 server. We will also explain how to add the Zabbix agent to the Zabbix server for monitoring. + +#### Requirements + + * Two system with Debian 9 installed. + * Minimum 1 GB of RAM and 10 DB of disk space required. Amount of RAM and Disk space depends on the number of hosts and the parameters that are being monitored. + * A non-root user with sudo privileges setup on your server. + + + +#### Getting Started + +Before starting, it is necessary to update your server's package repository to the latest stable version. You can update it by just running the following command on both instances: + +``` +sudo apt-get update -y +sudo apt-get upgrade -y +``` + +Next, restart your system to apply these changes. + +#### Install Apache, PHP and MariaDB + +Zabbix runs on Apache web server, written in PHP and uses MariaDB/MySQL to store their data. So in order to install Zabbix, you will require Apache, MariaDB and PHP to work. First, install Apache, PHP and Other PHP modules by running the following command: + +``` +sudo apt-get install apache2 libapache2-mod-php7.0 php7.0 php7.0-xml php7.0-bcmath php7.0-mbstring -y +``` + +Next, you will need to add MariaDB repository to your system. Because, latest version of the MariaDB is not available in Debian 9 default repository. + +You can add the repository by running the following command: + +``` +sudo apt-get install software-properties-common -y +sudo apt-key adv --recv-keys --keyserver keyserver.ubuntu.com 0xF1656F24C74CD1D8 +sudo add-apt-repository 'deb [arch=amd64] http://www.ftp.saix.net/DB/mariadb/repo/10.1/debian stretch main' +``` + +Next, update the repository by running the following command: + +``` +sudo apt-get update -y +``` + +Finally, install the MariaDB server with the following command: + +``` +sudo apt-get install mariadb-server -y +``` + +By default, MariaDB installation is not secured. So you will need to secure it first. You can do this by running the mysql_secure_installation script. + +``` +sudo mysql_secure_installation +``` + +Answer all the questions as shown below: +``` + +Enter current password for root (enter for none): Enter +Set root password? [Y/n]: Y +New password: +Re-enter new password: +Remove anonymous users? [Y/n]: Y +Disallow root login remotely? [Y/n]: Y +Remove test database and access to it? [Y/n]: Y +Reload privilege tables now? [Y/n]: Y + +``` + +The above script will set the root password, remove test database, remove anonymous user and Disallow root login from a remote location. + +Once the MariaDB installation is secured, start the Apache and MariaDB service and enable them to start on boot time by running the following command: + +``` +sudo systemctl start apache2 +sudo systemctl enable apache2 +sudo systemctl start mysql +sudo systemctl enable mysql +``` + +#### Installing Zabbix Server + +By default, Zabbix is available in the Debian 9 repository, but it might be outdated. So it is recommended to install most recent version from the official Zabbix repositories. You can download and add the latest version of the Zabbix repository with the following command: + +``` +wget http://repo.zabbix.com/zabbix/3.0/debian/pool/main/z/zabbix-release/zabbix-release_3.0-2+stretch_all.deb +``` + +Next, install the downloaded repository with the following command: + +``` +sudo dpkg -i zabbix-release_3.0-2+stretch_all.deb +``` + +Next, update the package cache and install Zabbix server with web front-end and Mysql support by running the following command: + +``` +sudo apt-get update -y +sudo apt-get install zabbix-server-mysql zabbix-frontend-php -y +``` + +You will also need to install the Zabbix agent to collect data about the Zabbix server status itself: + +``` +sudo apt-get install zabbix-agent -y +``` + +After installing Zabbix agent, start the Zabbix agent service and enable it to start on boot time by running the following command: + +``` +sudo systemctl start zabbix-agent +sudo systemctl enable zabbix-agent +``` + +#### Configuring Zabbix Database + +Zabbix uses MariaDB/MySQL as a database backend. So, you will need to create a MySQL database and User for zabbix installation: + +First, log into MySQL shell with the following command: + +``` +mysql -u root -p +``` + +Enter your root password, then create a database for Zabbix with the following command: + +``` +MariaDB [(none)]> CREATE DATABASE zabbixdb character set utf8 collate utf8_bin; +``` + +Next, create a user for Zabbix, assign a password and grant all privileges on Zabbix database with the following command: + +``` +MariaDB [(none)]> CREATE user zabbix identified by 'password'; +MariaDB [(none)]> GRANT ALL PRIVILEGES on zabbixdb.* to zabbixuser@localhost identified by 'password'; +``` + +Next, flush the privileges with the following command: + +``` +MariaDB [(none)]> FLUSH PRIVILEGES; +``` + +Finally, exit from the MySQL shell with the following command: + +``` +MariaDB [(none)]> exit; +``` + +Next, import initial schema and data to the newly created database with the following command: + +``` +cd /usr/share/doc/zabbix-server-mysql*/ +zcat create.sql.gz | mysql -u zabbix -p zabbixdb +``` + +#### Configuring Zabbix + +Zabbix creates its own configuration file at `/etc/zabbix/apache.conf`. Edit this file and update the Timezone and PHP setting as per your need: + +``` +sudo nano /etc/zabbix/apache.conf +``` + +Change the file as shown below: +``` + php_value max_execution_time 300 + php_value memory_limit 128M + php_value post_max_size 32M + php_value upload_max_filesize 8M + php_value max_input_time 300 + php_value always_populate_raw_post_data -1 + php_value date.timezone Asia/Kolkata + +``` + +Save the file when you are finished. + +Next, you will need to update the database details for Zabbix. You can do this by editing `/etc/zabbix/zabbix_server.conf` file: + +``` +sudo nano /etc/zabbix/zabbix_server.conf +``` + +Change the following lines: +``` +DBHost=localhost +DBName=zabbixdb +DBUser=zabbixuser +DBPassword=password + +``` + +Save and close the file when you are finished. Then restart all the services with the following command: + +``` +sudo systemctl restart apache2 +sudo systemctl restart mysql +sudo systemctl restart zabbix-server +``` + +#### Configuring Firewall + +Before proceeding, you will need to configure the UFW firewall to secure Zabbix server. + +First, make sure UFW is installed on your system. Otherewise, you can install it by running the following command: + +``` +sudo apt-get install ufw -y +``` + +Next, enable the UFW firewall: + +``` +sudo ufw enable +``` + +Next, allow port 10050, 10051 and 80 through UFW with the following command: + +``` +sudo ufw allow 10050/tcp +sudo ufw allow 10051/tcp +sudo ufw allow 80/tcp +``` + +Finally, reload the firewall to apply these changes with the following command: + +``` +sudo ufw reload +``` + +Once the UFW firewall is configured you can proceed to install the Zabbix server via web interface. + +#### Accessing Zabbix Web Installation Wizard + +Once everything is fine, it's time to access Zabbix web installation wizard. + +Open your web browser and navigate the URL , you will be redirected to the following page: + +[![Zabbix 3.0][2]][3] + +Click on the **Next step** button, you should see the following page: + +[![Zabbix Prerequisites][4]][5] + +Here, all the Zabbix pre-requisites are checked and verified, then click on the **Next step** button you should see the following page: + +[![Database Configuration][6]][7] + +Here, provide the Zabbix database name, database user and password then click on the **Next step** button, you should see the following page: + +[![Zabbix Server Details][8]][9] + +Here, specify the Zabbix server details and Port number then click on the **Next step** button, you should see the pre-installation summary of Zabbix Server in following page: + +[![Installation summary][10]][11] + +Next, click on the **Next step** button to start the Zabbix installation. Once the Zabbix installation is completed successfully, you should see the following page: + +[![Zabbix installed successfully][12]][13] + +Here, click on the **Finish** button, it will redirect to the Zabbix login page as shown below: + +[![Login to Zabbix][14]][15] + +Here, provide username as Admin and password as zabbix then click on the **Sign in** button. You should see the Zabbix server dashboard in the following image: + +[![Zabbix Dashboard][16]][17] + +Your Zabbix web installation is now finished. + +#### Install Zabbix Agent + +Now your Zabbix server is up and functioning. It's time to add Zabbix agent node to the Zabbix Server for Monitoring. + +First, log into Zabbix agent instance and add the Zabbix repository with the following command: + +``` +wget http://repo.zabbix.com/zabbix/3.0/debian/pool/main/z/zabbix-release/zabbix-release_3.0-2+stretch_all.deb +sudo dpkg -i zabbix-release_3.0-2+stretch_all.deb +sudo apt-get update -y +``` + +Once you have configured Zabbix repository on your system, install the Zabbix agent by just running the following command: + +``` +sudo apt-get install zabbix-agent -y +``` + +Once the Zabbix agent is installed, you will need to configure Zabbix agent to communicate with Zabbix server. You can do this by editing the Zabbix agent configuration file: + +``` +sudo nano /etc/zabbix/zabbix_agentd.conf +``` + +Change the file as shown below: +``` + #Zabbix Server IP Address / Hostname + + Server=192.168.0.103 + + #Zabbix Agent Hostname + + Hostname=zabbix-agent + + +``` + +Save and close the file when you are finished, then restart the Zabbix agent service and enable it to start on boot time with the following command: + +``` +sudo systemctl restart zabbix-agent +sudo systemctl enable zabbix-agent +``` + +#### Add Zabbix Agent Node to Zabbix Server + +Next, you will need to add the Zabbix agent node to the Zabbix server for monitoring. First, log in to the Zabbix server web interface. + +[![Zabbix UI][18]][19] + +Next, Click on **Configuration --> Hosts -> Create Host**, you should see the following page: + +[![Create Host in Zabbix][20]][21] + +Here, specify the Hostname, IP address and Group names of Zabbix agent. Then navigate to Templates tab, you should see the following page: + +[![specify the Hostname, IP address and Group name][22]][23] + +Here, search appropriate templates and click on **Add** button, you should see the following page: + +[![OS Template][24]][25] + +Finally, click on **Add** button again. You will see your new host with green labels indicating that everything is working fine. + +[![Hast successfully added to Zabbix][26]][27] + +If you have extra servers and network devices that you want to monitor, log into each host, install the Zabbix agent and add each host from the Zabbix web interface. + +#### Conclusion + +Congratulations! you have successfully installed the Zabbix server and Zabbix agent in Debian 9 server. You have also added Zabbix agent node to the Zabbix server for monitoring. You can now easily list the current issue and past history, get the latest data of hosts, list the current problems and also visualized the collected resource statistics such as CPU load, CPU utilization, Memory usage, etc via graphs. I hope you can now easily install and configure Zabbix on Debian 9 server and deploy it on production environment. Compared to other monitoring software, Zabbix allows you to build your own maps of different network segments while monitoring many hosts. You can also monitor Windows host using Zabbix windows agent. For more information, you can refer the [Zabbix Documentation Page][28]. Feel free to ask me if you have any questions. + + +-------------------------------------------------------------------------------- + +via: https://www.howtoforge.com/tutorial/install-zabbix-monitoring-server-and-agent-on-debian-9/ + +作者:[Hitesh Jethva][a] +译者:[译者ID](https://github.com/译者ID) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://www.howtoforge.com +[1]:/cdn-cgi/l/email-protection +[2]:https://www.howtoforge.com/images/install_zabbix_monitoring_server_and_agent_on_debian_9/Screenshot-of-zabbix-welcome-page.png +[3]:https://www.howtoforge.com/images/install_zabbix_monitoring_server_and_agent_on_debian_9/big/Screenshot-of-zabbix-welcome-page.png +[4]:https://www.howtoforge.com/images/install_zabbix_monitoring_server_and_agent_on_debian_9/Screenshot-of-zabbix-pre-requisite-check-page.png +[5]:https://www.howtoforge.com/images/install_zabbix_monitoring_server_and_agent_on_debian_9/big/Screenshot-of-zabbix-pre-requisite-check-page.png +[6]:https://www.howtoforge.com/images/install_zabbix_monitoring_server_and_agent_on_debian_9/Screenshot-of-zabbix-db-config-page.png +[7]:https://www.howtoforge.com/images/install_zabbix_monitoring_server_and_agent_on_debian_9/big/Screenshot-of-zabbix-db-config-page.png +[8]:https://www.howtoforge.com/images/install_zabbix_monitoring_server_and_agent_on_debian_9/Screenshot-of-zabbix-server-details.png +[9]:https://www.howtoforge.com/images/install_zabbix_monitoring_server_and_agent_on_debian_9/big/Screenshot-of-zabbix-server-details.png +[10]:https://www.howtoforge.com/images/install_zabbix_monitoring_server_and_agent_on_debian_9/Screenshot-of-pre-installation-summary.png +[11]:https://www.howtoforge.com/images/install_zabbix_monitoring_server_and_agent_on_debian_9/big/Screenshot-of-pre-installation-summary.png +[12]:https://www.howtoforge.com/images/install_zabbix_monitoring_server_and_agent_on_debian_9/Screenshot-of-zabbix-install-success.png +[13]:https://www.howtoforge.com/images/install_zabbix_monitoring_server_and_agent_on_debian_9/big/Screenshot-of-zabbix-install-success.png +[14]:https://www.howtoforge.com/images/install_zabbix_monitoring_server_and_agent_on_debian_9/Screenshot-of-zabbix-login-page.png +[15]:https://www.howtoforge.com/images/install_zabbix_monitoring_server_and_agent_on_debian_9/big/Screenshot-of-zabbix-login-page.png +[16]:https://www.howtoforge.com/images/install_zabbix_monitoring_server_and_agent_on_debian_9/Screenshot-of-zabbix-welcome-dashboard.png +[17]:https://www.howtoforge.com/images/install_zabbix_monitoring_server_and_agent_on_debian_9/big/Screenshot-of-zabbix-welcome-dashboard.png +[18]:https://www.howtoforge.com/images/install_zabbix_monitoring_server_and_agent_on_debian_9/Screenshot-of-zabbix-welcome-dashboard1.png +[19]:https://www.howtoforge.com/images/install_zabbix_monitoring_server_and_agent_on_debian_9/big/Screenshot-of-zabbix-welcome-dashboard1.png +[20]:https://www.howtoforge.com/images/install_zabbix_monitoring_server_and_agent_on_debian_9/Screenshot-of-zabbix-agent-host1.png +[21]:https://www.howtoforge.com/images/install_zabbix_monitoring_server_and_agent_on_debian_9/big/Screenshot-of-zabbix-agent-host1.png +[22]:https://www.howtoforge.com/images/install_zabbix_monitoring_server_and_agent_on_debian_9/Screenshot-of-zabbix-agent-add-templates.png +[23]:https://www.howtoforge.com/images/install_zabbix_monitoring_server_and_agent_on_debian_9/big/Screenshot-of-zabbix-agent-add-templates.png +[24]:https://www.howtoforge.com/images/install_zabbix_monitoring_server_and_agent_on_debian_9/Screenshot-of-zabbix-agent-select-templates.png +[25]:https://www.howtoforge.com/images/install_zabbix_monitoring_server_and_agent_on_debian_9/big/Screenshot-of-zabbix-agent-select-templates.png +[26]:https://www.howtoforge.com/images/install_zabbix_monitoring_server_and_agent_on_debian_9/Screenshot-of-zabbix-agent-dashboard.png +[27]:https://www.howtoforge.com/images/install_zabbix_monitoring_server_and_agent_on_debian_9/big/Screenshot-of-zabbix-agent-dashboard.png +[28]:https://www.zabbix.com/documentation/3.2/ From 94e541216bf7a6e3385e3326354c1e5e8e472c65 Mon Sep 17 00:00:00 2001 From: darksun Date: Tue, 30 Jan 2018 14:41:40 +0800 Subject: [PATCH 048/272] =?UTF-8?q?=E9=80=89=E9=A2=98:=20Being=20open=20ab?= =?UTF-8?q?out=20data=20privacy?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../20180128 Being open about data privacy.md | 107 ++++++++++++++++++ 1 file changed, 107 insertions(+) create mode 100644 sources/talk/20180128 Being open about data privacy.md diff --git a/sources/talk/20180128 Being open about data privacy.md b/sources/talk/20180128 Being open about data privacy.md new file mode 100644 index 0000000000..2deb88922b --- /dev/null +++ b/sources/talk/20180128 Being open about data privacy.md @@ -0,0 +1,107 @@ +Being open about data privacy +====== +![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/GOV_opendata.png?itok=M8L2HGVx) + + +Image by : opensource.com + +Today is [Data Privacy Day][1], ("Data Protection Day" in Europe), and you might think that those of us in the open source world should think that all data should be free, [as information supposedly wants to be][2], but life's not that simple. That's for two main reasons: + + 1. Most of us (and not just in open source) believe there's at least some data about us that we might not feel happy sharing (I compiled an example list in [a post][3] I published a while ago). + 2. Many of us working in open source actually work for commercial companies or other organisations subject to legal requirements around what they can share. + + + +So actually, data privacy is something that's important for pretty much everybody. + +It turns out that the starting point for what data people and governments believe should be available for organisations to use is somewhat different between the U.S. and Europe, with the former generally providing more latitude for entities--particularly, the more cynical might suggest, large commercial entities--to use data they've collected about us as they will. Europe, on the other hand, has historically taken a more restrictive view, and on the 25th of May, Europe's view arguably will have triumphed. + +### The impact of GDPR + +That's a rather sweeping statement, but the fact remains that this is the date on which a piece of legislation called the General Data Protection Regulation (GDPR), enacted by the European Union in 2016, becomes enforceable. The GDPR basically provides a stringent set of rules about how personal data can be stored, what it can be used for, who can see it, and how long it can be kept. It also describes what personal data is--and it's a pretty broad set of items, from your name and home address to your medical records and on through to your computer's IP address. + +What is important about the GDPR, though, is that it doesn't apply just to European companies, but to any organisation processing data about EU citizens. If you're an Argentinian, Japanese, U.S., or Russian company and you're collecting data about an EU citizen, you're subject to it. + +"Pah!" you may say,1 "I'm not based in the EU: what can they do to me?" The answer is simple: If you want to continue doing any business in the EU, you'd better comply, because if you breach GDPR rules, you could be liable for up to four percent of your global revenues. Yes, that's global revenues: not just revenues in a particular country in Europe or across the EU, not just profits, but global revenues. Those are the sorts of numbers that should lead you to talk to your legal team, who will direct you to your exec team, who will almost immediately direct you to your IT group to make sure you're compliant in pretty short order. + +This may seem like it's not particularly relevant to non-EU citizens, but it is. For most companies, it's going to be simpler and more efficient to implement the same protection measures for data associated with all customers, partners, and employees they deal with, rather than just targeting specific measures at EU citizens. This has got to be a good thing.2 + +However, just because GDPR will soon be applied to organisations across the globe doesn't mean that everything's fine and dandy3: it's not. We give away information about ourselves all the time--and permission for companies to use it. + +There's a telling (though disputed) saying: "If you're not paying, you're the product." What this suggests is that if you're not paying for a service, then somebody else is paying to use your data. Do you pay to use Facebook? Twitter? Gmail? How do you think they make their money? Well, partly through advertising, and some might argue that's a service they provide to you, but actually that's them using your data to get money from the advertisers. You're not really a customer of advertising--it's only once you buy something from the advertiser that you become their customer, but until you do, the relationship is between the the owner of the advertising platform and the advertiser. + +Some of these services allow you to pay to reduce or remove advertising (Spotify is a good example), but on the other hand, advertising may be enabled even for services that you think you do pay for (Amazon is apparently working to allow adverts via Alexa, for instance). Unless we want to start paying to use all of these "free" services, we need to be aware of what we're giving up, and making some choices about what we expose and what we don't. + +### Who's the customer? + +There's another issue around data that should be exercising us, and it's a direct consequence of the amounts of data that are being generated. There are many organisations out there--including "public" ones like universities, hospitals, or government departments4--who generate enormous quantities of data all the time, and who just don't have the capacity to store it. It would be a different matter if this data didn't have long-term value, but it does, as the tools for handling Big Data are developing, and organisations are realising they can be mining this now and in the future. + +The problem they face, though, as the amount of data increases and their capacity to store it fails to keep up, is what to do with it. Luckily--and I use this word with a very heavy dose of irony,5 big corporations are stepping in to help them. "Give us your data," they say, "and we'll host it for free. We'll even let you use the data you collected when you want to!" Sounds like a great deal, yes? A fantastic example of big corporations6 taking a philanthropic stance and helping out public organisations that have collected all of that lovely data about us. + +Sadly, philanthropy isn't the only reason. These hosting deals come with a price: in exchange for agreeing to host the data, these corporations get to sell access to it to third parties. And do you think the public organisations, or those whose data is collected, will get a say in who these third parties are or how they will use it? I'll leave this as an exercise for the reader.7 + +### Open and positive + +It's not all bad news, however. There's a growing "open data" movement among governments to encourage departments to make much of their data available to the public and other bodies for free. In some cases, this is being specifically legislated. Many voluntary organisations--particularly those receiving public funding--are starting to do the same. There are glimmerings of interest even from commercial organisations. What's more, there are techniques becoming available, such as those around differential privacy and multi-party computation, that are beginning to allow us to mine data across data sets without revealing too much about individuals--a computing problem that has historically been much less tractable than you might otherwise expect. + +What does this all mean to us? Well, I've written before on Opensource.com about the [commonwealth of open source][4], and I'm increasingly convinced that we need to look beyond just software to other areas: hardware, organisations, and, relevant to this discussion, data. Let's imagine that you're a company (A) that provides a service to another company, a customer (B).8 There are four different types of data in play: + + 1. Data that's fully open: visible to A, B, and the rest of the world + 2. Data that's known, shared, and confidential: visible to A and B, but nobody else + 3. Data that's company-confidential: visible to A, but not B + 4. Data that's customer-confidential: visible to B, but not A + + + +First of all, maybe we should be a bit more open about data and default to putting it into bucket 1. That data--on self-driving cars, voice recognition, mineral deposits, demographic statistics--could be enormously useful if it were available to everyone.9 Also, wouldn't it be great if we could find ways to make the data in buckets 2, 3, and 4--or at least some of it--available in bucket 1, whilst still keeping the details confidential? That's the hope for some of these new techniques being researched. They're a way off, though, so don't get too excited, and in the meantime, start thinking about making more of your data open by default. + +### Some concrete steps + +So, what can we do around data privacy and being open? Here are a few concrete steps that occurred to me: please use the comments to contribute more. + + * Check to see whether your organisation is taking GDPR seriously. If it isn't, push for it. + * Default to encrypting sensitive data (or hashing where appropriate), and deleting when it's no longer required--there's really no excuse for data to be in the clear to these days except for when it's actually being processed. + * Consider what information you disclose when you sign up to services, particularly social media. + * Discuss this with your non-technical friends. + * Educate your children, your friends' children, and their friends. Better yet, go and talk to their teachers about it and present something in their schools. + * Encourage the organisations you work for, volunteer for, or interact with to make data open by default. Rather than thinking, "why should I make this public?" start with "why shouldn't I make this public?" + * Try accessing some of the open data sources out there. Mine it, create apps that use it, perform statistical analyses, draw pretty graphs,10 make interesting music, but consider doing something with it. Tell the organisations that sourced it, thank them, and encourage them to do more. + + + +1. Though you probably won't, I admit. + +2. Assuming that you believe that your personal data should be protected. + +3. If you're wondering what "dandy" means, you're not alone at this point. + +4. Exactly how public these institutions seem to you will probably depend on where you live: [YMMV][5]. + +5. And given that I'm British, that's a really very, very heavy dose. + +6. And they're likely to be big corporations: nobody else can afford all of that storage and the infrastructure to keep it available. + +7. No. The answer's "no." + +8. Although the example works for people, too. Oh, look: A could be Alice, B could be Bob… + +9. Not that we should be exposing personal data or data that actually needs to be confidential, of course--not that type of data. + +10. A friend of mine decided that it always seemed to rain when she picked her children up from school, so to avoid confirmation bias, she accessed rainfall information across the school year and created graphs that she shared on social media. + +-------------------------------------------------------------------------------- + +via: https://opensource.com/article/18/1/being-open-about-data-privacy + +作者:[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://en.wikipedia.org/wiki/Data_Privacy_Day +[2]:https://en.wikipedia.org/wiki/Information_wants_to_be_free +[3]:https://aliceevebob.wordpress.com/2017/06/06/helping-our-governments-differently/ +[4]:https://opensource.com/article/17/11/commonwealth-open-source +[5]:http://www.outpost9.com/reference/jargon/jargon_40.html#TAG2036 From f1fc064797c3e3d7baac826d43486675d7b09862 Mon Sep 17 00:00:00 2001 From: darksun Date: Tue, 30 Jan 2018 14:44:44 +0800 Subject: [PATCH 049/272] =?UTF-8?q?=E9=80=89=E9=A2=98:=20Write=20Dumb=20Co?= =?UTF-8?q?de?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sources/talk/20180127 Write Dumb Code.md | 54 ++++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 sources/talk/20180127 Write Dumb Code.md diff --git a/sources/talk/20180127 Write Dumb Code.md b/sources/talk/20180127 Write Dumb Code.md new file mode 100644 index 0000000000..acc647b0e5 --- /dev/null +++ b/sources/talk/20180127 Write Dumb Code.md @@ -0,0 +1,54 @@ +Write Dumb Code +====== +The best way you can contribute to an open source project is to remove lines of code from it. We should endeavor to write code that a novice programmer can easily understand without explanation or that a maintainer can understand without significant time investment. + +As students we attempt increasingly challenging problems with increasingly sophisticated technologies. We first learn loops, then functions, then classes, etc.. We are praised as we ascend this hierarchy, writing longer programs with more advanced technology. We learn that experienced programmers use monads while new programmers use for loops. + +Then we graduate and find a job or open source project to work on with others. We search for something that we can add, and implement a solution pridefully, using the all the tricks that we learned in school. + +Ah ha! I can extend this project to do X! And I can use inheritance here! Excellent! + +We implement this feature and feel accomplished, and with good reason. Programming in real systems is no small accomplishment. This was certainly my experience. I was excited to write code and proud that I could show off all of the things that I knew how to do to the world. As evidence of my historical love of programming technology, here is a [linear algebra language][1] built with a another meta-programming language. Notice that no one has touched this code in several years. + +However after maintaining code a bit more I now think somewhat differently. + + 1. We should not seek to build software. Software is the currency that we pay to solve problems, which is our actual goal. We should endeavor to build as little software as possible to solve our problems. + 2. We should use technologies that are as simple as possible, so that as many people as possible can use and extend them without needing to understand our advanced techniques. We should use advanced techniques only when we are not smart enough to figure out how to use more common techniques. + + + +Neither of these points are novel. Most people I meet agree with them to some extent, but somehow we forget them when we go to contribute to a new project. The instinct to contribute by building and to demonstrate sophistication often take over. + +### Software is a cost + +Every line that you write costs people time. It costs you time to write it of course, but you are willing to make this personal sacrifice. However this code also costs the reviewers their time to understand it. It costs future maintainers and developers their time as they fix and modify your code. They could be spending this time outside in the sunshine or with their family. + +So when you add code to a project you should feel meek. It should feel as though you are eating with your family and there isn't enough food on the table. You should take only what you need and no more. The people with you will respect you for your efforts to restrict yourself. Solving problems with less code is a hard, but it is a burden that you take on yourself to lighten the burdens of others. + +### Complex technologies are harder to maintain + +As students, we demonstrate merit by using increasingly advanced technologies. Our measure of worth depends on our ability to use functions, then classes, then higher order functions, then monads, etc. in public projects. We show off our solutions to our peers and feel pride or shame according to our sophistication. + +However when working with a team to solve problems in the world the situation is reversed. Now we strive to solve problems with code that is as simple as possible. When we solve a problem simply we enable junior programmers to extend our solution to solve other problems. Simple code enables others and boosts our impact. We demonstrate our value by solving hard problems with only basic techniques. + +Look! I replaced this recursive function with a for loop and it still does everything that we need it to. I know it's not as clever, but I noticed that the interns were having trouble with it and I thought that this change might help. + +If you are a good programmer then you don't need to demonstrate that you know cool tricks. Instead, you can demonstrate your value by solving a problem in a simple way that enables everyone on your team to contribute in the future. + +### But moderation, of course + +That being said, over-adherence to the "build things with simple tools" dogma can be counter productive. Often a recursive solution can be much simpler than a for-loop solution and often times using a Class or a Monad is the right approach. But we should be mindful when using these technologies that we are building for ourselves our own system; a system with which others have had no experience. + + +-------------------------------------------------------------------------------- + +via: http://matthewrocklin.com/blog/work/2018/01/27/write-dumb-code + +作者:[Matthew Rocklin][a] +译者:[译者ID](https://github.com/译者ID) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:http://matthewrocklin.com +[1]:https://github.com/mrocklin/matrix-algebra From fe0187bda10b28520faf1db8e3d513b148ddbbfa Mon Sep 17 00:00:00 2001 From: darksun Date: Tue, 30 Jan 2018 14:50:09 +0800 Subject: [PATCH 050/272] =?UTF-8?q?=E9=80=89=E9=A2=98:=20How=20To=20Turn?= =?UTF-8?q?=20On/Off=20Colors=20For=20ls=20Command=20In=20Bash=20On=20a=20?= =?UTF-8?q?Linux/Unix?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ... For ls Command In Bash On a Linux-Unix.md | 87 +++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 sources/tech/20061104 How To Turn On-Off Colors For ls Command In Bash On a Linux-Unix.md diff --git a/sources/tech/20061104 How To Turn On-Off Colors For ls Command In Bash On a Linux-Unix.md b/sources/tech/20061104 How To Turn On-Off Colors For ls Command In Bash On a Linux-Unix.md new file mode 100644 index 0000000000..837179ee25 --- /dev/null +++ b/sources/tech/20061104 How To Turn On-Off Colors For ls Command In Bash On a Linux-Unix.md @@ -0,0 +1,87 @@ +How To Turn On/Off Colors For ls Command In Bash On a Linux/Unix +====== + +How do I turn on or off file name colors (ls command colors) in bash shell on a Linux or Unix like operating systems? + +Most modern Linux distributions and Unix systems comes with alias that defines colors for your file. However, ls command is responsible for displaying color on screen for files, directories and other file system objects. + +By default, color is not used to distinguish types of files. You need to pass --color option to the ls command on Linux. If you are using OS X or BSD based system pass -G option to the ls command. The syntax is as follows to turn on or off colors. + +#### How to turn off colors for ls command + +Type the following command +`$ ls --color=none` +Or just remove alias with the unalias command: +`$ unalias ls` +Please note that the following bash shell aliases are defined to display color with the ls command. Use combination of [alias command][1] and [grep command][2] as follows: +`$ alias | grep ls` +Sample outputs +``` +alias l='ls -CF' +alias la='ls -A' +alias ll='ls -alF' +alias ls='ls --color=auto' +``` + +#### How to turn on colors for ls command + +Use any one of the following command: +``` +$ ls --color=auto +$ ls --color=tty +``` +[Define bash shell aliases ][3]if you want: +`alias ls='ls --color=auto'` +You can add or remove ls command alias to the ~/.bash_profile or [~/.bashrc file][4]. Edit file using a text editor such as vi command: +`$ vi ~/.bashrc` +Append the following code: +``` +# my ls command aliases # +alias ls = 'ls --color=auto' +``` + +[Save and close the file in Vi/Vim text editor][5]. + +#### A note about *BSD/macOS/Apple OS X ls command + +Pass the -G option to ls command to enable colorized output on a {Free,Net,Open}BSD or macOS and Apple OS X Unix family of operating systems: +`$ ls -G` +Sample outputs: +[![How to enable colorized output for the ls command in Mac OS X Terminal][6]][7] +How to enable colorized output for the ls command in Mac OS X Terminal + +#### How do I skip colorful ls command output temporarily? + +You can always [disable bash shell aliases temporarily][8] using any one of the following syntax: +`\ls +/bin/ls +command ls +'ls'` + + +#### 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][9], [Facebook][10], [Google+][11]. + +-------------------------------------------------------------------------------- + +via: https://www.cyberciti.biz/faq/how-to-turn-on-or-off-colors-in-bash/ + +作者:[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/tips/bash-aliases-mac-centos-linux-unix.html (See Linux/Unix alias command examples for more info) +[2]:https://www.cyberciti.biz/faq/howto-use-grep-command-in-linux-unix/ (See Linux/Unix grep command examples for more info) +[3]:https://www.cyberciti.biz/tips/bash-aliases-mac-centos-linux-unix.html +[4]:https://bash.cyberciti.biz/guide/~/.bashrc +[5]:https://www.cyberciti.biz/faq/linux-unix-vim-save-and-quit-command/ +[6]:https://www.cyberciti.biz/media/new/faq/2016/01/color-ls-for-Mac-OS-X.jpg +[7]:https://www.cyberciti.biz/faq/apple-mac-osx-terminal-color-ls-output-option/ +[8]:https://www.cyberciti.biz/faq/bash-shell-temporarily-disable-an-alias/ +[9]:https://twitter.com/nixcraft +[10]:https://facebook.com/nixcraft +[11]:https://plus.google.com/+CybercitiBiz From 4252754ae731aca4ce18156abf21730ae7718685 Mon Sep 17 00:00:00 2001 From: darksun Date: Tue, 30 Jan 2018 14:56:37 +0800 Subject: [PATCH 051/272] =?UTF-8?q?=E9=80=89=E9=A2=98:=20www.reallylinux.c?= =?UTF-8?q?om=20exclusive?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../20180128 www.reallylinux.com exclusive.md | 98 +++++++++++++++++++ 1 file changed, 98 insertions(+) create mode 100644 sources/tech/20180128 www.reallylinux.com exclusive.md diff --git a/sources/tech/20180128 www.reallylinux.com exclusive.md b/sources/tech/20180128 www.reallylinux.com exclusive.md new file mode 100644 index 0000000000..5599bf8057 --- /dev/null +++ b/sources/tech/20180128 www.reallylinux.com exclusive.md @@ -0,0 +1,98 @@ +www.reallylinux.com exclusive +====== + +In a qualitative review of job posting websites, even highly skilled Linux administrators would be hamstrung to succeed in getting to the stage of an interview. + +All of this results in hundreds of decent and skilled people being snubbed without cause simply because today's job market requires a few extra tools to increase the odds. + +I have two colleagues and a cousin who have all received certifications with RedHat, managed quite extensive server rooms, and received earnest recommendations from former employers. + +All of these skills, certifications and experience come to naught as they apply to employer ads that are crudely constructed by someone hurriedly cutting and pasting snippets of "skill words" from a list of technical terms. + +Not surprisingly, today's politeness has gone the way of the bird, and a **non-response** from companies posting ads seems to be the new way of communicating. + +Unfortunately, it also means that these recruiters/HR personnel probably did **not** get the best candidate. + +The reason I can say this with such conviction is because of the type of buffoonery that takes place so often when creating job ads in the first place. + +Walter, another [Reallylinux.com][3] guest writer, presented how [**Job Want Ads Have Gone Mad**][4]. + +Perhaps he's right. However, I believe every Linux job seeker can avoid pitfalls of a job hunt by keeping in mind **three key facts** about job ads. + +First, few advertisements for Linux administrators are exclusively about Linux. + +Bear in mind the occasional Linux system administrator job, where you would actually be using Linux on servers. Instead, many jobs that rise up on a "Linux administrator" search are actually referring to a plethora of 'NX operating systems. + +For example, here is a quote from a **"Linux Administrator"** job posting: +This role will provide support for build system integration, especially operating system installation support for BSD applications... + +Or another ad declares in the bowels of its content: +Windows administration experience required. + +Ironically, if you show up to interview for any of these types of jobs and focus on Linux, they probably will not choose you. + +Even more importantly, if you simply include Linux as your expertise, they may not even bother with your resume, because they can't tell the difference between UNIX, BSD, Linux, etc. + +As a result, if you are conscientious and only include Linux on your resume, you are automatically out. But change that Linux to UNIX/Linux and you end up getting a bit farther in the human resources bureaucracy. + +I had two colleagues that ended up changing this on their resumes and getting a much better hit ratio for interviews, which were still slim pickings because most job ads are tailored with some particular person already in mind. The main intent behind such job ads being a cover for the ass of the department making the claim of having an open job. + +Second, the only person at the company who cares at all about the system administrator position is the technical lead/manager hiring for the slot. Others at the company, including the HR contact or the management could not care less. + +I remember sitting in a board room as a fly on the wall, hearing one executive vice president refer to server administrators as "dime a dozen geeks." How wrong they are to suggest this. + +Ironically, one day should the mail system fail, or the PBX connectivity hiccup, or perhaps core business files disappear from the intranet, these same executives are the first to get on the phone and threaten to fire the system admins. + +Perhaps if they would stop leaving so many hot air telephone messages, or filling their emails with 35MB photographs of another vice president's fishing trip and wife, the servers wouldn't be so problematic. + +Be aware that a Linux administrator ad, or any job posting for server administrator is placed because someone at the TECHNICAL level sees an urgent need for staffing. You're not going to get any empathy talking to HR or any leader of the company. Instead, take the time to find out who the hiring technical manager is and try to telephone them. + +You can always call them directly because you have some "specific technical questions" you know the HR person could not answer. This opens the dialogue with the person who actually cares that the position is filled and ensures you get a foot in because you took the time for personal contact, even if it was a 60 second phone call. + +What if the HR beauracracy won't let you through? + +Start asking as many tech questions as possible direct to the HR hiring contact, such as how their Linux clusters are setup and do they run VMs exclusively? Anything relatively technical will send these HR people in a tizzy and allow you the question: "may I contact the technical manager of the team?" + +If the response is a fluffy "maybe" or "I'll get back to you on that" they already filled the slot in their mind with someone else two weeks earlier, such as the HR staff member's fiance. They simply wanted it to look less like nepotism and more like indeterminism with a dash of egoism. + +``` +"They simply wanted it to look less like nepotism and more like indeterminism with a dash of egoism." +``` + +So take the time to find out who is the direct TECHNICAL leader hiring for the position and talk to them. It can make a difference and get you past some of the baloney. + +Third, few job ads today include any semblance of reality. + +I've seen enough ads requiring a junior system administrator with expertise that senior level experts don't have, to know the plan is to list the blue sky wish list and then find out who applies. + +In this situation, the Linux administrator ad you apply for, should include some key phrases for which you already have experience or certifications. + +The trick is to so overload your resume with the key phrases that MATCH their ad, it becomes almost impossible for them to determine which phrases you left out. + +This doesn't necessarily translate to a job, but it often adds enough intrigue to get you an interview, which now a days is a major step. + +By understanding and applying these three techniques, hopefully those seeking Linux administrator jobs have a head start on those who have only a slim chance in hell. + +Even if these tips don't get you interviews right away, you can use the experience and awareness when you go to the next trade show, or company sponsored technical conference. + +I strongly recommend you regularly attend these as well, especially if they are reasonably close, as they always provide a kick start to networking. + +Remember that job networking now a days is a pseudonym for "getting the gossip on which companies are actually hiring and which ones are just lying about jobs to give the appearance of growth for shareholders." + + + +-------------------------------------------------------------------------------- + +via: http://reallylinux.com/docs/gettinglinuxjobs.shtml + +作者:[Andrea W.Codingly][a] +译者:[译者ID](https://github.com/译者ID) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:http://reallylinux.com +[1]:http://www.reallylinux.com +[2]:http://reallylinux.com/docs/linuxrecessionproof.shtml +[3]:http://reallylinux.com +[4]:http://reallylinux.com/docs/wantadsmad.shtml From a0dd655253d6c5954679c968739ddf2584276639 Mon Sep 17 00:00:00 2001 From: darksun Date: Tue, 30 Jan 2018 15:01:45 +0800 Subject: [PATCH 052/272] add done: 20180128 www.reallylinux.com exclusive.md --- ...llylinux.com exclusive.md => 20180128 Getting Linux Jobs.md} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename sources/tech/{20180128 www.reallylinux.com exclusive.md => 20180128 Getting Linux Jobs.md} (99%) diff --git a/sources/tech/20180128 www.reallylinux.com exclusive.md b/sources/tech/20180128 Getting Linux Jobs.md similarity index 99% rename from sources/tech/20180128 www.reallylinux.com exclusive.md rename to sources/tech/20180128 Getting Linux Jobs.md index 5599bf8057..a7f1a075a5 100644 --- a/sources/tech/20180128 www.reallylinux.com exclusive.md +++ b/sources/tech/20180128 Getting Linux Jobs.md @@ -1,4 +1,4 @@ -www.reallylinux.com exclusive +Getting Linux Jobs ====== In a qualitative review of job posting websites, even highly skilled Linux administrators would be hamstrung to succeed in getting to the stage of an interview. From e9983a4dac9772292ae842759a35a51f8c616513 Mon Sep 17 00:00:00 2001 From: darksun Date: Tue, 30 Jan 2018 15:08:50 +0800 Subject: [PATCH 053/272] =?UTF-8?q?=E9=80=89=E9=A2=98:=20How=20to=20add=20?= =?UTF-8?q?network=20bridge=20with=20nmcli=20(NetworkManager)=20on=20Linux?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...ge with nmcli (NetworkManager) on Linux.md | 146 ++++++++++++++++++ 1 file changed, 146 insertions(+) create mode 100644 sources/tech/20180128 How to add network bridge with nmcli (NetworkManager) on Linux.md diff --git a/sources/tech/20180128 How to add network bridge with nmcli (NetworkManager) on Linux.md b/sources/tech/20180128 How to add network bridge with nmcli (NetworkManager) on Linux.md new file mode 100644 index 0000000000..bf7772ef1a --- /dev/null +++ b/sources/tech/20180128 How to add network bridge with nmcli (NetworkManager) on Linux.md @@ -0,0 +1,146 @@ +How to add network bridge with nmcli (NetworkManager) on Linux +====== + +I am using Debian Linux 9 "stretch" on the desktop. I would like to create network bridge with NetworkManager. But, I am unable to find the option to add br0. How can I create or add network bridge with nmcli for NetworkManager on Linux? + +A bridge is nothing but a device which joins two local networks into one network. It works at the data link layer, i.e., layer 2 of the OSI model. Network bridge often used with virtualization and other software. Disabling NetworkManager for a simple bridge especially on Linux Laptop/desktop doesn't make any sense. The nmcli tool can create Persistent bridge configuration without editing any files. **This page shows how to create a bridge interface using the Network Manager command line tool called nmcli**. + + + +### How to create/add network bridge with nmcli + +The procedure to add a bridge interface on Linux is as follows when you want to use Network Manager: + +1. Open the Terminal app +2. Get info about the current connection: +``` +nmcli con show +``` +3. Add a new bridge: +``` +nmcli con add type bridge ifname br0 +``` +4. Create a slave interface: +``` +nmcli con add type bridge-slave ifname eno1 master br0 +``` +5. Turn on br0: +``` +nmcli con up br0 +``` + +Let us see how to create a bridge, named br0 in details. + +### Get current network config + +You can view connection from the Network Manager GUI in settings: +[![Getting Network Info on Linux][1]][1] +Another option is to type the following command: +``` +$ nmcli con show +$ nmcli connection show --active +``` +[![View the connections with nmcli][2]][2] +I have a "Wired connection 1" which uses the eno1 Ethernet interface. My system has a VPN interface too. I am going to setup a bridge interface named br0 and add, (or enslave) an interface to eno1. + +### How to create a bridge, named br0 + +``` +$ sudo nmcli con add ifname br0 type bridge con-name br0 +$ sudo nmcli con add type bridge-slave ifname eno1 master br0 +$ nmcli connection show +``` +[![Create bridge interface using nmcli on Linux][3]][3] +You can disable STP too: +``` +$ sudo nmcli con modify br0 bridge.stp no +$ nmcli con show +$ nmcli -f bridge con show br0 +``` +The last command shows the bridge settings including disabled STP: +``` +bridge.mac-address: -- +bridge.stp: no +bridge.priority: 32768 +bridge.forward-delay: 15 +bridge.hello-time: 2 +bridge.max-age: 20 +bridge.ageing-time: 300 +bridge.multicast-snooping: yes +``` + + +### How to turn on bridge interface + +You must turn off "Wired connection 1" and turn on br0: +``` +$ sudo nmcli con down "Wired connection 1" +$ sudo nmcli con up br0 +$ nmcli con show +``` +Use [ip command][4] to view the IP settings: +``` +$ ip a s +$ ip a s br0 +``` +[![Build a network bridge with nmcli on Linux][5]][5] + +### Optional: How to use br0 with KVM + +Now you can connect VMs (virtual machine) created with KVM/VirtualBox/VMware workstation to a network directly without using NAT. Create a file named br0.xml for KVM using vi command or [cat command][6]: +`$ cat /tmp/br0.xml` +Append the following code: +``` + + br0 + + + +``` + +Run virsh command as follows: +``` +# virsh net-define /tmp/br0.xml +# virsh net-start br0 +# virsh net-autostart br0 +# virsh net-list --all +``` +Sample outputs: +``` + Name State Autostart Persistent +---------------------------------------------------------- + br0 active yes yes + default inactive no yes +``` + + +For more info read the following man page: +``` +$ man ip +$ man nmcli +``` + +### about the author + +The author is the creator of nixCraft and a seasoned sysadmin and a trainer for the Linux operating system/Unix shell scripting. He has worked with global clients and in various industries, including IT, education, defense and space research, and the nonprofit sector. Follow him on [Twitter][7], [Facebook][8], [Google+][9]. + +-------------------------------------------------------------------------------- + +via: https://www.cyberciti.biz/faq/how-to-add-network-bridge-with-nmcli-networkmanager-on-linux/ + +作者:[Vivek Gite][a] +译者:[译者ID](https://github.com/译者ID) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://www.cyberciti.biz +[1]:https://www.cyberciti.biz/media/new/faq/2018/01/Getting-Network-Info-on-Linux.jpg +[2]:https://www.cyberciti.biz/media/new/faq/2018/01/View-the-connections-with-nmcli.jpg +[3]:https://www.cyberciti.biz/media/new/faq/2018/01/Create-bridge-interface-using-nmcli-on-Linux.jpg +[4]:https://www.cyberciti.biz/faq/linux-ip-command-examples-usage-syntax/ (See Linux/Unix ip command examples for more info) +[5]:https://www.cyberciti.biz/media/new/faq/2018/01/Build-a-network-bridge-with-nmcli-on-Linux.jpg +[6]:https://www.cyberciti.biz/faq/linux-unix-appleosx-bsd-cat-command-examples/ (See Linux/Unix cat command examples for more info) +[7]:https://twitter.com/nixcraft +[8]:https://facebook.com/nixcraft +[9]:https://plus.google.com/+CybercitiBiz From 74d09d9c0dbaa4c3368101c5fa0b332579ce3a2f Mon Sep 17 00:00:00 2001 From: darksun Date: Tue, 30 Jan 2018 15:18:52 +0800 Subject: [PATCH 054/272] =?UTF-8?q?=E9=80=89=E9=A2=98:=20How=20to=20Make?= =?UTF-8?q?=20a=20Minecraft=20Server=20=E2=80=93=20ThisHosting.Rocks?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ... a Minecraft Server - ThisHosting.Rocks.md | 416 ++++++++++++++++++ 1 file changed, 416 insertions(+) create mode 100644 sources/tech/20180126 How to Make a Minecraft Server - ThisHosting.Rocks.md diff --git a/sources/tech/20180126 How to Make a Minecraft Server - ThisHosting.Rocks.md b/sources/tech/20180126 How to Make a Minecraft Server - ThisHosting.Rocks.md new file mode 100644 index 0000000000..3c948e65ba --- /dev/null +++ b/sources/tech/20180126 How to Make a Minecraft Server - ThisHosting.Rocks.md @@ -0,0 +1,416 @@ +How to Make a Minecraft Server – ThisHosting.Rocks +====== +We’ll show you how to make a Minecraft server with beginner-friendly step-by-step instructions. It will be a persistent multiplayer server that you can play on with your friends from all around the world. You don’t have to be in a LAN. + +### How to Make a Minecraft Server – Quick Guide + +This is our “Table of contents” if you’re in a hurry and want to go straight to the point. We recommend reading everything though. + +* [Learn stuff][1] (optional) + +* [Learn more stuff][2] (optional) + +* [Requirements][3] (required) + +* [Install and start the Minecraft server][4] (required) + +* [Run the server even after you log out of your VPS][5] (optional) + +* [Make the server automatically start at boot][6] (optional) + +* [Configure your Minecraft server][7] (required) + +* [FAQs][8] (optional) + +Before going into the actual instructions, a few things you should know: + +#### Reasons why you would NOT use a specialized Minecraft server hosting provider + +Since you’re here, you’re obviously interested in hosting your own Minecraft server. There are more reasons why you would not use a specialized Minecraft hosting provider, but here are a few: + +* They’re slow most of the time. This is because you actually share the resources with multiple users. It becomes overloaded at some point. Most of them oversell their servers too. + +* You don’t have full control over the Minecraft server or the actual server. You cannot customize anything you want to. + +* You’re limited. Those kinds of hosting plans are always limited in one way or another. + +Of course, there are positives to using a Minecraft hosting provider. The best upside is that you don’t actually have to do all the stuff we’ll write about below. But where’s the fun in that? +![🙂](https://s.w.org/images/core/emoji/2.3/svg/1f642.svg) + +#### Why you should NOT use your personal computer to make a Minecraft server + +We noticed lots of tutorials showing you how to host a server on your own computer. There are downsides to doing that, like: + +* Your home internet is not secured enough to handle DDoS attacks. Game servers are often prone to DDoS attacks, and your home network setup is most probably not secured enough to handle them. It’s most likely not powerful enough to handle a small attack. + +* You’ll need to handle port forwarding. If you’ve tried making a Minecraft server on your home network, you’ve surely stumbled upon port forwarding and had issues with it. + +* You’ll need to keep your computer on at all times. Your electricity bill will sky-rocket and you’ll add unnecessary load to your hardware. The hardware most servers use is enterprise-grade and designed to handle loads, with improved stability and longevity. + +* Your home internet is not fast enough. Home networks are not designed to handle multiplayer games. You’ll need a much larger internet plan to even consider making a small server. Luckily, data centers have multiple high-speed, enterprise-grade internet connections making sure they have (or strive to have) 100% uptime. + +* Your hardware is most likely not good enough. Again, servers use enterprise-grade hardware, latest and fastest CPUs, SSDs, and much more. Your personal computer most likely does not. + +* You probably use Windows/MacOS on your personal computer. Though this is debatable, we believe that Linux is much better for game hosting. Don’t worry, you don’t really need to know everything about Linux to make a Minecraft server (though it’s recommended). We’ll show you everything you need to know. + +Our tip is not to use your personal computer, though technically you can. It’s not expensive to buy a cloud server. We’ll show you how to make a Minecraft server on cloud hosting below. It’s easy if you carefully follow the steps. + +### Making a Minecraft Server – Requirements + +There are a few requirements. You should have and know all of this before continuing to the tutorial: + +* You’ll need a [Linux cloud server][9]. We recommend [Vultr][10]. Their prices are cheap, services are high-quality, customer support is great, all server hardware is high-end. Check the [Minecraft server requirements][11] to find out what kind of server you should get (resources like RAM and Disk space). We recommend getting the $20 per month server. They support hourly pricing so if you only need the server temporary for playing with friends, you’ll pay less. Choose the Ubuntu 16.04 distro during signup. Choose the closest server location to where your players live during the signup process. Keep in mind that you’ll be responsible for your server. So you’ll have to secure it and manage it. If you don’t want to do that, you can get a [managed server][12], in which case the hosting provider will likely make a Minecraft server for you. + +* You’ll need an SSH client to connect to the Linux cloud server. [PuTTy][13] is often recommended for beginners, but we also recommend [MobaXTerm][14]. There are many other SSH clients to choose from, so pick your favorite. + +* You’ll need to setup your server (basic security setup at least). Google it and you’ll find many tutorials. You can use [Linode’s Security Guide][15] and follow the exact steps on your [Vultr][16] server. + +* We’ll handle the software requirements like Java below. + +And finally, onto our actual tutorial: + +### How to Make a Minecraft Server on Ubuntu (Linux) + +These instructions are written for and tested on an Ubuntu 16.04 server from [Vultr][17]. Though they’ll also work on Ubuntu 14.04, [Ubuntu 18.04][18], and any other Ubuntu-based distro, and any other server provider. + +We’re using the default Vanilla server from Minecraft. You can use alternatives like CraftBukkit or Spigot that allow more customizations and plugins. Though if you use too many plugins you’ll essentially ruin the server. There are pros and cons to each one. Nevertheless, the instructions below are for the default Vanilla server to keep things simple and beginner-friendly. We may publish a tutorial for CraftBukkit soon if there’s an interest. + +#### 1. Login to your server + +We’ll use the root user. If you use a limited-user, you’ll have to execute most commands with ‘sudo’. You’ll get a warning if you’re doing something you don’t have enough permissions for. + +You can login to your server via your SSH client. Use your server IP and your port (most likely 22). + +After you log in, make sure you [secure your server][19]. + +#### 2. Update Ubuntu + +You should always first update your Ubuntu before you do anything else. You can update it with the following commands: + +``` +apt-get update && apt-get upgrade +``` + +Hit “enter” and/or “y” when prompted. + +#### 3. Install necessary tools + +You’ll need a few packages and tools for various things in this tutorial like text editing, making your server persistent etc. Install them with the following command: + +``` +apt-get install nano wget screen bash default-jdk ufw +``` + +Some of them may already be installed. + +#### 4. Download Minecraft Server + +First, create a directory where you’ll store your Minecraft server and all other files: + +``` +mkdir /opt/minecraft +``` + +And navigate to the new directory: + +``` +cd /opt/minecraft +``` + +Now you can download the Minecraft Server file. Go to the [download page][20] and get the link there. Download the file with wget: + +``` +wget https://s3.amazonaws.com/Minecraft.Download/versions/1.12.2/minecraft_server.1.12.2.jar +``` + +#### 5. Install the Minecraft server + +Once you’ve downloaded the server .jar file, you need to run it once and it will generate some files, including an eula.txt license file. The first time you run it, it will return an error and exit. That’s supposed to happen. Run in with the following command: + +``` +java -Xms2048M -Xmx3472M -jar minecraft_server.1.12.2.jar nogui +``` + +“-Xms2048M” is the minimum RAM that your Minecraft server can use and “-Xmx3472M” is the maximum. [Adjust][21] this based on your server’s resources. If you got the 4GB RAM server from [Vultr][22] you can leave them as-is, if you don’t use the server for anything else other than Minecraft. + +After that command ends and returns an error, a new eula.txt file will be generated. You need to accept the license in that file. You can do that by adding “eula=true” to the file with the following command: + +``` +sed -i.orig 's/eula=false/eula=true/g' eula.txt +``` + +You can now start the server again and access the Minecraft server console with that same java command from before: + +``` +java -Xms2048M -Xmx3472M -jar minecraft_server.1.12.2.jar nogui +``` + +Make sure you’re in the /opt/minecraft directory, or the directory where you installed your MC server. + +You’re free to stop here if you’re just testing this and need it for the short-term. If you’re having trouble loggin into the server, you’ll need to [configure your firewall][23]. + +The first time you successfully start the server it will take a bit longer to generate + +We’ll show you how to create a script so you can start the server with it. + +#### 6. Start the Minecraft server with a script, make it persistent, and enable it at boot + +To make things easier, we’ll create a bash script that will start the server automatically. + +So first, create a bash script with nano: + +``` +nano /opt/minecraft/startminecraft.sh +``` + +A new (blank) file will open. Paste the following: + +``` +#!/bin/bash +cd /opt/minecraft/ && java -Xms2048M -Xmx3472M -jar minecraft_server.1.12.2.jar nogui +``` + +If you’re new to nano – you can save and close the file with “CTRL + X”, then “Y”, and hitting enter. This script navigates to your Minecraft server directory you created previously and runs the java command for starting the server. You need to make it executable with the following command: + +``` +chmod +x startminecraft.sh +``` + +Then, you can start the server anytime with the following command: + +``` +/opt/minecraft/startminecraft.sh +``` + +But, if/when you log out of the SSH session the server will turn off. To keep the server up without being logged in all the time, you can use a screen session. A screen session basically means that it will keep running until the actual server reboots or turns off. + +Start a screen session with this command: + +``` +screen -S minecraft +``` + +Once you’re in the screen session (looks like you would start a new ssh session), you can use the bash script from earlier to start the server: + +``` +/opt/minecraft/startminecraft.sh +``` + +To get out of the screen session, you should press CTRL + A-D. Even after you get out of the screen session (detach), the server will keep running. You can safely log off your Ubuntu server now, and the Minecraft server you created will keep running. + +But, if the Ubuntu server reboots or shuts off, the screen session won’t work anymore. So **to do everything we did before automatically at boot** , do the following: + +Open the /etc/rc.local file: + +``` +nano /etc/rc.local +``` + +and add the following line above the “exit 0” line: + +``` +screen -dm -S minecraft /opt/minecraft/startminecraft.sh +exit 0 +``` + +Save and close the file. + +To access the Minecraft server console, just run the following command to attach to the screen session: + +``` +screen -r minecraft +``` + +That’s it for now. Congrats and have fun! You can now connect to your Minecraft server or configure/modify it. + +### Configure your Ubuntu Server + +You’ll, of course, need to set up your Ubuntu server and secure it if you haven’t already done so. Follow the [guide we mentioned earlier][24] and google it for more info. The configurations you need to do for your Minecraft server on your Ubuntu server are: + +#### Enable and configure the firewall + +First, if it’s not already enabled, you should enable UFW that you previously installed: + +``` +ufw enable +``` + +You should allow the default Minecraft server port: + +``` +ufw allow 25565/tcp +``` + +You should allow and deny other rules depending on how you use your server. You should deny ports like 80 and 443 if you don’t use the server for hosting websites. Google a UFW/Firewall guide for Ubuntu and you’ll get recommendations. Be careful when setting up your firewall, you may lock yourself out of your server if you block the SSH port. + +Since this is the default port, it often gets automatically scanned and attacked. You can prevent attacks by blocking access to anyone that’s not of your whitelist. + +First, you need to enable the whitelist mode in your [server.properties][25] file. To do that, open the file: + +``` +nano /opt/minecraft/server.properties +``` + +And change “white-list” line to “true”: + +``` +white-list=true +``` + +Save and close the file. + +Then restart your server (either by restarting your Ubuntu server or by running the start bash script again): + +``` +/opt/minecraft/startminecraft.sh +``` + +Access the Minecraft server console: + +``` +screen -r minecraft +``` + +And if you want someone to be able to join your server, you need to add them to the whitelist with the following command: + +``` +whitelist add PlayerUsername +``` + +To remove them from the whitelist, use: + +``` +whitelist remove PlayerUsername +``` + +Exit the screen session (server console) with CTRL + A-D. It’s worth noting that this will deny access to everyone but the whitelisted usernames. + + [![how to create a minecraft server](https://thishosting.rocks/wp-content/uploads/2018/01/create-a-minecraft-server.jpg)][26] + +### How to Make a Minecraft Server – FAQs + +We’ll answer some frequently asked questions about Minecraft Servers and our guide. + +#### How do I restart the Minecraft server? + +If you followed every step from our tutorial, including enabling the server to start on boot, you can just reboot your Ubuntu server. If you didn’t set it up to start at boot, you can just run the start script again which will restart the Minecraft server: + +``` +/opt/minecraft/startminecraft.sh +``` + +#### How do I configure my Minecraft server? + +You can configure your server using the [server.properties][27] file. Check the Minecraft Wiki for more info, though you can leave everything as-is and it will work perfectly fine. + +If you want to change the game mode, difficulty and stuff like that, you can use the server console. Access the server console by running: + +``` +screen -r minecraft +``` + +And execute [commands][28] there. Commands like: + +``` +difficulty hard +``` + +``` +gamemode survival @a +``` + +You may need to restart the server depending on what command you used. There are many more commands you can use, check the [wiki][29] for more. + +#### How do I upgrade my Minecraft server? + +If there’s a new release, you need to do this: + +Navigate to the minecraft directory: + +``` +cd /opt/minecraft +``` + +Download the latest version, example 1.12.3 with wget: + +``` +wget https://s3.amazonaws.com/Minecraft.Download/versions/1.12.3/minecraft_server.1.12.3.jar +``` + +Next, run and build the new server: + +``` +java -Xms2048M -Xmx3472M -jar minecraft_server.1.12.3.jar nogui +``` + +Finally, update your start script: + +``` +nano /opt/minecraft/startminecraft.sh +``` + +And update the version number accordingly: + +``` +#!/bin/bash +cd /opt/minecraft/ && java -Xms2048M -Xmx3472M -jar minecraft_server.1.12.3.jar nogui +``` + +Now you can restart the server and everything should go well. + +#### Why is your Minecraft server tutorial so long, and yet others are only 2 lines long?! + +We tried to make this beginner-friendly and be as detailed as possible. We also showed you how to make the Minecraft server persistent and start it automatically at boot, we showed you how to configure your server and everything. I mean, sure, you can start a Minecraft server with a couple of lines, but it would definitely suck, for more than one reason. + +#### I don’t know Linux or anything you wrote about here, how do I make a Minecraft server? + +Just read all of our article and copy and paste the commands. If you really don’t know how to do it all, [we can do it for you][30], or just get a [managed][31] server [provider][32] and let them do it for you. + +#### How do I install mods on my server? How do I install plugins? + +Our article is intended to be a starting guide. You should check the [Minecraft wiki][33] for more info, or just google it. There are plenty of tutorials online + +-------------------------------------------------------------------------------- + +via: https://thishosting.rocks/how-to-make-a-minecraft-server/ + +作者:[ThisHosting.Rocks][a] +译者:[译者ID](https://github.com/译者ID) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://thishosting.rocks +[1]:https://thishosting.rocks/how-to-make-a-minecraft-server/#reasons +[2]:https://thishosting.rocks/how-to-make-a-minecraft-server/#not-pc +[3]:https://thishosting.rocks/how-to-make-a-minecraft-server/#requirements +[4]:https://thishosting.rocks/how-to-make-a-minecraft-server/#make-minecraft-server +[5]:https://thishosting.rocks/how-to-make-a-minecraft-server/#persistent +[6]:https://thishosting.rocks/how-to-make-a-minecraft-server/#boot +[7]:https://thishosting.rocks/how-to-make-a-minecraft-server/#configure-minecraft-server +[8]:https://thishosting.rocks/how-to-make-a-minecraft-server/#faqs +[9]:https://thishosting.rocks/cheap-cloud-hosting-providers-comparison/ +[10]:https://thishosting.rocks/go/vultr/ +[11]:https://minecraft.gamepedia.com/Server/Requirements/Dedicated +[12]:https://thishosting.rocks/best-cheap-managed-vps/ +[13]:https://www.chiark.greenend.org.uk/~sgtatham/putty/ +[14]:https://mobaxterm.mobatek.net/ +[15]:https://www.linode.com/docs/security/securing-your-server/ +[16]:https://thishosting.rocks/go/vultr/ +[17]:https://thishosting.rocks/go/vultr/ +[18]:https://thishosting.rocks/ubuntu-18-04-new-features-release-date/ +[19]:https://www.linode.com/docs/security/securing-your-server/ +[20]:https://minecraft.net/en-us/download/server +[21]:https://minecraft.gamepedia.com/Commands +[22]:https://thishosting.rocks/go/vultr/ +[23]:https://thishosting.rocks/how-to-make-a-minecraft-server/#configure-minecraft-server +[24]:https://www.linode.com/docs/security/securing-your-server/ +[25]:https://minecraft.gamepedia.com/Server.properties +[26]:https://thishosting.rocks/wp-content/uploads/2018/01/create-a-minecraft-server.jpg +[27]:https://minecraft.gamepedia.com/Server.properties +[28]:https://minecraft.gamepedia.com/Commands +[29]:https://minecraft.gamepedia.com/Commands +[30]:https://thishosting.rocks/support/ +[31]:https://thishosting.rocks/best-cheap-managed-vps/ +[32]:https://thishosting.rocks/best-cheap-managed-vps/ +[33]:https://minecraft.gamepedia.com/Minecraft_Wiki From 3410a3b6872a52deb17101d72033cf7eed59245e Mon Sep 17 00:00:00 2001 From: darksun Date: Tue, 30 Jan 2018 15:25:09 +0800 Subject: [PATCH 055/272] =?UTF-8?q?=E9=80=89=E9=A2=98:=20Linux=20kill=20Co?= =?UTF-8?q?mmand=20Tutorial=20for=20Beginners=20(5=20Examples)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...and Tutorial for Beginners (5 Examples).md | 113 ++++++++++++++++++ 1 file changed, 113 insertions(+) create mode 100644 sources/tech/20180126 Linux kill Command Tutorial for Beginners (5 Examples).md diff --git a/sources/tech/20180126 Linux kill Command Tutorial for Beginners (5 Examples).md b/sources/tech/20180126 Linux kill Command Tutorial for Beginners (5 Examples).md new file mode 100644 index 0000000000..8fcdedef0e --- /dev/null +++ b/sources/tech/20180126 Linux kill Command Tutorial for Beginners (5 Examples).md @@ -0,0 +1,113 @@ +Linux kill Command Tutorial for Beginners (5 Examples) +====== + +Sometimes, while working on a Linux machine, you'll see that an application or a command line process gets stuck (becomes unresponsive). Then in those cases, terminating it is the only way out. Linux command line offers a utility that you can use in these scenarios. It's called **kill**. + +In this tutorial, we will discuss the basics of kill using some easy to understand examples. But before we do that, it's worth mentioning that all examples in the article have been tested on an Ubuntu 16.04 machine. + +#### Linux kill command + +The kill command is usually used to kill a process. Internally it sends a signal, and depending on what you want to do, there are different signals that you can send using this tool. Following is the command's syntax: + +``` +kill [options] [...] +``` + +And here's how the tool's man page describes it: +``` +The default signal for kill is TERM. Use -l or -L to list available signals. Particularly useful +signals include HUP, INT, KILL, STOP, CONT, and 0. Alternate signals may be specified in three ways: +-9, -SIGKILL or -KILL. Negative PID values may be used to choose whole process groups; see the PGID +column in ps command output.  A PID of -1 is special; it indicates all processes except the kill +process  itself and init. +``` + +The following Q&A-styled examples should give you a better idea of how the kill command works. + +#### Q1. How to terminate a process using kill command? + +This is very easy - all you need to do is to get the pid of the process you want to kill, and then pass it to the kill command. + +``` +kill [pid] +``` + +For example, I wanted to kill the 'gthumb' process on my system. So i first used the ps command to fetch the application's pid, and then passed it to the kill command to terminate it. Here's the screenshot showing all this: + +[![How to terminate a process using kill command][1]][2] + +#### Q2. How to send a custom signal? + +As already mentioned in the introduction section, TERM is the default signal that kill sends to the application/process in question. However, if you want, you can send any other signal that kill supports using the **-s** command line option. + +``` +kill -s [signal] [pid] +``` + +For example, if a process isn't responding to the TERM signal (which allows the process to do final cleanup before quitting), you can go for the KILL signal (which doesn't let process do any cleanup). Following is the command you need to run in that case. + +``` +kill -s KILL [pid] +``` + +#### Q3. What all signals you can send using kill? + +Of course, the next logical question that'll come to your mind is how to know which all signals you can send using kill. Well, thankfully, there exists a command line option **-l** that lists all supported signals. + +``` +kill -l +``` + +Following is the output the above command produced on our system: + +[![What all signals you can send using kill][3]][4] + +#### Q4. What are the other ways in which signal can be sent? + +In one of the previous examples, we told you if you want to send the KILL signal, you can do it in the following way: + +``` +kill -s KILL [pid] +``` + +However, there are a couple of other alternatives as well: + +``` +kill -s SIGKILL [pid] + +kill -s 9 [pid] +``` + +The corresponding number can be known using the -l option we've already discussed in the previous example. + +#### Q5. How to kill all running process in one go? + +In case a user wants to kill all processes that they can (this depends on their privilege level), then instead of specifying a large number of process IDs, they can simply pass the -1 option to kill. + +For example: + +``` +kill -s KILL -1 +``` + +#### Conclusion + +The kill command is pretty straightforward to understand and use. There's a slight learning curve in terms of the list of signal options it offers, but as we explained in here, there's an option to take a quick look at that list as well. Just practice whatever we've discussed and you should be good to go. For more information, head to the tool's [man page][5]. + + +-------------------------------------------------------------------------------- + +via: https://www.howtoforge.com/linux-kill-command/ + +作者:[Himanshu Arora][a] +译者:[译者ID](https://github.com/译者ID) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://www.howtoforge.com +[1]:https://www.howtoforge.com/images/usage_of_pfsense_to_block_dos_attack_/kill-default.png +[2]:https://www.howtoforge.com/images/usage_of_pfsense_to_block_dos_attack_/big/kill-default.png +[3]:https://www.howtoforge.com/images/usage_of_pfsense_to_block_dos_attack_/kill-l-option.png +[4]:https://www.howtoforge.com/images/usage_of_pfsense_to_block_dos_attack_/big/kill-l-option.png +[5]:https://linux.die.net/man/1/kill From 62876e4a5b66d2c60aac3441665fad224ce17ad2 Mon Sep 17 00:00:00 2001 From: darksun Date: Tue, 30 Jan 2018 15:33:53 +0800 Subject: [PATCH 056/272] =?UTF-8?q?=E9=80=89=E9=A2=98:=20How=20to=20instal?= =?UTF-8?q?l=20KVM=20on=20CentOS=207=20/=20RHEL=207=20Headless=20Server?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...VM on CentOS 7 - RHEL 7 Headless Server.md | 342 ++++++++++++++++++ 1 file changed, 342 insertions(+) create mode 100644 sources/tech/20180127 How to install KVM on CentOS 7 - RHEL 7 Headless Server.md diff --git a/sources/tech/20180127 How to install KVM on CentOS 7 - RHEL 7 Headless Server.md b/sources/tech/20180127 How to install KVM on CentOS 7 - RHEL 7 Headless Server.md new file mode 100644 index 0000000000..6dce30d6dc --- /dev/null +++ b/sources/tech/20180127 How to install KVM on CentOS 7 - RHEL 7 Headless Server.md @@ -0,0 +1,342 @@ +How to install KVM on CentOS 7 / RHEL 7 Headless Server +====== + + +How do I install and configure KVM (Kernel-based Virtual Machine) on a CentOS 7 or RHEL (Red Hat Enterprise Linux) 7 server? How can I setup KMV on a CentOS 7 and use cloud images/cloud-init for installing guest VM? + + +Kernel-based Virtual Machine (KVM) is virtualization software for CentOS or RHEL 7. KVM turn your server into a hypervisor. This page shows how to setup and manage a virtualized environment with KVM in CentOS 7 or RHEL 7. It also described how to install and administer Virtual Machines (VMs) on a physical server using the CLI. Make sure that **Virtualization Technology (VT)** is enabled in your server 's BIOS. You can also run the following command [to test if CPU Support Intel VT and AMD-V Virtualization tech][1] +``` +$ lscpu | grep Virtualization +Virtualization: VT-x +``` + + + +### Follow installation steps of KVM on CentOS 7/RHEL 7 headless sever + +#### Step 1: Install kvm + +Type the following [yum command][2]: +`# yum install qemu-kvm libvirt libvirt-python libguestfs-tools virt-install` +[![How to install KVM on CentOS 7 RHEL 7 Headless Server][3]][3] +Start the libvirtd service: +``` +# systemctl enable libvirtd +# systemctl start libvirtd +``` + +#### Step 2: Verify kvm installation + +Make sure KVM module loaded using lsmod command and [grep command][4]: +`# lsmod | grep -i kvm` + +#### Step 3: Configure bridged networking + +By default dhcpd based network bridge configured by libvirtd. You can verify that with the following commands: +``` +# brctl show +# virsh net-list +``` +[![KVM default networking][5]][5] +All VMs (guest machine) only have network access to other VMs on the same server. A private network 192.168.122.0/24 created for you. Verify it: +`# virsh net-dumpxml default` +If you want your VMs avilable to other servers on your LAN, setup a a network bridge on the server that connected to the your LAN. Update your nic config file such as ifcfg-enp3s0 or em1: +`# vi /etc/sysconfig/network-scripts/enp3s0 ` +Add line: +``` +BRIDGE=br0 +``` + +[Save and close the file in vi][6]. Edit /etc/sysconfig/network-scripts/ifcfg-br0 and add: +`# vi /etc/sysconfig/network-scripts/ifcfg-br0` +Append the following: +``` +DEVICE="br0" +# I am getting ip from DHCP server # +BOOTPROTO="dhcp" +IPV6INIT="yes" +IPV6_AUTOCONF="yes" +ONBOOT="yes" +TYPE="Bridge" +DELAY="0" +``` + +Restart the networking service (warning ssh command will disconnect, it is better to reboot the box): +`# systemctl restart NetworkManager` +Verify it with brctl command: +`# brctl show` + +#### Step 4: Create your first virtual machine + +I am going to create a CentOS 7.x VM. First, grab CentOS 7.x latest ISO image using the wget command: +``` +# cd /var/lib/libvirt/boot/ +# wget https://mirrors.kernel.org/centos/7.4.1708/isos/x86_64/CentOS-7-x86_64-Minimal-1708.iso +``` +Verify ISO images: +``` +# wget https://mirrors.kernel.org/centos/7.4.1708/isos/x86_64/sha256sum.txt +# sha256sum -c sha256sum.txt +``` + +##### Create CentOS 7.x VM + +In this example, I'm creating CentOS 7.x VM with 2GB RAM, 2 CPU core, 1 nics and 40GB disk space, enter: +``` +# virt-install \ +--virt-type=kvm \ +--name centos7 \ +--ram 2048 \ +--vcpus=1 \ +--os-variant=centos7.0 \ +--cdrom=/var/lib/libvirt/boot/CentOS-7-x86_64-Minimal-1708.iso \ +--network=bridge=br0,model=virtio \ +--graphics vnc \ +--disk path=/var/lib/libvirt/images/centos7.qcow2,size=40,bus=virtio,format=qcow2 +``` +To configure vnc login from another terminal over ssh and type: +``` +# virsh dumpxml centos7 | grep vnc + +``` +Please note down the port value (i.e. 5901). You need to use an SSH client to setup tunnel and a VNC client to access the remote vnc server. Type the following SSH port forwarding command from your client/desktop/macbook pro system: +`$ ssh vivek@server1.cyberciti.biz -L 5901:127.0.0.1:5901` +Once you have ssh tunnel established, you can point your VNC client at your own 127.0.0.1 (localhost) address and port 5901 as follows: +[![][7]][7] +You should see CentOS Linux 7 guest installation screen as follows: +[![][8]][8] +Now just follow on screen instructions and install CentOS 7. Once installed, go ahead and click the reboot button. The remote server closed the connection to our VNC client. You can reconnect via KVM client to configure the rest of the server including SSH based session or firewall. + +#### Step 5: Using cloud images + +The above installation method is okay for learning purpose or a single VM. Do you need to deploy lots of VMs? Try cloud images. You can modify pre built cloud images as per your needs. For example, add users, ssh keys, setup time zone, and more using [Cloud-init][9] which is the defacto multi-distribution package that handles early initialization of a cloud instance. Let us see how to create CentOS 7 vm with 1024MB ram, 20GB disk space, and 1 vCPU. + +##### Grab CentOS 7 cloud image + +``` +# cd /var/lib/libvirt/boot +# wget http://cloud.centos.org/centos/7/images/CentOS-7-x86_64-GenericCloud.qcow2 +``` + +##### Create required directories + +``` +# D=/var/lib/libvirt/images +# VM=centos7-vm1 ## vm name ## +# mkdir -vp $D/$VM +mkdir: created directory '/var/lib/libvirt/images/centos7-vm1' +``` + +##### Create meta-data file + +``` +# cd $D/$VM +# vi meta-data +``` +Append the following: +``` +instance-id: centos7-vm1 +local-hostname: centos7-vm1 +``` + +##### Crete user-data file + +I am going to login into VM using ssh keys. So make sure you have ssh-keys in place: +`# ssh-keygen -t ed25519 -C "VM Login ssh key"` +[![ssh-keygen command][10]][11] +See "[How To Setup SSH Keys on a Linux / Unix System][12]" for more info. Edit user-data as follows: +``` +# cd $D/$VM +# vi user-data +``` +Add as follows (replace hostname, users, ssh-authorized-keys as per your setup): +``` +#cloud-config + +# Hostname management +preserve_hostname: False +hostname: centos7-vm1 +fqdn: centos7-vm1.nixcraft.com + +# Users +users: + - default + - name: vivek + groups: ['wheel'] + shell: /bin/bash + sudo: ALL=(ALL) NOPASSWD:ALL + ssh-authorized-keys: + - ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIMP3MOF2ot8MOdNXCpHem0e2Wemg4nNmL2Tio4Ik1JY VM Login ssh key + +# Configure where output will go +output: + all: ">> /var/log/cloud-init.log" + +# configure interaction with ssh server +ssh_genkeytypes: ['ed25519', 'rsa'] + +# Install my public ssh key to the first user-defined user configured +# in cloud.cfg in the template (which is centos for CentOS cloud images) +ssh_authorized_keys: + - ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIMP3MOF2ot8MOdNXCpHem0e2Wemg4nNmL2Tio4Ik1JY VM Login ssh key + +# set timezone for VM +timezone: Asia/Kolkata + +# Remove cloud-init +runcmd: + - systemctl stop network && systemctl start network + - yum -y remove cloud-init +``` + +##### Copy cloud image + +``` +# cd $D/$VM +# cp /var/lib/libvirt/boot/CentOS-7-x86_64-GenericCloud.qcow2 $VM.qcow2 +``` + +##### Create 20GB disk image + +``` +# cd $D/$VM +# export LIBGUESTFS_BACKEND=direct +# qemu-img create -f qcow2 -o preallocation=metadata $VM.new.image 20G +# virt-resize --quiet --expand /dev/sda1 $VM.qcow2 $VM.new.image +``` +[![Set VM image disk size][13]][13] +Overwrite it resized image: +``` +# cd $D/$VM +# mv $VM.new.image $VM.qcow2 +``` + +##### Creating a cloud-init ISO + +`# mkisofs -o $VM-cidata.iso -V cidata -J -r user-data meta-data` +[![Creating a cloud-init ISO][14]][14] + +##### Creating a pool + +``` +# virsh pool-create-as --name $VM --type dir --target $D/$VM +Pool centos7-vm1 created +``` + +##### Installing a CentOS 7 VM + +``` +# cd $D/$VM +# virt-install --import --name $VM \ +--memory 1024 --vcpus 1 --cpu host \ +--disk $VM.qcow2,format=qcow2,bus=virtio \ +--disk $VM-cidata.iso,device=cdrom \ +--network bridge=virbr0,model=virtio \ +--os-type=linux \ +--os-variant=centos7.0 \ +--graphics spice \ +--noautoconsole +``` +Delete unwanted files: +``` +# cd $D/$VM +# virsh change-media $VM hda --eject --config +# rm meta-data user-data centos7-vm1-cidata.iso +``` + +##### Find out IP address of VM + +`# virsh net-dhcp-leases default` +[![CentOS7-VM1- Created][15]][15] + +##### Log in to your VM + +Use ssh command: +`# ssh vivek@192.168.122.85` +[![Sample VM session][16]][16] + +### Useful commands + +Let us see some useful commands for managing VMs. + +#### List all VMs + +`# virsh list --all` + +#### Get VM info + +``` +# virsh dominfo vmName +# virsh dominfo centos7-vm1 +``` + +#### Stop/shutdown a VM + +`# virsh shutdown centos7-vm1` + +#### Start VM + +`# virsh start centos7-vm1` + +#### Mark VM for autostart at boot time + +`# virsh autostart centos7-vm1` + +#### Reboot (soft & safe reboot) VM + +`# virsh reboot centos7-vm1` +Reset (hard reset/not safe) VM +`# virsh reset centos7-vm1` + +#### Delete VM + +``` +# virsh shutdown centos7-vm1 +# virsh undefine centos7-vm1 +# virsh pool-destroy centos7-vm1 +# D=/var/lib/libvirt/images +# VM=centos7-vm1 +# rm -ri $D/$VM +``` +To see a complete list of virsh command type +``` +# virsh help | less +# virsh help | grep reboot +``` + + +### 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][17], [Facebook][18], [Google+][19]. + +-------------------------------------------------------------------------------- + +via: https://www.cyberciti.biz/faq/how-to-install-kvm-on-centos-7-rhel-7-headless-server/ + +作者:[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/linux-xen-vmware-kvm-intel-vt-amd-v-support/ +[2]:https://www.cyberciti.biz/faq/rhel-centos-fedora-linux-yum-command-howto/ (See Linux/Unix yum command examples for more info) +[3]:https://www.cyberciti.biz/media/new/faq/2018/01/How-to-install-KVM-on-CentOS-7-RHEL-7-Headless-Server.jpg +[4]:https://www.cyberciti.biz/faq/howto-use-grep-command-in-linux-unix/ (See Linux/Unix grep command examples for more info) +[5]:https://www.cyberciti.biz/media/new/faq/2018/01/KVM-default-networking.jpg +[6]:https://www.cyberciti.biz/faq/linux-unix-vim-save-and-quit-command/ +[7]:https://www.cyberciti.biz/media/new/faq/2016/01/vnc-client.jpg +[8]:https://www.cyberciti.biz/media/new/faq/2016/01/centos7-guest-vnc.jpg +[9]:https://cloudinit.readthedocs.io/en/latest/index.html +[10]:https://www.cyberciti.biz/media/new/faq/2018/01/ssh-keygen-pub-key.jpg +[11]:https://www.cyberciti.biz/faq/linux-unix-generating-ssh-keys/ +[12]:https://www.cyberciti.biz/faq/how-to-set-up-ssh-keys-on-linux-unix/ +[13]:https://www.cyberciti.biz/media/new/faq/2018/01/Set-VM-image-disk-size.jpg +[14]:https://www.cyberciti.biz/media/new/faq/2018/01/Creating-a-cloud-init-ISO.jpg +[15]:https://www.cyberciti.biz/media/new/faq/2018/01/CentOS7-VM1-Created.jpg +[16]:https://www.cyberciti.biz/media/new/faq/2018/01/Sample-VM-session.jpg +[17]:https://twitter.com/nixcraft +[18]:https://facebook.com/nixcraft +[19]:https://plus.google.com/+CybercitiBiz From def413ca4145e19d6c4ae73ee0134cd540ca9c9a Mon Sep 17 00:00:00 2001 From: darksun Date: Tue, 30 Jan 2018 17:30:58 +0800 Subject: [PATCH 057/272] =?UTF-8?q?=E9=80=89=E9=A2=98:=20How=20To=20Manage?= =?UTF-8?q?=20NodeJS=20Packages=20Using=20Npm?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...How To Manage NodeJS Packages Using Npm.md | 372 ++++++++++++++++++ 1 file changed, 372 insertions(+) create mode 100644 sources/tech/20180126 How To Manage NodeJS Packages Using Npm.md diff --git a/sources/tech/20180126 How To Manage NodeJS Packages Using Npm.md b/sources/tech/20180126 How To Manage NodeJS Packages Using Npm.md new file mode 100644 index 0000000000..ac27816a7b --- /dev/null +++ b/sources/tech/20180126 How To Manage NodeJS Packages Using Npm.md @@ -0,0 +1,372 @@ +How To Manage NodeJS Packages Using Npm +====== + +![](https://www.ostechnix.com/wp-content/uploads/2018/01/npm-720x340.png) + +A while ago, we have published a guide to [**manage Python packages using PIP**][1]. Today, we are going to discuss how to manage NodeJS packages using Npm. NPM is the largest software registry that contains over 600,000 packages. Everyday, developers across the world shares and downloads packages through npm. In this guide, I will explain the the basics of working with npm, such as installing packages(locally and globally), installing certain version of a package, updating, removing and managing NodeJS packages and so on. + +### Manage NodeJS Packages Using Npm + +##### Installing NPM + +Since npm is written in NodeJS, we need to install NodeJS in order to use npm. To install NodeJS on different Linux distributions, refer the following link. + +Once installed, ensure that NodeJS and NPM have been properly installed. There are couple ways to do this. + +To check where node has been installed: +``` +$ which node +/home/sk/.nvm/versions/node/v9.4.0/bin/node +``` + +Check its version: +``` +$ node -v +v9.4.0 +``` + +Log in to Node REPL session: +``` +$ node +> .help +.break Sometimes you get stuck, this gets you out +.clear Alias for .break +.editor Enter editor mode +.exit Exit the repl +.help Print this help message +.load Load JS from a file into the REPL session +.save Save all evaluated commands in this REPL session to a file +> .exit +``` + +Check where npm installed: +``` +$ which npm +/home/sk/.nvm/versions/node/v9.4.0/bin/npm +``` + +And the version: +``` +$ npm -v +5.6.0 +``` + +Great! Node and NPM have been installed and are working! As you may have noticed, I have installed NodeJS and NPM in my $HOME directory to avoid permission issues while installing modules globally. This is the recommended method by NodeJS team. + +Well, let us go ahead to see managing NodeJS modules (or packages) using npm. + +##### Installing NodeJS modules + +NodeJS modules can either be installed locally or globally(system wide). Now I am going to show how to install a package locally. + +**Install packages locally** + +To manage packages locally, we normally use **package.json** file. + +First, let us create our project directory. +``` +$ mkdir demo +``` +``` +$ cd demo +``` + +Create a package.json file inside your project's directory. To do so, run: +``` +$ npm init +``` + +Enter the details of your package such as name, version, author, github page etc., or just hit ENTER key to accept the default values and type **YES** to confirm. +``` +This utility will walk you through creating a package.json file. +It only covers the most common items, and tries to guess sensible defaults. + +See `npm help json` for definitive documentation on these fields +and exactly what they do. + +Use `npm install ` afterwards to install a package and +save it as a dependency in the package.json file. + +Press ^C at any time to quit. +package name: (demo) +version: (1.0.0) +description: demo nodejs app +entry point: (index.js) +test command: +git repository: +keywords: +author: +license: (ISC) +About to write to /home/sk/demo/package.json: + +{ + "name": "demo", + "version": "1.0.0", + "description": "demo nodejs app", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "", + "license": "ISC" +} + +Is this ok? (yes) yes +``` + +The above command initializes your project and create package.json file. + +You can also do this non-interactively using command: +``` +npm init --y +``` + +This will create a package.json file quickly with default values without the user interaction. + +Now let us install package named [**commander**][2]. +``` +$ npm install commander +``` + +Sample output: +``` +npm notice created a lockfile as package-lock.json. You should commit this file. +npm WARN demo@1.0.0 No repository field. + ++ commander@2.13.0 +added 1 package in 2.519s +``` + +This will create a directory named **" node_modules"** (if it doesn't exist already) in the project's root directory and download the packages in it. + +Let us check the package.json file. +``` +$ cat package.json +{ + "name": "demo", + "version": "1.0.0", + "description": "demo nodejs app", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "", + "license": "ISC", + **"dependencies": {** +**"commander": "^2.13.0"** + } +} +``` + +You will see the dependencies have been added. The caret ( **^** ) at the front of the version number indicates that when installing, npm will pull the highest version of the package it can find. +``` +$ ls node_modules/ +commander +``` + +The advantage of package.json file is if you had the package.json file in your project's directory, you can just type "npm install", then npm will look into the dependencies that listed in the file and download all of them. You can even share it with other developers or push into your GitHub repository, so when they type "npm install", they will get all the same packages that you have. + +You may also noticed another json file named **package-lock.json**. This file ensures that the dependencies remain the same on all systems the project is installed on. + +To use the installed package in your program, create a file **index.js** (or any name of you choice) in the project's directory with the actual code, and then run it using command: +``` +$ node index.js +``` + +**Install packages globally** + +If you want to use a package as a command line tool, then it is better to install it globally. This way, it works no matter which directory is your current directory. +``` +$ npm install async -g ++ async@2.6.0 +added 2 packages in 4.695s +``` + +Or, +``` +$ npm install async --global +``` + +To install a specific version of a package, we do: +``` +$ npm install async@2.6.0 --global +``` + +##### Updating NodeJS modules + +To update the local packages, go the the project's directory where the package.json is located and run: +``` +$ npm update +``` + +Then, run the following command to ensure all packages were updated. +``` +$ npm outdated +``` + +If there is no update, then it returns nothing. + +To find out which global packages need to be updated, run: +``` +$ npm outdated -g --depth=0 +``` + +If there is no output, then all packages are updated. + +To update the a single global package, run: +``` +$ npm update -g +``` + +To update all global packages, run: +``` +$ npm update -g +``` + +##### Listing NodeJS modules + +To list the local packages, go the project's directory and run: +``` +$ npm list +demo@1.0.0 /home/sk/demo +└── commander@2.13.0 +``` + +As you see, I have installed "commander" package in local mode. + +To list global packages, run this command from any location: +``` +$ npm list -g +``` + +Sample output: +``` +/home/sk/.nvm/versions/node/v9.4.0/lib +├─┬ async@2.6.0 +│ └── lodash@4.17.4 +└─┬ npm@5.6.0 + ├── abbrev@1.1.1 + ├── ansi-regex@3.0.0 + ├── ansicolors@0.3.2 + ├── ansistyles@0.1.3 + ├── aproba@1.2.0 + ├── archy@1.0.0 +[...] +``` + +This command will list all modules and their dependencies. + +To list only the top level modules, use -depth=0 option: +``` +$ npm list -g --depth=0 +/home/sk/.nvm/versions/node/v9.4.0/lib +├── async@2.6.0 +└── npm@5.6.0 +``` + +##### Searching NodeJS modules + +To search for a module, use "npm search" command: +``` +npm search +``` + +Example: +``` +$ npm search request +``` + +This command will display all modules that contains the search string "request". + +##### Removing NodeJS modules + +To remove a local package, go to the project's directory and run following command to remove the package from your **node_modules** directory: +``` +$ npm uninstall +``` + +To remove it from the dependencies in **package.json** file, use the **save** flag like below: +``` +$ npm uninstall --save + +``` + +To remove the globally installed packages, run: +``` +$ npm uninstall -g +``` + +##### Cleaning NPM cache + +By default, NPM keeps the copy of a installed package in the cache folder named npm in your $HOME directory when installing it. So, you can install it next time without having to download again. + +To view the cached modules: +``` +$ ls ~/.npm +``` + +The cache folder gets flooded with all old packages over time. It is better to clean the cache from time to time. + +As of npm@5, the npm cache self-heals from corruption issues and data extracted from the cache is guaranteed to be valid. If you want to make sure everything is consistent, run: +``` +$ npm cache verify +``` + +To clear the entire cache, run: +``` +$ npm cache clean --force +``` + +##### Viewing NPM configuration + +To view the npm configuration, type: +``` +$ npm config list +``` + +Or, +``` +$ npm config ls +``` + +Sample output: +``` +; cli configs +metrics-registry = "https://registry.npmjs.org/" +scope = "" +user-agent = "npm/5.6.0 node/v9.4.0 linux x64" + +; node bin location = /home/sk/.nvm/versions/node/v9.4.0/bin/node +; cwd = /home/sk +; HOME = /home/sk +; "npm config ls -l" to show all defaults. +``` + +To display the current global location: +``` +$ npm config get prefix +/home/sk/.nvm/versions/node/v9.4.0 +``` + +And, that's all for now. What we have just covered here is just the basics. NPM is a vast topic. For more details, head over to the the [**NPM Getting Started**][3] guide. + +Hope this was useful. More good stuffs to come. Stay tuned! + +Cheers! + + + +-------------------------------------------------------------------------------- + +via: https://www.ostechnix.com/manage-nodejs-packages-using-npm/ + +作者:[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/ +[1]:https://www.ostechnix.com/manage-python-packages-using-pip/ +[2]:https://www.npmjs.com/package/commander +[3]:https://docs.npmjs.com/getting-started/ From b45715f7243f62cdf49ad37f23ac9a2620601413 Mon Sep 17 00:00:00 2001 From: darksun Date: Tue, 30 Jan 2018 17:44:46 +0800 Subject: [PATCH 058/272] =?UTF-8?q?=E9=80=89=E9=A2=98:=20Creating=20an=20A?= =?UTF-8?q?dventure=20Game=20in=20the=20Terminal=20with=20ncurses?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...nture Game in the Terminal with ncurses.md | 324 ++++++++++++++++++ 1 file changed, 324 insertions(+) create mode 100644 sources/tech/20180126 Creating an Adventure Game in the Terminal with ncurses.md diff --git a/sources/tech/20180126 Creating an Adventure Game in the Terminal with ncurses.md b/sources/tech/20180126 Creating an Adventure Game in the Terminal with ncurses.md new file mode 100644 index 0000000000..221c53a4ed --- /dev/null +++ b/sources/tech/20180126 Creating an Adventure Game in the Terminal with ncurses.md @@ -0,0 +1,324 @@ +Creating an Adventure Game in the Terminal with ncurses +====== +How to use curses functions to read the keyboard and manipulate the screen. + +My [previous article][1] introduced the ncurses library and provided a simple program that demonstrated a few curses functions to put text on the screen. In this follow-up article, I illustrate how to use a few other curses functions. + +### An Adventure + +When I was growing up, my family had an Apple II computer. It was on this machine that my brother and I taught ourselves how to write programs in AppleSoft BASIC. After writing a few math puzzles, I moved on to creating games. Having grown up in the 1980s, I already was a fan of the Dungeons and Dragons tabletop games, where you role-played as a fighter or wizard on some quest to defeat monsters and plunder loot in strange lands. So it shouldn't be surprising that I also created a rudimentary adventure game. + +The AppleSoft BASIC programming environment supported a neat feature: in standard resolution graphics mode (GR mode), you could probe the color of a particular pixel on the screen. This allowed a shortcut to create an adventure game. Rather than create and update an in-memory map that was transferred to the screen periodically, I could rely on GR mode to maintain the map for me, and my program could query the screen as the player's character moved around the screen. Using this method, I let the computer do most of the hard work. Thus, my top-down adventure game used blocky GR mode graphics to represent my game map. + +My adventure game used a simple map that represented a large field with a mountain range running down the middle and a large lake on the upper-left side. I might crudely draw this map for a tabletop gaming campaign to include a narrow path through the mountains, allowing the player to pass to the far side. + +![](http://www.linuxjournal.com/files/linuxjournal.com/ufiles/imagecache/large-550px-centered/u1000009/quest-map.jpg) + +Figure 1. A simple Tabletop Game Map with a Lake and Mountains + +You can draw this map in cursesusing characters to represent grass, mountains and water. Next, I describe how to do just that using curses functions and how to create and play a similar adventure game in the Linux terminal. + +### Constructing the Program + +In my last article, I mentioned that most curses programs start with the same set of instructions to determine the terminal type and set up the curses environment: + +``` +initscr(); +cbreak(); +noecho(); + +``` + +For this program, I add another statement: + +``` +keypad(stdscr, TRUE); + +``` + +The TRUE flag allows curses to read the keypad and function keys from the user's terminal. If you want to use the up, down, left and right arrow keys in your program, you need to use keypad(stdscr, TRUE) here. + +Having done that, you now can start drawing to the terminal screen. The curses functions include several ways to draw text on the screen. In my previous article, I demonstrated the addch() and addstr() functions and their associated mvaddch() and mvaddstr() counterparts that first moved to a specific location on the screen before adding text. To create the adventure game map on the terminal, you can use another set of functions: vline() and hline(), and their partner functions mvvline() and mvhline(). These mv functions accept screen coordinates, a character to draw and how many times to repeat that character. For example, mvhline(1, 2, '-', 20) will draw a line of 20 dashes starting at line 1, column 2. + +To draw the map to the terminal screen programmatically, let's define this draw_map() function: + +``` +#define GRASS ' ' +#define EMPTY '.' +#define WATER '~' +#define MOUNTAIN '^' +#define PLAYER '*' + +void draw_map(void) +{ + int y, x; + + /* draw the quest map */ + + /* background */ + + for (y = 0; y < LINES; y++) { + mvhline(y, 0, GRASS, COLS); + } + + /* mountains, and mountain path */ + + for (x = COLS / 2; x < COLS * 3 / 4; x++) { + mvvline(0, x, MOUNTAIN, LINES); + } + + mvhline(LINES / 4, 0, GRASS, COLS); + + /* lake */ + + for (y = 1; y < LINES / 2; y++) { + mvhline(y, 1, WATER, COLS / 3); + } +} + +``` + +In drawing this map, note the use of mvvline() and mvhline() to fill large chunks of characters on the screen. I created the fields of grass by drawing horizontal lines (mvhline) of characters starting at column 0, for the entire height and width of the screen. I added the mountains on top of that by drawing vertical lines (mvvline), starting at row 0, and a mountain path by drawing a single horizontal line (mvhline). And, I created the lake by drawing a series of short horizontal lines (mvhline). It may seem inefficient to draw overlapping rectangles in this way, but remember that curses doesn't actually update the screen until I call the refresh() function later. + +Having drawn the map, all that remains to create the game is to enter a loop where the program waits for the user to press one of the up, down, left or right direction keys and then moves a player icon appropriately. If the space the player wants to move into is unoccupied, it allows the player to go there. + +You can use curses as a shortcut. Rather than having to instantiate a version of the map in the program and replicate this map to the screen, you can let the screen keep track of everything for you. The inch() function, and associated mvinch() function, allow you to probe the contents of the screen. This allows you to query curses to find out whether the space the player wants to move into is already filled with water or blocked by mountains. To do this, you'll need a helper function that you'll use later: + +``` +int is_move_okay(int y, int x) +{ + int testch; + + /* return true if the space is okay to move into */ + + testch = mvinch(y, x); + return ((testch == GRASS) || (testch == EMPTY)); +} + +``` + +As you can see, this function probes the location at column y, row x and returns true if the space is suitably unoccupied, or false if not. + +That makes it really easy to write a navigation loop: get a key from the keyboard and move the user's character around depending on the up, down, left and right arrow keys. Here's a simplified version of that loop: + +``` + + do { + ch = getch(); + + /* test inputted key and determine direction */ + + switch (ch) { + case KEY_UP: + if ((y > 0) && is_move_okay(y - 1, x)) { + y = y - 1; + } + break; + case KEY_DOWN: + if ((y < LINES - 1) && is_move_okay(y + 1, x)) { + y = y + 1; + } + break; + case KEY_LEFT: + if ((x > 0) && is_move_okay(y, x - 1)) { + x = x - 1; + } + break; + case KEY_RIGHT + if ((x < COLS - 1) && is_move_okay(y, x + 1)) { + x = x + 1; + } + break; + } + } + while (1); + +``` + +To use this in a game, you'll need to add some code inside the loop to allow other keys (for example, the traditional WASD movement keys), provide a method for the user to quit the game and move the player's character around the screen. Here's the program in full: + +``` + +/* quest.c */ + +#include +#include + +#define GRASS ' ' +#define EMPTY '.' +#define WATER '~' +#define MOUNTAIN '^' +#define PLAYER '*' + +int is_move_okay(int y, int x); +void draw_map(void); + +int main(void) +{ + int y, x; + int ch; + + /* initialize curses */ + + initscr(); + keypad(stdscr, TRUE); + cbreak(); + noecho(); + + clear(); + + /* initialize the quest map */ + + draw_map(); + + /* start player at lower-left */ + + y = LINES - 1; + x = 0; + + do { + /* by default, you get a blinking cursor - use it to indicate player */ + + mvaddch(y, x, PLAYER); + move(y, x); + refresh(); + + ch = getch(); + + /* test inputted key and determine direction */ + + switch (ch) { + case KEY_UP: + case 'w': + case 'W': + if ((y > 0) && is_move_okay(y - 1, x)) { + mvaddch(y, x, EMPTY); + y = y - 1; + } + break; + case KEY_DOWN: + case 's': + case 'S': + if ((y < LINES - 1) && is_move_okay(y + 1, x)) { + mvaddch(y, x, EMPTY); + y = y + 1; + } + break; + case KEY_LEFT: + case 'a': + case 'A': + if ((x > 0) && is_move_okay(y, x - 1)) { + mvaddch(y, x, EMPTY); + x = x - 1; + } + break; + case KEY_RIGHT: + case 'd': + case 'D': + if ((x < COLS - 1) && is_move_okay(y, x + 1)) { + mvaddch(y, x, EMPTY); + x = x + 1; + } + break; + } + } + while ((ch != 'q') && (ch != 'Q')); + + endwin(); + + exit(0); +} + +int is_move_okay(int y, int x) +{ + int testch; + + /* return true if the space is okay to move into */ + + testch = mvinch(y, x); + return ((testch == GRASS) || (testch == EMPTY)); +} + +void draw_map(void) +{ + int y, x; + + /* draw the quest map */ + + /* background */ + + for (y = 0; y < LINES; y++) { + mvhline(y, 0, GRASS, COLS); + } + + /* mountains, and mountain path */ + + for (x = COLS / 2; x < COLS * 3 / 4; x++) { + mvvline(0, x, MOUNTAIN, LINES); + } + + mvhline(LINES / 4, 0, GRASS, COLS); + + /* lake */ + + for (y = 1; y < LINES / 2; y++) { + mvhline(y, 1, WATER, COLS / 3); + } +} + +``` + +In the full program listing, you can see the complete arrangement of curses functions to create the game: + +1) Initialize the curses environment. + +2) Draw the map. + +3) Initialize the player coordinates (lower-left). + +4) Loop: + +* Draw the player's character. + +* Get a key from the keyboard. + +* Adjust the player's coordinates up, down, left or right, accordingly. + +* Repeat. + +5) When done, close the curses environment and exit. + +### Let's Play + +When you run the game, the player's character starts in the lower-left corner. As the player moves around the play area, the program creates a "trail" of dots. This helps show where the player has been before, so the player can avoid crossing the path unnecessarily. + +![](http://www.linuxjournal.com/files/linuxjournal.com/ufiles/imagecache/large-550px-centered/u1000009/quest-start.png) + +Figure 2\. The player starts the game in the lower-left corner. + +![](http://www.linuxjournal.com/files/linuxjournal.com/ufiles/imagecache/large-550px-centered/u1000009/quest-1.png) + +Figure 3\. The player can move around the play area, such as around the lake and through the mountain pass. + +To create a complete adventure game on top of this, you might add random encounters with various monsters as the player navigates his or her character around the play area. You also could include special items the player could discover or loot after defeating enemies, which would enhance the player's abilities further. + +But to start, this is a good program for demonstrating how to use the curses functions to read the keyboard and manipulate the screen. + +### Next Steps + +This program is a simple example of how to use the curses functions to update and read the screen and keyboard. You can do so much more with curses, depending on what you need your program to do. In a follow up article, I plan to show how to update this sample program to use colors. In the meantime, if you are interested in learning more about curses, I encourage you to read Pradeep Padala's [NCURSES Programming HOWTO][2] at the Linux Documentation Project. + + +-------------------------------------------------------------------------------- + +via: http://www.linuxjournal.com/content/creating-adventure-game-terminal-ncurses + +作者:[Jim Hall][a] +译者:[译者ID](https://github.com/译者ID) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:http://www.linuxjournal.com/users/jim-hall +[1]:http://www.linuxjournal.com/content/getting-started-ncurses +[2]:http://tldp.org/HOWTO/NCURSES-Programming-HOWTO From 987996d768f7676afb597017aa60c497a46e4951 Mon Sep 17 00:00:00 2001 From: Yinr Date: Tue, 30 Jan 2018 18:00:48 +0800 Subject: [PATCH 059/272] translation finished --- ...1 Multimedia Apps for the Linux Console.md | 31 +++++++++++++------ 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/sources/tech/20180111 Multimedia Apps for the Linux Console.md b/sources/tech/20180111 Multimedia Apps for the Linux Console.md index 15dc5f2979..06bb363d0f 100644 --- a/sources/tech/20180111 Multimedia Apps for the Linux Console.md +++ b/sources/tech/20180111 Multimedia Apps for the Linux Console.md @@ -21,7 +21,6 @@ You're probably familiar with the amazing and versatile MPlayer, which supports ``` $ mplayer [视频文件名] - ``` If it works, then hurrah, and you can invest your time in learning useful MPlayer options, such as controlling the size of the video screen. However, some Linux distributions are managing the framebuffer differently than in the olden days, and you may have to adjust some settings to make it work. This is how to make it work on recent Ubuntu releases. @@ -44,7 +43,6 @@ $ sudo nano /etc/initramfs-tools/modules vesafb $ sudo update-initramfs -u - ``` [fbcon][1] is the Linux framebuffer console. It runs on top of the framebuffer and adds graphical features. It requires a framebuffer device, which is supplied by the `vesafb` module. @@ -55,7 +53,6 @@ Now you must edit your GRUB2 configuration. In `/etc/default/grub` you should se ``` GRUB_CMDLINE_LINUX_DEFAULT="quiet splash" - ``` It may have some other options, but it should be there. Add `vga=789`: @@ -63,7 +60,6 @@ It may have some other options, but it should be there. Add `vga=789`: ``` GRUB_CMDLINE_LINUX_DEFAULT="quiet splash vga=789" - ``` Reboot and enter your console (Ctrl+Alt+F1), and try playing a video. This command selects the `fbdev2` video device; I haven't learned yet how to know which one to use, but I had to use it to play the video. The default screen size is 320x240, so I scaled it to 960: @@ -74,7 +70,9 @@ $ mplayer -vo fbdev2 -vf scale -zoom -xy 960 AlienSong_mp4.mov ``` And behold Figure 1. It's grainy because I have a low-fi copy of this video, not because MPlayer is making it grainy. -来看图1。粗糙的画面是由于我原视频的质量不高,而不是 MPlayer 的显示问题。 +来看图 1。粗糙的画面是由于我原视频的质量不高,而不是 MPlayer 的显示问题。 + +![图 1 播放视频](https://www.linux.com/sites/lcom/files/styles/floated_images/public/fig-1_3.jpg?itok=PtSoKepn) MPLayer plays CDs, DVDs, network streams, and has a giant batch of playback options, which I shall leave as your homework to explore. MPlayer 可以播放 CD、DVD 以及网络视频流,并且还有一系列的回放选项,这些将作为作业让大家自己去发现。 @@ -83,38 +81,51 @@ MPlayer 可以播放 CD、DVD 以及网络视频流,并且还有一系列的 ### fbi 图片查看器 `fbi`, the framebuffer image viewer, comes in the [fbida][2] package on most Linuxes. It has native support for the common image file formats, and uses `convert` (from Image Magick), if it is installed, for other formats. Its simplest use is to view a single image file: -``` -$ fbi filename +`fbi` 是一个帧缓冲图片查看器。在大部分的 Linux 发行版中都,它被包含在 [fbida][2] 包中。它原生支持一些常见的图片格式,而如果你安装了 `convert`(来自于 Image Magick),那么它还能借此打开一些其他格式。最简单的用法是用来查看一个图片文件: +``` +$ fbi 文件名 ``` Use the arrow keys to scroll a large image, + and - to zoom, and r and l to rotate 90 degress right and left. Press the Escape key to close the image. You can play a slideshow by giving `fbi` a list of files: -``` -$ fbi --list file-list.txt +你可以使用方向键来在大图片中移动视野,使用 + 和 - 来缩放,或者使用 r 或 l 来向右或向左旋转 90 度。Escape 键则可以关闭查看的图片。此外,你还可以给 `fbi` 一个文件列表来实现幻灯播放: +``` +$ fbi --list 文件列表.txt ``` `fbi` supports autozoom. With `-a` `fbi` controls the zoom factor. `--autoup` and `--autodown` tell `fbi` to only zoom up or down. Control the blend time between images with `--blend [time]`, in milliseconds. Press the k and j keys to jump behind and ahead in your file list. +`fbi` 还支持自动缩放。还可以使用 `-a` 选项来控制缩放比例。`--autoup` 和 `--autodown` 则是用于告知 `fbi` 只进行放大或者缩小。要调整图片切换时淡入淡出的时间则可以使用 `--blend [时间]` 来指定一个毫秒为单位的时间长度。使用 k 和 j 键则可以切换文件列表中的上一张或下一张图片。 `fbi` has commands for creating file lists from images you have viewed, and for exporting your commands to a file, and a host of other cool options. Check out `man fbi` for complete options. +`fbi` 还提供了命令来为你浏览过的文件创建文件列表,或者将你的命令导出到文件中,以及一系列其它很棒的选项。你可以通过查看 `man fbi` 来查阅完整的选项列表。 ### CMatrix Console Screensaver +### CMatrix 终端屏保 The Matrix screensaver is still my favorite (Figure 2), second only to the bouncing cow. [CMatrix][3] runs on the console. Simply type `cmatrix` to start it, and Ctrl+C stops it. Run `cmatrix -s` to launch it in screensaver mode, which exits on any keypress. `-C` changes the color. Your choices are green, red, blue, yellow, white, magenta, cyan, and black. +黑客帝国(The Matrix)屏保仍然是我非常喜欢的屏保(图 2),仅次于弹跳牛(bouncing cow)。[CMatrix][3] 可以在终端运行。要运行它只需输入 `cmatrix`,然后可以用 Ctrl+C 来停止运行。执行 `cmatrix -s` 则启动屏保模式,这样的话按任意键都能退出屏保。`-C` 参数可以设定颜色,譬如绿色(green)、红色(red)、蓝色(blue)、黄色(yellow)、白色(white)、紫色(magenta)、青色(cyan)或者黑色(black)。 + +![图 2 黑客帝国屏保](https://www.linux.com/sites/lcom/files/styles/floated_images/public/fig-2_0.jpg?itok=E3f26R7w) CMatrix supports asynchronous key presses, which means you can change options while it's running. +CMatrix 还支持异步按键,这意味着你可以在它运行的时候改变设置选项。 `-B` is all bold text, and `-B` is partially bold. +`-B` 设置全部使用粗体,而 `-b`(LCTT 译注:原文误为 `-B`)则可以设置部分字体加粗。 ### fbgs PDF Viewer +### fbgs PDF 阅读器 It seems that the addiction to PDF documents is pandemic and incurable, though PDFs are better than they used to be, with live hyperlinks, copy-paste, and good text search. The `fbgs` console PDF viewer is part of the `fbida` package. Options include page size, resolution, page selections, and most `fbi` options, with the exceptions listed in `man fbgs`. The main option I use is page size; you get `-l`, `xl`, and `xxl` to choose from: +看起来,对 PDF 文档的上瘾是普遍而无法阻止的,尽管 PDF 比它之前好了很多,譬如实时超链接、复制粘贴以及更好的文本搜索功能等。`fbgs` 是 `fbida` 包中提供的一个 PDF 阅读器。它可以设置页面大小、分辨率、指定页码以及绝大部分 `fbi` 提供的选项,当然除了一些在 `man fbgs` 中列举出来的不可用选项之外。我主要用到的选项是页面大小,你可以选择 `-l`、`xl` 或者 `xxl`: + ``` $ fbgs -xl annoyingpdf.pdf - ``` Learn more about Linux through the free ["Introduction to Linux" ][4]course from The Linux Foundation and edX. +欢迎通过 Linux 基金会与 edX 免费提供的[“Linux 入门”][4]课程学习更多 Linux 知识。 -------------------------------------------------------------------------------- From 4c0f2a54774e2083bf994f9e62518d47a92f30c5 Mon Sep 17 00:00:00 2001 From: Yinr Date: Tue, 30 Jan 2018 19:18:32 +0800 Subject: [PATCH 060/272] modify translation --- ...1 Multimedia Apps for the Linux Console.md | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/sources/tech/20180111 Multimedia Apps for the Linux Console.md b/sources/tech/20180111 Multimedia Apps for the Linux Console.md index 06bb363d0f..def5412ab4 100644 --- a/sources/tech/20180111 Multimedia Apps for the Linux Console.md +++ b/sources/tech/20180111 Multimedia Apps for the Linux Console.md @@ -6,34 +6,34 @@ Linux 终端下的多媒体应用 ![](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/multimedia.jpg?itok=v-XrnKRB) The Linux console supports multimedia, so you can enjoy music, movies, photos, and even read PDF files. -Linux 终端是支持多媒体的,所以你可以在终端听音乐,看电影,看图片,甚至是阅读 PDF。 +Linux 终端是支持多媒体的,所以你可以在终端里听音乐,看电影,看图片,甚至是阅读 PDF。 When last we met, we learned that the Linux console supports multimedia. Yes, really! You can enjoy music, movies, photos, and even read PDF files without being in an X session with MPlayer, fbi, and fbgs. And, as a bonus, you can enjoy a Matrix-style screensaver for the console, CMatrix. -在我们上次见面时(?),我们了解到 Linux 终端可以支持多媒体。是的,这是真的!你可以使用 Mplayer、fbi 和 fbgs 来实现不打开 X 进程就听音乐、看电影、看照片,甚至阅读 PDF。此外,你还可以通过 CMatrix 来体验黑客帝国(Matrix)风格的屏幕保护。 +在我的上一篇文章里,我们了解到 Linux 终端是可以支持多媒体的。是的,这是真的!你可以使用 Mplayer、fbi 和 fbgs 来实现不打开 X 进程就听音乐、看电影、看照片,甚至阅读 PDF。此外,你还可以通过 CMatrix 来体验黑客帝国(Matrix)风格的屏幕保护。 You will probably have make some tweaks to your system to make this work. The examples used here are for Ubuntu Linux 16.04. -不过你可能需要对系统进行一些修改才能达到前面这些目的。以下的操作都是在 Ubuntu 16.04 上演示的。 +不过你可能需要对系统进行一些修改才能达到前面这些目的。下文的操作都是在 Ubuntu 16.04 上进行的。 ### MPlayer You're probably familiar with the amazing and versatile MPlayer, which supports almost every video and audio format, and runs on nearly everything, including Linux, Android, Windows, Mac, Kindle, OS/2, and AmigaOS. Using MPLayer in your console will probably require some tweaking, depending on your Linux distribution. To start, try playing a video: -你可能会比较熟悉功能丰富的 MPlayer。它支持几乎所有的视频与音频格式,并且能在绝大部分现有平台上运行,像 Linux,Android,Windows,Mac,Kindle,OS/2 甚至是 AmigaOS。不过要在你的终端运行 MPlayer 可能需要多做一点工作,这些工作与你使用的 Linux 发行版有关。来,我们试着播放一个视频: +你可能会比较熟悉功能丰富的 MPlayer。它支持几乎所有格式的视频与音频,并且能在绝大部分现有的平台上运行,像 Linux,Android,Windows,Mac,Kindle,OS/2 甚至是 AmigaOS。不过,要在你的终端运行 MPlayer 可能需要多做一点工作,这些工作与你使用的 Linux 发行版有关。来,我们先试着播放一个视频: ``` $ mplayer [视频文件名] ``` If it works, then hurrah, and you can invest your time in learning useful MPlayer options, such as controlling the size of the video screen. However, some Linux distributions are managing the framebuffer differently than in the olden days, and you may have to adjust some settings to make it work. This is how to make it work on recent Ubuntu releases. -如果上面的命令正常执行了,那么很好,接下来你可以把时间放在了解 MPlayer 的常用选项上了,譬如设定视频大小等。但是,有些 Linux 发行版在对帧缓冲(framebuffer)的处理方式上可能会与早期的不同,那么你就需要进行一些设置才能让其正常工作了。下面是在最近的 Ubuntu 发行版上需要做的一些操作。 +如果上面的命令正常执行了,那么很好,接下来你可以把时间放在了解 MPlayer 的常用选项上了,譬如设定视频大小等。但是,有些 Linux 发行版在对帧缓冲(framebuffer)的处理方式上与早期的不同,那么你就需要进行一些额外的设置才能让其正常工作了。下面是在最近的 Ubuntu 发行版上需要做的一些操作。 First, add yourself to the video group. -首先,将你添加到 video 用户组。 +首先,将你自己添加到 video 用户组。 Second, verify that `/etc/modprobe.d/blacklist-framebuffer.conf` has this line: `#blacklist vesafb`. It should already be commented out, and if it isn't then comment it. All the other module lines should be un-commented, which prevents them from loading. Side note: if you want to dig more deeply into managing your framebuffer, the module for your video card may give better performance. -其次,确认 `/etc/modprobe.d/blacklist-framebuffer.conf` 文件中包含这样一行:`#blacklist vesafb`。这一行应该默认被注释掉了,如果不是的话,那就手动把它注释掉。此外的其他模块行需要确认没有被注释,这样设置才能保证那些模块不会被载入。注:如果你想要对控制帧缓冲(framebuffer)有更深入的了解,针对你的显卡的这些模块将给你提供更深入的认识。 +其次,确认 `/etc/modprobe.d/blacklist-framebuffer.conf` 文件中包含这样一行:`#blacklist vesafb`。这一行应该默认被注释掉了,如果不是的话,那就手动把它注释掉。此外的其他模块行需要确认没有被注释,这样设置才能保证其他那些模块不会被载入。注:如果你想要对控制帧缓冲(framebuffer)有更深入的了解,可以从针对你的显卡的这些模块里获取更深入的认识。 Add these two modules to the end of `/etc/initramfs-tools/modules`, `vesafb` and `fbcon`, then rebuild the initramfs image: -在 `/etc/initramfs-tools/modules` 的结尾增加两个模块:`vesafb` 和 `fbcon`,然后更新 iniramfs 镜像: +然后,在 `/etc/initramfs-tools/modules` 的结尾增加两个模块:`vesafb` 和 `fbcon`,并且更新 iniramfs 镜像: ``` $ sudo nano /etc/initramfs-tools/modules @@ -46,7 +46,7 @@ $ sudo update-initramfs -u ``` [fbcon][1] is the Linux framebuffer console. It runs on top of the framebuffer and adds graphical features. It requires a framebuffer device, which is supplied by the `vesafb` module. -[fbcon][1] 是 Linux 帧缓冲(framebuffer)终端,它运行在帧缓冲(framebuffer)之上并为其增加图形功能。[fbcon][1] 需要一个帧缓冲(framebuffer)设备,这则是由 `vesafb` 模块来提供的。 +[fbcon][1] 是 Linux 帧缓冲(framebuffer)终端,它运行在帧缓冲(framebuffer)之上并为其增加图形功能。而它需要一个帧缓冲(framebuffer)设备,这则是由 `vesafb` 模块来提供的。 Now you must edit your GRUB2 configuration. In `/etc/default/grub` you should see a line like this: 接下来,你需要修改你的 GRUB2 配置。在 `/etc/default/grub` 中你将会看到类似下面的一行: @@ -75,13 +75,13 @@ And behold Figure 1. It's grainy because I have a low-fi copy of this video, not ![图 1 播放视频](https://www.linux.com/sites/lcom/files/styles/floated_images/public/fig-1_3.jpg?itok=PtSoKepn) MPLayer plays CDs, DVDs, network streams, and has a giant batch of playback options, which I shall leave as your homework to explore. -MPlayer 可以播放 CD、DVD 以及网络视频流,并且还有一系列的回放选项,这些将作为作业让大家自己去发现。 +MPlayer 可以播放 CD、DVD 以及网络视频流,并且还有一系列的回放选项,这些将作为作业留给大家自己去发现。 ### fbi Image Viewer ### fbi 图片查看器 `fbi`, the framebuffer image viewer, comes in the [fbida][2] package on most Linuxes. It has native support for the common image file formats, and uses `convert` (from Image Magick), if it is installed, for other formats. Its simplest use is to view a single image file: -`fbi` 是一个帧缓冲图片查看器。在大部分的 Linux 发行版中都,它被包含在 [fbida][2] 包中。它原生支持一些常见的图片格式,而如果你安装了 `convert`(来自于 Image Magick),那么它还能借此打开一些其他格式。最简单的用法是用来查看一个图片文件: +`fbi` 是一个帧缓冲图片查看器。在大部分的 Linux 发行版中,它被包含在 [fbida][2] 包里。它原生支持一些常见的图片格式,而如果你安装了 `convert`(来自于 Image Magick),那么它还能借此打开一些其他格式。最简单的用法是用来查看一个图片文件: ``` $ fbi 文件名 @@ -95,16 +95,16 @@ $ fbi --list 文件列表.txt ``` `fbi` supports autozoom. With `-a` `fbi` controls the zoom factor. `--autoup` and `--autodown` tell `fbi` to only zoom up or down. Control the blend time between images with `--blend [time]`, in milliseconds. Press the k and j keys to jump behind and ahead in your file list. -`fbi` 还支持自动缩放。还可以使用 `-a` 选项来控制缩放比例。`--autoup` 和 `--autodown` 则是用于告知 `fbi` 只进行放大或者缩小。要调整图片切换时淡入淡出的时间则可以使用 `--blend [时间]` 来指定一个毫秒为单位的时间长度。使用 k 和 j 键则可以切换文件列表中的上一张或下一张图片。 +`fbi` 还支持自动缩放。还可以使用 `-a` 选项来控制缩放比例。`--autoup` 和 `--autodown` 则是用于告知 `fbi` 只进行放大或者缩小。要调整图片切换时淡入淡出的时间则可以使用 `--blend [时间]` 来指定一个以毫秒为单位的时间长度。使用 k 和 j 键则可以切换文件列表中的上一张或下一张图片。 `fbi` has commands for creating file lists from images you have viewed, and for exporting your commands to a file, and a host of other cool options. Check out `man fbi` for complete options. -`fbi` 还提供了命令来为你浏览过的文件创建文件列表,或者将你的命令导出到文件中,以及一系列其它很棒的选项。你可以通过查看 `man fbi` 来查阅完整的选项列表。 +`fbi` 还提供了命令来为你浏览过的文件创建文件列表,或者将你的命令导出到文件中,以及一系列其它很棒的选项。你可以通过 `man fbi` 来查阅完整的选项列表。 ### CMatrix Console Screensaver ### CMatrix 终端屏保 The Matrix screensaver is still my favorite (Figure 2), second only to the bouncing cow. [CMatrix][3] runs on the console. Simply type `cmatrix` to start it, and Ctrl+C stops it. Run `cmatrix -s` to launch it in screensaver mode, which exits on any keypress. `-C` changes the color. Your choices are green, red, blue, yellow, white, magenta, cyan, and black. -黑客帝国(The Matrix)屏保仍然是我非常喜欢的屏保(图 2),仅次于弹跳牛(bouncing cow)。[CMatrix][3] 可以在终端运行。要运行它只需输入 `cmatrix`,然后可以用 Ctrl+C 来停止运行。执行 `cmatrix -s` 则启动屏保模式,这样的话按任意键都能退出屏保。`-C` 参数可以设定颜色,譬如绿色(green)、红色(red)、蓝色(blue)、黄色(yellow)、白色(white)、紫色(magenta)、青色(cyan)或者黑色(black)。 +黑客帝国(The Matrix)屏保仍然是我非常喜欢的屏保之一(如图 2),仅次于弹跳牛(bouncing cow)。[CMatrix][3] 可以在终端运行。要运行它只需输入 `cmatrix`,然后可以用 Ctrl+C 来停止运行。执行 `cmatrix -s` 则会启动屏保模式,这样的话,按任意键都会直接退出。`-C` 参数可以设定颜色,譬如绿色(green)、红色(red)、蓝色(blue)、黄色(yellow)、白色(white)、紫色(magenta)、青色(cyan)或者黑色(black)。 ![图 2 黑客帝国屏保](https://www.linux.com/sites/lcom/files/styles/floated_images/public/fig-2_0.jpg?itok=E3f26R7w) @@ -118,7 +118,7 @@ CMatrix 还支持异步按键,这意味着你可以在它运行的时候改变 ### fbgs PDF 阅读器 It seems that the addiction to PDF documents is pandemic and incurable, though PDFs are better than they used to be, with live hyperlinks, copy-paste, and good text search. The `fbgs` console PDF viewer is part of the `fbida` package. Options include page size, resolution, page selections, and most `fbi` options, with the exceptions listed in `man fbgs`. The main option I use is page size; you get `-l`, `xl`, and `xxl` to choose from: -看起来,对 PDF 文档的上瘾是普遍而无法阻止的,尽管 PDF 比它之前好了很多,譬如实时超链接、复制粘贴以及更好的文本搜索功能等。`fbgs` 是 `fbida` 包中提供的一个 PDF 阅读器。它可以设置页面大小、分辨率、指定页码以及绝大部分 `fbi` 提供的选项,当然除了一些在 `man fbgs` 中列举出来的不可用选项之外。我主要用到的选项是页面大小,你可以选择 `-l`、`xl` 或者 `xxl`: +看起来,PDF 文档的流行是普遍且无法阻止的,而且 PDF 比它之前好了很多,譬如超链接、复制粘贴以及更好的文本搜索功能等。`fbgs` 是 `fbida` 包中提供的一个 PDF 阅读器。它可以设置页面大小、分辨率、指定页码以及绝大部分 `fbi` 所提供的选项,当然除了一些在 `man fbgs` 中列举出来的不可用选项。我主要用到的选项是页面大小,你可以选择 `-l`、`xl` 或者 `xxl`: ``` $ fbgs -xl annoyingpdf.pdf From b5c6cf5ba48bc54f757b16a936c17569b28b140f Mon Sep 17 00:00:00 2001 From: Yinr Date: Tue, 30 Jan 2018 19:21:41 +0800 Subject: [PATCH 061/272] move file --- ...1 Multimedia Apps for the Linux Console.md | 30 +------------------ 1 file changed, 1 insertion(+), 29 deletions(-) rename {sources => translated}/tech/20180111 Multimedia Apps for the Linux Console.md (60%) diff --git a/sources/tech/20180111 Multimedia Apps for the Linux Console.md b/translated/tech/20180111 Multimedia Apps for the Linux Console.md similarity index 60% rename from sources/tech/20180111 Multimedia Apps for the Linux Console.md rename to translated/tech/20180111 Multimedia Apps for the Linux Console.md index def5412ab4..b460984a01 100644 --- a/sources/tech/20180111 Multimedia Apps for the Linux Console.md +++ b/translated/tech/20180111 Multimedia Apps for the Linux Console.md @@ -1,38 +1,28 @@ -Translating by Yinr - -Multimedia Apps for the Linux Console Linux 终端下的多媒体应用 ====== ![](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/multimedia.jpg?itok=v-XrnKRB) -The Linux console supports multimedia, so you can enjoy music, movies, photos, and even read PDF files. + Linux 终端是支持多媒体的,所以你可以在终端里听音乐,看电影,看图片,甚至是阅读 PDF。 -When last we met, we learned that the Linux console supports multimedia. Yes, really! You can enjoy music, movies, photos, and even read PDF files without being in an X session with MPlayer, fbi, and fbgs. And, as a bonus, you can enjoy a Matrix-style screensaver for the console, CMatrix. 在我的上一篇文章里,我们了解到 Linux 终端是可以支持多媒体的。是的,这是真的!你可以使用 Mplayer、fbi 和 fbgs 来实现不打开 X 进程就听音乐、看电影、看照片,甚至阅读 PDF。此外,你还可以通过 CMatrix 来体验黑客帝国(Matrix)风格的屏幕保护。 -You will probably have make some tweaks to your system to make this work. The examples used here are for Ubuntu Linux 16.04. 不过你可能需要对系统进行一些修改才能达到前面这些目的。下文的操作都是在 Ubuntu 16.04 上进行的。 ### MPlayer -You're probably familiar with the amazing and versatile MPlayer, which supports almost every video and audio format, and runs on nearly everything, including Linux, Android, Windows, Mac, Kindle, OS/2, and AmigaOS. Using MPLayer in your console will probably require some tweaking, depending on your Linux distribution. To start, try playing a video: 你可能会比较熟悉功能丰富的 MPlayer。它支持几乎所有格式的视频与音频,并且能在绝大部分现有的平台上运行,像 Linux,Android,Windows,Mac,Kindle,OS/2 甚至是 AmigaOS。不过,要在你的终端运行 MPlayer 可能需要多做一点工作,这些工作与你使用的 Linux 发行版有关。来,我们先试着播放一个视频: ``` $ mplayer [视频文件名] ``` -If it works, then hurrah, and you can invest your time in learning useful MPlayer options, such as controlling the size of the video screen. However, some Linux distributions are managing the framebuffer differently than in the olden days, and you may have to adjust some settings to make it work. This is how to make it work on recent Ubuntu releases. 如果上面的命令正常执行了,那么很好,接下来你可以把时间放在了解 MPlayer 的常用选项上了,譬如设定视频大小等。但是,有些 Linux 发行版在对帧缓冲(framebuffer)的处理方式上与早期的不同,那么你就需要进行一些额外的设置才能让其正常工作了。下面是在最近的 Ubuntu 发行版上需要做的一些操作。 -First, add yourself to the video group. 首先,将你自己添加到 video 用户组。 -Second, verify that `/etc/modprobe.d/blacklist-framebuffer.conf` has this line: `#blacklist vesafb`. It should already be commented out, and if it isn't then comment it. All the other module lines should be un-commented, which prevents them from loading. Side note: if you want to dig more deeply into managing your framebuffer, the module for your video card may give better performance. 其次,确认 `/etc/modprobe.d/blacklist-framebuffer.conf` 文件中包含这样一行:`#blacklist vesafb`。这一行应该默认被注释掉了,如果不是的话,那就手动把它注释掉。此外的其他模块行需要确认没有被注释,这样设置才能保证其他那些模块不会被载入。注:如果你想要对控制帧缓冲(framebuffer)有更深入的了解,可以从针对你的显卡的这些模块里获取更深入的认识。 -Add these two modules to the end of `/etc/initramfs-tools/modules`, `vesafb` and `fbcon`, then rebuild the initramfs image: 然后,在 `/etc/initramfs-tools/modules` 的结尾增加两个模块:`vesafb` 和 `fbcon`,并且更新 iniramfs 镜像: ``` @@ -45,86 +35,68 @@ $ sudo nano /etc/initramfs-tools/modules $ sudo update-initramfs -u ``` -[fbcon][1] is the Linux framebuffer console. It runs on top of the framebuffer and adds graphical features. It requires a framebuffer device, which is supplied by the `vesafb` module. [fbcon][1] 是 Linux 帧缓冲(framebuffer)终端,它运行在帧缓冲(framebuffer)之上并为其增加图形功能。而它需要一个帧缓冲(framebuffer)设备,这则是由 `vesafb` 模块来提供的。 -Now you must edit your GRUB2 configuration. In `/etc/default/grub` you should see a line like this: 接下来,你需要修改你的 GRUB2 配置。在 `/etc/default/grub` 中你将会看到类似下面的一行: ``` GRUB_CMDLINE_LINUX_DEFAULT="quiet splash" ``` -It may have some other options, but it should be there. Add `vga=789`: 它也可能还会有一些别的参数,不用管它,在其后加上 `vga=789`: ``` GRUB_CMDLINE_LINUX_DEFAULT="quiet splash vga=789" ``` -Reboot and enter your console (Ctrl+Alt+F1), and try playing a video. This command selects the `fbdev2` video device; I haven't learned yet how to know which one to use, but I had to use it to play the video. The default screen size is 320x240, so I scaled it to 960: 重启之后进入你的终端(Ctrl+Alt+F1)(LCTT 译注:在某些发行版中 Ctrl+Alt+F1 默认为图形界面,可以尝试 Ctrl+Alt+F2),然后就可以尝试播放一个视频了。下面的命令指定了 `fbdev2` 为视频输出设备,虽然我还没弄明白如何去选择用哪个输入设备,但是我用它成功过。默认的视频大小是 320x240,在此我给缩放到了 960: ``` $ mplayer -vo fbdev2 -vf scale -zoom -xy 960 AlienSong_mp4.mov ``` -And behold Figure 1. It's grainy because I have a low-fi copy of this video, not because MPlayer is making it grainy. 来看图 1。粗糙的画面是由于我原视频的质量不高,而不是 MPlayer 的显示问题。 ![图 1 播放视频](https://www.linux.com/sites/lcom/files/styles/floated_images/public/fig-1_3.jpg?itok=PtSoKepn) -MPLayer plays CDs, DVDs, network streams, and has a giant batch of playback options, which I shall leave as your homework to explore. MPlayer 可以播放 CD、DVD 以及网络视频流,并且还有一系列的回放选项,这些将作为作业留给大家自己去发现。 -### fbi Image Viewer ### fbi 图片查看器 -`fbi`, the framebuffer image viewer, comes in the [fbida][2] package on most Linuxes. It has native support for the common image file formats, and uses `convert` (from Image Magick), if it is installed, for other formats. Its simplest use is to view a single image file: `fbi` 是一个帧缓冲图片查看器。在大部分的 Linux 发行版中,它被包含在 [fbida][2] 包里。它原生支持一些常见的图片格式,而如果你安装了 `convert`(来自于 Image Magick),那么它还能借此打开一些其他格式。最简单的用法是用来查看一个图片文件: ``` $ fbi 文件名 ``` -Use the arrow keys to scroll a large image, + and - to zoom, and r and l to rotate 90 degress right and left. Press the Escape key to close the image. You can play a slideshow by giving `fbi` a list of files: 你可以使用方向键来在大图片中移动视野,使用 + 和 - 来缩放,或者使用 r 或 l 来向右或向左旋转 90 度。Escape 键则可以关闭查看的图片。此外,你还可以给 `fbi` 一个文件列表来实现幻灯播放: ``` $ fbi --list 文件列表.txt ``` -`fbi` supports autozoom. With `-a` `fbi` controls the zoom factor. `--autoup` and `--autodown` tell `fbi` to only zoom up or down. Control the blend time between images with `--blend [time]`, in milliseconds. Press the k and j keys to jump behind and ahead in your file list. `fbi` 还支持自动缩放。还可以使用 `-a` 选项来控制缩放比例。`--autoup` 和 `--autodown` 则是用于告知 `fbi` 只进行放大或者缩小。要调整图片切换时淡入淡出的时间则可以使用 `--blend [时间]` 来指定一个以毫秒为单位的时间长度。使用 k 和 j 键则可以切换文件列表中的上一张或下一张图片。 -`fbi` has commands for creating file lists from images you have viewed, and for exporting your commands to a file, and a host of other cool options. Check out `man fbi` for complete options. `fbi` 还提供了命令来为你浏览过的文件创建文件列表,或者将你的命令导出到文件中,以及一系列其它很棒的选项。你可以通过 `man fbi` 来查阅完整的选项列表。 -### CMatrix Console Screensaver ### CMatrix 终端屏保 -The Matrix screensaver is still my favorite (Figure 2), second only to the bouncing cow. [CMatrix][3] runs on the console. Simply type `cmatrix` to start it, and Ctrl+C stops it. Run `cmatrix -s` to launch it in screensaver mode, which exits on any keypress. `-C` changes the color. Your choices are green, red, blue, yellow, white, magenta, cyan, and black. 黑客帝国(The Matrix)屏保仍然是我非常喜欢的屏保之一(如图 2),仅次于弹跳牛(bouncing cow)。[CMatrix][3] 可以在终端运行。要运行它只需输入 `cmatrix`,然后可以用 Ctrl+C 来停止运行。执行 `cmatrix -s` 则会启动屏保模式,这样的话,按任意键都会直接退出。`-C` 参数可以设定颜色,譬如绿色(green)、红色(red)、蓝色(blue)、黄色(yellow)、白色(white)、紫色(magenta)、青色(cyan)或者黑色(black)。 ![图 2 黑客帝国屏保](https://www.linux.com/sites/lcom/files/styles/floated_images/public/fig-2_0.jpg?itok=E3f26R7w) -CMatrix supports asynchronous key presses, which means you can change options while it's running. CMatrix 还支持异步按键,这意味着你可以在它运行的时候改变设置选项。 -`-B` is all bold text, and `-B` is partially bold. `-B` 设置全部使用粗体,而 `-b`(LCTT 译注:原文误为 `-B`)则可以设置部分字体加粗。 -### fbgs PDF Viewer ### fbgs PDF 阅读器 -It seems that the addiction to PDF documents is pandemic and incurable, though PDFs are better than they used to be, with live hyperlinks, copy-paste, and good text search. The `fbgs` console PDF viewer is part of the `fbida` package. Options include page size, resolution, page selections, and most `fbi` options, with the exceptions listed in `man fbgs`. The main option I use is page size; you get `-l`, `xl`, and `xxl` to choose from: 看起来,PDF 文档的流行是普遍且无法阻止的,而且 PDF 比它之前好了很多,譬如超链接、复制粘贴以及更好的文本搜索功能等。`fbgs` 是 `fbida` 包中提供的一个 PDF 阅读器。它可以设置页面大小、分辨率、指定页码以及绝大部分 `fbi` 所提供的选项,当然除了一些在 `man fbgs` 中列举出来的不可用选项。我主要用到的选项是页面大小,你可以选择 `-l`、`xl` 或者 `xxl`: ``` $ fbgs -xl annoyingpdf.pdf ``` -Learn more about Linux through the free ["Introduction to Linux" ][4]course from The Linux Foundation and edX. 欢迎通过 Linux 基金会与 edX 免费提供的[“Linux 入门”][4]课程学习更多 Linux 知识。 -------------------------------------------------------------------------------- From 8cda027ba4c4c0da68124e8935930735b95fbfe9 Mon Sep 17 00:00:00 2001 From: imquanquan Date: Tue, 30 Jan 2018 20:33:12 +0800 Subject: [PATCH 062/272] First checking by imquanquan --- translated/tech/20171215 Linux Vs Unix.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/translated/tech/20171215 Linux Vs Unix.md b/translated/tech/20171215 Linux Vs Unix.md index 15f9a16b1c..2b789d03bb 100644 --- a/translated/tech/20171215 Linux Vs Unix.md +++ b/translated/tech/20171215 Linux Vs Unix.md @@ -7,15 +7,15 @@ [![what is unix](http://www.linuxandubuntu.com/uploads/2/1/1/5/21152474/unix_orig.png)][2] - 在 IT 领域,作为操作系统为我们为我们所知的 Unix ,是 1969 年 AT& 公司在美国新泽西所开发的,目前它的商标权由国际开放标准组织所拥有。大多数的操作系统都受 Unix 的启发,但 Unix 也受到了未完成的 Multics 系统的启发。 Unix 的另一版本是来自贝尔实验室的 Play 9。 + 在 IT 领域,作为操作系统为我们所知的 Unix,是 1969 年 AT& 公司在美国新泽西所开发的,目前它的商标权由国际开放标准组织所拥有。大多数的操作系统都受 Unix 的启发,而 Unix 也受到了未完成的 Multics 系统的启发。Unix 的另一版本是来自贝尔实验室的 Play 9。 ### Unix 被用于哪里? -作为一个操作系统,Unix 大多被用在服务器、工作站且现在也有用在个人计算机上。它在创建互联网、创建计算机网络或客户端服务器模型方面发挥着非常重要的作用。 +作为一个操作系统,Unix 大多被用在服务器、工作站且现在也有用在个人计算机上。它在创建互联网、创建计算机网络或客户端/服务器模型方面发挥着非常重要的作用。 #### Unix 系统的特点 -* 支持多任务(multitasking) +* 支持多任务(multitasking) * 相比 Multics 操作更加简单 @@ -37,11 +37,11 @@ [![what is linux](http://www.linuxandubuntu.com/uploads/2/1/1/5/21152474/linux_orig.png)][4] -这是一个基于 Unix 系统原理的开源操作系统。正如开源的含义一样,它是一个可以自由下载的系统。也可以干涉系统的编辑、添加,然后扩充其源代码。这是它最大的好处之一,而不像今天的其他操作系统(Windows、Mac OS X....)需要付费。Linux 系统的开发不仅是因为 Unix 系统提供了一个模板,其中还有一个重要的因素是 MINIX 系统的启发。不像 Linus,此版本被创造者(Andrew Tanenbaum)用于商业系统 。1991 年 **Linus Torvalds** 开始把对 Linux 系统的开发当做个人兴趣。其中,Linux 开始处理 Unix 的原因是系统的简单性。Linux(0.01)第一个官方版本发布于 1991年9月17日。虽然这个系统并不是很完美和完整,但 Linus 对它产生很大的兴趣。在接下来的几天,Linus 开始写关于 Linux 源代码扩展以及其他想法的电子邮件。看起来,此操作系统的正式名取自 Linus 的创造者的名字。其中,操作系统名称的结尾“x” 与 Unix 操作系统相名称相关联。 +这是一个基于 Unix 系统原理的开源操作系统。正如开源的含义一样,它是一个可以自由下载的系统。也可以干涉系统的编辑、添加,然后扩充其源代码。这是它最大的好处之一,而不像今天的其他操作系统(Windows、Mac OS X....)需要付费。Linux 系统的开发不仅是因为 Unix 系统提供了一个模板,其中还有一个重要的因素是 MINIX 系统的启发。不像 Linus,此版本被创造者(Andrew Tanenbaum)用于商业系统 。1991 年 **Linus Torvalds** 开始把对 Linux 系统的开发当做个人兴趣。其中,Linux 开始处理 Unix 的原因是系统的简单性。Linux(0.01)第一个官方版本发布于 1991年9月17日。虽然这个系统并不是很完美和完整,但 Linus 对它产生很大的兴趣。在接下来的几天,Linus 开始写关于 Linux 源代码扩展以及其他想法的电子邮件。 ### Linux 的特点 -Linux 内核是 Unix 内核,基于 Unix 的基本特点以及 **POSIX** 和 Single **UNIX 规范标准**。看起来那操作系统官方名字取自于 **Linus**,其中其操作系统名称的尾部"x"跟 **Unix 系统**相联系。 +Linux 内核是 Unix 内核,基于 Unix 的基本特点以及 **POSIX** 和 Single **UNIX 规范标准**。看起来那操作系统官方名字取自于 **Linus**,其中其操作系统名称的尾部"x"跟 **Unix 系统**相联系。 #### 主要特点: @@ -51,7 +51,7 @@ Linux 内核是 Unix 内核,基于 Unix 的基本特点以及 **POSIX** 和 Si * 多用户,因此它可以运行多个用户程序。 -* 个人帐户受适当授权的保护 +* 个人帐户受适当授权的保护。 * 因此账户准确地定义了系统控制权。 @@ -63,8 +63,8 @@ Linux 内核是 Unix 内核,基于 Unix 的基本特点以及 **POSIX** 和 Si via: http://www.linuxandubuntu.com/home/linux-vs-unix 作者:[linuxandubuntu][a] -译者:[译者ID](https://github.com/HardworkFish) -校对:[校对者ID](https://github.com/校对者ID) +译者:[HardworkFish](https://github.com/HardworkFish) +校对:[imquanquan](https://github.com/imquanquan) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 From e5bd453ecfebdf176a07c3e17fc2c41f86f18008 Mon Sep 17 00:00:00 2001 From: MjSeven <33125422+MjSeven@users.noreply.github.com> Date: Tue, 30 Jan 2018 21:29:23 +0800 Subject: [PATCH 063/272] Update 20170915 How To Install And Setup Vagrant.md --- sources/tech/20170915 How To Install And Setup Vagrant.md | 1 + 1 file changed, 1 insertion(+) diff --git a/sources/tech/20170915 How To Install And Setup Vagrant.md b/sources/tech/20170915 How To Install And Setup Vagrant.md index 1e76600595..6b6a8a0450 100644 --- a/sources/tech/20170915 How To Install And Setup Vagrant.md +++ b/sources/tech/20170915 How To Install And Setup Vagrant.md @@ -1,3 +1,4 @@ +Translating by MjSeven How To Install And Setup Vagrant ====== Vagrant is a powerful tool when it comes to virtual machines, here we will look at how to setup and use Vagrant with Virtualbox on Ubuntu to provision reproducible virtual machines. From 76f7439bbf2f681c5b5cea22aa1a180119d6ceeb Mon Sep 17 00:00:00 2001 From: Sun Yongfei Date: Tue, 30 Jan 2018 21:40:39 +0800 Subject: [PATCH 064/272] Delete 20180124 8 ways to generate random password in Linux.md --- ...ys to generate random password in Linux.md | 274 ------------------ 1 file changed, 274 deletions(-) delete mode 100644 sources/tech/20180124 8 ways to generate random password in Linux.md diff --git a/sources/tech/20180124 8 ways to generate random password in Linux.md b/sources/tech/20180124 8 ways to generate random password in Linux.md deleted file mode 100644 index 499aa5f2c1..0000000000 --- a/sources/tech/20180124 8 ways to generate random password in Linux.md +++ /dev/null @@ -1,274 +0,0 @@ -translating by heart4lor - -8 ways to generate random password in Linux -====== -Learn 8 different ways to generate random password in Linux using Linux native commands or third party utilities. - -![][1] - -In this article, we will walk you through various different ways to generate random password in Linux terminal. Few of them are using native Linux commands and others are using third party tools or utilities which can easily be installed on Linux machine. Here we are looking at native commands like `openssl`, [dd][2], `md5sum`, `tr`, `urandom` and third party tools like mkpasswd, randpw, pwgen, spw, gpg, xkcdpass, diceware, revelation, keepaasx, passwordmaker. - -These are actually ways to get some random alphanumeric string which can be utilized as password. Random passwords can be used for new users so that there will be uniqueness no matter how large your user base is. Without any further delay lets jump into those 15 different ways to generate random password in Linux. - -##### Generate password using mkpasswd utility - -`mkpasswd` comes with install of `expect` package on RHEL based systems. On Debian based systems `mkpasswd` comes with package `whois`. Trying to install `mkpasswd` package will results in error - - -No package mkpasswd available. on RHEL system and E: Unable to locate package mkpasswd in Debian based. - -So install their parent packages as mentioned above and you are good to go. - -Run `mkpasswd` to get passwords - -``` -root@kerneltalks# mkpasswd << on RHEL -zt*hGW65c - -root@kerneltalks# mkpas -``` - -Command behaves differently on different systems so work accordingly. There are many switches which can be used to control length etc parameters. You can explore them from man pages. - -##### Generate password using openssl - -Openssl comes in build with almost all the Linux distributions. We can use its random function to get alphanumeric string generated which can be used as password. - -``` -root@kerneltalks # openssl rand -base64 10 -nU9LlHO5nsuUvw== -``` - -Here, we are using `base64` encoding with random function and last digit for argument to `base64` encoding. - -##### Generate password using urandom - -Device file `/dev/urandom` is another source of getting random characters. We are using `tr` function and trimming output to get random string to use as password. - -``` -root@kerneltalks # strings /dev/urandom |tr -dc A-Za-z0-9 | head -c20; echo -UiXtr0NAOSIkqtjK4c0X -``` - -##### dd command to generate password - -We can even use /dev/urandom device along with [dd command ][2]to get string of random characters. - -``` -oot@kerneltalks# dd if=/dev/urandom bs=1 count=15|base64 -w 0 -15+0 records in -15+0 records out -15 bytes (15 B) copied, 5.5484e-05 s, 270 kB/s -QMsbe2XbrqAc2NmXp8D0 -``` - -We need to pass output through `base64` encoding to make it human readable. You can play with count value to get desired length. For much cleaner output, redirect std2 to `/dev/null`. Clean command will be - - -``` -oot@kerneltalks # dd if=/dev/urandom bs=1 count=15 2>/dev/null|base64 -w 0 -F8c3a4joS+a3BdPN9C++ -``` - -##### Using md5sum to generate password - -Another way to get array of random characters which can be used as password is to calculate MD5 checksum! s you know checksum value is indeed looks like random characters grouped together we can use it as password. Make sure you use source as something variable so that you get different checksum every time you run command. For example `date` ! [date command][3] always yields changing output. - -``` -root@kerneltalks # date |md5sum -4d8ce5c42073c7e9ca4aeffd3d157102 - -``` - -Here we passed `date` command output to `md5sum` and get the checksum hash! You can use [cut command][4] to get desired length of output. - -##### Generate password using pwgen - -`pwgen` package comes with [repositories like EPEL][5]. `pwgen` is more focused on generating passwords which are pronounceable but not a dictionary word or not in plain English. You may not find it in standard distribution repo. Install the package and run `pwgen` command. Boom ! - -``` -root@kerneltalks # pwgen -thu8Iox7 ahDeeQu8 Eexoh0ai oD8oozie ooPaeD9t meeNeiW2 Eip6ieph Ooh1tiet -cootad7O Gohci0vo wah9Thoh Ohh3Ziur Ao1thoma ojoo6aeW Oochai4v ialaiLo5 -aic2OaDa iexieQu8 Aesoh4Ie Eixou9ph ShiKoh0i uThohth7 taaN3fuu Iege0aeZ -cah3zaiW Eephei0m AhTh8guo xah1Shoo uh8Iengo aifeev4E zoo4ohHa fieDei6c -aorieP7k ahna9AKe uveeX7Hi Ohji5pho AigheV7u Akee9fae aeWeiW4a tiex8Oht -``` -You will be presented with list of passwords at your terminal! What else you want? Ok. You still want to explore, `pwgen` comes with many custom options which can be referred for man page. - -##### Generate password using gpg tool - -GPG is a OpenPGP encryption and signing tool. Mostly gpg tool comes pre-installed (at least it is on my RHEL7). But if not you can look for `gpg` or `gpg2` package and [install][6] it. - -Use below command to generate password from gpg tool. - -``` -root@kerneltalks # gpg --gen-random --armor 1 12 -mL8i+PKZ3IuN6a7a -``` - -Here we are passing generate random byte sequence switch (`--gen-random`) of quality 1 (first argument) with count of 12 (second argument). Switch `--armor` ensures output is `base64` encoded. - -##### Generate password using xkcdpass - -Famous geek humor website [xkcd][7], published a very interesting post about memorable but still complex passwords. You can view it [here][8]. So `xkcdpass` tool took inspiration from this post and did its work! Its a python package and available on python's official website [here][9] - -All installation and usage instructions are mentioned on that page. Here is install steps and outputs from my test RHEL server for your reference. - -``` -root@kerneltalks # wget https://pypi.python.org/packages/b4/d7/3253bd2964390e034cf0bba227db96d94de361454530dc056d8c1c096abc/xkcdpass-1.14.3.tar.gz#md5=5f15d52f1d36207b07391f7a25c7965f ---2018-01-23 19:09:17-- https://pypi.python.org/packages/b4/d7/3253bd2964390e034cf0bba227db96d94de361454530dc056d8c1c096abc/xkcdpass-1.14.3.tar.gz -Resolving pypi.python.org (pypi.python.org)... 151.101.32.223, 2a04:4e42:8::223 -Connecting to pypi.python.org (pypi.python.org)|151.101.32.223|:443... connected. -HTTP request sent, awaiting response... 200 OK -Length: 871848 (851K) [binary/octet-stream] -Saving to: ‘xkcdpass-1.14.3.tar.gz’ - -100%[==============================================================================================================================>] 871,848 --.-K/s in 0.01s - -2018-01-23 19:09:17 (63.9 MB/s) - ‘xkcdpass-1.14.3.tar.gz’ saved [871848/871848] - - -root@kerneltalks # tar -xvf xkcdpass-1.14.3.tar.gz -xkcdpass-1.14.3/ -xkcdpass-1.14.3/examples/ -xkcdpass-1.14.3/examples/example_import.py -xkcdpass-1.14.3/examples/example_json.py -xkcdpass-1.14.3/examples/example_postprocess.py -xkcdpass-1.14.3/LICENSE.BSD -xkcdpass-1.14.3/MANIFEST.in -xkcdpass-1.14.3/PKG-INFO -xkcdpass-1.14.3/README.rst -xkcdpass-1.14.3/setup.cfg -xkcdpass-1.14.3/setup.py -xkcdpass-1.14.3/tests/ -xkcdpass-1.14.3/tests/test_list.txt -xkcdpass-1.14.3/tests/test_xkcdpass.py -xkcdpass-1.14.3/tests/__init__.py -xkcdpass-1.14.3/xkcdpass/ -xkcdpass-1.14.3/xkcdpass/static/ -xkcdpass-1.14.3/xkcdpass/static/eff-long -xkcdpass-1.14.3/xkcdpass/static/eff-short -xkcdpass-1.14.3/xkcdpass/static/eff-special -xkcdpass-1.14.3/xkcdpass/static/fin-kotus -xkcdpass-1.14.3/xkcdpass/static/ita-wiki -xkcdpass-1.14.3/xkcdpass/static/legacy -xkcdpass-1.14.3/xkcdpass/static/spa-mich -xkcdpass-1.14.3/xkcdpass/xkcd_password.py -xkcdpass-1.14.3/xkcdpass/__init__.py -xkcdpass-1.14.3/xkcdpass.1 -xkcdpass-1.14.3/xkcdpass.egg-info/ -xkcdpass-1.14.3/xkcdpass.egg-info/dependency_links.txt -xkcdpass-1.14.3/xkcdpass.egg-info/entry_points.txt -xkcdpass-1.14.3/xkcdpass.egg-info/not-zip-safe -xkcdpass-1.14.3/xkcdpass.egg-info/PKG-INFO -xkcdpass-1.14.3/xkcdpass.egg-info/SOURCES.txt -xkcdpass-1.14.3/xkcdpass.egg-info/top_level.txt - - -root@kerneltalks # cd xkcdpass-1.14.3 - -root@kerneltalks # python setup.py install -running install -running bdist_egg -running egg_info -writing xkcdpass.egg-info/PKG-INFO -writing top-level names to xkcdpass.egg-info/top_level.txt -writing dependency_links to xkcdpass.egg-info/dependency_links.txt -writing entry points to xkcdpass.egg-info/entry_points.txt -reading manifest file 'xkcdpass.egg-info/SOURCES.txt' -reading manifest template 'MANIFEST.in' -writing manifest file 'xkcdpass.egg-info/SOURCES.txt' -installing library code to build/bdist.linux-x86_64/egg -running install_lib -running build_py -creating build -creating build/lib -creating build/lib/xkcdpass -copying xkcdpass/xkcd_password.py -> build/lib/xkcdpass -copying xkcdpass/__init__.py -> build/lib/xkcdpass -creating build/lib/xkcdpass/static -copying xkcdpass/static/eff-long -> build/lib/xkcdpass/static -copying xkcdpass/static/eff-short -> build/lib/xkcdpass/static -copying xkcdpass/static/eff-special -> build/lib/xkcdpass/static -copying xkcdpass/static/fin-kotus -> build/lib/xkcdpass/static -copying xkcdpass/static/ita-wiki -> build/lib/xkcdpass/static -copying xkcdpass/static/legacy -> build/lib/xkcdpass/static -copying xkcdpass/static/spa-mich -> build/lib/xkcdpass/static -creating build/bdist.linux-x86_64 -creating build/bdist.linux-x86_64/egg -creating build/bdist.linux-x86_64/egg/xkcdpass -copying build/lib/xkcdpass/xkcd_password.py -> build/bdist.linux-x86_64/egg/xkcdpass -copying build/lib/xkcdpass/__init__.py -> build/bdist.linux-x86_64/egg/xkcdpass -creating build/bdist.linux-x86_64/egg/xkcdpass/static -copying build/lib/xkcdpass/static/eff-long -> build/bdist.linux-x86_64/egg/xkcdpass/static -copying build/lib/xkcdpass/static/eff-short -> build/bdist.linux-x86_64/egg/xkcdpass/static -copying build/lib/xkcdpass/static/eff-special -> build/bdist.linux-x86_64/egg/xkcdpass/static -copying build/lib/xkcdpass/static/fin-kotus -> build/bdist.linux-x86_64/egg/xkcdpass/static -copying build/lib/xkcdpass/static/ita-wiki -> build/bdist.linux-x86_64/egg/xkcdpass/static -copying build/lib/xkcdpass/static/legacy -> build/bdist.linux-x86_64/egg/xkcdpass/static -copying build/lib/xkcdpass/static/spa-mich -> build/bdist.linux-x86_64/egg/xkcdpass/static -byte-compiling build/bdist.linux-x86_64/egg/xkcdpass/xkcd_password.py to xkcd_password.pyc -byte-compiling build/bdist.linux-x86_64/egg/xkcdpass/__init__.py to __init__.pyc -creating build/bdist.linux-x86_64/egg/EGG-INFO -copying xkcdpass.egg-info/PKG-INFO -> build/bdist.linux-x86_64/egg/EGG-INFO -copying xkcdpass.egg-info/SOURCES.txt -> build/bdist.linux-x86_64/egg/EGG-INFO -copying xkcdpass.egg-info/dependency_links.txt -> build/bdist.linux-x86_64/egg/EGG-INFO -copying xkcdpass.egg-info/entry_points.txt -> build/bdist.linux-x86_64/egg/EGG-INFO -copying xkcdpass.egg-info/not-zip-safe -> build/bdist.linux-x86_64/egg/EGG-INFO -copying xkcdpass.egg-info/top_level.txt -> build/bdist.linux-x86_64/egg/EGG-INFO -creating dist -creating 'dist/xkcdpass-1.14.3-py2.7.egg' and adding 'build/bdist.linux-x86_64/egg' to it -removing 'build/bdist.linux-x86_64/egg' (and everything under it) -Processing xkcdpass-1.14.3-py2.7.egg -creating /usr/lib/python2.7/site-packages/xkcdpass-1.14.3-py2.7.egg -Extracting xkcdpass-1.14.3-py2.7.egg to /usr/lib/python2.7/site-packages -Adding xkcdpass 1.14.3 to easy-install.pth file -Installing xkcdpass script to /usr/bin - -Installed /usr/lib/python2.7/site-packages/xkcdpass-1.14.3-py2.7.egg -Processing dependencies for xkcdpass==1.14.3 -Finished processing dependencies for xkcdpass==1.14.3 -``` - -Now running xkcdpass command will give you random set of dictionary words like below - - -``` -root@kerneltalks # xkcdpass -broadside unpadded osmosis statistic cosmetics lugged -``` - -You can use these words as input to other commands like `md5sum` to get random password (like below) or you can even use Nth letter of each words to form your password! - -``` -oot@kerneltalks # xkcdpass |md5sum -45f2ec9b3ca980c7afbd100268c74819 - - -root@kerneltalks # xkcdpass |md5sum -ad79546e8350744845c001d8836f2ff2 - -``` -Or even you can use all those words together as such a long password which is easy to remember for a user and very hard to crack using computer program. - -There are tools like [Diceware][10], [KeePassX][11], [Revelation][12], [PasswordMaker][13] for Linux which can be considered for making strong random passwords. - --------------------------------------------------------------------------------- - -via: https://kerneltalks.com/tips-tricks/8-ways-to-generate-random-password-in-linux/ - -作者:[kerneltalks][a] -译者:[译者ID](https://github.com/译者ID) -校对:[校对者ID](https://github.com/校对者ID) - -本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 - -[a]:https://kerneltalks.com -[1]:https://a1.kerneltalks.com/wp-content/uploads/2018/01/different-ways-to-generate-password-in-linux.png -[2]:https://kerneltalks.com/commands/learn-dd-command-with-examples/ -[3]:https://kerneltalks.com/commands/date-time-management-using-timedatectl-command/ -[4]:https://kerneltalks.com/linux/cut-command-examples/ -[5]:https://kerneltalks.com/package/how-to-install-epel-repository/ -[6]:https://kerneltalks.com/tools/package-installation-linux-yum-apt/ -[7]:https://xkcd.com/ -[8]:https://xkcd.com/936/ -[9]:https://pypi.python.org/pypi/xkcdpass/ -[10]:http://world.std.com/~reinhold/diceware.html -[11]:https://www.keepassx.org/ -[12]:https://packages.debian.org/sid/gnome/revelation -[13]:https://passwordmaker.org/ From 847fce425b7b70420cca72b50b3ac7dd9027d6f1 Mon Sep 17 00:00:00 2001 From: Sun Yongfei Date: Tue, 30 Jan 2018 21:41:58 +0800 Subject: [PATCH 065/272] translated by heart4lor --- ...ys to generate random password in Linux.md | 275 ++++++++++++++++++ 1 file changed, 275 insertions(+) create mode 100644 translated/tech/20180124 8 ways to generate random password in Linux.md diff --git a/translated/tech/20180124 8 ways to generate random password in Linux.md b/translated/tech/20180124 8 ways to generate random password in Linux.md new file mode 100644 index 0000000000..0e148b7f5f --- /dev/null +++ b/translated/tech/20180124 8 ways to generate random password in Linux.md @@ -0,0 +1,275 @@ +八种在 Linux 上生成随机密码的方法 +====== +学习使用 8 种 Linux 原生命令或第三方组件来生成随机密码。 + +![][1] + +在这篇文章中,我们将引导你通过几种不同的方式在 Linux 中生成随机密码。其中几种利用原生 Linux 命令,另外几种则利用极易在 Linux 机器上安装的第三方工具或组件实现。在这里我们利用像 `openssl`, [dd][2], `md5sum`, `tr`, `urandom` 这样的原生命令和 mkpasswd,randpw,pwgen,spw,gpg,xkcdpass,diceware,revelation,keepaasx,passwordmaker 这样的第三方工具。 + +其实这些方法就是生成一些能被用作密码的随机字母字符串。随机密码可以用于新用户的密码,不管用户基数有多大,这些密码都是独一无二的。话不多说,让我们来看看 8 种不同的在 Linux 上生成随机密码的方法吧。 + +##### 使用 mkpasswd 组件生成密码 + +`mkpasswd` 在基于 RHEL 的系统上随 `expect` 软件包一起安装。在基于 Debian 的系统上 `mkpasswd` 则在软件包 `whois` 中。直接安装 `mkpasswd` 软件包将会导致错误 - + +RHEL 系统:软件包 mkpasswd 不可用。 + +Debian 系统:错误:无法定位软件包 mkpasswd。 + +所以按照上面所述安装他们的父软件包,就没问题了。 + +运行 `mkpasswd` 来获得密码 + +```bash +root@kerneltalks# mkpasswd << on RHEL +zt*hGW65c + +root@kerneltalks# mkpasswd teststring << on Ubuntu +XnlrKxYOJ3vik +``` + +这个命令在不同的系统上表现得不一样,所以要对应工作。你也可以通过参数来控制长度等选项。你可以查阅 man 手册来探索。 + +##### 使用 openssl 生成密码 + +几乎所有 Linux 发行版都包含 openssl。我们可以利用它的随机功能来生成可以用作密码的随机字母字符串。 + +```bash +root@kerneltalks # openssl rand -base64 10 +nU9LlHO5nsuUvw== +``` + +这里我们使用 `base64` 编码随机函数,最后一个数字参数表示长度。 + +##### 使用 urandom 生成密码 + +设备文件 `/dev/urandom` 是另一个获得随机字符串的方法。我们使用 `tr` 功能裁剪输出来获得随机字符串,并把它作为密码。 + +```bash +root@kerneltalks # strings /dev/urandom |tr -dc A-Za-z0-9 | head -c20; echo +UiXtr0NAOSIkqtjK4c0X +``` + +##### 使用 dd 命令生成密码 + +我们甚至可以使用 /dev/urandom 设备配合 [dd 命令][2] 来获取随机字符串。 + +```bash +root@kerneltalks# dd if=/dev/urandom bs=1 count=15|base64 -w 0 +15+0 records in +15+0 records out +15 bytes (15 B) copied, 5.5484e-05 s, 270 kB/s +QMsbe2XbrqAc2NmXp8D0 +``` + +我们需要将结果通过 `base64` 编码使它能被人类读懂。你可以使用计数值来获取想要的长度。想要获得更简洁的输出的话,可以将 std2 重定向到 `/dev/null`。简洁输出的命令是 - + +```bash +root@kerneltalks # dd if=/dev/urandom bs=1 count=15 2>/dev/null|base64 -w 0 +F8c3a4joS+a3BdPN9C++ +``` + +##### 使用 md5sum 生成密码 + +另一种获取可用作密码的随机字符串的方法是计算 MD5 校验值!校验值看起来确实像是随机字符串组合在一起,我们可以用作为密码。确保你的计算源是个变量,这样的话每次运行命令时生成的校验值都不一样。比如 `date`![date 命令][3] 总会生成不同的输出。 + +```bash +root@kerneltalks # date |md5sum +4d8ce5c42073c7e9ca4aeffd3d157102 - +``` + +在这里我们将 `date` 命令的输出通过 `md5sum` 得到了校验和!你也可以用 [cut 命令][4] 裁剪你需要的长度。 + +##### 使用 pwgen 生成密码 + +`pwgen` 软件包在[类 EPEL 仓库][5](译者注:企业版 Linux 附加软件包)中。`pwgen` 更专注于生成可发音的密码,但它们不在英语词典中,也不是纯英文的。标准发行版仓库中可能并不包含这个工具。安装这个软件包然后运行 `pwgen` 命令行。Boom ! + +```bash +root@kerneltalks # pwgen +thu8Iox7 ahDeeQu8 Eexoh0ai oD8oozie ooPaeD9t meeNeiW2 Eip6ieph Ooh1tiet +cootad7O Gohci0vo wah9Thoh Ohh3Ziur Ao1thoma ojoo6aeW Oochai4v ialaiLo5 +aic2OaDa iexieQu8 Aesoh4Ie Eixou9ph ShiKoh0i uThohth7 taaN3fuu Iege0aeZ +cah3zaiW Eephei0m AhTh8guo xah1Shoo uh8Iengo aifeev4E zoo4ohHa fieDei6c +aorieP7k ahna9AKe uveeX7Hi Ohji5pho AigheV7u Akee9fae aeWeiW4a tiex8Oht +``` +你的终端会呈现出一个密码列表!你还想要什么呢?好吧。你还想再仔细探索的话, `pwgen` 还有很多自定义选项,这些都可以在 man 手册里查阅到。 + +##### 使用 gpg 工具生成密码 + +GPG 是一个遵循 OpenPGP 标准的加密及签名工具。大部分 gpg 工具都预先被安装好了(至少在我的 RHEL7 上是这样)。但如果没有的话你可以寻找 `gpg` 或 `gpg2` 软件包并[安装][6]它。 + +使用下面的命令以从 gpg 工具生成密码。 + +```bash +root@kerneltalks # gpg --gen-random --armor 1 12 +mL8i+PKZ3IuN6a7a +``` + +这里我们传了生成随机字节序列选项(`--gen-random`),质量为 1(第一个参数),次数 12 (第二个参数)。选项 `--armor` 保证以 `base64` 编码输出。 + +##### 使用 xkcdpass 生成密码 + +著名的极客幽默网站 [xkcd][7],发表了一篇非常有趣的文章,是关于好记但又复杂的密码的。你可以在[这里][8]阅读。所以 `xkcdpass` 工具就受这篇文章启发,做了这样的工作!这是一个 Python 软件包,可以在[这里][9]的 Python 的官网上找到它。 + +所有的安装使用说明都在上面那个页面提及了。这里是安装步骤和我的测试 RHEL 服务器的输出,以供参考。 + +```bash +root@kerneltalks # wget https://pypi.python.org/packages/b4/d7/3253bd2964390e034cf0bba227db96d94de361454530dc056d8c1c096abc/xkcdpass-1.14.3.tar.gz#md5=5f15d52f1d36207b07391f7a25c7965f +--2018-01-23 19:09:17-- https://pypi.python.org/packages/b4/d7/3253bd2964390e034cf0bba227db96d94de361454530dc056d8c1c096abc/xkcdpass-1.14.3.tar.gz +Resolving pypi.python.org (pypi.python.org)... 151.101.32.223, 2a04:4e42:8::223 +Connecting to pypi.python.org (pypi.python.org)|151.101.32.223|:443... connected. +HTTP request sent, awaiting response... 200 OK +Length: 871848 (851K) [binary/octet-stream] +Saving to: ‘xkcdpass-1.14.3.tar.gz’ + +100%[==============================================================================================================================>] 871,848 --.-K/s in 0.01s + +2018-01-23 19:09:17 (63.9 MB/s) - ‘xkcdpass-1.14.3.tar.gz’ saved [871848/871848] + + +root@kerneltalks # tar -xvf xkcdpass-1.14.3.tar.gz +xkcdpass-1.14.3/ +xkcdpass-1.14.3/examples/ +xkcdpass-1.14.3/examples/example_import.py +xkcdpass-1.14.3/examples/example_json.py +xkcdpass-1.14.3/examples/example_postprocess.py +xkcdpass-1.14.3/LICENSE.BSD +xkcdpass-1.14.3/MANIFEST.in +xkcdpass-1.14.3/PKG-INFO +xkcdpass-1.14.3/README.rst +xkcdpass-1.14.3/setup.cfg +xkcdpass-1.14.3/setup.py +xkcdpass-1.14.3/tests/ +xkcdpass-1.14.3/tests/test_list.txt +xkcdpass-1.14.3/tests/test_xkcdpass.py +xkcdpass-1.14.3/tests/__init__.py +xkcdpass-1.14.3/xkcdpass/ +xkcdpass-1.14.3/xkcdpass/static/ +xkcdpass-1.14.3/xkcdpass/static/eff-long +xkcdpass-1.14.3/xkcdpass/static/eff-short +xkcdpass-1.14.3/xkcdpass/static/eff-special +xkcdpass-1.14.3/xkcdpass/static/fin-kotus +xkcdpass-1.14.3/xkcdpass/static/ita-wiki +xkcdpass-1.14.3/xkcdpass/static/legacy +xkcdpass-1.14.3/xkcdpass/static/spa-mich +xkcdpass-1.14.3/xkcdpass/xkcd_password.py +xkcdpass-1.14.3/xkcdpass/__init__.py +xkcdpass-1.14.3/xkcdpass.1 +xkcdpass-1.14.3/xkcdpass.egg-info/ +xkcdpass-1.14.3/xkcdpass.egg-info/dependency_links.txt +xkcdpass-1.14.3/xkcdpass.egg-info/entry_points.txt +xkcdpass-1.14.3/xkcdpass.egg-info/not-zip-safe +xkcdpass-1.14.3/xkcdpass.egg-info/PKG-INFO +xkcdpass-1.14.3/xkcdpass.egg-info/SOURCES.txt +xkcdpass-1.14.3/xkcdpass.egg-info/top_level.txt + + +root@kerneltalks # cd xkcdpass-1.14.3 + +root@kerneltalks # python setup.py install +running install +running bdist_egg +running egg_info +writing xkcdpass.egg-info/PKG-INFO +writing top-level names to xkcdpass.egg-info/top_level.txt +writing dependency_links to xkcdpass.egg-info/dependency_links.txt +writing entry points to xkcdpass.egg-info/entry_points.txt +reading manifest file 'xkcdpass.egg-info/SOURCES.txt' +reading manifest template 'MANIFEST.in' +writing manifest file 'xkcdpass.egg-info/SOURCES.txt' +installing library code to build/bdist.linux-x86_64/egg +running install_lib +running build_py +creating build +creating build/lib +creating build/lib/xkcdpass +copying xkcdpass/xkcd_password.py -> build/lib/xkcdpass +copying xkcdpass/__init__.py -> build/lib/xkcdpass +creating build/lib/xkcdpass/static +copying xkcdpass/static/eff-long -> build/lib/xkcdpass/static +copying xkcdpass/static/eff-short -> build/lib/xkcdpass/static +copying xkcdpass/static/eff-special -> build/lib/xkcdpass/static +copying xkcdpass/static/fin-kotus -> build/lib/xkcdpass/static +copying xkcdpass/static/ita-wiki -> build/lib/xkcdpass/static +copying xkcdpass/static/legacy -> build/lib/xkcdpass/static +copying xkcdpass/static/spa-mich -> build/lib/xkcdpass/static +creating build/bdist.linux-x86_64 +creating build/bdist.linux-x86_64/egg +creating build/bdist.linux-x86_64/egg/xkcdpass +copying build/lib/xkcdpass/xkcd_password.py -> build/bdist.linux-x86_64/egg/xkcdpass +copying build/lib/xkcdpass/__init__.py -> build/bdist.linux-x86_64/egg/xkcdpass +creating build/bdist.linux-x86_64/egg/xkcdpass/static +copying build/lib/xkcdpass/static/eff-long -> build/bdist.linux-x86_64/egg/xkcdpass/static +copying build/lib/xkcdpass/static/eff-short -> build/bdist.linux-x86_64/egg/xkcdpass/static +copying build/lib/xkcdpass/static/eff-special -> build/bdist.linux-x86_64/egg/xkcdpass/static +copying build/lib/xkcdpass/static/fin-kotus -> build/bdist.linux-x86_64/egg/xkcdpass/static +copying build/lib/xkcdpass/static/ita-wiki -> build/bdist.linux-x86_64/egg/xkcdpass/static +copying build/lib/xkcdpass/static/legacy -> build/bdist.linux-x86_64/egg/xkcdpass/static +copying build/lib/xkcdpass/static/spa-mich -> build/bdist.linux-x86_64/egg/xkcdpass/static +byte-compiling build/bdist.linux-x86_64/egg/xkcdpass/xkcd_password.py to xkcd_password.pyc +byte-compiling build/bdist.linux-x86_64/egg/xkcdpass/__init__.py to __init__.pyc +creating build/bdist.linux-x86_64/egg/EGG-INFO +copying xkcdpass.egg-info/PKG-INFO -> build/bdist.linux-x86_64/egg/EGG-INFO +copying xkcdpass.egg-info/SOURCES.txt -> build/bdist.linux-x86_64/egg/EGG-INFO +copying xkcdpass.egg-info/dependency_links.txt -> build/bdist.linux-x86_64/egg/EGG-INFO +copying xkcdpass.egg-info/entry_points.txt -> build/bdist.linux-x86_64/egg/EGG-INFO +copying xkcdpass.egg-info/not-zip-safe -> build/bdist.linux-x86_64/egg/EGG-INFO +copying xkcdpass.egg-info/top_level.txt -> build/bdist.linux-x86_64/egg/EGG-INFO +creating dist +creating 'dist/xkcdpass-1.14.3-py2.7.egg' and adding 'build/bdist.linux-x86_64/egg' to it +removing 'build/bdist.linux-x86_64/egg' (and everything under it) +Processing xkcdpass-1.14.3-py2.7.egg +creating /usr/lib/python2.7/site-packages/xkcdpass-1.14.3-py2.7.egg +Extracting xkcdpass-1.14.3-py2.7.egg to /usr/lib/python2.7/site-packages +Adding xkcdpass 1.14.3 to easy-install.pth file +Installing xkcdpass script to /usr/bin + +Installed /usr/lib/python2.7/site-packages/xkcdpass-1.14.3-py2.7.egg +Processing dependencies for xkcdpass==1.14.3 +Finished processing dependencies for xkcdpass==1.14.3 +``` + +现在运行 xkcdpass 命令,将会随机给出你几个像下面这样的字典单词 - + +```bash +root@kerneltalks # xkcdpass +broadside unpadded osmosis statistic cosmetics lugged +``` + +你可以用这些单词作为其他命令,比如 `md5sum` 的输入,来获取随机密码(就像下面这样),甚至你也可以用每个单词的第 N 个字母来生成你的密码! + +```bash +root@kerneltalks # xkcdpass |md5sum +45f2ec9b3ca980c7afbd100268c74819 - + +root@kerneltalks # xkcdpass |md5sum +ad79546e8350744845c001d8836f2ff2 - +``` +或者你甚至可以把所有单词串在一起作为一个超长的密码,不仅非常好记,也不容易被电脑程序攻破。 + +Linux 上还有像 [Diceware][10], [KeePassX][11], [Revelation][12], [PasswordMaker][13] 这样的工具,也可以考虑用来生成强随机密码。 + +-------------------------------------------------------------------------------- + +via: https://kerneltalks.com/tips-tricks/8-ways-to-generate-random-password-in-linux/ + +作者:[kerneltalks][a] +译者:[heart4lor](https://github.com/heart4lor) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://kerneltalks.com +[1]:https://a1.kerneltalks.com/wp-content/uploads/2018/01/different-ways-to-generate-password-in-linux.png +[2]:https://kerneltalks.com/commands/learn-dd-command-with-examples/ +[3]:https://kerneltalks.com/commands/date-time-management-using-timedatectl-command/ +[4]:https://kerneltalks.com/linux/cut-command-examples/ +[5]:https://kerneltalks.com/package/how-to-install-epel-repository/ +[6]:https://kerneltalks.com/tools/package-installation-linux-yum-apt/ +[7]:https://xkcd.com/ +[8]:https://xkcd.com/936/ +[9]:https://pypi.python.org/pypi/xkcdpass/ +[10]:http://world.std.com/~reinhold/diceware.html +[11]:https://www.keepassx.org/ +[12]:https://packages.debian.org/sid/gnome/revelation +[13]:https://passwordmaker.org/ From d30372cdd4647ba0c342576532c8c21d6299375e Mon Sep 17 00:00:00 2001 From: wxy Date: Tue, 30 Jan 2018 22:32:35 +0800 Subject: [PATCH 066/272] PRF:20170921 Mastering file searches on Linux.md @jessie-pang --- ...170921 Mastering file searches on Linux.md | 65 +++++++------------ 1 file changed, 25 insertions(+), 40 deletions(-) diff --git a/translated/tech/20170921 Mastering file searches on Linux.md b/translated/tech/20170921 Mastering file searches on Linux.md index e964a35a64..2740e6a783 100644 --- a/translated/tech/20170921 Mastering file searches on Linux.md +++ b/translated/tech/20170921 Mastering file searches on Linux.md @@ -7,52 +7,49 @@ * 快速搜索 * 更复杂的搜索条件 - * 连接条件 + * 组合条件 * 反转条件 * 简单和详细的回应 * 寻找重复的文件 -有很多有用的命令可以搜索文件,**find** 命令可能是其中最有名的,但它不是唯一的命令,也不一定总是找到目标文件的最快方法。 +有很多有用的命令可以搜索文件,`find` 命令可能是其中最有名的,但它不是唯一的命令,也不一定总是找到目标文件的最快方法。 ### 快速搜索命令:which 和 locate -搜索文件的最简单的命令可能就是 **which** 和 **locate** 了,但二者都有一些局限性。**which** 命令只会在系统定义的搜索路径中,查找可执行的文件,通常用于识别命令。如果您对输入 which 时会运行的命令感到好奇,您可以使用命令 which which,它会指向对应的可执行文件。 +搜索文件的最简单的命令可能就是 `which` 和 `locate` 了,但二者都有一些局限性。`which` 命令只会在系统定义的搜索路径中,查找可执行的文件,通常用于识别命令。如果您对输入 `which` 时会运行哪个命令感到好奇,您可以使用命令 `which which`,它会指出对应的可执行文件。 ``` $ which which /usr/bin/which - ``` -**which** 命令会显示它找到的第一个以相应名称命名的可执行文件(也就是使用该命令时将运行的那个文件),然后停止。 +`which` 命令会显示它找到的第一个以相应名称命名的可执行文件(也就是使用该命令时将运行的那个文件),然后停止。 -**locate** 命令更大方一点,它可以查找任意数量的文件,但它也有一个限制:仅当文件名被包含在由 **updatedb** 命令准备的数据库时才有效。该文件可能会存储在某个位置,如 /var/lib/mlocate/mlocate.db,但不能用 locate 以外的任何命令读取。这个文件的更新通常是通过每天通过 cron 运行的 updatedb 进行的。 +`locate` 命令更大方一点,它可以查找任意数量的文件,但它也有一个限制:仅当文件名被包含在由 `updatedb` 命令构建的数据库时才有效。该文件可能会存储在某个位置,如 `/var/lib/mlocate/mlocate.db`,但不能用 `locate` 以外的任何命令读取。这个文件的更新通常是通过每天通过 cron 运行的 `updatedb` 进行的。 -简单的 **find** 命令不需要太多限制,不过它需要搜索的起点和指定搜索条件。最简单的 find 命令:按文件名搜索文件。如下所示: +简单的 `find` 命令没有太多限制,不过它需要指定搜索的起点和搜索条件。最简单的 `find` 命令:按文件名搜索文件。如下所示: ``` $ find . -name runme ./bin/runme - ``` 如上所示,通过文件名搜索文件系统的当前位置将会搜索所有子目录,除非您指定了搜索深度。 ### 不仅仅是文件名 -**find** 命令允许您搜索除文件名以外的多种条件,包括文件所有者、组、权限、大小、修改时间、缺少所有者或组和文件类型等。除了查找文件外,您还可以删除文件、对其进行重命名、更改所有者、更改权限和对文件运行几乎任何命令。 +`find` 命令允许您搜索除文件名以外的多种条件,包括文件所有者、组、权限、大小、修改时间、缺少所有者或组,和文件类型等。除了查找文件外,您还可以删除文件、对其进行重命名、更改所有者、更改权限和对找到的文件运行几乎任何命令。 -下面两条命令会查找:在当前目录中 root 用户拥有的文件,以及非指定用户(在本例中为 shs)拥有的文件。在这个例子中,两个输出是一样的,但并不总是如此。 +下面两条命令会查找:在当前目录中 root 用户拥有的文件,以及不被指定用户(在本例中为 shs)所拥有的文件。在这个例子中,两个输出是一样的,但并不总是如此。 ``` $ find . -user root -ls 396926 0 lrwxrwxrwx 1 root root 21 Sep 21 09:03 ./xyz -> /home/peanut/xyz $ find . ! -user shs -ls 396926 0 lrwxrwxrwx 1 root root 21 Sep 21 09:03 ./xyz -> /home/peanut/xyz - ``` -感叹号“!”字符代表“非”:反转跟随其后的条件。 +感叹号 `!` 字符代表“非”:反转跟随其后的条件。 下面的命令将查找具有特定权限的文件: @@ -61,7 +58,6 @@ $ find . -perm 750 -ls 397176 4 -rwxr-x--- 1 shs shs 115 Sep 14 13:52 ./ll 398209 4 -rwxr-x--- 1 shs shs 117 Sep 21 08:55 ./get-updates 397145 4 drwxr-x--- 2 shs shs 4096 Sep 14 15:42 ./newdir - ``` 接下来的命令显示具有 777 权限的非符号链接文件: @@ -70,19 +66,17 @@ $ find . -perm 750 -ls $ sudo find /home -perm 777 ! -type l -ls 397132 4 -rwxrwxrwx 1 shs shs 18 Sep 15 16:06 /home/shs/bin/runme 396949 4 -rwxrwxrwx 1 root root 558 Sep 21 11:21 /home/oops - ``` -以下命令将查找大小超过千兆字节的文件。请注意,我们找到了一个非常有趣的文件。它在 ELF 核心文件格式中代表该系统的物理内存。 +以下命令将查找大小超过千兆字节的文件。请注意,我们找到了一个非常有趣的文件。它以 ELF core 文件格式表示了该系统的物理内存。 ``` $ sudo find / -size +1G -ls 4026531994 0 -r-------- 1 root root 140737477881856 Sep 21 11:23 /proc/kcore 1444722 15332 -rw-rw-r-- 1 shs shs 1609039872 Sep 13 15:55 /home/shs/Downloads/ubuntu-17.04-desktop-amd64.iso - ``` -只要您知道 find 命令是如何描述文件类型的,就可以通过文件类型来查找文件。 +只要您知道 `find` 命令是如何描述文件类型的,就可以通过文件类型来查找文件。 ``` b = 块设备文件 @@ -93,7 +87,6 @@ f = 常规文件 l = 符号链接 s = 套接字 D = 门(仅限 Solaris) - ``` 在下面的命令中,我们要寻找符号链接和套接字: @@ -103,28 +96,25 @@ $ find . -type l -ls 396926 0 lrwxrwxrwx 1 root root 21 Sep 21 09:03 ./whatever -> /home/peanut/whatever $ find . -type s -ls 395256 0 srwxrwxr-x 1 shs shs 0 Sep 21 08:50 ./.gnupg/S.gpg-agent - ``` -您还可以根据 inode 数字来搜索文件: +您还可以根据 inode 号来搜索文件: ``` $ find . -inum 397132 -ls 397132 4 -rwx------ 1 shs shs 18 Sep 15 16:06 ./bin/runme - ``` -另一种通过 inode 搜索文件的方法是使用 **debugfs** 命令。在大的文件系统上,这个命令可能比 find 快得多,您可能需要安装 icheck。 +另一种通过 inode 搜索文件的方法是使用 `debugfs` 命令。在大的文件系统上,这个命令可能比 `find` 快得多,您可能需要安装 icheck。 ``` $ sudo debugfs -R 'ncheck 397132' /dev/sda1 debugfs 1.42.13 (17-May-2015) Inode Pathname 397132 /home/shs/bin/runme - ``` -在下面的命令中,我们从主目录(〜)开始,限制搜索的深度(是我们将搜索子目录的层数),并只查看在最近一天内创建或修改的文件(mtime 设置)。 +在下面的命令中,我们从主目录(`~`)开始,限制搜索的深度(即我们将搜索子目录的层数),并只查看在最近一天内创建或修改的文件(`mtime` 设置)。 ``` $ find ~ -maxdepth 2 -mtime -1 -ls @@ -132,29 +122,28 @@ $ find ~ -maxdepth 2 -mtime -1 -ls 394006 8 -rw------- 1 shs shs 5909 Sep 21 08:18 /home/shs/.bash_history 399612 4 -rw------- 1 shs shs 53 Sep 21 08:50 /home/shs/.Xauthority 399615 4 drwxr-xr-x 2 shs shs 4096 Sep 21 09:32 /home/shs/Downloads - ``` ### 不仅仅是列出文件 -使用 **-exec** 选项,在您使用 find 命令找到文件后可以以某种方式更改文件。您只需参照 -exec 选项即可运行相应的命令。 +使用 `-exec` 选项,在您使用 `find` 命令找到文件后可以以某种方式更改文件。您只需参照 `-exec` 选项即可运行相应的命令。 ``` $ find . -name runme -exec chmod 700 {} \; $ find . -name runme -ls 397132 4 -rwx------ 1 shs shs 18 Sep 15 16:06 ./bin/runme - ``` -在这条命令中,“{}”代表文件名。此命令将更改当前目录和子目录中任何名为“runme”的文件的权限。 +在这条命令中,`{}` 代表文件名。此命令将更改当前目录和子目录中任何名为 `runme` 的文件的权限。 -把您想运行的任何命令放在 -exec 选项之后,并使用类似于上面命令的语法即可。 +把您想运行的任何命令放在 `-exec` 选项之后,并使用类似于上面命令的语法即可。 ### 其他搜索条件 如上面的例子所示,您还可以通过其他条件进行搜索:文件的修改时间、所有者、权限等。以下是一些示例。 #### 根据用户查找文件 + ``` $ sudo find /home -user peanut /home/peanut @@ -162,23 +151,22 @@ $ sudo find /home -user peanut /home/peanut/.bash_logout /home/peanut/.profile /home/peanut/examples.desktop - ``` -#### 根据权限查找文件 +#### 根据权限查找文件 + ``` $ sudo find /home -perm 777 /home/shs/whatever /home/oops - ``` #### 根据修改时间查找文件 + ``` $ sudo find /home -mtime +100 /home/shs/.mozilla/firefox/krsw3giq.default/gmp-gmpopenh264/1.6/gmpopenh264.info /home/shs/.mozilla/firefox/krsw3giq.default/gmp-gmpopenh264/1.6/libgmpopenh264.so - ``` #### 通过比较修改时间查找文件 @@ -188,12 +176,11 @@ $ sudo find /home -mtime +100 ``` $ sudo find /var/log -newer /var/log/syslog /var/log/auth.log - ``` ### 寻找重复的文件 -如果您正在清理磁盘空间,则可能需要删除较大的重复文件。确定文件是否真正重复的最好方法是使用 **fdupes** 命令。此命令使用 md5 校验和来确定文件是否具有相同的内容。使用 -r(递归)选项,fdupes 将在一个目录下并查找具有相同校验和而被确定为内容相同的文件。 +如果您正在清理磁盘空间,则可能需要删除较大的重复文件。确定文件是否真正重复的最好方法是使用 `fdupes` 命令。此命令使用 md5 校验和来确定文件是否具有相同的内容。使用 `-r`(递归)选项,`fdupes` 将在一个目录下并查找具有相同校验和而被确定为内容相同的文件。 如果以 root 身份运行这样的命令,您可能会发现很多重复的文件,但是很多文件都是创建时被添加到主目录的启动文件。 @@ -209,25 +196,23 @@ $ sudo find /var/log -newer /var/log/syslog /home/tsmith/.bashrc /home/peanut/.bashrc /home/rocket/.bashrc - ``` -同样,您可能会在 /usr 中发现很多重复的但不该删除的配置文件。所以,请谨慎利用 fdupes 的输出。 +同样,您可能会在 `/usr` 中发现很多重复的但不该删除的配置文件。所以,请谨慎利用 `fdupes` 的输出。 -fdupes 命令并不总是很快,但是要记住,它正在对许多文件运行校验和来做比较,你可能会意识到它的有效性。 +`fdupes` 命令并不总是很快,但是要记住,它正在对许多文件运行校验和来做比较,你可能会意识到它是多么有效。 ### 总结 有很多方法可以在 Linux 系统上查找文件。如果您可以描述清楚您正在寻找什么,上面的命令将帮助您找到目标。 - -------------------------------------------------------------------------------- via: https://www.networkworld.com/article/3227075/linux/mastering-file-searches-on-linux.html 作者:[Sandra Henry-Stocker][a] 译者:[jessie-pang](https://github.com/jessie-pang) -校对:[校对者ID](https://github.com/校对者ID) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 From be3e623665521ee478bd88c2383dff1aa7c942b9 Mon Sep 17 00:00:00 2001 From: wxy Date: Tue, 30 Jan 2018 22:33:03 +0800 Subject: [PATCH 067/272] PUB:20170921 Mastering file searches on Linux.md @jessie-pang https://linux.cn/article-9295-1.html --- .../20170921 Mastering file searches on Linux.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename {translated/tech => published}/20170921 Mastering file searches on Linux.md (100%) diff --git a/translated/tech/20170921 Mastering file searches on Linux.md b/published/20170921 Mastering file searches on Linux.md similarity index 100% rename from translated/tech/20170921 Mastering file searches on Linux.md rename to published/20170921 Mastering file searches on Linux.md From 79f2c1519195514f5ba8534fc27456a2d11e7328 Mon Sep 17 00:00:00 2001 From: wxy Date: Tue, 30 Jan 2018 22:46:30 +0800 Subject: [PATCH 068/272] PRF&PUB:20170526 Creating a YUM repository from ISO - Online repo.md @geekpi https://linux.cn/article-9296-1.html --- ...a YUM repository from ISO - Online repo.md | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) rename {translated/tech => published}/20170526 Creating a YUM repository from ISO - Online repo.md (56%) diff --git a/translated/tech/20170526 Creating a YUM repository from ISO - Online repo.md b/published/20170526 Creating a YUM repository from ISO - Online repo.md similarity index 56% rename from translated/tech/20170526 Creating a YUM repository from ISO - Online repo.md rename to published/20170526 Creating a YUM repository from ISO - Online repo.md index a483766ddf..2e11780ac4 100644 --- a/translated/tech/20170526 Creating a YUM repository from ISO - Online repo.md +++ b/published/20170526 Creating a YUM repository from ISO - Online repo.md @@ -1,18 +1,18 @@ -从 ISO 和在线仓库创建一个 YUM 仓库 +从 ISO 和在线仓库创建一个 Yum 仓库 ====== -YUM 是 Centos/RHEL/Fedora 中最重要的工具之一。尽管在 Fedora 的最新版本中,它已经被 DNF 所取代,但这并不意味着它已经成功了。它仍然被广泛用于安装 rpm 包,我们已经在前面的教程([**在这里阅读**] [1])中用示例讨论了 YUM。 +Yum 是 Centos/RHEL/Fedora 中最重要的工具之一。尽管在 Fedora 的最新版本中,它已经被 DNF 所取代,但这并不意味着它自生自灭了。它仍然被广泛用于安装 rpm 包,我们已经在前面的教程([**在这里阅读**] [1])中用示例讨论了 Yum。 -在本教程中,我们将学习创建一个本地 YUM 仓库,首先使用系统的 ISO 镜像,然后创建一个在线 yum 仓库的镜像。 +在本教程中,我们将学习创建一个本地 Yum 仓库,首先使用系统的 ISO 镜像,然后创建一个在线 Yum 仓库的镜像。 -### 用 DVD ISO 创建 YUM +### 用 DVD ISO 创建 Yum 我们在本教程中使用 Centos 7 dvd,同样的过程也应该可以用在 RHEL 7 上。 -首先在根文件夹中创建一个名为 YUM 的目录 +首先在根文件夹中创建一个名为 Yum 的目录 ``` -$ mkdir /YUM- +$ mkdir /YUM ``` 然后挂载 Centos 7 ISO: @@ -21,7 +21,7 @@ $ mkdir /YUM- $ mount -t iso9660 -o loop /home/dan/Centos-7-x86_x64-DVD.iso /mnt/iso/ ``` -接下来,从挂载的 ISO 中复制软件包到 /YUM 中。当所有的软件包都被复制到系统中后,我们将安装创建 YUM 所需的软件包。打开 /YUM 并安装以下 RPM 包: +接下来,从挂载的 ISO 中复制软件包到 `/YUM` 中。当所有的软件包都被复制到系统中后,我们将安装创建 Yum 所需的软件包。打开 `/YUM` 并安装以下 RPM 包: ``` $ rpm -ivh deltarpm @@ -29,7 +29,7 @@ $ rpm -ivh python-deltarpm $ rpm -ivh createrepo ``` -安装完成后,我们将在 **/etc/yum.repos.d** 中创建一个名 为 **“local.repo”** 的文件,其中包含所有的 yum 信息。 +安装完成后,我们将在 `/etc/yum.repos.d` 中创建一个名 为 `local.repo` 的文件,其中包含所有的 Yum 信息。 ``` $ vi /etc/yum.repos.d/local.repo @@ -49,28 +49,28 @@ enabled=1 $ createrepo -v /YUM ``` -创建仓库数据需要一些时间。一切完成后,请运行 +创建仓库数据需要一些时间。一切完成后,请运行: ``` $ yum clean all ``` -清理缓存,然后运行 +清理缓存,然后运行: ``` $ yum repolist ``` -检查所有仓库列表。你应该在列表中看到 “local.repo”。 +检查所有仓库列表。你应该在列表中看到 `local.repo`。 -### 使用在线仓库创建镜像 YUM 仓库 +### 使用在线仓库创建镜像 Yum 仓库 -创建在线 yum 的过程与使用 ISO 镜像创建 yum 类似,只是我们将从在线仓库而不是 ISO 中获取 rpm 软件包。 +创建在线 Yum 的过程与使用 ISO 镜像创建 Yum 类似,只是我们将从在线仓库而不是 ISO 中获取 rpm 软件包。 -首先,我们需要找到一个在线仓库来获取最新的软件包。建议你找一个离你位置最近的在线 yum 仓库,以优化下载速度。我们将使用下面的镜像,你可以从[ CENTOS 镜像列表][2]中选择一个离你最近的镜像。 +首先,我们需要找到一个在线仓库来获取最新的软件包。建议你找一个离你位置最近的在线 Yum 仓库,以优化下载速度。我们将使用下面的镜像,你可以从 [CENTOS 镜像列表][2]中选择一个离你最近的镜像。 -选择镜像之后,我们将使用 rsync 将该镜像与我们的系统同步,但在此之前,请确保你服务器上有足够的空间。 +选择镜像之后,我们将使用 `rsync` 将该镜像与我们的系统同步,但在此之前,请确保你服务器上有足够的空间。 ``` $ rsync -avz rsync://mirror.fibergrid.in/centos/7.2/os/x86_64/Packages/s/ /YUM @@ -96,9 +96,9 @@ $ crontab -e 30 12 * * * rsync -avz http://mirror.centos.org/centos/7/os/x86_64/Packages/ /YUM ``` -这会在每晚 12:30 同步 yum。还请记住在 /etc/yum.repos.d 中创建仓库配置文件,就像我们上面所做的一样。 +这会在每晚 12:30 同步 Yum。还请记住在 `/etc/yum.repos.d` 中创建仓库配置文件,就像我们上面所做的一样。 -就是这样,你现在有你自己的 yum 仓库来使用。如果你喜欢它,请分享这篇文章,并在下面的评论栏留下你的意见/疑问。 +就是这样,你现在使用你自己的 Yum 仓库了。如果你喜欢它,请分享这篇文章,并在下面的评论栏留下你的意见/疑问。 -------------------------------------------------------------------------------- @@ -107,7 +107,7 @@ via: http://linuxtechlab.com/creating-yum-repository-iso-online-repo/ 作者:[Shusain][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 179b5b5f8ab6ae9b6b78439905feab4e24b4c730 Mon Sep 17 00:00:00 2001 From: GitFuture <752736341@qq.com> Date: Tue, 30 Jan 2018 23:06:18 +0800 Subject: [PATCH 069/272] Finish Translation --- ...t-s Build A Simple Interpreter. Part 3..md | 342 ------------------ ...t-s Build A Simple Interpreter. Part 3..md | 336 +++++++++++++++++ 2 files changed, 336 insertions(+), 342 deletions(-) delete mode 100644 sources/tech/20150812 Let-s Build A Simple Interpreter. Part 3..md create mode 100644 translated/tech/20150812 Let-s Build A Simple Interpreter. Part 3..md diff --git a/sources/tech/20150812 Let-s Build A Simple Interpreter. Part 3..md b/sources/tech/20150812 Let-s Build A Simple Interpreter. Part 3..md deleted file mode 100644 index d9deb9f50e..0000000000 --- a/sources/tech/20150812 Let-s Build A Simple Interpreter. Part 3..md +++ /dev/null @@ -1,342 +0,0 @@ -BriFuture is Translating this article - -Let’s Build A Simple Interpreter. Part 3. -====== - -I woke up this morning and I thought to myself: "Why do we find it so difficult to learn a new skill?" - -I don't think it's just because of the hard work. I think that one of the reasons might be that we spend a lot of time and hard work acquiring knowledge by reading and watching and not enough time translating that knowledge into a skill by practicing it. Take swimming, for example. You can spend a lot of time reading hundreds of books about swimming, talk for hours with experienced swimmers and coaches, watch all the training videos available, and you still will sink like a rock the first time you jump in the pool. - -The bottom line is: it doesn't matter how well you think you know the subject - you have to put that knowledge into practice to turn it into a skill. To help you with the practice part I put exercises into [Part 1][1] and [Part 2][2] of the series. And yes, you will see more exercises in today's article and in future articles, I promise :) - -Okay, let's get started with today's material, shall we? - - -So far, you've learned how to interpret arithmetic expressions that add or subtract two integers like "7 + 3" or "12 - 9". Today I'm going to talk about how to parse (recognize) and interpret arithmetic expressions that have any number of plus or minus operators in it, for example "7 - 3 + 2 - 1". - -Graphically, the arithmetic expressions in this article can be represented with the following syntax diagram: - -![][3] - -What is a syntax diagram? A **syntax diagram** is a graphical representation of a programming language 's syntax rules. Basically, a syntax diagram visually shows you which statements are allowed in your programming language and which are not. - -Syntax diagrams are pretty easy to read: just follow the paths indicated by the arrows. Some paths indicate choices. And some paths indicate loops. - -You can read the above syntax diagram as following: a term optionally followed by a plus or minus sign, followed by another term, which in turn is optionally followed by a plus or minus sign followed by another term and so on. You get the picture, literally. You might wonder what a "term" is. For the purpose of this article a "term" is just an integer. - -Syntax diagrams serve two main purposes: - - * They graphically represent the specification (grammar) of a programming language. - * They can be used to help you write your parser - you can map a diagram to code by following simple rules. - - - -You've learned that the process of recognizing a phrase in the stream of tokens is called **parsing**. And the part of an interpreter or compiler that performs that job is called a **parser**. Parsing is also called **syntax analysis** , and the parser is also aptly called, you guessed it right, a **syntax analyzer**. - -According to the syntax diagram above, all of the following arithmetic expressions are valid: - - * 3 - * 3 + 4 - * 7 - 3 + 2 - 1 - - - -Because syntax rules for arithmetic expressions in different programming languages are very similar we can use a Python shell to "test" our syntax diagram. Launch your Python shell and see for yourself: -``` ->>> 3 -3 ->>> 3 + 4 -7 ->>> 7 - 3 + 2 - 1 -5 -``` - -No surprises here. - -The expression "3 + " is not a valid arithmetic expression though because according to the syntax diagram the plus sign must be followed by a term (integer), otherwise it's a syntax error. Again, try it with a Python shell and see for yourself: -``` ->>> 3 + - File "", line 1 - 3 + - ^ -SyntaxError: invalid syntax -``` - -It's great to be able to use a Python shell to do some testing but let's map the above syntax diagram to code and use our own interpreter for testing, all right? - -You know from the previous articles ([Part 1][1] and [Part 2][2]) that the expr method is where both our parser and interpreter live. Again, the parser just recognizes the structure making sure that it corresponds to some specifications and the interpreter actually evaluates the expression once the parser has successfully recognized (parsed) it. - -The following code snippet shows the parser code corresponding to the diagram. The rectangular box from the syntax diagram (term) becomes a term method that parses an integer and the expr method just follows the syntax diagram flow: -``` -def term(self): - self.eat(INTEGER) - -def expr(self): - # set current token to the first token taken from the input - self.current_token = self.get_next_token() - - self.term() - while self.current_token.type in (PLUS, MINUS): - token = self.current_token - if token.type == PLUS: - self.eat(PLUS) - self.term() - elif token.type == MINUS: - self.eat(MINUS) - self.term() -``` - -You can see that expr first calls the term method. Then the expr method has a while loop which can execute zero or more times. And inside the loop the parser makes a choice based on the token (whether it's a plus or minus sign). Spend some time proving to yourself that the code above does indeed follow the syntax diagram flow for arithmetic expressions. - -The parser itself does not interpret anything though: if it recognizes an expression it's silent and if it doesn't, it throws out a syntax error. Let's modify the expr method and add the interpreter code: -``` -def term(self): - """Return an INTEGER token value""" - token = self.current_token - self.eat(INTEGER) - return token.value - -def expr(self): - """Parser / Interpreter """ - # set current token to the first token taken from the input - self.current_token = self.get_next_token() - - result = self.term() - while self.current_token.type in (PLUS, MINUS): - token = self.current_token - if token.type == PLUS: - self.eat(PLUS) - result = result + self.term() - elif token.type == MINUS: - self.eat(MINUS) - result = result - self.term() - - return result -``` - -Because the interpreter needs to evaluate an expression the term method was modified to return an integer value and the expr method was modified to perform addition and subtraction at the appropriate places and return the result of interpretation. Even though the code is pretty straightforward I recommend spending some time studying it. - -Le's get moving and see the complete code of the interpreter now, okay? - -Here is the source code for your new version of the calculator that can handle valid arithmetic expressions containing integers and any number of addition and subtraction operators: -``` -# Token types -# -# EOF (end-of-file) token is used to indicate that -# there is no more input left for lexical analysis -INTEGER, PLUS, MINUS, EOF = 'INTEGER', 'PLUS', 'MINUS', 'EOF' - - -class Token(object): - def __init__(self, type, value): - # token type: INTEGER, PLUS, MINUS, or EOF - self.type = type - # token value: non-negative integer value, '+', '-', or None - self.value = value - - def __str__(self): - """String representation of the class instance. - - Examples: - Token(INTEGER, 3) - Token(PLUS, '+') - """ - return 'Token({type}, {value})'.format( - type=self.type, - value=repr(self.value) - ) - - def __repr__(self): - return self.__str__() - - -class Interpreter(object): - def __init__(self, text): - # client string input, e.g. "3 + 5", "12 - 5 + 3", etc - self.text = text - # self.pos is an index into self.text - self.pos = 0 - # current token instance - self.current_token = None - self.current_char = self.text[self.pos] - - ########################################################## - # Lexer code # - ########################################################## - def error(self): - raise Exception('Invalid syntax') - - def advance(self): - """Advance the `pos` pointer and set the `current_char` variable.""" - self.pos += 1 - if self.pos > len(self.text) - 1: - self.current_char = None # Indicates end of input - else: - self.current_char = self.text[self.pos] - - def skip_whitespace(self): - while self.current_char is not None and self.current_char.isspace(): - self.advance() - - def integer(self): - """Return a (multidigit) integer consumed from the input.""" - result = '' - while self.current_char is not None and self.current_char.isdigit(): - result += self.current_char - self.advance() - return int(result) - - def get_next_token(self): - """Lexical analyzer (also known as scanner or tokenizer) - - This method is responsible for breaking a sentence - apart into tokens. One token at a time. - """ - while self.current_char is not None: - - if self.current_char.isspace(): - self.skip_whitespace() - continue - - if self.current_char.isdigit(): - return Token(INTEGER, self.integer()) - - if self.current_char == '+': - self.advance() - return Token(PLUS, '+') - - if self.current_char == '-': - self.advance() - return Token(MINUS, '-') - - self.error() - - return Token(EOF, None) - - ########################################################## - # Parser / Interpreter code # - ########################################################## - def eat(self, token_type): - # compare the current token type with the passed token - # type and if they match then "eat" the current token - # and assign the next token to the self.current_token, - # otherwise raise an exception. - if self.current_token.type == token_type: - self.current_token = self.get_next_token() - else: - self.error() - - def term(self): - """Return an INTEGER token value.""" - token = self.current_token - self.eat(INTEGER) - return token.value - - def expr(self): - """Arithmetic expression parser / interpreter.""" - # set current token to the first token taken from the input - self.current_token = self.get_next_token() - - result = self.term() - while self.current_token.type in (PLUS, MINUS): - token = self.current_token - if token.type == PLUS: - self.eat(PLUS) - result = result + self.term() - elif token.type == MINUS: - self.eat(MINUS) - result = result - self.term() - - return result - - -def main(): - while True: - try: - # To run under Python3 replace 'raw_input' call - # with 'input' - text = raw_input('calc> ') - except EOFError: - break - if not text: - continue - interpreter = Interpreter(text) - result = interpreter.expr() - print(result) - - -if __name__ == '__main__': - main() -``` - -Save the above code into the calc3.py file or download it directly from [GitHub][4]. Try it out. See for yourself that it can handle arithmetic expressions that you can derive from the syntax diagram I showed you earlier. - -Here is a sample session that I ran on my laptop: -``` -$ python calc3.py -calc> 3 -3 -calc> 7 - 4 -3 -calc> 10 + 5 -15 -calc> 7 - 3 + 2 - 1 -5 -calc> 10 + 1 + 2 - 3 + 4 + 6 - 15 -5 -calc> 3 + -Traceback (most recent call last): - File "calc3.py", line 147, in - main() - File "calc3.py", line 142, in main - result = interpreter.expr() - File "calc3.py", line 123, in expr - result = result + self.term() - File "calc3.py", line 110, in term - self.eat(INTEGER) - File "calc3.py", line 105, in eat - self.error() - File "calc3.py", line 45, in error - raise Exception('Invalid syntax') -Exception: Invalid syntax -``` - - -Remember those exercises I mentioned at the beginning of the article: here they are, as promised :) - -![][5] - - * Draw a syntax diagram for arithmetic expressions that contain only multiplication and division, for example "7 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 4 / 2 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 3". Seriously, just grab a pen or a pencil and try to draw one. - * Modify the source code of the calculator to interpret arithmetic expressions that contain only multiplication and division, for example "7 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 4 / 2 * 3". - * Write an interpreter that handles arithmetic expressions like "7 - 3 + 2 - 1" from scratch. Use any programming language you're comfortable with and write it off the top of your head without looking at the examples. When you do that, think about components involved: a lexer that takes an input and converts it into a stream of tokens, a parser that feeds off the stream of the tokens provided by the lexer and tries to recognize a structure in that stream, and an interpreter that generates results after the parser has successfully parsed (recognized) a valid arithmetic expression. String those pieces together. Spend some time translating the knowledge you've acquired into a working interpreter for arithmetic expressions. - - - -**Check your understanding.** - - 1. What is a syntax diagram? - 2. What is syntax analysis? - 3. What is a syntax analyzer? - - - - -Hey, look! You read all the way to the end. Thanks for hanging out here today and don't forget to do the exercises. :) I'll be back next time with a new article - stay tuned. - - --------------------------------------------------------------------------------- - -via: https://ruslanspivak.com/lsbasi-part3/ - -作者:[Ruslan Spivak][a] -译者:[译者ID](https://github.com/译者ID) -校对:[校对者ID](https://github.com/校对者ID) - -本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 - -[a]:https://ruslanspivak.com -[1]:http://ruslanspivak.com/lsbasi-part1/ (Part 1) -[2]:http://ruslanspivak.com/lsbasi-part2/ (Part 2) -[3]:https://ruslanspivak.com/lsbasi-part3/lsbasi_part3_syntax_diagram.png -[4]:https://github.com/rspivak/lsbasi/blob/master/part3/calc3.py -[5]:https://ruslanspivak.com/lsbasi-part3/lsbasi_part3_exercises.png diff --git a/translated/tech/20150812 Let-s Build A Simple Interpreter. Part 3..md b/translated/tech/20150812 Let-s Build A Simple Interpreter. Part 3..md new file mode 100644 index 0000000000..d50e5ce8f4 --- /dev/null +++ b/translated/tech/20150812 Let-s Build A Simple Interpreter. Part 3..md @@ -0,0 +1,336 @@ +让我们做个简单的解释器(3) +====== + +早上醒来的时候,我就在想:“为什么我们学习一个新技能这么难?” + +我不认为那是因为它很难。我认为原因可能在于我们花了太多的时间,而这件难事需要有丰富的阅历和足够的知识,然而我们要把这样的知识转换成技能所用的练习时间又不够。 +拿游泳来说,你可以花上几天时间来阅读很多有关游泳的书籍,花几个小时和资深的游泳者和教练交流,观看所有可以获得的训练视频,但你第一次跳进水池的时候,仍然会像一个石头那样沉入水中, + + +要点在于:你认为自己有多了解那件事都无关紧要 —— 你得通过练习把知识变成技能。为了帮你练习,我把训练放在了这个系列的 [第一部分][1] 和 [第二部分][2] 了。当然,你会在今后的文章中看到更多练习,我保证 :) + +好,让我们开始今天的学习。 + +到现在为止,你已经知道了怎样解释像 “7 + 3” 或者 “12 - 9” 这样的两个整数相加减的算术表达式。今天我要说的是怎么解析(识别)、解释有多个数字相加减的算术表达式,比如 “7 - 3 + 2 - 1”。 + +文中的这个算术表达式可以用下面的这个语法图表示: + +![][3] + +什么是语法图? **语法图** 是对一门编程语言中的语法规则进行图像化的表示。基本上,一个语法图就能告诉你哪些语句可以在程序中出现,哪些不能出现。 + +语法图很容易读懂:按照箭头指向的路径。某些路径表示的是判断,有些表示的是循环。 + +你可以按照以下的方式读上面的语法图:一个 term 后面可以是加号或者减号,接着可以是另一个 term,这个 term 后面又可以是一个加号或者减号,后面又是一个 term,如此循环。从字面上你就能读懂这个图片了。或许你会奇怪,“term” 是什么、对于本文来说,“term” 就是个整数。 + +语法图有两个主要的作用: + + * 它们用图形的方式表示一个编程语言的特性(语法)。 + * 它们可以用来帮你写出解析器 —— 你可以根据下列简单规则把图片转换成代码。 + + + +你已经知道,识别出记号流中的词组的过程就叫做 **解析**。解释器或者编译器执行这个任务的部分叫做 **解析器**。解析也称为 **语法分析**,并且解析器这个名字很合适,你猜的对,就是 **语法分析**。 + +根据上面的语法图,下面这些表达式都是合法的: + + * 3 + * 3 + 4 + * 7 - 3 + 2 - 1 + + + +因为算术表达式的语法规则在不同的编程语言里面是很相近的,我们可以用 Python shell 来“测试”语法图。打开 Python shell,运行下面的代码: +``` +>>> 3 +3 +>>> 3 + 4 +7 +>>> 7 - 3 + 2 - 1 +5 +``` + +意料之中。 + +表达式 “3 + ” 不是一个有效的数学表达式,根据语法图,加号后面必须要有个 term (整数),否则就是语法错误。然后,自己在 Python shell 里面运行: +``` +>>> 3 + + File "", line 1 + 3 + + ^ +SyntaxError: invalid syntax +``` + +能用 Python shell 来做这样的测试非常棒,让我们把上面的语法图转换成代码,用我们自己的解释器来测试,怎么样? + +从之前的文章里([第一部分][1] 和 [第二部分][2])你知道 expr 方法包含了我们的解析器和解释器。再说一遍,解析器仅仅识别出结构,确保它与某些特性对应,而解释器实际上是在解析器成功识别(解析)特性之后,就立即对表达式进行评估。 + +以下代码片段显示了对应于图表的解析器代码。语法图里面的矩形方框(term)变成了 term 方法,用于解析整数,expr 方法和语法图的流程一致: +``` +def term(self): + self.eat(INTEGER) + +def expr(self): + # 把当前标记设为从输入中拿到的第一个标记 + self.current_token = self.get_next_token() + + self.term() + while self.current_token.type in (PLUS, MINUS): + token = self.current_token + if token.type == PLUS: + self.eat(PLUS) + self.term() + elif token.type == MINUS: + self.eat(MINUS) + self.term() +``` + +你能看到 expr 首先调用了 term 方法。然后 expr 方法里面的 while 循环可以执行 0 或多次。在循环里面解析器基于标记做出判断(是加号还是减号)。花一些时间,你就知道,上述代码确实是遵循着语法图的算术表达式流程。 + +解析器并不解释任何东西:如果它识别出了一个表达式,它就静默着,如果没有识别出来,就会抛出一个语法错误。改一下 expr 方法,加入解释器的代码: +``` +def term(self): + """Return an INTEGER token value""" + token = self.current_token + self.eat(INTEGER) + return token.value + +def expr(self): + """Parser / Interpreter """ + # 将输入中的第一个标记设置成当前标记 + self.current_token = self.get_next_token() + + result = self.term() + while self.current_token.type in (PLUS, MINUS): + token = self.current_token + if token.type == PLUS: + self.eat(PLUS) + result = result + self.term() + elif token.type == MINUS: + self.eat(MINUS) + result = result - self.term() + + return result +``` + +因为解释器需要评估一个表达式, term 方法被改成返回一个整型值,expr 方法被改成在合适的地方执行加法或减法操作,并返回解释的结果。尽管代码很直白,我建议花点时间去理解它。 +进行下一步,看看完整的解释器代码,好不? + +这时新版计算器的源代码,它可以处理包含有任意多个加法和减法运算的有效的数学表达式。 +``` +# 标记类型 +# +# EOF (end-of-file 文件末尾) 标记是用来表示所有输入都解析完成 +INTEGER, PLUS, MINUS, EOF = 'INTEGER', 'PLUS', 'MINUS', 'EOF' + + +class Token(object): + def __init__(self, type, value): + # token 类型: INTEGER, PLUS, MINUS, or EOF + self.type = type + # token 值: 非负整数值, '+', '-', 或无 + self.value = value + + def __str__(self): + """String representation of the class instance. + + Examples: + Token(INTEGER, 3) + Token(PLUS, '+') + """ + return 'Token({type}, {value})'.format( + type=self.type, + value=repr(self.value) + ) + + def __repr__(self): + return self.__str__() + + +class Interpreter(object): + def __init__(self, text): + # 客户端字符输入, 例如. "3 + 5", "12 - 5", + self.text = text + # self.pos is an index into self.text + self.pos = 0 + # 当前标记实例 + self.current_token = None + self.current_char = self.text[self.pos] + + ########################################################## + # Lexer code # + ########################################################## + def error(self): + raise Exception('Invalid syntax') + + def advance(self): + """Advance the `pos` pointer and set the `current_char` variable.""" + self.pos += 1 + if self.pos > len(self.text) - 1: + self.current_char = None # Indicates end of input + else: + self.current_char = self.text[self.pos] + + def skip_whitespace(self): + while self.current_char is not None and self.current_char.isspace(): + self.advance() + + def integer(self): + """Return a (multidigit) integer consumed from the input.""" + result = '' + while self.current_char is not None and self.current_char.isdigit(): + result += self.current_char + self.advance() + return int(result) + + def get_next_token(self): + """Lexical analyzer (also known as scanner or tokenizer) + + This method is responsible for breaking a sentence + apart into tokens. One token at a time. + """ + while self.current_char is not None: + + if self.current_char.isspace(): + self.skip_whitespace() + continue + + if self.current_char.isdigit(): + return Token(INTEGER, self.integer()) + + if self.current_char == '+': + self.advance() + return Token(PLUS, '+') + + if self.current_char == '-': + self.advance() + return Token(MINUS, '-') + + self.error() + + return Token(EOF, None) + + ########################################################## + # Parser / Interpreter code # + ########################################################## + def eat(self, token_type): + # 将当前的标记类型与传入的标记类型作比较,如果他们相匹配,就 + # “eat” 掉当前的标记并将下一个标记赋给 self.current_token, + # 否则抛出一个异常 + if self.current_token.type == token_type: + self.current_token = self.get_next_token() + else: + self.error() + + def term(self): + """Return an INTEGER token value.""" + token = self.current_token + self.eat(INTEGER) + return token.value + + def expr(self): + """Arithmetic expression parser / interpreter.""" + # 将输入中的第一个标记设置成当前标记 + self.current_token = self.get_next_token() + + result = self.term() + while self.current_token.type in (PLUS, MINUS): + token = self.current_token + if token.type == PLUS: + self.eat(PLUS) + result = result + self.term() + elif token.type == MINUS: + self.eat(MINUS) + result = result - self.term() + + return result + + +def main(): + while True: + try: + # To run under Python3 replace 'raw_input' call + # 要在 Python3 下运行,请把 ‘raw_input’ 的调用换成 ‘input’ + text = raw_input('calc> ') + except EOFError: + break + if not text: + continue + interpreter = Interpreter(text) + result = interpreter.expr() + print(result) + + +if __name__ == '__main__': + main() +``` + +把上面的代码保存到 calc3.py 文件中,或者直接从 [GitHub][4] 上下载。试着运行它。看看它能不能处理我之前给你看过的语法图里面派生出的数学表达式。 + +这是我在自己的笔记本上运行的示例: +``` +$ python calc3.py +calc> 3 +3 +calc> 7 - 4 +3 +calc> 10 + 5 +15 +calc> 7 - 3 + 2 - 1 +5 +calc> 10 + 1 + 2 - 3 + 4 + 6 - 15 +5 +calc> 3 + +Traceback (most recent call last): + File "calc3.py", line 147, in + main() + File "calc3.py", line 142, in main + result = interpreter.expr() + File "calc3.py", line 123, in expr + result = result + self.term() + File "calc3.py", line 110, in term + self.eat(INTEGER) + File "calc3.py", line 105, in eat + self.error() + File "calc3.py", line 45, in error + raise Exception('Invalid syntax') +Exception: Invalid syntax +``` + + +记得我在文章开始时提过的练习吗:他们在这儿,我保证过的:) + +![][5] + + * 画出只包含乘法和除法的数学表达式的语法图,比如 “7 * 4 / 2 * 3”。认真点,拿只钢笔或铅笔,试着画一个。 + 修改计算器的源代码,解释只包含乘法和除法的数学表达式。比如 “7 * 4 / 2 * 3”。 + * 从头写一个可以处理像 “7 - 3 + 2 - 1” 这样的数学表达式的解释器。用你熟悉的编程语言,不看示例代码自己思考着写出代码。做的时候要想一想这里面包含的组件:一个 lexer,读取输入并转换成标记流,一个解析器,从 lexer 提供的记号流中取食,并且尝试识别流中的结构,一个解释器,在解析器成功解析(识别)有效的数学表达式后产生结果。把这些要点串起来。花一点时间把你获得的知识变成一个可以运行的数学表达式的解释器。 + + +**检验你的理解。** + + 1. 什么是语法图? + 2. 什么是语法分析? + 3. 什么是语法分析器? + + + + +嘿,看!你看完了所有内容。感谢你们坚持到今天,而且没有忘记练习。:) 下次我会带着新的文章回来,尽请期待。 + +-------------------------------------------------------------------------------- + +via: https://ruslanspivak.com/lsbasi-part3/ + +作者:[Ruslan Spivak][a] +译者:[译者ID](https://github.com/译者ID) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://ruslanspivak.com +[1]:http://ruslanspivak.com/lsbasi-part1/ (Part 1) +[2]:http://ruslanspivak.com/lsbasi-part2/ (Part 2) +[3]:https://ruslanspivak.com/lsbasi-part3/lsbasi_part3_syntax_diagram.png +[4]:https://github.com/rspivak/lsbasi/blob/master/part3/calc3.py +[5]:https://ruslanspivak.com/lsbasi-part3/lsbasi_part3_exercises.png From 2d1a953b4ed9096063dd4e2e3a1ede8d78e4cd11 Mon Sep 17 00:00:00 2001 From: wxy Date: Tue, 30 Jan 2018 23:15:40 +0800 Subject: [PATCH 070/272] PRF&PUB:20171123 Check Cryptocurrency Prices From Commandline @geekpi --- ... Cryptocurrency Prices From Commandline.md | 31 +++++++++++-------- 1 file changed, 18 insertions(+), 13 deletions(-) rename {translated/tech => published}/20171123 Check Cryptocurrency Prices From Commandline.md (65%) diff --git a/translated/tech/20171123 Check Cryptocurrency Prices From Commandline.md b/published/20171123 Check Cryptocurrency Prices From Commandline.md similarity index 65% rename from translated/tech/20171123 Check Cryptocurrency Prices From Commandline.md rename to published/20171123 Check Cryptocurrency Prices From Commandline.md index ba4a7bdefe..065984bc7d 100644 --- a/translated/tech/20171123 Check Cryptocurrency Prices From Commandline.md +++ b/published/20171123 Check Cryptocurrency Prices From Commandline.md @@ -1,13 +1,16 @@ -从命令行查看加密货币价格 +用命令行查看比特币等加密货币价格 ====== + ![配图](https://www.ostechnix.com/wp-content/uploads/2017/11/bitcoin-1-720x340.jpg) -前段时间,我们发布了一个关于 **[Cli-Fyi][1] ** 的指南 - 一个潜在有用的命令行查询工具。使用 Cli-Fyi,我们可以很容易地了解加密货币的最新价格和许多其他有用的细节。今天,我们将看到另一个名为 **“Coinmon”** 的加密货币价格查看工具。不像 Cli.Fyi,Coinmon 只能用来查看不同加密货币的价格。没有其他功能!Coinmon 会检查加密货币的价格,并立即直接从你的终端修改价格。它将从 [coinmarketcap.com][2] API 获取所有详细信息。对于那些 **加密货币投资者**和**工程师**来说是非常有用的。 + +前段时间,我们发布了一个关于 [Cli-Fyi][1] 的指南 - 一个可能有用的命令行查询工具。使用 Cli-Fyi,我们可以很容易地了解加密货币的最新价格和许多其他有用的细节。今天,我们将看到另一个名为 “Coinmon” 的加密货币价格查看工具。不像 Cli.Fyi,Coinmon 只能用来查看不同加密货币的价格。没有其他功能!Coinmon 会在终端上检查加密货币的价格。它将从 [coinmarketcap.com][2] API 获取所有详细信息。对于那些 **加密货币投资者**和**工程师**来说是非常有用的。 ### 安装 Coinmon 确保你的系统上安装了 Node.js 和 Npm。如果你的机器上没有安装 Node.js 和/或 npm,请参考以下链接进行安装。 安装完 Node.js 和 Npm 后,从终端运行以下命令安装 Coinmon。 + ``` sudo npm install -g coinmon ``` @@ -15,38 +18,42 @@ sudo npm install -g coinmon ### 从命令行查看加密货币价格 运行以下命令查看市值排名的前 10 位的加密货币: + ``` coinmon ``` 示例输出: -[![][3]][4] +![][4] + +如我所说,如果你不带任何参数运行 Coinmon,它将显示前 10 位加密货币。你还可以使用 `-t` 标志查看最高的 n 位加密货币,例如 20。 -如我所说,如果你不带任何参数运行 coinmon,它将显示前 10 位加密货币。你还可以使用 “-t” 标志查看最高的 n 位加密货币,例如 20。 ``` coinmon -t 20 ``` -所有价格默认以美元显示。你还可以使用 “-c” 标志将价格从美元转换为另一种货币。 +所有价格默认以美元显示。你还可以使用 `-c` 标志将价格从美元转换为另一种货币。 例如,要将价格转换为 INR(印度卢比),运行: + ``` coinmon -c inr ``` -[![][3]][5] +![][5] 目前,Coinmon 支持 AUD、BRL、CAD、CHF、CLP、CNY、CZK、DKK、EUR、GBP、HKD、HUF、IDR、ILS、INR、JPY、KRW、MXN、MYR、NOK、NZD、PHP、PKR、PLN、RUB、SEK、SGD、THB、TRY、TWD、ZAR 这些货币。 也可以使用加密货币的符号来搜索价格。 + ``` coinmon -f btc ``` -这里,**btc** 是比特币的符号。你可以在[**这**][6]查看所有可用的加密货币的符号。 +这里,`btc` 是比特币的符号。你可以在[**这里**][6]查看所有可用的加密货币的符号。 -有关更多详情,请参阅coinmon的帮助部分: +有关更多详情,请参阅 coinmon 的帮助部分: ``` $ coinmon -h @@ -67,15 +74,13 @@ Options: 干杯! - - -------------------------------------------------------------------------------- via: https://www.ostechnix.com/coinmon-check-cryptocurrency-prices-commandline/ 作者:[SK][a] 译者:[geekpi](https://github.com/geekpi) -校对:[校对者ID](https://github.com/校对者ID) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 @@ -83,6 +88,6 @@ via: https://www.ostechnix.com/coinmon-check-cryptocurrency-prices-commandline/ [1]:https://www.ostechnix.com/cli-fyi-quick-easy-way-fetch-information-ips-emails-domains-lots/ [2]:https://coinmarketcap.com/ [3]:data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7 -[4]:http://www.ostechnix.com/wp-content/uploads/2017/11/coinmon-1.png () -[5]:http://www.ostechnix.com/wp-content/uploads/2017/11/coinmon-2.png () +[4]:http://www.ostechnix.com/wp-content/uploads/2017/11/coinmon-1.png +[5]:http://www.ostechnix.com/wp-content/uploads/2017/11/coinmon-2.png [6]:https://en.wikipedia.org/wiki/List_of_cryptocurrencies From ae169e13e92d4cbcac5c239f5b0a483c3035ebd3 Mon Sep 17 00:00:00 2001 From: "Xingyu.Wang" Date: Tue, 30 Jan 2018 23:20:13 +0800 Subject: [PATCH 071/272] Update 20171123 Check Cryptocurrency Prices From Commandline.md --- .../20171123 Check Cryptocurrency Prices From Commandline.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/published/20171123 Check Cryptocurrency Prices From Commandline.md b/published/20171123 Check Cryptocurrency Prices From Commandline.md index 065984bc7d..ec340bb0a5 100644 --- a/published/20171123 Check Cryptocurrency Prices From Commandline.md +++ b/published/20171123 Check Cryptocurrency Prices From Commandline.md @@ -1,4 +1,4 @@ -用命令行查看比特币等加密货币价格 +用命令行查看比特币等加密货币的价格 ====== ![配图](https://www.ostechnix.com/wp-content/uploads/2017/11/bitcoin-1-720x340.jpg) From 233ce43499c08f6e332c65ec6f08c33aeca0bf12 Mon Sep 17 00:00:00 2001 From: GitFuture <752736341@qq.com> Date: Tue, 30 Jan 2018 23:34:54 +0800 Subject: [PATCH 072/272] BriFuture is translating this article --- .../tech/20150615 Let-s Build A Simple Interpreter. Part 1..md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sources/tech/20150615 Let-s Build A Simple Interpreter. Part 1..md b/sources/tech/20150615 Let-s Build A Simple Interpreter. Part 1..md index 9a815f2852..592e43e067 100644 --- a/sources/tech/20150615 Let-s Build A Simple Interpreter. Part 1..md +++ b/sources/tech/20150615 Let-s Build A Simple Interpreter. Part 1..md @@ -1,4 +1,5 @@ -// Translating by Linchenguang.... +BriFuture is translating this article + Let’s Build A Simple Interpreter. Part 1. ====== From ba0a49c74af21f0aa420df5aba2c91cddcca1e8a Mon Sep 17 00:00:00 2001 From: Sun Yongfei Date: Wed, 31 Jan 2018 00:00:30 +0800 Subject: [PATCH 073/272] apply for translation --- ...180126 How to Make a Minecraft Server - ThisHosting.Rocks.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sources/tech/20180126 How to Make a Minecraft Server - ThisHosting.Rocks.md b/sources/tech/20180126 How to Make a Minecraft Server - ThisHosting.Rocks.md index 3c948e65ba..30c6ccc54e 100644 --- a/sources/tech/20180126 How to Make a Minecraft Server - ThisHosting.Rocks.md +++ b/sources/tech/20180126 How to Make a Minecraft Server - ThisHosting.Rocks.md @@ -1,3 +1,5 @@ +translating by heart4lor + How to Make a Minecraft Server – ThisHosting.Rocks ====== We’ll show you how to make a Minecraft server with beginner-friendly step-by-step instructions. It will be a persistent multiplayer server that you can play on with your friends from all around the world. You don’t have to be in a LAN. From 4b2b04d058f8feb9341f20655f70e3722a36a342 Mon Sep 17 00:00:00 2001 From: geekpi Date: Wed, 31 Jan 2018 08:46:42 +0800 Subject: [PATCH 074/272] translated --- ...nfiguring MSMTP On Ubuntu 16.04 (Again).md | 2 + ...20180120 The World Map In Your Terminal.md | 112 ------------------ ...20180120 The World Map In Your Terminal.md | 111 +++++++++++++++++ 3 files changed, 113 insertions(+), 112 deletions(-) delete mode 100644 sources/tech/20180120 The World Map In Your Terminal.md create mode 100644 translated/tech/20180120 The World Map In Your Terminal.md diff --git a/sources/tech/20180118 Configuring MSMTP On Ubuntu 16.04 (Again).md b/sources/tech/20180118 Configuring MSMTP On Ubuntu 16.04 (Again).md index 9ddb25b40b..f557d841ac 100644 --- a/sources/tech/20180118 Configuring MSMTP On Ubuntu 16.04 (Again).md +++ b/sources/tech/20180118 Configuring MSMTP On Ubuntu 16.04 (Again).md @@ -1,3 +1,5 @@ +translating---geekpi + Configuring MSMTP On Ubuntu 16.04 (Again) ====== This post exists as a copy of what I had on my previous blog about configuring MSMTP on Ubuntu 16.04; I'm posting it as-is for posterity, and have no idea if it'll work on later versions. As I'm not hosting my own Ubuntu/MSMTP server anymore I can't see any updates being made to this, but if I ever do have to set this up again I'll create an updated post! Anyway, here's what I had… diff --git a/sources/tech/20180120 The World Map In Your Terminal.md b/sources/tech/20180120 The World Map In Your Terminal.md deleted file mode 100644 index edc23edf12..0000000000 --- a/sources/tech/20180120 The World Map In Your Terminal.md +++ /dev/null @@ -1,112 +0,0 @@ -translating---geekpi - -The World Map In Your Terminal -====== -I just stumbled upon an interesting utility. The World map in the Terminal! Yes, It is so cool. Say hello to **MapSCII** , a Braille and ASCII world map renderer for your xterm-compatible terminals. It supports GNU/Linux, Mac OS, and Windows. I thought it is a just another project hosted on GitHub. But I was wrong! It is really impressive what they did there. We can use our mouse pointer to drag and zoom in and out a location anywhere in the world map. The other notable features are; - - * Discover Point-of-Interests around any given location - * Highly customizable layer styling with [Mapbox Styles][1] support - * Connect to any public or private vector tile server - * Or just use the supplied and optimized [OSM2VectorTiles][2] based one - * Work offline and discover local [VectorTile][3]/[MBTiles][4] - * Compatible with most Linux and OSX terminals - * Highly optimizied algorithms for a smooth experience - - - -### Displaying the World Map in your Terminal using MapSCII - -To open the map, just run the following command from your Terminal: -``` -telnet mapscii.me -``` - -Here is the World map from my Terminal. - -[![][5]][6] - -Cool, yeah? - -To switch to Braille view, press **c**. - -[![][5]][7] - -Type **c** again to switch back to the previous format **.** - -To scroll around the map, use arrow keys **up** , **down** , **left** , **right**. To zoom in/out a location, use **a** and **z** keys. Also, you can use the scroll wheel of your mouse to zoom in or out. To quit the map, press **q**. - -Like I already said, don't think it is a simple project. Click on any location on the map and press **" a"** to zoom in. - -Here are some the sample screenshots after I zoomed it. - -[![][5]][8] - -I can be able to zoom to view the states in my country (India). - -[![][5]][9] - -And the districts in a state (Tamilnadu): - -[![][5]][10] - -Even the [Taluks][11] and the towns in a district: - -[![][5]][12] - -And, the place where I completed my schooling: - -[![][5]][13] - -Even though it is just a smallest town, MapSCII displayed it accurately. MapSCII uses [**OpenStreetMap**][14] to collect the data. - -### Install MapSCII locally - -Liked it? Great! You can host it on your own system. - -Make sure you have installed Node.js on your system. If not, refer the following link. - -[Install NodeJS on Linux][15] - -Then, run the following command to install it. -``` -sudo npm install -g mapscii - -``` - -To launch MapSCII, run: -``` -mapscii -``` - -Have fun! More good stuffs to come. Stay tuned! - -Cheers! - - - --------------------------------------------------------------------------------- - -via: https://www.ostechnix.com/mapscii-world-map-terminal/ - -作者:[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/ -[1]:https://www.mapbox.com/mapbox-gl-style-spec/ -[2]:https://github.com/osm2vectortiles -[3]:https://github.com/mapbox/vector-tile-spec -[4]:https://github.com/mapbox/mbtiles-spec -[5]:data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7 -[6]:http://www.ostechnix.com/wp-content/uploads/2018/01/MapSCII-1-2.png () -[7]:http://www.ostechnix.com/wp-content/uploads/2018/01/MapSCII-2.png () -[8]:http://www.ostechnix.com/wp-content/uploads/2018/01/MapSCII-3.png () -[9]:http://www.ostechnix.com/wp-content/uploads/2018/01/MapSCII-4.png () -[10]:http://www.ostechnix.com/wp-content/uploads/2018/01/MapSCII-5.png () -[11]:https://en.wikipedia.org/wiki/Tehsils_of_India -[12]:http://www.ostechnix.com/wp-content/uploads/2018/01/MapSCII-6.png () -[13]:http://www.ostechnix.com/wp-content/uploads/2018/01/MapSCII-7.png () -[14]:https://www.openstreetmap.org/ -[15]:https://www.ostechnix.com/install-node-js-linux/ diff --git a/translated/tech/20180120 The World Map In Your Terminal.md b/translated/tech/20180120 The World Map In Your Terminal.md new file mode 100644 index 0000000000..1a487b8154 --- /dev/null +++ b/translated/tech/20180120 The World Map In Your Terminal.md @@ -0,0 +1,111 @@ +在终端显示世界地图 +====== +我偶然发现了一个有趣的工具。在终端的世界地图!是的,这太酷了。向 **MapSCII** 问好,这是可在 xterm 兼容终端渲染的盲文和 ASCII 世界地图。它支持 GNU/Linux、Mac OS 和 Windows。我以为这是另一个在 GitHub 上托管的项目。但是我错了!他们做了令人印象深刻的事。我们可以使用我们的鼠标指针在世界地图的任何地方拖拽放大和缩小。其他显著的特性是: + + * 发现任何特定地点周围的兴趣点 + * 高度可定制的图层样式,带有[ Mapbox 样式][1]支持 + * 连接到任何公共或私有矢量贴片服务器 + * 或者使用已经提供并已优化的基于 [OSM2VectorTiles][2] 服务器 + * 离线工作,发现本地 [VectorTile][3]/[MBTiles][4] + * 兼容大多数 Linux 和 OSX 终端 + * 高度优化算法的流畅体验 + + + +### 使用 MapSCII 在终端中显示世界地图 + +要打开地图,只需从终端运行以下命令: +``` +telnet mapscii.me +``` + +这是我终端上的世界地图。 + +[![][5]][6] + +很酷,是吗? + +要切换到盲文视图,请按 **c**。 + +[![][5]][7] + +Type **c** again to switch back to the previous format **.** +再次输入 **c** 切回以前的格式。 + +要滚动地图,请使用**向上**、向下**、**向左**、**向右**箭头键。要放大/缩小位置,请使用 **a** 和 **a** 键。另外,你可以使用鼠标的滚轮进行放大或缩小。要退出地图,请按 **q**。 + +就像我已经说过的,不要认为这是一个简单的项目。点击地图上的任何位置,然后按 **“a”** 放大。 + +放大后,下面是一些示例截图。 + +[![][5]][8] + +我可以放大查看我的国家(印度)的州。 + +[![][5]][9] + +和州内的地区(Tamilnadu): + +[![][5]][10] + +甚至是地区内的镇 [Taluks][11]: + +[![][5]][12] + +还有,我完成学业的地方: + +[![][5]][13] + +即使它只是一个最小的城镇,MapSCII 也能准确地显示出来。 MapSCII 使用 [**OpenStreetMap**][14] 来收集数据。 + +### 在本地安装 MapSCII + +喜欢它吗?很好!你可以安装在你自己的系统上。 + +确保你的系统上已经安装了 Node.js。如果还没有,请参阅以下链接。 + +[Install NodeJS on Linux][15] + +然后,运行以下命令来安装它。 +``` +sudo npm install -g mapscii + +``` + +要启动 MapSCII,请运行: +``` +mapscii +``` + +玩的开心!会有更好的东西。敬请关注! + +干杯! + + + +-------------------------------------------------------------------------------- + +via: https://www.ostechnix.com/mapscii-world-map-terminal/ + +作者:[SK][a] +译者:[geekpi](https://github.com/geekpi) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://www.ostechnix.com/author/sk/ +[1]:https://www.mapbox.com/mapbox-gl-style-spec/ +[2]:https://github.com/osm2vectortiles +[3]:https://github.com/mapbox/vector-tile-spec +[4]:https://github.com/mapbox/mbtiles-spec +[5]:data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7 +[6]:http://www.ostechnix.com/wp-content/uploads/2018/01/MapSCII-1-2.png () +[7]:http://www.ostechnix.com/wp-content/uploads/2018/01/MapSCII-2.png () +[8]:http://www.ostechnix.com/wp-content/uploads/2018/01/MapSCII-3.png () +[9]:http://www.ostechnix.com/wp-content/uploads/2018/01/MapSCII-4.png () +[10]:http://www.ostechnix.com/wp-content/uploads/2018/01/MapSCII-5.png () +[11]:https://en.wikipedia.org/wiki/Tehsils_of_India +[12]:http://www.ostechnix.com/wp-content/uploads/2018/01/MapSCII-6.png () +[13]:http://www.ostechnix.com/wp-content/uploads/2018/01/MapSCII-7.png () +[14]:https://www.openstreetmap.org/ +[15]:https://www.ostechnix.com/install-node-js-linux/ From da76b2cb0707a574e69ec302d8f76b2a2df796ad Mon Sep 17 00:00:00 2001 From: geekpi Date: Wed, 31 Jan 2018 08:49:34 +0800 Subject: [PATCH 075/272] translating --- ...Turn On-Off Colors For ls Command In Bash On a Linux-Unix.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sources/tech/20061104 How To Turn On-Off Colors For ls Command In Bash On a Linux-Unix.md b/sources/tech/20061104 How To Turn On-Off Colors For ls Command In Bash On a Linux-Unix.md index 837179ee25..8923754d76 100644 --- a/sources/tech/20061104 How To Turn On-Off Colors For ls Command In Bash On a Linux-Unix.md +++ b/sources/tech/20061104 How To Turn On-Off Colors For ls Command In Bash On a Linux-Unix.md @@ -1,3 +1,5 @@ +translating---geekpi + How To Turn On/Off Colors For ls Command In Bash On a Linux/Unix ====== From 48c9e897efbe64362973ead496fc9dae993573ac Mon Sep 17 00:00:00 2001 From: qhwdw Date: Wed, 31 Jan 2018 09:47:29 +0800 Subject: [PATCH 076/272] Translating by qhwdw --- .../20170404 Kernel Tracing with Ftrace.md | 392 ++++++++++++++++++ 1 file changed, 392 insertions(+) create mode 100644 sources/tech/20170404 Kernel Tracing with Ftrace.md diff --git a/sources/tech/20170404 Kernel Tracing with Ftrace.md b/sources/tech/20170404 Kernel Tracing with Ftrace.md new file mode 100644 index 0000000000..98c23bff9a --- /dev/null +++ b/sources/tech/20170404 Kernel Tracing with Ftrace.md @@ -0,0 +1,392 @@ +Translating by qhwdw Kernel Tracing with Ftrace +============================================================ + +[Andrej Yemelianov][7] +Tags: [ftrace][8], [kernel][9], [kernel profiling][10], [kernel tracing][11], [linux][12], [tracepoints][13] + +![](https://blog.selectel.com/wp-content/uploads/2017/04/PR-1801-2-2.png) + +There are a number of tools for analyzing events at the kernel level: [SystemTap][14], [ktap][15], [Sysdig][16], [LTTNG][17], etc., and you can find plenty of detailed articles and materials about these on the web. + +You’ll find much less information on Linux’s native mechanism for tracing system events and retrieving/analyzing troubleshooting information. That would be [ftrace][18], the first tracing tool added to the kernel, and this is what we’ll be looking at today. Let’s start by defining some key terms. + +### Kernel Tracing and Profiling + +Kernel profiling detects performance “bottlenecks”. Profiling helps us determine where exactly in a program we’re losing performance. Special programs generate a profile—an event summary—which can be used to figure out which functions took the most time to run. These programs, however, don’t help identify why performance dropped. + +Bottlenecking usually occurs under conditions that can’t be identified from profiling. To understand why an event took place, the relevant context has to be restored. This requires tracing. + +Tracing is understood as the process of collecting information on the activity in a working system. This is done with special tools that register system events kind of like how a tape recorder records ambient sound. + +Tracing programs can simultaneously trace events at the application and OS level. The information they gather may be useful for diagnosing multiple system problems. + +Tracing is sometimes compared to logging. There definitely are similarities between the two, but there are differences, too. + +With tracing, information is written about low-level events. These number in the hundreds or even thousands. With logging, information is written about higher-level events, which are much less frequent. These include users logging into the system, application errors, database transaction, etc. + +Just like logs, tracing data can be read as is; however, it’s more useful to extract information about specific applications. All tracing programs are capable of this. + +The Linux kernel has three primary mechanisms for kernel tracing and profiling: + +* tracepoints – a mechanism that works over static instrumented code + +* kprobes – a dynamic tracing mechanism used to interrupt a kernel code at any point, call its own handler, and return after all of the necessary operations have been completed + +* perf_events – an interface for accessing the PMU (Performance Monitoring Unit) + +We won’t be writing about all of these mechanism here, but anyone interested can visit [Brendan Gregg’s blog][19]. + +Using ftrace, we can interact with these mechanisms and get debugging information directly from the user space. We’ll talk about this in more detail below. All command line examples are in Ubuntu 14.04, kernel ver. 3.13.0-24. + +### Ftrace: General Information + +Ftrace is short for Function Trace, but that’s not all it does: it can be used to track context switches, measure the time it takes to process interruptions, calculate the time for activating high-priority tasks, and much more. + +Ftrace was developed by Steven Rostedt and has been included in the kernel since version 2.6.27 in 2008\. This is the framework that provides a debugging ring buffer for recording data. This data is gathered by the kernel’s integrated tracing programs. + +Ftrace works on the debugfs file system, which is mounted by default in most modern Linux distributions. To start using ftrace, you’ll have to go to the sys/kernel/debug/tracing directory (this is only available to the root user): + +``` +# cd /sys/kernel/debug/tracing +``` + +The contents of the directory should look like this: + +``` +аvailable_filter_functions options stack_trace_filter +available_tracers per_cpu trace +buffer_size_kb printk_formats trace_clock +buffer_total_size_kb README trace_marker +current_tracer saved_cmdlines trace_options +dyn_ftrace_total_info set_event trace_pipe +enabled_functions set_ftrace_filter trace_stat +events set_ftrace_notrace tracing_cpumask +free_buffer set_ftrace_pid tracing_max_latency +function_profile_enabled set_graph_function tracing_on +instances set_graph_notrace tracing_thresh +kprobe_events snapshot uprobe_events +kprobe_profile stack_max_size uprobe_profile +``` + +We won’t describe all of these files and subdirectories; that’s already been taken care of in the [official documentation][20]. Instead, we’ll just briefly describe the files relevant to our context: + +* available_tracers – available tracing programs + +* current_tracer – the tracing program presently running + +* tracing_on – the system file responsible for enabling or disabling data writing to the ring buffer (to enable this, the number 1 has to be added to the file; to disable it, the number 0) + +* trace – the file where tracing data is saved in human-readable format + +### Available Tracers + +We can view a list of available tracers with the command + +``` +root@andrei:/sys/kernel/debug/tracing#: cat available_tracers +blk mmiotrace function_graph wakeup_rt wakeup function nop +``` + +Let’s take a quick look at the features of each tracer: + +* function – a function call tracer without arguments + +* function_graph – a function call tracer with subcalls + +* blk – a call and event tracer related to block device I/O operations (this is what blktrace uses) + +* mmiotrace – a memory-mapped I/O operation tracer + +* nop – the simplest tracer, which as the name suggests, doesn’t do anything (although it may come in handy in some situations, which we’ll describe later on) + +### The Function Tracer + +We’ll start our introduction to ftrace with the function tracer. Let’s look at a test script: + +``` +#!/bin/sh + +dir=/sys/kernel/debug/tracing + +sysctl kernel.ftrace_enabled=1 +echo function > ${dir}/current_tracer +echo 1 > ${dir}/tracing_on +sleep 1 +echo 0 > ${dir}/tracing_on +less ${dir}/trace +``` + +This script is fairly straightforward, but there are a few things worth noting. The command sysctl ftrace.enabled=1 enables the function tracer. We then enable the current tracer by writing its name to the current_tracer file. + +Next, we write a 1 to tracing_on, which enables the ring buffer. The syntax requires a space between 1 and the > symbol; echo1> tracing_on will not work. One line later, we disable it (if 0 is written to tracing_on, the buffer won’t clear and ftrace won’t be disabled). + +Why would we do this? Between the two echo commands, we see the command sleep 1\. We enable the buffer, run this command, and then disable it. This lets the tracer include information about all of the system calls that occur while the command runs. + +In the last line of the script, we give the command to display tracing data in the console. + +Once the script has run, we’ll see the following printout (here is just a small fragment): + +``` +# tracer: function +# +# entries-in-buffer/entries-written: 29571/29571 #P:2 +# +# _-----=> irqs-off +# / _----=> need-resched +# | / _---=> hardirq/softirq +# || / _--=> preempt-depth +# ||| / delay +# TASK-PID CPU# |||| TIMESTAMP FUNCTION +# | | | |||| | | + trace.sh-1295 [000] .... 90.502874: mutex_unlock <-rb_simple_write + trace.sh-1295 [000] .... 90.502875: __fsnotify_parent <-vfs_write + trace.sh-1295 [000] .... 90.502876: fsnotify <-vfs_write + trace.sh-1295 [000] .... 90.502876: __srcu_read_lock <-fsnotify + trace.sh-1295 [000] .... 90.502876: __srcu_read_unlock <-fsnotify + trace.sh-1295 [000] .... 90.502877: __sb_end_write <-vfs_write + trace.sh-1295 [000] .... 90.502877: syscall_trace_leave <-int_check_syscall_exit_work + trace.sh-1295 [000] .... 90.502878: context_tracking_user_exit <-syscall_trace_leave + trace.sh-1295 [000] .... 90.502878: context_tracking_user_enter <-syscall_trace_leave + trace.sh-1295 [000] d... 90.502878: vtime_user_enter <-context_tracking_user_enter + trace.sh-1295 [000] d... 90.502878: _raw_spin_lock <-vtime_user_enter + trace.sh-1295 [000] d... 90.502878: __vtime_account_system <-vtime_user_enter + trace.sh-1295 [000] d... 90.502878: get_vtime_delta <-__vtime_account_system + trace.sh-1295 [000] d... 90.502879: account_system_time <-__vtime_account_system + trace.sh-1295 [000] d... 90.502879: cpuacct_account_field <-account_system_time + trace.sh-1295 [000] d... 90.502879: acct_account_cputime <-account_system_time + trace.sh-1295 [000] d... 90.502879: __acct_update_integrals <-acct_account_cputime +``` + +The printout starts with information about the number of entries in the buffer and the total number of entries written. The difference between these two number is the number of events lost while filling the buffer (there were no losses in our example). + +Then there’s a list of functions that includes the following information: + +* process identifier (PID) + +* the CPU the process runs on (CPU#) + +* the process start time (TIMESTAMP) + +* the name of the traceable function and the parent function that called it (FUNCTION); for example, in the first line of our output, the mutex-unlock function was called by rb_simple_write + +### The Function_graph Tracer + +The function_graph tracer works just like function, but more detailed: the entry and exit point is shown for each function. With this tracer, we can trace functions with sub calls and measure the execution time of each function. + +Let’s edit the script from our last example: + +``` +#!/bin/sh + +dir=/sys/kernel/debug/tracing + +sysctl kernel.ftrace_enabled=1 +echo function_graph > ${dir}/current_tracer +echo 1 > ${dir}/tracing_on +sleep 1 +echo 0 > ${dir}/tracing_on +less ${dir}/trace +``` + +After running this script, we get the following printout: + +``` +# tracer: function_graph +# +# CPU DURATION FUNCTION CALLS +# | | | | | | | + 0) 0.120 us | } /* resched_task */ + 0) 1.877 us | } /* check_preempt_curr */ + 0) 4.264 us | } /* ttwu_do_wakeup */ + 0) + 29.053 us | } /* ttwu_do_activate.constprop.74 */ + 0) 0.091 us | _raw_spin_unlock(); + 0) 0.260 us | ttwu_stat(); + 0) 0.133 us | _raw_spin_unlock_irqrestore(); + 0) + 37.785 us | } /* try_to_wake_up */ + 0) + 38.478 us | } /* default_wake_function */ + 0) + 39.203 us | } /* pollwake */ + 0) + 40.793 us | } /* __wake_up_common */ + 0) 0.104 us | _raw_spin_unlock_irqrestore(); + 0) + 42.920 us | } /* __wake_up_sync_key */ + 0) + 44.160 us | } /* sock_def_readable */ + 0) ! 192.850 us | } /* tcp_rcv_established */ + 0) ! 197.445 us | } /* tcp_v4_do_rcv */ + 0) 0.113 us | _raw_spin_unlock(); + 0) ! 205.655 us | } /* tcp_v4_rcv */ + 0) ! 208.154 us | } /* ip_local_deliver_finish */ +``` + +In this graph, DURATION shows the time spent running a function. Pay careful attention to the points marked by the + and ! symbols. The plus sign (+) means the function took more than 10 microseconds; the exclamation point (!) means it took more than 100 microseconds. + +Under FUNCTION_CALLS, we find information on each function call. + +The symbols used to show the initiation and completion of each function is the same as in C: bracers ({) demarcate functions, one at the start and one at the end; leaf functions that don’t call any other function are marked with a semicolon (;). + +### Function Filters + +The ftrace printout can be big, and finding exactly what it is you’re looking for can be extremely difficult. We can use filters to simplify our search: the printout will only display information about the functions we’re interested in. To do this, we just have to write the name of our function in the set_ftrace_filter file. For example: + +``` +root@andrei:/sys/kernel/debug/tracing# echo kfree > set_ftrace_filter +``` + +To disable the filter, we add an empty line to this file: + +``` +root@andrei:/sys/kernel/debug/tracing# echo > set_ftrace_filter +``` + +By running the command + +``` +root@andrei:/sys/kernel/debug/tracing# echo kfree > set_ftrace_notrace +``` + +we get the opposite result: the printout will give us information about every function except kfree(). + +Another useful option is set_ftrace_pid. This is for tracing functions that can be called while a particular process runs. + +ftrace has many more filtering options. For a more detailed look at these, you can read Steven Rostedt’s article on [LWN.net][21]. + +### Tracing Events + +We mentioned the tracepoints mechanism above. Tracepoints are special code inserts that trigger system events. Tracepoints may be dynamic (meaning they have several checks attached to them) or static (no checks attached). + +Static tracepoints don’t affect the system in any way; they just add a few bytes for the function call at the end of the instrumented function and add a data structure in a separate section. + +Dynamic tracepoints call a trace function when the relevant code fragment is executed. Tracing data is written to the ring buffer. + +Tracepoints can be included anywhere in a code; in fact, they can already be found in a lot of kernel functions. Let’s look at the kmem_cache_alloc function (taken from [here][22]): + +``` +{ + void *ret = slab_alloc(cachep, flags, _RET_IP_); + + trace_kmem_cache_alloc(_RET_IP_, ret, + cachep->object_size, cachep->size, flags); + return ret; + } +``` + +trace_kmem_cache_alloc is itself a tracepoint. We can find countless more examples by just looking at the source code of other kernel functions. + +The Linux kernel has a special API for working with tracepoints from the user space. In the /sys/kernel/debug/tracing directory, there’s an events directory where system events are saved. These are available for tracing. System events in this context can be understood as the tracepoints included in the kernel. + +The list of these can be viewed by running the command: + +``` +root@andrei:/sys/kernel/debug/tracing# cat available_events +``` + +A long list will be printed out in the console. This is a bit inconvenient. We can print out a more structured listed using the command: + +``` +root@andrei:/sys/kernel/debug/tracing# ls events + +block gpio mce random skb vsyscall +btrfs header_event migrate ras sock workqueue +compaction header_page module raw_syscalls spi writeback +context_tracking iommu napi rcu swiotlb xen +enable irq net regmap syscalls xfs +exceptions irq_vectors nmi regulator task xhci-hcd +ext4 jbd2 oom rpm timer +filemap kmem pagemap sched udp +fs kvm power scsi vfs +ftrace kvmmmu printk signal vmscan +``` + +All possible events are combined in the subdirectory by subsystem. Before we can start tracing events, we’ll make sure we’ve enabled writing to the ring buffer: + +``` +root@andrei:/sys/kernel/debug/tracing# cat tracing_on +``` + +If the number 0 is shown in the console, we run: + +``` +root@andrei:/sys/kernel/debug/tracing# echo 1 > tracing_on +``` + +In our last article, we wrote about the chroot() system call; let’s trace access to this system call. For our tracer, we’ll use nop because function and function_graph record too much information, including event information that we’re just not interested in. + +``` +root@andrei:/sys/kernel/debug/tracing# echo nop > current_tracer +``` + +All system call related events are saved in the syscalls directory. Here we’ll find a directory for entering and exiting various system calls. We’ll activate the tracepoint we need by writing 1 in the corresponding file: + +``` +root@andrei:/sys/kernel/debug/tracing# echo 1 > events/syscalls/sys_enter_chroot/enable +``` + +Then we create an isolated file system using chroot (for more information, see this [previous post][23]). After we’ve executed the commands we want, we’ll disable the tracer so that no excess or irrelevant information appears in the printout: + +``` +root@andrei:/sys/kernel/debug/tracing# echo 0 > tracing_on +``` + +Then, we can look at the contents of the ring buffer. At the end of the printout, we’ll find information about our system call (here is a small section): + +``` +root@andrei:/sys/kernel/debug/tracing# сat trace + +...... + chroot-11321 [000] .... 4606.265208: sys_chroot(filename: 7fff785ae8c2) + chroot-11325 [000] .... 4691.677767: sys_chroot(filename: 7fff242308cc) + bash-11338 [000] .... 4746.971300: sys_chroot(filename: 7fff1efca8cc) + bash-11351 [000] .... 5379.020609: sys_chroot(filename: 7fffbf9918cc) +``` + +More detailed information about configuring event tracing can be found [here][24]. + +### Conclusion + +In this article, we presented a general overview of ftrace’s capabilities. We’d appreciate any comments or additions. If you’d like to dive deeper into this topic, we recommend looking at the following resources: + +* [https://www.kernel.org/doc/Documentation/trace/tracepoints.txt][1] — a detailed description of the tracepoints mechanism + +* [https://www.kernel.org/doc/Documentation/trace/events.txt][2] — a manual for tracing system events in Linux + +* [https://www.kernel.org/doc/Documentation/trace/ftrace.txt][3] — offical ftrace documentation + +* [https://lttng.org/files/thesis/desnoyers-dissertation-2009-12-v27.pdf][4] — Mathieu Desnoyers’ (the creator of tracepoints and LTTNG author) dissertation about kernel tracing and profiling + +* [https://lwn.net/Articles/370423/][5] — Steven Rostedt’s article on ftrace capabilities + +* [http://alex.dzyoba.com/linux/profiling-ftrace.html][6] — an ftrace overview that analyzes a practical use case + +-------------------------------------------------------------------------------- + +via:https://blog.selectel.com/kernel-tracing-ftrace/ + +作者:[Andrej Yemelianov][a] +译者:[译者ID](https://github.com/译者ID) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://blog.selectel.com/author/yemelianov/ +[1]:https://www.kernel.org/doc/Documentation/trace/tracepoints.txt +[2]:https://www.kernel.org/doc/Documentation/trace/events.txt +[3]:https://www.kernel.org/doc/Documentation/trace/ftrace.txt +[4]:https://lttng.org/files/thesis/desnoyers-dissertation-2009-12-v27.pdf +[5]:https://lwn.net/Articles/370423/ +[6]:http://alex.dzyoba.com/linux/profiling-ftrace.html +[7]:https://blog.selectel.com/author/yemelianov/ +[8]:https://blog.selectel.com/tag/ftrace/ +[9]:https://blog.selectel.com/tag/kernel/ +[10]:https://blog.selectel.com/tag/kernel-profiling/ +[11]:https://blog.selectel.com/tag/kernel-tracing/ +[12]:https://blog.selectel.com/tag/linux/ +[13]:https://blog.selectel.com/tag/tracepoints/ +[14]:https://sourceware.org/systemtap/ +[15]:https://github.com/ktap/ktap +[16]:http://www.sysdig.org/ +[17]:http://lttng.org/ +[18]:https://www.kernel.org/doc/Documentation/trace/ftrace.txt +[19]:http://www.brendangregg.com/blog/index.html +[20]:https://www.kernel.org/doc/Documentation/trace/ftrace.txt +[21]:https://lwn.net/Articles/370423/ +[22]:http://lxr.free-electrons.com/source/mm/slab.c +[23]:https://blog.selectel.com/containerization-mechanisms-namespaces/ +[24]:https://www.kernel.org/doc/Documentation/trace/events.txt \ No newline at end of file From 66ba794c6aec7d0aa79f96e6842baf725e82d141 Mon Sep 17 00:00:00 2001 From: darksun Date: Wed, 31 Jan 2018 13:04:00 +0800 Subject: [PATCH 077/272] =?UTF-8?q?=E9=80=89=E9=A2=98:=20tmux=20=E2=80=93?= =?UTF-8?q?=20A=20Powerful=20Terminal=20Multiplexer=20For=20Heavy=20Comman?= =?UTF-8?q?d-Line=20Linux=20User?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...lexer For Heavy Command-Line Linux User.md | 259 ++++++++++++++++++ 1 file changed, 259 insertions(+) create mode 100644 sources/tech/20180130 tmux - A Powerful Terminal Multiplexer For Heavy Command-Line Linux User.md 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 new file mode 100644 index 0000000000..4adaa7a2bc --- /dev/null +++ b/sources/tech/20180130 tmux - A Powerful Terminal Multiplexer For Heavy Command-Line Linux User.md @@ -0,0 +1,259 @@ +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. + +It uses a client-server model, which allows you to share sessions between users, also you can attach terminals to a tmux session back. We can easily move or rearrange the virtual console as per the need. Terminal sessions can freely rebound from one virtual console to another. + +tmux depends on libevent and ncurses libraries. tmux offers status-line at the bottom of the screen which display information about your current tmux session suc[]h as current window number, window name, username, hostname, current time, and current date. + +When tmux is started it creates a new session with a single window and displays it on screen. It allows users to create Any number of windows in the same session. + +Many of us says it's similar to screen but i'm not since this offers wide range of configuration options. + +**Make a note:** `Ctrl+b` is the default prefix in tmux so, to perform any action in tumx, you have to type the prefix first then required options. + +**Suggested Read :** [List Of Terminal Emulator For Linux][1] + +### tmux Features + + * Create any number of windows + * Create any number of panes in the single window + * It allows vertical and horizontal splits + * Detach and Re-attach window + * Server-client architecture which allows users to share sessions between users + * tmux offers wide range of configuration hacks + + + +**Suggested Read :** +**(#)** [tmate - Instantly Share Your Terminal Session To Anyone In Seconds][2] +**(#)** [Teleconsole - A Tool To Share Your Terminal Session Instantly To Anyone In Seconds][3] + +### How to Install tmux Command + +tmux command is pre-installed by default in most of the Linux systems. If no, follow the below procedure to get installed. + +For **`Debian/Ubuntu`** , use [APT-GET Command][4] or [APT Command][5] to install tmux. +``` +$ sudo apt install tmux + +``` + +For **`RHEL/CentOS`** , use [YUM Command][6] to install tmux. +``` +$ sudo yum install tmux + +``` + +For **`Fedora`** , use [DNF Command][7] to install tmux. +``` +$ sudo dnf install tmux + +``` + +For **`Arch Linux`** , use [Pacman Command][8] to install tmux. +``` +$ sudo pacman -S tmux + +``` + +For **`openSUSE`** , use [Zypper Command][9] to install tmux. +``` +$ sudo zypper in tmux + +``` + +### How to Use tmux + +kick start the tmux session by running following command on terminal. When tmux is started it creates a new session with a single window and will automatically login to your default shell with your user account. +``` +$ tmux + +``` + +[![][10]![][10]][11] + +You will get similar to above screenshot like us. tmux comes with status bar which display an information's about current sessions details, date, time, etc.,. + +The status bar information's are below: + + * **`0 :`** It is indicating the session number which was created by the tmux server. By default it starts with 0. + * **`0:username@host: :`** 0 is indicating the session number. Username and Hostname which is holding the current window. + * **`~ :`** It is indicating the current directory (We are in the Home directory) + * **`* :`** This indicate that the window is active now. + * **`Hostname :`** This shows fully qualified hostname of the server + * **`Date& Time:`** It shows current date and time + + + +### How to Split Window + +tmux allows users to split window vertically and horizontally. Let 's see how to do that. + +Press `**(Ctrl+b), %**` to split the pane vertically. +[![][10]![][10]][13] + +Press `**(Ctrl+b), "**` to split the pane horizontally. +[![][10]![][10]][14] + +### How to Move Between Panes + +Lets say, we have created few panes and want to move between them. How to do that? If you don 't know how to do, then there is no purpose to use tmux. Use the following control keys to perform the actions. There are many ways to move between panes. + +Press `(Ctrl+b), Left arrow` - To Move Left + +Press `(Ctrl+b), Right arrow` - To Move Right + +Press `(Ctrl+b), Up arrow` - To Move Up + +Press `(Ctrl+b), Down arrow` - To Move Down + +Press `(Ctrl+b), {` - To Move Left + +Press `(Ctrl+b), }` - To Move Right + +Press `(Ctrl+b), o` - Switch to next pane (left-to-right, top-down) + +Press `(Ctrl+b), ;` - Move to the previously active pane. + +For testing purpose, we are going to move between panes. Now, we are in the `pane2` which shows `lsb_release -a` command output. +[![][10]![][10]][15] + +And we are going to move to `pane0` which shows `uname -a` command output. +[![][10]![][10]][16] + +### How to Open/Create New Window + +You can open any number of windows within one terminal. Terminal window can be split vertically & horizontally which is called `panes`. Each pane will contain its own, independently running terminal instance. + +Press `(Ctrl+b), c` to create a new window. + +Press `(Ctrl+b), n` move to the next window. + +Press `(Ctrl+b), p` to move to the previous window. + +Press `(Ctrl+b), (0-9)` to immediately move to a specific window. + +Press `(Ctrl+b), l` Move to the previously selected window. + +I have two windows, first window has three panes which contains operating system distribution information, top command output & kernal information. +[![][10]![][10]][17] + +And second window has two panes which contains Linux distributions logo information. Use the following commands perform the action. +[![][10]![][10]][18] + +Press `(Ctrl+b), w` Choose the current window interactively. +[![][10]![][10]][19] + +### How to Zoom Panes + +You are working in some pane which is very small and you want to zoom it out for further work. To do use the following key binds. + +Currently we have three panes and i'm working in `pane1` which shows system activity using **Top** command and am going to zoom that. +[![][10]![][10]][17] + +When you zoom a pane, it will hide all other panes and display only the zoomed pane in the window. +[![][10]![][10]][20] + +Press `(Ctrl+b), z` to zoom the pane and press it again, to bring the zoomed pane back. + +### Display Pane Information + +To know about pane number and it's size, run the following command. + +Press `(Ctrl+b), q` to briefly display pane indexes. +[![][10]![][10]][21] + +### Display Window Information + +To know about window number, layout size, number of panes associated with the window and it's size, etc., run the following command. + +Just run `tmux list-windows` to view window information. +[![][10]![][10]][22] + +### How to Resize Panes + +You may want to resize the panes to fit your requirement. You have to press `(Ctrl+b), :` then type the following details on the `yellow` color bar in the bottom of the page. +[![][10]![][10]][23] + +In the previous section we have print pane index which shows panes size as well. To test this we are going to increase `10 cells UPward`. See the following output that has increased the pane1 & pane2 size from `55x21` to `55x31`. +[![][10]![][10]][24] + +**Syntax:** `(Ctrl+b), :` then type `resize-pane [options] [cells size]` + +`(Ctrl+b), :` then type `resize-pane -D 10` to resize the current pane Down for 10 cells. + +`(Ctrl+b), :` then type `resize-pane -U 10` to resize the current pane UPward for 10 cells. + +`(Ctrl+b), :` then type `resize-pane -L 10` to resize the current pane Left for 10 cells. + +`(Ctrl+b), :` then type `resize-pane -R 10` to resize the current pane Right for 10 cells. + +### Detaching and Re-attaching tmux Session + +One of the most powerful features of tmux is the ability to detach and reattach session whenever you need. + +Run a long running process and press `Ctrl+b` followed by `d` to detach your tmux session safely by leaving the running process. + +**Suggested Read :** [How To Keep A Process/Command Running After Disconnecting SSH Session][25] + +Now, run a long running process. For demonstration purpose, we are going to move this server backup to another remote server for disaster recovery (DR) purpose. + +You will get similar output like below after detached tmux session. +``` +[detached (from session 0)] + +``` + +Run the following command to list the available tmux sessions. +``` +$ tmux ls +0: 3 windows (created Tue Jan 30 06:17:47 2018) [109x45] + +``` + +Now, re-attach the tmux session using an appropriate session ID as follow. +``` +$ tmux attach -t 0 + +``` + +### How to Close Panes & Window + +Just type `exit` or hit `Ctrl-d` in the corresponding pane to close it. It's similar to terminal close. To close window, press `(Ctrl+b), &`. + +-------------------------------------------------------------------------------- + +via: https://www.2daygeek.com/tmux-a-powerful-terminal-multiplexer-emulator-for-linux/ + +作者:[Magesh Maruthamuthu][a] +译者:[译者ID](https://github.com/译者ID) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://www.2daygeek.com/author/magesh/ +[1]:https://www.2daygeek.com/category/terminal-emulator/ +[2]:https://www.2daygeek.com/tmate-instantly-share-your-terminal-session-to-anyone-in-seconds/ +[3]:https://www.2daygeek.com/teleconsole-share-terminal-session-instantly-to-anyone-in-seconds/ +[4]:https://www.2daygeek.com/apt-get-apt-cache-command-examples-manage-packages-debian-ubuntu-systems/ +[5]:https://www.2daygeek.com/apt-command-examples-manage-packages-debian-ubuntu-systems/ +[6]:https://www.2daygeek.com/yum-command-examples-manage-packages-rhel-centos-systems/ +[7]:https://www.2daygeek.com/dnf-command-examples-manage-packages-fedora-system/ +[8]:https://www.2daygeek.com/pacman-command-examples-manage-packages-arch-linux-system/ +[9]:https://www.2daygeek.com/zypper-command-examples-manage-packages-opensuse-system/ +[10]:data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7 +[11]:https://www.2daygeek.com/wp-content/uploads/2018/01/tmux-a-powerful-terminal-multiplexer-emulator-for-linux-1.png +[13]:https://www.2daygeek.com/wp-content/uploads/2018/01/tmux-a-powerful-terminal-multiplexer-emulator-for-linux-2.png +[14]:https://www.2daygeek.com/wp-content/uploads/2018/01/tmux-a-powerful-terminal-multiplexer-emulator-for-linux-3.png +[15]:https://www.2daygeek.com/wp-content/uploads/2018/01/tmux-a-powerful-terminal-multiplexer-emulator-for-linux-4.png +[16]:https://www.2daygeek.com/wp-content/uploads/2018/01/tmux-a-powerful-terminal-multiplexer-emulator-for-linux-5.png +[17]:https://www.2daygeek.com/wp-content/uploads/2018/01/tmux-a-powerful-terminal-multiplexer-emulator-for-linux-8.png +[18]:https://www.2daygeek.com/wp-content/uploads/2018/01/tmux-a-powerful-terminal-multiplexer-emulator-for-linux-6.png +[19]:https://www.2daygeek.com/wp-content/uploads/2018/01/tmux-a-powerful-terminal-multiplexer-emulator-for-linux-7.png +[20]:https://www.2daygeek.com/wp-content/uploads/2018/01/tmux-a-powerful-terminal-multiplexer-emulator-for-linux-9.png +[21]:https://www.2daygeek.com/wp-content/uploads/2018/01/tmux-a-powerful-terminal-multiplexer-emulator-for-linux-10.png +[22]:https://www.2daygeek.com/wp-content/uploads/2018/01/tmux-a-powerful-terminal-multiplexer-emulator-for-linux-14.png +[23]:https://www.2daygeek.com/wp-content/uploads/2018/01/tmux-a-powerful-terminal-multiplexer-emulator-for-linux-11.png +[24]:https://www.2daygeek.com/wp-content/uploads/2018/01/tmux-a-powerful-terminal-multiplexer-emulator-for-linux-13.png +[25]:https://www.2daygeek.com/how-to-keep-a-process-command-running-after-disconnecting-ssh-session/ From 86c541373401817437059dc11174e341ff41518b Mon Sep 17 00:00:00 2001 From: darksun Date: Wed, 31 Jan 2018 13:13:29 +0800 Subject: [PATCH 078/272] =?UTF-8?q?=E9=80=89=E9=A2=98:=20How=20to=20make?= =?UTF-8?q?=20your=20LXD=20containers=20get=20IP=20addresses=20from=20your?= =?UTF-8?q?=20LAN=20using=20a=20bridge?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ... addresses from your LAN using a bridge.md | 173 ++++++++++++++++++ 1 file changed, 173 insertions(+) create mode 100644 sources/tech/20180129 How to make your LXD containers get IP addresses from your LAN using a bridge.md diff --git a/sources/tech/20180129 How to make your LXD containers get IP addresses from your LAN using a bridge.md b/sources/tech/20180129 How to make your LXD containers get IP addresses from your LAN using a bridge.md new file mode 100644 index 0000000000..6f26f182b8 --- /dev/null +++ b/sources/tech/20180129 How to make your LXD containers get IP addresses from your LAN using a bridge.md @@ -0,0 +1,173 @@ +How to make your LXD containers get IP addresses from your LAN using a bridge +====== +**Background** : LXD is a hypervisor that manages machine containers on Linux distributions. You install LXD on your Linux distribution and then you can launch machine containers into your distribution running all sort of (other) Linux distributions. + +In the previous post, we saw how to get our LXD container to receive an IP address from the local network (instead of getting the default private IP address), using **macvlan**. + +In this post, we are going to see how to use a **bridge** to make our containers get an IP address from the local network. Specifically, we are going to see how to do this using NetworkManager. If you have several public IP addresses, you can use this method (or the other with the **macvlan** ) in order to expose your LXD containers directly to the Internet. + +### Creating the bridge with NetworkManager + +See this post [How to configure a Linux bridge with Network Manager on Ubuntu][1] on how to create the bridge with NetworkManager. It explains that you + + 1. Use **NetworkManager** to **Add a New Connection** , a **Bridge**. + 2. When configuring the **Bridge** , you specify the real network connection (the device, like **eth0** or **enp3s12** ) that will be **the slave of the bridge**. You can verify the device of the network connection if you run **ip route list 0.0.0.0/0**. + 3. Then, you can remove the old network connection and just keep the slave. The slave device ( **bridge0** ) will now be the device that gets you your LAN IP address. + + + +At this point you would have again network connectivity. Here is the new device, **bridge0**. +``` +$ ifconfig bridge0 +bridge0 Link encap:Ethernet HWaddr 00:e0:4b:e0:a8:c2 + inet addr:192.168.1.64 Bcast:192.168.1.255 Mask:255.255.255.0 + inet6 addr: fe80::d3ca:7a11:f34:fc76/64 Scope:Link + UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 + RX packets:9143 errors:0 dropped:0 overruns:0 frame:0 + TX packets:7711 errors:0 dropped:0 overruns:0 carrier:0 + collisions:0 txqueuelen:1000 + RX bytes:7982653 (7.9 MB) TX bytes:1056263 (1.0 MB) +``` + +### Creating a new profile in LXD for bridge networking + +In LXD, there is a default profile and then you can create additional profile that either are independent from the default (like in the **macvlan** post), or can be chained with the default profile. Now we see the latter. + +First, create a new and empty LXD profile, called **bridgeprofile**. +``` +$ lxc create profile bridgeprofile +``` + +Here is the fragment to add to the new profile. The **eth0** is the interface name in the container, so for the Ubuntu containers it does not change. Then, **bridge0** is the interface that was created by NetworkManager. If you created that bridge by some other way, add here the appropriate interface name. The **EOF** at the end is just a marker when we copy and past to the profile. +``` +description: Bridged networking LXD profile +devices: + eth0: + name: eth0 + nictype: bridged + parent: bridge0 + type: nic +**EOF** +``` + +Paste the fragment to the new profile. +``` +$ cat < Date: Tue, 30 Jan 2018 21:51:39 -0500 Subject: [PATCH 079/272] Translated: Internet Chemotherapy --- .../tech/20171218 Internet Chemotherapy.md | 336 ------------------ .../tech/20171218 Internet Chemotherapy.md | 76 ++++ 2 files changed, 76 insertions(+), 336 deletions(-) delete mode 100644 sources/tech/20171218 Internet Chemotherapy.md create mode 100644 translated/tech/20171218 Internet Chemotherapy.md diff --git a/sources/tech/20171218 Internet Chemotherapy.md b/sources/tech/20171218 Internet Chemotherapy.md deleted file mode 100644 index 2d2b950db5..0000000000 --- a/sources/tech/20171218 Internet Chemotherapy.md +++ /dev/null @@ -1,336 +0,0 @@ -(yixunx translating) -Internet Chemotherapy -====== - -12/10 2017 - -### 1. Internet Chemotherapy - -Internet Chemotherapy was a 13 month project between Nov 2016 - Dec 2017. -It has been known under names such as 'BrickerBot', 'bad firmware -upgrade', 'ransomware', 'large-scale network failure' and even -'unprecedented terrorist actions.' That last one was a little harsh, -Fernandez, but I guess I can't please everybody. - -You can download the module which executes the http and telnet-based -payloads from this router at http://91.215.104.140/mod_plaintext.py. Due to -platform limitations the module is obfuscated single threaded python, but -the payloads are in plain view and should be easy to figure out for any -programmer worth his/her/hir salt. Take a look at the number of payloads, -0-days and techniques and let the reality sink in for a moment. Then -imagine what would've happened to the Internet in 2017 if I had been a -blackhat dedicated to building a massive DDoS cannon for blackmailing the -biggest providers and companies. I could've disrupted them all and caused -extraordinary damage to the Internet in the process. - -My ssh crawler is too dangerous to publish. It contains various levels of -automation for the purpose of moving laterally through poorly designed -ISP networks and taking them over through only a single breached router. -My ability to commandeer and secure hundreds of thousands of ISP routers -was the foundation of my anti-IoT botnet project as it gave me great -visibility of what was happening on the Internet and it gave me an -endless supply of nodes for hacking back. I began my non-destructive ISP -network cleanup project in 2015 and by the time Mirai came around I was -in a good position to react. The decision to willfully sabotage other -people's equipment was nonetheless a difficult one to make, but the -colossally dangerous CVE-2016-10372 situation ultimately left me with no -other choice. From that moment on I was all-in. - -I am now here to warn you that what I've done was only a temporary band- -aid and it's not going to be enough to save the Internet in the future. -The bad guys are getting more sophisticated, the number of potentially -vulnerable devices keep increasing, and it's only a matter of time before -a large scale Internet-disrupting event will occur. If you are willing to -believe that I've disabled over 10 million vulnerable devices over the 13- -month span of the project then it's not far-fetched to say that such a -destructive event could've already happened in 2017. - -YOU SHOULD WAKE UP TO THE FACT THAT THE INTERNET IS ONLY ONE OR TWO -SERIOUS IOT EXPLOITS AWAY FROM BEING SEVERELY DISRUPTED. The damage of -such an event is immeasurable given how digitally connected our societies -have become, yet CERTs, ISPs and governments are not taking the gravity -of the situation seriously enough. ISPs keep deploying devices with -exposed control ports and although these are trivially found using -services like Shodan the national CERTs don't seem to care. A lot of -countries don't even have CERTs. Many of the world's biggest ISPs do not -have any actual security know-how in-house, and are instead relying on -foreign vendors for help in case anything goes wrong. I've watched large -ISPs withering for months under conditioning from my botnet without them -being able to fully mitigate the vulnerabilities (good examples are BSNL, -Telkom ZA, PLDT, from time to time PT Telkom, and pretty much most large -ISPs south of the border). Just look at how slow and ineffective Telkom -ZA was in dealing with its Aztech modem problem and you will begin to -understand the hopelessness of the current situation. In 99% of the -problem cases the solution would have simply been for the ISPs to deploy -sane ACLs and CPE segmentation, yet months later their technical staff -still hasn't figured this out. If ISPs are unable to mitigate weeks and -months of continuous deliberate sabotage of their equipment then what -hope is there that they would notice and fix a Mirai problem on their -networks? Many of the world's biggest ISPs are catastrophically negligent -and this is the biggest danger by a landslide, yet paradoxically it -should also be the easiest problem to fix. - -I've done my part to try to buy the Internet some time, but I've gone as -far as I can. Now it's up to you. Even small actions are important. Among -the things you can do are: - -* Review your own ISP's security through services such as Shodan and take - them to task over exposed telnet, http, httpd, ssh, tr069 etc. ports on - their networks. Refer them to this document if you have to. There's no - good reason why any of these control ports should ever be accessible - from the outside world. Exposing control ports is an amateur mistake. - If enough customers complain they might actually do something about it! - -* Vote with your wallet! Refuse to buy or use 'intelligent' products - unless the manufacturer can prove that the product can and will receive - timely security updates. Find out about the vendor's security track - record before giving them your hard-earned money. Be willing to pay a - little bit more for credible security. - -* Lobby your local politicians and government officials for improved - security legislation for IoT (Internet of Things) devices such as - routers, IP cameras and 'intelligent' devices. Private or public - companies currently lack the incentives for solving this problem in the - immediate term. This matter is as important as minimum safety - requirements for cars and general electrical appliances. - -* Consider volunteering your time or other resources to underappreciated - whitehat organizations such as GDI Foundation or Shadowserver - Foundation. These organizations and people make a big difference and - they can significantly amplify the impact of your skillset in helping - the Internet. - -* Last but not least, consider the long-shot potential of getting IoT - devices designated as an 'attractive nuisance' through precedent- - setting legal action. If a home owner can be held liable for a - burglar/trespasser getting injured then I don't see why a device owner - (or ISP or manufacturer) shouldn't be held liable for the damage that - was caused by their dangerous devices being exploitable through the - Internet. Attribution won't be a problem for Layer 7 attacks. If any - large ISPs with deep pockets aren't willing to fund such precedent - cases (and they might not since they fear that such precedents could - come back to haunt them) we could even crowdfund such initiatives over - here and in the EU. ISPs: consider your volumetric DDoS bandwidth cost - savings in 2017 as my indirect funding of this cause and as evidence - for its potential upside. - -### 2. Timeline - -Here are some of the more memorable events of the project: - -* Deutsche Telekom Mirai disruption in late November 2016. My hastily - assembled initial TR069/64 payload only performed a 'route del default' - but this was enough to get the ISP's attention to the problem and the - resulting headlines alerted other ISPs around the world to the - unfolding disaster. - -* Around January 11-12 some Mirai-infected DVRs with exposed control port - 6789 ended up getting bricked in Washington DC, and this made numerous - headlines. Gold star to Vemulapalli for determining that Mirai combined - with /dev/urandom had to be 'highly sophisticated ransomware'. Whatever - happened to those 2 unlucky souls in Europe? - -* In late January 2017 the first genuine large-scale ISP takedown occured - when Rogers Canada's supplier Hitron carelessly pushed out new firmware - with an unauthenticated root shell listening on port 2323 (presumably - this was a debugging interface that they forgot to disable). This epic - blunder was quickly discovered by Mirai botnets, and the end-result was - a large number of bricked units. - -* In February 2017 I noticed the first Mirai evolution of the year, with - both Netcore/Netis and Broadcom CLI-based modems being attacked. The - BCM CLI would turn out to become one of the main Mirai battlegrounds of - 2017, with both the blackhats and me chasing the massive long tail of - ISP and model-specific default credentials for the rest of the year. - The 'broadcom' payloads in the above source may look strange but - they're statistically the most likely sequences to disable any of the - endless number of buggy BCM CLI firmwares out there. - -* In March 2017 I significantly increased my botnet's node count and - started to add more web payloads in response to the threats from IoT - botnets such as Imeij, Amnesia and Persirai. The large-scale takedown - of these hacked devices created a new set of concerns. For example, - among the leaked credentials of the Avtech and Wificam devices there - were logins which strongly implied airports and other important - facilities, and around April 1 2017 the UK government officials - warned of a 'credible cyber threat' to airports and nuclear - facilities from 'hacktivists.' Oops. - -* The more aggressive scanning also didn't escape the attention of - civilian security researchers, and in April 6 2017 security company - Radware published an article about my project. The company trademarked - it under the name 'BrickerBot.' It became clear that if I were to - continue increasing the scale of my IoT counteroffensive I had to come - up with better network mapping/detection methods for honeypots and - other risky targets. - -* Around April 11th 2017 something very unusual happened. At first it - started like so many other ISP takedowns, with a semi-local ISP called - Sierra Tel running exposed Zyxel devices with the default telnet login - of supervisor/zyad1234. A Mirai runner discovered the exposed devices - and my botnet followed soon after, and yet another clash in the epic - BCM CLI war of 2017 took place. This battle didn't last long. It - would've been just like any of the hundreds of other ISP takedowns in - 2017 were it not for something very unusual occuring right after the - smoke settled. Amazingly, the ISP didn't try to cover up the outage as - some kind of network issue, power spike or a bad firmware upgrade. They - didn't lie to their customers at all. Instead, they promptly published - a press release about their modems having been vulnerable which allowed - their customers to assess their potential risk exposure. What did the - most honest ISP in the world get for its laudable transparency? Sadly - it got little more than criticism and bad press. It's still the most - depressing case of 'why we can't have nice things' to me, and probably - the main reason for why 99% of security mistakes get covered up and the - actual victims get left in the dark. Too often 'responsible disclosure' - simply becomes a euphemism for 'coverup.' - -* On April 14 2017 DHS warned of 'BrickerBot Threat to Internet of - Things' and the thought of my own government labeling me as a cyber - threat felt unfair and myopic. Surely the ISPs that run dangerously - insecure network deployments and the IoT manufacturers that peddle - amateurish security implementations should have been fingered as the - actual threat to Americans rather than me? If it hadn't been for me - millions of us would still be doing their banking and other sensitive - transactions over hacked equipment and networks. If anybody from DHS - ever reads this I urge you to reconsider what protecting the homeland - and its citizens actually means. - -* In late April 2017 I spent some time on improving my TR069/64 attack - methods, and in early May 2017 a company called Wordfence (now Defiant) - reported a significant decline in a TR069-exploiting botnet that had - previously posed a threat to Wordpress installations. It's noteworthy - that the same botnet temporarily returned a few weeks later using a - different exploit (but this was also eventually mitigated). - -* In May 2017 hosting company Akamai reported in its Q1 2017 State of the - Internet report an 89% decrease in large (over 100 Gbps) DDoS attacks - compared with Q1 2016, and a 30% decrease in total DDoS attacks. The - largest attack of Q1 2017 was 120 Gbps vs 517 Gbps in Q4 2016. As large - volumetric DDoS was one of the primary signatures of Mirai this felt - like concrete justification for all the months of hard work in the IoT - trenches. - -* During the summer I kept improving my exploit arsenal, and in late July - I performed some test runs against APNIC ISPs. The results were quite - surprising. Among other outcomes a few hundred thousand BSNL and MTNL - modems were disabled and this outage become headline news in India. - Given the elevated geopolitical tensions between India and China at the - time I felt that there was a credible risk of the large takedown being - blamed on China so I made the rare decision to publically take credit - for it. Catalin, I'm very sorry for the abrupt '2 day vacation' that - you had to take after reporting the news. - -* Previously having worked on APNIC and AfriNIC, on August 9th 2017 I - also launched a large scale cleanup of LACNIC space which caused - problems for various providers across the subcontinent. The attack made - headlines in Venezuela after a few million cell phone users of Movilnet - lost service. Although I'm personally against government surveillance - of the Internet the case of Venezuela is noteworthy. Many of the - LACNIC ISPs and networks have been languishing for months under - persistent conditioning from my botnet, but Venezuelan providers have - been quick to fortify their networks and secure their infrastructure. - I believe this is due to Venezuela engaging in far more invasive deep - packet inspection than the other LACNIC countries. Food for thought. - -* In August 2017 F5 Labs released a report called "The Hunt for IoT: The - Rise of Thingbots" in which the researchers were perplexed over the - recent lull in telnet activity. The researchers speculated that the - lack of activity may be evidence that one or more very large cyber - weapons are being built (which I guess was in fact true). This piece - is to my knowledge the most accurate assessment of the scope of my - project but fascinatingly the researchers were unable to put two and - two together in spite of gathering all the relevant clues on a single - page. - -* In August 2017 Akamai's Q2 2017 State of the Internet report announces - the first quarter in 3 years without the provider observing a single - large (over 100 Gbps) attack, and a 28% decrease in total DDoS attacks - vs Q1 2017. This seems like further validation of the cleanup effort. - This phenomenally good news is completely ignored by the mainstream - media which operates under an 'if it bleeds it leads' mentality even - when it comes to information security. This is yet another reason why - we can't have nice things. - -* After the publication of CVE-2017-7921 and 7923 in September 2017 I - decided to take a closer look at Hikvision devices, and to my horror - I realized that there's a technique for botting most of the vulnerable - firmwares that the blackhats hadn't discovered yet. As a result I - launched a global cleanup initiative around mid-September. Over a - million DVRs and cameras (mainly Hikvision and Dahua) were disabled - over a span of 3 weeks and publications such as IPVM.com wrote several - articles about the attacks. Dahua and Hikvision wrote press releases - mentioning or alluding to the attacks. A huge number of devices finally - got their firmwares upgraded. Seeing the confusion that the cleanup - effort caused I decided to write a quick summary for the CCTV people at - http://depastedihrn3jtw.onion.link/show.php?md5=62d1d87f67a8bf485d43a05ec32b1e6f - (sorry for the NSFW language of the pastebin service). The staggering - number of vulnerable units that were online months after critical - security patches were available should be the ultimate wakeup call to - everyone about the utter dysfunctionality of the current IoT patching - process. - -* Around September 28 2017 Verisign releases a report saying that DDoS - attacks declined 55% in Q2 2017 vs Q1, with a massive 81% attack peak - decline. - -* On November 23rd 2017 the CDN provider Cloudflare reports that 'in - recent months, Cloudflare has seen a dramatic reduction in simple - attempts to flood our network with junk traffic.' Cloudflare speculates - it could've partly been due to their change in policies, but the - reductions also line up well with the IoT cleanup activities. - -* At the end of November 2017 Akamai's Q3 2017 State of the Internet - report sees a small 8% increase in total DDoS attacks for the quarter. - Although this was a significant reduction compared to Q3 2016 the - slight uptick serves as a reminder of the continued risks and dangers. - -* As a further reminder of the dangers a new Mirai strain dubbed 'Satori' - reared its head in November-December of 2017. It's particularly - noteworthy how quickly the botnet managed to grow based on a single - 0-day exploit. This event underlines the current perilous operating - state of the Internet, and why we're only one or two severe IoT - exploits away from widespread disruption. What will happen when nobody - is around to disable the next threat? Sinkholing and other whitehat/ - 'legal' mitigations won't be enough in 2018 just like they weren't - enough in 2016. Perhaps in the future governments will be able to - collaborate on a counterhacking task force with a global mandate for - disabling particularly severe existential threats to the Internet, but - I'm not holding my breath. - -* Late in the year there were also some hysterical headlines regarding a - new botnet that was dubbed 'Reaper' and 'IoTroop'. I know some of you - will eventually ridicule those who estimated its size at 1-2 million - but you should understand that security researchers have very limited - knowledge of what's happening on networks and hardware that they don't - control. In practice the researchers could not possibly have known or - even assumed that most of the vulnerable device pool had already been - disabled by the time the botnet emerged. Give the 'Reaper' one or two - new unmitigated 0-days and it'll become as terrifying as our worst - fears. - -### 3. Parting Thoughts - -I'm sorry to leave you in these circumstances, but the threat to my own -safety is becoming too great to continue. I have made many enemies. If -you want to help look at the list of action items further up. Good luck. - -There will also be those who will criticize me and say that I've acted -irresponsibly, but that's completely missing the point. The real point -is that if somebody like me with no previous hacking background was able -to do what I did, then somebody better than me could've done far worse -things to the Internet in 2017. I'm not the problem and I'm not here to -play by anyone's contrived rules. I'm only the messenger. The sooner you -realize this the better. - --Dr Cyborkian a.k.a. janit0r, conditioner of 'terminally ill' devices. - --------------------------------------------------------------------------------- - -via:https://ghostbin.com/paste/q2vq2 - -作者:janit0r -译者:[译者ID](https://github.com/译者ID) -校对:[校对者ID](https://github.com/校对者ID) - -本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译, -[Linux中国](https://linux.cn/) 荣誉推出 diff --git a/translated/tech/20171218 Internet Chemotherapy.md b/translated/tech/20171218 Internet Chemotherapy.md new file mode 100644 index 0000000000..65271836af --- /dev/null +++ b/translated/tech/20171218 Internet Chemotherapy.md @@ -0,0 +1,76 @@ +互联网化疗 +====== + +译注:本文作者 janit0r 被认为是 BrickerBot 病毒的作者。此病毒会攻击物联网上安全性不足的设备并使其断开和其他网络设备的连接。janit0r 宣称他使用这个病毒的目的是保护互联网的安全,避免这些设备被入侵者用于入侵网络上的其他设备。janit0r 称此项目为”互联网化疗“。janit0r 决定在 2017 年 12 月终止这个项目,并在网络上发表了这篇文章。 + +12/10 2017 + +### 1. 互联网化疗 + +互联网化疗是在 2016 年 11 月 到 2017 年 12 月之间的一个为期 13 个月的项目。它曾被称为“BrickerBot”、“错误的固件升级”、“勒索软件”、“大规模网络瘫痪”,甚至“前所未有的恐怖行为”。最后一个有点伤人了,费尔南德斯(译注:委内瑞拉电信公司 CANTV 的光纤网络曾在 2017 年 8 月受到病毒攻击,公司董事长曼努埃尔·费尔南德斯称这次攻击为[“前所未有的恐怖行为”][1]),但我想我大概不能让所有人都满意吧。 + +你可以从 http://91.215.104.140/mod_plaintext.py 下载我的代码模块,它可以基于 http 和 telnet 发送恶意请求(译注:这个链接已经失效,不过在 [Github][2] 上有备份)。因为平台的限制,模块里是混淆过的单线程 Python 代码,但请求的内容依然是明文,任何合格的程序员应该都能看得懂。看看这里面有多少恶意请求、0-day 漏洞和入侵技巧,花点时间让自己接受现实。然后想象一下,如果我是一个黑客,致力于创造出强大的 DDoS 生成器来勒索那些最大的互联网服务提供商和公司的话,互联网在 2017 年会受到怎样的打击。我完全可以让他们全部陷入混乱,并同时对整个互联网造成巨大的伤害。 + +我的 ssh 爬虫太危险了,不能发布出来。它包含很多层面的自动化,可以只利用一个被入侵的路由器就能够在设计有缺陷的互联网服务提供商的网络上平行移动并加以入侵。正是因为我可以征用数以万计的互联网服务提供商的路由器,而这些路由器让我知晓网络上发生的事情并给我源源不断的节点用来进行入侵行动,我才得以进行我的反物联网僵尸网络项目。我于 2015 年开始了我的非破坏性的提供商网络清理项目,于是当 Mirai 病毒入侵时我已经做好了准备来做出回应。主动破坏其他人的设备仍然是一个困难的决定,但无比危险的 CVE-2016-10372 漏洞让我别无选择。从那时起我就决定一不做二不休。 + +(译注:上一段中提到的 Mirai 病毒首次出现在 2016 年 8 月。它可以远程入侵运行 Linux 系统的网络设备并利用这些设备构建僵尸网络。本文作者 janit0r 宣称当 Mirai 入侵时他利用自己的 BrickerBot 病毒强制将数以万计的设备从网络上断开,从而减少 Mirai 病毒可以利用的设备数量。) + +我在此警告你们,我所做的只是权宜之计,它并不足以在未来继续拯救互联网。坏人们正变得更加聪明,可能有漏洞的设备数量在持续增加,发生大规模的、能使网络瘫痪的事件只是时间问题。如果你愿意相信我曾经在一个持续 13 个月的项目中使上千万有漏洞的设备变得无法使用,那么不过分地说,如此严重的事件本可能在 2017 年就发生。 + +__你们应该意识到,只需要再有一两个严重的物联网漏洞,我们的网络就会严重瘫痪。__ 考虑到我们的社会现在是多么依赖数字网络,而计算机安全应急响应组和互联网服务提供商们又是多么地忽视问题的严重性,这种事件造成的伤害是无法估计的。互联网服务提供商在持续地部署有开放的控制端口的设备,而且即使像 Shodan 这样的服务可以轻而易举地发现这些问题,我国的计算机安全应急响应组还是似乎并不在意。而很多国家甚至都没有自己的计算机安全应急响应组。世界上许多的互联网服务提供商都没有雇佣任何熟知计算机安全问题的人,而是在出现问题的时候依赖于外来的专家来解决。我曾见识过大型互联网服务提供商在我的僵尸网络的调节之下连续多个月持续受损,但他们还是不能完全解决漏洞(几个好的例子是 BSNL、Telkom ZA、PLDT、某些时候的 PT Telkom,以及南半球大部分的大型互联网服务提供商)。只要看看 Telkom ZA 解决他们的 Aztech 调制解调器问题的速度有多慢,你就会开始理解现状有多么令人绝望。在 99% 的情况下,要解决这个问题只需要互联网服务提供商部署合理的访问控制列表并把部署在用户端的设备单独分段,但是几个月过去之后他们的技术人员依然没有弄明白。如果互联网服务提供商在经历了几周到几个月的针对他们设备的蓄意攻击之后仍然无法解决问题,我们又怎么能期望他们会注意到并解决 Mirai 在他们网络上造成的问题呢?世界上许多最大的互联网服务提供商对这些事情无知得令人发指,而这毫无疑问是最大的危险,但奇怪的是,这应该也是最容易解决的问题。 + +我已经尽自己的责任试着去让互联网多坚持一段时间,但我已经尽力了。接下来要交给你们了。即使很小的行动也是非常重要的。你们能做的事情有: + +* 使用像 Shodan 之类的服务来检查你的互联网服务提供商的安全性,并驱使他们去解决他们网络上开放的 telnet、http、httpd、ssh 和 tr069 等端口。如果需要的话,可以把这篇文章给他们看。从来不存在什么好的理由来让这些端口可以从外界访问。开放控制端口是业余人士的错误。如果有足够的客户抱怨,他们也许真的会采取行动! +* 用你的钱包投票!拒绝购买或使用任何“智能“产品,除非制造商保证这个产品能够而且将会收到及时的安全更新。在把你辛苦赚的钱交给提供商之前,先去查看他们的安全记录。为了更好的安全性,可以多花一些钱。 +* 游说你本地的政治家和政府官员,让他们改进法案来规范物联网设备,包括路由器、IP 照相机和各种”智能“设备。不论私有还是公有的公司目前都没有足够的动机去在短期内解决问题。这件事情和汽车或者通用电气的安全标准一样重要。 +* 考虑给像 GDI 基金会或者 Shadowserver 基金会这种缺少支持的白帽黑客组织贡献你的时间或者其他资源。这些组织和人能产生巨大的影响,并且他们可以很好地发挥你的能力来帮助互联网。 +* 最后,虽然希望不大,但可以考虑通过设立法律先例来让物联网设备成为一种”诱惑性危险品attractive nuisance“(译注:attractive nuisance 是美国法律中的一个原则,意思是如果儿童在私人领地上因为某些对儿童有吸引力的危险物品而受伤,领地的主人需要负责,无论受伤的儿童是否是合法进入领地)。如果一个房主可以因为小偷或者侵入者受伤而被追责,我不清楚为什么设备的主人(或者互联网服务提供商和设备制造商)不应该因为他们的危险的设备被远程入侵所造成的伤害而被追责。连带责任原则应该适用于对设备应用层的入侵。如果任何有钱的大型互联网服务提供商不愿意为设立这样的先例而出钱(他们也许的确不会,因为他们害怕这样的先例会反过来让自己吃亏),我们甚至可以在这里还有在欧洲为这个行动而众筹。互联网服务提供商们:把你们在用来应对 DDoS 的带宽上省下的可观的成本当做我为这个目标的间接投资,也当做它的好处的证明吧。 + +### 2. 时间线 + +下面是这个项目中一些值得纪念的事件: + +* 2016 年 11 月底的德国电信 Mirai 事故。我匆忙写出的最初的 TR069/64 请求只执行了 `route del default`,不过这已经足够引起互联网服务提供商去注意这个问题,而它引发的新闻头条警告了全球的其他互联网服务提供商来注意这个迫近的危机。 +* 大约 1 月 11 日 到 12 日,一些位于华盛顿特区的开放了 6789 控制端口的硬盘录像机被 Mirai 入侵并瘫痪,这上了很多头条新闻。我要给 Vemulapalli 点赞,她居然认为 Mirai 加上 /dev/urandom 一定是“非常复杂的勒索软件”(译注:Archana Vemulapalli 当时是华盛顿市政府的 CTO)。欧洲的那两个可怜人又怎么样了呢? +* 2017 年 1 月底发生了第一起真正的大规模互联网服务提供商下架事件。Rogers Canada 的提供商 Hitron 非常粗心地推送了一个在 2323 端口上监听的无验证的 root shell(这可能是一个他们忘记关闭的 debug 接口)。这个惊天的失误很快被 Mirai 的僵尸网络所发现,造成大量设备瘫痪。 +* 在 2017 年 2 月,我注意到 Mirai 在这一年里的第一次扩张,Netcore/Netis 以及基于 Broadcom CLI 的调制解调器都遭受了攻击。BCM CLI 后来成为了 Mirai 在 2017 年的主要战场,黑客们和我自己都在这一年的余下时间里花大量时间寻找无数互联网服务提供商和设备制造商设置的默认密码。前面代码中的“broadcom”请求内容也许看上去有点奇怪,但它们是统计角度上最可能禁用那些大量的有问题的 BCM CLI 固件的序列。 +* 在 2017 年 3 月,我大幅提升了我的僵尸网络的节点数量并开始加入更多的网络请求。这是为了应对包括 Imeij、Amnesia 和 Persirai 在内的僵尸网络的威胁。大规模地禁用这些被入侵的设备也带来了新的一些问题。比如在 Avtech 和 Wificam 设备所泄露的登录信息当中,有一些用户名和密码非常像是用于机场和其他重要设施的,而英国政府官员大概在 2017 年 4 月 1 日关于针对机场和核设施的“实际存在的网络威胁”做出过警告。哎呀。 +* 这种更加激进的排查还引起了民间安全研究者的注意,安全公司 Radware 在 2017 年 4 月 6 日发表了一篇关于我的项目的文章。这个公司把它叫做“BrickerBot”。显然,如果我要继续增加我的物联网防御措施的规模,我必须想出更好的网络映射与检测方法来应对蜜罐或者其他有风险的目标。 +* 2017 年 4 月 11 日左右的时候发生了一件非常不寻常的事情。一开始这看上去和许多其他的互联网服务提供商下架事件相似,一个叫 Sierra Tel 的半本地的互联网服务提供商在一些 Zyxel 设备上使用了默认的 telnet 用户名密码 supervisor/zyad1234。一个 Mirai 使用者发现了这些有漏洞的设备,而我的僵尸网络紧随其后,2017年精彩绝伦的 BCM CLI 战争又开启了新的一场战斗。这场战斗并没有持续很久。它本来会和 2017 年的其他数百起互联网服务提供商下架事件一样,如果不是在尘埃落定之后发生的那件非常不寻常的事情的话。令人惊奇的是,这家互联网服务提供商并没有试着把这次网络中断掩盖成某种网络故障、电力超额或错误的固件升级。他们完全没有对客户说谎。相反,他们很快发表了新闻公告,说他们的调制解调器有漏洞,这让他们的客户们得以评估自己可能遭受的风险。这家全世界最诚实的互联网服务提供商为他们值得赞扬的公开行为而收获了什么呢?悲哀的是,它得到的只是批评和不好的名声。这依然是我记忆中最令人沮丧的“为什么我们得不到好东西”的例子,这很有可能也是为什么 99% 的安全错误都被掩盖而真正的受害者被蒙在鼓里的最主要原因。太多时候,“有责任心的信息公开”会直接变成“粉饰太平”的委婉说法。 +* 在 2017 年 4 月 14 日,国土安全部关于“BrickerBot 对物联网的威胁”做出了警告,我自己的政府把我作为一个网络威胁这件事让我觉得他们很不公平而且目光短浅。跟我相比,对美国人民威胁最大的难道不应该是那些部署缺乏安全性的网络设备的提供商和贩卖不成熟的安全方案的物联网设备制造商吗?如果没有我,数以百万计的人们可能还在用被入侵的设备和网络来处理银行业务和其他需要保密的交易。如果国土安全部里有人读到这篇文章,我强烈建议你重新考虑一下保护国家和公民究竟是什么意思。 +* 在 2017 年 4 月底,我花了一些时间改进我的 TR069/64 攻击方法,然后在 2017 年 5 月初,一个叫 Wordfence 的公司(现在叫 Defiant)报道称一个曾给 Wordpress 网站造成威胁的基于入侵 TR069 的僵尸网络很明显地衰减了。值得注意的是,同一个僵尸网络在几星期后使用了一个不同的入侵方式暂时回归了(不过这最终也同样被化解了)。 +* 在 2017 年 5 月,主机公司 Akamai 在它的 2017 年第一季度互联网现状报告中写道,相比于 2016 年第一季度,大型(超过 100 Gbps)DDoS 攻击数减少了 89%,而总体 DDoS 攻击数减少了 30%。鉴于大型 DDoS 攻击是 Mirai 的主要手段,我觉得这给这些月来在物联网领域的辛苦劳动提供了实际的支持。 +* 在夏天我持续地改进我的入侵技术军火库,然后在 7 月底我针对亚太互联网络信息中心的互联网服务提供商进行了一些测试。测试结果非常令人吃惊。造成的影响之一是数十万的 BSNL 和 MTNL 调制解调器被禁用,而这次中断事故在印度成为了头条新闻。考虑到当时在印度和中国之间持续升级的地缘政治压力,我觉得这个事故有很大的风险会被归咎于中国所为,于是我很罕见地决定公开承认是我所做。Catalin,我很抱歉你在报道这条新闻之后突然被迫放的“两天的假期”。 +* 在处理过亚太地区和非洲地区的互联网络信息中心之后,在 2017 年 8 月 9 日我又针对拉丁美洲与加勒比地区互联网络信息中心进行了大规模的清理,给这个大洲的许多提供商造成了问题。在数百万的 Movilnet 的手机用户失去连接之后,这次攻击在委内瑞拉被大幅报道。虽然我个人反对政府监管互联网,委内瑞拉的这次情况值得注意。许多拉美与加勒比地区的提供商与网络曾在我的僵尸网络的持续调节之下连续数个月逐渐衰弱,但委内瑞拉的提供商很快加强了他们的网络防护并确保了他们的网络设施的安全。我认为这是由于委内瑞拉相比于该地区的其他国家来说进行了更具侵入性的深度包检测。值得思考一下。 +* F5 实验室在 2017 年 8 月发布了一个题为“狩猎物联网:僵尸物联网的崛起”的报告,研究者们在其中对近期 telnet 活动的平静表达了困惑。研究者们猜测这种活动的减少也许证实了一个或多个非常大型的网络武器正在成型(我想这大概确实是真的)。这篇报告是在我印象中对我的项目的规模最准确的评估,但神奇的是,这些研究者们什么都推断不出来,尽管他们把所有相关的线索都集中到了一页纸上。 +* 2017 年 8 月,Akamai 的 2017 年第二季度互联网现状报告宣布这是三年以来首个该提供商没有发现任何大规模(超过 100 Gbps)攻击的季度,而且 DDoS 攻击总数相比 2017 年第一季度减少了 28%。这看上去给我的清理工作提供了更多的支持。这个出奇的好消息被主流媒体所完全忽视了,这些媒体有着“流血的才是好新闻”的心态,即使是在信息安全领域。这是我们为什么不能得到好东西的又一个原因。 +* 在 CVE-2017-7921 和 7923 于 2017 年 9 月发表之后,我决定更密切地关注海康威视公司的设备,然后我惊恐地发现有一个黑客们还没有发现的方法可以用来入侵有漏洞的固件。于是我在 9 月中旬开启了一个全球范围的清理行动。超过一百万台硬盘录像机和摄像机(主要是海康威视和大华出品)在三周内被禁用,然后包括 IPVM.com 在内的媒体为这些攻击写了多篇报道。大华和海康威视在新闻公告中提到或暗示了这些攻击。大量的设备总算得到了固件升级。看到这次清理活动造成的困惑,我决定给这些闭路电视制造商写一篇[简短的总结][3](请原谅在这个粘贴板网站上的不和谐的语言)。这令人震惊的有漏洞而且在关键的安全补丁发布之后仍然在线的设备数量应该能够唤醒所有人,让他们知道现今的物联网补丁升级过程有多么无力。 +* 2017 年 9 月 28 日左右,Verisign 发表了报告称 2017 年第二季度的 DDoS 攻击数相比第一季度减少了 55%,而且攻击峰值大幅减少了 81%。 +* 2017 年 11 月 23 日,CDN 供应商 Cloudflare 报道称“近几个月来,Cloudflare 看到试图用垃圾流量挤满我们的网络的简单进攻尝试有了大幅减少”。Cloudflare 推测这可能和他们的政策变化有一定关系,但这些减少也和物联网清理行动有着明显的重合。 +* 2017 年 11 月底,Akamai 的 2017 年第三季度互联网现状报告称 DDoS 攻击数较前一季度小幅增加了 8%。虽然这相比 2016 年的第三季度已经减少了很多,但这次小幅上涨提醒我们危险仍然存在。 +* 作为潜在危险的更进一步的提醒,一个叫做“Satori”的新的 Mirai 变种于 2017 年 11 月至 12 月开始冒头。这个僵尸网络仅仅通过一个 0-day 漏洞而达成的增长速度非常值得注意。这起事件凸显了互联网的危险现状,以及我们为什么距离大规模的事故只差一两起物联网入侵。当下一次威胁发生而且没人阻止的时候,会发生什么?Sinkholing 和其他的白帽或“合法”的缓解措施在 2018 年不会有效,就像它们在 2016 年也不曾有效一样。也许未来各国政府可以合作创建一个国际范围的反黑客特别部队来应对特别严重的会影响互联网存续的威胁,但我并不抱太大期望。 +* 在年末出现了一些危言耸听的新闻报道,有关被一个被称作“Reaper”和“IoTroop”的新的僵尸网络。我知道你们中有些人最终会去嘲笑那些把它的规模估算为一两百万的人,但你们应该理解这些网络安全研究者们对网络上发生的事情以及不由他们掌控的硬件的事情都是一知半解。实际来说,研究者们不可能知道或甚至猜测到大部分有漏洞的设备在僵尸网络出现时已经被禁用了。给“Reaper”一两个新的未经处理的 0-day 漏洞的话,它就会变得和我们最担心的事情一样可怕。 + +### 3. 临别赠言 + +我很抱歉把你们留在这种境况当中,但我的人身安全受到的威胁已经不允许我再继续下去。我树了很多敌人。如果你想要帮忙,请看前面列举的该做的事情。祝你好运。 + +也会有人批评我,说我不负责任,但这完全找错了重点。真正的重点是如果一个像我一样没有黑客背景的人可以做我做到的事情,那么一个比我厉害的人可以在 2017 年对互联网做比这要可怕太多的事情。我并不是问题本身,我也不是来遵循任何人制定的规则的。我只是报信的人。你越早意识到这点越好。 + +-Dr Cyborkian 又名 janit0r,“病入膏肓”的设备的调节者。 + +-------------------------------------------------------------------------------- + +via:https://ghostbin.com/paste/q2vq2 + +作者:janit0r +译者:[yixunx](https://github.com/yixunx) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译, +[Linux中国](https://linux.cn/) 荣誉推出 + +[1]:https://www.telecompaper.com/news/venezuelan-operators-hit-by-unprecedented-cyberattack--1208384 +[2]:https://github.com/JeremyNGalloway/mod_plaintext.py +[3]:http://depastedihrn3jtw.onion.link/show.php?md5=62d1d87f67a8bf485d43a05ec32b1e6f \ No newline at end of file From c610ace827a4538e1556db2f2c45392066f52819 Mon Sep 17 00:00:00 2001 From: darksun Date: Wed, 31 Jan 2018 14:12:04 +0800 Subject: [PATCH 080/272] =?UTF-8?q?=E9=80=89=E9=A2=98:=20Installing=20Awst?= =?UTF-8?q?at=20for=20analyzing=20Apache=20logs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...alling Awstat for analyzing Apache logs.md | 117 ++++++++++++++++++ 1 file changed, 117 insertions(+) create mode 100644 sources/tech/20180123 Installing Awstat for analyzing Apache logs.md diff --git a/sources/tech/20180123 Installing Awstat for analyzing Apache logs.md b/sources/tech/20180123 Installing Awstat for analyzing Apache logs.md new file mode 100644 index 0000000000..b635417a47 --- /dev/null +++ b/sources/tech/20180123 Installing Awstat for analyzing Apache logs.md @@ -0,0 +1,117 @@ +Installing Awstat for analyzing Apache logs +====== +AWSTAT is free an very powerful log analyser tool for apache log files. After analyzing logs from apache, it present them in easy to understand graphical format. Awstat is short for Advanced Web statistics & it works on command line interface or on CGI. + +In this tutorial, we will be installing AWSTAT on our Centos 7 machine for analyzing apache logs. + +( **Recommended read** :[ **Scheduling important jobs with crontab**][1]) + +### Pre-requisites + + **1-** A website hosted on apache web server, to create one read below mentioned tutorials on apache web servers, + +( **Recommended reads** - [**installing Apache**][2], [**Securing apache with SSL cert**][3] & **hardening tips for apache** ) + + **2-** Epel repository enabled on the system, as Awstat packages are not available on default repositories. To enable epel-repo , run + +``` +$ rpm -Uvh https://dl.fedoraproject.org/pub/epel/7/x86_64/e/epel-release-7-10.noarch.rpm +``` + +### Installing Awstat + +Once the epel-repository has been enabled on the system, awstat can be installed by running, + +``` + $ yum install awstat +``` + +When awstat is installed, it creates a file for apache at '/etc/httpd/conf.d/awstat.conf' with some configurations. These configurations are good to be used incase web server &awstat are configured on the same machine but if awstat is on different machine than the webserver, then some changes are to be made to the file. + +#### Configuring Apache for Awstat + +To configure awstat for a remote web server, open /etc/httpd/conf.d/awstat.conf, & update the parameter 'Allow from' with the IP address of the web server + +``` +$ vi /etc/httpd/conf.d/awstat.conf + + +Options None +AllowOverride None + +# Apache 2.4 +Require local + + +# Apache 2.2 +Order allow,deny +Allow from 127.0.0.1 +Allow from 192.168.1.100 + + +``` + +Save the file & restart the apache services to implement the changes, + +``` + $ systemctl restart httpd +``` + +#### Configuring AWSTAT + +For every website that we add to awstat, a different configuration file needs to be created with the website information . An example file is created in folder '/etc/awstats' by the name 'awstats.localhost.localdomain.conf', we can make copies of it & configure our website with this, + +``` +$ cd /etc/awstats +$ cp awstats.localhost.localdomain.conf awstats.linuxtechlab.com.conf +``` + +Now open the file & edit the following three parameters to match your website, + +``` +$ vi awstats.linuxtechlab.com.conf + +LogFile="/var/log/httpd/access.log" +SiteDomain="linuxtechlab.com" +HostAliases=www.linuxtechlab.com localhost 127.0.0.1 +``` + +Last step is to update the configuration file, which can be done executing the command below, + +``` +/usr/share/awstats/wwwroot/cgi-bin/awstats.pl -config=linuxtechlab.com -update +``` + +#### Checking the awstat page + +To test/check the awstat page, open web-browser & enter the following URL in the address bar, +**https://linuxtechlab.com/awstats/awstats.pl?config=linuxtechlab.com** + +![awstat][5] + +**Note-** we can also schedule a cron job to update the awstat on regular basis. An example for the crontab + +``` +$ crontab -e +0 1 * * * /usr/share/awstats/wwwroot/cgi-bin/awstats.pl -config=linuxtechlab.com–update +``` + +We now end our tutorial on installing Awstat for analyzing apache logs, please leave your comments/queries in the comment box below. + + +-------------------------------------------------------------------------------- + +via: http://linuxtechlab.com/installing-awstat-analyzing-apache-logs/ + +作者:[SHUSAIN][a] +译者:[译者ID](https://github.com/译者ID) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:http://linuxtechlab.com/author/shsuain/ +[1]:http://linuxtechlab.com/scheduling-important-jobs-crontab/ +[2]:http://linuxtechlab.com/beginner-guide-configure-apache/ +[3]:http://linuxtechlab.com/create-ssl-certificate-apache-server/ +[4]:https://i1.wp.com/linuxtechlab.com/wp-content/plugins/a3-lazy-load/assets/images/lazy_placeholder.gif?resize=602%2C312 +[5]:https://i0.wp.com/linuxtechlab.com/wp-content/uploads/2017/04/awstat.jpg?resize=602%2C312 From a0e37d8b6a8adffd643a76ee0c6729f78a1fe404 Mon Sep 17 00:00:00 2001 From: darksun Date: Wed, 31 Jan 2018 14:17:04 +0800 Subject: [PATCH 081/272] =?UTF-8?q?=E9=80=89=E9=A2=98:=20How=20to=20Use=20?= =?UTF-8?q?DockerHub?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sources/tech/20180129 How to Use DockerHub.md | 135 ++++++++++++++++++ 1 file changed, 135 insertions(+) create mode 100644 sources/tech/20180129 How to Use DockerHub.md diff --git a/sources/tech/20180129 How to Use DockerHub.md b/sources/tech/20180129 How to Use DockerHub.md new file mode 100644 index 0000000000..3793a6b718 --- /dev/null +++ b/sources/tech/20180129 How to Use DockerHub.md @@ -0,0 +1,135 @@ +How to Use DockerHub +====== + +![](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/dockerhub-container.jpg?itok=tvraxGzh) + +In the previous articles, we learned the basics of [Docker terminology][1], [how to install Docker][2] on desktop Linux, macOS, and Windows, and [how to create container images][3] and run them on your system. In this last article in the series, we will talk about using images from DockerHub and publishing your own images to DockerHub. + +First things first: what is DockerHub and why is it important? DockerHub is a cloud-based repository run and managed by Docker Inc. It's an online repository where Docker images can be published and used by other users. There are both public and private repositories. If you are a company, you can have a private repository for use within your own organization, whereas public images can be used by anyone. + +You can also use official Docker images that are published publicly. I use many such images, including for my test WordPress installations, KDE plasma apps, and more. Although we learned last time how to create your own Docker images, you don't have to. There are thousands of images published on DockerHub for you to use. DockerHub is hardcoded into Docker as the default registry, so when you run the docker pull command against any image, it will be downloaded from DockerHub. + +### Download images from Docker Hub and run locally + +Please check out the previous articles in the series to get started. Then, once you have Docker running on your system, you can open the terminal and run: +``` +$ docker images +``` + +This command will show all the docker images currently on your system. Let's say you want to deploy Ubuntu on your local machine; you would do: +``` +$ docker pull ubuntu +``` + +If you already have Ubuntu image on your system, the command will automatically update that image to the latest version. So, if you want to update the existing images, just run the docker pull command, easy peasy. It's like apt-get upgrade without any muss and fuss. + +You already know how to run an image: +``` +$ docker run -it + +$ docker run -it ubuntu +``` + +The command prompt should change to something like this: +``` +root@1b3ec4621737:/# +``` + +Now you can run any command and utility that you use on Ubuntu. It's all safe and contained. You can run all the experiments and tests you want on that Ubuntu. Once you are done testing, you can nuke the image and download a new one. There is no system overhead that you would get with a virtual machine. + +You can exit that container by running the exit command: +``` +$ exit +``` + +Now let's say you want to install Nginx on your system. Run search to find the desired image: +``` +$ docker search nginx + +aizMFFysICAEsgDDYrsrlqwoCgGbWVHtcOzgV9mA +``` + +As you can see, there are many images of Nginx on DockerHub. Why? Because anyone can publish an image. Various images are optimized for different projects, so you can choose the appropriate image. You just need to install the appropriate image for your use-case. + +Let's say you want to pull Bitnami's Nginx container: +``` +$ docker pull bitnami/nginx +``` + +Now run it with: +``` +$ docker run -it bitnami/nginx +``` + +### How to publish images to Docker Hub? + +Previously, [we learned how to create a Docker image][3], and we can easily publish that image to DockerHub. First, you need to log into DockerHub. If you don't already have an account, please [create one][5]. Then, you can open terminal app and log in: +``` +$ docker login --username= +``` + +Replace with the name of your username for Docker Hub. In my case it's arnieswap: +``` +$ docker login --username=arnieswap> +``` + +Enter the password, and you are logged in. Now run the docker images command to get the ID of the image that you created last time. +``` +$ docker images + +tW1jDOugkX7J2FfyFyToM6B8m5OYFwMba-Ag5aez +``` + +Now, suppose you want to push the ng image to DockerHub. First, we need to tag that image ([learn more about tags][1]): +``` +$ docker tag e7083fd898c7 arnieswap/my_repo:testing +``` + +Now push that image: +``` +$ docker push arnieswap/my_repo +``` + +The push refers to repository [docker.io/arnieswap/my_repo] +``` +12628b20827e: Pushed + +8600ee70176b: Mounted from library/ubuntu + +2bbb3cec611d: Mounted from library/ubuntu + +d2bb1fc88136: Mounted from library/ubuntu + +a6a01ad8b53f: Mounted from library/ubuntu + +833649a3e04c: Mounted from library/ubuntu + +testing: digest: sha256:286cb866f34a2aa85c9fd810ac2cedd87699c02731db1b8ca1cfad16ef17c146 size: 1569 + +``` + +Eureka! Your image is being uploaded. Once finished, open DockerHub, log into your account, and you can see your very first Docker image. Now anyone can deploy your image. It's the easiest and fastest way to develop and distribute software. Whenever you update the image, users can simply run: +``` +$ docker run arnieswap/my_repo +``` + +Now you know why people love Docker containers. They solve many problems that traditional workloads face and allow you develop, test, and deploy applications in no time. And, by following the steps in this series, you can try them out for yourself. + + +-------------------------------------------------------------------------------- + +via: https://www.linux.com/blog/learn/intro-to-linux/2018/1/how-use-dockerhub + +作者:[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/intro-to-linux/2017/12/container-basics-terms-you-need-know +[2]:https://www.linux.com/blog/learn/intro-to-linux/how-install-docker-ce-your-desktop +[3]:https://www.linux.com/blog/learn/intro-to-linux/2018/1/how-create-docker-image +[4]:https://lh3.googleusercontent.com/aizMFFysICAEsgDDYrsrlqwoCgGbWVHtcOzgV9mAtV8IdBZgHPJTdHIZhWBNCRvOyJb108ZBajJ_Nz10yCxGSvk-AF-yvFxpojLdVu3Jjihcwaup6CQLc67A5nglBuGDaOZWcrbV +[5]:https://hub.docker.com/ +[6]:https://lh6.googleusercontent.com/tW1jDOugkX7J2FfyFyToM6B8m5OYFwMba-Ag5aezVGf2A5gsKJ47QrCh_TOKWgIKfE824Uc2Cwwwj9jWps1yJlUZqDyIceVQs-nEbKavFDxuUxLyd4thBA4_rsXrQH4r7hrG8FnD From e2b7294af57b2b276099dfd1f93d0e896fd19309 Mon Sep 17 00:00:00 2001 From: darksun Date: Wed, 31 Jan 2018 14:23:10 +0800 Subject: [PATCH 082/272] =?UTF-8?q?=E9=80=89=E9=A2=98:=20How=20To=20Resume?= =?UTF-8?q?=20Partially=20Transferred=20Files=20Over=20SSH=20Using=20Rsync?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ... Transferred Files Over SSH Using Rsync.md | 101 ++++++++++++++++++ 1 file changed, 101 insertions(+) create mode 100644 sources/tech/20180129 How To Resume Partially Transferred Files Over SSH Using Rsync.md diff --git a/sources/tech/20180129 How To Resume Partially Transferred Files Over SSH Using Rsync.md b/sources/tech/20180129 How To Resume Partially Transferred Files Over SSH Using Rsync.md new file mode 100644 index 0000000000..5e0583ab4f --- /dev/null +++ b/sources/tech/20180129 How To Resume Partially Transferred Files Over SSH Using Rsync.md @@ -0,0 +1,101 @@ +How To Resume Partially Transferred Files Over SSH Using Rsync +====== + +![](https://www.ostechnix.com/wp-content/uploads/2016/02/Resume-Partially-Transferred-Files-Over-SSH-Using-Rsync.png) + +There are chances that the large files which are being copied over SSH using SCP command might be interrupted or cancelled or broken due to various reasons such as power failure or network failure or user intervention. The other day I was copying the Ubuntu 16.04 ISO file to my remote system. Unfortunately, the power is gone, and the network connection is dropped immediately. The result? The copy process is terminated! This is just a simple example. The Ubuntu ISO is not so big, and I could restart the copy process as soon as the power is restored. But in production environment, you might not want to do it while you're transferring large files. + +Also, you can't always resume the aborted process using **scp** command. Because, If you do, It will simply overwrite the existing files. What would you do in such situations? No worries! This is where **Rsync** utility comes in handy! Rsync can help you to resume the interrupted copy or download process where you left it off. For those wondering, Rsync is a fast, versatile file copying utility that can be used to copy and transfer files or folders to and from remote and local systems. + +It offers a large number of options that control every aspect of its behavior and permit very flexible specification of the set of files to be copied. It is famous for its delta-transfer algorithm, which reduces the amount of data sent over the network by sending only the differences between the source files and the existing files in the destination. Rsync is widely used for backups and mirroring and as an improved copy command for everyday use. + +Just like SCP, rsync will also copy files over SSH. In case you wanted to download or transfer a big files and folders over SSH, I recommend you to use rsync utility. Be mindful that the **rsync utility should be installed on both sides** (remote and local systems) in order to resume partially transferred files. + +### Resume Partially Transferred Files Using Rsync + +Well, let me show you an example. I am going to copy Ubuntu 16.04 ISO from my local system to remote system with command: + +``` +$ scp Soft_Backup/OS\ Images/Linux/ubuntu-16.04-desktop-amd64.iso sk@192.168.43.2:/home/sk/ +``` + +Here, + + * **sk** is my remote system 's username + * **192.168.43.2** is the IP address of the remote machine. + + + +Now, I terminated it by pressing **CTRL+c**. + +**Sample output:** + +``` +sk@192.168.43.2's password: +ubuntu-16.04-desktop-amd64.iso 26% 372MB 26.2MB/s 00:39 ETA^c +``` + +[![][1]][2] + +As you see in the above output, I terminated the copy process when it reached 26%. + +If I re-run the above command, it will simply overwrite the existing file. In other words, the copy process will not resume where I left it off. + +In order to resume the copy process, we can use **rsync** command as shown below. + +``` +$ rsync -P -rsh=ssh Soft_Backup/OS\ Images/Linux/ubuntu-16.04-desktop-amd64.iso sk@192.168.43.2:/home/sk/ +``` + +**Sample output:** +``` +sk@192.168.1.103's password: +sending incremental file list +ubuntu-16.04-desktop-amd64.iso +                   380.56M 26% 41.05MB/s 0:00:25 +``` + +[![][1]][4] + +See? Now, the copying process is resumed where we left it off earlier. You also can use "-partial" instead of parameter "-P" like below. +``` +$ rsync --partial -rsh=ssh Soft_Backup/OS\ Images/Linux/ubuntu-16.04-desktop-amd64.iso sk@192.168.43.2:/home/sk/ +``` + +Here, the parameter "-partial" or "-P" tells the rsync command to keep the partial downloaded file and resumes the process. + +Alternatively, we can use the following commands as well to resume partially transferred files over SSH. + +``` +$ rsync -avP Soft_Backup/OS\ Images/Linux/ubuntu-16.04-desktop-amd64.iso sk@192.168.43.2:/home/sk/ +``` + +Or, + +``` +rsync -av --partial Soft_Backup/OS\ Images/Linux/ubuntu-16.04-desktop-amd64.iso sk@192.168.43.2:/home/sk/ +``` + +That's it. You know now how to resume the cancelled, interrupted, and partially downloaded files using rsync command. As you can see, it is not so difficult either. If rsync is installed on both systems, we can easily resume the copy process as described above. + +If you find this tutorial helpful, please share it on your social, professional networks and support OSTechNix. More good stuffs to come. Stay tuned! + +Cheers! + + + +-------------------------------------------------------------------------------- + +via: https://www.ostechnix.com/how-to-resume-partially-downloaded-or-transferred-files-using-rsync/ + +作者:[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/ +[1]:data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7 +[2]:http://www.ostechnix.com/wp-content/uploads/2016/02/scp.png () +[3]:/cdn-cgi/l/email-protection +[4]:http://www.ostechnix.com/wp-content/uploads/2016/02/rsync.png () From 01b8bf9d4ba49a51dc2151c25f3d1ca6e74af4ec Mon Sep 17 00:00:00 2001 From: darksun Date: Wed, 31 Jan 2018 14:28:16 +0800 Subject: [PATCH 083/272] =?UTF-8?q?=E9=80=89=E9=A2=98:=20WebSphere=20MQ=20?= =?UTF-8?q?programming=20in=20Python=20with=20Zato?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...here MQ programming in Python with Zato.md | 262 ++++++++++++++++++ 1 file changed, 262 insertions(+) create mode 100644 sources/tech/20180129 WebSphere MQ programming in Python with Zato.md diff --git a/sources/tech/20180129 WebSphere MQ programming in Python with Zato.md b/sources/tech/20180129 WebSphere MQ programming in Python with Zato.md new file mode 100644 index 0000000000..3e53d67201 --- /dev/null +++ b/sources/tech/20180129 WebSphere MQ programming in Python with Zato.md @@ -0,0 +1,262 @@ +WebSphere MQ programming in Python with Zato +====== +[WebSphere MQ][1] is a messaging middleware product by IBM - a message queue server - and this post shows how to integrate with MQ from Python and [Zato][2]. + +The article will go through a short process that will let you: + + * Send messages to queues in 1 line of Python code + * Receive messages from queues without coding + * Seamlessly integrate with Java JMS applications - frequently found in WebSphere MQ environments + * Push MQ messages from [Django][3] or [Flask][4] + + + +### Prerequisites + + * [Zato][2] 3.0+ (e.g. from [source code][5]) + * WebSphere MQ 6.0+ + + + +### Preliminary steps + + * Obtain connection details and credentials to the queue manager that you will be connecting to: + + * host, e.g. 10.151.13.11 + * port, e.g. 1414 + * channel name, e.g. DEV.SVRCONN.1 + * queue manager name (optional) + * username (optional) + * password (optional) + * Install [Zato][6] + + * On the same system that Zato is on, install a [WebSphere MQ Client][7] \- this is an umbrella term for a set of development headers and libraries that let applications connect to remote queue managers + + * Install [PyMQI][8] \- an additional dependency implementing the low-level proprietary MQ protocol. Note that you need to use the pip command that Zato ships with: + + + +``` +# Assuming Zato is in /opt/zato/current +zato$ cd /opt/zato/current/bin +zato$ ./pip install pymqi + +``` + + * That is it - everything is installed and the rest is a matter of configuration + + + +### Understanding definitions, outgoing connections and channels + +Everything in Zato revolves around re-usability and hot-reconfiguration - each individual piece of configuration can be changed on the fly, while servers are running, without restarts. + +Note that the concepts below are presented in the context of WebSphere MQ but they apply to other connection types in Zato too. + + * **Definitions** \- encapsulate common details that apply to other parts of configuration, e.g. a connection definition may contain remote host and port + * **Outgoing connections** \- objects through which data is sent to remote resources, such as MQ queues + * **Channels** \- objects through which data can be received, for instance, from MQ queues + + + +It is usually most convenient to configure environments during development using [web-admin GUI][9] but afterwards this can be automated with [enmasse][10], [API][11] or [command-line interface][12]. + +Once configuration is defined, it can be used from Zato services which in turn represent APIs that Zato clients invoke. Then, external applications, such as a Django or Flask, will connect using HTTP to a Zato service which will on their behalf send messages to MQ queues. + +Let's use web-admin to define all the Zato objects required for MQ integrations. (Hint: web-admin by default runs on ) + +### Definition + + * Go to Connections -> Definitions -> WebSphere MQ + * Fill out the form and click OK + * Observe the 'Use JMS' checkbox - more about it later on + + + +![Screenshots][13] + + * Note that a password is by default set to an unusable one (a random UUID4) so once a definition is created, click on Change password to set it to a required one + + + +![Screenshots][14] + + * Click Ping to confirm that connections to the remote queue manager can be established + + + +![Screenshots][15] + +### Outgoing connection + + * Go to Connections -> Outgoing -> WebSphere MQ + * Fill out the form - the connection's name is just a descriptive label + * Note that you do not specify a queue name here - this is because a single connection can be used with as many queues as needed + + + +![Screenshots][16] + + * You can now send a test MQ message directly from web-admin after click Send a message + + + +![Screenshots][17] + +![Screenshots][18] + +### API services + + * Having carried out the steps above, you can now send messages to queue managers from web-admin, which is a great way to confirm MQ-level connectivity but the crucial point of using Zato is to offer API services to client applications so let's create two services now, one for sending messages to MQ and one that will receive them. + + + +``` +# -*- coding: utf-8 -*- + +from __future__ import absolute_import, division, print_function, unicode_literals + +# Zato +from zato.server.service import Service + +class MQSender(Service): + """ Sends all incoming messages as they are straight to a remote MQ queue. + """ + def handle(self): + + # This single line suffices + self.out.wmq.send(self.request.raw_request, 'customer.updates', 'CUSTOMER.1') +``` + + * In practice, a service such as the one above could perform transformation on incoming messages or read its destination queue names from configuration files but it serves to illustrate the point that literally 1 line of code is needed to send MQ messages + + * Let's create a channel service now - one that will act as a callback invoked for each message consumed off a queue: + + + +``` +# -*- coding: utf-8 -*- + +from __future__ import absolute_import, division, print_function, unicode_literals + +# Zato +from zato.server.service import Service + +class MQReceiver(Service): + """ Invoked for each message taken from a remote MQ queue + """ + def handle(self): + self.logger.info(self.request.raw_request) +``` + +But wait - if this is the service that is a callback one then how does it know which queue to get messages from? + +That is the key point of Zato architecture - services do not need to know it and unless you really need it, they won't ever access this information. + +Such configuration details are configured externally (for instance, in web-admin) and a service is just a black box that receives some input, operates on it and produces output. + +In fact, the very same service could be mounted not only on WebSphere MQ ones but also on REST or AMQP channels. + +Without further ado, let's create a channel in that case, but since this is an article about MQ, only this connection type will be shown even if the same principle applies to other channel types. + +### Channel + + * Go to Connections -> Channels -> WebSphere MQ + * Fill out the form and click OK + * Data format may be JSON, XML or blank if no automatic de-serialization is required + + + +![Screenshots][19] + +After clicking OK a lightweight background task will start to listen for messages pertaining to a given queue and upon receiving any, the service configured for channel will be invoked. + +You can start as many channels as there are queues to consume messages from, that is, each channel = one input queue and each channel may declare a different service. + +### JMS Java integration + +In many MQ environments the majority of applications will be based on Java JMS and Zato implements the underlying wire-level MQ JMS protocol to let services integrate with such systems without any effort from a Python programmer's perspective. + +When creating connection definitions, merely check Use JMS and everything will be taken care of under the hood - all the necessary wire headers will be added or removed when it needs to be done. + +![Screenshots][20] + +### No restarts required + +It's worth to emphasize again that at no point are server restarts required to reconfigure connection details. + +No matter how many definitions, outgoing connections, channels there are, and no matter of what kind they are (MQ or not), changing any of them will only update that very one across the whole cluster of Zato servers without interrupting other API services running concurrently. + +### Configuration wrap-up + + * MQ connection definitions are re-used across outgoing connections and channels + * Outgoing connections are used by services to send messages to queues + * Data from queues is read through channels that invoke user-defined services + * Everything is reconfigurable on the fly + + + +Let's now check how to add a REST channel for the MQSender service thus letting Django and Flask push MQ messages. + +### Django and Flask integration + + * Any Zato-based API service can be mounted on a channel + * For Django and Flask, it is most convenient to mount one's services on REST channels and invoke them using the [zato-client][21] from PyPI + * zato-client is a set of convenience clients that lets any Python application, including ones based on Django or Flask, to invoke Zato services in just a few steps + * There is [a dedicated chapter][22] in documentation about Django and Flask, including a sample integration scenario + * It's recommended to go through the chapter step-by-step - since all Zato configuration objects share the same principles, the whole of its information applies to any sort of technology that Django or Flask may need to integrate with, including WebSphere MQ + * After completing that chapter, to push messages to MQ, you will only need to: + * Create a security definition for a new REST channel for Django or Flask + * Create the REST channel itself + * Assign a service to it (e.g. MQSender) + * Use a Python client from zato-client to invoke that channel from Django or Flask + * And that is it - no MQ programming is needed to send messages to MQ queues from any Python application :-) + + + +### Summary + + * Zato lets Python programmers integrate with WebSphere MQ with little to no effort + * Built-in support for JMS lets one integrate with existing Java applications in a transparent manner + * Built-in Python clients offer trivial access to Zato-based API services from other Python applications, including Django or Flask + + + +Where to next? Start off with the [tutorial][23], then consult the [documentation][24], there is a lot of information for all types of API and integration projects, and have a look at [support options][25] in case you need absolutely any sort of assistance! + +-------------------------------------------------------------------------------- + +via: https://zato.io/blog/posts/websphere-mq-python-zato.html + +作者:[zato][a] +译者:[译者ID](https://github.com/译者ID) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://zato.io +[1]:https://en.wikipedia.org/wiki/IBM_WebSphere_MQ +[2]:https://zato.io/docs +[3]:https://www.djangoproject.com/ +[4]:http://flask.pocoo.org/ +[5]:https://zato.io/docs/admin/guide/install/source.html +[6]:https://zato.io/docs/admin/guide/install/index.html +[7]:https://www.ibm.com/support/knowledgecenter/en/SSFKSJ_7.0.1/com.ibm.mq.csqzaf.doc/cs10230_.htm +[8]:https://github.com/dsuch/pymqi/ +[9]:https://zato.io/docs/web-admin/intro.html +[10]:https://zato.io/docs/admin/guide/enmasse.html +[11]:https://zato.io/docs/public-api/intro.html +[12]:https://zato.io/docs/admin/cli/index.html +[13]:https://zato.io/blog/images/wmq-python-zato/def-create.png +[14]:https://zato.io/blog/images/wmq-python-zato/def-options.png +[15]:https://zato.io/blog/images/wmq-python-zato/def-ping.png +[16]:https://zato.io/blog/images/wmq-python-zato/outconn-create.png +[17]:https://zato.io/blog/images/wmq-python-zato/outconn-options.png +[18]:https://zato.io/blog/images/wmq-python-zato/outconn-send.png +[19]:https://zato.io/blog/images/wmq-python-zato/channel-create.png +[20]:https://zato.io/blog/images/wmq-python-zato/def-create-jms.png +[21]:https://pypi.python.org/pypi/zato-client +[22]:https://zato.io/docs/progguide/clients/django-flask.html +[23]:https://zato.io/docs/tutorial/01.html +[24]:https://zato.io/docs/ +[25]:https://zato.io/support.html From 669be9f617650be09a42876d9e39c0df38f5efe0 Mon Sep 17 00:00:00 2001 From: darksun Date: Wed, 31 Jan 2018 14:32:17 +0800 Subject: [PATCH 084/272] =?UTF-8?q?=E9=80=89=E9=A2=98:=20Install=20AWFFull?= =?UTF-8?q?=20web=20server=20log=20analysis=20application=20on=20ubuntu=20?= =?UTF-8?q?17.10?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...og analysis application on ubuntu 17.10.md | 95 +++++++++++++++++++ 1 file changed, 95 insertions(+) create mode 100644 sources/talk/20180130 Install AWFFull web server log analysis application on ubuntu 17.10.md diff --git a/sources/talk/20180130 Install AWFFull web server log analysis application on ubuntu 17.10.md b/sources/talk/20180130 Install AWFFull web server log analysis application on ubuntu 17.10.md new file mode 100644 index 0000000000..03e15878b9 --- /dev/null +++ b/sources/talk/20180130 Install AWFFull web server log analysis application on ubuntu 17.10.md @@ -0,0 +1,95 @@ +Install AWFFull web server log analysis application on ubuntu 17.10 +====== + + +AWFFull is a web server log analysis program based on "The Webalizer".AWFFull produces usage statistics in HTML format for viewing with a browser. The results are presented in both columnar and graphical format, which facilitates interpretation. Yearly, monthly, daily and hourly usage statistics are presented, along with the ability to display usage by site, URL, referrer, user agent (browser), user name,search strings, entry/exit pages, and country (some information may not be available if not present in the log file being processed). + + + +AWFFull supports CLF (common log format) log files, as well as Combined log formats as defined by NCSA and others, and variations of these which it attempts to handle intelligently. In addition, AWFFull also supports wu-ftpd xferlog formatted log files, allowing analysis of ftp servers, and squid proxy logs. Logs may also be compressed, via gzip. + +AWFFull is a web server log analysis program based on "The Webalizer".AWFFull produces usage statistics in HTML format for viewing with a browser. The results are presented in both columnar and graphical format, which facilitates interpretation. Yearly, monthly, daily and hourly usage statistics are presented, along with the ability to display usage by site, URL, referrer, user agent (browser), user name,search strings, entry/exit pages, and country (some information may not be available if not present in the log file being processed).AWFFull supports CLF (common log format) log files, as well as Combined log formats as defined by NCSA and others, and variations of these which it attempts to handle intelligently. In addition, AWFFull also supports wu-ftpd xferlog formatted log files, allowing analysis of ftp servers, and squid proxy logs. Logs may also be compressed, via gzip. + +If a compressed log file is detected, it will be automatically uncompressed while it is read. Compressed logs must have the standard gzip extension of .gz. + +### Changes from Webalizer + +AWFFull is based on the Webalizer code and has a number of large and small changes. These include: + +o Beyond the raw statistics: Making use of published formulae to provide additional insights into site usage. + +o GeoIP IP Address look-ups for more accurate country detection. + +o Resizable graphs. + +o Integration with GNU gettext allowing for ease of translations.Currently 32 languages are supported. + +o Display more than 12 months of the site history on the front page. + +o Additional page count tracking and sort by same. + +o Some minor visual tweaks, including Geolizer's use of Kb, Mb etc for Volumes. + +o Additional Pie Charts for URL counts, Entry and Exit Pages, and Sites. + +o Horizontal lines on graphs that are more sensible and easier to read. + +o User Agent and Referral tracking is now calculated via PAGES not HITS. + +o GNU style long command line options are now supported (eg --help). + +o Can choose what is a page by excluding "what isn't" vs the original "what is" method. + +o Requests to the site being analysed are displayed with the matching referring URL. + +o A Table of 404 Errors, and the referring URL can be generated. + +o An external CSS file can be used with the generated html. + +o Manual performance optimisation of the config file is now easier with a post analysis summary output. + +o Specified IP's & Addresses can be assigned to a given country. + +o Additional Dump options for detailed analysis with other tools. + +o Lotus Domino v6 logs are now detected and processed. + +**Install awffull on ubuntu 17.10** + +> sudo apt-get install awffull + +### Configuring AWFFULL + +You have to edit awffull config file at /etc/awffull/awffull.conf. If you have multiple virtual websites running in the same machine, you can make several copies of the default config file. + +> sudo vi /etc/awffull/awffull.conf + +Make sure the following lines are there + +> LogFile /var/log/apache2/access.log.1 +> OutputDir /var/www/html/awffull + +Save and exit the file + +You can run the awffull config using the following command + +> awffull -c [your config file name] + +This will create all the required files under /var/www/html/awffull directory so you can access your webserver stats using http://serverip/awffull/ + +You should see similar to the following screen + +If you have more site and you can automate the process using shell script and cron job. + + +-------------------------------------------------------------------------------- + +via: http://www.ubuntugeek.com/install-awffull-web-server-log-analysis-application-on-ubuntu-17-10.html + +作者:[ruchi][a] +译者:[译者ID](https://github.com/译者ID) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:http://www.ubuntugeek.com/author/ubuntufix From c44c26f067d4de7d130dfdb4ad9c2207be8019ff Mon Sep 17 00:00:00 2001 From: darksun Date: Wed, 31 Jan 2018 14:42:31 +0800 Subject: [PATCH 085/272] =?UTF-8?q?=E9=80=89=E9=A2=98:=20Linux=20Check=20I?= =?UTF-8?q?DE=20/=20SATA=20SSD=20Hard=20Disk=20Transfer=20Speed?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...IDE - SATA SSD Hard Disk Transfer Speed.md | 134 ++++++++++++++++++ 1 file changed, 134 insertions(+) create mode 100644 sources/tech/20071007 Linux Check IDE - SATA SSD Hard Disk Transfer Speed.md diff --git a/sources/tech/20071007 Linux Check IDE - SATA SSD Hard Disk Transfer Speed.md b/sources/tech/20071007 Linux Check IDE - SATA SSD Hard Disk Transfer Speed.md new file mode 100644 index 0000000000..30e667fac3 --- /dev/null +++ b/sources/tech/20071007 Linux Check IDE - SATA SSD Hard Disk Transfer Speed.md @@ -0,0 +1,134 @@ +Linux Check IDE / SATA SSD Hard Disk Transfer Speed +====== +So how do you find out how fast is your hard disk under Linux? Is it running at the SATA I (150 MB/s) or SATA II (300 MB/s) or SATA III (6.0Gb/s) speed without opening computer case or chassis? + +You can use the **hdparm or dd command** to check hard disk speed. It provides a command line interface to various hard disk ioctls supported by the stock Linux ATA/IDE/SATA device driver subsystem. Some options may work correctly only with the latest kernels (make sure you have cutting edge kernel installed). I also recommend compiling hdparm with the included files from the most recent kernel source code. + +### How to measure hard disk data transfer speed using hdparm + +Login as the root user and enter the following command: +`$ sudo hdparm -tT /dev/sda` +OR +`$ sudo hdparm -tT /dev/hda` +Sample outputs: +``` +/dev/sda: + Timing cached reads: 7864 MB in 2.00 seconds = 3935.41 MB/sec + Timing buffered disk reads: 204 MB in 3.00 seconds = 67.98 MB/sec +``` + +For meaningful results, this operation should be **repeated 2-3 times**. This displays the speed of reading directly from the Linux buffer cache without disk access. This measurement is essentially an indication of the **throughput of the processor, cache, and memory** of the system under test. [Here is a for loop example][1], to run test 3 time in a row: +`for i in 1 2 3; do hdparm -tT /dev/hda; done` +Where, + + * **-t** :perform device read timings + * **-T** : perform cache read timings + * **/dev/sda** : Hard disk device file + + + +To [find out SATA hard disk link speed][2], enter: +`sudo hdparm -I /dev/sda | grep -i speed` +Output: +``` + * Gen1 signaling speed (1.5Gb/s) + * Gen2 signaling speed (3.0Gb/s) + * Gen3 signaling speed (6.0Gb/s) + +``` + +Above output indicate that my hard disk can use 1.5Gb/s, 3.0Gb/s, or 6.0Gb/s speed. Please note that your BIOS / Motherboard must have support for SATA-II/III: +`$ dmesg | grep -i sata | grep 'link up'` +[![Linux Check IDE SATA SSD Hard Disk Transfer Speed][3]][3] + +### dd Command + +You can use the dd command as follows to get speed info too: +``` +dd if=/dev/zero of=/tmp/output.img bs=8k count=256k +rm /tmp/output.img +``` + +Sample outputs: +``` +262144+0 records in +262144+0 records out +2147483648 bytes (2.1 GB) copied, 23.6472 seconds, **90.8 MB/s** + +``` + +The [recommended syntax for the dd command is as follows][4] +``` +dd if=/dev/input.file of=/path/to/output.file bs=block-size count=number-of-blocks oflag=dsync + +## GNU dd syntax ## +dd if=/dev/zero of=/tmp/test1.img bs=1G count=1 oflag=dsync + +## OR alternate syntax for GNU/dd ## +dd if=/dev/zero of=/tmp/testALT.img bs=1G count=1 conv=fdatasync +``` + + +Sample outputs from the last dd command: +``` +1+0 records in +1+0 records out +1073741824 bytes (1.1 GB, 1.0 GiB) copied, 4.23889 s, 253 MB/s +``` + +### Disks & storage - GUI tool + +You can also use disk utility located at System > Administration > Disk utility menu. Please note that in latest version of Gnome it is simply called Disks. + +#### How do I test the performance of my hard disk using Disks on Linux? + +To test the speed of your hard disk: + + 1. Open **Disks** from the **Activities** overview (press the Super key on your keyboard and type Disks) + 2. Choose the **disk** from the list in the **left pane** + 3. Select the menu button and select **Benchmark disk …** from the menu + 4. Click **Start Benchmark …** and adjust the Transfer Rate and Access Time parameters as desired. + 5. Choose **Start Benchmarking** to test how fast data can be read from the disk. Administrative privileges required. Enter your password + + + +A quick video demo of above procedure: + +https://www.cyberciti.biz/tips/wp-content/uploads/2007/10/disks-performance.mp4 + + +#### Read Only Benchmark (Safe option) + +Then, select > Read only: +![Fig.01: Linux Benchmarking Hard Disk Read Only Test Speed][5] +The above option will not destroy any data. + +#### Read and Write Benchmark (All data will be lost so be careful) + +Visit System > Administration > Disk utility menu > Click Benchmark > Click Start Read/Write Benchmark button: +![Fig.02:Linux Measuring read rate, write rate and access time][6] + +### About the author + +The author is the creator of nixCraft and a seasoned sysadmin and a trainer for the Linux operating system/Unix shell scripting. He has worked with global clients and in various industries, including IT, education, defense and space research, and the nonprofit sector. Follow him on [Twitter][7], [Facebook][8], [Google+][9]. + +-------------------------------------------------------------------------------- + +via: https://www.cyberciti.biz/tips/how-fast-is-linux-sata-hard-disk.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/bash-for-loop/ +[2]:https://www.cyberciti.biz/faq/linux-command-to-find-sata-harddisk-link-speed/ +[3]:https://www.cyberciti.biz/tips/wp-content/uploads/2007/10/Linux-Check-IDE-SATA-SSD-Hard-Disk-Transfer-Speed.jpg +[4]:https://www.cyberciti.biz/faq/howto-linux-unix-test-disk-performance-with-dd-command/ +[5]:https://www.cyberciti.biz/media/new/tips/2007/10/Linux-Hard-Disk-Speed-Benchmark.png (Linux Benchmark Hard Disk Speed) +[6]:https://www.cyberciti.biz/media/new/tips/2007/10/Linux-Hard-Disk-Read-Write-Benchmark.png (Linux Hard Disk Benchmark Read / Write Rate and Access Time) +[7]:https://twitter.com/nixcraft +[8]:https://facebook.com/nixcraft +[9]:https://plus.google.com/+CybercitiBiz From c833d883e82cc963da39d0023d24c196dc021eaa Mon Sep 17 00:00:00 2001 From: darksun Date: Wed, 31 Jan 2018 14:48:29 +0800 Subject: [PATCH 086/272] =?UTF-8?q?=E9=80=89=E9=A2=98:=20Quick=20Look=20at?= =?UTF-8?q?=20the=20Arch=20Based=20Indie=20Linux=20Distribution:=20MagpieO?= =?UTF-8?q?S?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...ased Indie Linux Distribution- MagpieOS.md | 78 +++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 sources/talk/20180130 Quick Look at the Arch Based Indie Linux Distribution- MagpieOS.md diff --git a/sources/talk/20180130 Quick Look at the Arch Based Indie Linux Distribution- MagpieOS.md b/sources/talk/20180130 Quick Look at the Arch Based Indie Linux Distribution- MagpieOS.md new file mode 100644 index 0000000000..a850a8fd33 --- /dev/null +++ b/sources/talk/20180130 Quick Look at the Arch Based Indie Linux Distribution- MagpieOS.md @@ -0,0 +1,78 @@ +Quick Look at the Arch Based Indie Linux Distribution: MagpieOS +====== +Most of the Linux distros that are in use today are either created and developed in the US or Europe. A young developer from Bangladesh wants to change all that. + +### Who is Rizwan? + +[Rizwan][1] is a computer science student from Bangladesh. He is currently studying to become a profession Python programmer. He started using Linux back in 2015. Working with Linux inspired him to create this own Linux distribution. He also wants to let the rest of the world know that Bangladesh is upgrading to Linux. + +He has also worked on creating a [live version of Linux From Scratch][2]. + +## ![MagpieOS Linux][3] + +### What is MagpieOS? + +Rizwan's new distro is named MagpieOS. [MagpieOS][4] is very simple. It is basically Arch with the GNOME3 desktop environment. MagpieOS also includes a custom repo with icons and themes (claimed to be) not available on other Arch-based distros or AUR. + +Here is a list of the software included with MagpieOS: Firefox, LibreOffice, Uget, Bleachbit, Notepadqq, SUSE Studio Image Writer, Pamac Package Manager, Gparted, Gimp, Rhythmbox, Simple Screen Recorder, all default GNOME software including Totem Video Player, and a new set of custom wallpaper. + +Currently, MagpieOS only supported the GNOME desktop environment. Rizwan picked it because it is his favorite. However, he plans to add more desktop environments in the future. + +Unfortunately, MagpieOS does not support the Bangla language or any other local languages. It supports GNOME's default language like English, Hindi etc. + +Rizwan named his distro MagpieOS because the [magpie][5] is the official bird of Bangladesh. + +## ![MagpieOS Linux][6] + +### Why Arch? + +Like most people, Rizwan started his Linux journey by using [Ubuntu][7]. In the beginning, he was happy with it. However, sometimes the software he wanted to install was not available in the repos and he had to hunt through Google looking for the correct PPA. He decided to switch to [Arch][8] because Arch has many packages that were not available on Ubuntu. Rizwan also liked the fact that Arch is a rolling release and would always be up-to-date. + +The problem with Arch is that it is complicated and time-consuming to install. So, Rizwan tried out several Arch-based distros and was not happy with any of them. He didn't like [Manjaro][9] because they did not have permission to use Arch's repos. Also, Arch repo mirrors are faster than Manjaro's and have more software. He liked [Antergos][10], but to install you need a constant internet connection. If your connection fails during installation, you have to start over. + +Because of these issues, Rizwan decided to create a simple distro that would give him and others an Arch install without all the hassle. He also hopes to get developers from his home country to switch from Ubuntu to Arch by using his distro. + +### How to Help Rizwan with MagpieOS + +If you are interested in helping Rizwan develop MagpieOS, you can contact him via the [MagpieOS website][4]. You can also check out the project's [GitHub page][11]. Rizwan said that he is not looking for financial support at the moment. + +## ![MagpieOS Linux][12] + +### Final Thoughts + +I installed MagpieOS to give it a quick once-over. It uses the [Calamares installer][13], which means installing it was relatively quick and painless. After I rebooted, I was greeted by an audio message welcoming me to MagpieOS. + +To be honest, it was the first time I have heard a post-install greeting. (Windows 10 might have one, but I'm not sure.) There was also a Mac OS-esque application dock at the bottom of the screen. Other than that, it felt like any other GNOME 3 desktop I have used. + +Considering that it's an indie project at the nascent stage, I won't recommend it using as your main OS. But if you are a distrohopper, you can surely give it a try. + +That being said, this is a good first try for a student seeking to put his country on the technological map. All the best, Rizwan. + +Have you already heard of MagpieOS? What is your favorite region or locally made Linux distro? Please let us know in the comments below. + +If you found this article interesting, please take a minute to share it on social media. + +-------------------------------------------------------------------------------- + +via: https://itsfoss.com/magpieos/ + +作者:[John Paul][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/john/ +[1]:https://twitter.com/Linux_Saikat +[2]:https://itsfoss.com/linux-from-scratch-live-cd/ +[3]:https://itsfoss.com/wp-content/uploads/2018/01/magpieos1.jpg +[4]:http://www.magpieos.net +[5]:https://en.wikipedia.org/wiki/Magpie +[6]:https://itsfoss.com/wp-content/uploads/2018/01/magpieos2.jpg +[7]:https://www.ubuntu.com +[8]:https://www.archlinux.org +[9]:http://manjaro.org +[10]:https://antergos.com +[11]:https://github.com/Rizwan-Hasan/MagpieOS +[12]:https://itsfoss.com/wp-content/uploads/2018/01/magpieos3.png +[13]:https://calamares.io From ebc1234c51574502fa1476a0c6e4125ef6b41753 Mon Sep 17 00:00:00 2001 From: darksun Date: Wed, 31 Jan 2018 14:53:53 +0800 Subject: [PATCH 087/272] =?UTF-8?q?=E9=80=89=E9=A2=98:=20Rapid,=20Secure?= =?UTF-8?q?=20Patching:=20Tools=20and=20Methods?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...pid, Secure Patching- Tools and Methods.md | 583 ++++++++++++++++++ 1 file changed, 583 insertions(+) create mode 100644 sources/tech/20180129 Rapid, Secure Patching- Tools and Methods.md diff --git a/sources/tech/20180129 Rapid, Secure Patching- Tools and Methods.md b/sources/tech/20180129 Rapid, Secure Patching- Tools and Methods.md new file mode 100644 index 0000000000..9ac7340c14 --- /dev/null +++ b/sources/tech/20180129 Rapid, Secure Patching- Tools and Methods.md @@ -0,0 +1,583 @@ +Rapid, Secure Patching: Tools and Methods +====== + +It was with some measure of disbelief that the computer science community greeted the recent [EternalBlue][1]-related exploits that have torn through massive numbers of vulnerable systems. The SMB exploits have kept coming (the most recent being [SMBLoris][2] presented at the last DEF CON, which impacts multiple SMB protocol versions, and for which Microsoft will issue no corrective patch. Attacks with these tools [incapacitated critical infrastructure][3] to the point that patients were even turned away from the British National Health Service. + +It is with considerable sadness that, during this SMB catastrophe, we also have come to understand that the famous Samba server presented an exploitable attack surface on the public internet in sufficient numbers for a worm to propagate successfully. I previously [have discussed SMB security][4] in Linux Journal, and I am no longer of the opinion that SMB server processes should run on Linux. + +In any case, systems administrators of all architectures must be able to down vulnerable network servers and patch them quickly. There is often a need for speed and competence when working with a large collection of Linux servers. Whether this is due to security situations or other concerns is immaterial—the hour of greatest need is not the time to begin to build administration tools. Note that in the event of an active intrusion by hostile parties, [forensic analysis][5] may be a legal requirement, and no steps should be taken on the compromised server without a careful plan and documentation. Especially in this new era of the black hats, computer professionals must step up their game and be able to secure vulnerable systems quickly. + +### Secure SSH Keypairs + +Tight control of a heterogeneous UNIX environment must begin with best-practice use of SSH authentication keys. I'm going to open this section with a simple requirement. SSH private keys must be one of three types: Ed25519, ECDSA using the E-521 curve or RSA keys of 3072 bits. Any key that does not meet those requirements should be retired (in particular, DSA keys must be removed from service immediately). + +The [Ed25519][6] key format is associated with Daniel J. Bernstein, who has such a preeminent reputation in modern cryptography that the field is becoming a DJB [monoculture][7]. The Ed25519 format is deigned for speed, security and size economy. If all of your SSH servers are recent enough to support Ed25519, then use it, and consider nothing else. + +[Guidance on creating Ed25519 keys][8] suggests 100 rounds for a work factor in the "-o" secure format. Raising the number of rounds raises the strength of the encrypted key against brute-force attacks (should a file copy of the private key fall into hostile hands), at the cost of more work and time in decrypting the key when ssh-add is executed. Although there always is [controversy and discussion][9] with security advances, I will repeat the guidance here and suggest that the best format for a newly created SSH key is this: + +``` + +ssh-keygen -a 100 -t ed25519 + +``` + +Your systems might be too old to support Ed25519—Oracle/CentOS/Red Hat 7 have this problem (the 7.1 release introduced support). If you cannot upgrade your old SSH clients and servers, your next best option is likely E-521, available in the ECDSA key format. + +The ECDSA curves came from the US government's National Institute of Standards (NIST). The best known and most implemented of all of the NIST curves are P-256, P-384 and E-521\. All three curves are approved for secret communications by a variety of government entities, but a number of cryptographers have [expressed growing suspicion][10] that the P-256 and P-384 curves are tainted. Well known cryptographer Bruce Schneier [has remarked][11]: "I no longer trust the constants. I believe the NSA has manipulated them through their relationships with industry." However, DJB [has expressed][12] limited praise of the E-521 curve: "To be fair I should mention that there's one standard NIST curve using a nice prime, namely 2521 – 1; but the sheer size of this prime makes it much slower than NIST P-256." All of the NIST curves have greater issues with "side channel" attacks than Ed25519—P-521 is certainly a step down, and many assert that none of the NIST curves are safe. In summary, there is a slight risk that a powerful adversary exists with an advantage over the P-256 and P-384 curves, so one is slightly inclined to avoid them. Note that even if your OpenSSH (source) release is capable of E-521, it may be [disabled by your vendor][13] due to patent concerns, so E-521 is not an option in this case. If you cannot use DJB's 2255 – 19 curve, this command will generate an E-521 key on a capable system: + +``` + +ssh-keygen -o -a 100 -b 521 -t ecdsa + +``` + +And, then there is the unfortunate circumstance with SSH servers that support neither ECDSA nor Ed25519\. In this case, you must fall back to RSA with much larger key sizes. An absolute minimum is the modern default of 2048 bits, but 3072 is a wiser choice: + +``` + +ssh-keygen -o -a 100 -b 3072 -t rsa + +``` + +Then in the most lamentable case of all, when you must use old SSH clients that are not able to work with private keys created with the -o option, you can remove the password on id_rsa and create a naked key, then use OpenSSL to encrypt it with AES256 in the PKCS#8 format, as [first documented by Martin Kleppmann][14]. Provide a blank new password for the keygen utility below, then supply a new password when OpenSSL reprocesses the key: + +``` + +$ cd ~/.ssh + +$ cp id_rsa id_rsa-orig + +$ ssh-keygen -p -t rsa +Enter file in which the key is (/home/cfisher/.ssh/id_rsa): +Enter old passphrase: +Key has comment 'cfisher@localhost.localdomain' +Enter new passphrase (empty for no passphrase): +Enter same passphrase again: +Your identification has been saved with the new passphrase. + +$ openssl pkcs8 -topk8 -v2 aes256 -in id_rsa -out id_rsa-strong +Enter Encryption Password: +Verifying - Enter Encryption Password: + +mv id_rsa-strong id_rsa +chmod 600 id_rsa + +``` + +After creating all of these keys on a newer system, you can compare the file sizes: + +``` + +$ ll .ssh +total 32 +-rw-------. 1 cfisher cfisher 801 Aug 10 21:30 id_ecdsa +-rw-r--r--. 1 cfisher cfisher 283 Aug 10 21:30 id_ecdsa.pub +-rw-------. 1 cfisher cfisher 464 Aug 10 20:49 id_ed25519 +-rw-r--r--. 1 cfisher cfisher 111 Aug 10 20:49 id_ed25519.pub +-rw-------. 1 cfisher cfisher 2638 Aug 10 21:45 id_rsa +-rw-------. 1 cfisher cfisher 2675 Aug 10 21:42 id_rsa-orig +-rw-r--r--. 1 cfisher cfisher 583 Aug 10 21:42 id_rsa.pub + +``` + +Although they are relatively enormous, all versions of OpenSSH that I have used have been compatible with the RSA private key in PKCS#8 format. The Ed25519 public key is now small enough to fit in 80 columns without word wrap, and it is as convenient as it is efficient and secure. + +Note that PuTTY may have problems using various versions of these keys, and you may need to remove passwords for a successful import into the PuTTY agent. + +These keys represent the most secure formats available for various OpenSSH revisions. They really aren't intended for PuTTY or other general interactive activity. Although one hopes that all users create strong keys for all situations, these are enterprise-class keys for major systems activities. It might be wise, however, to regenerate your system host keys to conform to these guidelines. + +These key formats may soon change. Quantum computers are causing increasing concern for their ability to run [Shor's Algorithm][15], which can be used to find prime factors to break these keys in reasonable time. The largest commercially available quantum computer, the [D-Wave 2000Q][16], effectively [presents under 200 qubits][17] for this activity, which is not (yet) powerful enough for a successful attack. NIST [announced a competition][18] for a new quantum-resistant public key system with a deadline of November 2017 In response, a team including DJB has released source code for [NTRU Prime][19]. It does appear that we will likely see a post-quantum public key format for OpenSSH (and potentially TLS 1.3) released within the next two years, so take steps to ease migration now. + +Also, it's important for SSH servers to restrict their allowed ciphers, MACs and key exchange lest strong keys be wasted on broken crypto (3DES, MD5 and arcfour should be long-disabled). My [previous guidance][20] on the subject involved the following (three) lines in the SSH client and server configuration (note that formatting in the sshd_config file requires all parameters on the same line with no spaces in the options; line breaks have been added here for clarity): + +``` + +Ciphers chacha20-poly1305@openssh.com, + aes256-gcm@openssh.com, + aes128-gcm@openssh.com, + aes256-ctr, + aes192-ctr, + aes128-ctr + +MACs hmac-sha2-512-etm@openssh.com, + hmac-sha2-256-etm@openssh.com, + hmac-ripemd160-etm@openssh.com, + umac-128-etm@openssh.com, + hmac-sha2-512, + hmac-sha2-256, + hmac-ripemd160, + umac-128@openssh.com + +KexAlgorithms curve25519-sha256@libssh.org, + diffie-hellman-group-exchange-sha256 + +``` + +Since the previous publication, RIPEMD160 is likely no longer safe and should be removed. Older systems, however, may support only SHA1, MD5 and RIPEMD160\. Certainly remove MD5, but users of PuTTY likely will want to retain SHA1 when newer MACs are not an option. Older servers can present a challenge in finding a reasonable Cipher/MAC/KEX when working with modern systems. + +At this point, you should have strong keys for secure clients and servers. Now let's put them to use. + +### Scripting the SSH Agent + +Modern OpenSSH distributions contain the ssh-copy-id shell script for easy key distribution. Below is an example of installing a specific, named key in a remote account: + +``` + +$ ssh-copy-id -i ~/.ssh/some_key.pub person@yourserver.com +ssh-copy-id: INFO: Source of key(s) to be installed: + "/home/cfisher/.ssh/some_key.pub" +ssh-copy-id: INFO: attempting to log in with the new key(s), + to filter out any that are already installed +ssh-copy-id: INFO: 1 key(s) remain to be installed -- + if you are prompted now it is to install the new keys +person@yourserver.com's password: + +Number of key(s) added: 1 + +Now try logging into the machine, with: + "ssh 'person@yourserver.com'" +and check to make sure that only the key(s) you wanted were added. + +``` + +If you don't have the ssh-copy-id script, you can install a key manually with the following command: + +``` + +$ ssh person@yourserver.com 'cat >> ~/.ssh/authorized_keys' < \ + ~/.ssh/some_key.pub + +``` + +If you have SELinux enabled, you might have to mark a newly created authorized_keys file with a security type; otherwise, the sshd server dæmon will be prevented from reading the key (the syslog may report this issue): + +``` + +$ ssh person@yourserver.com 'chcon -t ssh_home_t + ↪~/.ssh/authorized_keys' + +``` + +Once your key is installed, test it in a one-time use with the -i option (note that you are entering a local key password, not a remote authentication password): + +``` + +$ ssh -i ~/.ssh/some_key person@yourserver.com +Enter passphrase for key '/home/v-fishecj/.ssh/some_key': +Last login: Wed Aug 16 12:20:26 2017 from 10.58.17.14 +yourserver $ + +``` + +General, interactive users likely will cache their keys with an agent. In the example below, the same password is used on all three types of keys that were created in the previous section: + +``` + +$ eval $(ssh-agent) +Agent pid 4394 + +$ ssh-add +Enter passphrase for /home/cfisher/.ssh/id_rsa: +Identity added: ~cfisher/.ssh/id_rsa (~cfisher/.ssh/id_rsa) +Identity added: ~cfisher/.ssh/id_ecdsa (cfisher@init.com) +Identity added: ~cfisher/.ssh/id_ed25519 (cfisher@init.com) + +``` + +The first command above launches a user agent process, which injects environment variables (named SSH_AGENT_SOCK and SSH_AGENT_PID) into the parent shell (via eval). The shell becomes aware of the agent and passes these variables to the programs that it runs from that point forward. + +When launched, the ssh-agent has no credentials and is unable to facilitate SSH activity. It must be primed by adding keys, which is done with ssh-add. When called with no arguments, all of the default keys will be read. It also can be called to add a custom key: + +``` + +$ ssh-add ~/.ssh/some_key +Enter passphrase for /home/cfisher/.ssh/some_key: +Identity added: /home/cfisher/.ssh/some_key + ↪(cfisher@localhost.localdomain) + +``` + +Note that the agent will not retain the password on the key. ssh-add uses any and all passwords that you enter while it runs to decrypt keys that it finds, but the passwords are cleared from memory when ssh-add terminates (they are not sent to ssh-agent). This allows you to upgrade to new key formats with minimal inconvenience, while keeping the keys reasonably safe. + +The current cached keys can be listed with ssh-add -l (from, which you can deduce that "some_key" is an Ed25519): + +``` + +$ ssh-add -l +3072 SHA256:cpVFMZ17oO5n/Jfpv2qDNSNcV6ffOVYPV8vVaSm3DDo + /home/cfisher/.ssh/id_rsa (RSA) +521 SHA256:1L9/CglR7cstr54a600zDrBbcxMj/a3RtcsdjuU61VU + cfisher@localhost.localdomain (ECDSA) +256 SHA256:Vd21LEM4lixY4rIg3/Ht/w8aoMT+tRzFUR0R32SZIJc + cfisher@localhost.localdomain (ED25519) +256 SHA256:YsKtUA9Mglas7kqC4RmzO6jd2jxVNCc1OE+usR4bkcc + cfisher@localhost.localdomain (ED25519) + +``` + +While a "primed" agent is running, the SSH clients may use (trusting) remote servers fluidly, with no further prompts for credentials: + +``` + +$ sftp person@yourserver.com +Connected to yourserver.com. +sftp> quit + +$ scp /etc/passwd person@yourserver.com:/tmp +passwd 100% 2269 65.8KB/s 00:00 + +$ ssh person@yourserver.com + (motd for yourserver.com) +$ ls -l /tmp/passwd +-rw-r--r-- 1 root wheel 2269 Aug 16 09:07 /tmp/passwd +$ rm /tmp/passwd +$ exit +Connection to yourserver.com closed. + +``` + +The OpenSSH agent can be locked, preventing any further use of the credentials that it holds (this might be appropriate when suspending a laptop): + +``` + +$ ssh-add -x +Enter lock password: +Again: +Agent locked. + +$ ssh yourserver.com +Enter passphrase for key '/home/cfisher/.ssh/id_rsa': ^C + +``` + +It will provide credentials again when it is unlocked: + +``` + +$ ssh-add -X +Enter lock password: +Agent unlocked. + +``` + +You also can set ssh-agent to expire keys after a time limit with the -t option, which may be useful for long-lived agents that must clear keys after a set daily shift. + +General shell users may cache many types of keys with a number of differing agent implementations. In addition to the standard OpenSSH agent, users may rely upon PuTTY's pageant.exe, GNOME keyring or KDE Kwallet, among others (the use of the PUTTY agent could likely fill an article on its own). + +However, the goal here is to create "enterprise" keys for critical server controls. You likely do not want long-lived agents in order to limit the risk of exposure. When scripting with "enterprise" keys, you will run an agent only for the duration of the activity, then kill it at completion. + +There are special options for accessing the root account with OpenSSH—the PermitRootLogin parameter can be added to the sshd_config file (usually found in /etc/ssh). It can be set to a simple yes or no, forced-commands-only, which will allow only explicitly-authorized programs to be executed, or the equivalent options prohibit-password or without-password, both of which will allow access to the keys generated here. + +Many hold that root should not be allowed any access. [Michael W. Lucas][21] addresses the question in SSH Mastery: + +> Sometimes, it seems that you need to allow users to SSH in to the system as root. This is a colossally bad idea in almost all environments. When users must log in as a regular user and then change to root, the system logs record the user account, providing accountability. Logging in as root destroys that audit trail....It is possible to override the security precautions and make sshd permit a login directly as root. It's such a bad idea that I'd consider myself guilty of malpractice if I told you how to do it. Logging in as root via SSH almost always means you're solving the wrong problem. Step back and look for other ways to accomplish your goal. + +When root action is required quickly on more than a few servers, the above advice can impose painful delays. Lucas' direct criticism can be addressed by allowing only a limited set of "bastion" servers to issue root commands over SSH. Administrators should be forced to log in to the bastions with unprivileged accounts to establish accountability. + +However, one problem with remotely "changing to root" is the [statistical use of the Viterbi algorithm][22] Short passwords, the su - command and remote SSH calls that use passwords to establish a trinary network configuration are all uniquely vulnerable to timing attacks on a user's keyboard movement. Those with the highest security concerns will need to compensate. + +For the rest of us, I recommend that PermitRootLogin without-password be set for all target machines. + +Finally, you can easily terminate ssh-agent interactively with the -k option: + +``` + +$ eval $(ssh-agent -k) +Agent pid 4394 killed + +``` + +With these tools and the intended use of them in mind, here is a complete script that runs an agent for the duration of a set of commands over a list of servers for a common named user (which is not necessarily root): + +``` + +# cat artano + +#!/bin/sh + +if [[ $# -lt 1 ]]; then echo "$0 - requires commands"; exit; fi + +R="-R5865:127.0.0.1:5865" # set to "-2" if you don't want + ↪port forwarding + +eval $(ssh-agent -s) + +function cleanup { eval $(ssh-agent -s -k); } + +trap cleanup EXIT + +function remsh { typeset F="/tmp/${1}" h="$1" p="$2"; + ↪shift 2; echo "#$h" + if [[ "$ARTANO" == "PARALLEL" ]] + then ssh "$R" -p "$p" "$h" "$@" < /dev/null >>"${F}.out" + ↪2>>"${F}.err" & + else ssh "$R" -p "$p" "$h" "$@" + fi } # HOST PORT CMD + +if ssh-add ~/.ssh/master_key +then remsh yourserver.com 22 "$@" + remsh container.yourserver.com 2200 "$@" + remsh anotherserver.com 22 "$@" + # Add more hosts here. +else echo Bad password - killing agent. Try again. +fi + +wait + +####################################################################### +# Examples: # Artano is an epithet of a famous mythical being +# artano 'mount /patchdir' # you will need an fstab entry for this +# artano 'umount /patchdir' +# artano 'yum update -y 2>&1' +# artano 'rpm -Fvh /patchdir/\*.rpm' +####################################################################### + +``` + +This script runs all commands in sequence on a collection of hosts by default. If the ARTANO environment variable is set to PARALLEL, it instead will launch them all as background processes simultaneously and append their STDOUT and STDERR to files in /tmp (this should be no problem when dealing with fewer than a hundred hosts on a reasonable server). The PARALLEL setting is useful not only for pushing changes faster, but also for collecting audit results. + +Below is an example using the yum update agent. The source of this particular invocation had to traverse a firewall and relied on a proxy setting in the /etc/yum.conf file, which used the port-forwarding option (-R) above: + +``` + +# ./artano 'yum update -y 2>&1' +Agent pid 3458 +Enter passphrase for /root/.ssh/master_key: +Identity added: /root/.ssh/master_key (/root/.ssh/master_key) +#yourserver.com +Loaded plugins: langpacks, ulninfo +No packages marked for update +#container.yourserver.com +Loaded plugins: langpacks, ulninfo +No packages marked for update +#anotherserver.com +Loaded plugins: langpacks, ulninfo +No packages marked for update +Agent pid 3458 killed + +``` + +The script can be used for more general maintenance functions. Linux installations running the XFS filesystem should "defrag" periodically. Although this normally would be done with cron, it can be a centralized activity, stored in a separate script that includes only on the appropriate hosts: + +``` + +&1' +Agent pid 7897 +Enter passphrase for /root/.ssh/master_key: +Identity added: /root/.ssh/master_key (/root/.ssh/master_key) +#yourserver.com +#container.yourserver.com +#anotherserver.com +Agent pid 7897 killed + +``` + +An easy method to collect the contents of all authorized_keys files for all users is the following artano script (this is useful for system auditing and is coded to remove file duplicates): + +``` + +artano 'awk -F: {print\$6\"/.ssh/authorized_keys\"} \ + /etc/passwd | sort -u | xargs grep . 2> /dev/null' + +``` + +It is convenient to configure NFS mounts for file distribution to remote nodes. Bear in mind that NFS is clear text, and sensitive content should not traverse untrusted networks while unencrypted. After configuring an NFS server on host 1.2.3.4, I add the following line to the /etc/fstab file on all the clients and create the /patchdir directory. After the change, the artano script can be used to mass-mount the directory if the network configuration is correct: + +``` + +# tail -1 /etc/fstab +1.2.3.4:/var/cache/yum/x86_64/7Server/ol7_latest/packages + ↪/patchdir nfs4 noauto,proto=tcp,port=2049 0 0 + +``` + +Assuming that the NFS server is mounted, RPMs can be upgraded from images stored upon it (note that Oracle Spacewalk or Red Hat Satellite might be a more capable patch method): + +``` + +# ./artano 'rpm -Fvh /patchdir/\*.rpm' +Agent pid 3203 +Enter passphrase for /root/.ssh/master_key: +Identity added: /root/.ssh/master_key (/root/.ssh/master_key) +#yourserver.com +Preparing... ######################## +Updating / installing... +xmlsec1-1.2.20-7.el7_4 ######################## +xmlsec1-openssl-1.2.20-7.el7_4 ######################## +Cleaning up / removing... +xmlsec1-openssl-1.2.20-5.el7 ######################## +xmlsec1-1.2.20-5.el7 ######################## +#container.yourserver.com +Preparing... ######################## +Updating / installing... +xmlsec1-1.2.20-7.el7_4 ######################## +xmlsec1-openssl-1.2.20-7.el7_4 ######################## +Cleaning up / removing... +xmlsec1-openssl-1.2.20-5.el7 ######################## +xmlsec1-1.2.20-5.el7 ######################## +#anotherserver.com +Preparing... ######################## +Updating / installing... +xmlsec1-1.2.20-7.el7_4 ######################## +xmlsec1-openssl-1.2.20-7.el7_4 ######################## +Cleaning up / removing... +xmlsec1-openssl-1.2.20-5.el7 ######################## +xmlsec1-1.2.20-5.el7 ######################## +Agent pid 3203 killed + +``` + +I am assuming that my audience is already experienced with package tools for their preferred platforms. However, to avoid criticism that I've included little actual discussion of patch tools, the following is a quick reference of RPM manipulation commands, which is the most common package format on enterprise systems: + +* rpm -Uvh package.i686.rpm — install or upgrade a package file. + +* rpm -Fvh package.i686.rpm — upgrade a package file, if an older version is installed. + +* rpm -e package — remove an installed package. + +* rpm -q package — list installed package name and version. + +* rpm -q --changelog package — print full changelog for installed package (including CVEs). + +* rpm -qa — list all installed packages on the system. + +* rpm -ql package — list all files in an installed package. + +* rpm -qpl package.i686.rpm — list files included in a package file. + +* rpm -qi package — print detailed description of installed package. + +* rpm -qpi package — print detailed description of package file. + +* rpm -qf /path/to/file — list package that installed a particular file. + +* rpm --rebuild package.src.rpm — unpack and build a binary RPM under /usr/src/redhat. + +* rpm2cpio package.src.rpm | cpio -icduv — unpack all package files in the current directory. + +Another important consideration for scripting the SSH agent is limiting the capability of an authorized key. There is a [specific syntax][23] for such limitations Of particular interest is the from="" clause, which will restrict logins on a key to a limited set of hosts. It is likely wise to declare a set of "bastion" servers that will record non-root logins that escalate into controlled users who make use of the enterprise keys. + +An example entry might be the following (note that I've broken this line, which is not allowed syntax but done here for clarity): + +``` + +from="*.c2.security.yourcompany.com,4.3.2.1" ssh-ed25519 + ↪AAAAC3NzaC1lZDI1NTE5AAAAIJSSazJz6A5x6fTcDFIji1X+ +↪svesidBonQvuDKsxo1Mx + +``` + +A number of other useful restraints can be placed upon authorized_keys entries. The command="" will restrict a key to a single program or script and will set the SSH_ORIGINAL_COMMAND environment variable to the client's attempted call—scripts can set alarms if the variable does not contain approved contents. The restrict option also is worth consideration, as it disables a large set of SSH features that can be both superfluous and dangerous. + +Although it is possible to set server identification keys in the known_hosts file to a @revoked status, this cannot be done with the contents of authorized_keys. However, a system-wide file for forbidden keys can be set in the sshd_config with RevokedKeys. This file overrides any user's authorized_keys. If set, this file must exist and be readable by the sshd server process; otherwise, no keys will be accepted at all (so use care if you configure it on a machine where there are obstacles to physical access). When this option is set, use the artano script to append forbidden keys to the file quickly when they should be disallowed from the network. A clear and convenient file location would be /etc/ssh/revoked_keys. + +It is also possible to establish a local Certificate Authority (CA) for OpenSSH that will [allow keys to be registered with an authority][24] with expiration dates. These CAs can [become quite elaborate][25] in their control over an enterprise. Although the maintenance of an SSH CA is beyond the scope of this article, keys issued by such CAs should be strong by adhering to the requirements for Ed25519/E-521/RSA-3072. + +### pdsh + +Many higher-level tools for the control of collections of servers exist that are much more sophisticated than the script I've presented here. The most famous is likely [Puppet][26], which is a Ruby-based configuration management system for enterprise control. Puppet has a somewhat short list of supported operating systems. If you are looking for low-level control of Android, Tomato, Linux smart terminals or other "exotic" POSIX, Puppet is likely not the appropriate tool. Another popular Ruby-based tool is [Chef][27], which is known for its complexity. Both Puppet and Chef require Ruby installations on both clients and servers, and they both will catalog any SSH keys that they find, so this key strength discussion is completely applicable to them. + +There are several similar Python-based tools, including [Ansible][28], [Bcfg2][29], [Fabric][30] and [SaltStack][31]. Of these, only Ansible can run "agentless" over a bare SSH connection; the rest will require agents that run on target nodes (and this likely includes a Python runtime). + +Another popular configuration management tool is [CFEngine][32], which is coded in C and claims very high performance. [Rudder][33] has evolved from portions of CFEngine and has a small but growing user community. + +Most of the previously mentioned packages are licensed commercially and some are closed source. + +The closest low-level tool to the activities presented here is the Parallel Distributed Shell (pdsh), which can be found in the [EPEL repository][34]. The pdsh utilities grew out of an IBM-developed package named dsh designed for the control of compute clusters. Install the following packages from the repository to use pdsh: + +``` + +# rpm -qa | grep pdsh +pdsh-2.31-1.el7.x86_64 +pdsh-rcmd-ssh-2.31-1.el7.x86_64 + +``` + +An SSH agent must be running while using pdsh with encrypted keys, and there is no obvious way to control the destination port on a per-host basis as was done with the artano script. Below is an example using pdsh to run a command on three remote servers: + +``` + +# eval $(ssh-agent) +Agent pid 17106 + +# ssh-add ~/.ssh/master_key +Enter passphrase for /root/.ssh/master_key: +Identity added: /root/.ssh/master_key (/root/.ssh/master_key) + +# pdsh -w hosta.com,hostb.com,hostc.com uptime +hosta: 13:24:49 up 13 days, 2:13, 6 users, load avg: 0.00, 0.01, 0.05 +hostb: 13:24:49 up 7 days, 21:15, 5 users, load avg: 0.05, 0.04, 0.05 +hostc: 13:24:49 up 9 days, 3:26, 3 users, load avg: 0.00, 0.01, 0.05 + +# eval $(ssh-agent -k) +Agent pid 17106 killed + +``` + +The -w option above defines a host list. It allows for limited arithmetic expansion and can take the list of hosts from standard input if the argument is a dash (-). The PDSH_SSH_ARGS and PDSH_SSH_ARGS_APPEND environment variables can be used to pass custom options to the SSH call. By default, 32 sessions will be launched in parallel, and this "fanout/sliding window" will be maintained by launching new host invocations as existing connections complete and close. You can adjust the size of the "fanout" either with the -f option or the FANOUT environment variable. It's interesting to note that there are two file copy commands: pdcp and rpdcp, which are analogous to scp. + +Even a low-level utility like pdsh lacks some flexibility that is available by scripting OpenSSH, so prepare to feel even greater constraints as more complicated tools are introduced. + +### Conclusion + +Modern Linux touches us in many ways on diverse platforms. When the security of these systems is not maintained, others also may touch our platforms and turn them against us. It is important to realize the maintenance obligations when you add any Linux platform to your environment. This obligation always exists, and there are consequences when it is not met. + +In a security emergency, simple, open and well understood tools are best. As tool complexity increases, platform portability certainly declines, the number of competent administrators also falls, and this likely impacts speed of execution. This may be a reasonable trade in many other aspects, but in a security context, it demands a much more careful analysis. Emergency measures must be documented and understood by a wider audience than is required for normal operations, and using more general tools facilitates that discussion. + +I hope the techniques presented here will prompt that discussion for those who have not yet faced it. + +### Disclaimer + +The views and opinions expressed in this article are those of the author and do not necessarily reflect those of Linux Journal. + +### Note: + +An exploit [compromising Ed25519][35] was recently demonstrated that relies upon custom hardware changes to derive a usable portion of a secret key. Physical hardware security is a basic requirement for encryption integrity, and many common algorithms are further vulnerable to cache timing or other side channel attacks that can be performed by the unprivileged processes of other users. Use caution when granting access to systems that process sensitive data. + + +-------------------------------------------------------------------------------- + +via: http://www.linuxjournal.com/content/rapid-secure-patching-tools-and-methods + +作者:[Charles Fisher][a] +译者:[译者ID](https://github.com/译者ID) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:http://www.linuxjournal.com/users/charles-fisher +[1]:https://en.wikipedia.org/wiki/EternalBlue +[2]:http://securityaffairs.co/wordpress/61530/hacking/smbloris-smbv1-flaw.html +[3]:http://www.telegraph.co.uk/news/2017/05/13/nhs-cyber-attack-everything-need-know-biggest-ransomware-offensive +[4]:http://www.linuxjournal.com/content/smbclient-security-windows-printing-and-file-transfer +[5]:https://staff.washington.edu/dittrich/misc/forensics +[6]:https://ed25519.cr.yp.to +[7]:http://www.metzdowd.com/pipermail/cryptography/2016-March/028824.html +[8]:https://blog.g3rt.nl/upgrade-your-ssh-keys.html +[9]:https://news.ycombinator.com/item?id=12563899 +[10]:http://safecurves.cr.yp.to/rigid.html +[11]:https://en.wikipedia.org/wiki/Curve25519 +[12]:http://blog.cr.yp.to/20140323-ecdsa.html +[13]:https://lwn.net/Articles/573166 +[14]:http://martin.kleppmann.com/2013/05/24/improving-security-of-ssh-private-keys.html +[15]:https://en.wikipedia.org/wiki/Shor's_algorithm +[16]:https://www.dwavesys.com/d-wave-two-system +[17]:https://crypto.stackexchange.com/questions/40893/can-or-can-not-d-waves-quantum-computers-use-shors-and-grovers-algorithm-to-f +[18]:https://yro.slashdot.org/story/16/12/21/2334220/nist-asks-public-for-help-with-quantum-proof-cryptography +[19]:https://ntruprime.cr.yp.to/index.html +[20]:http://www.linuxjournal.com/content/cipher-security-how-harden-tls-and-ssh +[21]:https://www.michaelwlucas.com/tools/ssh +[22]:https://people.eecs.berkeley.edu/~dawnsong/papers/ssh-timing.pdf +[23]:https://man.openbsd.org/sshd#AUTHORIZED_KEYS_FILE_FORMAT +[24]:https://ef.gy/hardening-ssh +[25]:https://code.facebook.com/posts/365787980419535/scalable-and-secure-access-with-ssh +[26]:https://puppet.com +[27]:https://www.chef.io +[28]:https://www.ansible.com +[29]:http://bcfg2.org +[30]:http://www.fabfile.org +[31]:https://saltstack.com +[32]:https://cfengine.com +[33]:http://www.rudder-project.org/site +[34]:https://fedoraproject.org/wiki/EPEL +[35]:https://research.kudelskisecurity.com/2017/10/04/defeating-eddsa-with-faults From c7c58ecc0ed8bddd8fa53a17e0c9a687788775a7 Mon Sep 17 00:00:00 2001 From: wxy Date: Wed, 31 Jan 2018 14:55:48 +0800 Subject: [PATCH 088/272] PRF:20180123 What Is bashrc and Why Should You Edit It.md @heart4lor --- ...at Is bashrc and Why Should You Edit It.md | 43 ++++++++++--------- 1 file changed, 23 insertions(+), 20 deletions(-) diff --git a/translated/tech/20180123 What Is bashrc and Why Should You Edit It.md b/translated/tech/20180123 What Is bashrc and Why Should You Edit It.md index 2e1487bbf7..0b80202140 100644 --- a/translated/tech/20180123 What Is bashrc and Why Should You Edit It.md +++ b/translated/tech/20180123 What Is bashrc and Why Should You Edit It.md @@ -1,40 +1,41 @@ -什么是 bashrc,为什么要编辑 bashrc +什么是 .bashrc,为什么要编辑 .bashrc? ====== ![](https://www.maketecheasier.com/assets/uploads/2018/01/what-is-bashrc-hero.png) -你的 home 目录下藏着很多隐藏文件。如果你在运行 macOS 或者主流的 Linux 发行版的话,你就会看见一个名为“.bashrc”的文件靠近隐藏文件列表的上方。那么什么是 bashrc,编辑 bashrc 又有什么用呢? +你的 home 目录下藏着很多隐藏文件。如果你在运行 macOS 或者主流的 Linux 发行版的话,你就会在靠近隐藏文件列表的上方看见一个名为 `.bashrc` 的文件。那么什么是 `.bashrc`,编辑 `.bashrc` 又有什么用呢? ![finder-find-bashrc][1] -如果你运行一个基于 Unix 或者类 Unix 的操作系统,bash 很有可能是作为默认终端被安装的。虽然存在很多[不同的 shell][2],bash 却是最常见或许也是最主流的。如果你不明白那意味着什么,bash 能解释你输入进终端程序的东西,并且基于你的输入来运行命令。它在一定程度上支持使用脚本来定制功能,这时候就要用到 bashrc 了。 +如果你运行一个基于 Unix 或者类 Unix 的操作系统,bash 很有可能是作为默认终端被安装的。虽然存在很多[不同的 shell][2],bash 却是最常见或许也是最主流的。如果你不明白那意味着什么,bash 是一个能解释你输入进终端程序的东西,并且基于你的输入来运行命令。它在一定程度上支持使用脚本来定制功能,这时候就要用到 `.bashrc` 了。 -为了加载你的配置,bash 在每次启动时都会加载 bashrc 文件的内容。每个用户的 home 目录都能有这个 shell 脚本。它用来存储并加载你的终端配置和环境变量。 +为了加载你的配置,bash 在每次启动时都会加载 `.bashrc` 文件的内容。每个用户的 home 目录都有这个 shell 脚本。它用来存储并加载你的终端配置和环境变量。 -终端配置可以包含很多不同的东西。最常见的,bashrc 文件包含用户想要用的别名。别名允许用户通过更短的名字来指向命令,对于经常在终端下工作的人来说这可是一个省时利器。 +终端配置可以包含很多不同的东西。最常见的,`.bashrc` 文件包含用户想要用的别名。别名允许用户通过更短的名字或替代的名字来指向命令,对于经常在终端下工作的人来说这可是一个省时利器。 ![terminal-edit-bashrc-1][3] -你可以在任何终端文本编辑器上编辑 bashrc。在接下来的例子中我们将使用 `nano`。 +你可以在任何终端文本编辑器上编辑 `.bashrc`。在接下来的例子中我们将使用 `nano`。 -要使用 `nano` 来编辑 bashrc,在终端中调用以下命令: -```bash +要使用 `nano` 来编辑 `.bashrc`,在终端中调用以下命令: + +``` nano ~/.bashrc ``` -如果你之前从没有编辑过 bashrc 的话,你也许会发现它是空的。这没关系!如果不是的话,你可以随意在任一行添加你的配置。 +如果你之前从没有编辑过 `.bashrc` 的话,你也许会发现它是空的。这没关系!如果不是的话,你可以随意在任一行添加你的配置。 你对 bashrc 所做的任何修改将在下一次启动终端时生效。如果你想立刻生效的话,运行下面的命令: -```bash +``` source ~/.bashrc ``` -你可以添加到任何 bashrc 的位置,随意使用命令(通过 `#`)来组织你的代码。 +你可以添加到任何 `.bashrc` 的位置,随意使用命令(通过 `#`)来组织你的代码。 -编辑 bashrc 需要遵循 [bash 脚本格式][4]。如果你不知道如何用 bash 编写脚本的话,有很多在线资料可供查阅。这是一本相当全面的[介绍指南][5],包含一些我们没能在这里提及的 bashrc 的方面。 +编辑 `.bashrc` 需要遵循 [bash 脚本格式][4]。如果你不知道如何用 bash 编写脚本的话,有很多在线资料可供查阅。这是一本相当全面的[介绍指南][5],包含一些我们没能在这里提及的 bashrc 的方面。 - **相关**: [如何在 Linux 启动时以 root 权限运行 bash 脚本][6] +**相关**: [如何在 Linux 启动时以 root 权限运行 bash 脚本][6] 有一些有用的小技巧能使你的终端体验将更高效,也更用户友好。 @@ -44,28 +45,29 @@ source ~/.bashrc bash 提示符允许你自定义你的终端,并让它在你运行命令时显示提示。自定义的 bash 提示符着实能提高你在终端的工作效率。 -看看这些即[有用][7]又[有趣][8]的 bash 提示符,你可以把它们添加到你的 bashrc 里。 +看看这些即[有用][7]又[有趣][8]的 bash 提示符,你可以把它们添加到你的 `.bashrc` 里。 #### 别名 ![terminal-edit-bashrc-3][9] -别名也允许你使用简写的代码来执行你想要的某个命令的某种格式。让我们用 `ls` 命令来举个例子吧。`ls` 命令默认显示你目录里的内容。这挺有用的,不过显示目录的更多信息,或者显示目录下的隐藏内容,往往更加有用。因此,有个常见的别名就是 `ll`,用来运行 `ls -lha` 或者其他类似的命令。这样就能显示文件的大部分信息,找出隐藏的文件,并能以“能被人类阅读”的单位显示文件大小,而不是用“块”作为单位。 +别名允许你使用简写的代码来执行你想要的某种格式的某个命令。让我们用 `ls` 命令来举个例子吧。`ls` 命令默认显示你目录里的内容。这挺有用的,不过显示目录的更多信息,或者显示目录下的隐藏内容,往往更加有用。因此,有个常见的别名就是 `ll`,用来运行 `ls -lha` 或者其他类似的命令。这样就能显示文件的大部分信息,找出隐藏的文件,并能以“能被人类阅读”的单位显示文件大小,而不是用“块”作为单位。 你需要按照下面这样的格式书写别名: -```bash +``` alias ll = "ls -lha" ``` -左边输入你想设置的别名,右边引号里是要执行的命令。你可以用这种方法来创建命令的短版本,防止出现常见的拼写错误,或者让一个命令总是带上你想要的参数来运行。你也可以用你喜欢的缩写来规避讨厌或容易忘记的语法。这是一些[常见的别名的用法][10],你可以添加到你的 bashrc 里。 +左边输入你想设置的别名,右边引号里是要执行的命令。你可以用这种方法来创建命令的短版本,防止出现常见的拼写错误,或者让一个命令总是带上你想要的参数来运行。你也可以用你喜欢的缩写来规避讨厌或容易忘记的语法。这是一些[常见的别名的用法][10],你可以添加到你的 `.bashrc` 里。 #### 函数 ![terminal-edit-bashrc-2][11] 除了缩短命令名,你也可以用 bash 函数组合多个命令到一个操作。这些命令可以很复杂,但是它们大多遵循这种语法: -```bash + +``` function_name () { command_1 command_2 @@ -73,7 +75,8 @@ function_name () { ``` 下面的命令组合了 `mkdir` 和 `cd` 命令。输入 `md folder_name` 可以在你的工作目录创建一个名为“folder_name”的目录并立刻导航进入。 -```bash + +``` md () { mkdir -p $1 cd $1 @@ -92,7 +95,7 @@ via: https://www.maketecheasier.com/what-is-bashrc/ 作者:[Alexander Fox][a] 译者:[heart4lor](https://github.com/heart4lor) -校对:[校对者ID](https://github.com/校对者ID) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 From 27ca4f97c3d918d5c67069780e8efc04a231fc15 Mon Sep 17 00:00:00 2001 From: darksun Date: Wed, 31 Jan 2018 14:57:23 +0800 Subject: [PATCH 089/272] =?UTF-8?q?=E9=80=89=E9=A2=98:=20Ansible:=20Making?= =?UTF-8?q?=20Things=20Happen?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../20180130 Ansible- Making Things Happen.md | 174 ++++++++++++++++++ 1 file changed, 174 insertions(+) create mode 100644 sources/tech/20180130 Ansible- Making Things Happen.md diff --git a/sources/tech/20180130 Ansible- Making Things Happen.md b/sources/tech/20180130 Ansible- Making Things Happen.md new file mode 100644 index 0000000000..88210cd20c --- /dev/null +++ b/sources/tech/20180130 Ansible- Making Things Happen.md @@ -0,0 +1,174 @@ +Ansible: Making Things Happen +====== +In my [last article][1], I described how to configure your server and clients so you could connect to each client from the server. Ansible is a push-based automation tool, so the connection is initiated from your "server", which is usually just a workstation or a server you ssh in to from your workstation. In this article, I explain how modules work and how you can use Ansible in ad-hoc mode from the command line. + +Ansible is supposed to make your job easier, so the first thing you need to learn is how to do familiar tasks. For most sysadmins, that means some simple command-line work. Ansible has a few quirks when it comes to command-line utilities, but it's worth learning the nuances, because it makes for a powerful system. + +### Command Module + +This is the safest module to execute remote commands on the client machine. As with most Ansible modules, it requires Python to be installed on the client, but that's it. When Ansible executes commands using the Command Module, it does not process those commands through the user's shell. This means some variables like $HOME are not available. It also means stream functions (redirects, pipes) don't work. If you don't need to redirect output or to reference the user's home directory as a shell variable, the Command Module is what you want to use. To invoke the Command Module in ad-hoc mode, do something like this: + +``` + +ansible host_or_groupname -m command -a "whoami" + +``` + +Your output should show SUCCESS for each host referenced and then return the user name that the user used to log in. You'll notice that the user is not root, unless that's the user you used to connect to the client computer. + +If you want to see the elevated user, you'll add another argument to the ansible command. You can add -b in order to "become" the elevated user (or the sudo user). So, if you were to run the same command as above with a "-b" flag: + +``` + +ansible host_or_groupname -b -m command -a "whoami" + +``` + +you should see a similar result, but the whoami results should say root instead of the user you used to connect. That flag is important to use, especially if you try to run remote commands that require root access! + +### Shell Module + +There's nothing wrong with using the Shell Module to execute remote commands. It's just important to know that since it uses the remote user's environment, if there's something goofy with the user's account, it might cause problems that the Command Module avoids. If you use the Shell Module, however, you're able to use redirects and pipes. You can use the whoami example to see the difference. This command: + +``` + +ansible host_or_groupname -m command -a "whoami > myname.txt" + +``` + +should result in an error about > not being a valid argument. Since the Command Module doesn't run inside any shell, it interprets the greater-than character as something you're trying to pass to the whoami command. If you use the Shell Module, however, you have no problems: + +``` + +ansible host_or_groupname -m shell -a "whom > myname.txt" + +``` + +This should execute and give you a SUCCESS message for each host, but there should be nothing returned as output. On the remote machine, however, there should be a file called myname.txt in the user's home directory that contains the name of the user. My personal policy is to use the Command Module whenever possible and to use the Shell Module if needed. + +### The Raw Module + +Functionally, the Raw Module works like the Shell Module. The key difference is that Ansible doesn't do any error checking, and STDERR, STDOUT and Return Code is returned. Other than that, Ansible has no idea what happens, because it just executes the command over SSH directly. So while the Shell Module will use /bin/sh by default, the Raw Module just uses whatever the user's personal default shell might be. + +Why would a person decide to use the Raw Module? It doesn't require Python on the remote computer—at all. Although it's true that most servers have Python installed by default, or easily could have it installed, many embedded devices don't and can't have Python installed. For most configuration management tools, not having an agent program installed means the remote device can't be managed. With Ansible, if all you have is SSH, you still can execute remote commands using the Raw Module. I've used the Raw Module to manage Bitcoin miners that have a very minimal embedded environment. It's a powerful tool, and when you need it, it's invaluable! + +### Copy Module + +Although it's certainly possible to do file and folder manipulation with the Command and Shell Modules, Ansible includes a module specifically for copying files to the server. Even though it requires learning a new syntax for copying files, I like to use it because Ansible will check to see whether a file exists, and whether it's the same file. That means it copies the file only if it needs to, saving time and bandwidth. It even will make backups of existing files! I can't tell you how many times I've used scp and sshpass in a Bash FOR loop and dumped files on servers, even if they didn't need them. Ansible makes it easy and doesn't require FOR loops and IP iterations. + +The syntax is a little more complicated than with Command, Shell or Raw. Thankfully, as with most things in the Ansible world, it's easy to understand—for example: + +``` + +ansible host_or_groupname -b -m copy \ + -a "src=./updated.conf dest=/etc/ntp.conf \ + owner=root group=root mode=0644 backup=yes" + +``` + +This will look in the current directory (on the Ansible server/workstation) for a file called updated.conf and then copy it to each host. On the remote system, the file will be put in /etc/ntp.conf, and if a file already exists, and it's different, the original will be backed up with a date extension. If the files are the same, Ansible won't make any changes. + +I tend to use the Copy Module when updating configuration files. It would be perfect for updating configuration files on Bitcoin miners, but unfortunately, the Copy Module does require that the remote machine has Python installed. Nevertheless, it's a great way to update common files on many remote machines with one simple command. It's also important to note that the Copy Module supports copying remote files to other locations on the remote filesystem using the remote_src=true directive. + +### File Module + +The File Module has a lot in common with the Copy Module, but if you try to use the File Module to copy a file, it doesn't work as expected. The File Module does all its actions on the remote machine, so src and dest are all references to the remote filesystem. The File Module often is used for creating directories, creating links or deleting remote files and folders. The following will simply create a folder named /etc/newfolder on the remote servers and set the mode: + +``` + +ansible host_or_groupname -b -m file \ + -a "path=/etc/newfolder state=directory mode=0755" + +``` + +You can, of course, set the owner and group, along with a bunch of other options, which you can learn about on the Ansible doc site. I find I most often will either create a folder or symbolically link a file using the File Module. To create a symlink: + +``` + +sensible host_or_groupname -b -m file \ + -a "src=/etc/ntp.conf dest=/home/user/ntp.conf \ + owner=user group=user state=link" + +``` + +Notice that the state directive is how you inform Ansible what you actually want to do. There are several state options: + +* link — create symlink. + +* directory — create directory. + +* hard — create hardlink. + +* touch — create empty file. + +* absent — delete file or directory recursively. + +This might seem a bit complicated, especially when you easily could do the same with a Command or Shell Module command, but the clarity of using the appropriate module makes it more difficult to make mistakes. Plus, learning these commands in ad-hoc mode will make playbooks, which consist of many commands, easier to understand (I plan to cover this in my next article). + +### File Management + +Anyone who manages multiple distributions knows it can be tricky to handle the various package managers. Ansible handles this in a couple ways. There are specific modules for apt and yum, but there's also a generic module called "package" that will install on the remote computer regardless of whether it's Red Hat- or Debian/Ubuntu-based. + +Unfortunately, while Ansible usually can detect the type of package manager it needs to use, it doesn't have a way to fix packages with different names. One prime example is Apache. On Red Hat-based systems, the package is "httpd", but on Debian/Ubuntu systems, it's "apache2". That means some more complex things need to happen in order to install the correct package automatically. The individual modules, however, are very easy to use. I find myself just using apt or yum as appropriate, just like when I manually manage servers. Here's an apt example: + +``` + +ansible host_or_groupname -b -m apt \ + -a "update_cache=yes name=apache2 state=latest" + +``` + +With this one simple line, all the host machines will run apt-get update (that's the update_cache directive at work), then install apache2's latest version including any dependencies required. Much like the File Module, the state directive has a few options: + +* latest — get the latest version, upgrading existing if needed. + +* absent — remove package if installed. + +* present — make sure package is installed, but don't upgrade existing. + +The Yum Module works similarly to the Apt Module, but I generally don't bother with the update_cache directive, because yum updates automatically. Although very similar, installing Apache on a Red Hat-based system looks like this: + +``` + +ansible host_or_groupname -b -m yum \ + -a "name=httpd state=present" + +``` + +The difference with this example is that if Apache is already installed, it won't update, even if an update is available. Sometimes updating to the latest version isn't want you want, so this stops that from accidentally happening. + +### Just the Facts, Ma'am + +One frustrating thing about using Ansible in ad-hoc mode is that you don't have access to the "facts" about the remote systems. In my next article, where I plan to explore creating playbooks full of various tasks, you'll see how you can reference the facts Ansible learns about the systems. It makes Ansible far more powerful, but again, it can be utilized only in playbook mode. Nevertheless, it's possible to use ad-hoc mode to peek at the sorts information Ansible gathers. If you run the setup module, it will show you all the details from a remote system: + +``` + +ansible host_or_groupname -b -m setup + +``` + +That command will spew a ton of variables on your screen. You can scroll through them all to see the vast amount of information Ansible pulls from the host machines. In fact, it shows so much information, it can be overwhelming. You can filter the results: + +``` + +ansible host_or_groupname -b -m setup -a "filter=*family*" + +``` + +That should just return a single variable, ansible_os_family, which likely will be Debian or Red Hat. When you start building more complex Ansible setups with playbooks, it's possible to insert some logic and conditionals in order to use yum where appropriate and apt where the system is Debian-based. Really, the facts variables are incredibly useful and make building playbooks that much more exciting. + +But, that's for another article, because you've come to the end of the second installment. Your assignment for now is to get comfortable using Ansible in ad-hoc mode, doing one thing at a time. Most people think ad-hoc mode is just a stepping stone to more complex Ansible setups, but I disagree. The ability to configure hundreds of servers consistently and reliably with a single command is nothing to scoff at. I love making elaborate playbooks, but just as often, I'll use an ad-hoc command in a situation that used to require me to ssh in to a bunch of servers to do simple tasks. Have fun with Ansible; it just gets more interesting from here! + + +-------------------------------------------------------------------------------- + +via: http://www.linuxjournal.com/content/ansible-making-things-happen + +作者:[Shawn Powers][a] +译者:[译者ID](https://github.com/译者ID) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:http://www.linuxjournal.com/users/shawn-powers +[1]:http://www.linuxjournal.com/content/ansible-automation-framework-thinks-sysadmin From 07f399b6811ce0b7cd51d91a6cdfe5e4bf2827f0 Mon Sep 17 00:00:00 2001 From: wxy Date: Wed, 31 Jan 2018 14:57:36 +0800 Subject: [PATCH 090/272] PUB:20180123 What Is bashrc and Why Should You Edit It.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @heart4lor 恭喜你完成了第一篇翻译! 文章首发地址: https://linux.cn/article-9298-1.html 您的 LCTT 专页地址: https://linux.cn/lctt/heart4lor --- .../20180123 What Is bashrc and Why Should You Edit It.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename {translated/tech => published}/20180123 What Is bashrc and Why Should You Edit It.md (100%) diff --git a/translated/tech/20180123 What Is bashrc and Why Should You Edit It.md b/published/20180123 What Is bashrc and Why Should You Edit It.md similarity index 100% rename from translated/tech/20180123 What Is bashrc and Why Should You Edit It.md rename to published/20180123 What Is bashrc and Why Should You Edit It.md From cacf24670c84ab509b09587b8d330023885b881b Mon Sep 17 00:00:00 2001 From: darksun Date: Wed, 31 Jan 2018 15:01:56 +0800 Subject: [PATCH 091/272] =?UTF-8?q?=E9=80=89=E9=A2=98:=20Monitoring=20netw?= =?UTF-8?q?ork=20bandwidth=20with=20iftop=20command?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...ng network bandwidth with iftop command.md | 95 +++++++++++++++++++ 1 file changed, 95 insertions(+) create mode 100644 sources/tech/20170429 Monitoring network bandwidth with iftop command.md diff --git a/sources/tech/20170429 Monitoring network bandwidth with iftop command.md b/sources/tech/20170429 Monitoring network bandwidth with iftop command.md new file mode 100644 index 0000000000..c3369bf302 --- /dev/null +++ b/sources/tech/20170429 Monitoring network bandwidth with iftop command.md @@ -0,0 +1,95 @@ +Monitoring network bandwidth with iftop command +====== +System Admins are required to monitor IT infrastructure to make sure that everything is up & running. We have to monitor performance of hardware i.e memory, hdds & CPUs etc & so does we have to monitor our network. We need to make sure that our network is not being over utilised or our applications, websites might not work. In this tutorial, we are going to learn to use IFTOP utility. + +( **Recommended read** :[ **Resource monitoring using Nagios**][1], [**Tools for checking system info**,][2] [**Important logs to monitor**][3]) + +Iftop is network monitoring utility that provides real time real time bandwidth monitoring. Iftop measures total data moving in & out of the individual socket connections i.e. it captures packets moving in and out via network adapter & than sums those up to find the bandwidth being utilized. + +## Installation on Debian/Ubuntu + +Iftop is available with default repositories of Debian/Ubuntu & can be simply installed using the command below, + +``` +$ sudo apt-get install iftop +``` + +## Installation on RHEL/Centos using yum + +For installing iftop on CentOS or RHEL, we need to enable EPEL repository. To enable repository, run the following on your terminal, + +### RHEL/CentOS 7 + +``` +$ rpm -Uvh https://dl.fedoraproject.org/pub/epel/7/x86_64/e/epel-release-7-10.noarch.rpm +``` + +### RHEL/CentOS 6 (64 Bit) + +``` +$ rpm -Uvh http://download.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm +``` + +### RHEL/CentOS 6 (32 Bit) + +``` +$ rpm -Uvh http://dl.fedoraproject.org/pub/epel/6/i386/epel-release-6-8.noarch.rpm +``` + +After epel repository has been installed, we can now install iftop by running, + +``` +$ yum install iftop +``` + +This will install iftop utility on your system. We will now use it to monitor our network, + +## Using IFTOP + +You can start using iftop by opening your terminal windown & type, + +``` +$ iftop +``` + +![network monitoring][5] + +You will now be presented with network activity happening on your machine. You can also use + +``` +$ iftop -n +``` + +Which will present the network information on your screen but with '-n' , you will not be presented with the names related to IP addresses but only ip addresses. This option allows for some bandwidth to be saved, which goes into resolving IP addresses to names. + +Now we can also see all the commands that can be used with iftop. Once you have ran iftop, press 'h' button on the keyboard to see all the commands that can be used with iftop. + +![network monitoring][7] + +To monitor a particular network interface, we can mention interface with iftop, + +``` +$ iftop -I enp0s3 +``` + +You can check further options that are used with iftop using help, as mentioned above. But these mentioned examples are only what you might to monitor network. + + +-------------------------------------------------------------------------------- + +via: http://linuxtechlab.com/monitoring-network-bandwidth-iftop-command/ + +作者:[SHUSAIN][a] +译者:[译者ID](https://github.com/译者ID) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:http://linuxtechlab.com/author/shsuain/ +[1]:http://linuxtechlab.com/installing-configuring-nagios-server/ +[2]:http://linuxtechlab.com/commands-system-hardware-info/ +[3]:http://linuxtechlab.com/important-logs-monitor-identify-issues/ +[4]:https://i1.wp.com/linuxtechlab.com/wp-content/plugins/a3-lazy-load/assets/images/lazy_placeholder.gif?resize=661%2C424 +[5]:https://i0.wp.com/linuxtechlab.com/wp-content/uploads/2017/04/iftop-1.jpg?resize=661%2C424 +[6]:https://i1.wp.com/linuxtechlab.com/wp-content/plugins/a3-lazy-load/assets/images/lazy_placeholder.gif?resize=663%2C416 +[7]:https://i0.wp.com/linuxtechlab.com/wp-content/uploads/2017/04/iftop-help.jpg?resize=663%2C416 From ed97b680bfd8820696bd712abdb1b02c70d42101 Mon Sep 17 00:00:00 2001 From: qhwdw Date: Wed, 31 Jan 2018 15:02:12 +0800 Subject: [PATCH 092/272] Translated by qhwdw --- .../20170404 Kernel Tracing with Ftrace.md | 392 ------------------ .../20170404 Kernel Tracing with Ftrace.md | 391 +++++++++++++++++ 2 files changed, 391 insertions(+), 392 deletions(-) delete mode 100644 sources/tech/20170404 Kernel Tracing with Ftrace.md create mode 100644 translated/tech/20170404 Kernel Tracing with Ftrace.md diff --git a/sources/tech/20170404 Kernel Tracing with Ftrace.md b/sources/tech/20170404 Kernel Tracing with Ftrace.md deleted file mode 100644 index 98c23bff9a..0000000000 --- a/sources/tech/20170404 Kernel Tracing with Ftrace.md +++ /dev/null @@ -1,392 +0,0 @@ -Translating by qhwdw Kernel Tracing with Ftrace -============================================================ - -[Andrej Yemelianov][7] -Tags: [ftrace][8], [kernel][9], [kernel profiling][10], [kernel tracing][11], [linux][12], [tracepoints][13] - -![](https://blog.selectel.com/wp-content/uploads/2017/04/PR-1801-2-2.png) - -There are a number of tools for analyzing events at the kernel level: [SystemTap][14], [ktap][15], [Sysdig][16], [LTTNG][17], etc., and you can find plenty of detailed articles and materials about these on the web. - -You’ll find much less information on Linux’s native mechanism for tracing system events and retrieving/analyzing troubleshooting information. That would be [ftrace][18], the first tracing tool added to the kernel, and this is what we’ll be looking at today. Let’s start by defining some key terms. - -### Kernel Tracing and Profiling - -Kernel profiling detects performance “bottlenecks”. Profiling helps us determine where exactly in a program we’re losing performance. Special programs generate a profile—an event summary—which can be used to figure out which functions took the most time to run. These programs, however, don’t help identify why performance dropped. - -Bottlenecking usually occurs under conditions that can’t be identified from profiling. To understand why an event took place, the relevant context has to be restored. This requires tracing. - -Tracing is understood as the process of collecting information on the activity in a working system. This is done with special tools that register system events kind of like how a tape recorder records ambient sound. - -Tracing programs can simultaneously trace events at the application and OS level. The information they gather may be useful for diagnosing multiple system problems. - -Tracing is sometimes compared to logging. There definitely are similarities between the two, but there are differences, too. - -With tracing, information is written about low-level events. These number in the hundreds or even thousands. With logging, information is written about higher-level events, which are much less frequent. These include users logging into the system, application errors, database transaction, etc. - -Just like logs, tracing data can be read as is; however, it’s more useful to extract information about specific applications. All tracing programs are capable of this. - -The Linux kernel has three primary mechanisms for kernel tracing and profiling: - -* tracepoints – a mechanism that works over static instrumented code - -* kprobes – a dynamic tracing mechanism used to interrupt a kernel code at any point, call its own handler, and return after all of the necessary operations have been completed - -* perf_events – an interface for accessing the PMU (Performance Monitoring Unit) - -We won’t be writing about all of these mechanism here, but anyone interested can visit [Brendan Gregg’s blog][19]. - -Using ftrace, we can interact with these mechanisms and get debugging information directly from the user space. We’ll talk about this in more detail below. All command line examples are in Ubuntu 14.04, kernel ver. 3.13.0-24. - -### Ftrace: General Information - -Ftrace is short for Function Trace, but that’s not all it does: it can be used to track context switches, measure the time it takes to process interruptions, calculate the time for activating high-priority tasks, and much more. - -Ftrace was developed by Steven Rostedt and has been included in the kernel since version 2.6.27 in 2008\. This is the framework that provides a debugging ring buffer for recording data. This data is gathered by the kernel’s integrated tracing programs. - -Ftrace works on the debugfs file system, which is mounted by default in most modern Linux distributions. To start using ftrace, you’ll have to go to the sys/kernel/debug/tracing directory (this is only available to the root user): - -``` -# cd /sys/kernel/debug/tracing -``` - -The contents of the directory should look like this: - -``` -аvailable_filter_functions options stack_trace_filter -available_tracers per_cpu trace -buffer_size_kb printk_formats trace_clock -buffer_total_size_kb README trace_marker -current_tracer saved_cmdlines trace_options -dyn_ftrace_total_info set_event trace_pipe -enabled_functions set_ftrace_filter trace_stat -events set_ftrace_notrace tracing_cpumask -free_buffer set_ftrace_pid tracing_max_latency -function_profile_enabled set_graph_function tracing_on -instances set_graph_notrace tracing_thresh -kprobe_events snapshot uprobe_events -kprobe_profile stack_max_size uprobe_profile -``` - -We won’t describe all of these files and subdirectories; that’s already been taken care of in the [official documentation][20]. Instead, we’ll just briefly describe the files relevant to our context: - -* available_tracers – available tracing programs - -* current_tracer – the tracing program presently running - -* tracing_on – the system file responsible for enabling or disabling data writing to the ring buffer (to enable this, the number 1 has to be added to the file; to disable it, the number 0) - -* trace – the file where tracing data is saved in human-readable format - -### Available Tracers - -We can view a list of available tracers with the command - -``` -root@andrei:/sys/kernel/debug/tracing#: cat available_tracers -blk mmiotrace function_graph wakeup_rt wakeup function nop -``` - -Let’s take a quick look at the features of each tracer: - -* function – a function call tracer without arguments - -* function_graph – a function call tracer with subcalls - -* blk – a call and event tracer related to block device I/O operations (this is what blktrace uses) - -* mmiotrace – a memory-mapped I/O operation tracer - -* nop – the simplest tracer, which as the name suggests, doesn’t do anything (although it may come in handy in some situations, which we’ll describe later on) - -### The Function Tracer - -We’ll start our introduction to ftrace with the function tracer. Let’s look at a test script: - -``` -#!/bin/sh - -dir=/sys/kernel/debug/tracing - -sysctl kernel.ftrace_enabled=1 -echo function > ${dir}/current_tracer -echo 1 > ${dir}/tracing_on -sleep 1 -echo 0 > ${dir}/tracing_on -less ${dir}/trace -``` - -This script is fairly straightforward, but there are a few things worth noting. The command sysctl ftrace.enabled=1 enables the function tracer. We then enable the current tracer by writing its name to the current_tracer file. - -Next, we write a 1 to tracing_on, which enables the ring buffer. The syntax requires a space between 1 and the > symbol; echo1> tracing_on will not work. One line later, we disable it (if 0 is written to tracing_on, the buffer won’t clear and ftrace won’t be disabled). - -Why would we do this? Between the two echo commands, we see the command sleep 1\. We enable the buffer, run this command, and then disable it. This lets the tracer include information about all of the system calls that occur while the command runs. - -In the last line of the script, we give the command to display tracing data in the console. - -Once the script has run, we’ll see the following printout (here is just a small fragment): - -``` -# tracer: function -# -# entries-in-buffer/entries-written: 29571/29571 #P:2 -# -# _-----=> irqs-off -# / _----=> need-resched -# | / _---=> hardirq/softirq -# || / _--=> preempt-depth -# ||| / delay -# TASK-PID CPU# |||| TIMESTAMP FUNCTION -# | | | |||| | | - trace.sh-1295 [000] .... 90.502874: mutex_unlock <-rb_simple_write - trace.sh-1295 [000] .... 90.502875: __fsnotify_parent <-vfs_write - trace.sh-1295 [000] .... 90.502876: fsnotify <-vfs_write - trace.sh-1295 [000] .... 90.502876: __srcu_read_lock <-fsnotify - trace.sh-1295 [000] .... 90.502876: __srcu_read_unlock <-fsnotify - trace.sh-1295 [000] .... 90.502877: __sb_end_write <-vfs_write - trace.sh-1295 [000] .... 90.502877: syscall_trace_leave <-int_check_syscall_exit_work - trace.sh-1295 [000] .... 90.502878: context_tracking_user_exit <-syscall_trace_leave - trace.sh-1295 [000] .... 90.502878: context_tracking_user_enter <-syscall_trace_leave - trace.sh-1295 [000] d... 90.502878: vtime_user_enter <-context_tracking_user_enter - trace.sh-1295 [000] d... 90.502878: _raw_spin_lock <-vtime_user_enter - trace.sh-1295 [000] d... 90.502878: __vtime_account_system <-vtime_user_enter - trace.sh-1295 [000] d... 90.502878: get_vtime_delta <-__vtime_account_system - trace.sh-1295 [000] d... 90.502879: account_system_time <-__vtime_account_system - trace.sh-1295 [000] d... 90.502879: cpuacct_account_field <-account_system_time - trace.sh-1295 [000] d... 90.502879: acct_account_cputime <-account_system_time - trace.sh-1295 [000] d... 90.502879: __acct_update_integrals <-acct_account_cputime -``` - -The printout starts with information about the number of entries in the buffer and the total number of entries written. The difference between these two number is the number of events lost while filling the buffer (there were no losses in our example). - -Then there’s a list of functions that includes the following information: - -* process identifier (PID) - -* the CPU the process runs on (CPU#) - -* the process start time (TIMESTAMP) - -* the name of the traceable function and the parent function that called it (FUNCTION); for example, in the first line of our output, the mutex-unlock function was called by rb_simple_write - -### The Function_graph Tracer - -The function_graph tracer works just like function, but more detailed: the entry and exit point is shown for each function. With this tracer, we can trace functions with sub calls and measure the execution time of each function. - -Let’s edit the script from our last example: - -``` -#!/bin/sh - -dir=/sys/kernel/debug/tracing - -sysctl kernel.ftrace_enabled=1 -echo function_graph > ${dir}/current_tracer -echo 1 > ${dir}/tracing_on -sleep 1 -echo 0 > ${dir}/tracing_on -less ${dir}/trace -``` - -After running this script, we get the following printout: - -``` -# tracer: function_graph -# -# CPU DURATION FUNCTION CALLS -# | | | | | | | - 0) 0.120 us | } /* resched_task */ - 0) 1.877 us | } /* check_preempt_curr */ - 0) 4.264 us | } /* ttwu_do_wakeup */ - 0) + 29.053 us | } /* ttwu_do_activate.constprop.74 */ - 0) 0.091 us | _raw_spin_unlock(); - 0) 0.260 us | ttwu_stat(); - 0) 0.133 us | _raw_spin_unlock_irqrestore(); - 0) + 37.785 us | } /* try_to_wake_up */ - 0) + 38.478 us | } /* default_wake_function */ - 0) + 39.203 us | } /* pollwake */ - 0) + 40.793 us | } /* __wake_up_common */ - 0) 0.104 us | _raw_spin_unlock_irqrestore(); - 0) + 42.920 us | } /* __wake_up_sync_key */ - 0) + 44.160 us | } /* sock_def_readable */ - 0) ! 192.850 us | } /* tcp_rcv_established */ - 0) ! 197.445 us | } /* tcp_v4_do_rcv */ - 0) 0.113 us | _raw_spin_unlock(); - 0) ! 205.655 us | } /* tcp_v4_rcv */ - 0) ! 208.154 us | } /* ip_local_deliver_finish */ -``` - -In this graph, DURATION shows the time spent running a function. Pay careful attention to the points marked by the + and ! symbols. The plus sign (+) means the function took more than 10 microseconds; the exclamation point (!) means it took more than 100 microseconds. - -Under FUNCTION_CALLS, we find information on each function call. - -The symbols used to show the initiation and completion of each function is the same as in C: bracers ({) demarcate functions, one at the start and one at the end; leaf functions that don’t call any other function are marked with a semicolon (;). - -### Function Filters - -The ftrace printout can be big, and finding exactly what it is you’re looking for can be extremely difficult. We can use filters to simplify our search: the printout will only display information about the functions we’re interested in. To do this, we just have to write the name of our function in the set_ftrace_filter file. For example: - -``` -root@andrei:/sys/kernel/debug/tracing# echo kfree > set_ftrace_filter -``` - -To disable the filter, we add an empty line to this file: - -``` -root@andrei:/sys/kernel/debug/tracing# echo > set_ftrace_filter -``` - -By running the command - -``` -root@andrei:/sys/kernel/debug/tracing# echo kfree > set_ftrace_notrace -``` - -we get the opposite result: the printout will give us information about every function except kfree(). - -Another useful option is set_ftrace_pid. This is for tracing functions that can be called while a particular process runs. - -ftrace has many more filtering options. For a more detailed look at these, you can read Steven Rostedt’s article on [LWN.net][21]. - -### Tracing Events - -We mentioned the tracepoints mechanism above. Tracepoints are special code inserts that trigger system events. Tracepoints may be dynamic (meaning they have several checks attached to them) or static (no checks attached). - -Static tracepoints don’t affect the system in any way; they just add a few bytes for the function call at the end of the instrumented function and add a data structure in a separate section. - -Dynamic tracepoints call a trace function when the relevant code fragment is executed. Tracing data is written to the ring buffer. - -Tracepoints can be included anywhere in a code; in fact, they can already be found in a lot of kernel functions. Let’s look at the kmem_cache_alloc function (taken from [here][22]): - -``` -{ - void *ret = slab_alloc(cachep, flags, _RET_IP_); - - trace_kmem_cache_alloc(_RET_IP_, ret, - cachep->object_size, cachep->size, flags); - return ret; - } -``` - -trace_kmem_cache_alloc is itself a tracepoint. We can find countless more examples by just looking at the source code of other kernel functions. - -The Linux kernel has a special API for working with tracepoints from the user space. In the /sys/kernel/debug/tracing directory, there’s an events directory where system events are saved. These are available for tracing. System events in this context can be understood as the tracepoints included in the kernel. - -The list of these can be viewed by running the command: - -``` -root@andrei:/sys/kernel/debug/tracing# cat available_events -``` - -A long list will be printed out in the console. This is a bit inconvenient. We can print out a more structured listed using the command: - -``` -root@andrei:/sys/kernel/debug/tracing# ls events - -block gpio mce random skb vsyscall -btrfs header_event migrate ras sock workqueue -compaction header_page module raw_syscalls spi writeback -context_tracking iommu napi rcu swiotlb xen -enable irq net regmap syscalls xfs -exceptions irq_vectors nmi regulator task xhci-hcd -ext4 jbd2 oom rpm timer -filemap kmem pagemap sched udp -fs kvm power scsi vfs -ftrace kvmmmu printk signal vmscan -``` - -All possible events are combined in the subdirectory by subsystem. Before we can start tracing events, we’ll make sure we’ve enabled writing to the ring buffer: - -``` -root@andrei:/sys/kernel/debug/tracing# cat tracing_on -``` - -If the number 0 is shown in the console, we run: - -``` -root@andrei:/sys/kernel/debug/tracing# echo 1 > tracing_on -``` - -In our last article, we wrote about the chroot() system call; let’s trace access to this system call. For our tracer, we’ll use nop because function and function_graph record too much information, including event information that we’re just not interested in. - -``` -root@andrei:/sys/kernel/debug/tracing# echo nop > current_tracer -``` - -All system call related events are saved in the syscalls directory. Here we’ll find a directory for entering and exiting various system calls. We’ll activate the tracepoint we need by writing 1 in the corresponding file: - -``` -root@andrei:/sys/kernel/debug/tracing# echo 1 > events/syscalls/sys_enter_chroot/enable -``` - -Then we create an isolated file system using chroot (for more information, see this [previous post][23]). After we’ve executed the commands we want, we’ll disable the tracer so that no excess or irrelevant information appears in the printout: - -``` -root@andrei:/sys/kernel/debug/tracing# echo 0 > tracing_on -``` - -Then, we can look at the contents of the ring buffer. At the end of the printout, we’ll find information about our system call (here is a small section): - -``` -root@andrei:/sys/kernel/debug/tracing# сat trace - -...... - chroot-11321 [000] .... 4606.265208: sys_chroot(filename: 7fff785ae8c2) - chroot-11325 [000] .... 4691.677767: sys_chroot(filename: 7fff242308cc) - bash-11338 [000] .... 4746.971300: sys_chroot(filename: 7fff1efca8cc) - bash-11351 [000] .... 5379.020609: sys_chroot(filename: 7fffbf9918cc) -``` - -More detailed information about configuring event tracing can be found [here][24]. - -### Conclusion - -In this article, we presented a general overview of ftrace’s capabilities. We’d appreciate any comments or additions. If you’d like to dive deeper into this topic, we recommend looking at the following resources: - -* [https://www.kernel.org/doc/Documentation/trace/tracepoints.txt][1] — a detailed description of the tracepoints mechanism - -* [https://www.kernel.org/doc/Documentation/trace/events.txt][2] — a manual for tracing system events in Linux - -* [https://www.kernel.org/doc/Documentation/trace/ftrace.txt][3] — offical ftrace documentation - -* [https://lttng.org/files/thesis/desnoyers-dissertation-2009-12-v27.pdf][4] — Mathieu Desnoyers’ (the creator of tracepoints and LTTNG author) dissertation about kernel tracing and profiling - -* [https://lwn.net/Articles/370423/][5] — Steven Rostedt’s article on ftrace capabilities - -* [http://alex.dzyoba.com/linux/profiling-ftrace.html][6] — an ftrace overview that analyzes a practical use case - --------------------------------------------------------------------------------- - -via:https://blog.selectel.com/kernel-tracing-ftrace/ - -作者:[Andrej Yemelianov][a] -译者:[译者ID](https://github.com/译者ID) -校对:[校对者ID](https://github.com/校对者ID) - -本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 - -[a]:https://blog.selectel.com/author/yemelianov/ -[1]:https://www.kernel.org/doc/Documentation/trace/tracepoints.txt -[2]:https://www.kernel.org/doc/Documentation/trace/events.txt -[3]:https://www.kernel.org/doc/Documentation/trace/ftrace.txt -[4]:https://lttng.org/files/thesis/desnoyers-dissertation-2009-12-v27.pdf -[5]:https://lwn.net/Articles/370423/ -[6]:http://alex.dzyoba.com/linux/profiling-ftrace.html -[7]:https://blog.selectel.com/author/yemelianov/ -[8]:https://blog.selectel.com/tag/ftrace/ -[9]:https://blog.selectel.com/tag/kernel/ -[10]:https://blog.selectel.com/tag/kernel-profiling/ -[11]:https://blog.selectel.com/tag/kernel-tracing/ -[12]:https://blog.selectel.com/tag/linux/ -[13]:https://blog.selectel.com/tag/tracepoints/ -[14]:https://sourceware.org/systemtap/ -[15]:https://github.com/ktap/ktap -[16]:http://www.sysdig.org/ -[17]:http://lttng.org/ -[18]:https://www.kernel.org/doc/Documentation/trace/ftrace.txt -[19]:http://www.brendangregg.com/blog/index.html -[20]:https://www.kernel.org/doc/Documentation/trace/ftrace.txt -[21]:https://lwn.net/Articles/370423/ -[22]:http://lxr.free-electrons.com/source/mm/slab.c -[23]:https://blog.selectel.com/containerization-mechanisms-namespaces/ -[24]:https://www.kernel.org/doc/Documentation/trace/events.txt \ No newline at end of file diff --git a/translated/tech/20170404 Kernel Tracing with Ftrace.md b/translated/tech/20170404 Kernel Tracing with Ftrace.md new file mode 100644 index 0000000000..6ed3a87bf9 --- /dev/null +++ b/translated/tech/20170404 Kernel Tracing with Ftrace.md @@ -0,0 +1,391 @@ +使用 Ftrace 跟踪内核 +============================================================ + +标签: [ftrace][8],[kernel][9],[kernel profiling][10],[kernel tracing][11],[linux][12],[tracepoints][13] + +![](https://blog.selectel.com/wp-content/uploads/2017/04/PR-1801-2-2.png) + +在内核级别上分析事件有很多的工具:[SystemTap][14],[ktap][15],[Sysdig][16],[LTTNG][17]等等,并且你也可以在网络上找到关于这些工具的大量介绍文章和资料。 + +而对于使用 Linux 原生机制去跟踪系统事件以及检索/分析故障信息的方面的资料却很少找的到。这就是 [ftrace][18],它是添加到内核中的第一款跟踪工具,今天我们来看一下它都能做什么,让我们从它的一些重要术语开始吧。 + +### 内核跟踪和分析 + +内核分析可以发现性能“瓶颈”。分析能够帮我们发现在一个程序中性能损失的准确位置。特定的程序生成一个概述 — 一个事件的总结 — 它能够用于帮我们找出哪个函数占用了大量的运行时间。尽管这些程序并不能识别出为什么会损失性能。 + +瓶颈经常发生在无法通过分析来识别的情况下。去推断出为什么会发生事件,去保存发生事件时的相关上下文,这就需要去跟踪。 + +跟踪可以理解为在一个正常工作的系统上活动的信息收集进程。它使用特定的工具来完成这项工作,就像录音机来记录声音一样,用它来记录各种注册的系统事件。 + +跟踪程序能够同时跟踪应用级和操作系统级的事件。它们收集的信息能够用于诊断多种系统问题。 + +有时候会将跟踪与日志比较。它们两者确时很相似,但是也有不同的地方。 + +对于跟踪,记录的信息都是些低级别事件。它们的数量是成百上千的,甚至是成千上万的。对于日志,记录的信息都是些高级别事件,数量上通常少多了。这些包含用户登陆系统、应用程序错误、数据库事务等等。 + +就像日志一样,跟踪数据可以被原样读取,但是用特定的应用程序提取的信息更有用。所有的跟踪程序都能这样做。 + +在内核跟踪和分析方面,Linux 内核有三个主要的机制: + +* 跟踪点 —— 一种基于静态测试代码的工作机制 + +* 探针 —— 一种动态跟踪机制,用于在任意时刻中断内核代码的运行,调用它自己的处理程序,在完成需要的操作之后再返回。 + +* perf_events —— 一个访问 PMU(性能监视单元)的接口 + +我并不想在这里写关于这些机制方面的内容,任何对它们感兴趣的人可以去访问 [Brendan Gregg 的博客][19]。 + +使用 ftrace,我们可以与这些机制进行交互,并可以从用户空间直接得到调试信息。下面我们将讨论这方面的详细内容。示例中的所有命令行都是在内核版本为 3.13.0-24 的 Ubuntu 14.04 中运行的。 + +### Ftrace:常用信息 + +Ftrace 是函数 Trace 的简写,但它能做的远不止这些:它可以跟踪上下文切换、测量进程阻塞时间、计算高优先级任务的活动时间等等。 + +Ftrace 是由 Steven Rostedt 开发的,从 2008 年发布的内核 2.6.27 中开始就内置了。这是为记录数据提供的一个调试 `Ring` 缓冲区的框架。这些数据由集成到内核中的跟踪程序来采集。 + +Ftrace 工作在 debugfs 文件系统上,这是在大多数现代 Linux 分发版中默认挂载的文件系统。为开始使用 ftrace,你将进入到 `sys/kernel/debug/tracing` 目录(仅对 root 用户可用): + +``` +# cd /sys/kernel/debug/tracing +``` + +这个目录的内容看起来应该像这样: + +``` +аvailable_filter_functions options stack_trace_filter +available_tracers per_cpu trace +buffer_size_kb printk_formats trace_clock +buffer_total_size_kb README trace_marker +current_tracer saved_cmdlines trace_options +dyn_ftrace_total_info set_event trace_pipe +enabled_functions set_ftrace_filter trace_stat +events set_ftrace_notrace tracing_cpumask +free_buffer set_ftrace_pid tracing_max_latency +function_profile_enabled set_graph_function tracing_on +instances set_graph_notrace tracing_thresh +kprobe_events snapshot uprobe_events +kprobe_profile stack_max_size uprobe_profile +``` + +我不想去描述这些文件和子目录;它们的描述在 [官方文档][20] 中已经写的很详细了。我只想去详细介绍与我们这篇文章相关的这几个文件: + +* available_tracers —— 可用的跟踪程序 + +* current_tracer —— 正在运行的跟踪程序 + +* tracing_on —— 负责启用或禁用数据写入到 `Ring` 缓冲区的系统文件(如果启用它,在文件中添加数字 1,禁用它,添加数字 0) + +* trace —— 以人类友好格式保存跟踪数据的文件 + +### 可用的跟踪程序 + +我们可以使用如下的命令去查看可用的跟踪程序的一个列表 + +``` +root@andrei:/sys/kernel/debug/tracing#: cat available_tracers +blk mmiotrace function_graph wakeup_rt wakeup function nop +``` + +我们来快速浏览一下每个跟踪程序的特性: + +* function —— 一个无需参数的函数调用跟踪程序 + +* function_graph —— 一个使用子调用的函数调用跟踪程序 + +* blk —— 一个与块 I/O 跟踪相关的调用和事件跟踪程序(它是 blktrace 的用途) + +* mmiotrace —— 一个内存映射 I/O 操作跟踪程序 + +* nop —— 简化的跟踪程序,就像它的名字所暗示的那样,它不做任何事情(尽管在某些情况下可能会派上用场,我们将在后文中详细解释) + +### 函数跟踪程序 + +在开始介绍函数跟踪程序 ftrace 之前,我们先看一下测试脚本: + +``` +#!/bin/sh + +dir=/sys/kernel/debug/tracing + +sysctl kernel.ftrace_enabled=1 +echo function > ${dir}/current_tracer +echo 1 > ${dir}/tracing_on +sleep 1 +echo 0 > ${dir}/tracing_on +less ${dir}/trace +``` + +这个脚本是非常简单的,但是还有几个需要注意的地方。命令 `sysctl ftrace.enabled=1` 启用了函数跟踪程序。然后我们通过写它的名字到 `current_tracer` 文件来启用 `current tracer`。 + +接下来,我们写入一个 `1` 到 `tracing_on`,它启用了 `Ring` 缓冲区。这些语法都要求在 `1` 和 `>` 符号前后有一个空格;写成像 `echo1> tracing_on` 这样将不能工作。一行之后我们禁用它(如果 `0` 写入到 `tracing_on`, 缓冲区不会被清除并且 ftrace 并不会被禁用)。 + +我们为什么这样做呢?在两个 `echo` 命令之间,我们看到了命令 `sleep 1`。我们启用了缓冲区,运行了这个命令,然后禁用它。这将使跟踪程序采集了这个命令运行期间发生的所有系统调用的信息。 + +在脚本的最后一行,我们写了一个在控制台上显示跟踪数据的命令。 + +一旦脚本运行完成后,我们将看到下列的输出(这里只列出了一个小片断): + +``` +# tracer: function +# +# entries-in-buffer/entries-written: 29571/29571 #P:2 +# +# _-----=> irqs-off +# / _----=> need-resched +# | / _---=> hardirq/softirq +# || / _--=> preempt-depth +# ||| / delay +# TASK-PID CPU# |||| TIMESTAMP FUNCTION +# | | | |||| | | + trace.sh-1295 [000] .... 90.502874: mutex_unlock <-rb_simple_write + trace.sh-1295 [000] .... 90.502875: __fsnotify_parent <-vfs_write + trace.sh-1295 [000] .... 90.502876: fsnotify <-vfs_write + trace.sh-1295 [000] .... 90.502876: __srcu_read_lock <-fsnotify + trace.sh-1295 [000] .... 90.502876: __srcu_read_unlock <-fsnotify + trace.sh-1295 [000] .... 90.502877: __sb_end_write <-vfs_write + trace.sh-1295 [000] .... 90.502877: syscall_trace_leave <-int_check_syscall_exit_work + trace.sh-1295 [000] .... 90.502878: context_tracking_user_exit <-syscall_trace_leave + trace.sh-1295 [000] .... 90.502878: context_tracking_user_enter <-syscall_trace_leave + trace.sh-1295 [000] d... 90.502878: vtime_user_enter <-context_tracking_user_enter + trace.sh-1295 [000] d... 90.502878: _raw_spin_lock <-vtime_user_enter + trace.sh-1295 [000] d... 90.502878: __vtime_account_system <-vtime_user_enter + trace.sh-1295 [000] d... 90.502878: get_vtime_delta <-__vtime_account_system + trace.sh-1295 [000] d... 90.502879: account_system_time <-__vtime_account_system + trace.sh-1295 [000] d... 90.502879: cpuacct_account_field <-account_system_time + trace.sh-1295 [000] d... 90.502879: acct_account_cputime <-account_system_time + trace.sh-1295 [000] d... 90.502879: __acct_update_integrals <-acct_account_cputime +``` + +这个输出以缓冲区中的信息条目数量和写入的条目数量开始。这两者的数据差异是缓冲区中事件的丢失数量(在我们的示例中没有发生丢失)。 + +在这里有一个包含下列信息的函数列表: + +* 进程标识符(PID) + +* 运行这个进程的 CPU(CPU#) + +* 进程开始时间(TIMESTAMP) + +* 被跟踪函数的名字以及调用它的父级函数;例如,在我们输出的第一行,`rb_simple_write` 调用了 `mutex-unlock` 函数。 + +### Function_graph 跟踪程序 + +`function_graph` 跟踪程序的工作和函数一样,但是它更详细:它显示了每个函数的进入和退出点。使用这个跟踪程序,我们可以跟踪函数的子调用并且测量每个函数的运行时间。 + +我们来编辑一下最后一个示例的脚本: + +``` +#!/bin/sh + +dir=/sys/kernel/debug/tracing + +sysctl kernel.ftrace_enabled=1 +echo function_graph > ${dir}/current_tracer +echo 1 > ${dir}/tracing_on +sleep 1 +echo 0 > ${dir}/tracing_on +less ${dir}/trace +``` + +运行这个脚本之后,我们将得到如下的输出: + +``` +# tracer: function_graph +# +# CPU DURATION FUNCTION CALLS +# | | | | | | | + 0) 0.120 us | } /* resched_task */ + 0) 1.877 us | } /* check_preempt_curr */ + 0) 4.264 us | } /* ttwu_do_wakeup */ + 0) + 29.053 us | } /* ttwu_do_activate.constprop.74 */ + 0) 0.091 us | _raw_spin_unlock(); + 0) 0.260 us | ttwu_stat(); + 0) 0.133 us | _raw_spin_unlock_irqrestore(); + 0) + 37.785 us | } /* try_to_wake_up */ + 0) + 38.478 us | } /* default_wake_function */ + 0) + 39.203 us | } /* pollwake */ + 0) + 40.793 us | } /* __wake_up_common */ + 0) 0.104 us | _raw_spin_unlock_irqrestore(); + 0) + 42.920 us | } /* __wake_up_sync_key */ + 0) + 44.160 us | } /* sock_def_readable */ + 0) ! 192.850 us | } /* tcp_rcv_established */ + 0) ! 197.445 us | } /* tcp_v4_do_rcv */ + 0) 0.113 us | _raw_spin_unlock(); + 0) ! 205.655 us | } /* tcp_v4_rcv */ + 0) ! 208.154 us | } /* ip_local_deliver_finish */ +``` + +在这个图中,`DURATION` 展示了花费在每个运行的函数上的时间。注意使用 `+` 和 `!` 符号标记的地方。加号(+)意思是这个函数花费的时间超过 10 毫秒;而感叹号(!)意思是这个函数花费的时间超过了 100 毫秒。 + +在 `FUNCTION_CALLS` 下面,我们可以看到每个函数调用的信息。 + +和 C 语言一样使用了花括号({)标记每个函数的边界,它展示了每个函数的开始和结束,一个用于开始,一个用于结束;不能调用其它任何函数的叶子函数用一个分号(;)标记。 + +### 函数过滤器 + +ftrace 输出可能会很大,精确找出你所需要的内容可能会非常困难。我们可以使用过滤器去简化我们的搜索:输出中将只显示与我们感兴趣的函数相关的信息。为实现过滤,我们只需要在 `set_ftrace_filter` 文件中写入我们需要过滤的函数的名字即可。例如: + +``` +root@andrei:/sys/kernel/debug/tracing# echo kfree > set_ftrace_filter +``` + +如果禁用过滤器,我们只需要在这个文件中添加一个空白行即可: + +``` +root@andrei:/sys/kernel/debug/tracing# echo > set_ftrace_filter +``` + +通过运行这个命令: + +``` +root@andrei:/sys/kernel/debug/tracing# echo kfree > set_ftrace_notrace +``` + +我们将得到相反的结果:输出将包含除了 `kfree()` 以外的任何函数的信息。 + +另一个有用的选项是 `set_ftrace_pid`。它是为在一个特定的进程运行期间调用跟踪函数准备的。 + +ftrace 还有很多过滤选项。对于它们更详细的介绍,你可以去查看 Steven Rostedt 在 [LWN.net][21] 上的文章。 + +### 跟踪事件 + +我们在上面提到到跟踪点机制。跟踪点是插入的由系统事件触发的特定代码。跟踪点可以是动态的(意味着可能会在它们上面附加几个检查),也可以是静态的(意味着不会附加任何检查)。 + +静态跟踪点不会对系统有任何影响;它们只是增加几个字节用于调用测试函数以及在一个独立的节上增加一个数据结构。 + +当相关代码片断运行时,动态跟踪点调用一个跟踪函数。跟踪数据是写入到 `Ring` 缓冲区。 + +跟踪点可以设置在代码的任何位置;事实上,它们确实可以在许多的内核函数中找到。我们来看一下 `kmem_cache_alloc` 函数(它在 [这里][22]): + +``` +{ + void *ret = slab_alloc(cachep, flags, _RET_IP_); + + trace_kmem_cache_alloc(_RET_IP_, ret, + cachep->object_size, cachep->size, flags); + return ret; + } +``` + +`trace_kmem_cache_alloc` 它本身就是一个跟踪点。我们可以通过查看其它内核函数的源代码找到这样无数的例子。 + +在 Linux 内核中为了从用户空间使用跟踪点,它有一个专门的 API。在 `/sys/kernel/debug/tracing` 目录中,这里有一个事件目录,它是为了保存系统事件。这些只是为了跟踪系统事件。在这个上下文中系统事件可以理解为包含在内核中的跟踪点。 + +可以通过运行如下的命令来查看这个事件列表: + +``` +root@andrei:/sys/kernel/debug/tracing# cat available_events +``` + +这个命令将在控制台中输出一个很长的列表。这样看起来很不方便。我们可以使用如下的命令来列出一个结构化的列表: + +``` +root@andrei:/sys/kernel/debug/tracing# ls events + +block gpio mce random skb vsyscall +btrfs header_event migrate ras sock workqueue +compaction header_page module raw_syscalls spi writeback +context_tracking iommu napi rcu swiotlb xen +enable irq net regmap syscalls xfs +exceptions irq_vectors nmi regulator task xhci-hcd +ext4 jbd2 oom rpm timer +filemap kmem pagemap sched udp +fs kvm power scsi vfs +ftrace kvmmmu printk signal vmscan +``` + +所有可能的事件都按子系统分组到子目录中。在我们开始跟踪事件之前,我们要先确保启用了 `Ring` 缓冲区写入: + +``` +root@andrei:/sys/kernel/debug/tracing# cat tracing_on +``` + +如果在控制台中显示的是数字 0,那么,我们可以运行如下的命令来启用它: + +``` +root@andrei:/sys/kernel/debug/tracing# echo 1 > tracing_on +``` + +在我们上一篇的文章中,我们写了关于 `chroot()` 系统调用的内容;我们来跟踪访问一下这个系统调用。为了跟踪,我们使用 `nop` 因为函数跟踪程序和 `function_graph` 跟踪程序记录的信息太多,它包含了我们不感兴趣的事件信息。 + +``` +root@andrei:/sys/kernel/debug/tracing# echo nop > current_tracer +``` + +所有事件相关的系统调用都保存在系统调用目录下。在这里我们将找到一个进入和退出多个系统调用的目录。我们需要在相关的文件中通过写入数字 `1` 来激活跟踪点: + +``` +root@andrei:/sys/kernel/debug/tracing# echo 1 > events/syscalls/sys_enter_chroot/enable +``` + +然后我们使用 `chroot` 来创建一个独立的文件系统(更多内容,请查看 [这篇文章][23])。在我们执行完我们需要的命令之后,我们将禁用跟踪程序,以便于不需要的信息或者过量信息出现在输出中: + +``` +root@andrei:/sys/kernel/debug/tracing# echo 0 > tracing_on +``` + +然后,我们去查看 `Ring` 缓冲区的内容。在输出的结束部分,我们找到了有关的系统调用信息(这里只是一个节选)。 + +``` +root@andrei:/sys/kernel/debug/tracing# сat trace + +...... + chroot-11321 [000] .... 4606.265208: sys_chroot(filename: 7fff785ae8c2) + chroot-11325 [000] .... 4691.677767: sys_chroot(filename: 7fff242308cc) + bash-11338 [000] .... 4746.971300: sys_chroot(filename: 7fff1efca8cc) + bash-11351 [000] .... 5379.020609: sys_chroot(filename: 7fffbf9918cc) +``` + +关于配置事件跟踪的更的信息可以在 [这里][24] 找到。 + +### 结束语 + +在这篇文篇中,我们做了一个 ftrace 的功能概述。我们非常感谢你的任何意见或者补充。如果你想深入研究这个主题,我们为你推荐下列的资源: + +* [https://www.kernel.org/doc/Documentation/trace/tracepoints.txt][1] — 一个跟踪点机制的详细描述 + +* [https://www.kernel.org/doc/Documentation/trace/events.txt][2] — 在 Linux 中跟踪系统事件的指南 + +* [https://www.kernel.org/doc/Documentation/trace/ftrace.txt][3] — ftrace 的官方文档 + +* [https://lttng.org/files/thesis/desnoyers-dissertation-2009-12-v27.pdf][4] — Mathieu Desnoyers(作者是跟踪点和 LTTNG 的创建者)的关于内核跟踪和分析的学术论文。 + +* [https://lwn.net/Articles/370423/][5] — Steven Rostedt 的关于 ftrace 功能的文章 + +* [http://alex.dzyoba.com/linux/profiling-ftrace.html][6] — 用 ftrace 分析实际案例的一个概述 + +-------------------------------------------------------------------------------- + +via:https://blog.selectel.com/kernel-tracing-ftrace/ + +作者:[Andrej Yemelianov][a] +译者:[qhwdw](https://github.com/qhwdw) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://blog.selectel.com/author/yemelianov/ +[1]:https://www.kernel.org/doc/Documentation/trace/tracepoints.txt +[2]:https://www.kernel.org/doc/Documentation/trace/events.txt +[3]:https://www.kernel.org/doc/Documentation/trace/ftrace.txt +[4]:https://lttng.org/files/thesis/desnoyers-dissertation-2009-12-v27.pdf +[5]:https://lwn.net/Articles/370423/ +[6]:http://alex.dzyoba.com/linux/profiling-ftrace.html +[7]:https://blog.selectel.com/author/yemelianov/ +[8]:https://blog.selectel.com/tag/ftrace/ +[9]:https://blog.selectel.com/tag/kernel/ +[10]:https://blog.selectel.com/tag/kernel-profiling/ +[11]:https://blog.selectel.com/tag/kernel-tracing/ +[12]:https://blog.selectel.com/tag/linux/ +[13]:https://blog.selectel.com/tag/tracepoints/ +[14]:https://sourceware.org/systemtap/ +[15]:https://github.com/ktap/ktap +[16]:http://www.sysdig.org/ +[17]:http://lttng.org/ +[18]:https://www.kernel.org/doc/Documentation/trace/ftrace.txt +[19]:http://www.brendangregg.com/blog/index.html +[20]:https://www.kernel.org/doc/Documentation/trace/ftrace.txt +[21]:https://lwn.net/Articles/370423/ +[22]:http://lxr.free-electrons.com/source/mm/slab.c +[23]:https://blog.selectel.com/containerization-mechanisms-namespaces/ +[24]:https://www.kernel.org/doc/Documentation/trace/events.txt \ No newline at end of file From d6f3cabbe83f55a343558cbcf8787f5e6e864f00 Mon Sep 17 00:00:00 2001 From: wxy Date: Wed, 31 Jan 2018 15:18:57 +0800 Subject: [PATCH 093/272] PRF:20171107 How To Protect Server Against Brute Force Attacks With Fail2ban On Linux.md @Flowsnow --- ...te Force Attacks With Fail2ban On Linux.md | 84 ++++++++++--------- 1 file changed, 43 insertions(+), 41 deletions(-) diff --git a/translated/tech/20171107 How To Protect Server Against Brute Force Attacks With Fail2ban On Linux.md b/translated/tech/20171107 How To Protect Server Against Brute Force Attacks With Fail2ban On Linux.md index 1d90ea333c..2a4547fef3 100644 --- a/translated/tech/20171107 How To Protect Server Against Brute Force Attacks With Fail2ban On Linux.md +++ b/translated/tech/20171107 How To Protect Server Against Brute Force Attacks With Fail2ban On Linux.md @@ -1,64 +1,65 @@ -如何在Linux上用Fail2ban保护服务器免受暴力攻击 +如何在 Linux 上用 Fail2Ban 保护服务器免受暴力攻击 ====== -Linux管理员的一个重要任务是保护服务器免受非法攻击或访问。 默认情况下,Linux系统带有配置良好的防火墙,比如Iptables,Uncomplicated Firewall(UFW),ConfigServer Security Firewall(CSF)等,可以防止多种攻击。 +Linux 管理员的一个重要任务是保护服务器免受非法攻击或访问。 默认情况下,Linux 系统带有配置良好的防火墙,比如iptables、Uncomplicated Firewall(UFW),ConfigServer Security Firewall(CSF)等,可以防止多种攻击。 -任何连接到互联网的机器都是恶意攻击的潜在目标。 有一个名为fail2ban的工具可用来缓解服务器上的非法访问。 +任何连接到互联网的机器都是恶意攻击的潜在目标。 有一个名为 Fail2Ban 的工具可用来缓解服务器上的非法访问。 -### 什么是Fail2ban? +### 什么是 Fail2Ban? -[Fail2ban][1]是一款入侵防御软件,可以保护服务器免受暴力攻击。 它是用Python编程语言编写的。 Fail2ban基于auth日志文件工作,默认情况下它会扫描所有auth日志文件,如`/var/log/auth.log`,`/var/log/apache/access.log`等,并禁止带有恶意标志的IP,比如密码失败太多,寻找漏洞等等标志。 +[Fail2Ban][1] 是一款入侵防御软件,可以保护服务器免受暴力攻击。 它是用 Python 编程语言编写的。 Fail2Ban 基于auth 日志文件工作,默认情况下它会扫描所有 auth 日志文件,如 `/var/log/auth.log`、`/var/log/apache/access.log` 等,并禁止带有恶意标志的IP,比如密码失败太多,寻找漏洞等等标志。 -通常,fail2Ban用于更新防火墙规则,用于在指定的时间内拒绝IP地址。 它也会发送邮件通知。 Fail2Ban为各种服务提供了许多过滤器,如ssh,apache,nginx,squid,named,mysql,nagios等。 +通常,Fail2Ban 用于更新防火墙规则,用于在指定的时间内拒绝 IP 地址。 它也会发送邮件通知。 Fail2Ban 为各种服务提供了许多过滤器,如 ssh、apache、nginx、squid、named、mysql、nagios 等。 -Fail2Ban能够降低错误认证尝试的速度,但是它不能消除弱认证带来的风险。 这只是服务器防止暴力攻击的安全手段之一。 +Fail2Ban 能够降低错误认证尝试的速度,但是它不能消除弱认证带来的风险。 这只是服务器防止暴力攻击的安全手段之一。 -### 如何在Linux中安装Fail2ban +### 如何在 Linux 中安装 Fail2Ban -Fail2ban已经与大部分Linux发行版打包在一起了,所以只需使用你的发行包版的包管理器来安装它。 +Fail2Ban 已经与大部分 Linux 发行版打包在一起了,所以只需使用你的发行包版的包管理器来安装它。 -对于**`Debian / Ubuntu`**,使用[APT-GET命令][2]或[APT命令][3]安装。 +对于 Debian / Ubuntu,使用 [APT-GET 命令][2]或 [APT 命令][3]安装。 ``` $ sudo apt install fail2ban ``` -对于**`Fedora`**,使用[DNF命令][4]安装。 +对于 Fedora,使用 [DNF 命令][4]安装。 ``` $ sudo dnf install fail2ban ``` -对于 **`CentOS/RHEL`**,启用[EPEL库][5]或[RPMForge][6]库,使用[YUM命令][7]安装。 +对于 CentOS/RHEL,启用 [EPEL 库][5]或 [RPMForge][6] 库,使用 [YUM 命令][7]安装。 ``` $ sudo yum install fail2ban ``` -对于**`Arch Linux`**,使用[Pacman命令][8]安装。 +对于 Arch Linux,使用 [Pacman 命令][8]安装。 ``` $ sudo pacman -S fail2ban ``` -对于 **`openSUSE`** , 使用[Zypper命令][9]安装. +对于 openSUSE , 使用 [Zypper命令][9]安装。 + ``` $ sudo zypper in fail2ban ``` -### 如何配置Fail2ban +### 如何配置 Fail2Ban -默认情况下,Fail2ban将所有配置文件保存在`/etc/fail2ban/` 目录中。 主配置文件是`jail.conf`,它包含一组预定义的过滤器。 所以,不要编辑文件,这是不可取的,因为只要有新的更新配置就会重置为默认值。 +默认情况下,Fail2Ban 将所有配置文件保存在 `/etc/fail2ban/` 目录中。 主配置文件是 `jail.conf`,它包含一组预定义的过滤器。 所以,不要编辑该文件,这是不可取的,因为只要有新的更新,配置就会重置为默认值。 -只需在同一目录下创建一个名为`jail.local`的新配置文件,并根据您的意愿进行修改。 +只需在同一目录下创建一个名为 `jail.local` 的新配置文件,并根据您的意愿进行修改。 ``` # cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local ``` -默认情况下,大多数选项都已经配置的很完美了,如果要启用对任何特定IP的访问,则可以将IP地址添加到`ignoreip` 区域,对于多个ip的情况,用空格隔开ip地址。 +默认情况下,大多数选项都已经配置的很完美了,如果要启用对任何特定 IP 的访问,则可以将 IP 地址添加到 `ignoreip` 区域,对于多个 IP 的情况,用空格隔开 IP 地址。 -配置文件中的`DEFAULT`部分包含Fail2Ban遵循的基本规则集,您可以根据自己的意愿调整任何参数。 +配置文件中的 `DEFAULT` 部分包含 Fail2Ban 遵循的基本规则集,您可以根据自己的意愿调整任何参数。 ``` # nano /etc/fail2ban/jail.local @@ -71,16 +72,14 @@ maxretry = 3 destemail = 2daygeek@gmail.com ``` - * **ignoreip:**本部分允许我们列出IP地址列表,Fail2ban不会禁止与列表中的地址匹配的主机 -* **bantime:**主机被禁止的秒数 -* **findtime:**如果在上次“findtime”秒期间已经发生了“maxretry”次重试,则主机会被禁止 -* **maxretry:**“maxretry”是主机被禁止之前的失败次数 - - +* `ignoreip`:本部分允许我们列出 IP 地址列表,Fail2Ban 不会禁止与列表中的地址匹配的主机 +* `bantime`:主机被禁止的秒数 +* `findtime`:如果在最近 `findtime` 秒期间已经发生了 `maxretry` 次重试,则主机会被禁止 +* `maxretry`:是主机被禁止之前的失败次数 ### 如何配置服务 -Fail2ban带有一组预定义的过滤器,用于各种服务,如ssh,apache,nginx,squid,named,mysql,nagios等。 我们不希望对配置文件进行任何更改,只需在服务区域中添加`enabled = true`这一行就可以启用任何服务。 禁用服务时将true改为false即可。 +Fail2Ban 带有一组预定义的过滤器,用于各种服务,如 ssh、apache、nginx、squid、named、mysql、nagios 等。 我们不希望对配置文件进行任何更改,只需在服务区域中添加 `enabled = true` 这一行就可以启用任何服务。 禁用服务时将 `true` 改为 `false` 即可。 ``` # SSH servers @@ -91,16 +90,15 @@ logpath = %(sshd_log)s backend = %(sshd_backend)s ``` - * **enabled:** 确定服务是打开还是关闭。 -* **port :**指的是特定的服务。 如果使用默认端口,则服务名称可以放在这里。 如果使用非传统端口,则应该是端口号。 -* **logpath:**提供服务日志的位置 -* **backend:**“后端”指定用于获取文件修改的后端。 +* `enabled`: 确定服务是打开还是关闭。 +* `port`:指明特定的服务。 如果使用默认端口,则服务名称可以放在这里。 如果使用非传统端口,则应该是端口号。 +* `logpath`:提供服务日志的位置 +* `backend`:指定用于获取文件修改的后端。 +### 重启 Fail2Ban +进行更改后,重新启动 Fail2Ban 才能生效。 -### 重启Fail2Ban - -进行更改后,重新启动Fail2Ban才能生效。 ``` [For SysVinit Systems] # service fail2ban restart @@ -109,9 +107,10 @@ backend = %(sshd_backend)s # systemctl restart fail2ban.service ``` -### 验证Fail2Ban iptables规则 +### 验证 Fail2Ban iptables 规则 + +你可以使用下面的命令来确认是否在防火墙中成功添加了Fail2Ban iptables 规则。 -你可以使用下面的命令来确认是否在防火墙中成功添加了Fail2Ban iptables规则。 ``` # iptables -L Chain INPUT (policy ACCEPT) @@ -135,9 +134,9 @@ target prot opt source destination RETURN all -- anywhere anywhere ``` -### 如何测试Fail2ban +### 如何测试 Fail2Ban -我做了一些失败的尝试来测试这个。 为了证实这一点,我要验证`/var/log/fail2ban.log` 文件。 +我做了一些失败的尝试来测试这个。 为了证实这一点,我要验证 `/var/log/fail2ban.log` 文件。 ``` 2017-11-05 14:43:22,901 fail2ban.server [7141]: INFO Changed logging target to /var/log/fail2ban.log for Fail2ban v0.9.6 @@ -184,6 +183,7 @@ RETURN all -- anywhere anywhere ``` 要查看启用的监狱列表,请运行以下命令。 + ``` # fail2ban-client status Status @@ -191,7 +191,8 @@ Status `- Jail list: apache-auth, sshd ``` -通过运行以下命令来获取禁止的IP地址。 +通过运行以下命令来获取禁止的 IP 地址。 + ``` # fail2ban-client status ssh Status for the jail: ssh @@ -205,18 +206,19 @@ Status for the jail: ssh `- Total banned: 1 ``` -要从Fail2Ban中删除禁止的IP地址,请运行以下命令。 +要从 Fail2Ban 中删除禁止的 IP 地址,请运行以下命令。 + ``` # fail2ban-client set ssh unbanip 192.168.1.115 ``` -------------------------------------------------------------------------------- -via: https://www.2daygeek.com/how-to-install-setup-configure-fail2ban-on-linux/# +via: https://www.2daygeek.com/how-to-install-setup-configure-fail2ban-on-linux/ 作者:[Magesh Maruthamuthu][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 82882b78ff506e654808862355319e0cec43f8e8 Mon Sep 17 00:00:00 2001 From: wxy Date: Wed, 31 Jan 2018 15:19:40 +0800 Subject: [PATCH 094/272] PUB:20171107 How To Protect Server Against Brute Force Attacks With Fail2ban On Linux.md @Flowsnow https://linux.cn/article-9299-1.html --- ...t Server Against Brute Force Attacks With Fail2ban On Linux.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename {translated/tech => published}/20171107 How To Protect Server Against Brute Force Attacks With Fail2ban On Linux.md (100%) diff --git a/translated/tech/20171107 How To Protect Server Against Brute Force Attacks With Fail2ban On Linux.md b/published/20171107 How To Protect Server Against Brute Force Attacks With Fail2ban On Linux.md similarity index 100% rename from translated/tech/20171107 How To Protect Server Against Brute Force Attacks With Fail2ban On Linux.md rename to published/20171107 How To Protect Server Against Brute Force Attacks With Fail2ban On Linux.md From f4fb9f18601b44b87780350ad37626991f77db0a Mon Sep 17 00:00:00 2001 From: ChenYi <31087327+cyleft@users.noreply.github.com> Date: Wed, 31 Jan 2018 20:32:15 +0800 Subject: [PATCH 095/272] Delete 20180125 A step-by-step guide to Git.md --- .../20180125 A step-by-step guide to Git.md | 134 ------------------ 1 file changed, 134 deletions(-) delete mode 100644 sources/tech/20180125 A step-by-step guide to Git.md diff --git a/sources/tech/20180125 A step-by-step guide to Git.md b/sources/tech/20180125 A step-by-step guide to Git.md deleted file mode 100644 index 823e730a0f..0000000000 --- a/sources/tech/20180125 A step-by-step guide to Git.md +++ /dev/null @@ -1,134 +0,0 @@ -# translated by cyleft -# translated by cyleft -# translated by cyleft - -A step-by-step guide to Git -====== - -![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/lightbulb-idea-think-yearbook-lead.png?itok=5ZpCm0Jh) - -If you've never used [Git][1], you may be nervous about it. There's nothing to worry about--just follow along with this step-by-step getting-started guide, and you will soon have a new Git repository hosted on [GitHub][2]. - -Before we dive in, let's clear up a common misconception: Git isn't the same thing as GitHub. Git is a version-control system (i.e., a piece of software) that helps you keep track of your computer programs and files and the changes that are made to them over time. It also allows you to collaborate with your peers on a program, code, or file. GitHub and similar services (including GitLab and BitBucket) are websites that host a Git server program to hold your code. - -### Step 1: Create a GitHub account - -The easiest way to get started is to create an account on [GitHub.com][3] (it's free). - -![](https://opensource.com/sites/default/files/u128651/git_guide1.png) - -Pick a username (e.g., octocat123), enter your email address and a password, and click **Sign up for GitHub**. Once you are in, it will look something like this: - -![](https://opensource.com/sites/default/files/u128651/git_guide2.png) - -### Step 2: Create a new repository - -A repository is like a place or a container where something is stored; in this case we're creating a Git repository to store code. To create a new repository, select **New Repository** from the `+` sign dropdown menu (you can see I've selected it in the upper-right corner in the image above). - -![](https://opensource.com/sites/default/files/u128651/git_guide3.png) - -Enter a name for your repository (e.g, "Demo") and click **Create Repository**. Don't worry about changing any other options on this page. - -Congratulations! You have set up your first repo on GitHub.com. - -### Step 3: Create a file - -Once your repo is created, it will look like this: - -![](https://opensource.com/sites/default/files/u128651/git_guide4.png) - -Don't panic, it's simpler than it looks. Stay with me. Look at the section that starts "...or create a new repository on the command line," and ignore the rest for now. - -Open the Terminal program on your computer. - -![](https://opensource.com/sites/default/files/u128651/git_guide5.png) - -Type `git` and hit **Enter**. If it says command `bash: git: command not found`, then [install Git][4] with the command for your Linux operating system or distribution. Check the installation by typing `git` and hitting **Enter** ; if it's installed, you should see a bunch of information about how you can use the command. - -In the terminal, type: -``` -mkdir Demo -``` - -This command will create a directory (or folder) named Demo. - -Change your terminal to the Demo directory with the command: -``` -cd Demo -``` - -Then enter: -``` -echo "#Demo" >> README.md -``` - -This creates a file named `README.md` and writes `#Demo` in it. To check that the file was created successfully, enter: -``` -cat README.md -``` - -This will show you what is inside the `README.md` file, if the file was created correctly. Your terminal will look like this: - -![](https://opensource.com/sites/default/files/u128651/git_guide7.png) - -To tell your computer that Demo is a directory managed by the Git program, enter: -``` -git init -``` - -Then, to tell the Git program you care about this file and want to track any changes from this point forward, enter: -``` -git add README.md -``` - -### Step 4: Make a commit - -So far you've created a file and told Git about it, and now it's time to create a commit. Commit can be thought of as a milestone. Every time you accomplish some work, you can write a Git commit to store that version of your file, so you can go back later and see what it looked like at that point in time. Whenever you make a change to your file, you create a new version of that file, different from the previous one. - -To make a commit, enter: -``` -git commit -m "first commit" -``` - -That's it! You just created a Git commit and included a message that says first commit. You must always write a message in commit; it not only helps you identify a commit, but it also enables you to understand what you did with the file at that point. So tomorrow, if you add a new piece of code in your file, you can write a commit message that says, Added new code, and when you come back in a month to look at your commit history or Git log (the list of commits), you will know what you changed in the files. - -### Step 5: Connect your GitHub repo with your computer - -Now, it's time to connect your computer to GitHub with the command: -``` -git remote add origin https://github.com//Demo.git -``` - -Let's look at this command step by step. We are telling Git to add a `remote` called `origin` with the address `https://github.com//Demo.git` (i.e., the URL of your Git repo on GitHub.com). This allows you to interact with your Git repository on GitHub.com by typing `origin` instead of the full URL and Git will know where to send your code. Why `origin`? Well, you can name it anything else if you'd like. - -Now we have connected our local copy of the Demo repository to its remote counterpart on GitHub.com. Your terminal looks like this: - -![](https://opensource.com/sites/default/files/u128651/git_guide8.png) - -Now that we have added the remote, we can push our code (i.e., upload our `README.md` file) to GitHub.com. - -Once you are done, your terminal will look like this: - -![](https://opensource.com/sites/default/files/u128651/git_guide9.png) - -And if you go to `https://github.com//Demo` you will see something like this: - -![](https://opensource.com/sites/default/files/u128651/git_guide10.png) - -That's it! You have created your first GitHub repo, connected it to your computer, and pushed (or uploaded) a file from your computer to your repository called Demo on GitHub.com. Next time, I will write about Git cloning (downloading your code from GitHub to your computer), adding new files, modifying existing files, and pushing (uploading) files to GitHub. - --------------------------------------------------------------------------------- - -via: https://opensource.com/article/18/1/step-step-guide-git - -作者:[Kedar Vijay Kulkarni][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/kkulkarn -[1]:https://opensource.com/resources/what-is-git -[2]:https://opensource.com/life/15/11/short-introduction-github -[3]:https://github.com/ -[4]:https://www.linuxbabe.com/linux-server/install-git-verion-control-on-linux-debianubuntufedoraarchlinux#crt-2 From 4d5697d4cafe3652529c46dc2a34d399a58d8d98 Mon Sep 17 00:00:00 2001 From: ChenYi <31087327+cyleft@users.noreply.github.com> Date: Wed, 31 Jan 2018 20:32:42 +0800 Subject: [PATCH 096/272] translated by cyleft --- .../20180125 A step-by-step guide to Git.md | 128 ++++++++++++++++++ 1 file changed, 128 insertions(+) create mode 100644 translated/tech/20180125 A step-by-step guide to Git.md diff --git a/translated/tech/20180125 A step-by-step guide to Git.md b/translated/tech/20180125 A step-by-step guide to Git.md new file mode 100644 index 0000000000..7a7d999742 --- /dev/null +++ b/translated/tech/20180125 A step-by-step guide to Git.md @@ -0,0 +1,128 @@ +手把手指导您使用 Git +====== + +![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/lightbulb-idea-think-yearbook-lead.png?itok=5ZpCm0Jh) + +如果您从未使用过 [Git][1],甚至可能从未听说过它。莫慌张,只需要一步步地跟着入门教程,很快您就会在 [GitHub][2] 上拥有一个全新的 Git 仓库。 + +在开始之前,让我们先理清一个常见的误解:Git 并不是 GitHub。Git 是一套版本控制系统(或者说是一款软件),能够协助您跟踪计算机程序和文件在任何时间的更改。它同样允许您在程序、代码和文件操作上与同事协作。GitHub 以及类似服务(包括 GitLab 和 BitBucket)都属于部署了 Git 程序的网站,能够托管您的代码。 + +### 步骤 1:申请一个 GitHub 账户 + +在 [GitHub.com][3] (免费)网站上创建一个账户是最简单的方式。 + +![](https://opensource.com/sites/default/files/u128651/git_guide1.png) + +选择一个用户名(比如说,octocat123),输入您的邮箱地址和密码,然后点击 **Sign up for GitHub**。进入之后,您将看到下方插图的界面: + +![](https://opensource.com/sites/default/files/u128651/git_guide2.png) + +### 步骤 2:创建一个新的 repository + +一个 repository(仓库),类似于能储存物品的场所或是容器;在这里,我们创建仓库存储代码。在 `+` 符号内(在插图的右上角,我已经选中它了) 的下拉菜单中选择 **New Pepositiry**。 + +![](https://opensource.com/sites/default/files/u128651/git_guide3.png) + +给您的仓库命名(比如说,123)然后点击 **Create Repository**。无需考虑本页面的其他选项。 + +恭喜!您已经在 GitHub.com 中建立了您的第一个仓库。 + +### 步骤 3: 创建文件 + +当仓库创建完毕后,界面将和下方一致: + +![](https://opensource.com/sites/default/files/u128651/git_guide4.png) + +不必惊慌,它比看上去简单。跟紧步骤。忽略其他内容,注意截图上的“...or create a new repository on the command line,”。 + +在您的计算机中打开终端。 + +![](https://opensource.com/sites/default/files/u128651/git_guide5.png) + +键入 `git` 然后回车。如果命令行显示 `bash: git: command not found`,在您的操作系统或发行版使用 [安装 Git][4] 命令。键入 `git` 并回车检查是否成功安装;如果安装成功,您将看见大量关于使用说明的信息。 + +在终端内输入: +``` +mkdir Demo +``` +这个命令将会创建一个名为 Demo 的目录(文件夹)。 + +如下命令将会切换终端目录,跳转到 Demo 目录: +``` +cd Demo +``` + +然后输入: +``` +echo "#Demo" >> README.md +``` +创建一个名为 `README.md` 的文件,并写入 `#Demo`。检查文件是否创建成功,请输入: + +``` +cat README.md +``` +这将会为您显示 `README.md` 文件的内容,如果文件创建成功,您的终端会有如下显示: + +![](https://opensource.com/sites/default/files/u128651/git_guide7.png) + +使用 Git 程序告诉您的电脑,Demo 是一个被 Git 托管的目录,请输入: +``` +git init +``` + +然后,告诉 Git 程序您关心的文件并且想在此刻起跟踪它的任何改变,请输入: +``` +git add README.md +``` + +### 步骤 4:创建一次提交 + +目前为止,您已经创建了一个文件,并且已经通知了 Git,现在,是时候创建一次提交了。提交被看作为一个里程碑。每当完成一些工作之时,您都可以创建一次提交,保存文件当前版本,这样一来,您可以返回之前的版本,并且查看那时候的文件内容。无论那一次,您对修改过后的文件创建的新的存档,都和上一次的不一样。 + +创建一次提交,请输入: +``` +git commit -m "first commit" +``` + +就是这样!刚才您创建了包含一条注释为“first commit”的 Git 提交。每次提交,您都必须编辑注释信息;它不仅能协助您识别提交,而且能让您理解此时您对文件做了什么修改。这样到了明天,如果您在文件中添加新的代码,您可以写一句提交信息:添加了新的代码,然后当您一个月后回来查看提交记录或者 Git 日志(提交列表),您还能知道当时的您在文件夹里做了什么。 + +### 步骤 5: 将您的计算机连接到 GitHub 仓库 + +现在,是时候用如下命令将您的计算机连接到 GitHub 仓库了: +``` +git remote add origin https://github.com//Demo.git +``` + +让我们一步步的分析这行命令。我们通知 Git 去添加一个叫做 `origin` 的,拥有地址为 `https://github.com//Demo.git`(它也是您的 GitHub 地址仓库) 的 `remote`。当您递送代码时,允许您在 GitHub.com 和 Git 仓库交互时使用 `origin` 而不是完整的 Git 地址。为什么叫做 `origin`?当然,您可以叫点别的,只要您喜欢。 + +现在,在 GitHub.com 我们已经连接并复制本地 Demo 仓库副本到远程仓库。您的设备会有如下显示: + +![](https://opensource.com/sites/default/files/u128651/git_guide8.png) + +此刻我们已经连接到远程仓库,可以推送我们的代码(上传 `README.md` 文件) 到 GitHub.com。 + +执行完毕后,您的终端会显示如下信息: + +![](https://opensource.com/sites/default/files/u128651/git_guide9.png) + +然后,如果您访问 `https://github.com//Demo`,您会看到截图内显示的情况: + +![](https://opensource.com/sites/default/files/u128651/git_guide10.png) + +就是这么回事!您已经创建了您的第一个 GitHub 仓库,连接到了您的电脑,并且在 GitHub.com 推送(或者称:上传)名叫 Demo 的文件到您的远程仓库。下一次,我将编写关于 Git 复制、添加新文件、修改现存文件、推送(上传)文件到 GitHub。 + +-------------------------------------------------------------------------------- + +via: https://opensource.com/article/18/1/step-step-guide-git + +作者:[Kedar Vijay Kulkarni][a] +译者:[CYLeft](https://github.com/CYLeft) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://opensource.com/users/kkulkarn +[1]:https://opensource.com/resources/what-is-git +[2]:https://opensource.com/life/15/11/short-introduction-github +[3]:https://github.com/ +[4]:https://www.linuxbabe.com/linux-server/install-git-verion-control-on-linux-debianubuntufedoraarchlinux#crt-2 From 391d95a3c0a7f28ae0acb6c734d66efb821d84f8 Mon Sep 17 00:00:00 2001 From: ChenYi <31087327+cyleft@users.noreply.github.com> Date: Wed, 31 Jan 2018 20:53:34 +0800 Subject: [PATCH 097/272] apply for translation --- ...180129 Create your own personal Cloud- Install OwnCloud.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sources/tech/20180129 Create your own personal Cloud- Install OwnCloud.md b/sources/tech/20180129 Create your own personal Cloud- Install OwnCloud.md index de2fccaed8..1c366c580a 100644 --- a/sources/tech/20180129 Create your own personal Cloud- Install OwnCloud.md +++ b/sources/tech/20180129 Create your own personal Cloud- Install OwnCloud.md @@ -1,4 +1,6 @@ -Create your own personal Cloud: Install OwnCloud +translated by cyleft + +reate your own personal Cloud: Install OwnCloud ====== Cloud is what everyone is talking about. We have a number of major players in the market that are offering cloud storage as well as other cloud based services. But we can also create a personal cloud for ourselves. From c53ac668ec70501d373dca96877f0e975c63f88a Mon Sep 17 00:00:00 2001 From: geekpi Date: Thu, 1 Feb 2018 09:08:54 +0800 Subject: [PATCH 098/272] translated --- ...Intorduction to simple Ansible commands.md | 158 ------------------ ...Intorduction to simple Ansible commands.md | 157 +++++++++++++++++ 2 files changed, 157 insertions(+), 158 deletions(-) delete mode 100644 sources/tech/20170508 Ansible Tutorial- Intorduction to simple Ansible commands.md create mode 100644 translated/tech/20170508 Ansible Tutorial- Intorduction to simple Ansible commands.md diff --git a/sources/tech/20170508 Ansible Tutorial- Intorduction to simple Ansible commands.md b/sources/tech/20170508 Ansible Tutorial- Intorduction to simple Ansible commands.md deleted file mode 100644 index d0300fe6e3..0000000000 --- a/sources/tech/20170508 Ansible Tutorial- Intorduction to simple Ansible commands.md +++ /dev/null @@ -1,158 +0,0 @@ -translating---geekpi - -Ansible Tutorial: Intorduction to simple Ansible commands -====== -In our earlier Ansible tutorial, we discussed [**the installation & configuration of Ansible**][1]. Now in this ansible tutorial, we will learn some basic examples of ansible commands that we will use to manage our infrastructure. So let us start by looking at the syntax of a complete ansible command, - -``` -$ ansible -m -a -``` - -Here, we can also use a single host or all in place of & are optional to provide. Now let's look at some basic commands to use with ansible, - -### Check connectivity of hosts - -We have used this command in our previous tutorial also. The command to check connectivity of hosts is - -``` -$ ansible -m ping -``` - -### Rebooting hosts - -``` -$ ansible -a "/sbin/reboot" -``` - -### Checking host 's system information - -Ansible collects the system's information for all the hosts connected to it. To display the information of hosts, run - -``` -$ ansible -m setup | less -``` - -Secondly, to check a particular info from the collected information by passing an argument, - -``` -$ ansible -m setup -a "filter=ansible_distribution" -``` - -### Transfering files - -For transferring files we use a module 'copy' & complete command that is used is - -``` -$ ansible -m copy -a "src=/home/dan dest=/tmp/home" -``` - -### Manging users - -So to manage the users on the connected hosts, we use a module named 'user' & comamnds to use it are as follows, - -#### Creating a new user - -``` - $ ansible -m user -a "name=testuser password=" -``` - -#### Deleting a user - -``` -$ ansible -m user -a "name=testuser state=absent" -``` - - **Note:-** To create an encrypted password, use the 'mkpasswd -method=sha-512' command. - -### Changing permissions & ownership - -So for changing ownership of files of connected hosts, we use module named 'file' & commands used are - -### Changing permission of a file - -``` -$ ansible -m file -a "dest=/home/dan/file1.txt mode=777" -``` - -### Changing ownership of a file - -``` - $ ansible -m file -a "dest=/home/dan/file1.txt mode=777 owner=dan group=dan" -``` - -### Managing Packages - -So, we can manage the packages installed on all the hosts connected to ansible by using 'yum' & 'apt' modules & the complete commands used are - -#### Check if package is installed & update it - -``` -$ ansible -m yum -a "name=ntp state=latest" -``` - -#### Check if package is installed & don't update it - -``` -$ ansible -m yum -a "name=ntp state=present" -``` - -#### Check if package is at a specific version - -``` -$ ansible -m yum -a "name= ntp-1.8 state=present" -``` - -#### Check if package is not installed - -``` -$ ansible -m yum -a "name=ntp state=absent" -``` - -### Managing services - -So to manage services with ansible, we use a modules 'service' & complete commands that are used are, - -#### Starting a service - -``` -$ansible -m service -a "name=httpd state=started" -``` - -#### Stopping a service - -``` -$ ansible -m service -a "name=httpd state=stopped" -``` - -#### Restarting a service - -``` -$ ansible -m service -a "name=httpd state=restarted" -``` - -So this completes our tutorial of some simple, one line commands that can be used with ansible. Also, for our future tutorials, we will learn to create plays & playbooks that help us manage our hosts more easliy & efficiently. - -If you think we have helped you or just want to support us, please consider these :- - -Connect to us: [Facebook][2] | [Twitter][3] | [Google Plus][4] - -Become a Supporter - [Make a contribution via PayPal][5] - -Linux TechLab is thankful for your continued support. - --------------------------------------------------------------------------------- - -via: http://linuxtechlab.com/ansible-tutorial-simple-commands/ - -作者:[SHUSAIN][a] -译者:[译者ID](https://github.com/译者ID) -校对:[校对者ID](https://github.com/校对者ID) - -本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 - -[a]:http://linuxtechlab.com/author/shsuain/ -[1]:http://linuxtechlab.com/create-first-ansible-server-automation-setup/ -[2]:https://www.facebook.com/linuxtechlab/ -[3]:https://twitter.com/LinuxTechLab -[4]:https://plus.google.com/+linuxtechlab -[5]:http://linuxtechlab.com/contact-us-2/ diff --git a/translated/tech/20170508 Ansible Tutorial- Intorduction to simple Ansible commands.md b/translated/tech/20170508 Ansible Tutorial- Intorduction to simple Ansible commands.md new file mode 100644 index 0000000000..f9cfea9ecc --- /dev/null +++ b/translated/tech/20170508 Ansible Tutorial- Intorduction to simple Ansible commands.md @@ -0,0 +1,157 @@ +Ansible 教程:简单 Ansible 命令介绍 +====== +在我们之前的 Ansible 教程中,我们讨论了[ **Ansible** 的安装和配置][1]。在这个 ansible 教程中,我们将学习一些基本的 ansible 命令的例子,我们将用它来管理基础设施。所以让我们先看看一个完整的 ansible 命令的语法: + +``` +$ ansible -m -a +``` + +在这里,我们可以用单个主机或用 代替全部主机, 代表可以提供的选项。现在我们来看看一些 ansible 的基本命令。 + +### 检查主机的连通性 + +我们在之前的教程中也使用了这个命令。检查主机连接的命令是: + +``` +$ ansible -m ping +``` + +### 重启主机 + +``` +$ ansible -a "/sbin/reboot" +``` + +### 检查主机的系统信息 + +Ansible 收集所有连接到它主机的信息。要显示主机的信息,请运行: + +``` +$ ansible -m setup | less +``` + +其次,通过传递参数来从收集的信息中检查特定的信息: + +``` +$ ansible -m setup -a "filter=ansible_distribution" +``` + +### 传输文件 + +对于传输文件,我们使用模块 “copy” ,完整的命令是这样的: + +``` +$ ansible -m copy -a "src=/home/dan dest=/tmp/home" +``` + +### 管理用户 + +要管理已连接主机上的用户,我们使用一个名为 “user” 的模块,并如下使用它。 + +#### 创建新用户 + +``` + $ ansible -m user -a "name=testuser password=" +``` + +#### 删除用户 + +``` +$ ansible -m user -a "name=testuser state=absent" +``` + +**注意:** 要创建加密密码,请使用 ”mkpasswd -method=sha-512“。 + +### 更改权限和所有者 + +要改变已连接主机文件的所有者,我们使用名为 ”file“ 的模块,使用如下。 + +### 更改文件权限 + +``` +$ ansible -m file -a "dest=/home/dan/file1.txt mode=777" +``` + +### 更改文件的所有者 + +``` + $ ansible -m file -a "dest=/home/dan/file1.txt mode=777 owner=dan group=dan" +``` + +### 管理软件包 + +我们可以通过使用 ”yum“ 和 ”apt“ 模块来管理所有已连接主机的软件包,完整的命令如下: + +#### 检查包是否已安装并更新 + +``` +$ ansible -m yum -a "name=ntp state=latest" +``` + +#### 检查包是否已安装,但不更新 + +``` +$ ansible -m yum -a "name=ntp state=present" +``` + +#### 检查包是否是特定的版本 + +``` +$ ansible -m yum -a "name= ntp-1.8 state=present" +``` + +#### 检查包是否没有安装 + +``` +$ ansible -m yum -a "name=ntp state=absent" +``` + +### 管理服务 + +要管理服务,我们使用模块 “service” ,完整命令如下: + +#### 启动服务 + +``` +$ansible -m service -a "name=httpd state=started" +``` + +#### 停止服务 + +``` +$ ansible -m service -a "name=httpd state=stopped" +``` + +#### 重启服务 + +``` +$ ansible -m service -a "name=httpd state=restarted" +``` + +这样我们简单的,只有一行的 ansible 命令的教程就完成了。此外,在未来的教程中,我们将学习创建 playbook,来帮助我们更轻松高效地管理主机。 + +If you think we have helped you or just want to support us, please consider these :- +如果你认为我们帮助到您,或者只是想支持我们,请考虑这些: + +关注我们:[Facebook][2] | [Twitter][3] | [Google Plus][4] + +成为支持者 - [通过 PayPal 捐助][5] + +Linux TechLab 感谢你的持续支持。 + +-------------------------------------------------------------------------------- + +via: http://linuxtechlab.com/ansible-tutorial-simple-commands/ + +作者:[SHUSAIN][a] +译者:[geekpi](https://github.com/geekpi) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:http://linuxtechlab.com/author/shsuain/ +[1]:http://linuxtechlab.com/create-first-ansible-server-automation-setup/ +[2]:https://www.facebook.com/linuxtechlab/ +[3]:https://twitter.com/LinuxTechLab +[4]:https://plus.google.com/+linuxtechlab +[5]:http://linuxtechlab.com/contact-us-2/ From 1c4b300b38cae9485c335fb4ae067b91ef215518 Mon Sep 17 00:00:00 2001 From: geekpi Date: Thu, 1 Feb 2018 09:19:37 +0800 Subject: [PATCH 099/272] translating --- .../20170429 Monitoring network bandwidth with iftop command.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sources/tech/20170429 Monitoring network bandwidth with iftop command.md b/sources/tech/20170429 Monitoring network bandwidth with iftop command.md index c3369bf302..1eb7ed24a8 100644 --- a/sources/tech/20170429 Monitoring network bandwidth with iftop command.md +++ b/sources/tech/20170429 Monitoring network bandwidth with iftop command.md @@ -1,3 +1,5 @@ +translating---geekpi + Monitoring network bandwidth with iftop command ====== System Admins are required to monitor IT infrastructure to make sure that everything is up & running. We have to monitor performance of hardware i.e memory, hdds & CPUs etc & so does we have to monitor our network. We need to make sure that our network is not being over utilised or our applications, websites might not work. In this tutorial, we are going to learn to use IFTOP utility. From b58b097dc576b087dce8eaab754c180e0942933f Mon Sep 17 00:00:00 2001 From: darksun Date: Thu, 1 Feb 2018 09:32:20 +0800 Subject: [PATCH 100/272] =?UTF-8?q?=E9=80=89=E9=A2=98:=20Linux=20Find=20Ou?= =?UTF-8?q?t=20Last=20System=20Reboot=20Time=20and=20Date=20Command?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...ast System Reboot Time and Date Command.md | 160 ++++++++++++++++++ 1 file changed, 160 insertions(+) create mode 100644 sources/tech/20060430 Linux Find Out Last System Reboot Time and Date Command.md diff --git a/sources/tech/20060430 Linux Find Out Last System Reboot Time and Date Command.md b/sources/tech/20060430 Linux Find Out Last System Reboot Time and Date Command.md new file mode 100644 index 0000000000..f2e8de12bd --- /dev/null +++ b/sources/tech/20060430 Linux Find Out Last System Reboot Time and Date Command.md @@ -0,0 +1,160 @@ +Linux Find Out Last System Reboot Time and Date Command +====== +So, how do you find out your Linux or UNIX-like system was last rebooted? How do you display the system shutdown date and time? The last utility will either list the sessions of specified users, ttys, and hosts, in reverse time order, or list the users logged in at a specified date and time. Each line of output contains the user name, the tty from which the session was conducted, any hostname, the start and stop times for the session, and the duration of the session. To view Linux or Unix system reboot and shutdown date and time stamp using the following commands: + + * last command + * who command + + + +### Use who command to find last system reboot time/date + +You need to use the [who command][1], to print who is logged on. It also displays the time of last system boot. Use the last command to display system reboot and shutdown date and time, run: +`$ who -b` +Sample outputs: +``` + system boot 2017-06-20 17:41 +``` + +Use the last command to display listing of last logged in users and system last reboot time and date, enter: +`$ last reboot | less` +Sample outputs: +[![Fig.01: last command in action][2]][2] +Or, better try: +`$ last reboot | head -1` +Sample outputs: +``` +reboot system boot 4.9.0-3-amd64 Sat Jul 15 19:19 still running +``` + +The last command searches back through the file /var/log/wtmp and displays a list of all users logged in (and out) since that file was created. The pseudo user reboot logs in each time the system is rebooted. Thus last reboot command will show a log of all reboots since the log file was created. + +### Finding systems last shutdown date and time + +To display last shutdown date and time use the following command: +`$ last -x|grep shutdown | head -1` +Sample outputs: +``` +shutdown system down 2.6.15.4 Sun Apr 30 13:31 - 15:08 (01:37) +``` + +Where, + + * **-x** : Display the system shutdown entries and run level changes. + + + +Here is another session from my last command: +``` +$ last +$ last -x +$ last -x reboot +$ last -x shutdown +``` +Sample outputs: +![Fig.01: How to view last Linux System Reboot Date/Time ][3] + +### Find out Linux system up since… + +Another option as suggested by readers in the comments section below is to run the following command: +`$ uptime -s` +Sample outputs: +``` +2017-06-20 17:41:51 +``` + +### OS X/Unix/FreeBSD find out last reboot and shutdown time command examples + +Type the following command: +`$ last reboot` +Sample outputs from OS X unix: +``` +reboot ~ Fri Dec 18 23:58 +reboot ~ Mon Dec 14 09:54 +reboot ~ Wed Dec 9 23:21 +reboot ~ Tue Nov 17 21:52 +reboot ~ Tue Nov 17 06:01 +reboot ~ Wed Nov 11 12:14 +reboot ~ Sat Oct 31 13:40 +reboot ~ Wed Oct 28 15:56 +reboot ~ Wed Oct 28 11:35 +reboot ~ Tue Oct 27 00:00 +reboot ~ Sun Oct 18 17:28 +reboot ~ Sun Oct 18 17:11 +reboot ~ Mon Oct 5 09:35 +reboot ~ Sat Oct 3 18:57 + + +wtmp begins Sat Oct 3 18:57 +``` + +To see shutdown date and time, enter: +`$ last shutdown` +Sample outputs: +``` +shutdown ~ Fri Dec 18 23:57 +shutdown ~ Mon Dec 14 09:53 +shutdown ~ Wed Dec 9 23:20 +shutdown ~ Tue Nov 17 14:24 +shutdown ~ Mon Nov 16 21:15 +shutdown ~ Tue Nov 10 13:15 +shutdown ~ Sat Oct 31 13:40 +shutdown ~ Wed Oct 28 03:10 +shutdown ~ Sun Oct 18 17:27 +shutdown ~ Mon Oct 5 09:23 + + +wtmp begins Sat Oct 3 18:57 +``` + +### How do I find who rebooted/shutdown the Linux box? + +You need [to enable psacct service and run the following command to see info][4] about executed commands including user name. Type the following [lastcomm command][5] to see +``` +# lastcomm userNameHere +# lastcomm commandNameHere +# lastcomm | more +# lastcomm reboot +# lastcomm shutdown +### OR see both reboot and shutdown time +# lastcomm | egrep 'reboot|shutdown' +``` +Sample outputs: +``` +reboot S X root pts/0 0.00 secs Sun Dec 27 23:49 +shutdown S root pts/1 0.00 secs Sun Dec 27 23:45 +``` + +So root user rebooted the box from 'pts/0' on Sun, Dec, 27th at 23:49 local time. + +### See also + + * For more information read last(1) and [learn how to use the tuptime command on Linux server to see the historical and statistical uptime][6]. + + + +### about the author + + +The author is the creator of nixCraft and a seasoned sysadmin and a trainer for the Linux operating system/Unix shell scripting. He has worked with global clients and in various industries, including IT, education, defense and space research, and the nonprofit sector. Follow him on [Twitter][7], [Facebook][8], [Google+][9]. + +-------------------------------------------------------------------------------- + +via: https://www.cyberciti.biz/tips/linux-last-reboot-time-and-date-find-out.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/unix-linux-who-command-examples-syntax-usage/ (See Linux/Unix who command examples for more info) +[2]:https://www.cyberciti.biz/tips/wp-content/uploads/2006/04/last-reboot.jpg +[3]:https://www.cyberciti.biz/media/new/tips/2006/04/check-last-time-system-was-rebooted.jpg +[4]:https://www.cyberciti.biz/tips/howto-log-user-activity-using-process-accounting.html +[5]:https://www.cyberciti.biz/faq/linux-unix-lastcomm-command-examples-usage-syntax/ (See Linux/Unix lastcomm command examples for more info) +[6]:https://www.cyberciti.biz/hardware/howto-see-historical-statistical-uptime-on-linux-server/ +[7]:https://twitter.com/nixcraft +[8]:https://facebook.com/nixcraft +[9]:https://plus.google.com/+CybercitiBiz From 86c1e5ac77c43f7d2673f1767b1d293a881f825e Mon Sep 17 00:00:00 2001 From: darksun Date: Thu, 1 Feb 2018 09:37:15 +0800 Subject: [PATCH 101/272] =?UTF-8?q?=E9=80=89=E9=A2=98:=20An=20old=20DOS=20?= =?UTF-8?q?BBS=20in=20a=20Docker=20container?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...31 An old DOS BBS in a Docker container.md | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 sources/talk/20180131 An old DOS BBS in a Docker container.md diff --git a/sources/talk/20180131 An old DOS BBS in a Docker container.md b/sources/talk/20180131 An old DOS BBS in a Docker container.md new file mode 100644 index 0000000000..769b5db1bd --- /dev/null +++ b/sources/talk/20180131 An old DOS BBS in a Docker container.md @@ -0,0 +1,51 @@ +An old DOS BBS in a Docker container +====== +Awhile back, I wrote about [my Debian Docker base images][1]. I decided to extend this concept a bit further: to running DOS applications in Docker. + +But first, a screenshot: + +![][2] + +It turns out this is possible, but difficult. I went through all three major DOS emulators available (dosbox, qemu, and dosemu). I got them all running inside the Docker container, but had a number of, er, fun issues to resolve. + +The general thing one has to do here is present a fake modem to the DOS environment. This needs to be exposed outside the container as a TCP port. That much is possible in various ways -- I wound up using tcpser. dosbox had a TCP modem interface, but it turned out to be too buggy for this purpose. + +The challenge comes in where you want to be able to accept more than one incoming telnet (or TCP) connection at a time. DOS was not a multitasking operating system, so there were any number of hackish solutions back then. One might have had multiple physical computers, one for each incoming phone line. Or they might have run multiple pseudo-DOS instances under a multitasking layer like [DESQview][3], OS/2, or even Windows 3.1. + +(Side note: I just learned of [DESQview/X][4], which integrated DESQview with X11R5 and [replaced the Windows 3 drivers][5] to allow running Windows as an X application). + +For various reasons, I didn't want to try running one of those systems inside Docker. That left me with emulating the original multiple physical node setup. In theory, pretty easy -- spin up a bunch of DOS boxes, each using at most 1MB of emulated RAM, and go to town. But here came the challenge. + +In a multiple-physical-node setup, you need some sort of file sharing, because your nodes have to access the shared message and file store. There were a myriad of clunky ways to do this in the old DOS days - [Netware][6], [LAN manager][7], even some PC NFS clients. I didn't have access to Netware. I tried the Microsoft LM client in DOS, talking to a Samba server running inside the Docker container. This I got working, but the LM client used so much RAM that, even with various high memory tricks, BBS software wasn't going to run. I couldn't just mount an underlying filesystem in multiple dosbox instances either, because dosbox did caching that wasn't going to be compatible. + +This is why I wound up using dosemu. Besides being a more complete emulator than dosbox, it had a way of sharing the host's filesystems that was going to work. + +So, all of this wound up with this: [jgoerzen/docker-bbs-renegade][8]. + +I also prepared building blocks for others that want to do something similar: [docker-dos-bbs][9] and the lower-level [docker-dosemu][10]. + +As a side bonus, I also attempted running this under Joyent's Triton (SmartOS, Solaris-based). I was pleasantly impressed that I got it all almost working there. So yes, a Renegade DOS BBS running under a Linux-based DOS emulator in a container on a Solaris machine. + + + +-------------------------------------------------------------------------------- + +via: http://changelog.complete.org/archives/9836-an-old-dos-bbs-in-a-docker-container + +作者:[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://changelog.complete.org/archives/9794-fixing-the-problems-with-docker-images +[2]:https://raw.githubusercontent.com/jgoerzen/docker-bbs-renegade/master/renegade-login.png +[3]:https://en.wikipedia.org/wiki/DESQview +[4]:http://toastytech.com/guis/dvx.html +[5]:http://toastytech.com/guis/dvx3.html +[6]:https://en.wikipedia.org/wiki/NetWare +[7]:https://en.wikipedia.org/wiki/LAN_Manager +[8]:https://github.com/jgoerzen/docker-bbs-renegade +[9]:https://github.com/jgoerzen/docker-dos-bbs +[10]:https://github.com/jgoerzen/docker-dosemu From b1f76fc987d8bef51860925c8e13281ae1299394 Mon Sep 17 00:00:00 2001 From: darksun Date: Thu, 1 Feb 2018 09:41:52 +0800 Subject: [PATCH 102/272] =?UTF-8?q?=E9=80=89=E9=A2=98:=20How=20to=20access?= =?UTF-8?q?/view=20Python=20help=20when=20using=20vim?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ... access-view Python help when using vim.md | 86 +++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 sources/tech/20180131 How to access-view Python help when using vim.md 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 new file mode 100644 index 0000000000..c91e16d81d --- /dev/null +++ b/sources/tech/20180131 How to access-view Python help when using vim.md @@ -0,0 +1,86 @@ +How to access/view Python help when using vim +====== + +I am a new Vim text editor user. I am writing Python code. Is there is a way to see Python documentation within vim and without visiting the Internet? Say my cursor is under the print Python keyword, and I press F1. I want to look at the help for the print keyword. How do I show python help() inside vim? How do I call pydoc3/pydoc to seek help without leaving vim? + +The pydoc or pydoc3 command show text documentation on the name of a Python keyword, topic, function, module, or package, or a dotted reference to a class or function within a module or module in a package. You can call pydoc from vim itself. Let us see how to access Python documentation using pydoc within vim text editor. + +### Access python help using pydoc + +The syntax is: +``` +pydoc keyword +pydoc3 keyword +pydoc len +pydoc print +``` +Edit your ~/.vimrc: +`$ vim ~/.vimrc` +Append the following configuration for pydoc3 (python v3.x docs). Create a mapping for H key that works in normal mode: +``` +nnoremap H :execute "!pydoc3 " . expand("") +``` + + +Save and close the file. Open vim text editor: +`$ vim file.py` +Write some code: +``` +#!/usr/bin/python3 +x=5 +y=10 +z=x+y +print(z) +print("Hello world") +``` + +Position cursor under the print Python keyword and press Shift followed by H. You will see output as follows: + +[![Access Python Help Within Vim][1]][1] +Gif.01: Press H to view help for the print Python keyword + +### How to view python help when using vim + +[jedi-vim][2] is a VIM binding to the autocompletion library Jed. It can do many things including display help for keyword when you press Shift followed by K i.e. press capital K. + +#### How to install jedi-vim on Linux or Unix-like system + +Use [pathogen][3], [vim-plug][4] or [Vundle][5] to install jedi-vim. I am using Vim-Plug. Add the following line in ~/vimrc: +`Plug 'davidhalter/jedi-vim'` +Save and close the file. Start vim and type: +`PlugInstall` +On Arch Linux, you can also install jedi-vim from official repositories as vim-jedi using pacman command: +`$ sudo pacman -S vim-jedi` +It is also available on Debian (?8) and Ubuntu (?14.04) as vim-python-jedi using [apt command][6]/[apt-get command][7]: +`$ sudo apt install vim-python-jedi` +On Fedora Linux, it is available as vim-jedi using dnf command: +`$ sudo dnf install vim-jedi` +Jedi is by default automatically initialized. So no further configuration needed on your part. To see Documentation/Pydoc press K. It shows a popup with assignments: +[![How to view python help when using vim][8]][8] + +### 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][9], [Facebook][10], [Google+][11]. + +-------------------------------------------------------------------------------- + +via: https://www.cyberciti.biz/faq/how-to-access-view-python-help-when-using-vim/ + +作者:[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/media/new/faq/2018/01/Access-Python-Help-Within-Vim.gif +[2]:https://github.com/davidhalter/jedi-vim +[3]:https://github.com/tpope/vim-pathogen +[4]:https://www.cyberciti.biz/programming/vim-plug-a-beautiful-and-minimalist-vim-plugin-manager-for-unix-and-linux-users/ +[5]:https://github.com/gmarik/vundle +[6]:https://www.cyberciti.biz/faq/ubuntu-lts-debian-linux-apt-command-examples/ (See Linux/Unix apt command examples for more info) +[7]:https://www.cyberciti.biz/tips/linux-debian-package-management-cheat-sheet.html (See Linux/Unix apt-get command examples for more info) +[8]:https://www.cyberciti.biz/media/new/faq/2018/01/How-to-view-Python-Documentation-using-pydoc-within-vim-on-Linux-Unix.jpg +[9]:https://twitter.com/nixcraft +[10]:https://facebook.com/nixcraft +[11]:https://plus.google.com/+CybercitiBiz From 5fa421aed396493c0454be4ca95fb8b30750301a Mon Sep 17 00:00:00 2001 From: darksun Date: Thu, 1 Feb 2018 09:45:01 +0800 Subject: [PATCH 103/272] =?UTF-8?q?=E9=80=89=E9=A2=98:=20Linux=20ln=20Comm?= =?UTF-8?q?and=20Tutorial=20for=20Beginners=20(5=20Examples)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...and Tutorial for Beginners (5 Examples).md | 119 ++++++++++++++++++ 1 file changed, 119 insertions(+) create mode 100644 sources/tech/20180130 Linux ln Command Tutorial for Beginners (5 Examples).md diff --git a/sources/tech/20180130 Linux ln Command Tutorial for Beginners (5 Examples).md b/sources/tech/20180130 Linux ln Command Tutorial for Beginners (5 Examples).md new file mode 100644 index 0000000000..df0c4a0f46 --- /dev/null +++ b/sources/tech/20180130 Linux ln Command Tutorial for Beginners (5 Examples).md @@ -0,0 +1,119 @@ +Linux ln Command Tutorial for Beginners (5 Examples) +====== + +Sometimes, while working on the command line, you need to create links between files. This can be achieved using a dedicated command, dubbed **ln**. In this tutorial, we will discuss the basics of this tool using some easy to understand examples. But before we do that, it's worth mentioning that all examples here have been tested on an Ubuntu 16.04 machine. + +### Linux ln command + +As you'd have understood by now, the ln command lets you make links between files. Following is the syntax (or rather different syntax available) for this tool: + +``` +ln [OPTION]... [-T] TARGET LINK_NAME (1st form) +ln [OPTION]... TARGET (2nd form) +ln [OPTION]... TARGET... DIRECTORY (3rd form) +ln [OPTION]... -t DIRECTORY TARGET... (4th form) +``` + +And here's how the tool's man page explains it: +``` +In  the  1st form, create a link to TARGET with the name LINK_NAME. In the 2nd form, create a link +to TARGET in the current directory. In the 3rd and 4th forms, create links to each TARGET in +DIRECTORY. Create hard links by default, symbolic links with --symbolic. By default, each +destination (name of new link) should not already exist. When creating hard links, each TARGET +must exist. Symbolic links can hold arbitrary text; if later resolved, a relative link is +interpreted in relation to its parent directory. +``` + +The following Q&A-styled examples will give you a better idea on how the ln command works. But before that, it's good you get a understanding of what's the [difference between hard links and soft links][1]. + +### Q1. How to create a hard link using ln? + +That's pretty straightforward - all you have to do is to use the ln command in the following way: + +``` +ln [file] [hard-link-to-file] +``` + +For example: + +``` +ln test.txt test_hard_link.txt +``` + +[![How to create a hard link using ln][2]][3] + +So you can see a hard link was created with the name test_hard_link.txt. + +### Q2. How to create soft/symbolic link using ln? + +For this, use the -s command line option. + +``` +ln -s [file] [soft-link-to-file] +``` + +For example: + +``` +ln -s test.txt test_soft_link.txt +``` + +[![How to create soft/symbolic link using ln][4]][5] + +The test_soft_link.txt file is a soft/symbolic link, as [confirmed][6] by its sky blue text color. + +### Q3. How to make ln remove existing destination files of same name? + +By default, ln won't let you create a link if a file of the same name already exists in the destination directory. + +[![ln command example][7]][8] + +However, if you want, you can make ln override this behavior by using the **-f** command line option. + +[![How to make ln remove existing destination files of same name][9]][10] + +**Note** : You can use the **-i** command line option if you want to make all this deletion process interactive. + +### Q4. How to make ln create backup of existing files with same name? + +If you don't want ln to delete existing files of same name, you can make it create backup of these files. This can be achieved using the **-b** command line option. Backup files created this way will contain a tilde (~) towards the end of their name. + +[![How to make ln create backup of existing files with same name][11]][12] + +A particular destination directory (other than the current one) can be specified using the **-t** command line option. For example: + +``` +ls test* | xargs ln -s -t /home/himanshu/Desktop/ +``` + +The aforementioned command will create links to all test* files (present in the current directory) and put them in the Desktop directory. + +### Conclusion + +Agreed, **ln** isn't something that you'll require on daily basis, especially if you're a newbie. But it's a helpful command to know about, as you never know when it'd save your day. We've discussed some useful command line options the tool offers. Once you're done with these, you can learn more about ln by heading to its [man page][13]. + + +-------------------------------------------------------------------------------- + +via: https://www.howtoforge.com/linux-ln-command/ + +作者:[Himanshu Arora][a] +译者:[译者ID](https://github.com/译者ID) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://www.howtoforge.com +[1]:https://medium.com/meatandmachines/explaining-the-difference-between-hard-links-symbolic-links-using-bruce-lee-32828832e8d3 +[2]:https://www.howtoforge.com/images/command-tutorial/ln-hard-link.png +[3]:https://www.howtoforge.com/images/command-tutorial/big/ln-hard-link.png +[4]:https://www.howtoforge.com/images/command-tutorial/ln-soft-link.png +[5]:https://www.howtoforge.com/images/command-tutorial/big/ln-soft-link.png +[6]:https://askubuntu.com/questions/17299/what-do-the-different-colors-mean-in-ls +[7]:https://www.howtoforge.com/images/command-tutorial/ln-file-exists.png +[8]:https://www.howtoforge.com/images/command-tutorial/big/ln-file-exists.png +[9]:https://www.howtoforge.com/images/command-tutorial/ln-f-option.png +[10]:https://www.howtoforge.com/images/command-tutorial/big/ln-f-option.png +[11]:https://www.howtoforge.com/images/command-tutorial/ln-b-option.png +[12]:https://www.howtoforge.com/images/command-tutorial/big/ln-b-option.png +[13]:https://linux.die.net/man/1/ln From 63aae0656e28626c50140f99baea9f6a372136af Mon Sep 17 00:00:00 2001 From: darksun Date: Thu, 1 Feb 2018 10:00:25 +0800 Subject: [PATCH 104/272] =?UTF-8?q?=E9=80=89=E9=A2=98:=20[erfahrungen,=20m?= =?UTF-8?q?einungen,=20halluzinationen]:=20Migrating=20the=20debichem=20gr?= =?UTF-8?q?oup=20subversion=20repository=20to=20Git?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...chem group subversion repository to Git.md | 223 ++++++++++++++++++ 1 file changed, 223 insertions(+) create mode 100644 sources/tech/20180131 [erfahrungen, meinungen, halluzinationen]- Migrating the debichem group subversion repository to Git.md diff --git a/sources/tech/20180131 [erfahrungen, meinungen, halluzinationen]- Migrating the debichem group subversion repository to Git.md b/sources/tech/20180131 [erfahrungen, meinungen, halluzinationen]- Migrating the debichem group subversion repository to Git.md new file mode 100644 index 0000000000..435ac8d56a --- /dev/null +++ b/sources/tech/20180131 [erfahrungen, meinungen, halluzinationen]- Migrating the debichem group subversion repository to Git.md @@ -0,0 +1,223 @@ +Migrating the debichem group subversion repository to Git - Part 1: svn-all-fast-export basics +====== +With the [deprecation of alioth.debian.org][1] the subversion service hosted there will be shut down too. [According to lintian][2] the estimated date is May 1st 2018 and there are currently more then 1500 source packages affected. In the [debichem group][3] we've used the subversion service since 2006. Our repository contains around 7500 commits done by around 20 different alioth user accounts and the packaging history of around 70 to 80 packages, including packaging attempts. I've spent the last days to prepare the Git migration, comparing different tools, controlling the created repositories and testing possibilities to automate the process as much as possible. The resulting scripts can currently be found [here][4]. + +Of course I began as described at the [Debian Wiki][5]. But following this guide, using `git-svn` and converting the tags with the script supplied under rubric Convert remote tags and branches to local one gave me really weird results. The tags were pointing to the wrong commit-IDs. I thought, that `git-svn` was to blame and reported this as [bug #887881][6]. In the following mail exchange Andreas Kaesorg explained to me, that the issue is caused by so-called mixed-revision-tags in our repository as shown in the following example: +``` +$ svn log -v -r7405 +------------------------------------------------------------------------ +r7405 | dleidert | 2018-01-17 18:14:57 +0100 (Mi, 17. Jan 2018) | 1 Zeile +Geanderte Pfade: + A /tags/shelxle/1.0.888-1 (von /unstable/shelxle:7396) + R /tags/shelxle/1.0.888-1/debian/changelog (von /unstable/shelxle/debian/changelog:7404) + R /tags/shelxle/1.0.888-1/debian/control (von /unstable/shelxle/debian/control:7403) + D /tags/shelxle/1.0.888-1/debian/patches/qt5.patch + R /tags/shelxle/1.0.888-1/debian/patches/series (von /unstable/shelxle/debian/patches/series:7402) + R /tags/shelxle/1.0.888-1/debian/rules (von /unstable/shelxle/debian/rules:7403) + +[svn-buildpackage] Tagging shelxle 1.0.888-1 +------------------------------------------------------------------------ + +``` + +Looking into the git log, the tags deteremined by git-svn are really not in their right place in the history line, even before running the script to convert the branches into real Git tags. So IMHO git-svn is not able to cope with this kind of situation. Because it also cannot handle our branch model, where we use /branch/package/, I began to look for different tools and found [svn-all-fast-export][7], a tool created (by KDE?) to convert even large subversion repositories based on a ruleset. My attempt using this tool was so successful (not to speak of, how fast it is), that I want to describe it more. Maybe it will prove to be useful for others as well and it won't hurt to give some more information about this poorly documented tool :) + +### Step 1: Setting up a local subversion mirror + +First I suggest setting up a local copy of the subversion repository to migrate, that is kept in sync with the remote repository. This can be achieved using the svnsync command. There are several howtos for this, so I won't describe this step here. Please check out [this guide][8]. In my case I have such a copy in /srv/svn/debichem. + +### Step 2: Creating the identity map + +svn-all-fast-export needs at least two files to work. One is the so called identity map. This file contains the mapping between subversion user IDs (login names) and the (Git) committer info, like real name and mail address. The format is the same as used by git-svn: +``` +loginname = author name +``` + +e.g. +``` +dleidert = Daniel Leidert +``` + +The list of subversion user IDs can be obtained the same way as [described in the Wiki][9]: +``` +svn log SVN_URL | awk -F'|' '/^r[0-9]+/ { print $2 }' | sort -u +``` + +Just replace the placeholder SVN_URL with your subversion URL. [Here][10] is the complete file for the debichem group. + +### Step 3: Creating the rules + +The most important thing is the second file, which contains the processing rules. There is really not much documentation out there. So when in doubt, one has to read the source file [src/ruleparser.cpp][11]. I'll describe, what I already found out. If you are impatient, [here][12] is my result so far. + +The basic rules are: +``` +create repository REPOSITORY +... +end repository + +``` + +and +``` +match PATTERN +... +end match + +``` + +The first rule creates a bare git repository with the name you've chosen (above represented by REPOSITORY). It can have one child, that is the repository description to be put into the repositories description file. There are AFAIK no other elements allowed here. So in case of e.g. ShelXle the rule might look like this: +``` +create repository shelxle +description packaging of ShelXle, a graphical user interface for SHELXL +end repository + +``` + +You'll have to create every repository, before you can put something into it. Else svn-all-fast-export will exit with an error. JFTR: It won't complain, if you create a repository, but don't put anything into it. You will just end up with an empty Git repository. + +Now the second type of rule is the most important one. Based on regular expression match patterns (above represented by PATTERN), one can define actions, including the possibility to limit these actions to repositories, branches and revisions. **The patterns are applied in their order of appearance. Thus if a matching pattern is found, other patterns matching but appearing later in the rules file, won't apply!** So a special rule should always be put above a general rule. The patterns, that can be used, seem to be of type [QRegExp][13] and seem like basic Perl regular expressions including e.g. capturing, backreferences and lookahead capabilities. For a multi-package subversion repository with standard layout (that is /PACKAGE/{trunk,tags,branches}/), clean naming and subversion history, the rules could be: +``` +match /([^/]+)/trunk/ + repository \1 + branch master +end match + +match /([^/]+)/tags/([^/]+)/ + repository \1 + branch refs/tags/debian/\2 + annotated true +end match + +match /([^/]+)/branches/([^/]+)/ + repository \1 + branch \2 +end match + +``` + +The first rule captures the (source) package name from the path and puts it into the backreference `\1`. It applies to the trunk directory history and will put everything it finds there into the repository named after the directory - here we simply use the backreference `\1` to that name - and there into the master branch. Note, that svn-all-fast-export will error out, if it tries to access a repository, which has not been created. So make sure, all repositories are created as shown with the `create repository` rule. The second rule captures the (source) package name from the path too and puts it into the backreference `\1`. But in backreference `\2` it further captures (and applies to) all the tag directories under the /tags/ directory. Usually these have a Debian package version as name. With the branch statement as shown in this rule, the tags, which are really just branches in subversion, are automatically converted to [annotated][14] Git tags (another advantage of svn-all-fast-export over git-svn). Without enabling the `annotated` statement, the tags created will be [lightweight tags][15]. So the tag name (here: debian/VERSION) is determined via backreference `\2`. The third rule is almost the same, except that everything found in the matching path will be pushed into a Git branch named after the top-level directory captured from the subversion path. + +Now in an ideal world, this might be enough and the actual conversion can be done. The command should only be executed in an empty directory. I'll assume, that the identity map is called authors and the rules file is called rules and that both are in the parent directory. I'll also assume, that the local subversion mirror of the packaging repository is at /srv/svn/mymirror. So ... +``` +svn-all-fast-export --stats --identity-map=../authors.txt --rules=../debichem.rules --stats /srv/svn/mymirror +``` + +... will create one or more **bare** Git repositories (depending on your rules file) in the current directory. After the command succeeded, you can test the results ... +``` +git -C REPOSITORY/ --bare show-ref +git -C REPOSITORY/ --bare log --all --graph + +``` + +... and you will find your repositories description (if you added one to the rules file) in REPOSITORY/description: +``` +cat REPOSITORY/description +``` + +**Please note, that not all the debian version strings are[well formed Git reference names][16] and therefor need fixing. There might also be gaps shown in the Git history log. Or maybe the command didn't even suceed or complained (without you noticing it) or you ended up with an empty repository, although the matching rules applied. I encountered all of these issues and I'll describe the cause and fixes in the next blog article.** + +But if everything went well (you have no history gaps, the tags are in their right place within the linearized history and the repository looks fine) and you can and want to proceed, you might want to skip to the next step. + +In the debichem group we used a different layout. The packaging directories were under /{unstable,experimental,wheezy,lenny,non-free}/PACKAGE/. This translates to [/unstable/][17]PACKAGE/ and [/non-free/][18]PACKAGE/ being the trunk directories and the [others][19] being the branches. The tags are in [/tags/][20]PACKAGE/. And packages, that are yet to upload are located in [/wnpp/][21]PACKAGE/. With this layout, the basic rules are: +``` +# trunk handling +# e.g. /unstable/espresso/ +# e.g. /non-free/molden/ +match /(?:unstable|non-free)/([^/]+)/ + repository \1 + branch master +end match + +# handling wnpp +# e.g. /wnpp/osra/ +match /(wnpp)/([^/]+)/ + repository \2 + branch \1 +end match + +# branch handling +# e.g. /wheezy/espresso/ +match /(lenny|wheezy|experimental)/([^/]+)/ + repository \2 + branch \1 +end match + +# tags handling +# e.g. /tags/espresso/VERSION/ +match /tags/([^/]+)/([^/]+)/ + repository \1 + annotated true + branch refs/tags/debian/\2 + substitute branch s/~/_/ + substitute branch s/:/_/ +end match + +``` + +In the first rule, there is a non-capturing expression (?: ... ), which simply means, that the rule applies to /unstable/ and /non-free/. Thus the backreference `\1` refers to second part of the path, the package directory name. The contents found are pushed to the master branch. In the second rule, the contents from the wnpp directory are not pushed to master, but instead to a branch called wnpp. This was necessary because of overlaps between /unstable/ and /wnpp/ history and already shows, that the repositories history makes things complicated. In the third rule, the first backreference `\1` determines the branch (note the capturing expression in contrast to the first rule) and the second backreference `\2` the package repository to act on. The last rule is similar, but now `\1` determines the package repository and `\2` the tag name (debian package version) based on the matching path. The example also shows another issue, which I'd like to explain more in the next article: some characters we use in debian package versions, e.g. the tilde sign and the colon, are not allowed within Git tag names and must therefor be substituted, which is done by the `substitute branch EXPRESSION` instructions. + +### Step 4: Cleaning the bare repository + +The [tool documentation][27] suggests to run ... +``` +git -C REPOSITORY/ repack -a -d -f +``` + +... before you upload this bare repository to another location. But [Stuart Prescott told me on the debichem list][28], that this might not be enough and still leave some garbage behind. I'm not experienved enough to judge here, but his suggestion is, to clone the repository, either a bare clone or clone and init a new bare. I used the first approach: +``` +git -C REPOSITORY/ --bare clone --bare REPOSITORY.git +git -C REPOSITORY.git/ repack -a -d -f + +``` + +**Please note, that this won't copy the repositories description file. You'll have to copy it manually, if you wanna keep it.** The resulting bare repository can be uploaded (e.g. to [git.debian.org as personal repository][29]: +``` +cp REPOSITORY/description REPOSITORY.git/description +touch REPOSITORY.git/git-daemon-export-ok +rsync -avz REPOSITORY.git git.debian.org:~/public_git/ + +``` + +Or you clone the repository, add a remote origin and push everything there. It is even possible to use the gitlab API at salsa.debian.org to create a project and push there. I'll save the latter for another post. If you are hasty, you'll find a script [here][30]. + +-------------------------------------------------------------------------------- + +via: http://www.wgdd.de/2018/01/migrating-debichem-group-subversion.html + +作者:[Daniel Leidert][a] +译者:[译者ID](https://github.com/译者ID) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://www.blogger.com/profile/17052464961644858181 +[1]:https://wiki.debian.org/Alioth#Deprecation_of_Alioth +[2]:https://lintian.debian.org/tags/vcs-deprecated-in-debian-infrastructure.html +[3]:https://debichem.alioth.debian.org/ +[4]:https://anonscm.debian.org/viewvc/debichem/tools/svn2git/ +[5]:https://wiki.debian.org/de/Alioth/Git#Convert_a_SVN_Alioth_repository_to_Git +[6]:https://bugs.debian.org/887881 +[7]:https://github.com/svn-all-fast-export/svn2git +[8]:http://www.microhowto.info/howto/mirror_a_subversion_repository.html +[9]:https://wiki.debian.org/de/Alioth/Git#Create_the_author_file +[10]:https://anonscm.debian.org/viewvc/debichem/tools/svn2git/authors.txt?view=co&content-type=text%2Fplain +[11]:https://raw.githubusercontent.com/svn-all-fast-export/svn2git/master/src/ruleparser.cpp +[12]:https://anonscm.debian.org/viewvc/debichem/tools/svn2git/debichem.rules?view=co&content-type=text%2Fplain +[13]:http://doc.qt.io/qt-5/qregexp.html#introduction +[14]:https://git-scm.com/book/en/v2/Git-Basics-Tagging#_annotated_tags +[15]:https://git-scm.com/book/en/v2/Git-Basics-Tagging#_lightweight_tags +[16]:https://git-scm.com/docs/git-check-ref-format +[17]:https://anonscm.debian.org/viewvc/debichem/unstable/ +[18]:https://anonscm.debian.org/viewvc/debichem/non-free/ +[19]:https://anonscm.debian.org/viewvc/debichem/experimental/ +[20]:https://anonscm.debian.org/viewvc/debichem/tags/ +[21]:https://anonscm.debian.org/viewvc/debichem/wnpp/ +[22]:https://anonscm.debian.org/viewvc/debichem/unstable/espresso/ +[23]:https://anonscm.debian.org/viewvc/debichem/non-free/molden/ +[24]:https://anonscm.debian.org/viewvc/debichem/wnpp/osra/ +[25]:https://anonscm.debian.org/viewvc/debichem/wheezy/espresso/ +[26]:https://anonscm.debian.org/viewvc/debichem/tags/espresso/ +[27]:https://techbase.kde.org/Projects/MoveToGit/UsingSvn2Git#Checking_for_proper_history_in_the_new_git_repository +[28]:http://lists.alioth.debian.org/pipermail/debichem-devel/2018-January/008816.html +[29]:https://wiki.debian.org/de/Alioth/Git#Using_personal_Git_repositories +[30]:https://anonscm.debian.org/viewvc/debichem/tools/svn2git/gitimport.sh?view=co&content-type=text%2Fplain From 71ae9c998fa979e73d5cf70c7824336820c3dfe3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E6=9D=BE=E5=B3=B0?= Date: Thu, 1 Feb 2018 10:14:23 +0800 Subject: [PATCH 105/272] Update 20180119 Linux mv Command Explained for Beginners (8 Examples).md --- ...119 Linux mv Command Explained for Beginners (8 Examples).md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sources/tech/20180119 Linux mv Command Explained for Beginners (8 Examples).md b/sources/tech/20180119 Linux mv Command Explained for Beginners (8 Examples).md index 786528137f..78cf02f4a9 100644 --- a/sources/tech/20180119 Linux mv Command Explained for Beginners (8 Examples).md +++ b/sources/tech/20180119 Linux mv Command Explained for Beginners (8 Examples).md @@ -1,3 +1,5 @@ +translating by cncuckoo + Linux mv Command Explained for Beginners (8 Examples) ====== From 526c3514a1f2e21ca2822ab686791d20d92887dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E6=9D=BE=E5=B3=B0?= Date: Thu, 1 Feb 2018 10:21:12 +0800 Subject: [PATCH 106/272] translating claim translating for "Rediscovering make: the power behind rules" --- .../tech/20180118 Rediscovering make- the power behind rules.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sources/tech/20180118 Rediscovering make- the power behind rules.md b/sources/tech/20180118 Rediscovering make- the power behind rules.md index 2dbddb8949..ea500a2689 100644 --- a/sources/tech/20180118 Rediscovering make- the power behind rules.md +++ b/sources/tech/20180118 Rediscovering make- the power behind rules.md @@ -1,3 +1,5 @@ +Translating by cncuckoo + Rediscovering make: the power behind rules ====== From 75c05c0f42f08f1dd8e2b32ec5f28aa2fe9531ba Mon Sep 17 00:00:00 2001 From: darksun Date: Thu, 1 Feb 2018 10:33:56 +0800 Subject: [PATCH 107/272] =?UTF-8?q?=E9=80=89=E9=A2=98:=20An=20introduction?= =?UTF-8?q?=20to=20the=20DomTerm=20terminal=20emulator=20for=20Linux?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...the DomTerm terminal emulator for Linux.md | 126 ++++++++++++++++++ 1 file changed, 126 insertions(+) create mode 100644 sources/talk/20180130 An introduction to the DomTerm terminal emulator for Linux.md diff --git a/sources/talk/20180130 An introduction to the DomTerm terminal emulator for Linux.md b/sources/talk/20180130 An introduction to the DomTerm terminal emulator for Linux.md new file mode 100644 index 0000000000..4553570166 --- /dev/null +++ b/sources/talk/20180130 An introduction to the DomTerm terminal emulator for Linux.md @@ -0,0 +1,126 @@ +An introduction to the DomTerm terminal emulator for Linux +====== +![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/osdc_terminals.png?itok=CfBqYBah) + +[DomTerm][1] is a modern terminal emulator that uses a browser engine as a "GUI toolkit." This enables some neat features, such as embeddable graphics and links, HTML rich text, and foldable (show/hide) commands. Otherwise it looks and feels like a feature-full, standalone terminal emulator, with excellent xterm compatibility (including mouse handling and 24-bit color), and appropriate "chrome" (menus). In addition, there is built-in support for session management and sub-windows (as in `tmux` and `GNU screen`), basic input editing (as in `readline`), and paging (as in `less`). + +![](https://opensource.com/sites/default/files/u128651/domterm1.png) +Image 1: The DomTerminal terminal emulator. View larger image. + +Below we'll look more at these features. We'll assume you have `domterm` installed (skip to the end of this article if you need to get and build DomTerm). First, though, here's a quick overview of the technology. + +### Frontend vs. backend + +Most of DomTerm is written in JavaScript and runs in a browser engine. This can be a desktop web browser, such as Chrome or Firefox (see image 3), or it can be an embedded browser. Using a general web browser works fine, but the user experience isn't as nice (as the menus are designed for general browsing, not for a terminal emulator), and the security model gets in the way, so using an embedded browser is nicer. + +The following are currently supported: + + * `qtdomterm`, which uses the Qt toolkit and `QtWebEngine` + * An `[Electron][2]` embedding (see image 1) + * `atom-domterm` runs DomTerm as a package in the [Atom text editor][3] (which is also based on Electron) and integrates with the Atom pane system (see image 2) + * A wrapper for JavaFX's `WebEngine`, which is useful for code written in Java (see image 4) + * Previously, the preferred frontend used [Firefox-XUL][4], but Mozilla has since dropped XUL + + + +![DomTerm terminal panes in Atom editor][6] + +Image 2: DomTerm terminal panes in Atom editor. [View larger image.][7] + +Currently, the Electron frontend is probably the nicest option, closely followed by the Qt frontend. If you use Atom, `atom-domterm` works pretty well. + +The backend server is written in C. It manages pseudo terminals (PTYs) and sessions. It is also an HTTP server that provides the JavaScript and other files to the frontend. The `domterm` command starts terminal jobs and performs other requests. If there is no server running, `domterm` daemonizes itself. Communication between the backend and the server is normally done using WebSockets (with [libwebsockets][8] on the server). However, the JavaFX embedding uses neither WebSockets nor the DomTerm server; instead Java applications communicate directly using the Java-JavaScript bridge. + +### A solid xterm-compatible terminal emulator + +DomTerm looks and feels like a modern terminal emulator. It handles mouse events, 24-bit color, Unicode, double-width (CJK) characters, and input methods. DomTerm does a very good job on the [vttest testsuite][9]. + +Unusual features include: + +**Show/hide buttons ("folding"):** The little triangles (seen in image 2 above) are buttons that hide/show the corresponding output. To create the buttons, just add certain [escape sequences][10] in the [prompt text][11]. + +**Mouse-click support for`readline` and similar input editors:** If you click in the (yellow) input area, DomTerm will send the right sequence of arrow-key keystrokes to the application. (This is enabled by escape sequences in the prompt; you can also force it using Alt+Click.) + +**Style the terminal using CSS:** This is usually done in `~/.domterm/settings.ini`, which is automatically reloaded when saved. For example, in image 2, terminal-specific background colors were set. + +### A better REPL console + +A classic terminal emulator works on rectangular grids of character cells. This works for a REPL (command shell), but it is not ideal. Here are some DomTerm features useful for REPLs that are not typically found in terminal emulators: + +**A command can "print" an image, a graph, a mathematical formula, or a set of clickable links:** An application can send an escape sequence containing almost any HTML. (The HTML is scrubbed to remove JavaScript and other dangerous features.) + +The image 3 shows a fragment from a [`gnuplot`][12] session. Gnuplot (2.1 or later) supports `domterm` as a terminal type. Graphical output is converted to an [SVG image][13], which is then printed to the terminal. My blog post [Gnuplot display on DomTerm][14] provides more information on this. + +![](https://opensource.com/sites/default/files/dt-gnuplot.png) +Image 3: Gnuplot screenshot. View larger image. + +The [Kawa][15] language has a library for creating and transforming [geometric picture values][16]. If you print such a picture value to a DomTerm terminal, the picture is converted to SVG and embedded in the output. + +![](https://opensource.com/sites/default/files/dt-kawa1.png) +Image 4: Computable geometry in Kawa. View larger image. + +**Rich text in output:** Help messages are more readable and look nicer with HTML styling. The lower pane of image 1 shows the ouput from `domterm help`. (The output is plaintext if not running under DomTerm.) Note the `PAUSED` message from the built-in pager. + +**Error messages can include clickable links:** DomTerm recognizes the syntax `filename:line:column:` and turns it into a link that opens the file and line in a configurable text editor. (This works for relative filenames if you use `PROMPT_COMMAND` or similar to track directories.) + +A compiler can detect that it is running under DomTerm and directly emit file links in an escape sequence. This is more robust than depending on DomTerm's pattern matching, as it handles spaces and other special characters, and it does not depend on directory tracking. In image 4, you can see error messages from the [Kawa compiler][15]. Hovering over the file position causes it to be underlined, and the `file:` URL shows in the `atom-domterm` message area (bottom of the window). (When not using `atom-domterm`, such messages are shown in an overlay box, as seen for the `PAUSED` message in image 1.) + +The action when clicking on a link is configurable. The default action for a `file:` link with a `#position` suffix is to open the file in a text editor. + +**Structured internal representation:** The following are all represented in the internal node structure: Commands, prompts, input lines, normal and error output, tabs, and preserving the structure if you "Save as HTML." The HTML file is compatible with XML, so you can use XML tools to search or transform the output. The command `domterm view-saved` opens a saved HTML file in a way that enables command folding (show/hide buttons are active) and reflow on window resize. + +**Built-in Lisp-style pretty-printing:** You can include pretty-printing directives (e.g., grouping) in the output such that line breaks are recalculated on window resize. See my article [Dynamic pretty-printing in DomTerm][17] for a deeper discussion. + +**Basic built-in line editing** with history (like `GNU readline`): This uses the browser's built-in editor, so it has great mouse and selection handling. You can switch between normal character-mode (most characters typed are sent directly to the process); or line-mode (regular characters are inserted while control characters cause editing actions, with Enter sending the edited line to the process). The default is automatic mode, where DomTerm switches between character-mode and line-mode depending on whether the PTY is in raw or canonical mode. + +**A built-in pager** (like a simplified `less`): Keyboard shortcuts will control scrolling. In "paging mode," the output pauses after each new screen (or single line, if you move forward line-by-line). The paging mode is unobtrusive and smart about user input, so you can (if you wish) run it without it interfering with interactive programs. + +### Multiplexing and sessions + +**Tabs and tiling:** Not only can you create multiple terminal tabs, you can also tile them. You can use either the mouse or a keyboard shortcut to move between panes and tabs as well as create new ones. They can be rearranged and resized with the mouse. This is implemented using the [GoldenLayout][18] JavaScript library. [Image 1][19] shows a window with two panes. The top one has two tabs, with one running [Midnight Commander][20]; the bottom pane shows `domterm help` output as HTML. However, on Atom we instead use its built-in draggable tiles and tabs; you can see this in image 2. + +**Detaching and reattaching to sessions:** DomTerm supports sessions arrangement, similar to `tmux` and GNU `screen`. You can even attach multiple windows or panes to the same session. This supports multi-user session sharing and remote connections. (For security, all sessions of the same server need to be able to read a Unix domain socket and a local file containing a random key. This restriction will be lifted when we have a good, safe remote-access story.) + +**The** **`domterm`** **command** is also like `tmux` or GNU `screen` in that has multiple options for controlling or starting a server that manages one or more sessions. The major difference is that, if it's not already running under DomTerm, the `domterm` command creates a new top-level window, rather than running in the existing terminal. + +The `domterm` command has a number of sub-commands, similar to `tmux` or `git`. Some sub-commands create windows or sessions. Others (such as "printing" an image) only work within an existing DomTerm session. + +The command `domterm browse` opens a window or pane for browsing a specified URL, such as when browsing documentation. + +### Getting and installing DomTerm + +DomTerm is available from its [GitHub repository][21]. Currently, there are no prebuilt packages, but there are [detailed instructions][22]. All prerequisites are available on Fedora 27, which makes it especially easy to build. + +-------------------------------------------------------------------------------- + +via: https://opensource.com/article/18/1/introduction-domterm-terminal-emulator + +作者:[Per Bothner][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/perbothner +[1]:http://domterm.org/ +[2]:https://electronjs.org/ +[3]:https://atom.io/ +[4]:https://en.wikipedia.org/wiki/XUL +[5]:/file/385346 +[6]:https://opensource.com/sites/default/files/images/dt-atom1.png (DomTerm terminal panes in Atom editor) +[7]:https://opensource.com/sites/default/files/images/dt-atom1.png +[8]:https://libwebsockets.org/ +[9]:http://invisible-island.net/vttest/ +[10]:http://domterm.org/Wire-byte-protocol.html +[11]:http://domterm.org/Shell-prompts.html +[12]:http://www.gnuplot.info/ +[13]:https://developer.mozilla.org/en-US/docs/Web/SVG +[14]:http://per.bothner.com/blog/2016/gnuplot-in-domterm/ +[15]:https://www.gnu.org/software/kawa/ +[16]:https://www.gnu.org/software/kawa/Composable-pictures.html +[17]:http://per.bothner.com/blog/2017/dynamic-prettyprinting/ +[18]:https://golden-layout.com/ +[19]:https://opensource.com/sites/default/files/u128651/domterm1.png +[20]:https://midnight-commander.org/ +[21]:https://github.com/PerBothner/DomTerm +[22]:http://domterm.org/Downloading-and-building.html From 9dc855615fb24f0a6809ce139dba2586d20f13f1 Mon Sep 17 00:00:00 2001 From: darksun Date: Thu, 1 Feb 2018 10:39:17 +0800 Subject: [PATCH 108/272] =?UTF-8?q?=E9=80=89=E9=A2=98:=20Introduction=20to?= =?UTF-8?q?=20AWS=20for=20Data=20Scientists?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...Introduction to AWS for Data Scientists.md | 212 ++++++++++++++++++ 1 file changed, 212 insertions(+) create mode 100644 sources/talk/20180130 Introduction to AWS for Data Scientists.md diff --git a/sources/talk/20180130 Introduction to AWS for Data Scientists.md b/sources/talk/20180130 Introduction to AWS for Data Scientists.md new file mode 100644 index 0000000000..ada3585745 --- /dev/null +++ b/sources/talk/20180130 Introduction to AWS for Data Scientists.md @@ -0,0 +1,212 @@ +Introduction to AWS for Data Scientists +====== +![sky-690293_1920][1] + +These days, many businesses use cloud based services; as a result various companies have started building and providing such services. Amazon [began the trend][2], with Amazon Web Services (AWS). While AWS began in 2006 as a side business, it now makes [$14.5 billion in revenue each year][3]. + +Other leaders in this area include: + + * Google--Google Cloud Platform (GCP) + * Microsoft--Azure Cloud Services + * IBM--IBM Cloud + + + +Cloud services are useful to businesses of all sizes--small companies benefit from the low cost, as compared to buying servers. Larger companies gain reliability and productivity, with less cost, since the services run on optimum energy and maintenance. + +These services are also powerful tools that you can use to ease your work. Setting up a Hadoop cluster to work with Spark manually could take days if it's your first time, but AWS sets that up for you in minutes. + +We are going to focus on AWS here because it comes with more products relevant to data scientists. In general, we can say familiarity with AWS helps data scientists to: + + 1. Prepare the infrastructure they need for their work (e.g. Hadoop clusters) with ease + 2. Easily set up necessary tools (e.g. Spark) + 3. Decrease expenses significantly--such as by paying for huge Hadoop clusters only when needed + 4. Spend less time on maintenance, as there's no need for tasks like manually backing up data + 5. Develop products and features that are ready to launch without needing help from engineers (or, at least, needing very little help) + + + +In this post, I'll give an overview of useful AWS services for data scientists -- what they are, why they're useful, and how much they cost. + +### Elastic Compute Cloud (EC2) + +Many other AWS services are built around EC2, making it a core piece of AWS. EC2s are in fact (virtual) servers that you can rent from Amazon and set up or run any program/application on it. These servers come in different operating systems and Amazon charges you based on the computing power and capacity of the server (i.e. Hard Drive capacity, CPU, Memory, etc.) and the duration the server been up. + +#### EC2 benefits + +For example, you can rent a Linux or Windows server with computation power and storage capacity that fits your specific needs and Amazon charges you based on these specifications and the duration you use the server. Note that previously AWS charged at least for one hour for each instance you run, but they recently changed their policy to [per-second billing][4]. + +One of the good things about EC2 is its scalability--by changing memory, number of vCPUs, bandwidth, and so on, you can easily scale your system up or down. Therefore, if you think a system doesn't have enough power for running a specific task or a calculation in your project is taking too long, you can scale up to finish your work and later scale down again to reduce the cost. EC2 is also very reliable, since Amazon takes care of the maintenance. + +#### EC2 cost + +EC2 instances are relatively low-cost, and there are different types of instances for different use cases. For example, there are instances that are optimized for computation and those have relatively lower cost on CPU usage. Or those optimized for memory have lower cost on memory usage. + +To give you an idea on EC2 cost, a general purpose medium instance with 2 vCPUs and 4 GIG of memory (at the time of writing this article) costs $0.0464 per hour for a linux server, see [Amazon EC2 Pricing][5] for prices and more information. AWS also now has [spot instance pricing][6], which calculates the price based on supply/demand at the time and provides up to a 90% discount for short term usages depending on the time you want to use the instance. For example, the same instance above costs $0.0173 per hour on spot pricing plan. + +Note that you have to add storage costs to the above as well. Most EC2 instances use Elastic Block Store (EBS) systems, which cost around $0.1/GIG/month; see the prices [here][7]. [Storage optimized instances][8] use Solid State Drive (SSD) systems, which are more expensive. + +![Ec2cost][9] + +EBS acts like an external hard drive. You can attach it to an instance, de-attach it, and re-attach it to another instance. You can also stop or terminate an instance after your work is done and not pay for the instance when it is idle. + +If you stop an instance, AWS will still keep the EBS live and as a result the data you have on the hard drive will remain intact (it's like powering off your computer). Later you can restart stopped instances and get access to the data you generated, or even tools you installed there in the previous sessions. However, when you stop an instance instead of terminating it, Amazon will still charge you for the attached EBS (~$0.1/GIG/month). If you terminate the instance, the EBS will get cleaned so you will lose all the data on that instance, but you no longer need to pay for the EBS. + +If you need to keep the data on EBS for your future use (let's say you have custom tools installed on that instance and you don't want to redo your work again later) you can make a snapshot of the EBS and can later restore it in a new EBS and attach it to a new instance. + +Snapshots get stored on S3 (Amazon's cheap storage system; we will get to it later) so it will cost you less ($0.05 per GB-month) to keep the data in EBS like that. However, it takes time (depending on the size of the EBS) to get snapshot and restoring it. Besides, reattaching a restored EBS to EC2 instance is not that straight forward, so it only make sense to use a snapshot like that if you know you are not going to use that EBS for a while. + +Note that to scale an instance up or down, you have to first stop the instance and then change the instance specifications. You can't decrease the EBS size, only increase it, and it's more difficult. You have to: + + 1. Stop the instance + 2. Make a snapshot out of the EBS + 3. Restore the snapshot in an EBS with the new size + 4. De-attach previous EBS + 5. Attach the new one. + + + +### Simple Storage Service (S3) + +S3 is AWS object (file) storage service. S3 is like Dropbox or Google drive, but way more scalable and is made particularly to work with codes and applications. + +S3 doesn't provide a user friendly interface since it is designed to work with online applications, not the end user. Therefore, working with S3 through APIs is easier than through its web console and there are many libraries and APIs developed (in various languages) to work with this service. For example, [Boto3][10] is a S3 library written in Python (in fact Boto3 is suitable for working with many other AWS services as well) . + +S3 stores files based on `bucket`s and `key`s. Buckets are similar to root folders, and keys are similar to subfolders and files. So if you store a file named `my_file.txt` on s3 like `myproject/mytextfiles/my_file.txt`, then "myproject" is the bucket you are using and then `mytextfiles/my_file.txt` is the key to that file. This is important to know since APIs will ask for the bucket and key separately when you want to retrieve your file from s3. + +#### S3 benefits + +There is no limit on the size of data you can store on S3--you just have to pay for the storage based on the size you need per month. + +S3 is also very reliable and "[it is designed to deliver 99.999999999% durability][11]". However, the service may not be always up. On February 28th, 2017 some of s3 servers went down for couple of hours and that disrupted many applications such as Slack, Trello, etc. see [these][12] [articles][13] for more information on this incident. + +#### S3 cost + +The cost is low, starting at $0.023 per GB per month for standard access, if you want to get access to these files regularly. It could go down even lower if you don't need to load data too frequently. See [Amazon S3 Pricing][14] for more information. + +AWS may charge you for other S3 related actions such as requests through APIs, but the cost for those are insignificant (less than $0.05 per 1,000 requests in most cases). + +### Relational Database Service (RDS) + +AWS RDS is a relational database service in the cloud. RDS currently supports SQL Server, MySQL, PostgreSQL, ORACLE, and a couple of other SQL-based frameworks. AWS sets up the system you need and configures the parameters so you can have a relational database up and running in minutes. RDS also handles backup, recovery, software patching, failure detection, and repairs by itself so you don't need to maintain the system. + +#### RDS benefits + +RDS is scalable, both computing power and the storage capacity can be scaled up or down easily. RDS system runs on EC2 servers (as I mentioned EC2 servers are the core of most of AWS services, including RDS service) so by computing power here we mean the computing power of the EC2 server our RDS service is running on, and you can scale up the computing power of this system up to 32 vCPUs and 244 GiB of RAM and changing the scale would not take more than few minutes. + +Scaling the storage requirements up or down is also possible. [Amazon Aurora][15] is a version of MySQL and PostgreSQL with some additional features, and can automatically scale up when more storage space is needed (you can define the maximum). The MySQL, MariaDB, Oracle, and PostgreSQL engines allow you to scale up on the fly without downtime. + +#### RDS cost + +The [cost of RDS servers][16] is based on three factors: computational power, storage, and data transfer. + +![RDSpricing][17] + +For example, a PostgreSQL system with medium computational power (2 vCPUs and 8 gig of memory) costs $0.182 per hour; you can pay less if you go under a one- or three-year contract. + +For storage, there are a [variety of options and prices][18]. If you choose single availability zone General Purpose SSD Storage (gp2), a good option for data scientists, the cost for a server in north Virginia at the time of writing this article is $0.115 per GB-month, and you can select from 5 GB to 16 TB of SSD. + +For data transfer, the cost varies a little based on the source and destination of data (one of which is RDS). For example, all data transferred from the internet into RDS is free. The first gig of data transferred from RDS to the internet is free as well, and for the next 10 terabytes of data in a month it costs $0.09 per GB; the cost decreases for transfering more data than that. + +### Redshift + +Redshift is Amazon's data warehouse service; it is a distributed system (something like the Hadoop framework) which lets you store huge amounts of data and get queries. The difference between this service and RDS is its high capacity and ability to work with big data (terabytes and petabytes). You can use simple SQL queries on Redshift as well. + +Redshift works on a distributed framework--data is distributed on different nodes (servers) connected on a cluster. Simply put, queries on a distributed system run in parallel on all the nodes and then the results get collected from each node and get summarized. + +#### Redshift benefits + +Redshift is highly scalable, meaning in theory (depending on the query, network structure and design, service specification, etc.) the speed of getting query out of 1 terabyte of data and 1 petabyte of data can match by scaling up (adding more cluster to) the system. + +When you create a table on Redshift, you can choose one of three distribution styles: EVEN, KEY, or ALL. + + * EVEN means the table rows will get distributed over all the nodes evenly. Then queries involving that table get distributed over the cluster and run in parallel, summarized at the end. Per Amazon's documentation, "[EVEN distribution is appropriate when a table does not participate in joins][19]". + + * ALL means that on each node there will be a copy of this table, so if you query for a join on that table, the table is already there on all the nodes and there is no need for copying the required data across the network from node to node. The problem is "[ALL distribution multiplies the storage required by the number of nodes in the cluster, and so it takes much longer to load, update, or insert data into multiple tables][19]". + + * In the KEY style, distribution rows of the table are distributed based on the values in one column, in an attempt to keep the rows with the same value of that column in the same node. Physically storing matching values on the same nodes make joining on that specific column faster in parallel systems, see more information [here][19]. + + + + +#### Redshift cost + +Redshift has two types of instances: Dense Compute or Dense Storage. Dense Compute is optimized for fast querying and it is cost effective for less than 500GB of data in size (~$5,500/TB/Year for a three-year contract with partial upfront). + +Dense Storage is optimized for high size storage (~$1,000/TB/Year for a three-year contract with partial upfront) and is cost effective for +500GB, but it is slower. You can find more general pricing [here][20]. + +You can also save a large amount of data on S3 and use [Amazon Redshift Spectrum][21] to run SQL query on that data. For Redshift Spectrum, AWS charges you by the number of bytes scanned by Redshift Spectrum per query; and $5 per terabyte of data scanned (10 megabyte minimum per query). + +### Elastic MapReduce (EMR) + +EMR is suitable for setting up Hadoop clusters with Spark and other distributed type applications. A Hadoop cluster can be used as a compute engine or a (distributed) storage system. However, if the data is so big that you need a distributed system to handle it, Redshift is more suitable and way cheaper than storing in EMR. + +There are three types of [nodes][22] on a cluster: + + * The master node (you only have one) is responsible for managing the cluster. It distributes the workloads to the core and task nodes, tracks the status of tasks, and monitors the health of the cluster. + * Core nodes run tasks and store the data. + * Task nodes can only run tasks. + + + +#### EMR benefits + +Since you can set EMR to install Apache Spark, this service is good for for cleaning, reformatting, and analyzing big data. You can use EMR on-demand, meaning you can set it to grab the code and data from a source (e.g. S3 for the code, and S3 or RDS for the data), run the task on the cluster, and store the results somewhere (again s3, RDS, or Redshift) and terminate the cluster. + +By using the service in such a way, you can reduce the cost of your cluster significantly. In my opinion, EMR is one of the most useful AWS services for data scientists. + +To setup an EMR cluster, you need to first configure applications you want to have on the cluster. Note that different versions of EMR come with different versions of the applications. For example, if you configure EMR version 5.10.0 to install Spark, the default version of the Spark for this version is 2.2.0. So if your code works only on Spark 1.6, you need to run EMR on the 4.x version. EMR will set up the network and configures all the nodes on the cluster along with needed tools. + +An EMR cluster comes with one master instance and a number of core nodes (slave instances). You can choose the number of core nodes, and can even select to have no core node and only use the master server for your work. Like other services, you can choose the computational power of the servers and the storage size available on each node. You can use autoscale option for your core nodes, meaning you can add rules to the system to add/remove core node (up to a maximum number you choose) if needed while running your code. See [Using Automatic Scaling in Amazon EMR][23] for more information on auto scaling. + +#### EMR pricing + +EMR pricing is based on the computational power you choose for different instances (master, core and task nodes). Basically, it is the cost of the EC2 servers plus the cost of EMR. You can find detailed pricing [here][24]. + +![EMRpricing][25] + +### Conclusion + +I have developed many end-to-end data-driven products (including reporting, machine learning models, and product health checking systems) for our company using Python and Spark on AWS, which later became good sources of income for the company. + +Experience working with cloud services, especially a well-known one like AWS, is a huge plus in your data scientist career. Many companies depend on these services now and use them constantly, so you being familiar with these services will give them the confidence that you need less training to get on board. With more and more people moving into data science, you want your resume to stand out as much as possible. + +Do you have cloud tips to add? [Let us know][26]. + +-------------------------------------------------------------------------------- + +via: https://www.dataquest.io/blog/introduction-to-aws-for-data-scientists/ + +作者:[Read More][a] +译者:[译者ID](https://github.com/译者ID) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://www.dataquest.io/blog/author/armin/ +[1]:/blog/content/images/2018/01/sky-690293_1920.jpg +[2]:http://www.computerweekly.com/feature/A-history-of-cloud-computing +[3]:https://www.forbes.com/sites/bobevans1/2017/07/28/ibm-beats-amazon-in-12-month-cloud-revenue-15-1-billion-to-14-5-billion/#53c3e14c39d6 +[4]:https://aws.amazon.com/blogs/aws/new-per-second-billing-for-ec2-instances-and-ebs-volumes/ +[5]:https://aws.amazon.com/ec2/pricing/on-demand/ +[6]:https://aws.amazon.com/ec2/spot/pricing/ +[7]:https://aws.amazon.com/ebs/pricing/ +[8]:https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/storage-optimized-instances.html +[9]:/blog/content/images/2018/01/Ec2cost.png +[10]:https://boto3.readthedocs.io +[11]:https://aws.amazon.com/s3/ +[12]:https://aws.amazon.com/message/41926/ +[13]:https://venturebeat.com/2017/02/28/aws-is-investigating-s3-issues-affecting-quora-slack-trello/ +[14]:https://aws.amazon.com/s3/pricing/ +[15]:https://aws.amazon.com/rds/aurora/ +[16]:https://aws.amazon.com/rds/postgresql/pricing/ +[17]:/blog/content/images/2018/01/RDSpricing.png +[18]:https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/CHAP_Storage.html +[19]:http://docs.aws.amazon.com/redshift/latest/dg/c_choosing_dist_sort.html +[20]:https://aws.amazon.com/redshift/pricing/ +[21]:https://aws.amazon.com/redshift/spectrum/ +[22]:http://docs.aws.amazon.com/emr/latest/DeveloperGuide/emr-nodes.html +[23]:https://docs.aws.amazon.com/emr/latest/ManagementGuide/emr-automatic-scaling.html +[24]:https://aws.amazon.com/emr/pricing/ +[25]:/blog/content/images/2018/01/EMRpricing.png +[26]:https://twitter.com/dataquestio From 651f1db6a978ac3873d33af5d18a390087226a27 Mon Sep 17 00:00:00 2001 From: darksun Date: Thu, 1 Feb 2018 10:43:28 +0800 Subject: [PATCH 109/272] =?UTF-8?q?=E9=80=89=E9=A2=98:=20Use=20of=20du=20&?= =?UTF-8?q?=20df=20commands=20(with=20examples)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...Use of du - df commands (with examples).md | 110 ++++++++++++++++++ 1 file changed, 110 insertions(+) create mode 100644 sources/tech/20180130 Use of du - df commands (with examples).md diff --git a/sources/tech/20180130 Use of du - df commands (with examples).md b/sources/tech/20180130 Use of du - df commands (with examples).md new file mode 100644 index 0000000000..5a1d374e3b --- /dev/null +++ b/sources/tech/20180130 Use of du - df commands (with examples).md @@ -0,0 +1,110 @@ +Use of du & df commands (with examples) +====== +In this article I will discuss du & df commands. Both du & df commands are important utilities of Linux system & shows disk usage of Linux filesystem. Here we will share usage of both commands with some examples. + +**(Recommended Read:[Files transfer using scp & rsync commands][1])** + + **(Also Read:[Cloning Disks using dd & cat commands for Linux systems][2])** + +### du COMMAND + +du command (short for disk usage) is useful command which is used to find disk usage for files & directories. du command when used with various options provides results in many formats. + +Some of the examples are mentioned below:- + + **1- To find out summary of disk usage for a directory with all its sub-directories** + +``` + $ du /home +``` + +![du command][4] + +Output of the command shows all the files & directories in /home with block size. + +**2- Disk usage with file/directory sizes in human readable format I.e. in kb, mb etc** + +``` + $ du -h /home +``` + +![du command][6] + +**3- Total disk size of a directory** + +``` + $ du -s /home +``` + +![du command][8] + +It will total size of /home directory. + +### df COMMAND + +df command (short for disk filesystem) is used to show disk utilization for a Linux system. + +Some examples are shared below. + + **1- To display information of device name, total blocks, total disk space, used disk space, available disk space and mount points on a file system.** + +``` + $ df +``` + + +![df command][10] + +**2- Information in human readable format** + +``` + $ df -h +``` + +![df command][12] + +Above command displays information in human readable format. + +**3- Display information of a particular partition** + +``` + $ df -hT /etc +``` + +![df command][14] + +Using -hT with a target directory will show information of /etc/ in human readable format. + +Though there are many more options that can be used with du & df commands, but these should get you started. If you don't find what you are looking for here then you can always refer to man pages for the concerned command. + +Also, read my other posts [**HERE**][15] where i have shared some other important & frequently used Linux. + +And as always your comments/queries are really appreciated, so please leave your comments/queries down below & I will get back to you. + + +-------------------------------------------------------------------------------- + +via: http://linuxtechlab.com/du-df-commands-examples/ + +作者:[SHUSAIN][a] +译者:[译者ID](https://github.com/译者ID) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:http://linuxtechlab.com/author/shsuain/ +[1]:http://linuxtechlab.com/files-transfer-scp-rsync-commands/ +[2]:http://linuxtechlab.com/linux-cloning-disks-using-dd-cat-commands/ +[3]:https://i1.wp.com/linuxtechlab.com/wp-content/plugins/a3-lazy-load/assets/images/lazy_placeholder.gif?resize=453%2C162 +[4]:https://i2.wp.com/linuxtechlab.com/wp-content/uploads/2017/02/du1.jpg?resize=453%2C162 +[5]:https://i1.wp.com/linuxtechlab.com/wp-content/plugins/a3-lazy-load/assets/images/lazy_placeholder.gif?resize=491%2C163 +[6]:https://i1.wp.com/linuxtechlab.com/wp-content/uploads/2017/02/du2.jpg?resize=491%2C163 +[7]:https://i1.wp.com/linuxtechlab.com/wp-content/plugins/a3-lazy-load/assets/images/lazy_placeholder.gif?resize=584%2C61 +[8]:https://i0.wp.com/linuxtechlab.com/wp-content/uploads/2017/02/du3.jpg?resize=584%2C61 +[9]:https://i1.wp.com/linuxtechlab.com/wp-content/plugins/a3-lazy-load/assets/images/lazy_placeholder.gif?resize=638%2C157 +[10]:https://i0.wp.com/linuxtechlab.com/wp-content/uploads/2017/02/df1.jpg?resize=638%2C157 +[11]:https://i1.wp.com/linuxtechlab.com/wp-content/plugins/a3-lazy-load/assets/images/lazy_placeholder.gif?resize=641%2C149 +[12]:https://i0.wp.com/linuxtechlab.com/wp-content/uploads/2017/02/df2.jpg?resize=641%2C149 +[13]:https://i1.wp.com/linuxtechlab.com/wp-content/plugins/a3-lazy-load/assets/images/lazy_placeholder.gif?resize=638%2C62 +[14]:https://i0.wp.com/linuxtechlab.com/wp-content/uploads/2017/02/df3-1.jpg?resize=638%2C62 +[15]:http://linuxtechlab.com/tips-tricks/ From 17a55ce0cda6a102e33a6c224d5f966433148130 Mon Sep 17 00:00:00 2001 From: darksun Date: Thu, 1 Feb 2018 10:48:52 +0800 Subject: [PATCH 110/272] =?UTF-8?q?=E9=80=89=E9=A2=98:=20Graphics=20and=20?= =?UTF-8?q?music=20tools=20for=20game=20development?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...cs and music tools for game development.md | 179 ++++++++++++++++++ 1 file changed, 179 insertions(+) create mode 100644 sources/tech/20180130 Graphics and music tools for game development.md diff --git a/sources/tech/20180130 Graphics and music tools for game development.md b/sources/tech/20180130 Graphics and music tools for game development.md new file mode 100644 index 0000000000..7414e89704 --- /dev/null +++ b/sources/tech/20180130 Graphics and music tools for game development.md @@ -0,0 +1,179 @@ +Graphics and music tools for game development +====== + +![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/OSDC_Life_opengame.png?itok=JPxruL3k) + +In early October, our club, [Geeks and Gadgets][1] from Marshall University, participated in the inaugural [Open Jam][2], a game jam that celebrated the best of open source tools. Game jams are events where participants work as teams to develop computer games for fun. Jams tend to be very short--only three days long--and very exhausting. Opensource.com [announced][3] Open Jam in late August, and more than [three dozen games][4] were entered into the competition. + +Our club likes to create and use open source software in our projects, so Open Jam was naturally the jam we wanted to participate in. Our submission was an experimental game called [Mark My Words][5]. We used a variety of free and open source (FOSS) tools to develop it; in this article we'll discuss some of the tools we used and potential stumbling blocks to be aware of. + +### Audio tools + +#### MilkyTracker + +[MilkyTracker][6] is one of the best software packages available for composing old-style video game music. It is an example of a [music tracker][7], a powerful MOD and XM file creator with a characteristic grid-based pattern editor. We used it to compose most of the musical pieces in our game. One of the great things about this program is that it consumed much less disk space and RAM than most of our other tools. Even so, MilkyTracker is still extremely powerful. + +![](https://opensource.com/sites/default/files/u128651/mtracker.png) + +The user interface took a while to get used to, so here are some pointers for any musician who wants to try out MilkyTracker: + + * Go to Config > Misc. and set the edit mode control style to "MilkyTracker." This will give you modern keyboard shortcuts for almost everything + * Undo with Ctrl+Z + * Redo with Ctrl+Y + * Toggle pattern-edit mode with the Spacebar + * Delete the previous note with the Backspace key + * Insert a row with the Insert key + * By default, a note will continue playing until it is replaced on that channel. You can end a note explicitly by inserting a KeyOff note with the backquote (`) key + * You will have to create or find samples before you can start composing. We recommend finding [Creative Commons][8] licensed samples at websites such as [Freesound][9] or [ccMixter][10] + + + +In addition, keep the [MilkyTracker documentation page][11] handy. It contains links to numerous tutorials and manuals. A good starting point is the [MilkyTracker Guide][12] on the project's wiki. + +#### LMMS + +Two of our musicians used the versatile and modern music creation tool [LMMS][13]. It comes with a library of cool samples and effects, plus a variety of flexible plugins for generating unique sounds. The learning curve for LMMS was surprisingly low, in part due to the nice beat/bassline editor. + +![](https://opensource.com/sites/default/files/u128651/lmms_plugins.png) + +We have one suggestion for musicians trying out LMMS: Use the plugins. For [chiptune][14]-style music, we recommend [sfxr][15], [BitInvader][16], and [FreeBoy][17]. For other styles, [ZynAddSubFX][18] is a good choice. It comes with a wide range of synthesized instruments that can be altered however you see fit. + +### Graphics tools + +#### Tiled + +[Tiled][19] is a popular tilemap editor in open source game development. We used it to assemble consistent, retro-looking backgrounds for our in-game scenes. + +![](https://opensource.com/sites/default/files/u128651/tiled.png) + +Tiled can export maps as XML, JSON, or as flattened images. It is stable and cross-platform. + +One of Tiled's features, which we did not use during the jam, allows you to define and place arbitrary game objects, such as coins and powerups, onto the map. All you have to do is load the object's graphics as a tileset, then place them using Insert Tile. + +Overall, Tiled is a stellar piece of software that we recommend for any project that needs a map editor. + +#### Piskel + +[Piskel][20] is a pixel art editor whose source code is licensed under the [Apache License, Version 2.0][21]. We used Piskel for almost all our graphical assets during the jam, and we will certainly be using it in future projects as well. + +Two features of Piskel that helped us immensely during the jam are onion skin and spritesheet exporting. + +##### Onion skin + +The onion skin feature will make Piskel show a ghostly overlay of the previous and next frames of your animation as you edit, like this: + +![](https://opensource.com/sites/default/files/u128651/onionshow.gif) + +Onion skin is handy because it serves as a drawing guide and helps you maintain consistent shapes and volumes on your characters throughout the animation process. To enable it, just click the onion-shaped icon underneath the preview window on the top-right of the screen. + +![](https://opensource.com/sites/default/files/u128651/onionenable.png) + +##### Spritesheet exporting + +Piskel's ability to export animations as a spritesheet was also very helpful. A spritesheet is a single raster image that contains all the frames of an animation. For example, here is a spritesheet we exported from Piskel: + +![](https://opensource.com/sites/default/files/u128651/sprite-artist.png) + +The spritesheet consists of two frames. One frame is in the top half of the image and the other frame is in the bottom half of the image. Spritesheets greatly simplify a game's code by enabling an entire animation to be loaded from a single file. Here is an animated version of the above spritesheet: + +![](https://opensource.com/sites/default/files/u128651/sprite-artist-anim.gif) + +##### Unpiskel.py + +There were several times during the jam when we wanted to batch convert Piskel files into PNGs. Since the Piskel file format is based on JSON, we wrote a small GPLv3-licensed Python script called [unpiskel.py][22] to do the conversion. + +It is invoked like this: +``` + + +python unpiskel.py input.piskel +``` + +The script will extract the PNG data frames and layers from a Piskel file (here `input.piskel`) and store them in their own files. The files follow the pattern `NAME_XX_YY.png` where `NAME` is the truncated name of the Piskel file, `XX` is the frame number, and `YY` is the layer number. + +Because the script can be invoked from a shell, it can be used on a whole list of files. +``` +for f in *.piskel; do python unpiskel.py "$f"; done +``` + +### Python, Pygame, and cx_Freeze + +#### Python and Pygame + +We used the [Python][23] language to make our game. It is a scripting language that is commonly used for text processing and desktop app development. It can also be used for game development, as projects like [Angry Drunken Dwarves][24] and [Ren'Py][25] have shown. Both of these projects use a Python library called [Pygame][26] to display graphics and produce sound, so we decided to use this library in Open Jam, too. + +Pygame turned out to be both stable and featureful, and it was great for the arcade-style game we were creating. The library's speed was fast enough at low resolutions, but its CPU-only rendering starts to slow down at higher resolutions. This is because Pygame does not use hardware-accelerated rendering. However, the infrastructure is there for developers to take full advantage of OpenGL. + +If you're looking for a good 2D game programming library, Pygame is one to keep your eye on. Its website has [a good tutorial][27] to get started. Be sure to check it out! + +#### cx_Freeze + +Prepping our game for distribution was interesting. We knew that Windows users were unlikely to have a Python installation, and asking them to install it would have been too much. On top of that, they would have had to also install Pygame, which is not an intuitive task on Windows. + +One thing was clear: We had to put our game into a more convenient form. Many of the other Open Jam participants used the proprietary game engine Unity, which enabled their games to be played in the web browser. This made them extremely convenient to play. Convenience was one thing our game didn't have even a sliver of. But, thanks to a vibrant Python ecosystem, we had options. Tools exist to help Python programmers prepare their programs for distribution on Windows. The two that we considered were [cx_Freeze][28] and [Pygame2exe][29] (which uses [py2exe][30]). We decided on cx_Freeze because it was cross-platform. + +In cx_Freeze, you can pack a single-script game for distribution just by running a command like this in the shell: +``` +cxfreeze main.py --target-dir dist +``` + +This invocation of `cxfreeze` will take your script (here `main.py`) and the Python interpreter on your system and bundle them up into the `dist` directory. Once this is done, all you have to do is manually copy your game's data files into the `dist` directory. You will find that the `dist` directory contains an executable file that can be run to start your game. + +There is a more involved way to use cx_Freeze that allows you to automate the copying of data files, but we found the straightforward invocation of `cxfreeze` to be good enough for our needs. Thanks to this tool, we made our game a little more convenient to play. + +### Celebrating open source + +Open Jam is important because it celebrates the open source model of software development. This is an opportunity to analyze the current state of open source tools and what we need to work on in the future. Game jams are perhaps the best time for game devs to try to push their tools to the limit, to learn what must be improved for the good of future game devs. + +Open source tools enable people to explore their creativity without compromising their freedom and without investing money upfront. Although we might not become professional game developers, we were still able to get a small taste of it with our short, experimental game called [Mark My Words][5]. It is a linguistically themed game that depicts the evolution of a fictional writing system throughout its history. There were many other delightful submissions to Open Jam, and they are all worth checking out. Really, [go look][31]! + +Before closing, we would like to thank all the [club members who participated][32] and made this experience truly worthwhile. We would also like to thank [Michael Clayton][33], [Jared Sprague][34], and [Opensource.com][35] for hosting Open Jam. It was a blast. + +Now, we have some questions for readers. Are you a FOSS game developer? What are your tools of choice? Be sure to leave a comment below! + +-------------------------------------------------------------------------------- + +via: https://opensource.com/article/18/1/graphics-music-tools-game-dev + +作者:[Charlie Murphy][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/rsg167 +[1]:http://mugeeks.org/ +[2]:https://itch.io/jam/open-jam-1 +[3]:https://opensource.com/article/17/8/open-jam-announcement +[4]:https://opensource.com/article/17/11/open-jam +[5]:https://mugeeksalpha.itch.io/mark-omy-words +[6]:http://milkytracker.titandemo.org/ +[7]:https://en.wikipedia.org/wiki/Music_tracker +[8]:https://creativecommons.org/ +[9]:https://freesound.org/ +[10]:http://ccmixter.org/view/media/home +[11]:http://milkytracker.titandemo.org/documentation/ +[12]:https://github.com/milkytracker/MilkyTracker/wiki/MilkyTracker-Guide +[13]:https://lmms.io/ +[14]:https://en.wikipedia.org/wiki/Chiptune +[15]:https://github.com/grimfang4/sfxr +[16]:https://lmms.io/wiki/index.php?title=BitInvader +[17]:https://lmms.io/wiki/index.php?title=FreeBoy +[18]:http://zynaddsubfx.sourceforge.net/ +[19]:http://www.mapeditor.org/ +[20]:https://www.piskelapp.com/ +[21]:https://github.com/piskelapp/piskel/blob/master/LICENSE +[22]:https://raw.githubusercontent.com/MUGeeksandGadgets/MarkMyWords/master/tools/unpiskel.py +[23]:https://www.python.org/ +[24]:https://www.sacredchao.net/~piman/angrydd/ +[25]:https://renpy.org/ +[26]:https://www.Pygame.org/ +[27]:http://Pygame.org/docs/tut/PygameIntro.html +[28]:https://anthony-tuininga.github.io/cx_Freeze/ +[29]:https://Pygame.org/wiki/Pygame2exe +[30]:http://www.py2exe.org/ +[31]:https://itch.io/jam/open-jam-1/entries +[32]:https://github.com/MUGeeksandGadgets/MarkMyWords/blob/3e1e8aed12ebe13acccf0d87b06d4f3bd124b9db/README.md#credits +[33]:https://twitter.com/mwcz +[34]:https://twitter.com/caramelcode +[35]:https://opensource.com/ From 9c7ac694909c37556ec3b8839e99cae294ce5fec Mon Sep 17 00:00:00 2001 From: MjSeven <33125422+MjSeven@users.noreply.github.com> Date: Thu, 1 Feb 2018 12:21:38 +0800 Subject: [PATCH 111/272] Delete 20170915 How To Install And Setup Vagrant.md --- ...170915 How To Install And Setup Vagrant.md | 266 ------------------ 1 file changed, 266 deletions(-) delete mode 100644 sources/tech/20170915 How To Install And Setup Vagrant.md diff --git a/sources/tech/20170915 How To Install And Setup Vagrant.md b/sources/tech/20170915 How To Install And Setup Vagrant.md deleted file mode 100644 index 6b6a8a0450..0000000000 --- a/sources/tech/20170915 How To Install And Setup Vagrant.md +++ /dev/null @@ -1,266 +0,0 @@ -Translating by MjSeven -How To Install And Setup Vagrant -====== -Vagrant is a powerful tool when it comes to virtual machines, here we will look at how to setup and use Vagrant with Virtualbox on Ubuntu to provision reproducible virtual machines. - -## Virtual Machines, not all that complex - -For years, developers have been using virtual machines as part of their workflow, allowing them to swap and change environments that the software is running in, this is generally to prevent conflicts between projects such as project A needing php 5.3 and project b needing php 5.4. - -Also, using Virtual Machines means you only ever need the computer you're working on, you don't need dedicated hardware to mirror the production environment. - -It also comes in handy when multiple developers are working on one project, they can all run an environment which contains all of its requirements, but it can be hard maintaining multiple machines and ensuring all have the same versions of all the requirements, this is where Vagrant comes in. - -### The benefits of using Virtual Machines - - * Your vm is separate from your host environment - * You can have a vm tailor for the requirements of your code - * Anything done in one vm does not effect another VM - * You can run programs in a vm which your host may not be able to run, such as running some windows only software in a - windows vm on top of ubuntu - - - -## What is Vagrant - -In short, it's a tool that works with virtual box to allow you to automate the creation and removal of a virtual machines. - -It revolves around a Config File Called the VagrantFile, which tells vagrant what version of what os you want to install, and some other options such as the IP and Directory Syncing. You can also add a provisioning script of commands to run on the virtual machine. - -By Sharing this VagrantFile around, all developers on a project. You will all be using the exact same virtual machine. - -## Installing the Requirements - -### Install VirtualBox - -VirtualBox is the program which will run the Virtual Machine and is available in the Ubuntu Repos -``` -sudo apt-get install virtualbox -``` - -### Install Vagrant - -For vagrant itself, you need to head to and install the package for your OS. - -### Install Guest Additions - -If you intend to sharing any folders with virtual machine, you need to install the following plugin. -``` -vagrant plugin install vagrant-vbguest -``` - -## Setting Up Vagrant - -### First we need to create an area for vagrant setups. -``` -mkdir ~/Vagrant/test-vm -cd ~/Vagrant/test-vm -``` - -### Create the VagrantFile -``` -vagrant init -``` - -### Start the Virtual Machine -``` -vagrant up -``` - -### Login to the Machine -``` -vagrant-ssh -``` - -By this point you will have the basic vagrant box, and a file called VagrantFile. - -## Customising - -The VagrantFile created in the steps above will look similar to the following - -**VagrantFile** - -``` -# -*- mode: ruby -*- -# vi: set ft=ruby : -# All Vagrant configuration is done below. The "2" in Vagrant.configure -# configures the configuration version (we support older styles for -# backwards compatibility). Please don't change it unless you know what -# you're doing. -Vagrant.configure("2") do |config| - # The most common configuration options are documented and commented below. - # For a complete reference, please see the online documentation at - # https://docs.vagrantup.com. - - # Every Vagrant development environment requires a box. You can search for - # boxes at https://vagrantcloud.com/search. - config.vm.box = "base" - - # Disable automatic box update checking. If you disable this, then - # boxes will only be checked for updates when the user runs - # `vagrant box outdated`. This is not recommended. - # config.vm.box_check_update = false - - # Create a forwarded port mapping which allows access to a specific port - # within the machine from a port on the host machine. In the example below, - # accessing "localhost:8080" will access port 80 on the guest machine. - # NOTE: This will enable public access to the opened port - # config.vm.network "forwarded_port", guest: 80, host: 8080 - - # Create a forwarded port mapping which allows access to a specific port - # within the machine from a port on the host machine and only allow access - # via 127.0.0.1 to disable public access - # config.vm.network "forwarded_port", guest: 80, host: 8080, host_ip: "127.0.0.1" - - # Create a private network, which allows host-only access to the machine - # using a specific IP. - # config.vm.network "private_network", ip: "192.168.33.10" - - # Create a public network, which generally matched to bridged network. - # Bridged networks make the machine appear as another physical device on - # your network. - # config.vm.network "public_network" - - # Share an additional folder to the guest VM. The first argument is - # the path on the host to the actual folder. The second argument is - # the path on the guest to mount the folder. And the optional third - # argument is a set of non-required options. - # config.vm.synced_folder "../data", "/vagrant_data" - - # Provider-specific configuration so you can fine-tune various - # backing providers for Vagrant. These expose provider-specific options. - # Example for VirtualBox: - # - # config.vm.provider "virtualbox" do |vb| - # # Display the VirtualBox GUI when booting the machine - # vb.gui = true - # - # # Customize the amount of memory on the VM: - # vb.memory = "1024" - # end - # - # View the documentation for the provider you are using for more - # information on available options. - - # Enable provisioning with a shell script. Additional provisioners such as - # Puppet, Chef, Ansible, Salt, and Docker are also available. Please see the - # documentation for more information about their specific syntax and use. - # config.vm.provision "shell", inline: <<-SHELL - # apt-get update - # apt-get install -y apache2 - # SHELL -end -``` - -Now this VagrantFile wll create the basic virtual machine. But the concept behind vagrant is to have the virtual machines set up for our specific tasks. So lets remove the comments and tweak the config. - -**VagrantFile** -``` -# -*- mode: ruby -*- -# vi: set ft=ruby : - -Vagrant.configure("2") do |config| - # Set the Linux Version to Debian Jessie - config.vm.box = "debian/jessie64" - # Set the IP of the Box - config.vm.network "private_network", ip: "192.168.33.10" - # Sync Our Projects Directory with the WWW directory - config.vm.synced_folder "~/Projects", "/var/www/" - # Run the following to Provision - config.vm.provision "shell", path: "install.sh" -end -``` - -Now we have a simple VagrantFile, Which sets the box to debian jessie, sets an IP for us to use, syncs the folders we are interested in, and finally runs an install.sh, which is where our shell commands can go. - -**install.sh** -``` -#! /usr/bin/env bash -# Variables -DBHOST=localhost -DBNAME=dbname -DBUSER=dbuser -DBPASSWD=test123 - -echo "[ Provisioning machine ]" -echo "1) Update APT..." -apt-get -qq update - -echo "1) Install Utilities..." -apt-get install -y tidy pdftk curl xpdf imagemagick openssl vim git - -echo "2) Installing Apache..." -apt-get install -y apache2 - -echo "3) Installing PHP and packages..." -apt-get install -y php5 libapache2-mod-php5 libssh2-php php-pear php5-cli php5-common php5-curl php5-dev php5-gd php5-imagick php5-imap php5-intl php5-mcrypt php5-memcached php5-mysql php5-pspell php5-xdebug php5-xmlrpc -#php5-suhosin-extension, php5-mysqlnd - -echo "4) Installing MySQL..." -debconf-set-selections <<< "mysql-server mysql-server/root_password password secret" -debconf-set-selections <<< "mysql-server mysql-server/root_password_again password secret" -apt-get install -y mysql-server -mysql -uroot -p$DBPASSWD -e "CREATE DATABASE $DBNAME" -mysql -uroot -p$DBPASSWD -e "grant all privileges on $DBNAME.* to '$DBUSER'@'localhost' identified by '$DBPASSWD'" - -echo "5) Generating self signed certificate..." -mkdir -p /etc/ssl/localcerts -openssl req -new -x509 -days 365 -nodes -subj "/C=US/ST=Denial/L=Springfield/O=Dis/CN=www.example.com" -out /etc/ssl/localcerts/apache.pem -keyout /etc/ssl/localcerts/apache.key -chmod 600 /etc/ssl/localcerts/apache* - -echo "6) Setup Apache..." -a2enmod rewrite -> /etc/apache2/sites-enabled/000-default.conf -echo " - - ServerAdmin [[email protected]][1] - DocumentRoot /var/www/ - ErrorLog ${APACHE_LOG_DIR}/error.log - CustomLog ${APACHE_LOG_DIR}/access.log combined - - -" >> /etc/apache2/sites-enabled/000-default.conf -service apache2 restart - -echo "7) Composer Install..." -curl --silent https://getcomposer.org/installer | php -mv composer.phar /usr/local/bin/composer - -echo "8) Install NodeJS..." -curl -sL https://deb.nodesource.com/setup_6.x | sudo -E bash - -apt-get -qq update -apt-get -y install nodejs - -echo "9) Install NPM Packages..." -npm install -g gulp gulp-cli - -echo "Provisioning Completed" -``` - -By having the above VagrantFile and Install.sh in your directory, running vagrant up will do the following - - * Create a Virtual Machine Using Debian Jessie - * Set the Machines IP to 192.168.33.10 - * Sync ~/Projects with /var/www/ - * Install and Setup Apache, Mysql, PHP, Git, Vim - * Install and Run Composer - * Install Nodejs and gulp - * Create A MySQL Database - * Create Self Sign Certificates - - - -By sharing the VagrantFile and install.sh with others, you can work on the exact same environment, on two different machines. - - --------------------------------------------------------------------------------- - -via: https://www.chris-shaw.com/blog/how-to-install-and-setup-vagrant - -作者:[Christopher Shaw][a] -译者:[译者ID](https://github.com/译者ID) -校对:[校对者ID](https://github.com/校对者ID) - -本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 - -[a]:https://www.chris-shaw.com -[1]:/cdn-cgi/l/email-protection From f9cc05624f069e183f7ffc5e2eaa4de16d1e71df Mon Sep 17 00:00:00 2001 From: MjSeven <33125422+MjSeven@users.noreply.github.com> Date: Thu, 1 Feb 2018 12:24:45 +0800 Subject: [PATCH 112/272] Create 20170915 How To Install And Setup Vagrant.md --- ...170915 How To Install And Setup Vagrant.md | 252 ++++++++++++++++++ 1 file changed, 252 insertions(+) create mode 100644 translated/tech/20170915 How To Install And Setup Vagrant.md diff --git a/translated/tech/20170915 How To Install And Setup Vagrant.md b/translated/tech/20170915 How To Install And Setup Vagrant.md new file mode 100644 index 0000000000..4a2ec91aca --- /dev/null +++ b/translated/tech/20170915 How To Install And Setup Vagrant.md @@ -0,0 +1,252 @@ +如何安装并设置 Vagrant +============================= + +Vagrant 对于虚拟机来说是一个强大的工具,在这里我们将研究如何在 Ubuntu 上设置和使用 Virtualbox 的 Vagrant 来提供可重复的虚拟机。 + +##虚拟机,并不复杂 + +多年来,开发人员一直使用虚拟机作为其工作流程的一部分,允许他们交换和更改运行软件的环境,这通常是为了防止项目之间的冲突,例如需要 php 5.3 的项目 A 和需要 php 5.4 的项目 B。 + +并且使用虚拟机意味着你只需要你正在使用的计算机,不需要专用硬件来镜像生产环境。 + +当多个开发人员在一个项目上工作时,它也很方便,他们都可以运行一个包含所有需求的环境,但是维护多台机器并确保所有的需求都具有相同的版本是非常困难的,这时 Vagrant 就能派上用场了。 + +###使用虚拟机的好处 + +- 你的虚拟机与主机环境是分开的 +- 可以根据你代码的要求有一个定制的虚拟机 +- 不会影响其他虚拟机 +- 可以运行在你的主机上无法运行的程序,例如在 Ubuntu 中运行一些只能在 Windows 运行的软件 + +##什么是 Vagrant + +简而言之,这是一个与虚拟机一起工作的工具,可以让你自动创建和删除虚拟机。 + +它围绕一个名为 VagrantFile 的配置文件进行,这个配置文件告诉 Vagrant 你想要安装的操作系统,以及一些其他选项,如 IP 和同步目录。 你还可以在虚拟机上添加一个命令的配置脚本。 + +一个项目的所有开发人员通过共享这个 VagrantFile,你们将全部使用完全相同的虚拟机。 + +##安装要求 + +###安装 VirtualBox + +VirtualBox 是运行虚拟机的程序,它可以在 Ubuntu Repos 中使用。 + + sudo apt-get install virtualbox + + +###安装 Vagrant + +对于 Vagrant 本身,你要前往 [https://www.vagrantup.com/downloads.html ](https://www.vagrantup.com/downloads.html) 查看并为你的 OS 安装软件包。 + +###安装增强功能 + +如果你打算与虚拟机共享任何文件夹,则需要安装以下插件。 + + + vagrant plugin install vagrant-vbguest + + +##配置 Vagrant + +###首先我们需要为 Vagrant 的配置创建一个文件夹 + + + mkdir ~/Vagrant/test-vm + cd ~/Vagrant/test-vm + + +###创建 VagrantFile + + vagrant init + + +###开启虚拟机 + + vagrant up + + +###登录机器 + + vagrant-ssh + + +此时,你将拥有一个基本的 vagrant box,以及一个名为 VagrantFile 的文件。 + +##定制 + +在上面的步骤中创建的 VagrantFile 看起来类似于以下内容 + +**VagrantFile** + + # -*- mode: ruby -*- + # vi: set ft=ruby : + # All Vagrant configuration is done below. The "2" in Vagrant.configure + # configures the configuration version (we support older styles for + # backwards compatibility). Please don't change it unless you know what + # you're doing. + Vagrant.configure("2") do |config| + # The most common configuration options are documented and commented below. + # For a complete reference, please see the online documentation at + # https://docs.vagrantup.com. + + # Every Vagrant development environment requires a box. You can search for + # boxes at https://vagrantcloud.com/search. + config.vm.box = "base" + + # Disable automatic box update checking. If you disable this, then + # boxes will only be checked for updates when the user runs + # `vagrant box outdated`. This is not recommended. + # config.vm.box_check_update = false + + # Create a forwarded port mapping which allows access to a specific port + # within the machine from a port on the host machine. In the example below, + # accessing "localhost:8080" will access port 80 on the guest machine. + # NOTE: This will enable public access to the opened port + # config.vm.network "forwarded_port", guest: 80, host: 8080 + + # Create a forwarded port mapping which allows access to a specific port + # within the machine from a port on the host machine and only allow access + # via 127.0.0.1 to disable public access + # config.vm.network "forwarded_port", guest: 80, host: 8080, host_ip: "127.0.0.1" + + # Create a private network, which allows host-only access to the machine + # using a specific IP. + # config.vm.network "private_network", ip: "192.168.33.10" + + # Create a public network, which generally matched to bridged network. + # Bridged networks make the machine appear as another physical device on + # your network. + # config.vm.network "public_network" + + # Share an additional folder to the guest VM. The first argument is + # the path on the host to the actual folder. The second argument is + # the path on the guest to mount the folder. And the optional third + # argument is a set of non-required options. + # config.vm.synced_folder "../data", "/vagrant_data" + + # Provider-specific configuration so you can fine-tune various + # backing providers for Vagrant. These expose provider-specific options. + # Example for VirtualBox: + # + # config.vm.provider "virtualbox" do |vb| + # # Display the VirtualBox GUI when booting the machine + # vb.gui = true + # + # # Customize the amount of memory on the VM: + # vb.memory = "1024" + # end + # + # View the documentation for the provider you are using for more + # information on available options. + + # Enable provisioning with a shell script. Additional provisioners such as + # Puppet, Chef, Ansible, Salt, and Docker are also available. Please see the + # documentation for more information about their specific syntax and use. + # config.vm.provision "shell", inline: <<-SHELL + # apt-get update + # apt-get install -y apache2 + # SHELL + end + +现在这个 VagrantFile 将创建基本的虚拟机。但 Vagrant 背后的理念是让虚拟机设置我们的特定任务,所以我们删除注释和调整配置。 + +**VagrantFile** + + # -*- mode: ruby -*- + # vi: set ft=ruby : + + Vagrant.configure("2") do |config| + # Set the Linux Version to Debian Jessie + config.vm.box = "debian/jessie64" + # Set the IP of the Box + config.vm.network "private_network", ip: "192.168.33.10" + # Sync Our Projects Directory with the WWW directory + config.vm.synced_folder "~/Projects", "/var/www/" + # Run the following to Provision + config.vm.provision "shell", path: "install.sh" + end + +现在我们有一个简单的 VagrantFile,它将 Linux 版本设置为 debian jessie,设置一个 IP 给我们使用,同步我们感兴趣的文件夹,最后运行 install.sh,这是我们的 shell 命令可以使用的地方。 + +**install.sh** + + #! /usr/bin/env bash + # Variables + DBHOST=localhost + DBNAME=dbname + DBUSER=dbuser + DBPASSWD=test123 + + echo "[ Provisioning machine ]" + echo "1) Update APT..." + apt-get -qq update + + echo "1) Install Utilities..." + apt-get install -y tidy pdftk curl xpdf imagemagick openssl vim git + + echo "2) Installing Apache..." + apt-get install -y apache2 + + echo "3) Installing PHP and packages..." + apt-get install -y php5 libapache2-mod-php5 libssh2-php php-pear php5-cli php5-common php5-curl php5-dev php5-gd php5-imagick php5-imap php5-intl php5-mcrypt php5-memcached php5-mysql php5-pspell php5-xdebug php5-xmlrpc + #php5-suhosin-extension, php5-mysqlnd + + echo "4) Installing MySQL..." + debconf-set-selections <<< "mysql-server mysql-server/root_password password secret" + debconf-set-selections <<< "mysql-server mysql-server/root_password_again password secret" + apt-get install -y mysql-server + mysql -uroot -p$DBPASSWD -e "CREATE DATABASE $DBNAME" + mysql -uroot -p$DBPASSWD -e "grant all privileges on $DBNAME.* to '$DBUSER'@'localhost' identified by '$DBPASSWD'" + + echo "5) Generating self signed certificate..." + mkdir -p /etc/ssl/localcerts + openssl req -new -x509 -days 365 -nodes -subj "/C=US/ST=Denial/L=Springfield/O=Dis/CN=www.example.com" -out /etc/ssl/localcerts/apache.pem -keyout /etc/ssl/localcerts/apache.key + chmod 600 /etc/ssl/localcerts/apache* + + echo "6) Setup Apache..." + a2enmod rewrite + > /etc/apache2/sites-enabled/000-default.conf + echo " + + ServerAdmin [[email protected]][1] + DocumentRoot /var/www/ + ErrorLog ${APACHE_LOG_DIR}/error.log + CustomLog ${APACHE_LOG_DIR}/access.log combined + + + " >> /etc/apache2/sites-enabled/000-default.conf + service apache2 restart + + echo "7) Composer Install..." + curl --silent https://getcomposer.org/installer | php + mv composer.phar /usr/local/bin/composer + + echo "8) Install NodeJS..." + curl -sL https://deb.nodesource.com/setup_6.x | sudo -E bash - + apt-get -qq update + apt-get -y install nodejs + + echo "9) Install NPM Packages..." + npm install -g gulp gulp-cli + + echo "Provisioning Completed" + +通过上面的步骤,在你的目录中会有 VagrantFile 和 Install.sh,运行 vagrant 会做下面的事情 + +- 采用 Debian Jessie 来创建虚拟机 +- 将机器的 IP 设置为 192.168.33.10 +- 同步 ~/Projects 和 /var/www/ 目录 +- 安装并设置 Apache, Mysql, PHP, Git, Vim +- 安装并运行 Composer +- 安装 Nodejs 和 gulp +- 创建一个 MySQL 数据库 +- 创建自签名证书 + +通过与其他人共享 VagrantFile 和 install.sh,你可以在两台不同的机器上使用完全相同的环境。 + +via: [https://www.chris-shaw.com/blog/how-to-install-and-setup-vagrant)](https://www.chris-shaw.com/blog/how-to-install-and-setup-vagrant) + +作者:[Christopher Shaw](a) 译者:[MjSeven](https://github.com/MjSeven) 校对:[校对者 ID](a) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 From 652b0be6267fe179d164bc7ab1f0ad5cabbffb95 Mon Sep 17 00:00:00 2001 From: wxy Date: Thu, 1 Feb 2018 14:48:17 +0800 Subject: [PATCH 113/272] PRF:20170915 How To Install And Setup Vagrant.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @MjSeven 恭喜你完成了第一篇翻译 --- ...170915 How To Install And Setup Vagrant.md | 383 +++++++++--------- 1 file changed, 200 insertions(+), 183 deletions(-) diff --git a/translated/tech/20170915 How To Install And Setup Vagrant.md b/translated/tech/20170915 How To Install And Setup Vagrant.md index 4a2ec91aca..92d56ab7b8 100644 --- a/translated/tech/20170915 How To Install And Setup Vagrant.md +++ b/translated/tech/20170915 How To Install And Setup Vagrant.md @@ -1,252 +1,269 @@ 如何安装并设置 Vagrant ============================= -Vagrant 对于虚拟机来说是一个强大的工具,在这里我们将研究如何在 Ubuntu 上设置和使用 Virtualbox 的 Vagrant 来提供可重复的虚拟机。 +Vagrant 对于虚拟机来说是一个强大的工具,在这里我们将研究如何在 Ubuntu 上设置和使用 Virtualbox 和 Vagrant 来提供可复制的虚拟机。 -##虚拟机,并不复杂 +### 虚拟机,并不复杂 多年来,开发人员一直使用虚拟机作为其工作流程的一部分,允许他们交换和更改运行软件的环境,这通常是为了防止项目之间的冲突,例如需要 php 5.3 的项目 A 和需要 php 5.4 的项目 B。 -并且使用虚拟机意味着你只需要你正在使用的计算机,不需要专用硬件来镜像生产环境。 +并且使用虚拟机意味着你只需要你正在使用的计算机就行,而不需要专用硬件来镜像你的生产环境。 当多个开发人员在一个项目上工作时,它也很方便,他们都可以运行一个包含所有需求的环境,但是维护多台机器并确保所有的需求都具有相同的版本是非常困难的,这时 Vagrant 就能派上用场了。 -###使用虚拟机的好处 +#### 使用虚拟机的好处 - 你的虚拟机与主机环境是分开的 -- 可以根据你代码的要求有一个定制的虚拟机 +- 你可以根据你代码的要求裁剪一个定制虚拟机 - 不会影响其他虚拟机 - 可以运行在你的主机上无法运行的程序,例如在 Ubuntu 中运行一些只能在 Windows 运行的软件 -##什么是 Vagrant +### 什么是 Vagrant 简而言之,这是一个与虚拟机一起工作的工具,可以让你自动创建和删除虚拟机。 -它围绕一个名为 VagrantFile 的配置文件进行,这个配置文件告诉 Vagrant 你想要安装的操作系统,以及一些其他选项,如 IP 和同步目录。 你还可以在虚拟机上添加一个命令的配置脚本。 +它围绕一个名为 `VagrantFile` 的配置文件而工作,这个配置文件告诉 Vagrant 你想要安装的操作系统,以及一些其他选项,如 IP 和目录同步。 你还可以在虚拟机上添加一个命令的配置脚本。 -一个项目的所有开发人员通过共享这个 VagrantFile,你们将全部使用完全相同的虚拟机。 +通过共享这个 `VagrantFile`,项目的所有开发人员全可以使用完全相同的虚拟机。 -##安装要求 +### 安装要求 -###安装 VirtualBox +#### 安装 VirtualBox -VirtualBox 是运行虚拟机的程序,它可以在 Ubuntu Repos 中使用。 +VirtualBox 是运行虚拟机的程序,它可以从 Ubuntu 仓库中安装。 - sudo apt-get install virtualbox +``` +sudo apt-get install virtualbox +``` +#### 安装 Vagrant -###安装 Vagrant +对于 Vagrant 本身,你要前往 [https://www.vagrantup.com/downloads.html ](https://www.vagrantup.com/downloads.html) 查看适用于你的操作系统的安装软件包。 -对于 Vagrant 本身,你要前往 [https://www.vagrantup.com/downloads.html ](https://www.vagrantup.com/downloads.html) 查看并为你的 OS 安装软件包。 - -###安装增强功能 +#### 安装增强功能 如果你打算与虚拟机共享任何文件夹,则需要安装以下插件。 +``` +vagrant plugin install vagrant-vbguest +``` - vagrant plugin install vagrant-vbguest +### 配置 Vagrant +首先我们需要为 Vagrant 创建一个文件夹。 -##配置 Vagrant +``` +mkdir ~/Vagrant/test-vm +cd ~/Vagrant/test-vm +``` -###首先我们需要为 Vagrant 的配置创建一个文件夹 +创建 VagrantFile: +``` +vagrant init +``` - mkdir ~/Vagrant/test-vm - cd ~/Vagrant/test-vm +开启虚拟机: +``` +vagrant up +``` -###创建 VagrantFile +登录机器: - vagrant init +``` +vagrant-ssh +``` +此时,你将拥有一个基本的 vagrant 机器,以及一个名为 `VagrantFile` 的文件。 -###开启虚拟机 +### 定制 - vagrant up +在上面的步骤中创建的 `VagrantFile` 看起来类似于以下内容 +VagrantFile: -###登录机器 +``` +# -*- mode: ruby -*- +# vi: set ft=ruby : +# All Vagrant configuration is done below. The "2" in Vagrant.configure +# configures the configuration version (we support older styles for +# backwards compatibility). Please don't change it unless you know what +# you're doing. +Vagrant.configure("2") do |config| + # The most common configuration options are documented and commented below. + # For a complete reference, please see the online documentation at + # https://docs.vagrantup.com. - vagrant-ssh + # Every Vagrant development environment requires a box. You can search for + # boxes at https://vagrantcloud.com/search. + config.vm.box = "base" + # Disable automatic box update checking. If you disable this, then + # boxes will only be checked for updates when the user runs + # `vagrant box outdated`. This is not recommended. + # config.vm.box_check_update = false -此时,你将拥有一个基本的 vagrant box,以及一个名为 VagrantFile 的文件。 + # Create a forwarded port mapping which allows access to a specific port + # within the machine from a port on the host machine. In the example below, + # accessing "localhost:8080" will access port 80 on the guest machine. + # NOTE: This will enable public access to the opened port + # config.vm.network "forwarded_port", guest: 80, host: 8080 -##定制 + # Create a forwarded port mapping which allows access to a specific port + # within the machine from a port on the host machine and only allow access + # via 127.0.0.1 to disable public access + # config.vm.network "forwarded_port", guest: 80, host: 8080, host_ip: "127.0.0.1" -在上面的步骤中创建的 VagrantFile 看起来类似于以下内容 + # Create a private network, which allows host-only access to the machine + # using a specific IP. + # config.vm.network "private_network", ip: "192.168.33.10" -**VagrantFile** + # Create a public network, which generally matched to bridged network. + # Bridged networks make the machine appear as another physical device on + # your network. + # config.vm.network "public_network" - # -*- mode: ruby -*- - # vi: set ft=ruby : - # All Vagrant configuration is done below. The "2" in Vagrant.configure - # configures the configuration version (we support older styles for - # backwards compatibility). Please don't change it unless you know what - # you're doing. - Vagrant.configure("2") do |config| - # The most common configuration options are documented and commented below. - # For a complete reference, please see the online documentation at - # https://docs.vagrantup.com. - - # Every Vagrant development environment requires a box. You can search for - # boxes at https://vagrantcloud.com/search. - config.vm.box = "base" - - # Disable automatic box update checking. If you disable this, then - # boxes will only be checked for updates when the user runs - # `vagrant box outdated`. This is not recommended. - # config.vm.box_check_update = false - - # Create a forwarded port mapping which allows access to a specific port - # within the machine from a port on the host machine. In the example below, - # accessing "localhost:8080" will access port 80 on the guest machine. - # NOTE: This will enable public access to the opened port - # config.vm.network "forwarded_port", guest: 80, host: 8080 - - # Create a forwarded port mapping which allows access to a specific port - # within the machine from a port on the host machine and only allow access - # via 127.0.0.1 to disable public access - # config.vm.network "forwarded_port", guest: 80, host: 8080, host_ip: "127.0.0.1" - - # Create a private network, which allows host-only access to the machine - # using a specific IP. - # config.vm.network "private_network", ip: "192.168.33.10" - - # Create a public network, which generally matched to bridged network. - # Bridged networks make the machine appear as another physical device on - # your network. - # config.vm.network "public_network" - - # Share an additional folder to the guest VM. The first argument is - # the path on the host to the actual folder. The second argument is - # the path on the guest to mount the folder. And the optional third - # argument is a set of non-required options. - # config.vm.synced_folder "../data", "/vagrant_data" - - # Provider-specific configuration so you can fine-tune various - # backing providers for Vagrant. These expose provider-specific options. - # Example for VirtualBox: - # - # config.vm.provider "virtualbox" do |vb| - # # Display the VirtualBox GUI when booting the machine - # vb.gui = true - # - # # Customize the amount of memory on the VM: - # vb.memory = "1024" - # end - # - # View the documentation for the provider you are using for more - # information on available options. - - # Enable provisioning with a shell script. Additional provisioners such as - # Puppet, Chef, Ansible, Salt, and Docker are also available. Please see the - # documentation for more information about their specific syntax and use. - # config.vm.provision "shell", inline: <<-SHELL - # apt-get update - # apt-get install -y apache2 - # SHELL - end + # Share an additional folder to the guest VM. The first argument is + # the path on the host to the actual folder. The second argument is + # the path on the guest to mount the folder. And the optional third + # argument is a set of non-required options. + # config.vm.synced_folder "../data", "/vagrant_data" -现在这个 VagrantFile 将创建基本的虚拟机。但 Vagrant 背后的理念是让虚拟机设置我们的特定任务,所以我们删除注释和调整配置。 + # Provider-specific configuration so you can fine-tune various + # backing providers for Vagrant. These expose provider-specific options. + # Example for VirtualBox: + # + # config.vm.provider "virtualbox" do |vb| + # # Display the VirtualBox GUI when booting the machine + # vb.gui = true + # + # # Customize the amount of memory on the VM: + # vb.memory = "1024" + # end + # + # View the documentation for the provider you are using for more + # information on available options. -**VagrantFile** + # Enable provisioning with a shell script. Additional provisioners such as + # Puppet, Chef, Ansible, Salt, and Docker are also available. Please see the + # documentation for more information about their specific syntax and use. + # config.vm.provision "shell", inline: <<-SHELL + # apt-get update + # apt-get install -y apache2 + # SHELL +end +``` - # -*- mode: ruby -*- - # vi: set ft=ruby : - - Vagrant.configure("2") do |config| - # Set the Linux Version to Debian Jessie - config.vm.box = "debian/jessie64" - # Set the IP of the Box - config.vm.network "private_network", ip: "192.168.33.10" - # Sync Our Projects Directory with the WWW directory - config.vm.synced_folder "~/Projects", "/var/www/" - # Run the following to Provision - config.vm.provision "shell", path: "install.sh" - end +现在这个 `VagrantFile` 将创建基本的虚拟机。但 Vagrant 背后的理念是让虚拟机为我们的特定任务而配置,所以我们删除注释和调整配置。 -现在我们有一个简单的 VagrantFile,它将 Linux 版本设置为 debian jessie,设置一个 IP 给我们使用,同步我们感兴趣的文件夹,最后运行 install.sh,这是我们的 shell 命令可以使用的地方。 +VagrantFile: -**install.sh** +``` +# -*- mode: ruby -*- +# vi: set ft=ruby : - #! /usr/bin/env bash - # Variables - DBHOST=localhost - DBNAME=dbname - DBUSER=dbuser - DBPASSWD=test123 - - echo "[ Provisioning machine ]" - echo "1) Update APT..." - apt-get -qq update - - echo "1) Install Utilities..." - apt-get install -y tidy pdftk curl xpdf imagemagick openssl vim git - - echo "2) Installing Apache..." - apt-get install -y apache2 - - echo "3) Installing PHP and packages..." - apt-get install -y php5 libapache2-mod-php5 libssh2-php php-pear php5-cli php5-common php5-curl php5-dev php5-gd php5-imagick php5-imap php5-intl php5-mcrypt php5-memcached php5-mysql php5-pspell php5-xdebug php5-xmlrpc - #php5-suhosin-extension, php5-mysqlnd - - echo "4) Installing MySQL..." - debconf-set-selections <<< "mysql-server mysql-server/root_password password secret" - debconf-set-selections <<< "mysql-server mysql-server/root_password_again password secret" - apt-get install -y mysql-server - mysql -uroot -p$DBPASSWD -e "CREATE DATABASE $DBNAME" - mysql -uroot -p$DBPASSWD -e "grant all privileges on $DBNAME.* to '$DBUSER'@'localhost' identified by '$DBPASSWD'" - - echo "5) Generating self signed certificate..." - mkdir -p /etc/ssl/localcerts - openssl req -new -x509 -days 365 -nodes -subj "/C=US/ST=Denial/L=Springfield/O=Dis/CN=www.example.com" -out /etc/ssl/localcerts/apache.pem -keyout /etc/ssl/localcerts/apache.key - chmod 600 /etc/ssl/localcerts/apache* - - echo "6) Setup Apache..." - a2enmod rewrite - > /etc/apache2/sites-enabled/000-default.conf - echo " - - ServerAdmin [[email protected]][1] - DocumentRoot /var/www/ - ErrorLog ${APACHE_LOG_DIR}/error.log - CustomLog ${APACHE_LOG_DIR}/access.log combined - - - " >> /etc/apache2/sites-enabled/000-default.conf - service apache2 restart - - echo "7) Composer Install..." - curl --silent https://getcomposer.org/installer | php - mv composer.phar /usr/local/bin/composer - - echo "8) Install NodeJS..." - curl -sL https://deb.nodesource.com/setup_6.x | sudo -E bash - - apt-get -qq update - apt-get -y install nodejs - - echo "9) Install NPM Packages..." - npm install -g gulp gulp-cli - - echo "Provisioning Completed" +Vagrant.configure("2") do |config| + # Set the Linux Version to Debian Jessie + config.vm.box = "debian/jessie64" + # Set the IP of the Box + config.vm.network "private_network", ip: "192.168.33.10" + # Sync Our Projects Directory with the WWW directory + config.vm.synced_folder "~/Projects", "/var/www/" + # Run the following to Provision + config.vm.provision "shell", path: "install.sh" +end +``` -通过上面的步骤,在你的目录中会有 VagrantFile 和 Install.sh,运行 vagrant 会做下面的事情 +现在我们有一个简单的 `VagrantFile`,它将 Linux 版本设置为 debian jessie,设置一个 IP 给我们使用,同步我们感兴趣的文件夹,并最后运行 `install.sh`,这是我们可以运行 shell 命令的地方。 + +install.sh: + +``` +#! /usr/bin/env bash +# Variables +DBHOST=localhost +DBNAME=dbname +DBUSER=dbuser +DBPASSWD=test123 + +echo "[ Provisioning machine ]" +echo "1) Update APT..." +apt-get -qq update + +echo "1) Install Utilities..." +apt-get install -y tidy pdftk curl xpdf imagemagick openssl vim git + +echo "2) Installing Apache..." +apt-get install -y apache2 + +echo "3) Installing PHP and packages..." +apt-get install -y php5 libapache2-mod-php5 libssh2-php php-pear php5-cli php5-common php5-curl php5-dev php5-gd php5-imagick php5-imap php5-intl php5-mcrypt php5-memcached php5-mysql php5-pspell php5-xdebug php5-xmlrpc +#php5-suhosin-extension, php5-mysqlnd + +echo "4) Installing MySQL..." +debconf-set-selections <<< "mysql-server mysql-server/root_password password secret" +debconf-set-selections <<< "mysql-server mysql-server/root_password_again password secret" +apt-get install -y mysql-server +mysql -uroot -p$DBPASSWD -e "CREATE DATABASE $DBNAME" +mysql -uroot -p$DBPASSWD -e "grant all privileges on $DBNAME.* to '$DBUSER'@'localhost' identified by '$DBPASSWD'" + +echo "5) Generating self signed certificate..." +mkdir -p /etc/ssl/localcerts +openssl req -new -x509 -days 365 -nodes -subj "/C=US/ST=Denial/L=Springfield/O=Dis/CN=www.example.com" -out /etc/ssl/localcerts/apache.pem -keyout /etc/ssl/localcerts/apache.key +chmod 600 /etc/ssl/localcerts/apache* + +echo "6) Setup Apache..." +a2enmod rewrite +> /etc/apache2/sites-enabled/000-default.conf +echo " + + ServerAdmin webmaster@localhost + DocumentRoot /var/www/ + ErrorLog ${APACHE_LOG_DIR}/error.log + CustomLog ${APACHE_LOG_DIR}/access.log combined + + +" >> /etc/apache2/sites-enabled/000-default.conf +service apache2 restart + +echo "7) Composer Install..." +curl --silent https://getcomposer.org/installer | php +mv composer.phar /usr/local/bin/composer + +echo "8) Install NodeJS..." +curl -sL https://deb.nodesource.com/setup_6.x | sudo -E bash - +apt-get -qq update +apt-get -y install nodejs + +echo "9) Install NPM Packages..." +npm install -g gulp gulp-cli + +echo "Provisioning Completed" +``` + +通过上面的步骤,在你的目录中会有 `VagrantFile` 和 `install.sh`,运行 vagrant 会做下面的事情: - 采用 Debian Jessie 来创建虚拟机 - 将机器的 IP 设置为 192.168.33.10 -- 同步 ~/Projects 和 /var/www/ 目录 -- 安装并设置 Apache, Mysql, PHP, Git, Vim +- 同步 `~/Projects` 和 `/var/www/` 目录 +- 安装并设置 Apache、Mysql、PHP、Git、Vim - 安装并运行 Composer - 安装 Nodejs 和 gulp - 创建一个 MySQL 数据库 - 创建自签名证书 -通过与其他人共享 VagrantFile 和 install.sh,你可以在两台不同的机器上使用完全相同的环境。 +通过与其他人共享 `VagrantFile` 和 `install.sh`,你可以在两台不同的机器上使用完全相同的环境。 -via: [https://www.chris-shaw.com/blog/how-to-install-and-setup-vagrant)](https://www.chris-shaw.com/blog/how-to-install-and-setup-vagrant) +-------------------------------------------------------------------------------- -作者:[Christopher Shaw](a) 译者:[MjSeven](https://github.com/MjSeven) 校对:[校对者 ID](a) +via: https://www.chris-shaw.com/blog/how-to-install-and-setup-vagrant + +作者:[Christopher Shaw][a] +译者:[MjSeven](https://github.com/MjSeven) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://www.chris-shaw.com +[1]:/cdn-cgi/l/email-protection From 3f78e1d607b9ee9ac1b68a134ae3c6d75816cf74 Mon Sep 17 00:00:00 2001 From: wxy Date: Thu, 1 Feb 2018 14:49:26 +0800 Subject: [PATCH 114/272] PUB:20170915 How To Install And Setup Vagrant.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @MjSeven 首发地址: https://linux.cn/article-9301-1.html 你的 LCTT 专页地址: https://linux.cn/lctt/MjSeven --- .../20170915 How To Install And Setup Vagrant.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename {translated/tech => published}/20170915 How To Install And Setup Vagrant.md (100%) diff --git a/translated/tech/20170915 How To Install And Setup Vagrant.md b/published/20170915 How To Install And Setup Vagrant.md similarity index 100% rename from translated/tech/20170915 How To Install And Setup Vagrant.md rename to published/20170915 How To Install And Setup Vagrant.md From 9ab5d29dd739c53c48189b1632f0b6bd5c57056d Mon Sep 17 00:00:00 2001 From: wxy Date: Thu, 1 Feb 2018 15:11:08 +0800 Subject: [PATCH 115/272] PRF:20070129 How To Debug a Bash Shell Script Under Linux or UNIX.md @zjon --- ...a Bash Shell Script Under Linux or UNIX.md | 147 ++++++++++++------ 1 file changed, 97 insertions(+), 50 deletions(-) diff --git a/translated/tech/20070129 How To Debug a Bash Shell Script Under Linux or UNIX.md b/translated/tech/20070129 How To Debug a Bash Shell Script Under Linux or UNIX.md index 4cc979015b..1517fc151d 100644 --- a/translated/tech/20070129 How To Debug a Bash Shell Script Under Linux or UNIX.md +++ b/translated/tech/20070129 How To Debug a Bash Shell Script Under Linux or UNIX.md @@ -1,32 +1,35 @@ 如何在 Linux 或者 UNIX 下调试 Bash Shell 脚本 ====== + 来自我的邮箱: -**我写了一个你好世界的小脚本。我如何能调试运行在 Linux 或者类 UNIX 的系统上的 bash shell 脚本呢?** + +> 我写了一个 hello world 小脚本。我如何能调试运行在 Linux 或者类 UNIX 的系统上的 bash shell 脚本呢? + 这是 Linux / Unix 系统管理员或新用户最常问的问题。shell 脚本调试可能是一项繁琐的工作(不容易阅读)。调试 shell 脚本有多种方法。 -您需要传递 -X 或 -V 参数,以在 bash shell 中浏览每行代码。 +您需要传递 `-x` 或 `-v` 参数,以在 bash shell 中浏览每行代码。 [![如何在 Linux 或者 UNIX 下调试 Bash Shell 脚本][1]][1] 让我们看看如何使用各种方法调试 Linux 和 UNIX 上运行的脚本。 -``` ### -x 选项来调试脚本 -用 -x 选项来运行脚本 +用 `-x` 选项来运行脚本: + ``` $ bash -x script-name $ bash -x domains.sh ``` - ### 使用 set 内置命令 bash shell 提供调试选项,可以打开或关闭使用 [set 命令][2]: - * **set -x** : 显示命令及其执行时的参数。 - * **set -v** : 显示 shell 输入行作为它们读取的 +* `set -x` : 显示命令及其执行时的参数。 +* `set -v` : 显示 shell 输入行作为它们读取的 + +可以在 shell 脚本本身中使用上面的两个命令: -可以在shell脚本本身中使用上面的两个命令: ``` #!/bin/bash clear @@ -43,18 +46,28 @@ ls # more commands ``` -你可以代替 [标准 Shebang][3] 行: -`#!/bin/bash` -用一下代码(用于调试): -`#!/bin/bash -xv` +你可以代替 [标准释伴][3] 行: + +``` +#!/bin/bash +``` + +用以下代码(用于调试): + +``` +#!/bin/bash -xv +``` ### 使用智能调试功能 -首先添加一个叫做 _DEBUG 的特殊变量。当你需要调试脚本的时候,设置 _DEBUG 为 'on': -`_DEBUG="on"` +首先添加一个叫做 `_DEBUG` 的特殊变量。当你需要调试脚本的时候,设置 `_DEBUG` 为 `on`: +``` +_DEBUG="on" +``` 在脚本的开头放置以下函数: + ``` function DEBUG() { @@ -62,11 +75,14 @@ function DEBUG() } ``` -function DEBUG() { [ "$_DEBUG" == "on" ] && $@ } +现在,只要你需要调试,只需使用 `DEBUG` 函数如下: + +``` +DEBUG echo "File is $filename" +``` + +或者: -现在,只要你需要调试,只需使用 DEBUG 函数如下: -`DEBUG echo "File is $filename"` -或者 ``` DEBUG set -x Cmd1 @@ -74,11 +90,14 @@ Cmd2 DEBUG set +x ``` -当调试完(在移动你的脚本到生产环境之前)设置 _DEBUG 为 'off'。不需要删除调试行。 -`_DEBUG="off" # 设置为非 'on' 的任何字符` +当调试完(在移动你的脚本到生产环境之前)设置 `_DEBUG` 为 `off`。不需要删除调试行。 +``` +_DEBUG="off" # 设置为非 'on' 的任何字符 +``` 示例脚本: + ``` #!/bin/bash _DEBUG="on" @@ -102,8 +121,13 @@ echo "$a + $b = $c" ``` 保存并关闭文件。运行脚本如下: -`$ ./script.sh` -输出: + +``` +$ ./script.sh +``` + +输出: + ``` Reading files Found in xyz.txt file @@ -114,31 +138,43 @@ Found in xyz.txt file + '[' on == on ']' + set +x 2 + 3 = 5 - ``` -现在设置 DEBUG 为关闭(你需要编辑文件): -`_DEBUG="off"` -运行脚本: -`$ ./script.sh` -输出: +现在设置 `_DEBUG` 为 `off`(你需要编辑该文件): + +``` +_DEBUG="off" +``` + +运行脚本: + +``` +$ ./script.sh +``` + +输出: + ``` Found in xyz.txt file 2 + 3 = 5 - ``` -以上是一个简单但非常有效的技术。还可以尝试使用 DEBUG 作为别名替代函数。 +以上是一个简单但非常有效的技术。还可以尝试使用 `DEBUG` 作为别名而不是函数。 ### 调试 Bash Shell 的常见错误 Bash 或者 sh 或者 ksh 在屏幕上给出各种错误信息,在很多情况下,错误信息可能不提供详细的信息。 #### 跳过在文件上应用执行权限 -When you [write your first hello world bash shell script][4], you might end up getting an error that read as follows: + 当你 [编写你的第一个 hello world 脚本][4],您可能会得到一个错误,如下所示: -`bash: ./hello.sh: Permission denied` -设置权限使用 chmod 命令: + +``` +bash: ./hello.sh: Permission denied +``` + +设置权限使用 `chmod` 命令: + ``` $ chmod +x hello.sh $ ./hello.sh @@ -147,21 +183,21 @@ $ bash hello.sh #### 文件结束时发生意外的错误 -如果您收到文件结束意外错误消息,请打开脚本文件,并确保它有打开和关闭引号。在这个例子中,echo 语句有一个开头引号,但没有结束引号: +如果您收到文件结束意外错误消息,请打开脚本文件,并确保它有打开和关闭引号。在这个例子中,`echo` 语句有一个开头引号,但没有结束引号: + ``` #!/bin/bash - ... .... - echo 'Error: File not found ^^^^^^^ missing quote ``` -还要确保你检查缺少的括号和大括号 ({}): +还要确保你检查缺少的括号和大括号 `{}`: + ``` #!/bin/bash ..... @@ -172,7 +208,9 @@ echo 'Error: File not found ``` #### 丢失像 fi,esac,;; 等关键字。 -如果你缺少了结尾的关键字,如 fi 或 ;; 你会得到一个错误,如 “XXX 意外”。因此,确保所有嵌套的 if 和 case 语句以适当的关键字结束。有关语法要求的页面。在本例中,缺少 fi: + +如果你缺少了结尾的关键字,如 `fi` 或 `;;` 你会得到一个错误,如 “XXX 意外”。因此,确保所有嵌套的 `if` 和 `case` 语句以适当的关键字结束。有关语法要求的页面。在本例中,缺少 `fi`: + ``` #!/bin/bash echo "Starting..." @@ -189,16 +227,23 @@ do echo $f done -# 注意 fi 已经丢失 +# 注意 fi 丢失了 ``` #### 在 Windows 或 UNIX 框中移动或编辑 shell 脚本 -不要在 Linux 上创建脚本并移动到 Windows。另一个问题是编辑 Windows 10上的 shell 脚本并将其移动到 UNIX 服务器上。这将导致一个错误的命令没有发现由于回车返回(DOS CR-LF)。你可以 [将 DOS 换行转换为 CR-LF 的Unix/Linux 格式][5] 使用下列命令: -`dos2unix my-script.sh` +不要在 Linux 上创建脚本并移动到 Windows。另一个问题是编辑 Windows 10上的 shell 脚本并将其移动到 UNIX 服务器上。这将由于换行符不同而导致命令没有发现的错误。你可以使用下列命令 [将 DOS 换行转换为 CR-LF 的Unix/Linux 格式][5] : + +``` +dos2unix my-script.sh +``` + +### 技巧 + +#### 技巧 1 - 发送调试信息输出到标准错误 -### 提示1 - 发送调试信息输出到标准错误 [标准错误] 是默认错误输出设备,用于写所有系统错误信息。因此,将消息发送到默认的错误设备是个好主意: + ``` # 写错误到标准输出 echo "Error: $1 file not found" @@ -208,17 +253,19 @@ echo "Error: $1 file not found" echo "Error: $1 file not found" 1>&2 ``` -### 提示2 - 在使用 vim 文本编辑器时,打开语法高亮。 -大多数现代文本编辑器允许设置语法高亮选项。这对于检测语法和防止常见错误如打开或关闭引号非常有用。你可以在不同的颜色中看到。这个特性简化了 shell 脚本结构中的编写,语法错误在视觉上截然不同。强调不影响文本本身的意义,它只为你编写。在这个例子中,我的脚本使用了 vim 语法高亮: +#### 技巧 2 - 在使用 vim 文本编辑器时,打开语法高亮 + +大多数现代文本编辑器允许设置语法高亮选项。这对于检测语法和防止常见错误如打开或关闭引号非常有用。你可以在不同的颜色中看到。这个特性简化了 shell 脚本结构中的编写,语法错误在视觉上截然不同。高亮不影响文本本身的意义,它只为你提示而已。在这个例子中,我的脚本使用了 vim 语法高亮: + [!如何调试 Bash Shell 脚本,在 Linux 或者 UNIX 使用 Vim 语法高亮特性][7]][7] -### 提示3 - 使用 shellcheck 检查脚本 -[shellcheck 是一个用于静态分析 shell 脚本的工具][8]。可以使用它来查找 shell 脚本中的错误。这是用 Haskell 编写的。您可以使用这个工具找到警告和建议。让我们看看如何在 Linux 或 类UNIX 系统上安装和使用 shellcheck 来改善你的 shell 脚本,避免错误和高效。 +#### 技巧 3 - 使用 shellcheck 检查脚本 -### 关于作者 -发表者: +[shellcheck 是一个用于静态分析 shell 脚本的工具][8]。可以使用它来查找 shell 脚本中的错误。这是用 Haskell 编写的。您可以使用这个工具找到警告和建议。你可以看看如何在 Linux 或 类UNIX 系统上安装和使用 shellcheck 来改善你的 shell 脚本,避免错误和高效。 -作者是 nixCraft 创造者,一个经验丰富的系统管理员和一个练习 Linux 操作系统/ UNIX shell 脚本的教练。他曾与全球客户和各种行业,包括 IT,教育,国防和空间研究,以及非营利部门。跟随他 [推特][9],[脸谱网][10],[谷歌+ ][11]。 +作者:Vivek Gite + +作者是 nixCraft 创造者,一个经验丰富的系统管理员和一个练习 Linux 操作系统/ UNIX shell 脚本的教练。他曾与全球客户和各种行业,包括 IT,教育,国防和空间研究,以及非营利部门。关注他的 [推特][9],[脸谱网][10],[谷歌+ ][11]。 -------------------------------------------------------------------------------- @@ -226,7 +273,7 @@ via: https://www.cyberciti.biz/tips/debugging-shell-script.html 作者:[Vivek Gite][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/) 荣誉推出 From 1637abeacd95f7fd793962c3a1db6a79ccade1c0 Mon Sep 17 00:00:00 2001 From: wxy Date: Thu, 1 Feb 2018 15:13:30 +0800 Subject: [PATCH 116/272] PUB:20070129 How To Debug a Bash Shell Script Under Linux or UNIX.md @zjon https://linux.cn/article-9302-1.html --- ...070129 How To Debug a Bash Shell Script Under Linux or UNIX.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename {translated/tech => published}/20070129 How To Debug a Bash Shell Script Under Linux or UNIX.md (100%) diff --git a/translated/tech/20070129 How To Debug a Bash Shell Script Under Linux or UNIX.md b/published/20070129 How To Debug a Bash Shell Script Under Linux or UNIX.md similarity index 100% rename from translated/tech/20070129 How To Debug a Bash Shell Script Under Linux or UNIX.md rename to published/20070129 How To Debug a Bash Shell Script Under Linux or UNIX.md From 421a75a67375aabdea75cd53fe5ea18251839581 Mon Sep 17 00:00:00 2001 From: wxy Date: Thu, 1 Feb 2018 15:19:34 +0800 Subject: [PATCH 117/272] =?UTF-8?q?=E5=BD=92=E6=A1=A3=20201801?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- published/{ => 201801}/20090127 Anatomy of a Program in Memory.md | 0 ...are Linux Guest Add a New Hard Disk Without Rebooting Guest.md | 0 ...ow to find hidden processes and ports on Linux-Unix-Windows.md | 0 ...611 30 Handy Bash Shell Aliases For Linux - Unix - Mac OS X.md | 0 ...0121211 Python Nmon Analyzer- moving away from excel macros.md | 0 published/{ => 201801}/20140210 Three steps to learning GDB.md | 0 ...se curl command with proxy username-password on Linux- Unix.md | 0 .../20160625 Trying out LXD containers on our Ubuntu.md | 0 .../{ => 201801}/20160808 Top 10 Command Line Games For Linux.md | 0 .../20161004 What happens when you start a process on Linux.md | 0 .../{ => 201801}/20170131 Book review Ours to Hack and to Own.md | 0 .../20170209 INTRODUCING DOCKER SECRETS MANAGEMENT.md | 0 .../{ => 201801}/20170319 ftrace trace your kernel functions.md | 0 .../20170426 Important Docker commands for Beginners.md | 0 .../{ => 201801}/20170502 A beginner-s guide to Raspberry Pi 3.md | 0 .../20170512 Which Official Ubuntu Flavor Is Best for You.md | 0 .../20170515 Commands to check System & Hardware Information.md | 0 published/{ => 201801}/20170524 View Counting at Reddit.md | 0 .../20170524 Working with Vi-Vim Editor - Advanced concepts.md | 0 .../20170526 Creating a YUM repository from ISO - Online repo.md | 0 ...0607 Why Car Companies Are Hiring Computer Security Experts.md | 0 ...02 Creating SWAP partition using FDISK - FALLOCATE commands.md | 0 .../{ => 201801}/20170804 Add speech to your Fedora system.md | 0 .../20170820 How To Display Date And Time In History Command.md | 0 ...story Command To Rollback An Updates In RHEL-CentOS Systems.md | 0 .../20170915 12 ip Command Examples for Linux Users.md | 0 .../20170915 Fake A Hollywood Hacker Screen in Linux Terminal.md | 0 ... Auto Logout Inactive Users After A Period Of Time In Linux.md | 0 .../20170918 3 text editor alternatives to Emacs and Vim.md | 0 .../20170918 Linux fmt command - usage and examples.md | 0 published/{ => 201801}/20170919 What Are Bitcoins.md | 0 .../20170920 Easy APT Repository - Iain R. Learmonth.md | 0 .../{ => 201801}/20170921 Mastering file searches on Linux.md | 0 published/{ => 201801}/20170924 Simulate System Loads.md | 0 .../20170925 A Commandline Fuzzy Search Tool For Linux.md | 0 ...925 Linux Free Command Explained for Beginners (6 Examples).md | 0 ...Easily Find Awesome Projects And Resources Hosted In GitHub.md | 0 .../20170927 Microservices and containers- 5 pitfalls to avoid.md | 0 .../20171002 Connect To Wifi From The Linux Command Line.md | 0 .../20171004 How To Create A Video From PDF Files In Linux.md | 0 ...n-hwinfo - Display Summary Of Hardware Information In Linux.md | 0 .../20171008 The most important Firefox command line options.md | 0 published/{ => 201801}/20171011 What is a firewall.md | 0 .../20171012 Install and Use YouTube-DL on Ubuntu 16.04.md | 0 .../20171013 Get Your Weather Forecast From the Linux CLI.md | 0 .../20171016 Fixing vim in Debian - There and back again.md | 0 ...7 check_mk error Cannot fetch deployment URL via curl error.md | 0 .../20171019 3 Simple Excellent Linux Network Monitors.md | 0 .../20171024 Run Linux On Android Devices, No Rooting Required.md | 0 ...0171028 Let Us Play Piano In Terminal Using Our PC Keyboard.md | 0 .../20171030 How To Create Custom Ubuntu Live CD Image.md | 0 .../{ => 201801}/20171031 Migrating to Linux- An Introduction.md | 0 .../20171106 Autorandr- automatically adjust screen layout.md | 0 ...t Server Against Brute Force Attacks With Fail2ban On Linux.md | 0 published/{ => 201801}/20171107 The long goodbye to C.md | 0 .../20171109 Learn how to use tcpdump command with examples.md | 0 published/{ => 201801}/20171112 Love Your Bugs.md | 0 ...1114 Restore Corrupted USB Drive To Original State In Linux.md | 0 ...115 How to Fix the ‘No Space Left on Device- Error on Linux.md | 0 .../20171115 Security Jobs Are Hot Get Trained and Get Noticed.md | 0 .../{ => 201801}/20171119 10 Best LaTeX Editors For Linux.md | 0 .../{ => 201801}/20171120 Adopting Kubernetes step by step.md | 0 ...Files Directly To Google Drive And Download 10 Times Faster.md | 0 .../20171123 Check Cryptocurrency Prices From Commandline.md | 0 .../20171127 Migrating to Linux Disks Files and Filesystems.md | 0 .../{ => 201801}/20171128 A generic introduction to Gitlab CI.md | 0 .../20171201 Launching an Open Source Project A Free Guide.md | 0 .../{ => 201801}/20171205 How to Use the Date Command in Linux.md | 0 .../20171205 Using sudo to delegate permissions in Linux.md | 0 ...07 Cheat – A Collection Of Practical Linux Command Examples.md | 0 .../20171207 How To Find Files Based On their Permissions.md | 0 ...1212 How to Search PDF Files from the Terminal with pdfgrep.md | 0 ...User To Access A Specific File or Folder In Linux Using ACL.md | 0 .../20171214 A step-by-step guide to building open culture.md | 0 .../20171214 How to Install Moodle on Ubuntu 16.04.md | 0 ...71214 How to squeeze the most out of Linux file compression.md | 0 .../20171214 The Most Famous Classic Text-based Adventure Game.md | 0 .../20171215 5 of the Best Bitcoin Clients for Linux.md | 0 .../20171215 How to find and tar files into a tar ball.md | 0 .../20171216 Saving window position in Xfce session.md | 0 ...How to Create a .Desktop File For Your Application in Linux.md | 0 .../20171219 Migrating to Linux- Graphical Environments.md | 0 ...219 Surf anonymously- Learn to install TOR network on Linux.md | 0 .../20171219 The Linux commands you should NEVER use.md | 0 .../20171220 The current state of kernel page-table isolation.md | 0 ...eck Linux filesystem for errors- FSCK command with examples.md | 0 .../{ => 201801}/20171226 How to Configure Linux for Children.md | 0 ...20171226 How to use-run bash aliases over ssh based session.md | 0 .../20171227 Best Programming Languages To Learn In 2018.md | 0 ...1228 How to exclude file when using scp command recursively.md | 0 ...171229 Set Ubuntu Derivatives Back to Default with Resetter.md | 0 ...171230 How To Sync Time Between Linux And Windows Dual Boot.md | 0 ...e mysterious case of the Linux Page Table Isolation patches.md | 0 ...ux-Unix desktop fun- Simulates the display from -The Matrix.md | 0 .../20180104 4 artificial intelligence trends to watch.md | 0 ... find out path where is package installed to on CentOS-RHEL.md | 0 ...elona Kicks Out Microsoft in Favor of Linux and Open Source.md | 0 ...n is the New Choice For Googles In-house Linux Distribution.md | 0 .../20180123 What Is bashrc and Why Should You Edit It.md | 0 99 files changed, 0 insertions(+), 0 deletions(-) rename published/{ => 201801}/20090127 Anatomy of a Program in Memory.md (100%) rename published/{ => 201801}/20090718 Vmware Linux Guest Add a New Hard Disk Without Rebooting Guest.md (100%) rename published/{ => 201801}/20111124 How to find hidden processes and ports on Linux-Unix-Windows.md (100%) rename published/{ => 201801}/20120611 30 Handy Bash Shell Aliases For Linux - Unix - Mac OS X.md (100%) rename published/{ => 201801}/20121211 Python Nmon Analyzer- moving away from excel macros.md (100%) rename published/{ => 201801}/20140210 Three steps to learning GDB.md (100%) rename published/{ => 201801}/20160117 How to use curl command with proxy username-password on Linux- Unix.md (100%) rename published/{ => 201801}/20160625 Trying out LXD containers on our Ubuntu.md (100%) rename published/{ => 201801}/20160808 Top 10 Command Line Games For Linux.md (100%) rename published/{ => 201801}/20161004 What happens when you start a process on Linux.md (100%) rename published/{ => 201801}/20170131 Book review Ours to Hack and to Own.md (100%) rename published/{ => 201801}/20170209 INTRODUCING DOCKER SECRETS MANAGEMENT.md (100%) rename published/{ => 201801}/20170319 ftrace trace your kernel functions.md (100%) rename published/{ => 201801}/20170426 Important Docker commands for Beginners.md (100%) rename published/{ => 201801}/20170502 A beginner-s guide to Raspberry Pi 3.md (100%) rename published/{ => 201801}/20170512 Which Official Ubuntu Flavor Is Best for You.md (100%) rename published/{ => 201801}/20170515 Commands to check System & Hardware Information.md (100%) rename published/{ => 201801}/20170524 View Counting at Reddit.md (100%) rename published/{ => 201801}/20170524 Working with Vi-Vim Editor - Advanced concepts.md (100%) rename published/{ => 201801}/20170526 Creating a YUM repository from ISO - Online repo.md (100%) rename published/{ => 201801}/20170607 Why Car Companies Are Hiring Computer Security Experts.md (100%) rename published/{ => 201801}/20170802 Creating SWAP partition using FDISK - FALLOCATE commands.md (100%) rename published/{ => 201801}/20170804 Add speech to your Fedora system.md (100%) rename published/{ => 201801}/20170820 How To Display Date And Time In History Command.md (100%) rename published/{ => 201801}/20170828 How To Use YUM History Command To Rollback An Updates In RHEL-CentOS Systems.md (100%) rename published/{ => 201801}/20170915 12 ip Command Examples for Linux Users.md (100%) rename published/{ => 201801}/20170915 Fake A Hollywood Hacker Screen in Linux Terminal.md (100%) rename published/{ => 201801}/20170916 How To Auto Logout Inactive Users After A Period Of Time In Linux.md (100%) rename published/{ => 201801}/20170918 3 text editor alternatives to Emacs and Vim.md (100%) rename published/{ => 201801}/20170918 Linux fmt command - usage and examples.md (100%) rename published/{ => 201801}/20170919 What Are Bitcoins.md (100%) rename published/{ => 201801}/20170920 Easy APT Repository - Iain R. Learmonth.md (100%) rename published/{ => 201801}/20170921 Mastering file searches on Linux.md (100%) rename published/{ => 201801}/20170924 Simulate System Loads.md (100%) rename published/{ => 201801}/20170925 A Commandline Fuzzy Search Tool For Linux.md (100%) rename published/{ => 201801}/20170925 Linux Free Command Explained for Beginners (6 Examples).md (100%) rename published/{ => 201801}/20170927 How To Easily Find Awesome Projects And Resources Hosted In GitHub.md (100%) rename published/{ => 201801}/20170927 Microservices and containers- 5 pitfalls to avoid.md (100%) rename published/{ => 201801}/20171002 Connect To Wifi From The Linux Command Line.md (100%) rename published/{ => 201801}/20171004 How To Create A Video From PDF Files In Linux.md (100%) rename published/{ => 201801}/20171005 python-hwinfo - Display Summary Of Hardware Information In Linux.md (100%) rename published/{ => 201801}/20171008 The most important Firefox command line options.md (100%) rename published/{ => 201801}/20171011 What is a firewall.md (100%) rename published/{ => 201801}/20171012 Install and Use YouTube-DL on Ubuntu 16.04.md (100%) rename published/{ => 201801}/20171013 Get Your Weather Forecast From the Linux CLI.md (100%) rename published/{ => 201801}/20171016 Fixing vim in Debian - There and back again.md (100%) rename published/{ => 201801}/20171017 check_mk error Cannot fetch deployment URL via curl error.md (100%) rename published/{ => 201801}/20171019 3 Simple Excellent Linux Network Monitors.md (100%) rename published/{ => 201801}/20171024 Run Linux On Android Devices, No Rooting Required.md (100%) rename published/{ => 201801}/20171028 Let Us Play Piano In Terminal Using Our PC Keyboard.md (100%) rename published/{ => 201801}/20171030 How To Create Custom Ubuntu Live CD Image.md (100%) rename published/{ => 201801}/20171031 Migrating to Linux- An Introduction.md (100%) rename published/{ => 201801}/20171106 Autorandr- automatically adjust screen layout.md (100%) rename published/{ => 201801}/20171107 How To Protect Server Against Brute Force Attacks With Fail2ban On Linux.md (100%) rename published/{ => 201801}/20171107 The long goodbye to C.md (100%) rename published/{ => 201801}/20171109 Learn how to use tcpdump command with examples.md (100%) rename published/{ => 201801}/20171112 Love Your Bugs.md (100%) rename published/{ => 201801}/20171114 Restore Corrupted USB Drive To Original State In Linux.md (100%) rename published/{ => 201801}/20171115 How to Fix the ‘No Space Left on Device- Error on Linux.md (100%) rename published/{ => 201801}/20171115 Security Jobs Are Hot Get Trained and Get Noticed.md (100%) rename published/{ => 201801}/20171119 10 Best LaTeX Editors For Linux.md (100%) rename published/{ => 201801}/20171120 Adopting Kubernetes step by step.md (100%) rename published/{ => 201801}/20171120 Save Files Directly To Google Drive And Download 10 Times Faster.md (100%) rename published/{ => 201801}/20171123 Check Cryptocurrency Prices From Commandline.md (100%) rename published/{ => 201801}/20171127 Migrating to Linux Disks Files and Filesystems.md (100%) rename published/{ => 201801}/20171128 A generic introduction to Gitlab CI.md (100%) rename published/{ => 201801}/20171201 Launching an Open Source Project A Free Guide.md (100%) rename published/{ => 201801}/20171205 How to Use the Date Command in Linux.md (100%) rename published/{ => 201801}/20171205 Using sudo to delegate permissions in Linux.md (100%) rename published/{ => 201801}/20171207 Cheat – A Collection Of Practical Linux Command Examples.md (100%) rename published/{ => 201801}/20171207 How To Find Files Based On their Permissions.md (100%) rename published/{ => 201801}/20171212 How to Search PDF Files from the Terminal with pdfgrep.md (100%) rename published/{ => 201801}/20171213 How To Allow-Permit User To Access A Specific File or Folder In Linux Using ACL.md (100%) rename published/{ => 201801}/20171214 A step-by-step guide to building open culture.md (100%) rename published/{ => 201801}/20171214 How to Install Moodle on Ubuntu 16.04.md (100%) rename published/{ => 201801}/20171214 How to squeeze the most out of Linux file compression.md (100%) rename published/{ => 201801}/20171214 The Most Famous Classic Text-based Adventure Game.md (100%) rename published/{ => 201801}/20171215 5 of the Best Bitcoin Clients for Linux.md (100%) rename published/{ => 201801}/20171215 How to find and tar files into a tar ball.md (100%) rename published/{ => 201801}/20171216 Saving window position in Xfce session.md (100%) rename published/{ => 201801}/20171218 How to Create a .Desktop File For Your Application in Linux.md (100%) rename published/{ => 201801}/20171219 Migrating to Linux- Graphical Environments.md (100%) rename published/{ => 201801}/20171219 Surf anonymously- Learn to install TOR network on Linux.md (100%) rename published/{ => 201801}/20171219 The Linux commands you should NEVER use.md (100%) rename published/{ => 201801}/20171220 The current state of kernel page-table isolation.md (100%) rename published/{ => 201801}/20171226 Check Linux filesystem for errors- FSCK command with examples.md (100%) rename published/{ => 201801}/20171226 How to Configure Linux for Children.md (100%) rename published/{ => 201801}/20171226 How to use-run bash aliases over ssh based session.md (100%) rename published/{ => 201801}/20171227 Best Programming Languages To Learn In 2018.md (100%) rename published/{ => 201801}/20171228 How to exclude file when using scp command recursively.md (100%) rename published/{ => 201801}/20171229 Set Ubuntu Derivatives Back to Default with Resetter.md (100%) rename published/{ => 201801}/20171230 How To Sync Time Between Linux And Windows Dual Boot.md (100%) rename published/{ => 201801}/20180101 The mysterious case of the Linux Page Table Isolation patches.md (100%) rename published/{ => 201801}/20180103 Linux-Unix desktop fun- Simulates the display from -The Matrix.md (100%) rename published/{ => 201801}/20180104 4 artificial intelligence trends to watch.md (100%) rename published/{ => 201801}/20180105 yum find out path where is package installed to on CentOS-RHEL.md (100%) rename published/{ => 201801}/20180112 City of Barcelona Kicks Out Microsoft in Favor of Linux and Open Source.md (100%) rename published/{ => 201801}/20180119 No More Ubuntu Debian is the New Choice For Googles In-house Linux Distribution.md (100%) rename published/{ => 201801}/20180123 What Is bashrc and Why Should You Edit It.md (100%) diff --git a/published/20090127 Anatomy of a Program in Memory.md b/published/201801/20090127 Anatomy of a Program in Memory.md similarity index 100% rename from published/20090127 Anatomy of a Program in Memory.md rename to published/201801/20090127 Anatomy of a Program in Memory.md diff --git a/published/20090718 Vmware Linux Guest Add a New Hard Disk Without Rebooting Guest.md b/published/201801/20090718 Vmware Linux Guest Add a New Hard Disk Without Rebooting Guest.md similarity index 100% rename from published/20090718 Vmware Linux Guest Add a New Hard Disk Without Rebooting Guest.md rename to published/201801/20090718 Vmware Linux Guest Add a New Hard Disk Without Rebooting Guest.md diff --git a/published/20111124 How to find hidden processes and ports on Linux-Unix-Windows.md b/published/201801/20111124 How to find hidden processes and ports on Linux-Unix-Windows.md similarity index 100% rename from published/20111124 How to find hidden processes and ports on Linux-Unix-Windows.md rename to published/201801/20111124 How to find hidden processes and ports on Linux-Unix-Windows.md diff --git a/published/20120611 30 Handy Bash Shell Aliases For Linux - Unix - Mac OS X.md b/published/201801/20120611 30 Handy Bash Shell Aliases For Linux - Unix - Mac OS X.md similarity index 100% rename from published/20120611 30 Handy Bash Shell Aliases For Linux - Unix - Mac OS X.md rename to published/201801/20120611 30 Handy Bash Shell Aliases For Linux - Unix - Mac OS X.md diff --git a/published/20121211 Python Nmon Analyzer- moving away from excel macros.md b/published/201801/20121211 Python Nmon Analyzer- moving away from excel macros.md similarity index 100% rename from published/20121211 Python Nmon Analyzer- moving away from excel macros.md rename to published/201801/20121211 Python Nmon Analyzer- moving away from excel macros.md diff --git a/published/20140210 Three steps to learning GDB.md b/published/201801/20140210 Three steps to learning GDB.md similarity index 100% rename from published/20140210 Three steps to learning GDB.md rename to published/201801/20140210 Three steps to learning GDB.md diff --git a/published/20160117 How to use curl command with proxy username-password on Linux- Unix.md b/published/201801/20160117 How to use curl command with proxy username-password on Linux- Unix.md similarity index 100% rename from published/20160117 How to use curl command with proxy username-password on Linux- Unix.md rename to published/201801/20160117 How to use curl command with proxy username-password on Linux- Unix.md diff --git a/published/20160625 Trying out LXD containers on our Ubuntu.md b/published/201801/20160625 Trying out LXD containers on our Ubuntu.md similarity index 100% rename from published/20160625 Trying out LXD containers on our Ubuntu.md rename to published/201801/20160625 Trying out LXD containers on our Ubuntu.md diff --git a/published/20160808 Top 10 Command Line Games For Linux.md b/published/201801/20160808 Top 10 Command Line Games For Linux.md similarity index 100% rename from published/20160808 Top 10 Command Line Games For Linux.md rename to published/201801/20160808 Top 10 Command Line Games For Linux.md diff --git a/published/20161004 What happens when you start a process on Linux.md b/published/201801/20161004 What happens when you start a process on Linux.md similarity index 100% rename from published/20161004 What happens when you start a process on Linux.md rename to published/201801/20161004 What happens when you start a process on Linux.md diff --git a/published/20170131 Book review Ours to Hack and to Own.md b/published/201801/20170131 Book review Ours to Hack and to Own.md similarity index 100% rename from published/20170131 Book review Ours to Hack and to Own.md rename to published/201801/20170131 Book review Ours to Hack and to Own.md diff --git a/published/20170209 INTRODUCING DOCKER SECRETS MANAGEMENT.md b/published/201801/20170209 INTRODUCING DOCKER SECRETS MANAGEMENT.md similarity index 100% rename from published/20170209 INTRODUCING DOCKER SECRETS MANAGEMENT.md rename to published/201801/20170209 INTRODUCING DOCKER SECRETS MANAGEMENT.md diff --git a/published/20170319 ftrace trace your kernel functions.md b/published/201801/20170319 ftrace trace your kernel functions.md similarity index 100% rename from published/20170319 ftrace trace your kernel functions.md rename to published/201801/20170319 ftrace trace your kernel functions.md diff --git a/published/20170426 Important Docker commands for Beginners.md b/published/201801/20170426 Important Docker commands for Beginners.md similarity index 100% rename from published/20170426 Important Docker commands for Beginners.md rename to published/201801/20170426 Important Docker commands for Beginners.md diff --git a/published/20170502 A beginner-s guide to Raspberry Pi 3.md b/published/201801/20170502 A beginner-s guide to Raspberry Pi 3.md similarity index 100% rename from published/20170502 A beginner-s guide to Raspberry Pi 3.md rename to published/201801/20170502 A beginner-s guide to Raspberry Pi 3.md diff --git a/published/20170512 Which Official Ubuntu Flavor Is Best for You.md b/published/201801/20170512 Which Official Ubuntu Flavor Is Best for You.md similarity index 100% rename from published/20170512 Which Official Ubuntu Flavor Is Best for You.md rename to published/201801/20170512 Which Official Ubuntu Flavor Is Best for You.md diff --git a/published/20170515 Commands to check System & Hardware Information.md b/published/201801/20170515 Commands to check System & Hardware Information.md similarity index 100% rename from published/20170515 Commands to check System & Hardware Information.md rename to published/201801/20170515 Commands to check System & Hardware Information.md diff --git a/published/20170524 View Counting at Reddit.md b/published/201801/20170524 View Counting at Reddit.md similarity index 100% rename from published/20170524 View Counting at Reddit.md rename to published/201801/20170524 View Counting at Reddit.md diff --git a/published/20170524 Working with Vi-Vim Editor - Advanced concepts.md b/published/201801/20170524 Working with Vi-Vim Editor - Advanced concepts.md similarity index 100% rename from published/20170524 Working with Vi-Vim Editor - Advanced concepts.md rename to published/201801/20170524 Working with Vi-Vim Editor - Advanced concepts.md diff --git a/published/20170526 Creating a YUM repository from ISO - Online repo.md b/published/201801/20170526 Creating a YUM repository from ISO - Online repo.md similarity index 100% rename from published/20170526 Creating a YUM repository from ISO - Online repo.md rename to published/201801/20170526 Creating a YUM repository from ISO - Online repo.md diff --git a/published/20170607 Why Car Companies Are Hiring Computer Security Experts.md b/published/201801/20170607 Why Car Companies Are Hiring Computer Security Experts.md similarity index 100% rename from published/20170607 Why Car Companies Are Hiring Computer Security Experts.md rename to published/201801/20170607 Why Car Companies Are Hiring Computer Security Experts.md diff --git a/published/20170802 Creating SWAP partition using FDISK - FALLOCATE commands.md b/published/201801/20170802 Creating SWAP partition using FDISK - FALLOCATE commands.md similarity index 100% rename from published/20170802 Creating SWAP partition using FDISK - FALLOCATE commands.md rename to published/201801/20170802 Creating SWAP partition using FDISK - FALLOCATE commands.md diff --git a/published/20170804 Add speech to your Fedora system.md b/published/201801/20170804 Add speech to your Fedora system.md similarity index 100% rename from published/20170804 Add speech to your Fedora system.md rename to published/201801/20170804 Add speech to your Fedora system.md diff --git a/published/20170820 How To Display Date And Time In History Command.md b/published/201801/20170820 How To Display Date And Time In History Command.md similarity index 100% rename from published/20170820 How To Display Date And Time In History Command.md rename to published/201801/20170820 How To Display Date And Time In History Command.md diff --git a/published/20170828 How To Use YUM History Command To Rollback An Updates In RHEL-CentOS Systems.md b/published/201801/20170828 How To Use YUM History Command To Rollback An Updates In RHEL-CentOS Systems.md similarity index 100% rename from published/20170828 How To Use YUM History Command To Rollback An Updates In RHEL-CentOS Systems.md rename to published/201801/20170828 How To Use YUM History Command To Rollback An Updates In RHEL-CentOS Systems.md diff --git a/published/20170915 12 ip Command Examples for Linux Users.md b/published/201801/20170915 12 ip Command Examples for Linux Users.md similarity index 100% rename from published/20170915 12 ip Command Examples for Linux Users.md rename to published/201801/20170915 12 ip Command Examples for Linux Users.md diff --git a/published/20170915 Fake A Hollywood Hacker Screen in Linux Terminal.md b/published/201801/20170915 Fake A Hollywood Hacker Screen in Linux Terminal.md similarity index 100% rename from published/20170915 Fake A Hollywood Hacker Screen in Linux Terminal.md rename to published/201801/20170915 Fake A Hollywood Hacker Screen in Linux Terminal.md diff --git a/published/20170916 How To Auto Logout Inactive Users After A Period Of Time In Linux.md b/published/201801/20170916 How To Auto Logout Inactive Users After A Period Of Time In Linux.md similarity index 100% rename from published/20170916 How To Auto Logout Inactive Users After A Period Of Time In Linux.md rename to published/201801/20170916 How To Auto Logout Inactive Users After A Period Of Time In Linux.md diff --git a/published/20170918 3 text editor alternatives to Emacs and Vim.md b/published/201801/20170918 3 text editor alternatives to Emacs and Vim.md similarity index 100% rename from published/20170918 3 text editor alternatives to Emacs and Vim.md rename to published/201801/20170918 3 text editor alternatives to Emacs and Vim.md diff --git a/published/20170918 Linux fmt command - usage and examples.md b/published/201801/20170918 Linux fmt command - usage and examples.md similarity index 100% rename from published/20170918 Linux fmt command - usage and examples.md rename to published/201801/20170918 Linux fmt command - usage and examples.md diff --git a/published/20170919 What Are Bitcoins.md b/published/201801/20170919 What Are Bitcoins.md similarity index 100% rename from published/20170919 What Are Bitcoins.md rename to published/201801/20170919 What Are Bitcoins.md diff --git a/published/20170920 Easy APT Repository - Iain R. Learmonth.md b/published/201801/20170920 Easy APT Repository - Iain R. Learmonth.md similarity index 100% rename from published/20170920 Easy APT Repository - Iain R. Learmonth.md rename to published/201801/20170920 Easy APT Repository - Iain R. Learmonth.md diff --git a/published/20170921 Mastering file searches on Linux.md b/published/201801/20170921 Mastering file searches on Linux.md similarity index 100% rename from published/20170921 Mastering file searches on Linux.md rename to published/201801/20170921 Mastering file searches on Linux.md diff --git a/published/20170924 Simulate System Loads.md b/published/201801/20170924 Simulate System Loads.md similarity index 100% rename from published/20170924 Simulate System Loads.md rename to published/201801/20170924 Simulate System Loads.md diff --git a/published/20170925 A Commandline Fuzzy Search Tool For Linux.md b/published/201801/20170925 A Commandline Fuzzy Search Tool For Linux.md similarity index 100% rename from published/20170925 A Commandline Fuzzy Search Tool For Linux.md rename to published/201801/20170925 A Commandline Fuzzy Search Tool For Linux.md diff --git a/published/20170925 Linux Free Command Explained for Beginners (6 Examples).md b/published/201801/20170925 Linux Free Command Explained for Beginners (6 Examples).md similarity index 100% rename from published/20170925 Linux Free Command Explained for Beginners (6 Examples).md rename to published/201801/20170925 Linux Free Command Explained for Beginners (6 Examples).md diff --git a/published/20170927 How To Easily Find Awesome Projects And Resources Hosted In GitHub.md b/published/201801/20170927 How To Easily Find Awesome Projects And Resources Hosted In GitHub.md similarity index 100% rename from published/20170927 How To Easily Find Awesome Projects And Resources Hosted In GitHub.md rename to published/201801/20170927 How To Easily Find Awesome Projects And Resources Hosted In GitHub.md diff --git a/published/20170927 Microservices and containers- 5 pitfalls to avoid.md b/published/201801/20170927 Microservices and containers- 5 pitfalls to avoid.md similarity index 100% rename from published/20170927 Microservices and containers- 5 pitfalls to avoid.md rename to published/201801/20170927 Microservices and containers- 5 pitfalls to avoid.md diff --git a/published/20171002 Connect To Wifi From The Linux Command Line.md b/published/201801/20171002 Connect To Wifi From The Linux Command Line.md similarity index 100% rename from published/20171002 Connect To Wifi From The Linux Command Line.md rename to published/201801/20171002 Connect To Wifi From The Linux Command Line.md diff --git a/published/20171004 How To Create A Video From PDF Files In Linux.md b/published/201801/20171004 How To Create A Video From PDF Files In Linux.md similarity index 100% rename from published/20171004 How To Create A Video From PDF Files In Linux.md rename to published/201801/20171004 How To Create A Video From PDF Files In Linux.md diff --git a/published/20171005 python-hwinfo - Display Summary Of Hardware Information In Linux.md b/published/201801/20171005 python-hwinfo - Display Summary Of Hardware Information In Linux.md similarity index 100% rename from published/20171005 python-hwinfo - Display Summary Of Hardware Information In Linux.md rename to published/201801/20171005 python-hwinfo - Display Summary Of Hardware Information In Linux.md diff --git a/published/20171008 The most important Firefox command line options.md b/published/201801/20171008 The most important Firefox command line options.md similarity index 100% rename from published/20171008 The most important Firefox command line options.md rename to published/201801/20171008 The most important Firefox command line options.md diff --git a/published/20171011 What is a firewall.md b/published/201801/20171011 What is a firewall.md similarity index 100% rename from published/20171011 What is a firewall.md rename to published/201801/20171011 What is a firewall.md diff --git a/published/20171012 Install and Use YouTube-DL on Ubuntu 16.04.md b/published/201801/20171012 Install and Use YouTube-DL on Ubuntu 16.04.md similarity index 100% rename from published/20171012 Install and Use YouTube-DL on Ubuntu 16.04.md rename to published/201801/20171012 Install and Use YouTube-DL on Ubuntu 16.04.md diff --git a/published/20171013 Get Your Weather Forecast From the Linux CLI.md b/published/201801/20171013 Get Your Weather Forecast From the Linux CLI.md similarity index 100% rename from published/20171013 Get Your Weather Forecast From the Linux CLI.md rename to published/201801/20171013 Get Your Weather Forecast From the Linux CLI.md diff --git a/published/20171016 Fixing vim in Debian - There and back again.md b/published/201801/20171016 Fixing vim in Debian - There and back again.md similarity index 100% rename from published/20171016 Fixing vim in Debian - There and back again.md rename to published/201801/20171016 Fixing vim in Debian - There and back again.md diff --git a/published/20171017 check_mk error Cannot fetch deployment URL via curl error.md b/published/201801/20171017 check_mk error Cannot fetch deployment URL via curl error.md similarity index 100% rename from published/20171017 check_mk error Cannot fetch deployment URL via curl error.md rename to published/201801/20171017 check_mk error Cannot fetch deployment URL via curl error.md diff --git a/published/20171019 3 Simple Excellent Linux Network Monitors.md b/published/201801/20171019 3 Simple Excellent Linux Network Monitors.md similarity index 100% rename from published/20171019 3 Simple Excellent Linux Network Monitors.md rename to published/201801/20171019 3 Simple Excellent Linux Network Monitors.md diff --git a/published/20171024 Run Linux On Android Devices, No Rooting Required.md b/published/201801/20171024 Run Linux On Android Devices, No Rooting Required.md similarity index 100% rename from published/20171024 Run Linux On Android Devices, No Rooting Required.md rename to published/201801/20171024 Run Linux On Android Devices, No Rooting Required.md diff --git a/published/20171028 Let Us Play Piano In Terminal Using Our PC Keyboard.md b/published/201801/20171028 Let Us Play Piano In Terminal Using Our PC Keyboard.md similarity index 100% rename from published/20171028 Let Us Play Piano In Terminal Using Our PC Keyboard.md rename to published/201801/20171028 Let Us Play Piano In Terminal Using Our PC Keyboard.md diff --git a/published/20171030 How To Create Custom Ubuntu Live CD Image.md b/published/201801/20171030 How To Create Custom Ubuntu Live CD Image.md similarity index 100% rename from published/20171030 How To Create Custom Ubuntu Live CD Image.md rename to published/201801/20171030 How To Create Custom Ubuntu Live CD Image.md diff --git a/published/20171031 Migrating to Linux- An Introduction.md b/published/201801/20171031 Migrating to Linux- An Introduction.md similarity index 100% rename from published/20171031 Migrating to Linux- An Introduction.md rename to published/201801/20171031 Migrating to Linux- An Introduction.md diff --git a/published/20171106 Autorandr- automatically adjust screen layout.md b/published/201801/20171106 Autorandr- automatically adjust screen layout.md similarity index 100% rename from published/20171106 Autorandr- automatically adjust screen layout.md rename to published/201801/20171106 Autorandr- automatically adjust screen layout.md diff --git a/published/20171107 How To Protect Server Against Brute Force Attacks With Fail2ban On Linux.md b/published/201801/20171107 How To Protect Server Against Brute Force Attacks With Fail2ban On Linux.md similarity index 100% rename from published/20171107 How To Protect Server Against Brute Force Attacks With Fail2ban On Linux.md rename to published/201801/20171107 How To Protect Server Against Brute Force Attacks With Fail2ban On Linux.md diff --git a/published/20171107 The long goodbye to C.md b/published/201801/20171107 The long goodbye to C.md similarity index 100% rename from published/20171107 The long goodbye to C.md rename to published/201801/20171107 The long goodbye to C.md diff --git a/published/20171109 Learn how to use tcpdump command with examples.md b/published/201801/20171109 Learn how to use tcpdump command with examples.md similarity index 100% rename from published/20171109 Learn how to use tcpdump command with examples.md rename to published/201801/20171109 Learn how to use tcpdump command with examples.md diff --git a/published/20171112 Love Your Bugs.md b/published/201801/20171112 Love Your Bugs.md similarity index 100% rename from published/20171112 Love Your Bugs.md rename to published/201801/20171112 Love Your Bugs.md diff --git a/published/20171114 Restore Corrupted USB Drive To Original State In Linux.md b/published/201801/20171114 Restore Corrupted USB Drive To Original State In Linux.md similarity index 100% rename from published/20171114 Restore Corrupted USB Drive To Original State In Linux.md rename to published/201801/20171114 Restore Corrupted USB Drive To Original State In Linux.md diff --git a/published/20171115 How to Fix the ‘No Space Left on Device- Error on Linux.md b/published/201801/20171115 How to Fix the ‘No Space Left on Device- Error on Linux.md similarity index 100% rename from published/20171115 How to Fix the ‘No Space Left on Device- Error on Linux.md rename to published/201801/20171115 How to Fix the ‘No Space Left on Device- Error on Linux.md diff --git a/published/20171115 Security Jobs Are Hot Get Trained and Get Noticed.md b/published/201801/20171115 Security Jobs Are Hot Get Trained and Get Noticed.md similarity index 100% rename from published/20171115 Security Jobs Are Hot Get Trained and Get Noticed.md rename to published/201801/20171115 Security Jobs Are Hot Get Trained and Get Noticed.md diff --git a/published/20171119 10 Best LaTeX Editors For Linux.md b/published/201801/20171119 10 Best LaTeX Editors For Linux.md similarity index 100% rename from published/20171119 10 Best LaTeX Editors For Linux.md rename to published/201801/20171119 10 Best LaTeX Editors For Linux.md diff --git a/published/20171120 Adopting Kubernetes step by step.md b/published/201801/20171120 Adopting Kubernetes step by step.md similarity index 100% rename from published/20171120 Adopting Kubernetes step by step.md rename to published/201801/20171120 Adopting Kubernetes step by step.md diff --git a/published/20171120 Save Files Directly To Google Drive And Download 10 Times Faster.md b/published/201801/20171120 Save Files Directly To Google Drive And Download 10 Times Faster.md similarity index 100% rename from published/20171120 Save Files Directly To Google Drive And Download 10 Times Faster.md rename to published/201801/20171120 Save Files Directly To Google Drive And Download 10 Times Faster.md diff --git a/published/20171123 Check Cryptocurrency Prices From Commandline.md b/published/201801/20171123 Check Cryptocurrency Prices From Commandline.md similarity index 100% rename from published/20171123 Check Cryptocurrency Prices From Commandline.md rename to published/201801/20171123 Check Cryptocurrency Prices From Commandline.md diff --git a/published/20171127 Migrating to Linux Disks Files and Filesystems.md b/published/201801/20171127 Migrating to Linux Disks Files and Filesystems.md similarity index 100% rename from published/20171127 Migrating to Linux Disks Files and Filesystems.md rename to published/201801/20171127 Migrating to Linux Disks Files and Filesystems.md diff --git a/published/20171128 A generic introduction to Gitlab CI.md b/published/201801/20171128 A generic introduction to Gitlab CI.md similarity index 100% rename from published/20171128 A generic introduction to Gitlab CI.md rename to published/201801/20171128 A generic introduction to Gitlab CI.md diff --git a/published/20171201 Launching an Open Source Project A Free Guide.md b/published/201801/20171201 Launching an Open Source Project A Free Guide.md similarity index 100% rename from published/20171201 Launching an Open Source Project A Free Guide.md rename to published/201801/20171201 Launching an Open Source Project A Free Guide.md diff --git a/published/20171205 How to Use the Date Command in Linux.md b/published/201801/20171205 How to Use the Date Command in Linux.md similarity index 100% rename from published/20171205 How to Use the Date Command in Linux.md rename to published/201801/20171205 How to Use the Date Command in Linux.md diff --git a/published/20171205 Using sudo to delegate permissions in Linux.md b/published/201801/20171205 Using sudo to delegate permissions in Linux.md similarity index 100% rename from published/20171205 Using sudo to delegate permissions in Linux.md rename to published/201801/20171205 Using sudo to delegate permissions in Linux.md diff --git a/published/20171207 Cheat – A Collection Of Practical Linux Command Examples.md b/published/201801/20171207 Cheat – A Collection Of Practical Linux Command Examples.md similarity index 100% rename from published/20171207 Cheat – A Collection Of Practical Linux Command Examples.md rename to published/201801/20171207 Cheat – A Collection Of Practical Linux Command Examples.md diff --git a/published/20171207 How To Find Files Based On their Permissions.md b/published/201801/20171207 How To Find Files Based On their Permissions.md similarity index 100% rename from published/20171207 How To Find Files Based On their Permissions.md rename to published/201801/20171207 How To Find Files Based On their Permissions.md diff --git a/published/20171212 How to Search PDF Files from the Terminal with pdfgrep.md b/published/201801/20171212 How to Search PDF Files from the Terminal with pdfgrep.md similarity index 100% rename from published/20171212 How to Search PDF Files from the Terminal with pdfgrep.md rename to published/201801/20171212 How to Search PDF Files from the Terminal with pdfgrep.md diff --git a/published/20171213 How To Allow-Permit User To Access A Specific File or Folder In Linux Using ACL.md b/published/201801/20171213 How To Allow-Permit User To Access A Specific File or Folder In Linux Using ACL.md similarity index 100% rename from published/20171213 How To Allow-Permit User To Access A Specific File or Folder In Linux Using ACL.md rename to published/201801/20171213 How To Allow-Permit User To Access A Specific File or Folder In Linux Using ACL.md diff --git a/published/20171214 A step-by-step guide to building open culture.md b/published/201801/20171214 A step-by-step guide to building open culture.md similarity index 100% rename from published/20171214 A step-by-step guide to building open culture.md rename to published/201801/20171214 A step-by-step guide to building open culture.md diff --git a/published/20171214 How to Install Moodle on Ubuntu 16.04.md b/published/201801/20171214 How to Install Moodle on Ubuntu 16.04.md similarity index 100% rename from published/20171214 How to Install Moodle on Ubuntu 16.04.md rename to published/201801/20171214 How to Install Moodle on Ubuntu 16.04.md diff --git a/published/20171214 How to squeeze the most out of Linux file compression.md b/published/201801/20171214 How to squeeze the most out of Linux file compression.md similarity index 100% rename from published/20171214 How to squeeze the most out of Linux file compression.md rename to published/201801/20171214 How to squeeze the most out of Linux file compression.md diff --git a/published/20171214 The Most Famous Classic Text-based Adventure Game.md b/published/201801/20171214 The Most Famous Classic Text-based Adventure Game.md similarity index 100% rename from published/20171214 The Most Famous Classic Text-based Adventure Game.md rename to published/201801/20171214 The Most Famous Classic Text-based Adventure Game.md diff --git a/published/20171215 5 of the Best Bitcoin Clients for Linux.md b/published/201801/20171215 5 of the Best Bitcoin Clients for Linux.md similarity index 100% rename from published/20171215 5 of the Best Bitcoin Clients for Linux.md rename to published/201801/20171215 5 of the Best Bitcoin Clients for Linux.md diff --git a/published/20171215 How to find and tar files into a tar ball.md b/published/201801/20171215 How to find and tar files into a tar ball.md similarity index 100% rename from published/20171215 How to find and tar files into a tar ball.md rename to published/201801/20171215 How to find and tar files into a tar ball.md diff --git a/published/20171216 Saving window position in Xfce session.md b/published/201801/20171216 Saving window position in Xfce session.md similarity index 100% rename from published/20171216 Saving window position in Xfce session.md rename to published/201801/20171216 Saving window position in Xfce session.md diff --git a/published/20171218 How to Create a .Desktop File For Your Application in Linux.md b/published/201801/20171218 How to Create a .Desktop File For Your Application in Linux.md similarity index 100% rename from published/20171218 How to Create a .Desktop File For Your Application in Linux.md rename to published/201801/20171218 How to Create a .Desktop File For Your Application in Linux.md diff --git a/published/20171219 Migrating to Linux- Graphical Environments.md b/published/201801/20171219 Migrating to Linux- Graphical Environments.md similarity index 100% rename from published/20171219 Migrating to Linux- Graphical Environments.md rename to published/201801/20171219 Migrating to Linux- Graphical Environments.md diff --git a/published/20171219 Surf anonymously- Learn to install TOR network on Linux.md b/published/201801/20171219 Surf anonymously- Learn to install TOR network on Linux.md similarity index 100% rename from published/20171219 Surf anonymously- Learn to install TOR network on Linux.md rename to published/201801/20171219 Surf anonymously- Learn to install TOR network on Linux.md diff --git a/published/20171219 The Linux commands you should NEVER use.md b/published/201801/20171219 The Linux commands you should NEVER use.md similarity index 100% rename from published/20171219 The Linux commands you should NEVER use.md rename to published/201801/20171219 The Linux commands you should NEVER use.md diff --git a/published/20171220 The current state of kernel page-table isolation.md b/published/201801/20171220 The current state of kernel page-table isolation.md similarity index 100% rename from published/20171220 The current state of kernel page-table isolation.md rename to published/201801/20171220 The current state of kernel page-table isolation.md diff --git a/published/20171226 Check Linux filesystem for errors- FSCK command with examples.md b/published/201801/20171226 Check Linux filesystem for errors- FSCK command with examples.md similarity index 100% rename from published/20171226 Check Linux filesystem for errors- FSCK command with examples.md rename to published/201801/20171226 Check Linux filesystem for errors- FSCK command with examples.md diff --git a/published/20171226 How to Configure Linux for Children.md b/published/201801/20171226 How to Configure Linux for Children.md similarity index 100% rename from published/20171226 How to Configure Linux for Children.md rename to published/201801/20171226 How to Configure Linux for Children.md diff --git a/published/20171226 How to use-run bash aliases over ssh based session.md b/published/201801/20171226 How to use-run bash aliases over ssh based session.md similarity index 100% rename from published/20171226 How to use-run bash aliases over ssh based session.md rename to published/201801/20171226 How to use-run bash aliases over ssh based session.md diff --git a/published/20171227 Best Programming Languages To Learn In 2018.md b/published/201801/20171227 Best Programming Languages To Learn In 2018.md similarity index 100% rename from published/20171227 Best Programming Languages To Learn In 2018.md rename to published/201801/20171227 Best Programming Languages To Learn In 2018.md diff --git a/published/20171228 How to exclude file when using scp command recursively.md b/published/201801/20171228 How to exclude file when using scp command recursively.md similarity index 100% rename from published/20171228 How to exclude file when using scp command recursively.md rename to published/201801/20171228 How to exclude file when using scp command recursively.md diff --git a/published/20171229 Set Ubuntu Derivatives Back to Default with Resetter.md b/published/201801/20171229 Set Ubuntu Derivatives Back to Default with Resetter.md similarity index 100% rename from published/20171229 Set Ubuntu Derivatives Back to Default with Resetter.md rename to published/201801/20171229 Set Ubuntu Derivatives Back to Default with Resetter.md diff --git a/published/20171230 How To Sync Time Between Linux And Windows Dual Boot.md b/published/201801/20171230 How To Sync Time Between Linux And Windows Dual Boot.md similarity index 100% rename from published/20171230 How To Sync Time Between Linux And Windows Dual Boot.md rename to published/201801/20171230 How To Sync Time Between Linux And Windows Dual Boot.md diff --git a/published/20180101 The mysterious case of the Linux Page Table Isolation patches.md b/published/201801/20180101 The mysterious case of the Linux Page Table Isolation patches.md similarity index 100% rename from published/20180101 The mysterious case of the Linux Page Table Isolation patches.md rename to published/201801/20180101 The mysterious case of the Linux Page Table Isolation patches.md diff --git a/published/20180103 Linux-Unix desktop fun- Simulates the display from -The Matrix.md b/published/201801/20180103 Linux-Unix desktop fun- Simulates the display from -The Matrix.md similarity index 100% rename from published/20180103 Linux-Unix desktop fun- Simulates the display from -The Matrix.md rename to published/201801/20180103 Linux-Unix desktop fun- Simulates the display from -The Matrix.md diff --git a/published/20180104 4 artificial intelligence trends to watch.md b/published/201801/20180104 4 artificial intelligence trends to watch.md similarity index 100% rename from published/20180104 4 artificial intelligence trends to watch.md rename to published/201801/20180104 4 artificial intelligence trends to watch.md diff --git a/published/20180105 yum find out path where is package installed to on CentOS-RHEL.md b/published/201801/20180105 yum find out path where is package installed to on CentOS-RHEL.md similarity index 100% rename from published/20180105 yum find out path where is package installed to on CentOS-RHEL.md rename to published/201801/20180105 yum find out path where is package installed to on CentOS-RHEL.md diff --git a/published/20180112 City of Barcelona Kicks Out Microsoft in Favor of Linux and Open Source.md b/published/201801/20180112 City of Barcelona Kicks Out Microsoft in Favor of Linux and Open Source.md similarity index 100% rename from published/20180112 City of Barcelona Kicks Out Microsoft in Favor of Linux and Open Source.md rename to published/201801/20180112 City of Barcelona Kicks Out Microsoft in Favor of Linux and Open Source.md diff --git a/published/20180119 No More Ubuntu Debian is the New Choice For Googles In-house Linux Distribution.md b/published/201801/20180119 No More Ubuntu Debian is the New Choice For Googles In-house Linux Distribution.md similarity index 100% rename from published/20180119 No More Ubuntu Debian is the New Choice For Googles In-house Linux Distribution.md rename to published/201801/20180119 No More Ubuntu Debian is the New Choice For Googles In-house Linux Distribution.md diff --git a/published/20180123 What Is bashrc and Why Should You Edit It.md b/published/201801/20180123 What Is bashrc and Why Should You Edit It.md similarity index 100% rename from published/20180123 What Is bashrc and Why Should You Edit It.md rename to published/201801/20180123 What Is bashrc and Why Should You Edit It.md From df58793886ef3202c6179822b556f5a765925a5a Mon Sep 17 00:00:00 2001 From: XYenChi <466530436@qq.com> Date: Thu, 1 Feb 2018 16:49:21 +0800 Subject: [PATCH 118/272] translated --- ...171231 Why You Should Still Love Telnet.md | 161 ------------------ ...171231 Why You Should Still Love Telnet.md | 160 +++++++++++++++++ 2 files changed, 160 insertions(+), 161 deletions(-) delete mode 100644 sources/tech/20171231 Why You Should Still Love Telnet.md create mode 100644 translated/tech/20171231 Why You Should Still Love Telnet.md diff --git a/sources/tech/20171231 Why You Should Still Love Telnet.md b/sources/tech/20171231 Why You Should Still Love Telnet.md deleted file mode 100644 index 201ee91bd4..0000000000 --- a/sources/tech/20171231 Why You Should Still Love Telnet.md +++ /dev/null @@ -1,161 +0,0 @@ -XYenChi is translating -Why You Should Still Love Telnet -====== -Telnet, the protocol and the command line tool, were how system administrators used to log into remote servers. However, due to the fact that there is no encryption all communication, including passwords, are sent in plaintext meant that Telnet was abandoned in favour of SSH almost as soon as SSH was created. - -For the purposes of logging into a remote server, you should never, and probably have never considered it. This does not mean that the `telnet` command is not a very useful tool when used for debugging remote connection problems. - -In this guide, we will explore using `telnet` to answer the all too common question, "Why can't I ###### connect‽". - -This frustrated question is usually encountered after installing a application server like a web server, an email server, an ssh server, a Samba server etc, and for some reason, the client won't connect to the server. - -`telnet` isn't going to solve your problem but it will, very quickly, narrow down where you need to start looking to fix your problem. - -`telnet` is a very simple command to use for debugging network related issues and has the syntax: -``` -telnet - -``` - -Because `telnet` will initially simply establish a connection to the port without sending any data it can be used with almost any protocol including encrypted protocols. - -There are four main errors that you will encounter when trying to connect to a problem server. We will look at all four, explore what they mean and look at how you should fix them. - -For this guide we will assume that we have just installed a [Samba][1] server at `samba.example.com` and we can't get a local client to connect to the server. - -### Error 1 - The connection that hangs forever - -First, we need to attempt to connect to the Samba server with `telnet`. This is done with the following command (Samba listens on port 445): -``` -telnet samba.example.com 445 - -``` - -Sometimes, the connection will get to this point stop indefinitely: -``` -telnet samba.example.com 445 -Trying 172.31.25.31... - -``` - -This means that `telnet` has not received any response to its request to establish a connection. This can happen for two reasons: - - 1. There is a router down between you and the server. - 2. There is a firewall dropping your request. - - - -In order to rule out **1.** run a quick [`mtr samba.example.com`][2] to the server. If the server is accessible then it's a firewall (note: it's almost always a firewall). - -Firstly, check if there are any firewall rules on the server itself with the following command `iptables -L -v -n`, if there are none then you will get the following output: -``` -iptables -L -v -n -Chain INPUT (policy ACCEPT 0 packets, 0 bytes) - pkts bytes target prot opt in out source destination - -Chain FORWARD (policy ACCEPT 0 packets, 0 bytes) - pkts bytes target prot opt in out source destination - -Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes) - pkts bytes target prot opt in out source destination - -``` - -If you see anything else then this is likely the problem. In order to check, stop `iptables` for a moment and run `telnet samba.example.com 445` again and see if you can connect. If you still can't connect see if your provider and/or office has a firewall in place that is blocking you. - -### Error 2 - DNS problems - -A DNS issue will occur if the hostname you are using does not resolve to an IP address. The error that you will see is as follows: -``` -telnet samba.example.com 445 -Server lookup failure: samba.example.com:445, Name or service not known - -``` - -The first step here is to substitute the IP address of the server for the hostname. If you can connect to the IP but not the hostname then the problem is the hostname. - -This can happen for many reasons (I have seen all of the following): - - 1. Is the domain registered? Use `whois` to find out if it is. - 2. Is the domain expired? Use `whois` to find out if it is. - 3. Are you using the correct hostname? Use `dig` or `host` to ensure that the hostname you are using resolves to the correct IP. - 4. Is your **A** record correct? Check that you didn 't accidentally create an **A** record for something like `smaba.example.com`. - - - -Always double check the spelling and the correct hostname (is it `samba.example.com` or `samba1.example.com`) as this will often trip you up especially with long, complicated or foreign hostnames. - -### Error 3 - The server isn't listening on that port - -This error occurs when `telnet` is able to reach to the server but there is nothing listening on the port you specified. The error looks like this: -``` -telnet samba.example.com 445 -Trying 172.31.25.31... -telnet: Unable to connect to remote host: Connection refused - -``` - -This can happen for a couple of reasons: - - 1. Are you **sure** you 're connecting to the right server? - 2. Your application server is not listening on the port you think it is. Check exactly what it's doing by running `netstat -plunt` on the server and see what port it is, in fact, listening on. - 3. The application server isn't running. This can happen when the application server exits immediately and silently after you start it. Start the server and run `ps auxf` or `systemctl status application.service` to check it's running. - - - -### Error 4 - The connection was closed by the server - -This error happens when the connection was successful but the application server has a build in security measure that killed the connection as soon as it was made. This error looks like: -``` -telnet samba.example.com 445 -Trying 172.31.25.31... -Connected to samba.example.com. -Escape character is '^]'. -��Connection closed by foreign host. - -``` - -The last line `Connection closed by foreign host.` indicates that the connection was actively terminated by the server. In order to fix this, you need to look at the security configuration of the application server to ensure your IP or user is allowed to connect to it. - -### A successful connection - -This is what a successful `telnet` connection attempt looks like: -``` -telnet samba.example.com 445 -Trying 172.31.25.31... -Connected to samba.example.com. -Escape character is '^]'. - -``` - -The connection will stay open for a while depending on the timeout of the application server you are connected to. - -A telnet connection is closed by typing `CTRL+]` and then when you see the `telnet>` prompt, type "quit" and hit ENTER i.e.: -``` -telnet samba.example.com 445 -Trying 172.31.25.31... -Connected to samba.example.com. -Escape character is '^]'. -^] -telnet> quit -Connection closed. - -``` - -### Conclusion - -There are a lot of reasons that a client application can't connect to a server. The exact reason can be difficult to establish especially when the client is a GUI that offers little or no error information. Using `telnet` and observing the output will allow you to very rapidly narrow down where the problem lies and save you a whole lot of time. - --------------------------------------------------------------------------------- - -via: https://bash-prompt.net/guides/telnet/ - -作者:[Elliot Cooper][a] -译者:[译者ID](https://github.com/译者ID) -校对:[校对者ID](https://github.com/校对者ID) - -本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 - -[a]:https://bash-prompt.net -[1]:https://www.samba.org/ -[2]:https://www.systutorials.com/docs/linux/man/8-mtr/ diff --git a/translated/tech/20171231 Why You Should Still Love Telnet.md b/translated/tech/20171231 Why You Should Still Love Telnet.md new file mode 100644 index 0000000000..c08fe6a7eb --- /dev/null +++ b/translated/tech/20171231 Why You Should Still Love Telnet.md @@ -0,0 +1,160 @@ +Telnet,爱一直在 +====== +Telnet, 是系统管理员登录远程服务器的协议和工具。然而,由于所有的通信都没有加密,包括密码,都是明文发送的。Telnet 在 SSH 被开发出来之后就基本弃用了。 + +登录远程服务器,你可能不会也从未考虑过它。但这并不意味着 `telnet` 命令在调试远程连接问题时不是一个实用的工具。 + +本教程中,我们将探索使用 `telnet` 解决所有常见问题,“我怎么又连不上啦?” + +这种讨厌的问题通常会在安装了像web服务器、邮件服务器、ssh服务器、Samba服务器等诸如此类的事之后遇到,用户无法连接服务器。 + +`telnet` 不会解决问题但可以很快缩小问题的范围。 + +`telnet` 用来调试网络问题的简单命令和语法: +``` +telnet + +``` + +因为 `telnet` 最初通过端口建立连接不会发送任何数据,适用于任何协议包括加密协议。 + +连接问题服务器有四个可能会遇到的主要问题。我们会研究这四个问题,研究他们意味着什么以及如何解决。 + +本教程默认已经在 `samba.example.com` 安装了 [Samba][1] 服务器而且本地客户无法连上服务器。 + +### Error 1 - 连接挂起 + +首先,我们需要试着用 `telnet` 连接 Samba 服务器。使用下列命令 (Samba 监听端口445): +``` +telnet samba.example.com 445 + +``` + +有时连接会莫名停止: +``` +telnet samba.example.com 445 +Trying 172.31.25.31... + +``` + +这意味着 `telnet` 没有收到任何回应来建立连接。有两个可能的原因: + + 1. 你和服务器之间有个路由器宕掉了。 + 2. 防火墙拦截了你的请求。 + + + +为了排除 **1.** 在服务器上运行一个快速 [`mtr samba.example.com`][2] 。如果服务器是可达的那么便是防火墙(注意:防火墙总是存在的)。 + +首先用 `iptables -L -v -n` 命令检查服务器本身有没有防火墙, 没有的话你能看到以下内容: +``` +iptables -L -v -n +Chain INPUT (policy ACCEPT 0 packets, 0 bytes) + pkts bytes target prot opt in out source destination + +Chain FORWARD (policy ACCEPT 0 packets, 0 bytes) + pkts bytes target prot opt in out source destination + +Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes) + pkts bytes target prot opt in out source destination + +``` + +如果你看到其他东西那可能就是问题所在了。为了检验,停止 `iptables` 一下并再次运行 `telnet samba.example.com 445` 看看你是否能连接。如果你还是不能连接看看你的提供商或企业有没有防火墙拦截你。 + +### Error 2 - DNS 问题 + +DNS问题通常发生在你正使用的主机名没有解析到 IP 地址。错误如下: +``` +telnet samba.example.com 445 +Server lookup failure: samba.example.com:445, Name or service not known + +``` + +第一步是把主机名替换成服务器的IP地址。如果你可以连上那么就是主机名的问题。 + +有很多发生的原因(以下是我见过的): + + 1. 域注册了吗?用 `whois` 来检验。 + 2. 域过期了吗?用 `whois` 来检验。 + 3. 是否使用正确的主机名?用 `dig` 或 `host` 来确保你使用的主机名解析到正确的 IP。 + 4. 你的 **A** 记录正确吗?确保你没有偶然创建类似 `smaba.example.com` 的 **A** 记录。 + + + +一定要多检查几次拼写和主机名是否正确(是 `samba.example.com` 还是 `samba1.example.com`)这些经常会困扰你特别是长、难或外来主机名。 + +### Error 3 - 服务器没有侦听端口 + +这种错误发生在 `telnet` 可达服务器但是指定端口没有监听。就像这样: +``` +telnet samba.example.com 445 +Trying 172.31.25.31... +telnet: Unable to connect to remote host: Connection refused + +``` + +有这些原因: + + 1. 你 **确定** 连接的是正确的服务器? + 2. 你的应用服务器没有侦听预期的端口。在服务器上运行 `netstat -plunt` 来查看它究竟在干什么并看哪个端口才是对的,实际正在监听中的。 + 3. 应用服务器没有运行。这可能突然而又悄悄地发生在你启动应用服务器之后。启动服务器运行 `ps auxf` 或 `systemctl status application.service` 查看运行。 + + + +### Error 4 - 连接被服务器关闭 + +这种错误发生在连接成功建立但是应用服务器建立的安全措施一连上就将其结束。错误如下: +``` +telnet samba.example.com 445 +Trying 172.31.25.31... +Connected to samba.example.com. +Escape character is '^]'. +��Connection closed by foreign host. + +``` + +最后一行 `Connection closed by foreign host.` 意味着连接被服务器主动终止。为了修复这个问题,需要看看应用服务器的安全设置确保你的 IP 或用户允许连接。 + +### 成功连接 + +成功的 `telnet` 连接如下: +``` +telnet samba.example.com 445 +Trying 172.31.25.31... +Connected to samba.example.com. +Escape character is '^]'. + +``` + +连接会保持一段时间只要你连接的应用服务器时限没到。 + +输入 `CTRL+]` 中止连接然后当你看到 `telnet>` 提示,输入 "quit" 并点击 ENTER 例: +``` +telnet samba.example.com 445 +Trying 172.31.25.31... +Connected to samba.example.com. +Escape character is '^]'. +^] +telnet> quit +Connection closed. + +``` + +### 总结 + +客户程序连不上服务器的原因有很多。确切原理很难确定特别是当客户是图形用户界面提供很少或没有错误信息。用 `telnet` 并观察输出可以让你很快确定问题所在节约很多时间。 + +-------------------------------------------------------------------------------- + +via: https://bash-prompt.net/guides/telnet/ + +作者:[Elliot Cooper][a] +译者:[XYenChi](https://github.com/XYenChi) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://bash-prompt.net +[1]:https://www.samba.org/ +[2]:https://www.systutorials.com/docs/linux/man/8-mtr/ From aca9ad22e2270c0d17e7743e5a0840b9739ec7db Mon Sep 17 00:00:00 2001 From: wxy Date: Thu, 1 Feb 2018 20:54:15 +0800 Subject: [PATCH 119/272] PRF:20141029 What does an idle CPU do.md @qhwdw --- .../tech/20141029 What does an idle CPU do.md | 50 +++++++++---------- 1 file changed, 24 insertions(+), 26 deletions(-) diff --git a/translated/tech/20141029 What does an idle CPU do.md b/translated/tech/20141029 What does an idle CPU do.md index dad24ae0be..d5259385c5 100644 --- a/translated/tech/20141029 What does an idle CPU do.md +++ b/translated/tech/20141029 What does an idle CPU do.md @@ -1,19 +1,17 @@ -[当 CPU 空闲时它都在做什么?][1] +当 CPU 空闲时它都在做什么? ============================================================ -在 [上篇文章中][2] 我说了操作系统行为的基本原理是,在任何一个给定的时刻,在一个 CPU 上有且只有一个任务是活动的。但是,如果 CPU 无事可做的时候,又会是什么样的呢? +在 [上篇文章中][2] 我说了操作系统行为的基本原理是,*在任何一个给定的时刻*,在一个 CPU 上**有且只有一个任务是活动的**。但是,如果 CPU 无事可做的时候,又会是什么样的呢? -事实证明,这种情况是非常普遍的,对于绝大多数的个人电脑来说,这确实是一种常态:大量的睡眠进程,它们都在等待某种情况下被唤醒,差不多在 100% 的 CPU 时间中,它们都处于虚构的“空闲任务”中。事实上,如果一个普通用户的 CPU 处于持续的繁忙中,它可能意味着有一个错误、bug、或者运行了恶意软件。 +事实证明,这种情况是非常普遍的,对于绝大多数的个人电脑来说,这确实是一种常态:大量的睡眠进程,它们都在等待某种情况下被唤醒,差不多在 100% 的 CPU 时间中,都处于虚构的“空闲任务”中。事实上,如果一个普通用户的 CPU 处于持续的繁忙中,它可能意味着有一个错误、bug、或者运行了恶意软件。 -因为我们不能违反我们的原理,一些任务需要在一个 CPU 上激活。首先是因为,这是一个良好的设计:持续很长时间去遍历内核,检查是否有一个活动任务,这种特殊情况是不明智的做法。最好的设计是没有任何例外的情况。无论何时,你写一个 `if` 语句,Nyan 猫就会叫。其次,我们需要使用空闲的 CPU 去做一些事情,让它们充满活力,并且,你懂得,创建天网卫星计划。 +因为我们不能违反我们的原理,*一些任务需要在一个 CPU 上激活*。首先是因为,这是一个良好的设计:持续很长时间去遍历内核,检查是否*有*一个活动任务,这种特殊情况是不明智的做法。最好的设计是*没有任何例外的情况*。无论何时,你写一个 `if` 语句,Nyan Cat 就会喵喵喵。其次,我们需要使用空闲的 CPU 去做*一些事情*,让它们充满活力,你懂得,就是创建天网计划呗。 -因此,保持这种设计的连续性,并领先于恶魔(devil)一步,操作系统开发者创建了一个空闲任务,当没有其它任务可做时就调度它去运行。我们可以在 Linux 的 [引导进程][3] 中看到,这个空闲任务就是进程 0,它是由计算机打开电源时运行的第一个指令直接派生出来的。它在 [rest_init][4] 中初始化,在 [init_idle_bootup_task][5] 中初始化空闲调度类。 +因此,保持这种设计的连续性,并领先于那些邪恶计划一步,操作系统开发者创建了一个**空闲任务**,当没有其它任务可做时就调度它去运行。我们可以在 Linux 的 [引导过程][3] 中看到,这个空闲任务就是进程 0,它是由计算机打开电源时运行的第一个指令直接派生出来的。它在 [rest_init][4] 中初始化,在 [init_idle_bootup_task][5] 中初始化空闲调度类scheduling class。 -简而言之,Linux 支持像实时进程、普通用户进程、等等的不同调度类。当选择一个进程变成活动任务时,这些类是被优先询问的。通过这种方式,核反应堆的控制代码总是优先于 web 浏览器运行。尽管在通常情况下,这些类返回 `NULL`,意味着它们没有合适的任务需要去运行 —— 它们总是处于睡眠状态。但是空闲调度类,它是持续运行的,从不会失败:它总是返回空闲任务。 +简而言之,Linux 支持像实时进程、普通用户进程等等的不同调度类。当选择一个进程变成活动任务时,这些类按优先级进行查询。通过这种方式,核反应堆的控制代码总是优先于 web 浏览器运行。尽管在通常情况下,这些类返回 `NULL`,意味着它们没有合适的任务需要去运行 —— 它们总是处于睡眠状态。但是空闲调度类,它是持续运行的,从不会失败:它总是返回空闲任务。 -好吧,我们来看一下这个空闲任务到底做了些什么。下面是 [cpu_idle_loop][6],感谢开源能让我们看到它的代码: - -cpu_idle_loop +好吧,我们来看一下这个空闲任务*到底做了些什么*。下面是 [cpu_idle_loop][6],感谢开源能让我们看到它的代码: ``` while (1) { @@ -28,9 +26,9 @@ while (1) { } ``` -我省略了很多的细节,稍后我们将去了解任务切换,但是,如果你阅读了源代码,你就会找到它的要点:由于这里不需要重新调度 —— 改变活动任务,它一直处于空闲状态。以经过的时间来计算,这个循环和操作系统中它的“堂兄弟们”相比,在计算的历史上它是运行的最多的代码片段。对于 Intel 处理器来说,处于空闲状态意味着运行着一个 [halt][7] 指令: +*cpu_idle_loop* -native_halt +我省略了很多的细节,稍后我们将去了解任务切换,但是,如果你阅读了这些源代码,你就会找到它的要点:由于这里不需要重新调度(即改变活动任务),它一直处于空闲状态。以所经历的时间来计算,这个循环和其它操作系统中它的“堂兄弟们”相比,在计算的历史上它是运行的最多的代码片段。对于 Intel 处理器来说,处于空闲状态意味着运行着一个 [halt][7] 指令: ``` static inline void native_halt(void) @@ -39,50 +37,50 @@ static inline void native_halt(void) } ``` -`halt` 指令停止处理器中运行的代码,并将它置于 `halt` 的状态。奇怪的是,全世界各地数以百万计的像 Intel 这样的 CPU 们花费大量的时间让它们处于 `halt` 的状态,直到它们被激活。这并不是高效、节能的做法,这促使芯片制造商们去开发处理器的深度睡眠状态,它意味着更少的功耗和更长的唤醒延迟。内核的 [cpuidle 子系统][8] 是这些节能模式能够产生好处的原因。 +*native_halt* -现在,一旦我们告诉 CPU 去 `halt` 或者睡眠之后,我们需要以某种方式去将它t重新带回(back to life)。如果你读过 [上篇文章][9],(译者注:指的是《你的操作系统什么时候运行?》) 你可能会猜到中断会参与其中,而事实确实如此。中断促使 CPU 离开 `halt` 状态返回到激活状态。因此,将这些拼到一起,下图是当你阅读一个完全呈现的 web 网页时,你的系统主要做的事情: +`hlt` 指令停止处理器中的代码执行,并将它置于 `halt` 的状态。奇怪的是,全世界各地数以百万计的 Intel 类的 CPU 们花费大量的时间让它们处于 `halt` 的状态,甚至它们在通电的时候也是如此。这并不是高效、节能的做法,这促使芯片制造商们去开发处理器的深度睡眠状态,以带来着更少的功耗和更长休眠时间。内核的 [cpuidle 子系统][8] 是这些节能模式能够产生好处的原因。 + +现在,一旦我们告诉 CPU 去 `halt`(睡眠)之后,我们需要以某种方式让它醒来。如果你读过 [上篇文章《你的操作系统什么时候运行?》][9] ,你可能会猜到*中断*会参与其中,而事实确实如此。中断促使 CPU 离开 `halt` 状态返回到激活状态。因此,将这些拼到一起,下图是当你阅读一个完全呈现的 web 网页时,你的系统主要做的事情: ![](https://manybutfinite.com/img/os/idle.png) - +除定时器中断外的其它中断也会使处理器再次发生变化。如果你再次点击一个 web 页面就会产生这种变化,例如:你的鼠标发出一个中断,它的驱动会处理它,并且因为它产生了一个新的输入,突然进程就可运行了。在那个时刻, `need_resched()` 返回 `true`,然后空闲任务因你的浏览器而被踢出而终止运行。 -除定时器中断外的其它中断也会使处理器再次发生变化。如果你再次点击一个 web 页面就会产生这种变化,例如:你的鼠标发出一个中断,它会导致系统去处理它,并且使处理器因为它产生了一个新的输入而突然地可运行。在那个时刻, `need_resched()` 返回 `true`,然后空闲任务因你的浏览器而被踢出终止运行。 - -如果我们阅读这篇文章,而不做任何事情。那么随着时间的推移,这个空闲循环就像下图一样: +如果我们呆呆地看着这篇文章,而不做任何事情。那么随着时间的推移,这个空闲循环就像下图一样: ![](https://manybutfinite.com/img/os/idleCycles.png) -在这个示例中,由内核计划的定时器中断会每 4 毫秒发生一次。这就是滴答周期。也就是说每秒钟将有 250 个滴答,因此,这个滴答速率或者频率是 250 Hz。这是运行在 Intel 处理器上的 Linux 的典型值,而很多人喜欢使用 100 Hz。这是由你构建内核时在 `CONFIG_HZ` 选项中定义的。 +在这个示例中,由内核计划的定时器中断会每 4 毫秒发生一次。这就是滴答tick周期。也就是说每秒钟将有 250 个滴答,因此,这个*滴答速率(频率)*是 250 Hz。这是运行在 Intel 处理器上的 Linux 的典型值,而其它操作系统喜欢使用 100 Hz。这是由你构建内核时在 `CONFIG_HZ` 选项中定义的。 -对于一个空闲 CPU 来说,它看起来似乎是个无意义的工作。如果外部世界没有新的输入,在你的笔记本电脑的电池耗尽之前,CPU 将始终处于这种每秒钟被唤醒 250 次的地狱般折磨的小憩中。如果它运行在一个虚拟机中,那我们正在消耗着宿主机 CPU 的性能和宝贵的时钟周期。 +对于一个*空闲 CPU* 来说,它看起来似乎是个无意义的工作。如果外部世界没有新的输入,在你的笔记本电脑的电池耗尽之前,CPU 将始终处于这种每秒钟被唤醒 250 次的地狱般折磨的小憩中。如果它运行在一个虚拟机中,那我们正在消耗着宿主机 CPU 的性能和宝贵的时钟周期。 -在这里的解决方案是拥有一个 [动态滴答][10] ,因此,当 CPU 处于空闲状态时,定时器中断要么被 [暂停要么被重计划][11],直到内核知道将有事情要做时(例如,一个进程的定时器可能要在 5 秒内过期,因此,我们不能再继续睡眠了),定时器中断才会重新发出。这也被称为无滴答模式。 +在这里的解决方案是 [动态滴答][10],当 CPU 处于空闲状态时,定时器中断被 [暂停或重计划][11],直到内核*知道*将有事情要做时(例如,一个进程的定时器可能要在 5 秒内过期,因此,我们不能再继续睡眠了),定时器中断才会重新发出。这也被称为*无滴答模式*。 -最后,假设在一个系统中你有一个活动进程,例如,一个长周期运行的 CPU 密集型任务。那样几乎就和一个空闲系统是相同的:这些示意图仍然是相同的,只是将空闲任务替换为这个进程,并且描述也是准确的。在那种情况下,每 4 毫秒去中断一次任务仍然是无意义的:它只是操作系统的抖动,甚至会使你的工作变得更慢而已。Linux 也可以在这种单一进程的场景中停止这种固定速率的滴答,这被称为 [adaptive-tick][12] 模式。最终,这种固定速率的滴答可能会 [完全消失][13]。 +最后,假设在一个系统中你有一个*活动进程*,例如,一个长时间运行的 CPU 密集型任务。那样几乎就和一个空闲系统是相同的:这些示意图仍然是相同的,只是将空闲任务替换为这个进程,并且相应的描述也是准确的。在那种情况下,每 4 毫秒去中断一次任务仍然是无意义的:它只是操作系统的性能抖动,甚至会使你的工作变得更慢而已。Linux 也可以在这种单一进程的场景中停止这种固定速率的滴答,这被称为 [自适应滴答][12] 模式。最终,这种固定速率的滴答可能会 [完全消失][13]。 -对于阅读一篇文章来说,CPU 基本是无事可做的。内核的这种空闲行为是操作系统难题的一个重要部分,并且它与我们看到的其它情况非常相似,因此,这将帮助我们构建一个运行中的内核的蓝图。更多的内容将发布在下周的 [RSS][14] 和 [Twitter][15] 上。 +对于阅读一篇文章来说,CPU 基本是无事可做的。内核的这种空闲行为是操作系统难题的一个重要部分,并且它与我们看到的其它情况非常相似,因此,这将帮助我们理解一个运行中的内核。更多的内容将发布在下周的 [RSS][14] 和 [Twitter][15] 上。 -------------------------------------------------------------------------------- -via:https://manybutfinite.com/post/what-does-an-idle-cpu-do/ +via: https://manybutfinite.com/post/what-does-an-idle-cpu-do/ 作者:[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]:https://manybutfinite.com/post/what-does-an-idle-cpu-do/ -[2]:https://manybutfinite.com/post/when-does-your-os-run +[2]:https://linux.cn/article-9095-1.html [3]:https://manybutfinite.com/post/kernel-boot-process [4]:https://github.com/torvalds/linux/blob/v3.17/init/main.c#L393 [5]:https://github.com/torvalds/linux/blob/v3.17/kernel/sched/core.c#L4538 [6]:https://github.com/torvalds/linux/blob/v3.17/kernel/sched/idle.c#L183 [7]:https://github.com/torvalds/linux/blob/v3.17/arch/x86/include/asm/irqflags.h#L52 [8]:http://lwn.net/Articles/384146/ -[9]:https://manybutfinite.com/post/when-does-your-os-run +[9]:https://linux.cn/article-9095-1.html [10]:https://github.com/torvalds/linux/blob/v3.17/Documentation/timers/NO_HZ.txt#L17 [11]:https://github.com/torvalds/linux/blob/v3.17/Documentation/timers/highres.txt#L215 [12]:https://github.com/torvalds/linux/blob/v3.17/Documentation/timers/NO_HZ.txt#L100 From a933f4e6bef6bc7b8bbde83d65fb7dabda25f07a Mon Sep 17 00:00:00 2001 From: wxy Date: Thu, 1 Feb 2018 20:54:45 +0800 Subject: [PATCH 120/272] PUB:20141029 What does an idle CPU do.md @qhwdw https://linux.cn/article-9303-1.html --- .../tech => published}/20141029 What does an idle CPU do.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename {translated/tech => published}/20141029 What does an idle CPU do.md (100%) diff --git a/translated/tech/20141029 What does an idle CPU do.md b/published/20141029 What does an idle CPU do.md similarity index 100% rename from translated/tech/20141029 What does an idle CPU do.md rename to published/20141029 What does an idle CPU do.md From 29f52711dc4a5d4954a2d6242ead9750b6317713 Mon Sep 17 00:00:00 2001 From: geekpi Date: Fri, 2 Feb 2018 08:45:39 +0800 Subject: [PATCH 121/272] translated --- ...new projects to try in COPR for January.md | 85 ------------------- ...new projects to try in COPR for January.md | 83 ++++++++++++++++++ 2 files changed, 83 insertions(+), 85 deletions(-) delete mode 100644 sources/tech/20180124 4 cool new projects to try in COPR for January.md create mode 100644 translated/tech/20180124 4 cool new projects to try in COPR for January.md diff --git a/sources/tech/20180124 4 cool new projects to try in COPR for January.md b/sources/tech/20180124 4 cool new projects to try in COPR for January.md deleted file mode 100644 index 53e8f362a0..0000000000 --- a/sources/tech/20180124 4 cool new projects to try in COPR for January.md +++ /dev/null @@ -1,85 +0,0 @@ -translating---geekpi - -4 cool new projects to try in COPR for January -====== - -![](https://fedoramagazine.org/wp-content/uploads/2017/08/4-copr-945x400.jpg) - -COPR is a [collection][1] of personal repositories for software that isn't carried in Fedora. Some software doesn't conform to standards that allow easy packaging. Or it may not meet other Fedora standards, despite being free and open source. COPR can offer these projects outside the Fedora set of packages. Software in COPR isn't supported by Fedora infrastructure or signed by the project. However, it can be a neat way to try new or experimental software. - -Here's a set of new and interesting projects in COPR. - -### Elisa - -[Elisa][2] is a minimal music player. It lets you browse music by albums, artists or tracks. It automatically detects all playable music in your ~/Music directory, thus it requires no set up at all - neither does it offer any. Currently, Elisa focuses on being a simple music player, so it offers no tools for managing your music collection. - -![][3] - -#### Installation instructions - -The repo currently provides Elisa for Fedora 26, 27 and Rawhide. To install Elisa, use these commands: -``` -sudo dnf copr enable eclipseo/elisa -sudo dnf install elisa -``` - -### Bing Wallpapers - -[Bing Wallpapers][4] is a simple program that downloads Bing's wallpaper of the day and sets it as a desktop wallpaper or a lock screen image. The program can rotate over pictures in its directory in set intervals as well as delete old pictures after a set amount of time. - -#### Installation instructions - -The repo currently provides Bing Wallpapers for Fedora 25, 26, 27 and Rawhide. To install Bing Wallpapers, use these commands: -``` -sudo dnf copr enable julekgwa/Bingwallpapers -sudo dnf install bingwallpapers -``` - -### Polybar - -[Polybar][5] is a tool for creating status bars. It has a lot of customization options as well as built-in functionality to display information about commonly used services, such as systray icons, window title, workspace and desktop panel for [bspwm][6], [i3][7], and more. You can also configure your own modules for your status bar. See [Polybar's wiki][8] for more information about usage and configuration. - -#### Installation instructions - -The repo currently provides Polybar for Fedora 27. To install Polybar, use these commands: -``` -sudo dnf copr enable tomwishaupt/polybar -sudo dnf install polybar -``` - -### Netdata - -[Netdata][9] is a distributed monitoring system. It can run on all your systems including PCs, servers, containers and IoT devices, from which it collects metrics in real time. All the information then can be accessed using netdata's web dashboard. Additionally, Netdata provides pre-configured alarms and notifications for detecting performance issue, as well as templates for creating your own alarms. - -![][10] - -#### Installation instructions - -The repo currently provides netdata for EPEL 7, Fedora 27 and Rawhide. To install netdata, use these commands: -``` -sudo dnf copr enable recteurlp/netdata -sudo dnf install netdata -``` - - --------------------------------------------------------------------------------- - -via: https://fedoramagazine.org/4-cool-new-projects-to-try-in-copr-for-january/ - -作者:[Dominik Turecek][a] -译者:[译者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://copr.fedorainfracloud.org/ -[2]:https://community.kde.org/Elisa -[3]:https://fedoramagazine.org/wp-content/uploads/2018/01/elisa.png -[4]:http://bingwallpapers.lekgoara.com/ -[5]:https://github.com/jaagr/polybar -[6]:https://github.com/baskerville/bspwm -[7]:https://i3wm.org/ -[8]:https://github.com/jaagr/polybar/wiki -[9]:http://my-netdata.io/ -[10]:https://fedoramagazine.org/wp-content/uploads/2018/01/netdata.png diff --git a/translated/tech/20180124 4 cool new projects to try in COPR for January.md b/translated/tech/20180124 4 cool new projects to try in COPR for January.md new file mode 100644 index 0000000000..68b131967f --- /dev/null +++ b/translated/tech/20180124 4 cool new projects to try in COPR for January.md @@ -0,0 +1,83 @@ +一月 COPR 中 4 个新的很酷的项目 +====== + +![](https://fedoramagazine.org/wp-content/uploads/2017/08/4-copr-945x400.jpg) + +COPR 是一个个人软件仓库[集合][1],它们不存在于 Fedora 中。有些软件不符合标准而不容易打包。或者它可能不符合其他的 Fedora 标准,尽管它是免费和开源的。COPR 可以在 Fedora 套件之外提供这些项目。COPR 中的软件不受 Fedora 支持或者由项目自己签名。但是,它是尝试新的或实验性软件的一种很好的方法。 + +这是 COPR 中一系列新的和有趣的项目。 + +### Elisa + +[Elisa][2] 是一个最小的音乐播放器。它可以让你通过专辑、艺术家或曲目浏览音乐。它会自动检测你的 ~/Music 目录中的所有可播放音乐,因此它根本不需要设置 - 它也不提供任何音乐。目前,Elisa 专注于做一个简单的音乐播放器,所以它不提供管理音乐收藏的工具。 + +![][3] + +#### 安装说明 + +仓库目前为 Fedora 26、27 和 Rawhide 提供 Elisa。要安装 Elisa,请使用以下命令: +``` +sudo dnf copr enable eclipseo/elisa +sudo dnf install elisa +``` + +### 必应壁纸 + +[必应壁纸][4]是一个简单的程序,它会下载当日的必应壁纸,并将其设置为桌面壁纸或锁屏图片。该程序可以在设定的时间间隔内轮转目录中的图片,并在一段时间后删除旧图片。 + +#### 安装说明 + +仓库目前为 Fedora 25、26、27 和 Rawhide 提供必应壁纸。要安装必应壁纸,请使用以下命令: +``` +sudo dnf copr enable julekgwa/Bingwallpapers +sudo dnf install bingwallpapers +``` + +### Polybar + +[Polybar][5] 是一个创建状态栏的工具。它有很多自定义选项以及内置的功能来显示常用服务的信息,例如 [bspwm][6]、[i3][7] 的系统托盘图标、窗口标题、工作区和桌面面板等。你也可以为你的状态栏配置你自己的模块。有关使用和配置的更多信息,请参考[ Polybar 的 wiki][8]。 + +#### 安装说明 + +仓库目前为 Fedora 27 提供 Polybar。要安装 Polybar,请使用以下命令: +``` +sudo dnf copr enable tomwishaupt/polybar +sudo dnf install polybar +``` + +### Netdata + +[Netdata][9] 是一个分布式监控系统。它可以运行在包括个人电脑、服务器、容器和物联网设备在内的所有系统上,从中实时收集指标。所有的信息都可以使用 netdata 的 web 面板访问。此外,Netdata 还提供预配置的警报和通知来检测性能问题,以及用于创建自己的警报的模板。 + +![][10] + +#### 安装说明 + +仓库目前提供 EPEL 7、Fedora 27 和 Rawhide 提供 netdata。要安装 netdata,请使用以下命令: +``` +sudo dnf copr enable recteurlp/netdata +sudo dnf install netdata +``` + + +-------------------------------------------------------------------------------- + +via: https://fedoramagazine.org/4-cool-new-projects-to-try-in-copr-for-january/ + +作者:[Dominik Turecek][a] +译者:[geekpi](https://github.com/geekpi) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://fedoramagazine.org +[1]:https://copr.fedorainfracloud.org/ +[2]:https://community.kde.org/Elisa +[3]:https://fedoramagazine.org/wp-content/uploads/2018/01/elisa.png +[4]:http://bingwallpapers.lekgoara.com/ +[5]:https://github.com/jaagr/polybar +[6]:https://github.com/baskerville/bspwm +[7]:https://i3wm.org/ +[8]:https://github.com/jaagr/polybar/wiki +[9]:http://my-netdata.io/ +[10]:https://fedoramagazine.org/wp-content/uploads/2018/01/netdata.png From 13cb63349e331ecd01327871abb5f0193457cffe Mon Sep 17 00:00:00 2001 From: geekpi Date: Fri, 2 Feb 2018 08:52:54 +0800 Subject: [PATCH 122/272] translating --- .../tech/20180130 Use of du - df commands (with examples).md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sources/tech/20180130 Use of du - df commands (with examples).md b/sources/tech/20180130 Use of du - df commands (with examples).md index 5a1d374e3b..ac284b0025 100644 --- a/sources/tech/20180130 Use of du - df commands (with examples).md +++ b/sources/tech/20180130 Use of du - df commands (with examples).md @@ -1,3 +1,5 @@ +translating---geekpi + Use of du & df commands (with examples) ====== In this article I will discuss du & df commands. Both du & df commands are important utilities of Linux system & shows disk usage of Linux filesystem. Here we will share usage of both commands with some examples. From 6f8dc36d115909841fb66d1d469de4c00855f1cf Mon Sep 17 00:00:00 2001 From: qhwdw Date: Fri, 2 Feb 2018 12:35:56 +0800 Subject: [PATCH 123/272] Translated by qhwdw --- .../tech/20171211 A tour of containerd 1.0.md | 48 ------------------- .../tech/20171211 A tour of containerd 1.0.md | 47 ++++++++++++++++++ 2 files changed, 47 insertions(+), 48 deletions(-) delete mode 100644 sources/tech/20171211 A tour of containerd 1.0.md create mode 100644 translated/tech/20171211 A tour of containerd 1.0.md diff --git a/sources/tech/20171211 A tour of containerd 1.0.md b/sources/tech/20171211 A tour of containerd 1.0.md deleted file mode 100644 index 4cf3e2b587..0000000000 --- a/sources/tech/20171211 A tour of containerd 1.0.md +++ /dev/null @@ -1,48 +0,0 @@ -A tour of containerd 1.0 -====== -![containerd][1] - -We have done a few talks in the past on different features of containerd, how it was designed, and some of the problems that we have fixed along the way. Containerd is used by Docker, Kubernetes CRI, and a few other projects but this is a post for people who may not know what containerd actually does within these platforms. I would like to do more posts on the feature set and design of containerd in the future but for now, we will start with the basics. - -I think the container ecosystem can be confusing at times. Especially with the terminology that we use. Whats this? A runtime. And this? A runtime… containerd (pronounced " _container-dee "_) as the name implies, not contain nerd as some would like to troll me with, is a container daemon. It was originally built as an integration point for OCI runtimes like runc but over the past six months it has added a lot of functionality to bring it up to par with the needs of modern container platforms like Docker and orchestration systems like Kubernetes. - -So what do you actually get using containerd? You get push and pull functionality as well as image management. You get container lifecycle APIs to create, execute, and manage containers and their tasks. An entire API dedicated to snapshot management and an openly governed project to depend on. Basically everything that you need to build a container platform without having to deal with the underlying OS details. I think the most important part of containerd is having a versioned and stable API that will have bug fixes and security patches backported. - -![containerd][2] - -Since there is no such thing as Linux containers in the kernel, containers are various kernel features tied together, when you are building a large platform or distributed system you want an abstraction layer between your management code and the syscalls and duct tape of features to run a container. That is where containerd lives. It provides a client a layer of stable types that platforms can build on top of without ever having to drop down to the kernel level. It's so much nicer to work with Container, Task, and Snapshot types than it is to manage calls to clone() or mount(). Balanced with the flexibility to directly interact with the runtime or host-machine, these objects avoid the sacrifice of capabilities that typically come with higher-level abstractions. The result is that easy tasks are simple to complete and hard tasks are possible. - -![containerd][3]Containerd was designed to be used by Docker and Kubernetes as well as any other container system that wants to abstract away syscalls or OS specific functionality to run containers on Linux, Windows, Solaris, or other Operating Systems. With these users in mind, we wanted to make sure that containerd has only what they need and nothing that they don't. Realistically this is impossible but at least that is what we try for. While networking is out of scope for containerd, what it doesn't do lets higher level systems have full control. The reason for this is, when you are building a distributed system, networking is a very central aspect. With SDN and service discovery today, networking is way more platform specific than abstracting away netlink calls on linux. Most of the new overlay networks are route based and require routing tables to be updated each time a new container is created or deleted. Service discovery, DNS, etc all have to be notified of these changes as well. It would be a large chunk of code to be able to support all the different network interfaces, hooks, and integration points to support this if we added networking to containerd. What we did instead is opted for a robust events system inside containerd so that multiple consumers can subscribe to the events that they care about. We also expose a [Task API ][4]that lets users create a running task, have the ability to add interfaces to the network namespace of the container, and then start the container's process without the need for complex hooks in various points of a container's lifecycle. - -Another area that has been added to containerd over the past few months is a complete storage and distribution system that supports both OCI and Docker image formats. You have a complete content addressed storage system across the containerd API that works not only for images but also metadata, checkpoints, and arbitrary data attached to containers. - -We also took the time to [rethink how "graphdrivers" work][5]. These are the overlay or block level filesystems that allow images to have layers and you to perform efficient builds. Graphdrivers were initially written by Solomon and I when we added support for devicemapper. Docker only supported AUFS at the time so we modeled the graphdrivers after the overlay filesystem. However, making a block level filesystem such as devicemapper/lvm act like an overlay filesystem proved to be much harder to do in the long run. The interfaces had to expand over time to support different features than what we originally thought would be needed. With containerd, we took a different approach, make overlay filesystems act like a snapshotter instead of vice versa. This was much easier to do as overlay filesystems provide much more flexibility than snapshotting filesystems like BTRFS, ZFS, and devicemapper as they don't have a strict parent/child relationship. This helped us build out [a smaller interface for the snapshotters][6] while still fulfilling the requirements needed from things [like a builder][7] as well as reduce the amount of code needed, making it much easier to maintain in the long run. - -![][8] - -You can find more details about the architecture of containerd in [Stephen Day's Dec 7th 2017 KubeCon SIG Node presentation][9]. - -In addition to the technical and design changes in the 1.0 codebase, we also switched the containerd [governance model from the long standing BDFL to a Technical Steering Committee][10] giving the community an independent third party resource to rely on. - - --------------------------------------------------------------------------------- - -via: https://blog.docker.com/2017/12/containerd-ga-features-2/ - -作者:[Michael Crosby][a] -译者:[译者ID](https://github.com/译者ID) -校对:[校对者ID](https://github.com/校对者ID) - -本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 - -[a]:https://blog.docker.com/author/michael/ -[1]:https://i0.wp.com/blog.docker.com/wp-content/uploads/950cf948-7c08-4df6-afd9-cc9bc417cabe-6.jpg?resize=400%2C120&ssl=1 -[2]:https://i1.wp.com/blog.docker.com/wp-content/uploads/4a7666e4-ebdb-4a40-b61a-26ac7c3f663e-4.jpg?resize=906%2C470&ssl=1 (containerd) -[3]:https://i1.wp.com/blog.docker.com/wp-content/uploads/2a73a4d8-cd40-4187-851f-6104ae3c12ba-1.jpg?resize=1140%2C680&ssl=1 -[4]:https://github.com/containerd/containerd/blob/master/api/services/tasks/v1/tasks.proto -[5]:https://blog.mobyproject.org/where-are-containerds-graph-drivers-145fc9b7255 -[6]:https://github.com/containerd/containerd/blob/master/api/services/snapshots/v1/snapshots.proto -[7]:https://blog.mobyproject.org/introducing-buildkit-17e056cc5317 -[8]:https://i1.wp.com/blog.docker.com/wp-content/uploads/d0fb5eb9-c561-415d-8d57-e74442a879a2-1.jpg?resize=1140%2C556&ssl=1 -[9]:https://speakerdeck.com/stevvooe/whats-happening-with-containerd-and-the-cri -[10]:https://github.com/containerd/containerd/pull/1748 diff --git a/translated/tech/20171211 A tour of containerd 1.0.md b/translated/tech/20171211 A tour of containerd 1.0.md new file mode 100644 index 0000000000..7b30ccd304 --- /dev/null +++ b/translated/tech/20171211 A tour of containerd 1.0.md @@ -0,0 +1,47 @@ +containerd 1.0 探索之旅 +====== +![containerd][1] + +我们在过去的文章中讨论了一些 containerd 的不同特性,它是如何设计的,以及随着时间推移已经修复的一些问题。Containerd 是被用于 Docker、Kubernetes CRI、以及一些其它的项目,在这些平台中事实上都使用了 containerd,而许多人并不知道 containerd 存在于这些平台之中,这篇文章就是为这些人所写的。我想写更多的关于 containerd 的设计以及特性集方面的文章,但是现在,我们从它的基础知识开始。 + +我认为容器生态系统有时候可能很复杂。尤其是我们所使用的技术。它是什么?一个运行时,还是别的?一个运行时 … containerd(它的发音是 " _container-dee "_)正如它的名字,它是一个容器守护进程,而不是一些人所“传说”的那样。它最初是作为 OCI 运行时(就像 runc 一样)的集成点构建的,在过去的六个月中它增加了许多特性,使其达到了像 Docker 这样的现代容器平台以及像 Kubernetes 这样的编排平台的需求。 + +那么,你使用 containerd 能去做些什么呢?你可以推送或拉取功能以及镜像管理。可以获得容器生命周期 APIs 去创建、运行、以及管理容器和它们的任务。一个完整的专门用于快照管理的 API,以及一个公开管理的项目。如果你需要去构建一个容器平台,基本上你不需要去处理任何底层操作系统细节方面的事情。我认为关于 containerd 中最重要的部分是,它有一个版本化的并且有 bug 修复和安全补丁的稳定 API。 + +![containerd][2] + +由于在内核中并没有太多的用作 Linux 容器的东西,因此容器是多种内核特性捆绑在一起的,当你构建一个大型平台或者分布式系统时,你需要在你的管理代码和系统调用之间构建一个抽象层,然后将这些特性捆绑粘接在一起去运行一个容器。而这个抽象层就是 containerd 的所在之外。它为稳定类型的平台层提供了一个客户端,这样平台可以构建在顶部而无需进入到内核级。因此,可以让使用容器、任务、和快照类型的工作相比通过管理调用去 clone() 或者 mount() 要友好的多。与灵活性相平衡,直接与运行时或者宿主机交互,这些对象避免了常规的高级抽象所带来的性能牺牲。结果是简单的任务很容易完成,而困难的任务也变得更有可能完成。 + +![containerd][3]Containerd 被设计用于 Docker 和 Kubernetes、以及想去抽象出系统调用或者在 Linux、Windows、Solaris、 以及其它的操作系统上特定的功能去运行容器的其它的容器系统。考虑到这些用户的想法,我们希望确保 containerd 只拥有它们所需要的东西,而没有它们不希望的东西。事实上这是不太可能的,但是至少我们想去尝试一下。虽然网络不在 containerd 的范围之内,它并不能做到高级系统完全控制的那些东西。原因是,当你构建一个分布式系统时,网络是非常重要的方面。现在,对于 SDN 和服务发现,在 Linux 上,相比于抽象出 netlink 调用,网络是更特殊的平台。大多数新的网络都是基于路由的,并且每次一个新的容器被创建或者删除时,都会请求更新路由表。服务发现、DNS 等等都需要及时通知到这些改变。如果在 containerd 中添加对网络的管理,为了能够支持不同的网络接口、钩子、以及集成点,将会在 containerd 中增加很大的一块代码。而我们的选择是,在 containerd 中做一个健壮的事件系统,以便于很多的消费者可以去订阅它们所关心的事件。我们也公开发布了一个 [任务 API ][4],它可以让用户去创建一个运行任务,也可以在一个容器的网络命名空间中添加一个接口,以及在一个容器的生命周期中的任何时候,无需复杂的 hooks 来启用容器的进程。 + +在过去的几个月中另一个添加到 containerd 中的领域是完整的存储,以及支持 OCI 和 Docker 镜像格式的分布式系统。你有一个跨 containerd API 的完整的目录地址存储系统,它不仅适用于镜像,也适用于元数据、检查点、以及附加到容器的任何数据。 + +我们也花时间去 [重新考虑如何使用 "图形驱动" 工作][5]。这些是叠加的或者允许镜像分层的块级文件系统,以使你执行的构建更加高效。当我们添加对 devicemapper 的支持时,图形驱动最初是由 Solomon 和我写的。Docker 在那个时候仅支持 AUFS,因此我们在叠加文件系统之后,对图形驱动进行建模。但是,做一个像 devicemapper/lvm 这样的块级文件系统,就如同一个堆叠文件系统一样,从长远来看是非常困难的。这些接口必须基于时间的推移进行扩展,以支持我们最初认为并不需要的那些不同的特性。对于 containerd,我们使用了一个不同的方法,像快照一样做一个堆叠文件系统而不是相反。这样做起来更容易,因为堆叠文件系统比起像 BTRFS、ZFS、以及 devicemapper 这样的文件系统提供了更好的灵活性。因为这些文件系统没有严格的父/子关系。这有助于我们去构建出 [快照的一个小型接口][6],同时还能满足 [构建者][7] 的要求,还能减少了需要的代码数量,从长远来看这样更易于维护。 + +![][8] + +你可以在 [Stephen Day's Dec 7th 2017 KubeCon SIG Node presentation][9]上找到更多关于 containerd 的架构方面的详细资料。 + +除了在 1.0 代码库中的技术和设计上的更改之外,我们也将 [containerd 管理模式从长期 BDFL 转换为技术委员会][10],为社区提供一个独立的可信任的第三方资源。 + +-------------------------------------------------------------------------------- + +via: https://blog.docker.com/2017/12/containerd-ga-features-2/ + +作者:[Michael Crosby][a] +译者:[qhwdw](https://github.com/qhwdw) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://blog.docker.com/author/michael/ +[1]:https://i0.wp.com/blog.docker.com/wp-content/uploads/950cf948-7c08-4df6-afd9-cc9bc417cabe-6.jpg?resize=400%2C120&amp;ssl=1 +[2]:https://i1.wp.com/blog.docker.com/wp-content/uploads/4a7666e4-ebdb-4a40-b61a-26ac7c3f663e-4.jpg?resize=906%2C470&amp;ssl=1 "containerd" +[3]:https://i1.wp.com/blog.docker.com/wp-content/uploads/2a73a4d8-cd40-4187-851f-6104ae3c12ba-1.jpg?resize=1140%2C680&amp;ssl=1 +[4]:https://github.com/containerd/containerd/blob/master/api/services/tasks/v1/tasks.proto +[5]:https://blog.mobyproject.org/where-are-containerds-graph-drivers-145fc9b7255 +[6]:https://github.com/containerd/containerd/blob/master/api/services/snapshots/v1/snapshots.proto +[7]:https://blog.mobyproject.org/introducing-buildkit-17e056cc5317 +[8]:https://i1.wp.com/blog.docker.com/wp-content/uploads/d0fb5eb9-c561-415d-8d57-e74442a879a2-1.jpg?resize=1140%2C556&amp;ssl=1 +[9]:https://speakerdeck.com/stevvooe/whats-happening-with-containerd-and-the-cri +[10]:https://github.com/containerd/containerd/pull/1748 From 28070252d0a92937c36bff86fc2595b87939d434 Mon Sep 17 00:00:00 2001 From: darksun Date: Fri, 2 Feb 2018 12:57:33 +0800 Subject: [PATCH 124/272] =?UTF-8?q?=E9=80=89=E9=A2=98:=20How=20to=20reload?= =?UTF-8?q?=20.vimrc=20file=20without=20restarting=20vim=20on=20Linux/Unix?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...le without restarting vim on Linux-Unix.md | 83 +++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 sources/tech/20180201 How to reload .vimrc file without restarting vim on Linux-Unix.md diff --git a/sources/tech/20180201 How to reload .vimrc file without restarting vim on Linux-Unix.md b/sources/tech/20180201 How to reload .vimrc file without restarting vim on Linux-Unix.md new file mode 100644 index 0000000000..46c7fe1cd8 --- /dev/null +++ b/sources/tech/20180201 How to reload .vimrc file without restarting vim on Linux-Unix.md @@ -0,0 +1,83 @@ +How to reload .vimrc file without restarting vim on Linux/Unix +====== + +I am a new vim text editor user. I usually load ~/.vimrc usingfor configuration. Once edited my .vimrc file I need to reload it without having to quit Vim session. How do I edit my .vimrc file and reload it without having to restart Vim on Linux or Unix-like system? + +Vim is free and open source text editor that is upwards compatible to Vi. It can be used to edit all kinds of good old text. It is especially useful for editing programs written in C/Perl/Python. One can use it for editing Linux/Unix configuration files. ~/.vimrc is your personal Vim initializations and customization file. + +### How to reload .vimrc file without restarting vim session + +The procedure to reload .vimrc in Vim without restart: + + 1. Start vim text editor by typing: `vim filename` + 2. Load vim config file by typing vim command: `Esc` followed by `:vs ~/.vimrc` + 3. Add customization like: + ``` + filetype indent plugin on + set number + syntax on + ``` + 4. Use `:wq` to save a file and exit from ~/.vimrc window. + 5. Reload ~/.vimrc by typing any one of the following command: + ``` + :so $MYVIMRC + ``` + OR + ``` + :source ~/.vimrc + ``` + +[![How to reload .vimrc file without restarting vim][1]][1] +Fig.01: Editing ~/.vimrc and reloading it when needed without quiting vim so that you can continuing editing program + +The `:so[urce]! {file}` vim command read vim configfileor ommands from given file such as ~/.vimrc. These are commands that are executed from Normal mode, like you type them. When used after :global, :argdo, :windo, :bufdo, in a loop or when another command follows the display won't be updated while executing the commands. + +### How to may keys for edit and reload ~/.vimrc + +Append the following in your ~/.vimrc file +``` +" Edit vimr configuration file +nnoremap confe :e $MYVIMRC +" + + Reload vims configuration file +nnoremap confr :source $MYVIMRC +``` + +" Edit vimr configuration file nnoremap confe :e $MYVIMRC " Reload vims configuration file nnoremap confr :source $MYVIMRC + +Now just press `Esc` followed by `confe` to edit ~/.vimrc file. To reload type `Esc` followed by `confr`. Some people like to use the key in a .vimrc file. So above mapping becomes: +``` +" Edit vimr configuration file +nnoremap ve :e $MYVIMRC +" +" Reload vimr configuration file +nnoremap vr :source $MYVIMRC +``` + +" Edit vimr configuration file nnoremap ve :e $MYVIMRC " " Reload vimr configuration file nnoremap vr :source $MYVIMRC + +The key is mapped to \ by default. So you just press \ followed by ve to edit the file. To reload the ~/vimrc file you press \ followed by vr +And there you have it, you just reload .vimrc file without restarting vim ever. + + +### 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][2], [Facebook][3], [Google+][4]. Get the **latest tutorials on SysAdmin, Linux/Unix and open source topics via[my RSS/XML feed][5]**. + +-------------------------------------------------------------------------------- + +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) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://www.cyberciti.biz/ +[1]:https://www.cyberciti.biz/media/new/faq/2018/02/How-to-reload-.vimrc-file-without-restarting-vim.jpg +[2]:https://twitter.com/nixcraft +[3]:https://facebook.com/nixcraft +[4]:https://plus.google.com/+CybercitiBiz +[5]:https://www.cyberciti.biz/atom/atom.xml From c00eae1e29b6311034ffbd3ba84903672903716e Mon Sep 17 00:00:00 2001 From: darksun Date: Fri, 2 Feb 2018 13:03:23 +0800 Subject: [PATCH 125/272] =?UTF-8?q?=E9=80=89=E9=A2=98:=20A=20history=20of?= =?UTF-8?q?=20low-level=20Linux=20container=20runtimes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...y of low-level Linux container runtimes.md | 117 ++++++++++++++++++ 1 file changed, 117 insertions(+) create mode 100644 sources/tech/20180131 A history of low-level Linux container runtimes.md diff --git a/sources/tech/20180131 A history of low-level Linux container runtimes.md b/sources/tech/20180131 A history of low-level Linux container runtimes.md new file mode 100644 index 0000000000..e83477249d --- /dev/null +++ b/sources/tech/20180131 A history of low-level Linux container runtimes.md @@ -0,0 +1,117 @@ +A history of low-level Linux container runtimes +====== + +![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/running-containers-two-ship-container-beach.png?itok=wr4zJC6p) + +At Red Hat we like to say, "Containers are Linux--Linux is Containers." Here is what this means. Traditional containers are processes on a system that usually have the following three characteristics: + +### 1\. Resource constraints + +When you run lots of containers on a system, you do not want to have any container monopolize the operating system, so we use resource constraints to control things like CPU, memory, network bandwidth, etc. The Linux kernel provides the cgroups feature, which can be configured to control the container process resources. + +### 2\. Security constraints + +Usually, you do not want your containers being able to attack each other or attack the host system. We take advantage of several features of the Linux kernel to set up security separation, such as SELinux, seccomp, capabilities, etc. + +### 3\. Virtual separation + +Container processes should not have a view of any processes outside the container. They should be on their own network. Container processes need to be able to bind to port 80 in different containers. Each container needs a different view of its image, needs its own root filesystem (rootfs). In Linux we use kernel namespaces to provide virtual separation. + +Therefore, a process that runs in a cgroup, has security settings, and runs in namespaces can be called a container. Looking at PID 1, systemd, on a Red Hat Enterprise Linux 7 system, you see that systemd runs in a cgroup. +``` + + +# tail -1 /proc/1/cgroup + +1:name=systemd:/ +``` + +The `ps` command shows you that the system process has an SELinux label ... +``` + + +# ps -eZ | grep systemd + +system_u:system_r:init_t:s0             1 ?     00:00:48 systemd +``` + +and capabilities. +``` + + +# grep Cap /proc/1/status + +... + +CapEff: 0000001fffffffff + +CapBnd: 0000001fffffffff + +CapBnd:    0000003fffffffff +``` + +Finally, if you look at the `/proc/1/ns` subdir, you will see the namespace that systemd runs in. +``` + + +ls -l /proc/1/ns + +lrwxrwxrwx. 1 root root 0 Jan 11 11:46 mnt -> mnt:[4026531840] + +lrwxrwxrwx. 1 root root 0 Jan 11 11:46 net -> net:[4026532009] + +lrwxrwxrwx. 1 root root 0 Jan 11 11:46 pid -> pid:[4026531836] + +... +``` + +If PID 1 (and really every other process on the system) has resource constraints, security settings, and namespaces, I argue that every process on the system is in a container. + +Container runtime tools just modify these resource constraints, security settings, and namespaces. Then the Linux kernel executes the processes. After the container is launched, the container runtime can monitor PID 1 inside the container or the container's `stdin`/`stdout`--the container runtime manages the lifecycles of these processes. + +### Container runtimes + +You might say to yourself, well systemd sounds pretty similar to a container runtime. Well, after having several email discussions about why container runtimes do not use `systemd-nspawn` as a tool for launching containers, I decided it would be worth discussing container runtimes and giving some historical context. + +[Docker][1] is often called a container runtime, but "container runtime" is an overloaded term. When folks talk about a "container runtime," they're really talking about higher-level tools like Docker, [ CRI-O][2], and [ RKT][3] that come with developer functionality. They are API driven. They include concepts like pulling the container image from the container registry, setting up the storage, and finally launching the container. Launching the container often involves running a specialized tool that configures the kernel to run the container, and these are also referred to as "container runtimes." I will refer to them as "low-level container runtimes." Daemons like Docker and CRI-O, as well as command-line tools like [ Podman][4] and [ Buildah][5], should probably be called "container managers" instead. + +When Docker was originally written, it launched containers using the `lxc` toolset, which predates `systemd-nspawn`. Red Hat's original work with Docker was to try to integrate `[ libvirt][6]` (`libvirt-lxc`) into Docker as an alternative to the `lxc` tools, which were not supported in RHEL. `libvirt-lxc` also did not use `systemd-nspawn`. At that time, the systemd team was saying that `systemd-nspawn` was only a tool for testing, not for production. + +At the same time, the upstream Docker developers, including some members of my Red Hat team, decided they wanted a golang-native way to launch containers, rather than launching a separate application. Work began on libcontainer, as a native golang library for launching containers. Red Hat engineering decided that this was the best path forward and dropped `libvirt-lxc`. + +Later, the [Open Container Initiative][7] (OCI) was formed, party because people wanted to be able to launch containers in additional ways. Traditional namespace-separated containers were popular, but people also had the desire for virtual machine-level isolation. Intel and [Hyper.sh][8] were working on KVM-separated containers, and Microsoft was working on Windows-based containers. The OCI wanted a standard specification defining what a container is, so the [ OCI Runtime Specification][9] was born. + +The OCI Runtime Specification defines a JSON file format that describes what binary should be run, how it should be contained, and the location of the rootfs of the container. Tools can generate this JSON file. Then other tools can read this JSON file and execute a container on the rootfs. The libcontainer parts of Docker were broken out and donated to the OCI. The upstream Docker engineers and our engineers helped create a new frontend tool to read the OCI Runtime Specification JSON file and interact with libcontainer to run the container. This tool, called `[ runc][10]`, was also donated to the OCI. While `runc` can read the OCI JSON file, users are left to generate it themselves. `runc` has since become the most popular low-level container runtime. Almost all container-management tools support `runc`, including CRI-O, Docker, Buildah, Podman, and [ Cloud Foundry Garden][11]. Since then, other tools have also implemented the OCI Runtime Spec to execute OCI-compliant containers. + +Both [Clear Containers][12] and Hyper.sh's `runV` tools were created to use the OCI Runtime Specification to execute KVM-based containers, and they are combining their efforts in a new project called [ Kata][12]. Last year, Oracle created a demonstration version of an OCI runtime tool called [RailCar][13], written in Rust. It's been two months since the GitHub project has been updated, so it's unclear if it is still in development. A couple of years ago, Vincent Batts worked on adding a tool, `[ nspawn-oci][14]`, that interpreted an OCI Runtime Specification file and launched `systemd-nspawn`, but no one really picked up on it, and it was not a native implementation. + +If someone wants to implement a native `systemd-nspawn --oci OCI-SPEC.json` and get it accepted by the systemd team for support, then CRI-O, Docker, and eventually Podman would be able to use it in addition to `runc `and Clear Container/runV ([Kata][15]). (No one on my team is working on this.) + +The bottom line is, back three or four years, the upstream developers wanted to write a low-level golang tool for launching containers, and this tool ended up becoming `runc`. Those developers at the time had a C-based tool for doing this called `lxc` and moved away from it. I am pretty sure that at the time they made the decision to build libcontainer, they would not have been interested in `systemd-nspawn` or any other non-native (golang) way of running "namespace" separated containers. + +-------------------------------------------------------------------------------- + +via: https://opensource.com/article/18/1/history-low-level-container-runtimes + +作者:[Daniel Walsh][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/rhatdan +[1]:https://github.com/docker +[2]:https://github.com/kubernetes-incubator/cri-o +[3]:https://github.com/rkt/rkt +[4]:https://github.com/projectatomic/libpod/tree/master/cmd/podman +[5]:https://github.com/projectatomic/buildah +[6]:https://libvirt.org/ +[7]:https://www.opencontainers.org/ +[8]:https://www.hyper.sh/ +[9]:https://github.com/opencontainers/runtime-spec +[10]:https://github.com/opencontainers/runc +[11]:https://github.com/cloudfoundry/garden +[12]:https://clearlinux.org/containers +[13]:https://github.com/oracle/railcar +[14]:https://github.com/vbatts/nspawn-oci +[15]:https://github.com/kata-containers From 190ef36c95e592fb57df8f64c50b77a75bfb9420 Mon Sep 17 00:00:00 2001 From: qhwdw Date: Fri, 2 Feb 2018 14:05:48 +0800 Subject: [PATCH 126/272] Translated by qhwdw --- .../20180122 How to Create a Docker Image.md | 197 ------------------ .../20180122 How to Create a Docker Image.md | 197 ++++++++++++++++++ 2 files changed, 197 insertions(+), 197 deletions(-) delete mode 100644 sources/tech/20180122 How to Create a Docker Image.md create mode 100644 translated/tech/20180122 How to Create a Docker Image.md diff --git a/sources/tech/20180122 How to Create a Docker Image.md b/sources/tech/20180122 How to Create a Docker Image.md deleted file mode 100644 index 4894085a8f..0000000000 --- a/sources/tech/20180122 How to Create a Docker Image.md +++ /dev/null @@ -1,197 +0,0 @@ -How to Create a Docker Image -====== - -![](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/container-image_0.jpg?itok=G_Gz80R9) - -In the previous [article][1], we learned about how to get started with Docker on Linux, macOS, and Windows. In this article, we will get a basic understanding of creating Docker images. There are prebuilt images available on DockerHub that you can use for your own project, and you can publish your own image there. - -We are going to use prebuilt images to get the base Linux subsystem, as it's a lot of work to build one from scratch. You can get Alpine (the official distro used by Docker Editions), Ubuntu, BusyBox, or scratch. In this example, I will use Ubuntu. - -Before we start building our images, let's "containerize" them! By this I just mean creating directories for all of your Docker images so that you can maintain different projects and stages isolated from each other. -``` -$ mkdir dockerprojects - -cd dockerprojects - -``` - -Now create a Dockerfile inside the dockerprojects directory using your favorite text editor; I prefer nano, which is also easy for new users. -``` -$ nano Dockerfile - -``` - -And add this line: -``` -FROM Ubuntu - -``` - -![m7_f7No0pmZr2iQmEOH5_ID6MDG2oEnODpQZkUL7][2] - -Save it with Ctrl+Exit then Y. - -Now create your new image and provide it with a name (run these commands within the same directory): -``` -$ docker build -t dockp . - -``` - -(Note the dot at the end of the command.) This should build successfully, so you'll see: -``` -Sending build context to Docker daemon 2.048kB - -Step 1/1 : FROM ubuntu - ----> 2a4cca5ac898 - -Successfully built 2a4cca5ac898 - -Successfully tagged dockp:latest - -``` - -It's time to run and test your image: -``` -$ docker run -it Ubuntu - -``` - -You should see root prompt: -``` -root@c06fcd6af0e8:/# - -``` - -This means you are literally running bare minimal Ubuntu inside Linux, Windows, or macOS. You can run all native Ubuntu commands and CLI utilities. - -![vpZ8ts9oq3uk--z4n6KP3DD3uD_P4EpG7fX06MC3][3] - -Let's check all the Docker images you have in your directory: -``` -$docker images - - -REPOSITORY TAG IMAGE ID CREATED SIZE - -dockp latest 2a4cca5ac898 1 hour ago 111MB - -ubuntu latest 2a4cca5ac898 1 hour ago 111MB - -hello-world latest f2a91732366c 8 weeks ago 1.85kB - -``` - -You can see all three images: dockp, Ubuntu, and hello-world, which I created a few weeks ago when working on the previous articles of this series. Building a whole LAMP stack can be challenging, so we are going create a simple Apache server image with Dockerfile. - -Dockerfile is basically a set of instructions to install all the needed packages, configure, and copy files. In this case, it's Apache and Nginx. - -You may also want to create an account on DockerHub and log into your account before building images, in case you are pulling something from DockerHub. To log into DockerHub from the command line, just run: -``` -$ docker login - -``` - -Enter your username and password and you are logged in. - -Next, create a directory for Apache inside the dockerproject: -``` -$ mkdir apache - -``` - -Create a Dockerfile inside Apache folder: -``` -$ nano Dockerfile - -``` - -And paste these lines: -``` -FROM ubuntu - -MAINTAINER Kimbro Staken version: 0.1 - -RUN apt-get update && apt-get install -y apache2 && apt-get clean && rm -rf /var/lib/apt/lists/* - - -ENV APACHE_RUN_USER www-data - -ENV APACHE_RUN_GROUP www-data - -ENV APACHE_LOG_DIR /var/log/apache2 - - -EXPOSE 80 - - -CMD ["/usr/sbin/apache2", "-D", "FOREGROUND"] - -``` - -Then, build the image: -``` -docker build -t apache . - -``` - -(Note the dot after a space at the end.) - -It will take some time, then you should see successful build like this: -``` -Successfully built e7083fd898c7 - -Successfully tagged ng:latest - -Swapnil:apache swapnil$ - -``` - -Now let's run the server: -``` -$ docker run -d apache - -a189a4db0f7c245dd6c934ef7164f3ddde09e1f3018b5b90350df8be85c8dc98 - -``` - -Eureka. Your container image is running. Check all the running containers: -``` -$ docker ps - -CONTAINER ID IMAGE COMMAND CREATED - -a189a4db0f7 apache "/usr/sbin/apache2ctl" 10 seconds ago - -``` - -You can kill the container with the docker kill command: -``` -$docker kill a189a4db0f7 - -``` - -So, you see the "image" itself is persistent that stays in your directory, but the container runs and goes away. Now you can create as many images as you want and spin and nuke as many containers as you need from those images. - -That's how to create an image and run containers. - -To learn more, you can open your web browser and check out the documentation about how to build more complicated Docker images like the whole LAMP stack. Here is a[ Dockerfile][4] file for you to play with. In the next article, I'll show how to push images to DockerHub. - -Learn more about Linux through the free ["Introduction to Linux" ][5]course from The Linux Foundation and edX. - --------------------------------------------------------------------------------- - -via: https://www.linux.com/blog/learn/intro-to-linux/2018/1/how-create-docker-image - -作者:[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/intro-to-linux/how-install-docker-ce-your-desktop -[2]:https://lh6.googleusercontent.com/m7_f7No0pmZr2iQmEOH5_ID6MDG2oEnODpQZkUL7q3GYRB9f1-lvMYLE5f3GBpzIk-ev5VlcB0FHYSxn6NNQjxY4jJGqcgdFWaeQ-027qX_g-SVtbCCMybJeD6QIXjzM2ga8M4l4 -[3]:https://lh3.googleusercontent.com/vpZ8ts9oq3uk--z4n6KP3DD3uD_P4EpG7fX06MC3uFvj2-WaI1DfOfec9ZXuN7XUNObQ2SCc4Nbiqp-CM7ozUcQmtuzmOdtUHTF4Jq8YxkC49o2k7y5snZqTXsueITZyaLiHq8bT -[4]:https://github.com/fauria/docker-lamp/blob/master/Dockerfile -[5]:https://training.linuxfoundation.org/linux-courses/system-administration-training/introduction-to-linux diff --git a/translated/tech/20180122 How to Create a Docker Image.md b/translated/tech/20180122 How to Create a Docker Image.md new file mode 100644 index 0000000000..ec0810a10a --- /dev/null +++ b/translated/tech/20180122 How to Create a Docker Image.md @@ -0,0 +1,197 @@ +如何创建一个 Docker 镜像 +====== + +![](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/container-image_0.jpg?itok=G_Gz80R9) + +在 [前面的文章][1] 中,我们学习了在 Linux、macOS、以及 Windows 上如何使用 Docker 的基础知识。在这篇文章中,我们将去学习创建 Docker 镜像的基本知识。我们可以在 DockerHub 上得到你可以用于你自己的项目的预构建镜像,并且也可以将你自己的镜像发布到这里。 + +我们使用预构建镜像得到一个基本的 Linux 子系统,因为,从头开始构建需要大量的工作。你可以得到 Alpine( Docker 版使用的官方版本)、Ubuntu、BusyBox、或者 scratch。在我们的示例中,我将使用 Ubuntu。 + +在我们开始构建镜像之前,让我们先“容器化”它们!我的意思是,为你的所有 Docker 镜像创建目录,这样你就可以维护不同的项目和阶段,并保持它们彼此隔离。 +``` +$ mkdir dockerprojects + +cd dockerprojects + +``` + +现在,在 `dockerprojects` 目录中,你可以使用自己喜欢的文本编辑器去创建一个 `Dockerfile` 文件;我喜欢使用 nano,它对新手来说很容易上手。 +``` +$ nano Dockerfile + +``` + +然后添加这样的一行内容: +``` +FROM Ubuntu + +``` + +![m7_f7No0pmZr2iQmEOH5_ID6MDG2oEnODpQZkUL7][2] + +使用 Ctrl+Exit 然后选择 Y 去保存它。 + +现在开始创建你的新镜像,然后给它起一个名字(在刚才的目录中运行如下的命令): +``` +$ docker build -t dockp . + +``` + +(注意命令后面的圆点)这样就创建成功了,因此,你将看到如下内容: +``` +Sending build context to Docker daemon 2.048kB + +Step 1/1 : FROM ubuntu + +---> 2a4cca5ac898 + +Successfully built 2a4cca5ac898 + +Successfully tagged dockp:latest + +``` + +现在去运行和测试一下你的镜像: +``` +$ docker run -it Ubuntu + +``` + +你将看到 root 提示符: +``` +root@c06fcd6af0e8:/# + +``` + +这意味着在 Linux、Windows、或者 macOS 中你可以运行一个最小的 Ubuntu 了。你可以运行所有的 Ubuntu 原生命令或者 CLI 实用程序。 + +![vpZ8ts9oq3uk--z4n6KP3DD3uD_P4EpG7fX06MC3][3] + +我们来查看一下在你的目录下你拥有的所有 Docker 镜像: +``` +$docker images + + +REPOSITORY TAG IMAGE ID CREATED SIZE + +dockp latest 2a4cca5ac898 1 hour ago 111MB + +ubuntu latest 2a4cca5ac898 1 hour ago 111MB + +hello-world latest f2a91732366c 8 weeks ago 1.85kB + +``` + +你可以看到共有三个镜像:dockp、Ubuntu、和 hello-world, hello-world 是我在几周前创建的,这一系列的前面的文章就是在它下面工作的。构建一个完整的 LAMP 栈可能是一个挑战,因此,我们使用 Dockerfile 去创建一个简单的 Apache 服务器镜像。 + +从本质上说,Dockerfile 是安装所有需要的包、配置、以及拷贝文件的一套指令。在这个案例中,它是安装配置 Apache 和 Nginx。 + +你也可以在 DockerHub 上去创建一个帐户,然后在构建镜像之前登入到你的帐户,在这个案例中,你需要从 DockerHub 上拉取一些东西。从命令行中登入 DockerHub,运行如下所求的命令: +``` +$ docker login + +``` + +在登入时输入你的用户名和密码。 + +接下来,为这个 Docker 项目,在目录中创建一个 Apache 目录: +``` +$ mkdir apache + +``` + +在 Apache 目录中创建 Dockerfile 文件: +``` +$ nano Dockerfile + +``` + +然后,粘贴下列内容: +``` +FROM ubuntu + +MAINTAINER Kimbro Staken version: 0.1 + +RUN apt-get update && apt-get install -y apache2 && apt-get clean && rm -rf /var/lib/apt/lists/* + + +ENV APACHE_RUN_USER www-data + +ENV APACHE_RUN_GROUP www-data + +ENV APACHE_LOG_DIR /var/log/apache2 + + +EXPOSE 80 + + +CMD ["/usr/sbin/apache2", "-D", "FOREGROUND"] + +``` + +然后,构建镜像: +``` +docker build -t apache . + +``` + +(注意命令尾部的空格和圆点) + +这将花费一些时间,然后你将看到如下的构建成功的消息: +``` +Successfully built e7083fd898c7 + +Successfully tagged ng:latest + +Swapnil:apache swapnil$ + +``` + +现在,我们来运行一下这个服务器: +``` +$ docker run -d apache + +a189a4db0f7c245dd6c934ef7164f3ddde09e1f3018b5b90350df8be85c8dc98 + +``` + +发现了吗,你的容器镜像已经运行了。可以运行如下的命令来检查所有运行的容器: +``` +$ docker ps + +CONTAINER ID IMAGE COMMAND CREATED + +a189a4db0f7 apache "/usr/sbin/apache2ctl" 10 seconds ago + +``` + +你可以使用 docker kill 命令来杀死容器: +``` +$docker kill a189a4db0f7 + +``` + +正如你所见,这个 "镜像" 它已经永久存在于你的目录中了,而不论运行与否。现在你可以根据你的需要创建很多的镜像,并且可以从这些镜像中繁衍出来更多的镜像。 + +这就是如何去创建镜像和运行容器。 + +想学习更多内容,你可以打开你的浏览器,然后找到更多的关于如何构建像 LAMP 栈这样的完整的 Docker 镜像的文档。这里有一个帮你实现它的 [ Dockerfile][4] 文件。在下一篇文章中,我将演示如何推送一个镜像到 DockerHub。 + +你可以通过来自 Linux 基金会和 edX 的 ["介绍 Linux" ][5] 免费课程来学习更多的知识。 + +-------------------------------------------------------------------------------- + +via: https://www.linux.com/blog/learn/intro-to-linux/2018/1/how-create-docker-image + +作者:[SWAPNIL BHARTIYA][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/arnieswap +[1]:https://www.linux.com/blog/learn/intro-to-linux/how-install-docker-ce-your-desktop +[2]:https://lh6.googleusercontent.com/m7_f7No0pmZr2iQmEOH5_ID6MDG2oEnODpQZkUL7q3GYRB9f1-lvMYLE5f3GBpzIk-ev5VlcB0FHYSxn6NNQjxY4jJGqcgdFWaeQ-027qX_g-SVtbCCMybJeD6QIXjzM2ga8M4l4 +[3]:https://lh3.googleusercontent.com/vpZ8ts9oq3uk--z4n6KP3DD3uD_P4EpG7fX06MC3uFvj2-WaI1DfOfec9ZXuN7XUNObQ2SCc4Nbiqp-CM7ozUcQmtuzmOdtUHTF4Jq8YxkC49o2k7y5snZqTXsueITZyaLiHq8bT +[4]:https://github.com/fauria/docker-lamp/blob/master/Dockerfile +[5]:https://training.linuxfoundation.org/linux-courses/system-administration-training/introduction-to-linux From 60262438c91351b13ca5f89a6722d49088107b25 Mon Sep 17 00:00:00 2001 From: darksun Date: Fri, 2 Feb 2018 14:12:34 +0800 Subject: [PATCH 127/272] =?UTF-8?q?=E9=80=89=E9=A2=98:=20Ultimate=20guide?= =?UTF-8?q?=20to=20securing=20SSH=20sessions?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...Ultimate guide to securing SSH sessions.md | 139 ++++++++++++++++++ 1 file changed, 139 insertions(+) create mode 100644 sources/tech/20170428 Ultimate guide to securing SSH sessions.md diff --git a/sources/tech/20170428 Ultimate guide to securing SSH sessions.md b/sources/tech/20170428 Ultimate guide to securing SSH sessions.md new file mode 100644 index 0000000000..a96c4da6e7 --- /dev/null +++ b/sources/tech/20170428 Ultimate guide to securing SSH sessions.md @@ -0,0 +1,139 @@ +Ultimate guide to securing SSH sessions +====== +Hi Linux-fanatics, in this tutorial we will be discussing some ways with which we make our ssh server more secure. OpenSSH is currently used by default to work on servers as physical access to servers is very limited. We use ssh to copy/backup files/folders, to remotely execute commands etc. But these ssh connections might not be as secure as we believee & we must make some changes to our default settings to make them more secure. + +Here are steps needed to secure our ssh sessions, + +### Use complex username & password + +This is first of the problem that needs to be addressed, I have known users who have '12345' as their password. It seems they are inviting hackers to get themselves hacked. You should always have a complex password. + +It should have at-least 8 characters with numbers & alphabets, lower case & upper case letter, and also special characters. A good example would be " ** ** _vXdrf23#$wd_**** " , it is not a word so dictionary attack will be useless & has uppercase, lowercase characters, numbers & special characters. + +### Limit user logins + +Not all the users are required to have access to ssh in an organization, so we should make changes to our configuration file to limit user logins. Let's say only Bob & Susan are authorized have access to ssh, so open your configuration file + +``` + $ vi /etc/ssh/sshd_config +``` + +& add the allowed users to the bottom of the file + +``` + AllowUsers bob susan +``` + +Save the file & restart the service. Now only Bob & Susan will have access to ssh , others won't be able to access ssh. + +### Configure Idle logout time + + +Once logged into ssh sessions, there is default time before sessions logs out on it own. By default idle logout time is 60 minutes, which according to me is way to much. Consider this, you logged into a session , executed some commands & then went out to get a cup of coffee but you forgot to log-out of the ssh. Just think what could be done in the 60 seconds, let alone in 60 minutes. + +So, its wise to reduce idle log-out time to something around 5 minutes & it can be done in config file only. Open '/etc/ssh/sshd_config' & change the values + +``` +ClientAliveInterval 300 +ClientAliveCountMax 0 +``` + +Its in seconds, so configure them accordingly. + +### Disable root logins + +As we know root have access to anything & everything on the server, so we must disable root access through ssh session. Even if it is needed to complete a task that only root can do, we can escalate the privileges of a normal user. + +To disable root access, open your configuration file & change the following parameter + +``` +PermitRootLogin no +ClientAliveCountMax 0 +``` + +This will disable root access to ssh sessions. + +### Enable Protocol 2 + +SSH protocol 1 had man in the middle attack issues & other security issues as well, all these issues were addressed in Protocol 2. So protocol 1 must not be used at any cost. To change the protocol , open your sshd_config file & change the following parameter + +``` + Protocol 2 +``` + +### Enable a warning screen + +It would be a good idea to enable a warning screen stating a warning about misuse of ssh, just before a user logs into the session. To create a warning screen, create a file named **" warning"** in **/etc/** folder (or any other folder) & write something like "We monitor all our sessions on continuously. Don't misuse your access or else you will be prosecuted" or whatever you wish to warn. You can also consult legal team about this warning to make it more official. + +After this file is create, open sshd_config file & enter the following parameter into the file + +``` + Banner /etc/issue +``` + +now you warning message will be displayed each time someone tries to access the session. + +### Use non-standard ssh port + +By default, ssh uses port 22 & all the brute force scripts are written for port 22 only. So to make your sessions even more secure, use a non-standard port like 15000. But make sure before selecting a port that its not being used by some other service. + +To change port, open sshd_config & change the following parameter + +``` + Port 15000 +``` + +Save & restart the service and you can access the ssh only with this new port. To start a session with custom port use the following command + +``` + $ ssh -p 15000 {server IP} +``` + +** Note:-** If using firewall, open the port on your firewall & we must also change the SELinux settings if using a custom port for ssh. Run the following command to update the SELinux label + +``` +$ semanage port -a -t ssh_port_t -p tcp 15000 +``` + +### Limit IP access + +If you have an environment where your server is accessed by only limited number of IP addresses, you can also allow access to those IP addresses only. Open sshd_config file & enter the following with your custom port + +``` +Port 15000 +ListenAddress 192.168.1.100 +ListenAddress 192.168.1.115 +``` + +Now ssh session will only be available to these mentioned IPs with the custom port 15000. + +### Disable empty passwords + +As mentioned already that you should only use complex username & passwords, so using an empty password for remote login is a complete no-no. To disable empty passwords, open sshd_config file & edit the following parameter + +``` +PermitEmptyPasswords no +``` + +### Use public/private key based authentication + +Using Public/Private key based authentication has its advantages i.e. you no longer need to enter the password when entering into a session (unless you are using a passphrase to decrypt the key) & no one can have access to your server until & unless they have the right authentication key. Process to setup public/private key based authentication is discussed in [**this tutorial here**][1]. + +So, this completes our tutorial on securing your ssh server. If having any doubts or issues, please leave a message in the comment box below. + +-------------------------------------------------------------------------------- + +via: http://linuxtechlab.com/ultimate-guide-to-securing-ssh-sessions/ + +作者:[SHUSAIN][a] +译者:[译者ID](https://github.com/译者ID) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:http://linuxtechlab.com/author/shsuain/ +[1]:http://linuxtechlab.com/configure-ssh-server-publicprivate-key/ +[2]:https://www.facebook.com/techlablinux/ +[3]:https://twitter.com/LinuxTechLab +[4]:https://plus.google.com/+linuxtechlab +[5]:http://linuxtechlab.com/contact-us-2/ From b7800d5dd2c43eedadc73a39fd8cf07c318c0580 Mon Sep 17 00:00:00 2001 From: darksun Date: Fri, 2 Feb 2018 14:18:04 +0800 Subject: [PATCH 128/272] =?UTF-8?q?=E9=80=89=E9=A2=98:=20Linux=20seq=20Com?= =?UTF-8?q?mand=20Tutorial=20for=20Beginners=20(5=20Examples)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...and Tutorial for Beginners (5 Examples).md | 161 ++++++++++++++++++ 1 file changed, 161 insertions(+) create mode 100644 sources/tech/20180201 Linux seq Command Tutorial for Beginners (5 Examples).md diff --git a/sources/tech/20180201 Linux seq Command Tutorial for Beginners (5 Examples).md b/sources/tech/20180201 Linux seq Command Tutorial for Beginners (5 Examples).md new file mode 100644 index 0000000000..19b1fa890b --- /dev/null +++ b/sources/tech/20180201 Linux seq Command Tutorial for Beginners (5 Examples).md @@ -0,0 +1,161 @@ +Linux seq Command Tutorial for Beginners (5 Examples) +====== + +Sometimes, you come across a command line tool that offers limited functionality on its own, but when used with other tools, you realize its actual potential. Once such tool is **seq** , which prints a sequence of numbers. In this tutorial, we will discuss the basics of this command line utility using easy to understand examples. + +But before jumping on to that, it's worth mentioning that all examples in this article have been tested on an Ubuntu 16.04 machine. + +### Linux seq command + +As already mentioned, the seq command lets you print a sequence of numbers. Following is its syntax: + +``` +seq [OPTION]... LAST +seq [OPTION]... FIRST LAST +seq [OPTION]... FIRST INCREMENT LAST +``` + +And here's how the tool's man page explains it: +``` + Print numbers from FIRST to LAST, in steps of INCREMENT. If FIRST or + INCREMENT is omitted, it defaults to 1.  That is, an omitted  INCREMENT + defaults to 1 even when LAST is smaller than FIRST.  + + The sequence of numbers ends when the sum of the current number and  + INCREMENT  would  become  greater than LAST.  FIRST, INCREMENT, and LAST + are interpreted as floating point values.  INCREMENT is usually positive if +       FIRST  is smaller than LAST, and INCREMENT is usually negative if FIRST +       is greater than LAST.  FORMAT must be suitable for printing  one  argu? +       ment  of type 'double'; it defaults to %.PRECf if FIRST, INCREMENT, and +       LAST are all fixed point decimal numbers with maximum  precision  PREC, +       and to %g otherwise. +``` + +Following are some Q&A-styled examples that should give you a better idea on how the seq command works. + +### Q1. How seq command works? + +Basic usage is very easy. All you have to do is to pass a number to seq, and the tool will producein output numbers from 1 to the input number. + +For example: + +``` +seq 8 +``` + +[![How seq command works][1]][2] + +Of course, you can also specify the number from which you want the output to begin with. + +For example: + +``` +seq 3 8 +``` + +[![Example sequence][3]][4] + +Movin on, you can also set the incremental difference, which is 1 by default. For example, if you want seq to print from 1 to 9, but with a difference of 2, then here's how you can do that: + +``` +seq 1 2 9 +``` + +[![Another seq command example][5]][6] + +### Q2. How to add a separator? + +If you want, you can also have a separator to make the seq output look better. This feature is available through the **-s** command line option. + +For example, the following command intends to use a comma (,) as a separator: + +``` +seq -s, 1 9 +``` + +[![How to add a separator][7]][8] + +### Q3. How to specify output format? + +The seq command allows you to use printf style floating-point FORMAT. This feature is accessible through the **-f** command line option. The tool's man page doesn't have much information on how to use this option, but the info page contains the required details. Here's what the info page says: +``` +`-f FORMAT' + `--format=FORMAT' + Print all numbers using FORMAT. FORMAT must contain exactly one + of the `printf'-style floating point conversion specifications + `%a', `%e', `%f', `%g', `%A', `%E', `%F', `%G'. The `%' may be + followed by zero or more flags taken from the set `-+#0 '', then + an optional width containing one or more digits, then an optional + precision consisting of a `.' followed by zero or more digits. + FORMAT may also contain any number of `%%' conversion + specifications. All conversion specifications have the same + meaning as with `printf'. + + The default format is derived from FIRST, STEP, and LAST. If + these all use a fixed point decimal representation, the default + format is `%.Pf', where P is the minimum precision that can + represent the output numbers exactly. Otherwise, the default + format is `%g'. +``` + +For example, you can use this option in the following way: + +``` +seq -f "%02g" 6 +``` + +[![How to specify output format][9]][10] + +### Q4. How to use seq with other commands? (Use case 1) + +Suppose you want to perform addition of some numbers, say from 1 to 10. Here's how you can do this using seq: + +``` +expr `seq -s " + " 111 121` +``` + +Here's the above command in action: + +[![How to use seq with other commands][11]][12] + +### Q5. How to use seq with other commands? (Use case 2) + +Suppose you want to create a bunch of new files with names where only an integer value changes. For example, file1, file2, file3, and so on. Here's how you can do this using seq. + +``` +touch $(seq -f "file%g" 1 10) +``` + +[![How to use seq with other commands? \(Use case 2\)][13]][14] + +### Conclusion + +So now you'll agree how useful the seq command is. If you talk about the command line options Seq offers, there's not much of a learning curve, just that you should know when and how to use the command and its options. We've covered several use cases here - should be enough to get you started with the tool. For more information on Seq, head to its [man page][15]. + + +-------------------------------------------------------------------------------- + +via: https://www.howtoforge.com/linux-seq-command/ + +作者:[Himanshu Arora][a] +译者:[译者ID](https://github.com/译者ID) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://www.howtoforge.com +[1]:https://www.howtoforge.com/images/command-tutorial/seq-basic-usage.png +[2]:https://www.howtoforge.com/images/command-tutorial/big/seq-basic-usage.png +[3]:https://www.howtoforge.com/images/command-tutorial/seq-basic-usage2.png +[4]:https://www.howtoforge.com/images/command-tutorial/big/seq-basic-usage2.png +[5]:https://www.howtoforge.com/images/command-tutorial/seq-basic-usage3.png +[6]:https://www.howtoforge.com/images/command-tutorial/big/seq-basic-usage3.png +[7]:https://www.howtoforge.com/images/command-tutorial/seq-s-option.png +[8]:https://www.howtoforge.com/images/command-tutorial/big/seq-s-option.png +[9]:https://www.howtoforge.com/images/command-tutorial/seq-f-option.png +[10]:https://www.howtoforge.com/images/command-tutorial/big/seq-f-option.png +[11]:https://www.howtoforge.com/images/command-tutorial/seq-practical-1.png +[12]:https://www.howtoforge.com/images/command-tutorial/big/seq-practical-1.png +[13]:https://www.howtoforge.com/images/command-tutorial/seq-practical2.png +[14]:https://www.howtoforge.com/images/command-tutorial/big/seq-practical2.png +[15]:https://linux.die.net/man/1/seq From fc7e8b62aa49c1b986209655cb1408ff54e675b4 Mon Sep 17 00:00:00 2001 From: darksun Date: Fri, 2 Feb 2018 14:25:21 +0800 Subject: [PATCH 129/272] add done: 20180201 Linux seq Command Tutorial for Beginners (5 Examples).md --- ...and Tutorial for Beginners (5 Examples).md | 161 ------------------ 1 file changed, 161 deletions(-) delete mode 100644 sources/tech/20180201 Linux seq Command Tutorial for Beginners (5 Examples).md diff --git a/sources/tech/20180201 Linux seq Command Tutorial for Beginners (5 Examples).md b/sources/tech/20180201 Linux seq Command Tutorial for Beginners (5 Examples).md deleted file mode 100644 index 19b1fa890b..0000000000 --- a/sources/tech/20180201 Linux seq Command Tutorial for Beginners (5 Examples).md +++ /dev/null @@ -1,161 +0,0 @@ -Linux seq Command Tutorial for Beginners (5 Examples) -====== - -Sometimes, you come across a command line tool that offers limited functionality on its own, but when used with other tools, you realize its actual potential. Once such tool is **seq** , which prints a sequence of numbers. In this tutorial, we will discuss the basics of this command line utility using easy to understand examples. - -But before jumping on to that, it's worth mentioning that all examples in this article have been tested on an Ubuntu 16.04 machine. - -### Linux seq command - -As already mentioned, the seq command lets you print a sequence of numbers. Following is its syntax: - -``` -seq [OPTION]... LAST -seq [OPTION]... FIRST LAST -seq [OPTION]... FIRST INCREMENT LAST -``` - -And here's how the tool's man page explains it: -``` - Print numbers from FIRST to LAST, in steps of INCREMENT. If FIRST or - INCREMENT is omitted, it defaults to 1.  That is, an omitted  INCREMENT - defaults to 1 even when LAST is smaller than FIRST.  - - The sequence of numbers ends when the sum of the current number and  - INCREMENT  would  become  greater than LAST.  FIRST, INCREMENT, and LAST - are interpreted as floating point values.  INCREMENT is usually positive if -       FIRST  is smaller than LAST, and INCREMENT is usually negative if FIRST -       is greater than LAST.  FORMAT must be suitable for printing  one  argu? -       ment  of type 'double'; it defaults to %.PRECf if FIRST, INCREMENT, and -       LAST are all fixed point decimal numbers with maximum  precision  PREC, -       and to %g otherwise. -``` - -Following are some Q&A-styled examples that should give you a better idea on how the seq command works. - -### Q1. How seq command works? - -Basic usage is very easy. All you have to do is to pass a number to seq, and the tool will producein output numbers from 1 to the input number. - -For example: - -``` -seq 8 -``` - -[![How seq command works][1]][2] - -Of course, you can also specify the number from which you want the output to begin with. - -For example: - -``` -seq 3 8 -``` - -[![Example sequence][3]][4] - -Movin on, you can also set the incremental difference, which is 1 by default. For example, if you want seq to print from 1 to 9, but with a difference of 2, then here's how you can do that: - -``` -seq 1 2 9 -``` - -[![Another seq command example][5]][6] - -### Q2. How to add a separator? - -If you want, you can also have a separator to make the seq output look better. This feature is available through the **-s** command line option. - -For example, the following command intends to use a comma (,) as a separator: - -``` -seq -s, 1 9 -``` - -[![How to add a separator][7]][8] - -### Q3. How to specify output format? - -The seq command allows you to use printf style floating-point FORMAT. This feature is accessible through the **-f** command line option. The tool's man page doesn't have much information on how to use this option, but the info page contains the required details. Here's what the info page says: -``` -`-f FORMAT' - `--format=FORMAT' - Print all numbers using FORMAT. FORMAT must contain exactly one - of the `printf'-style floating point conversion specifications - `%a', `%e', `%f', `%g', `%A', `%E', `%F', `%G'. The `%' may be - followed by zero or more flags taken from the set `-+#0 '', then - an optional width containing one or more digits, then an optional - precision consisting of a `.' followed by zero or more digits. - FORMAT may also contain any number of `%%' conversion - specifications. All conversion specifications have the same - meaning as with `printf'. - - The default format is derived from FIRST, STEP, and LAST. If - these all use a fixed point decimal representation, the default - format is `%.Pf', where P is the minimum precision that can - represent the output numbers exactly. Otherwise, the default - format is `%g'. -``` - -For example, you can use this option in the following way: - -``` -seq -f "%02g" 6 -``` - -[![How to specify output format][9]][10] - -### Q4. How to use seq with other commands? (Use case 1) - -Suppose you want to perform addition of some numbers, say from 1 to 10. Here's how you can do this using seq: - -``` -expr `seq -s " + " 111 121` -``` - -Here's the above command in action: - -[![How to use seq with other commands][11]][12] - -### Q5. How to use seq with other commands? (Use case 2) - -Suppose you want to create a bunch of new files with names where only an integer value changes. For example, file1, file2, file3, and so on. Here's how you can do this using seq. - -``` -touch $(seq -f "file%g" 1 10) -``` - -[![How to use seq with other commands? \(Use case 2\)][13]][14] - -### Conclusion - -So now you'll agree how useful the seq command is. If you talk about the command line options Seq offers, there's not much of a learning curve, just that you should know when and how to use the command and its options. We've covered several use cases here - should be enough to get you started with the tool. For more information on Seq, head to its [man page][15]. - - --------------------------------------------------------------------------------- - -via: https://www.howtoforge.com/linux-seq-command/ - -作者:[Himanshu Arora][a] -译者:[译者ID](https://github.com/译者ID) -校对:[校对者ID](https://github.com/校对者ID) - -本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 - -[a]:https://www.howtoforge.com -[1]:https://www.howtoforge.com/images/command-tutorial/seq-basic-usage.png -[2]:https://www.howtoforge.com/images/command-tutorial/big/seq-basic-usage.png -[3]:https://www.howtoforge.com/images/command-tutorial/seq-basic-usage2.png -[4]:https://www.howtoforge.com/images/command-tutorial/big/seq-basic-usage2.png -[5]:https://www.howtoforge.com/images/command-tutorial/seq-basic-usage3.png -[6]:https://www.howtoforge.com/images/command-tutorial/big/seq-basic-usage3.png -[7]:https://www.howtoforge.com/images/command-tutorial/seq-s-option.png -[8]:https://www.howtoforge.com/images/command-tutorial/big/seq-s-option.png -[9]:https://www.howtoforge.com/images/command-tutorial/seq-f-option.png -[10]:https://www.howtoforge.com/images/command-tutorial/big/seq-f-option.png -[11]:https://www.howtoforge.com/images/command-tutorial/seq-practical-1.png -[12]:https://www.howtoforge.com/images/command-tutorial/big/seq-practical-1.png -[13]:https://www.howtoforge.com/images/command-tutorial/seq-practical2.png -[14]:https://www.howtoforge.com/images/command-tutorial/big/seq-practical2.png -[15]:https://linux.die.net/man/1/seq From 1a44f9f50107e31ea9c330b78e24a506e5ffc623 Mon Sep 17 00:00:00 2001 From: darksun Date: Fri, 2 Feb 2018 14:26:53 +0800 Subject: [PATCH 130/272] =?UTF-8?q?=E9=80=89=E9=A2=98:=20How=20to=20Run=20?= =?UTF-8?q?Your=20Own=20Public=20Time=20Server=20on=20Linux?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...un Your Own Public Time Server on Linux.md | 101 ++++++++++++++++++ 1 file changed, 101 insertions(+) create mode 100644 sources/tech/20180201 How to Run Your Own Public Time Server on Linux.md diff --git a/sources/tech/20180201 How to Run Your Own Public Time Server on Linux.md b/sources/tech/20180201 How to Run Your Own Public Time Server on Linux.md new file mode 100644 index 0000000000..752d06bc6a --- /dev/null +++ b/sources/tech/20180201 How to Run Your Own Public Time Server on Linux.md @@ -0,0 +1,101 @@ +How to Run Your Own Public Time Server on Linux +====== + +![](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/eddington_a._space_time_and_gravitation._fig._9.jpg?itok=KgNqViyZ) + +One of the most important public services is timekeeping, but it doesn't get a lot of attention. Most public time servers are run by volunteers to help meet always-increasing demands. Learn how to run your own public time server and contribute to an essential public good. (See [Keep Accurate Time on Linux with NTP][1] to learn how to set up a LAN time server.) + +### Famous Time Server Abusers + +Like everything in life, even something as beneficial as time servers are subject to abuse fueled by either incompetence or malice. + +Vendors of consumer network appliances are notorious for creating big messes. The first one I recall happened in 2003, when Netgear hard-coded the address of the University of Wisconsin-Madison's NTP server into their routers. All of a sudden the server was getting hammered with requests, and as Netgear sold more routers, the worse it got. Adding to the fun, the routers were programmed to send requests every second, which is way too many. Netgear issued a firmware upgrade, but few users ever upgrade their devices, and a number of them are pummeling the University of Wisconsin-Madison's NTP server to this day. Netgear gave them a pile of money, which hopefully will cover their costs until the last defective router dies. Similar ineptitudes were perpetrated by D-Link, Snapchat, TP-Link, and others. + +The NTP protocol has become a choice vector for distributed denial-of-service attacks, using both reflection and amplification. It is called reflection when an attacker uses a forged source address to target a victim; the attacker sends requests to multiple servers, which then reply and bombard the forged address. Amplification is a large reply to a small request. For example, on Linux the `ntpq` command is a useful tool to query your NTP servers to verify that they are operating correctly. Some replies, such as lists of peers, are large. Combine reflection with amplification, and an attacker can get a return of 10x or more on the bandwidth they spend on the attack. + +How do you protect your nice beneficial public NTP server? Start by using NTP 4.2.7p26 or newer, which hopefully is not an issue with your Linux distribution because that version was released in 2010. That release shipped with the most significant abuse vectors disabled as the default. The [current release is 4.2.8p10][2], released in 2017. + +Another step you can take, which you should be doing anyway, is use ingress and egress filtering on your network. Block packets from entering your network that claim to be from your network, and block outgoing packets with forged return addresses. Ingress filtering helps you, and egress filtering helps you and everyone else. Read [BCP38.info][3] for much more information. + +### Stratum 0, 1, 2 Time Servers + +NTP is more than 30 years old, one of the oldest Internet protocols that is still widely used. Its purpose is keep computers synchronized to Coordinated Universal Time (UTC). The NTP network is both hierarchical, organized into strata, and peer. Stratum 0 contains master timekeeping devices such as atomic clocks. Stratum 1 time servers synchronize with Stratum 0 devices. Stratum 2 time servers synchronize with Stratum 1 time servers, and Stratum 3 with Stratum 2. The NTP protocol supports 16 strata, though in real life there not that many. Servers in each stratum also peer with each other. + +In the olden days, we selected individual NTP servers for our client configurations. Those days are long gone, and now the better way is to use the [NTP pool addresses][4], which use round-robin DNS to share the load. Pool addresses are only for clients, such as individual PCs and your local LAN NTP server. When you run your own public server you won't use the pool addresses. + +### Public NTP Server Configuration + +There are two steps to running a public NTP server: set up your server, and then apply to join the NTP server pool. Running a public NTP server is a noble deed, but make sure you know what you're getting into. Joining the NTP pool is a long-term commitment, because even if you run it for a short time and then quit, you'll be receiving requests for years. + +You need a static public IP address, a permanent reliable Internet connection with at least 512Kb/s bandwidth, and know how to configure your firewall correctly. NTP uses UDP port 123. The machine itself doesn't have to be any great thing, and a lot of admins piggyback NTP on other public-facing servers such as Web servers. + +Configuring a public NTP server is just like configuring a LAN NTP server, with a few more configurations. Start by reading the [Rules of Engagement][5]. Follow the rules and mind your manners; almost everyone maintaining a time server is a volunteer just like you. Then select 4-7 Stratum 2 upstream time servers from [StratumTwoTimeServers][6]. Select some that are geographically close to your upstream Internet service provider (mine is 300 miles away), read their access policies, and then use `ping` and `mtr` to find the servers with the lowest latency and least number of hops. + +This example `/etc/ntp.conf` includes both IPv4 and IPv6 and basic safeguards: +``` +# stratum 2 server list +server servername_1 iburst +server servername_2 iburst +server servername_3 iburst +server servername_4 iburst +server servername_5 iburst + +# access restrictions +restrict -4 default kod noquery nomodify notrap nopeer limited +restrict -6 default kod noquery nomodify notrap nopeer limited + +# Allow ntpq and ntpdc queries only from localhost +restrict 127.0.0.1 +restrict ::1 + +``` + +Start your NTP server, let it run for a few minutes, and then test that it is querying the remote servers: +``` +$ ntpq -p + remote refid st t when poll reach delay offset jitter +================================================================= ++tock.no-such-ag 200.98.196.212 2 u 36 64 7 98.654 88.439 65.123 ++PBX.cytranet.ne 45.33.84.208 3 u 37 64 7 72.419 113.535 129.313 +*eterna.binary.n 199.102.46.70 2 u 39 64 7 92.933 98.475 56.778 ++time.mclarkdev. 132.236.56.250 3 u 37 64 5 111.059 88.029 74.919 + +``` + +Good so far. Now test from another PC, using your NTP server name. The following example shows correct output. If something is not correct you'll see an error message. +``` +$ ntpdate -q _yourservername_ +server 66.96.99.10, stratum 2, offset 0.017690, delay 0.12794 +server 98.191.213.2, stratum 1, offset 0.014798, delay 0.22887 +server 173.49.198.27, stratum 2, offset 0.020665, delay 0.15012 +server 129.6.15.28, stratum 1, offset -0.018846, delay 0.20966 +26 Jan 11:13:54 ntpdate[17293]: adjust time server 98.191.213.2 offset 0.014798 sec + +``` + +Once your server is running satisfactorily apply at [manage.ntppool.org][7] to join the pool. + +See the official handbook, [The Network Time Protocol (NTP) Distribution][8] to learn about all the command and configuration options, and advanced features such as management, querying, and authentication. Visit the following sites to learn pretty much everything you need about running a time server. + +Learn more about Linux through the free ["Introduction to Linux" ][9]course from The Linux Foundation and edX. + +-------------------------------------------------------------------------------- + +via: https://www.linux.com/learn/intro-to-linux/2018/2/how-run-your-own-public-time-server-linux + +作者:[CARLA SCHRODER][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/cschroder +[1]:https://www.linux.com/learn/intro-to-linux/2018/1/keep-accurate-time-linux-ntp +[2]:http://www.ntp.org/downloads.html +[3]:http://www.bcp38.info/index.php/Main_Page +[4]:http://www.pool.ntp.org/en/use.html +[5]:http://support.ntp.org/bin/view/Servers/RulesOfEngagement +[6]:http://support.ntp.org/bin/view/Servers/StratumTwoTimeServers?redirectedfrom=Servers.StratumTwo +[7]:https://manage.ntppool.org/manage +[8]:https://www.eecis.udel.edu/~mills/ntp/html/index.html +[9]:https://training.linuxfoundation.org/linux-courses/system-administration-training/introduction-to-linux From e4589d7f0843e4229e43e32db570a4df52acca78 Mon Sep 17 00:00:00 2001 From: darksun Date: Fri, 2 Feb 2018 14:36:35 +0800 Subject: [PATCH 131/272] =?UTF-8?q?=E9=80=89=E9=A2=98:=20Why=20you=20shoul?= =?UTF-8?q?d=20use=20named=20pipes=20on=20Linux?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...Why you should use named pipes on Linux.md | 104 ++++++++++++++++++ 1 file changed, 104 insertions(+) create mode 100644 sources/tech/20180131 Why you should use named pipes on Linux.md diff --git a/sources/tech/20180131 Why you should use named pipes on Linux.md b/sources/tech/20180131 Why you should use named pipes on Linux.md new file mode 100644 index 0000000000..99467ee1f7 --- /dev/null +++ b/sources/tech/20180131 Why you should use named pipes on Linux.md @@ -0,0 +1,104 @@ +Why you should use named pipes on Linux +====== + +![](https://images.techhive.com/images/article/2017/05/blue-1845806_1280-100722976-large.jpg) + +Just about every Linux user is familiar with the process of piping data from one process to another using | signs. It provides an easy way to send output from one command to another and end up with only the data you want to see without having to write scripts to do all of the selecting and reformatting. + +There is another type of pipe, however, one that warrants the name "pipe" but has a very different personality. It's one that you may have never tried or even thought about -- the named pipe. + + **Also read:[11 pointless but awesome Linux terminal tricks][1]** + +One of the key differences between regular pipes and named pipes is that named pipes have a presense in the file system. That is, they show up as files. But unlike most files, they never appear to have contents. Even if you write a lot of data to a named pipe, the file appears to be empty. + +### How to set up a named pipe on Linux + +Before we look at one of these empty named pipes, let's step back and see how a named pipe is set up. You would use a command called **mkfifo**. Why the reference to "FIFO"? Because a named pipe is also known as a FIFO special file. The term "FIFO" refers to its first-in, first-out character. If you fill a dish with ice cream and then start eating it, you'd be doing a LIFO (last-in, first-out) maneuver. If you suck a milkshake through a straw, you'd be doing a FIFO one. So, here's an example of creating a named pipe. +``` +$ mkfifo mypipe +$ ls -l mypipe +prw-r-----. 1 shs staff 0 Jan 31 13:59 mypipe + +``` + +Notice the special file type designation of "p" and the file length of zero. You can write to a named pipe by redirecting output to it and the length will still be zero. +``` +$ echo "Can you read this?" > mypipe +$ ls -l mypipe +prw-r-----. 1 shs staff 0 Jan 31 13:59 mypipe + +``` + +So far, so good, but hit return and nothing much happens. +``` +$ echo "Can you read this?" > mypipe + + +``` + +While it might not be obvious, your text has entered into the pipe, but you're still peeking into the _input_ end of it. You or someone else may be sitting at the _output_ end and be ready to read the data that's being poured into the pipe, now waiting for it to be read. +``` +$ cat mypipe +Can you read this? + +``` + +Once read, the contents of the pipe are gone. + +Another way to see how a named pipe works is to perform both operations (pouring the data into the pipe and retrieving it at the other end) yourself by putting the pouring part into the background. +``` +$ echo "Can you read this?" > mypipe & +[1] 79302 +$ cat mypipe +Can you read this? +[1]+ Done echo "Can you read this?" > mypipe + +``` + +Once the pipe has been read or "drained," it's empty, though it still will be visible as an empty file ready to be used again. Of course, this brings us to the "why bother?" stage. + +### Why use named pipes? + +Named pipes are used infrequently for a good reason. On Unix systems, there are almost always many ways to do pretty much the same thing. There are many ways to write to a file, read from a file, and empty a file, though named pipes have a certain efficiency going for them. + +For one thing, named pipe content resides in memory rather than being written to disk. It is passed only when both ends of the pipe have been opened. And you can write to a pipe multiple times before it is opened at the other end and read. By using named pipes, you can establish a process in which one process writes to a pipe and another reads from a pipe without much concern about trying to time or carefully orchestrate their interaction. + +You can set up a process that simply waits for data to appear at the output end of the pipe and then works with it when it does. In the command below, we use the tail command to wait for data to appear. +``` +$ tail -f mypipe + +``` + +Once the process that will be feeding the pipe has finished, we will see some output. +``` +$ tail -f mypipe +Uranus replicated to WCDC7 +Saturn replicated to WCDC8 +Pluto replicated to WCDC9 +Server replication operation completed + +``` + +If you look at the process writing to a named pipe, you might be surprised by how little resources it uses. In the ps output below, the only significant resource use is virtual memory (the VSZ column). +``` +ps u -P 80038 +USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND +shs 80038 0.0 0.0 108488 764 pts/4 S 15:25 0:00 -bash + +``` + +Named pipes are different enough from the more commonly used Unix/Linux pipes to warrant a different name, but "pipe" really invokes a good image of how they move data between processes, so "named pipe" fits pretty well. Maybe you'll come across a task that will benefit significantly from this very clever Unix/Linux feature. + + +-------------------------------------------------------------------------------- + +via: https://www.networkworld.com/article/3251853/linux/why-use-named-pipes-on-linux.html + +作者:[Sandra Henry-Stocker][a] +译者:[译者ID](https://github.com/译者ID) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://www.networkworld.com/author/Sandra-Henry_Stocker/ +[1]:http://www.networkworld.com/article/2926630/linux/11-pointless-but-awesome-linux-terminal-tricks.html#tk.nww-fsb From 7981f922a3e0d4abf2b61ee34021b52bd76482e1 Mon Sep 17 00:00:00 2001 From: Ezio Date: Fri, 2 Feb 2018 15:20:07 +0800 Subject: [PATCH 132/272] =?UTF-8?q?20180202=20=E9=80=89=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ... your tools Navigating your Git History.md | 161 ++ ... and manage MacOS LaunchAgents using Go.md | 305 ++++ .../tech/20180130 Trying Other Go Versions.md | 112 ++ ...ience Courses You Can Start in February.md | 1406 +++++++++++++++++ ... Webhooks when youre developing locally.md | 222 +++ ...eat resume that actually gets you hired.md | 395 +++++ ...t I Learned from Programming Interviews.md | 140 ++ ... Rendering in React using Ternaries and.md | 206 +++ ...ges of Go that you dont hear much about.md | 223 +++ ...y a React App on a DigitalOcean Droplet.md | 199 +++ ... React.js Foundations A Beginners Guide.md | 292 ++++ 11 files changed, 3661 insertions(+) create mode 100644 sources/tech/20160606 Learn your tools Navigating your Git History.md create mode 100644 sources/tech/20180130 Create and manage MacOS LaunchAgents using Go.md create mode 100644 sources/tech/20180130 Trying Other Go Versions.md create mode 100644 sources/tech/20180131 440 Free Online Programming Computer Science Courses You Can Start in February.md create mode 100644 sources/tech/20180131 How to test Webhooks when youre developing locally.md create mode 100644 sources/tech/20180131 How to write a really great resume that actually gets you hired.md create mode 100644 sources/tech/20180131 What I Learned from Programming Interviews.md create mode 100644 sources/tech/20180201 Conditional Rendering in React using Ternaries and.md create mode 100644 sources/tech/20180201 Here are some amazing advantages of Go that you dont hear much about.md create mode 100644 sources/tech/20180201 I Built This - Now What How to deploy a React App on a DigitalOcean Droplet.md create mode 100644 sources/tech/20180201 Rock Solid React.js Foundations A Beginners Guide.md diff --git a/sources/tech/20160606 Learn your tools Navigating your Git History.md b/sources/tech/20160606 Learn your tools Navigating your Git History.md new file mode 100644 index 0000000000..2d17cac30b --- /dev/null +++ b/sources/tech/20160606 Learn your tools Navigating your Git History.md @@ -0,0 +1,161 @@ +Learn your tools: Navigating your Git History +============================================================ + +Starting a greenfield application everyday is nearly impossible, especially in your daily job. In fact, most of us are facing (somewhat) legacy codebases on a daily basis, and regaining the context of why some feature, or line of code exists in the codebase is very important. This is where `git`, the distributed version control system, is invaluable. Let’s dive in and see how we can use our `git` history and easily navigate through it. + +### Git history + +First and foremost, what is `git` history? As the name says, it is the commit history of a `git` repo. It contains a bunch of commit messages, with their authors’ name, the commit hash and the date of the commit. The easiest way to see the history of a `git`repo, is the `git log` command. + +Sidenote: For the purpose of this post, we will use Ruby on Rails’ repo, the `master`branch. The reason behind this is because Rails has a very good `git` history, with nice commit messages, references and explanations behind every change. Given the size of the codebase, the age and the number of maintainers, it’s certainly one of the best repositories that I have seen. Of course, I am not saying there are no other repositories built with good `git` practices, but this is one that has caught my eye. + +So back to Rails’ repo. If you run `git log` in the Rails’ repo, you will see something like this: + +``` +commit 66ebbc4952f6cfb37d719f63036441ef98149418Author: Arthur Neves Date: Fri Jun 3 17:17:38 2016 -0400 Dont re-define class SQLite3Adapter on test We were declaring in a few tests, which depending of the order load will cause an error, as the super class could change. see https://github.com/rails/rails/commit/ac1c4e141b20c1067af2c2703db6e1b463b985da#commitcomment-17731383commit 755f6bf3d3d568bc0af2c636be2f6df16c651eb1Merge: 4e85538 f7b850eAuthor: Eileen M. Uchitelle Date: Fri Jun 3 10:21:49 2016 -0400 Merge pull request #25263 from abhishekjain16/doc_accessor_thread [skip ci] Fix grammarcommit f7b850ec9f6036802339e965c8ce74494f731b4aAuthor: Abhishek Jain Date: Fri Jun 3 16:49:21 2016 +0530 [skip ci] Fix grammarcommit 4e85538dddf47877cacc65cea6c050e349af0405Merge: 082a515 cf2158cAuthor: Vijay Dev Date: Fri Jun 3 14:00:47 2016 +0000 Merge branch 'master' of github.com:rails/docrails Conflicts: guides/source/action_cable_overview.mdcommit 082a5158251c6578714132e5c4f71bd39f462d71Merge: 4bd11d4 3bd30d9Author: Yves Senn Date: Fri Jun 3 11:30:19 2016 +0200 Merge pull request #25243 from sukesan1984/add_i18n_validation_test Add i18n_validation_testcommit 4bd11d46de892676830bca51d3040f29200abbfaMerge: 99d8d45 e98caf8Author: Arthur Nogueira Neves Date: Thu Jun 2 22:55:52 2016 -0400 Merge pull request #25258 from alexcameron89/master [skip ci] Make header bullets consistent in engines.mdcommit e98caf81fef54746126d31076c6d346c48ae8e1bAuthor: Alex Kitchens Date: Thu Jun 2 21:26:53 2016 -0500 [skip ci] Make header bullets consistent in engines.md +``` + +As you can see, the `git log` shows the commit hash, the author and his email and the date of when the commit was created. Of course, `git` being super customisable, it allows you to customise the output format of the `git log` command. Let’s say, we want to just see the first line of the commit message, we could run `git log --oneline`, which will produce a more compact log: + +``` +66ebbc4 Dont re-define class SQLite3Adapter on test755f6bf Merge pull request #25263 from abhishekjain16/doc_accessor_threadf7b850e [skip ci] Fix grammar4e85538 Merge branch 'master' of github.com:rails/docrails082a515 Merge pull request #25243 from sukesan1984/add_i18n_validation_test4bd11d4 Merge pull request #25258 from alexcameron89/mastere98caf8 [skip ci] Make header bullets consistent in engines.md99d8d45 Merge pull request #25254 from kamipo/fix_debug_helper_test818397c Merge pull request #25240 from matthewd/reloadable-channels2c5a8ba Don't blank pad day of the month when formatting dates14ff8e7 Fix debug helper test +``` + +To see all of the `git log` options, I recommend checking out manpage of `git log`, available in your terminal via `man git-log` or `git help log`. A tip: if `git log` is a bit scarse or complicated to use, or maybe you are just bored, I recommend checking out various `git` GUIs and command line tools. In the past I’ve used [GitX][1] which was very good, but since the command line feels like home to me, after trying [tig][2] I’ve never looked back. + +### Finding Nemo + +So now, since we know the bare minimum of the `git log` command, let’s see how we can explore the history more effectively in our everyday work. + +Let’s say, hypothetically, we are suspecting an unexpected behaviour in the`String#classify` method and we want to find how and where it has been implemented. + +One of the first commands that you can use, to see where the method is defined, is `git grep`. Simply said, this command prints out lines that match a certain pattern. Now, to find the definition of the method, it’s pretty simple - we can grep for `def classify` and see what we get: + +``` +➜ git grep 'def classify'activesupport/lib/active_support/core_ext/string/inflections.rb: def classifyactivesupport/lib/active_support/inflector/methods.rb: def classify(table_name)tools/profile: def classify +``` + +Now, although we can already see where our method is created, we are not sure on which line it is. If we add the `-n` flag to our `git grep` command, `git` will provide the line numbers of the match: + +``` +➜ git grep -n 'def classify'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 +``` + +Much better, right? Having the context in mind, we can easily figure out that the method that we are looking for lives in `activesupport/lib/active_support/core_ext/string/inflections.rb`, on line 205\. The `classify` method, in all of it’s glory looks like this: + +``` +# Creates a class name from a plural table name like Rails does for table names to models.# Note that this returns a string and not a class. (To convert to an actual class# follow +classify+ with +constantize+.)## 'ham_and_eggs'.classify # => "HamAndEgg"# 'posts'.classify # => "Post"def classify ActiveSupport::Inflector.classify(self)end +``` + +Although the method we found is the one we usually call on `String`s, it invokes another method on the `ActiveSupport::Inflector`, with the same name. Having our `git grep` result available, we can easily navigate there, since we can see the second line of the result being`activesupport/lib/active_support/inflector/methods.rb` on line 186\. The method that we are are looking for is: + +``` +# Creates a class name from a plural table name like Rails does for table# names to models. Note that this returns a string and not a Class (To# convert to an actual class follow +classify+ with #constantize).## classify('ham_and_eggs') # => "HamAndEgg"# classify('posts') # => "Post"## Singular names are not handled correctly:## classify('calculus') # => "Calculus"def classify(table_name) # strip out any leading schema name camelize(singularize(table_name.to_s.sub(/.*\./, ''.freeze)))end +``` + +Boom! Given the size of Rails, finding this should not take us more than 30 seconds with the help of `git grep`. + +### So, what changed last? + +Now, since we have the method available, we need to figure out what were the changes that this file has gone through. The since we know the correct file name and line number, we can use `git blame`. This command shows what revision and author last modified each line of a file. Let’s see what were the latest changes made to this file: + +``` +git blame activesupport/lib/active_support/inflector/methods.rb +``` + +Whoa! Although we get the last change of every line in the file, we are more interested in the specific method (lines 176 to 189). Let’s add a flag to the `git blame` command, that will show the blame of just those lines. Also, we will add the `-s` (suppress) option to the command, to skip the author names and the timestamp of the revision (commit) that changed the line: + +``` +git blame -L 176,189 -s activesupport/lib/active_support/inflector/methods.rb9fe8e19a 176) # Creates a class name from a plural table name like Rails does for table5ea3f284 177) # names to models. Note that this returns a string and not a Class (To9fe8e19a 178) # convert to an actual class follow +classify+ with #constantize).51cd6bb8 179) #6d077205 180) # classify('ham_and_eggs') # => "HamAndEgg"9fe8e19a 181) # classify('posts') # => "Post"51cd6bb8 182) #51cd6bb8 183) # Singular names are not handled correctly:5ea3f284 184) #66d6e7be 185) # classify('calculus') # => "Calculus"51cd6bb8 186) def classify(table_name)51cd6bb8 187) # strip out any leading schema name5bb1d4d2 188) camelize(singularize(table_name.to_s.sub(/.*\./, ''.freeze)))51cd6bb8 189) end +``` + +The output of the `git blame` command now shows all of the file lines and their respective revisions. Now, to see a specific revision, or in other words, what each of those revisions changed, we can use the `git show` command. When supplied a revision hash (like `66d6e7be`) as an argument, it will show you the full revision, with the author name, timestamp and the whole revision in it’s glory. Let’s see what actually changed at the latest revision that changed line 188: + +``` +git show 5bb1d4d2 +``` + +Whoa! Did you test that? If you didn’t, it’s an awesome [commit][3] by [Schneems][4] that made a very interesting performance optimization by using frozen strings, which makes sense in our current context. But, since we are on this hypothetical debugging session, this doesn’t tell much about our current problem. So, how can we see what changes has our method under investigation gone through? + +### Searching the logs + +Now, we are back to the `git` log. The question is, how can we see all the revisions that the `classify` method went under? + +The `git log` command is quite powerful, because it has a rich list of options to apply to it. We can try to see what the `git` log has stored for this file, using the `-p`options, which means show me the patch for this entry in the `git` log: + +``` +git log -p activesupport/lib/active_support/inflector/methods.rb +``` + +This will show us a big list of revisions, for every revision of this file. But, just like before, we are interested in the specific file lines. Let’s modify the command a bit, to show us what we need: + +``` +git log -L 176,189:activesupport/lib/active_support/inflector/methods.rb +``` + +The `git log` command accepts the `-L` option, which takes the lines range and the filename as arguments. The format might be a bit weird for you, but it translates to: + +``` +git log -L ,: +``` + +When we run this command, we can see the list of revisions for these lines, which will lead us to the first revision that created the method: + +``` +commit 51xd6bb829c418c5fbf75de1dfbb177233b1b154Author: Foo Bar Date: Tue Jun 7 19:05:09 2011 -0700 Refactordiff --git a/activesupport/lib/active_support/inflector/methods.rb b/activesupport/lib/active_support/inflector/methods.rb--- a/activesupport/lib/active_support/inflector/methods.rb+++ b/activesupport/lib/active_support/inflector/methods.rb@@ -58,0 +135,14 @@+ # Create a class name from a plural table name like Rails does for table names to models.+ # Note that this returns a string and not a Class. (To convert to an actual class+ # follow +classify+ with +constantize+.)+ #+ # Examples:+ # "egg_and_hams".classify # => "EggAndHam"+ # "posts".classify # => "Post"+ #+ # Singular names are not handled correctly:+ # "business".classify # => "Busines"+ def classify(table_name)+ # strip out any leading schema name+ camelize(singularize(table_name.to_s.sub(/.*\./, '')))+ end +``` + +Now, look at that - it’s a commit from 2011\. Practically, `git` allows us to travel back in time. This is a very good example of why a proper commit message is paramount to regain context, because from the commit message we cannot really regain context of how this method came to be. But, on the flip side, you should **never ever** get frustrated about it, because you are looking at someone that basically gives away his time and energy for free, doing open source work. + +Coming back from that tangent, we are not sure how the initial implementation of the `classify` method came to be, given that the first commit is just a refactor. Now, if you are thinking something within the lines of “but maybe, just maybe, the method was not on the line range 176 to 189, and we should look more broadly in the file”, you are very correct. The revision that we saw said “Refactor” in it’s commit message, which means that the method was actually there, but after that refactor it started to exist on that line range. + +So, how can we confirm this? Well, believe it or not, `git` comes to the rescue again. The `git log` command accepts the `-S` option, which looks for the code change (additions or deletions) for the specified string as an argument to the command. This means that, if we call `git log -S classify`, we can see all of the commits that changed a line that contains that string. + +If you call this command in the Rails repo, you will first see `git` slowing down a bit. But, when you realise that `git` actually parses all of the revisions in the repo to match the string, it’s actually super fast. Again, the power of `git` at your fingertips. So, to find the first version of the `classify` method, we can run: + +``` +git log -S 'def classify' +``` + +This will return all of the revisions where this method has been introduced or changed. If you were following along, the last commit in the log that you will see is: + +``` +commit db045dbbf60b53dbe013ef25554fd013baf88134Author: David Heinemeier Hansson Date: Wed Nov 24 01:04:44 2004 +0000 Initial git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@4 5ecf4fe2-1ee6-0310-87b1-e25e094e27de +``` + +How cool is that? It’s the initial commit to Rails, made on a `svn` repo by DHH! This means that `classify` has been around since the beginning of (Rails) time. Now, to see the commit with all of it’s changes, we can run: + +``` +git show db045dbbf60b53dbe013ef25554fd013baf88134 +``` + +Great, we got to the bottom of it. Now, by using the output from `git log -S 'def classify'` you can track the changes that have happened to this method, combined with the power of the `git log -L` command. + +### Until next time + +Sure, we didn’t really fix any bugs, because we were trying some `git` commands and following along the evolution of the `classify` method. But, nevertheless, `git` is a very powerful tool that we all must learn to use and to embrace. I hope this article gave you a little bit more knowledge of how useful `git` is. + +What are your favourite (or, most effective) ways of navigating through the `git`history? + +-------------------------------------------------------------------------------- + +作者简介: + +Backend engineer, interested in Ruby, Go, microservices, building resilient architectures and solving challenges at scale. I coach at Rails Girls in Amsterdam, maintain a list of small gems and often contribute to Open Source. +This is where I write about software development, programming languages and everything else that interests me. + +------ + +via: https://ieftimov.com/learn-your-tools-navigating-git-history + +作者:[Ilija Eftimov ][a] +译者:[译者ID](https://github.com/译者ID) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://ieftimov.com/ +[1]:http://gitx.frim.nl/ +[2]:https://github.com/jonas/tig +[3]:https://github.com/rails/rails/commit/5bb1d4d288d019e276335465d0389fd2f5246bfd +[4]:https://twitter.com/schneems \ No newline at end of file diff --git a/sources/tech/20180130 Create and manage MacOS LaunchAgents using Go.md b/sources/tech/20180130 Create and manage MacOS LaunchAgents using Go.md new file mode 100644 index 0000000000..8bd6b8bf64 --- /dev/null +++ b/sources/tech/20180130 Create and manage MacOS LaunchAgents using Go.md @@ -0,0 +1,305 @@ +Create and manage MacOS LaunchAgents using Go +============================================================ + +If you have ever tried writing a daemon for MacOS you have met with `launchd`. For those that don’t have the experience, think of it as a framework for starting, stopping and managing daemons, applications, processes, and scripts. If you have any *nix experience the word daemon should not be too alien to you. + +For those unfamiliar, a daemon is a program running in the background without requiring user input. A typical daemon might, for instance, perform daily maintenance tasks or scan a device for malware when connected. + +This post is aimed at folks that know a little bit about what daemons are, what is the common way of using them and know a bit about Go. Also, if you have ever written a daemon for any other *nix system, you will have a good idea of what we are going to talk here. If you are an absolute beginner in Go or systems this might prove to be an overwhelming article. Still, feel free to give it a shot and let me know how it goes. + +If you ever find yourself wanting to write a MacOS daemon with Go you would like to know most of the stuff we are going to talk about in this article. Without further ado, let’s dive in. + +### What is `launchd` and how it works? + +`launchd` is a unified service-management framework, that starts, stops and manages daemons, applications, processes, and scripts in MacOS. + +One of its key features is that it differentiates between agents and daemons. In `launchd` land, an agent runs on behalf of the logged in user while a daemon runs on behalf of the root user or any specified user. + +### Defining agents and daemons + +An agent/daemon is defined in an XML file, which states the properties of the program that will execute, among a list of other properties. Another aspect to keep in mind is that `launchd` decides if a program will be treated as a daemon or an agent by where the program XML is located. + +Over at [launchd.info][3], there’s a simple table that shows where you would (or not) place your program’s XML: + +``` ++----------------+-------------------------------+----------------------------------------------------+| Type | Location | Run on behalf of |+----------------+-------------------------------+----------------------------------------------------+| User Agents | ~/Library/LaunchAgents | Currently logged in user || Global Agents | /Library/LaunchAgents | Currently logged in user || Global Daemons | /Library/LaunchDaemons | root or the user specified with the key 'UserName' || System Agents | /System/Library/LaunchAgents | Currently logged in user || System Daemons | /System/Library/LaunchDaemons | root or the user specified with the key 'UserName' |+----------------+-------------------------------+----------------------------------------------------+ +``` + +This means that when we set our XML file in, for example, the `/Library/LaunchAgents` path our process will be treated as a global agent. The main difference between the daemons and agents is that LaunchDaemons will run as root, and are generally background processes. On the other hand, LaunchAgents are jobs that will run as a user or in the context of userland. These may be scripts or other foreground items and they also have access to the MacOS UI (e.g. you can send notifications, control the windows, etc.) + +So, how do we define an agent? Let’s take a look at a simple XML file that `launchd`understands: + +``` + Label com.example.app Program /Users/Me/Scripts/cleanup.sh RunAtLoad +``` + +The XML is quite self-explanatory, unless it’s the first time you are seeing an XML file. The file has three main properties, with values. In fact, if you take a better look you will see the `dict` keyword which means `dictionary`. This actually means that the XML represents a key-value structure, so in Go it would look like: + +``` +map[string]string{ "Label": "com.example.app", "Program": "/Users/Me/Scripts/cleanup.sh", "RunAtLoad": "true",} +``` + +Let’s look at each of the keys: + +1. `Label` - The job definition or the name of the job. This is the unique identifier for the job within the `launchd` instance. Usually, the label (and hence the name) is written in [Reverse domain name notation][1]. + +2. `Program` - This key defines what the job should start, in our case a script with the path `/Users/Me/Scripts/cleanup.sh`. + +3. `RunAtLoad` - This key specifies when the job should be run, in this case right after it’s loaded. + +As you can see, the keys used in this XML file are quite self-explanatory. This is the case for the remaining 30-40 keys that `launchd` supports. Last but not least these files although have an XML syntax, in fact, they have a `.plist` extension (which means `Property List`). Makes a lot of sense, right? + +### `launchd` v.s. `launchctl` + +Before we continue with our little exercise of creating daemons/agents with Go, let’s first see how `launchd` allows us to control these jobs. While `launchd`’s job is to boot the system and to load and maintain services, there is a different command used for jobs management - `launchctl`. With `launchd` facilitating jobs, the control of services is centralized in the `launchctl` command. + +`launchctl` has a long list of subcommands that we can use. For example, loading or unloading a job is done via: + +``` +launchctl unload/load ~/Library/LaunchAgents/com.example.app.plist +``` + +Or, starting/stopping a job is done via: + +``` +launchctl start/stop ~/Library/LaunchAgents/com.example.app.plist +``` + +To get any confusion out of the way, `load` and `start` are different. While `start`only starts the agent/daemon, `load` loads the job and it might also start it if the job is configured to run on load. This is achieved by setting the `RunAtLoad` property in the property list XML of the job: + +``` + Label com.example.app Program /Users/Me/Scripts/cleanup.sh RunAtLoad +``` + +If you would like to see what other commands `launchctl` supports, you can run`man launchctl` in your terminal and see the options in detail. + +### Automating with Go + +After getting the basics of `launchd` and `launctl` out of the way, why don’t we see how we can add an agent to any Go package? For our example, we are going to write a simple way of plugging in a `launchd` agent for any of your Go packages. + +As we already established before, `launchd` speaks in XML. Or, rather, it understands XML files, called  _property lists_  (or `.plist`). This means, for our Go package to have an agent running on MacOS, it will need to tell `launchd` “hey, `launchd`, run this thing!”. And since `launch` speaks only in `.plist`, that means our package needs to be capable of generating XML files. + +### Templates in Go + +While one could have a hardcoded `.plist` file in their project and copy it across to the `~/Library/LaunchAgents` path, a more programmatical way to do this would be to use a template to generate these XML files. The good thing is Go’s standard library has us covered - the `text/template` package ([docs][4]) does exactly what we need. + +In a nutshell, `text/template` implements data-driven templates for generating textual output. Or in other words, you give it a template and a data structure, it will mash them up together and produce a nice and clean text file. Perfect. + +Let’s say the `.plist` we need to generate in our case is the following: + +``` + LabelTicker Program/usr/local/bin/ticker StandardOutPath/tmp/ticker.out.log StandardErrorPath/tmp/ticker.err.log KeepAlive RunAtLoad +``` + +We want to keep it quite simple in our little exercise. It will contain only six properties: `Label`, `Program`, `StandardOutPath`, `StandardErrorPath`, `KeepAlive` and `RunAtLoad`. To generate such a XML, its template would look something like this: + +``` + + + + + Label{{.Label}} + Program{{.Program}} + StandardOutPath/tmp/{{.Label}}.out.log + StandardErrorPath/tmp/{{.Label}}.err.log + KeepAlive<{{.KeepAlive}}/> + RunAtLoad<{{.RunAtLoad}}/> + + + +``` + +As you can see, the difference between the two XMLs is that the second one has the double curly braces with expressions in them in places where the first XML has some sort of a value. These are called “actions”, which can be data evaluations or control structures and are delimited by “ and “. Any of the text outside actions is copied to the output untouched. + +### Injecting your data + +Now that we have our template with its glorious XML and curly braces (or actions), let’s see how we can inject our data into it. Since things are generally simple in Go, especially when it comes to its standard library, you should not worry - this will be easy! + +To keep thing simple, we will store the whole XML template in a plain old string. Yes, weird, I know. The best way would be to store it in a file and read it from there, or embed it in the binary itself, but in our little example let’s keep it simple: + +``` +// template.go +package main + +func Template() string { + return ` + + + + + Label{{.Label}} + Program{{.Program}} + StandardOutPath/tmp/{{.Label}}.out.log + StandardErrorPath/tmp/{{.Label}}.err.log + KeepAlive<{{.KeepAlive}}/> + RunAtLoad<{{.RunAtLoad}}/> + + +` +} + +``` + +And the program that will use our little template function: + +``` +// main.gopackage mainimport ( "log" "os" "text/template")func main() { data := struct { Label string Program string KeepAlive bool RunAtLoad bool }{ Label: "ticker", Program: "/usr/local/bin/ticker", KeepAlive: true, RunAtLoad: true, } t := template.Must(template.New("launchdConfig").Parse(Template())) err := t.Execute(os.Stdout, data) if err != nil { log.Fatalf("Template generation failed: %s", err) }} +``` + +So, what happens there, in the `main` function? It’s actually quite simple: + +1. We declare a small `struct`, which has only the properties that will be needed in the template, and we immediately initialize it with the values for our program. + +2. We build a new template, using the `template.New` function, with the name`launchdConfig`. Then, we invoke the `Parse` function on it, which takes the XML template as an argument. + +3. We invoke the `template.Must` function, which takes our built template as argument. From the documentation, `template.Must` is a helper that wraps a call to a function returning `(*Template, error)` and panics if the error is non-`nil`. Actually, `template.Must` is built to, in a way, validate if the template can be understood by the `text/template` package. + +4. Finally, we invoke `Execute` on our built template, which takes a data structure and applies its attributes to the actions in the template. Then it sends the output to `os.Stdout`, which does the trick for our example. Of course, the output can be sent to any struct that implements the `io.Writer` interface, like a file (`os.File`). + +### Make and load my `.plist` + +Instead of sending all this nice XML to standard out, let’s throw in an open file descriptor to the `Execute` function and finally save our `.plist` file in`~/Library/LaunchAgents`. There are a couple of main points we need to change. + +First, getting the location of the binary. Since it’s a Go binary, and we will install it via `go install`, we can assume that the path will be at `$GOPATH/bin`. Second, since we don’t know the actual `$HOME` of the current user, we will have to get it through the environment. Both of these can be done via `os.Getenv` ([docs][5]) which takes a variable name and returns its value. + +``` +// main.gopackage mainimport ( "log" "os" "text/template")func main() { data := struct { Label string Program string KeepAlive bool RunAtLoad bool }{ Label: "com.ieftimov.ticker", // Reverse-DNS naming convention Program: fmt.Sprintf("%s/bin/ticker", os.Getenv("GOPATH")), KeepAlive: true, RunAtLoad: true, } plistPath := fmt.Sprintf("%s/Library/LaunchAgents/%s.plist", os.Getenv("HOME"), data.Label) f, err := os.Open(plistPath) t := template.Must(template.New("launchdConfig").Parse(Template())) err := t.Execute(f, data) if err != nil { log.Fatalf("Template generation failed: %s", err) }} +``` + +That’s about it. The first part, about setting the correct `Program` property, is done by concatenating the name of the program and `$GOPATH`: + +``` +fmt.Sprintf("%s/bin/ticker", os.Getenv("GOPATH"))// Output: /Users//go/bin/ticker +``` + +The second part is slightly more complex, and it’s done by concatenating three strings, the `$HOME` environment variable, the `Label` property of the program and the `/Library/LaunchAgents` string: + +``` +fmt.Sprintf("%s/Library/LaunchAgents/%s.plist", os.Getenv("HOME"), data.Label)// Output: /Users//Library/LaunchAgents/com.ieftimov.ticker.plist +``` + +By having these two paths, opening the file and writing to it is very trivial - we open the file via `os.Open` and we pass in the `os.File` structure to `t.Execute` which writes to the file descriptor. + +### What about the Launch Agent? + +We will keep this one simple as well. Let’s throw in a command to our package, make it installable via `go install` (not that there’s much to it) and make it runnable by our `.plist` file: + +``` +// cmd/ticker/main.gopackage tickerimport ( "time" "fmt")func main() { for range time.Tick(30 * time.Second) { fmt.Println("tick!") }} +``` + +This the `ticker` program will use `time.Tick`, to execute an action every 30 seconds. Since this will be an infinite loop, `launchd` will kick off the program on boot (because `RunAtLoad` is set to `true` in the `.plist` file) and will keep it running. But, to make the program controllable from the operating system, we need to make the program react to some OS signals, like `SIGINT` or `SIGTERM`. + +### Understanding and handling OS signals + +While there’s quite a bit to be learned about OS signals, in our example we will scratch a bit off the surface. (If you know a lot about inter-process communication this might be too much of an oversimplification to you - and I apologize up front. Feel free to drop some links on the topic in the comments so others can learn more!) + +The best way to think about a signal is that it’s a message from the operating system or another process, to a process. It is an asynchronous notification sent to a process or to a specific thread within the same process to notify it of an event that occurred. + +There are quite a bit of various signals that can be sent to a process (or a thread), like `SIGKILL` (which kills a process), `SIGSTOP` (stop), `SIGTERM` (termination), `SIGILL`and so on and so forth. There’s an exhaustive list of signal types on [Wikipedia’s page][6]on signals. + +To get back to `launchd`, if we look at its documentation about stopping a job we will notice the following: + +> Stopping a job will send the signal `SIGTERM` to the process. Should this not stop the process launchd will wait `ExitTimeOut` seconds (20 seconds by default) before sending `SIGKILL`. + +Pretty self-explanatory, right? We need to handle one signal - `SIGTERM`. Why not `SIGKILL`? Because `SIGKILL` is a special signal that cannot be caught - it kills the process without any chance for a graceful shutdown, no questions asked. That’s why there’s a termination signal and a “kill” signal. + +Let’s throw in a bit of signal handling in our code, so our program knows that it needs to exit when it gets told to do so: + +``` +package mainimport ( "fmt" "os" "os/signal" "syscall" "time")func main() { sigs := make(chan os.Signal, 1) signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM) go func() { <-sigs os.Exit(0) }() for range time.Tick(30 * time.Second) { fmt.Println("tick!") }} +``` + +In the new version, the agent program has two new packages imported: `os/signal`and `syscall`. `os/signal` implements access to incoming signals, that are primarily used on Unix-like systems. Since in this article we are specifically interested in MacOS, this is exactly what we need. + +Package `syscall` contains an interface to the low-level operating system primitives. An important note about `syscall` is that it is locked down since Go v1.4\. This means that any code outside of the standard library that uses the `syscall` package should be migrated to use the new `golang.org/x/sys` [package][7]. Since we are using **only**the signals constants of `syscall` we can get away with this. + +(If you want to read more about the package lockdown, you can see [the rationale on locking it down][8] by the Go team and the new [golang.org/s/sys][9] package.) + +Having the basics of the packages out of the way, let’s go step by step through the new lines of code added: + +1. We make a buffered channel of type `os.Signal`, with a size of `1`. `os.Signal`is a type that represents an operating system signal. + +2. We call `signal.Notify` with the new channel as an argument, plus`syscall.SIGINT` and `syscall.SIGTERM`. This function states “when the OS sends a `SIGINT` or a `SIGTERM` signal to this program, send the signal to the channel”. This allows us to somehow handle the sent OS signal. + +3. The new goroutine that we spawn waits for any of the signals to arrive through the channel. Since we know that any of the signals that will arrive are about shutting down the program, after receiving any signal we use `os.Exit(0)`([docs][2]) to gracefully stop the program. One caveat here is that if we had any `defer`red calls they would not be run. + +Now `launchd` can run the agent program and we can `load` and `unload`, `start`and `stop` it using `launchctl`. + +### Putting it all together + +Now that we have all the pieces ready, we need to put them together to a good use. Our application will consist of two binaries - a CLI tool and an agent (daemon). Both of the programs will be stored in separate subdirectories of the `cmd` directory. + +The CLI tool: + +``` +// cmd/cli/main.gopackage mainimport ( "log" "os" "text/template")func main() { data := struct { Label string Program string KeepAlive bool RunAtLoad bool }{ Label: "com.ieftimov.ticker", // Reverse-DNS naming convention Program: fmt.Sprintf("%s/bin/ticker", os.Getenv("GOPATH")), KeepAlive: true, RunAtLoad: true, } plistPath := fmt.Sprintf("%s/Library/LaunchAgents/%s.plist", os.Getenv("HOME"), data.Label) f, err := os.Open(plistPath) t := template.Must(template.New("launchdConfig").Parse(Template())) err := t.Execute(f, data) if err != nil { log.Fatalf("Template generation failed: %s", err) }} +``` + +And the ticker program: + +``` +// cmd/ticker/main.gopackage mainimport ( "fmt" "os" "os/signal" "syscall" "time")func main() { sigs := make(chan os.Signal, 1) signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM) go func() { <-sigs os.Exit(0) }() for range time.Tick(30 * time.Second) { fmt.Println("tick!") }} +``` + +To install them both, we need to run `go install ./...` in the project root. The command will install all the sub-packages that are located within the project. This will leave us with two available binaries, installed in the `$GOPATH/bin` path. + +To install our launch agent, we need to run only the CLI tool, via the `cli` command. This will generate the `.plist` file and place it in the `~/Library/LaunchAgents`path. We don’t need to touch the `ticker` binary - that one will be managed by `launchd`. + +To load the newly created `.plist` file, we need to run: + +``` +launchctl load ~/Library/LaunchAgents/com.ieftimov.ticker.plist +``` + +When we run it, we will not see anything immediately, but after 30 seconds the ticker will add a `tick!` line in `/tmp/ticker.out.log`. We can `tail` the file to see the new lines being added. If we want to unload the agent, we can use: + +``` +launchctl unload ~/Library/LaunchAgents/com.ieftimov.ticker.plist +``` + +This will unload the launch agent and will stop the ticker from running. Remember the signal handling we added? This is the case where it’s being used! Also, we could have automated the (un)loading of the file via the CLI tool but for simplicity, we left it out. You can try to improve the CLI tool by making it a bit smarter with subcommands and flags, as a follow-up exercise from this tutorial. + +Finally, if you decide to completely delete the launch agent, you can remove the`.plist` file: + +``` +rm ~/Library/LaunchAgents/com.ieftimov.ticker.plist +``` + +### In closing + +As part of this (quite long!) article, we saw how we can work with `launchd` and Golang. We took a detour, like learning about `launchd` and `launchctl`, generating XML files using the `text/template` package, we took a look at OS signals and how we can gracefully shutdown a Go program by handling the `SIGINT` and `SIGTERM`signals. There was quite a bit to learn and see, but we got to the end. + +Of course, we only scratched the surface with this article. For example, `launchd` is quite an interesting tool. You can use it also like `crontab` because it allows running programs at explicit time/date combinations or on specific days. Or, for example, the XML template can be embedded in the program binary using tools like [`go-bindata`][10], instead of hardcoding it in a function. Also, you explore more about signals, how they work and how Go implements these low-level primitives so you can use them with ease in your programs. The options are plenty, feel free to explore! + +If you have found any mistakes in the article, feel free to drop a comment below - I will appreciate it a ton. I find learning through teaching (blogging) a very pleasant experience and would like to have all the details fully correct in my posts. + +-------------------------------------------------------------------------------- + +作者简介: + +Backend engineer, interested in Ruby, Go, microservices, building resilient architectures and solving challenges at scale. I coach at Rails Girls in Amsterdam, maintain a list of small gems and often contribute to Open Source. +This is where I write about software development, programming languages and everything else that interests me. + +--------------------- + + +via: https://ieftimov.com/create-manage-macos-launchd-agents-golang + +作者:[Ilija Eftimov ][a] +译者:[译者ID](https://github.com/译者ID) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://ieftimov.com/about +[1]:https://ieftimov.com/en.wikipedia.org/wiki/Reverse_domain_name_notation +[2]:https://godoc.org/os#Exit +[3]:https://launchd.info/ +[4]:https://godoc.org/text/template +[5]:https://godoc.org/os#Getenv +[6]:https://en.wikipedia.org/wiki/Signal_(IPC) +[7]:https://golang.org/x/sys +[8]:https://docs.google.com/document/d/1QXzI9I1pOfZPujQzxhyRy6EeHYTQitKKjHfpq0zpxZs/edit +[9]:https://golang.org/x/sys +[10]:https://github.com/jteeuwen/go-bindata \ No newline at end of file diff --git a/sources/tech/20180130 Trying Other Go Versions.md b/sources/tech/20180130 Trying Other Go Versions.md new file mode 100644 index 0000000000..731747d19a --- /dev/null +++ b/sources/tech/20180130 Trying Other Go Versions.md @@ -0,0 +1,112 @@ +Trying Other Go Versions +============================================================ + +While I generally use the current release of Go, sometimes I need to try a different version. For example, I need to check that all the examples in my [Guide to JSON][2] work with [both the supported releases of Go][3](1.8.6 and 1.9.3 at time of writing) along with go1.10rc1. + +I primarily use the current version of Go, updating it when new versions are released. I try out other versions as needed following the methods described in this article. + +### Trying Betas and Release Candidates[¶][4] + +When [go1.8beta2 was released][5], a new tool for trying the beta and release candidates was also released that allowed you to `go get` the beta. It allowed you to easily run the beta alongside your Go installation by getting the beta with: + +``` +go get golang.org/x/build/version/go1.8beta2 +``` + +This downloads and builds a small program that will act like the `go` tool for that specific version. The full release can then be downloaded and installed with: + +``` +go1.8beta2 download +``` + +This downloads the release from [https://golang.org/dl][6] and installs it into `$HOME/sdk` or `%USERPROFILE%\sdk`. + +Now you can use `go1.8beta2` as if it were the normal Go command. + +This method works for [all the beta and release candidates][7] released after go1.8beta2. + +### Trying a Specific Release[¶][8] + +While only beta and release candidates are provided, they can easily be adapted to work with any released version. For example, to use go1.9.2: + +``` +package main + +import ( + "golang.org/x/build/version" +) + +func main() { + version.Run("go1.9.2") +} +``` + +Replace `go1.9.2` with the release you want to run and build/install as usual. + +Since the program I use to build my [Guide to JSON][9] calls `go` itself (for each example), I build this as `go` and prepend the directory to my `PATH` so it will use this one instead of my normal version. + +### Trying Any Release[¶][10] + +This small program can be extended so you can specify the release to use instead of having to maintain binaries for each version. + +``` +package main + +import ( + "fmt" + "os" + + "golang.org/x/build/version" +) + +func main() { + if len(os.Args) < 2 { + fmt.Printf("USAGE: %v [commands as normal]\n", + os.Args[0]) + os.Exit(1) + } + + v := os.Args[1] + os.Args = append(os.Args[0:1], os.Args[2:]...) + + version.Run("go" + v) +} +``` + +I have this installed as `gov` and run it like `gov 1.8.6 version`, using the version I want to run. + +### Trying a Source Build (e.g., tip)[¶][11] + +I also use this same infrastructure to manage source builds of Go, such as tip. There’s just a little trick to it: + +* use the directory `$HOME/sdk/go` (e.g., `$HOME/sdk/gotip`) + +* [build as normal][1] + +* `touch $HOME/sdk/go/.unpacked-success` This is an empty file used as a sentinel to indicate the download and unpacking was successful. + +(On Windows, replace `$HOME/sdk` with `%USERPROFILE%\sdk`) + + +-------------------------------------------------------------------------------- + +via: https://pocketgophers.com/trying-other-versions/ + +作者:[Nathan Kerr ][a] +译者:[译者ID](https://github.com/译者ID) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:nathan@pocketgophers.com +[1]:https://golang.org/doc/install/source +[2]:https://pocketgophers.com/guide-to-json/ +[3]:https://pocketgophers.com/when-should-you-upgrade-go/ +[4]:https://pocketgophers.com/trying-other-versions/#trying-betas-and-release-candidates +[5]:https://groups.google.com/forum/#!topic/golang-announce/LvfYP-Wk1s0 +[6]:https://golang.org/dl +[7]:https://godoc.org/golang.org/x/build/version#pkg-subdirectories +[8]:https://pocketgophers.com/trying-other-versions/#trying-a-specific-release +[9]:https://pocketgophers.com/guide-to-json/ +[10]:https://pocketgophers.com/trying-other-versions/#trying-any-release +[11]:https://pocketgophers.com/trying-other-versions/#trying-a-source-build-e-g-tip \ No newline at end of file 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 new file mode 100644 index 0000000000..e400049fb5 --- /dev/null +++ b/sources/tech/20180131 440 Free Online Programming Computer Science Courses You Can Start in February.md @@ -0,0 +1,1406 @@ +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 \ No newline at end of file diff --git a/sources/tech/20180131 How to test Webhooks when youre developing locally.md b/sources/tech/20180131 How to test Webhooks when youre developing locally.md new file mode 100644 index 0000000000..78242caae9 --- /dev/null +++ b/sources/tech/20180131 How to test Webhooks when youre developing locally.md @@ -0,0 +1,222 @@ +How to test Webhooks when you’re developing locally +============================================================ + +![](https://cdn-images-1.medium.com/max/1000/1*0HNQmPw5yXva6powvVwn5Q.jpeg) +Photo by [Fernando Venzano][1] on [Unsplash][2] + +[Webhooks][10] can be used by an external system for notifying your system about a certain event or update. Probably the most well known type is the one where a Payment Service Provider (PSP) informs your system about status updates of payments. + +Often they come in the form where you listen on a predefined URL. For example [http://example.com/webhooks/payment-update][11]. Meanwhile the other system sends a POST request with a certain payload to that URL (for example a payment ID). As soon as the request comes in, you fetch the payment ID, ask the PSP for the latest status via their API, and update your database afterward. + +Other examples can be found in this excellent explanation about Webhooks. [https://sendgrid.com/blog/whats-webhook/][12]. + +Testing these webhooks goes fairly smoothly as long as the system is publicly accessible over the internet. This might be your production environment or a publicly accessible staging environment. It becomes harder when you are developing locally on your laptop or inside a Virtual Machine (VM, for example, a Vagrant box). In those cases, the local URL’s are not publicly accessible by the party sending the webhook. Also, monitoring the requests being sent around is be difficult, which might make development and debugging hard. + +What will this example solve: + +* Testing webhooks from a local development environment, which is not accessible over the internet. It cannot be accessed by the service sending the data to the webhook from their servers. + +* Monitor the requests and data being sent around, but also the response your application generates. This will allow easier debugging, and therefore a shorter development cycle. + +Prerequisites: + +* _Optional_ : in case you are developing using a Virtual Machine (VM), make sure it’s running and make sure the next steps are done in the VM. + +* For this tutorial, we assume you have a vhost defined at `webhook.example.vagrant`. I used a Vagrant VM for this tutorial, but you are free in choosing the name of your vhost. + +* Install `ngrok`by following the [installation instructions][3]. Inside a VM, I find the Node version of it also useful: [https://www.npmjs.com/package/ngrok][4], but feel free to use other methods. + +I assume you don’t have SSL running in your environment, but if you do, feel free to replace port 80 with port 433 and  `_http://_`  with  `_https://_`  in the examples below. + +#### Make the webhook testable + +Let’s assume the following example code. I’ll be using PHP, but read it as pseudo-code as I left some crucial parts out (for example API keys, input validation, etc.) + +The first file:  _payment.php_ . This file creates a payment object and then registers it with the PSP. It then fetches the URL the customer needs to visit in order to pay and redirects the user to the customer in there. + +Note that the `webhook.example.vagrant` in this example is the local vhost we’ve defined for our development set-up. It’s not accessible from the outside world. + +``` + 123, + 'amount' => 25.00, + 'description' => 'Test payment', + 'redirect_url' => 'http://webhook.example.vagrant/redirect.php', + 'webhook_url' => 'http://webhook.example.vagrant/webhook.php', +]; +``` + +``` +$payment = $paymentProvider->createPayment($payment); +header("Location: " . $payment->getPaymentUrl()); +``` + +Second file:  _webhook.php_ . This file waits to be called by the PSP to get notified about updates. + +``` +getPayment($paymentId); +$status = $paymentInfo->getStatus(); +``` + +``` +// Perform actions in here to update your system +if ($status === 'paid') { + .. +} +elseif ($status === 'cancelled') { + .. +} +``` + +Our webhook URL is not accessible over the internet (remember: `webhook.example.vagrant`). Thus, the file  _webhook.php_  will never be called by the PSP. Your system will never get to know about the payment status. This ultimately leads to orders never being shipped to customers. + +Luckily,  _ngrok_  can in solving this problem.  [_ngrok_][13]  describes itself as: + +> ngrok exposes local servers behind NATs and firewalls to the public internet over secure tunnels. + +Let’s start a basic tunnel for our project. On your environment (either on your system or on the VM) run the following command: + +`ngrok http -host-header=rewrite webhook.example.vagrant:80` + +Read about more configuration options in their documentation: [https://ngrok.com/docs][14]. + +A screen like this will come up: + + +![](https://cdn-images-1.medium.com/max/1000/1*BZZE-CvZwHZ3pxsElJMWbA.png) +ngrok output + +What did we just start? Basically, we instructed `ngrok` to start a tunnel to `[http://webhook.example.vagr][5]ant` at port 80\. This same URL can now be reached via `[http://39741ffc.ngrok.i][6]o` or `[https://39741ffc.ngrok.io][7]`[,][15] They are publicly accessible over the internet by anyone that knows this URL. + +Note that you get both HTTP and HTTPS available out of the box. The documentation gives examples of how to restrict this to HTTPS only: [https://ngrok.com/docs#bind-tls][16]. + +So, how do we make our webhook work now? Update  _payment.php_  to the following code: + +``` + 123, + 'amount' => 25.00, + 'description' => 'Test payment', + 'redirect_url' => 'http://webhook.example.vagrant/redirect.php', + 'webhook_url' => 'https://39741ffc.ngrok.io/webhook.php', +]; +``` + +``` +$payment = $paymentProvider->createPayment($payment); +header("Location: " . $payment->getPaymentUrl()); +``` + +Now, we told the PSP to call the tunnel URL over HTTPS.  _ngrok_  will make sure your internal URL get’s called with an unmodified payload, as soon as the PSP calls the webhook via the tunnel. + +#### How to monitor calls to the webhook? + +The screenshot you’ve seen above gives an overview of the calls being made to the tunnel host. This data is rather limited. Fortunately, `ngrok` offers a very nice dashboard, which allows you to inspect all calls: + + +![](https://cdn-images-1.medium.com/max/1000/1*qZw9GRTnG1sMgEUmsJPz3g.png) + +I won’t go into this very deep because it’s self-explanatory as soon as you have it running. Therefore I will explain how to access it on the Vagrant box as it doesn’t work out of the box. + +The dashboard will allow you to see all the calls, their status codes, the headers and data being sent around. You will also see the response your application generated. + +Another neat feature of the dashboard is that it allows you to replay a certain call. Let’s say your webhook code ran into a fatal error, it would be tedious to start a new payment and wait for the webhook to be called. Replaying the previous call makes your development process way faster. + +The dashboard by default is accessible at [http://localhost:4040.][17] + +#### Dashboard in a VM + +In order to make this work inside a VM, you have to perform some additional steps: + +First, make sure the VM can be accessed on port 4040\. Then, create a file inside the VM holding this configuration: + +`web_addr: 0.0.0.0:4040` + +Now, kill the `ngrok` process that’s still running and start it with this slightly adjusted command: + +`ngrok http -config=/path/to/config/ngrok.conf -host-header=rewrite webhook.example.vagrant:80` + +You will get a screen looking similar to the previous screenshot though the ID’s have changed. The previous URL doesn’t work anymore, but you got a new URL. Also, the `Web Interface` URL got changed: + + +![](https://cdn-images-1.medium.com/max/1000/1*3FZq37TF4dmBqRc1R0FMVg.png) + +Now direct your browser to `[http://webhook.example.vagrant:4040][8]` to access the dashboard. Also, make a call to `[https://e65642b5.ngrok.io/webhook.php][9]`[.][18]This will probably result in an error in your browser, but the dashboard should show the request being made. + +#### Final remarks + +The examples above are pseudo-code. The reason is that every external system uses webhooks in a different way. I tried to give an example based on a fictive PSP implementation, as probably many developers have to deal with payments at some moment. + +Please be aware that your webhook URL can also be used by others with bad intentions. Make sure to validate any input being sent to it. + +Preferably also add a token to the URL which is unique for each payment. This token must only be known by your system and the system sending the webhook. + +Good luck testing and debugging your webhooks! + +Note: I haven’t tested this tutorial on Docker. However, this Docker container looks like a good starting point and includes clear instructions. [https://github.com/wernight/docker-ngrok][19]. + +Stefan Doorn + +[https://github.com/stefandoorn][20] +[https://twitter.com/stefan_doorn][21] +[https://www.linkedin.com/in/stefandoorn][22] + +-------------------------------------------------------------------------------- + +作者简介: + +Backend Developer (PHP/Node/Laravel/Symfony/Sylius) + + +-------- + +via: https://medium.freecodecamp.org/testing-webhooks-while-using-vagrant-for-development-98b5f3bedb1d + +作者:[Stefan Doorn ][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/@stefandoorn +[1]:https://unsplash.com/photos/MYTyXb7fgG0?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText +[2]:https://unsplash.com/?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText +[3]:https://ngrok.com/download +[4]:https://www.npmjs.com/package/ngrok +[5]:http://webhook.example.vagrnat/ +[6]:http://39741ffc.ngrok.io/ +[7]:http://39741ffc.ngrok.io/ +[8]:http://webhook.example.vagrant:4040/ +[9]:https://e65642b5.ngrok.io/webhook.php. +[10]:https://sendgrid.com/blog/whats-webhook/ +[11]:http://example.com/webhooks/payment-update%29 +[12]:https://sendgrid.com/blog/whats-webhook/ +[13]:https://ngrok.com/ +[14]:https://ngrok.com/docs +[15]:http://39741ffc.ngrok.io%2C/ +[16]:https://ngrok.com/docs#bind-tls +[17]:http://localhost:4040./ +[18]:https://e65642b5.ngrok.io/webhook.php. +[19]:https://github.com/wernight/docker-ngrok +[20]:https://github.com/stefandoorn +[21]:https://twitter.com/stefan_doorn +[22]:https://www.linkedin.com/in/stefandoorn \ No newline at end of file diff --git a/sources/tech/20180131 How to write a really great resume that actually gets you hired.md b/sources/tech/20180131 How to write a really great resume that actually gets you hired.md new file mode 100644 index 0000000000..b54b3944ae --- /dev/null +++ b/sources/tech/20180131 How to write a really great resume that actually gets you hired.md @@ -0,0 +1,395 @@ +How to write a really great resume that actually gets you hired +============================================================ + + +![](https://cdn-images-1.medium.com/max/2000/1*k7HRLZAsuINP9vIs2BIh1g.png) + +This is a data-driven guide to writing a resume that actually gets you hired. I’ve spent the past four years analyzing which resume advice works regardless of experience, role, or industry. The tactics laid out below are the result of what I’ve learned. They helped me land offers at Google, Microsoft, and Twitter and have helped my students systematically land jobs at Amazon, Apple, Google, Microsoft, Facebook, and more. + +### Writing Resumes Sucks. + +It’s a vicious cycle. + +We start by sifting through dozens of articles by career “gurus,” forced to compare conflicting advice and make our own decisions on what to follow. + +The first article says “one page MAX” while the second says “take two or three and include all of your experience.” + +The next says “write a quick summary highlighting your personality and experience” while another says “summaries are a waste of space.” + +You scrape together your best effort and hit “Submit,” sending your resume into the ether. When you don’t hear back, you wonder what went wrong: + + _“Was it the single page or the lack of a summary? Honestly, who gives a s**t at this point. I’m sick of sending out 10 resumes every day and hearing nothing but crickets.”_ + + +![](https://cdn-images-1.medium.com/max/1000/1*_zQqAjBhB1R4fz55InrrIw.jpeg) +How it feels to try and get your resume read in today’s world. + +Writing resumes sucks but it’s not your fault. + +The real reason it’s so tough to write a resume is because most of the advice out there hasn’t been proven against the actual end goal of getting a job. If you don’t know what consistently works, you can’t lay out a system to get there. + +It’s easy to say “one page works best” when you’ve seen it happen a few times. But how does it hold up when we look at 100 resumes across different industries, experience levels, and job titles? + +That’s what this article aims to answer. + +Over the past four years, I’ve personally applied to hundreds of companies and coached hundreds of people through the job search process. This has given me a huge opportunity to measure, analyze, and test the effectiveness of different resume strategies at scale. + +This article is going to walk through everything I’ve learned about resumes over the past 4 years, including: + +* Mistakes that more than 95% of people make, causing their resumes to get tossed immediately + +* Three things that consistently appear in the resumes of highly effective job searchers (who go on to land jobs at the world’s best companies) + +* A quick hack that will help you stand out from the competition and instantly build relationships with whomever is reading your resume (increasing your chances of hearing back and getting hired) + +* The exact resume template that got me interviews and offers at Google, Microsoft, Twitter, Uber, and more + +Before we get to the unconventional strategies that will help set you apart, we need to make sure our foundational bases are covered. That starts with understanding the mistakes most job seekers make so we can make our resume bulletproof. + +### Resume Mistakes That 95% Of People Make + +Most resumes that come through an online portal or across a recruiter’s desk are tossed out because they violate a simple rule. + +When recruiters scan a resume, the first thing they look for is mistakes. Your resume could be fantastic, but if you violate a rule like using an unprofessional email address or improper grammar, it’s going to get tossed out. + +Our goal is to fully understand the triggers that cause recruiters/ATS systems to make the snap decisions on who stays and who goes. + +In order to get inside the heads of these decision makers, I collected data from dozens of recruiters and hiring mangers across industries. These people have several hundred years of hiring experience under their belts and they’ve reviewed 100,000+ resumes across industries. + +They broke down the five most common mistakes that cause them to cut resumes from the pile: + + +![](https://cdn-images-1.medium.com/max/1000/1*5Zbr3HFeKSjvPGZdq_LCKA.png) + +### The Five Most Common Resume Mistakes (According To Recruiters & Hiring Managers) + +Issue #1: Sloppiness (typos, spelling errors, & grammatical mistakes). Close to 60% of resumes have some sort of typo or grammatical issue. + +Solution: Have your resume reviewed by three separate sources — spell checking software, a friend, and a professional. Spell check should be covered if you’re using Microsoft Word or Google Docs to create your resume. + +A friend or family member can cover the second base, but make sure you trust them with reviewing the whole thing. You can always include an obvious mistake to see if they catch it. + +Finally, you can hire a professional editor on [Upwork][1]. It shouldn’t take them more than 15–20 minutes to review so it’s worth paying a bit more for someone with high ratings and lots of hours logged. + +Issue #2: Summaries are too long and formal. Many resumes include summaries that consist of paragraphs explaining why they are a “driven, results oriented team player.” When hiring managers see a block of text at the top of the resume, you can bet they aren’t going to read the whole thing. If they do give it a shot and read something similar to the sentence above, they’re going to give up on the spot. + +Solution: Summaries are highly effective, but they should be in bullet form and showcase your most relevant experience for the role. For example, if I’m applying for a new business sales role my first bullet might read “Responsible for driving $11M of new business in 2018, achieved 168% attainment (#1 on my team).” + +Issue #3: Too many buzz words. Remember our driven team player from the last paragraph? Phrasing like that makes hiring managers cringe because your attempt to stand out actually makes you sound like everyone else. + +Solution: Instead of using buzzwords, write naturally, use bullets, and include quantitative results whenever possible. Would you rather hire a salesperson who “is responsible for driving new business across the healthcare vertical to help companies achieve their goals” or “drove $15M of new business last quarter, including the largest deal in company history”? Skip the buzzwords and focus on results. + +Issue #4: Having a resume that is more than one page. The average employer spends six seconds reviewing your resume — if it’s more than one page, it probably isn’t going to be read. When asked, recruiters from Google and Barclay’s both said multiple page resumes “are the bane of their existence.” + +Solution: Increase your margins, decrease your font, and cut down your experience to highlight the most relevant pieces for the role. It may seem impossible but it’s worth the effort. When you’re dealing with recruiters who see hundreds of resumes every day, you want to make their lives as easy as possible. + +### More Common Mistakes & Facts (Backed By Industry Research) + +In addition to personal feedback, I combed through dozens of recruitment survey results to fill any gaps my contacts might have missed. Here are a few more items you may want to consider when writing your resume: + +* The average interviewer spends 6 seconds scanning your resume + +* The majority of interviewers have not looked at your resume until +  you walk into the room + +* 76% of resumes are discarded for an unprofessional email address + +* Resumes with a photo have an 88% rejection rate + +* 58% of resumes have typos + +* Applicant tracking software typically eliminates 75% of resumes due to a lack of keywords and phrases being present + +Now that you know every mistake you need to avoid, the first item on your to-do list is to comb through your current resume and make sure it doesn’t violate anything mentioned above. + +Once you have a clean resume, you can start to focus on more advanced tactics that will really make you stand out. There are a few unique elements you can use to push your application over the edge and finally get your dream company to notice you. + + +![](https://cdn-images-1.medium.com/max/1000/1*KthhefFO33-8tm0kBEPbig.jpeg) + +### The 3 Elements Of A Resume That Will Get You Hired + +My analysis showed that highly effective resumes typically include three specific elements: quantitative results, a simple design, and a quirky interests section. This section breaks down all three elements and shows you how to maximize their impact. + +### Quantitative Results + +Most resumes lack them. + +Which is a shame because my data shows that they make the biggest difference between resumes that land interviews and resumes that end up in the trash. + +Here’s an example from a recent resume that was emailed to me: + +> Experience + +> + Identified gaps in policies and processes and made recommendations for solutions at the department and institution level + +> + Streamlined processes to increase efficiency and enhance quality + +> + Directly supervised three managers and indirectly managed up to 15 staff on multiple projects + +> + Oversaw execution of in-house advertising strategy + +> + Implemented comprehensive social media plan + +As an employer, that tells me absolutely nothing about what to expect if I hire this person. + +They executed an in-house marketing strategy. Did it work? How did they measure it? What was the ROI? + +They also also identified gaps in processes and recommended solutions. What was the result? Did they save time and operating expenses? Did it streamline a process resulting in more output? + +Finally, they managed a team of three supervisors and 15 staffers. How did that team do? Was it better than the other teams at the company? What results did they get and how did those improve under this person’s management? + +See what I’m getting at here? + +These types of bullets talk about daily activities, but companies don’t care about what you do every day. They care about results. By including measurable metrics and achievements in your resume, you’re showcasing the value that the employer can expect to get if they hire you. + +Let’s take a look at revised versions of those same bullets: + +> Experience + +> + Managed a team of 20 that consistently outperformed other departments in lead generation, deal size, and overall satisfaction (based on our culture survey) + +> + Executed in-house marketing strategy that resulted in a 15% increase in monthly leads along with a 5% drop in the cost per lead + +> + Implemented targeted social media campaign across Instagram & Pintrest, which drove an additional 50,000 monthly website visits and generated 750 qualified leads in 3 months + +If you were in the hiring manager’s shoes, which resume would you choose? + +That’s the power of including quantitative results. + +### Simple, Aesthetic Design That Hooks The Reader + +These days, it’s easy to get carried away with our mission to “stand out.” I’ve seen resume overhauls from graphic designers, video resumes, and even resumes [hidden in a box of donuts.][2] + +While those can work in very specific situations, we want to aim for a strategy that consistently gets results. The format I saw the most success with was a black and white Word template with sections in this order: + +* Summary + +* Interests + +* Experience + +* Education + +* Volunteer Work (if you have it) + +This template is effective because it’s familiar and easy for the reader to digest. + +As I mentioned earlier, hiring managers scan resumes for an average of 6 seconds. If your resume is in an unfamiliar format, those 6 seconds won’t be very comfortable for the hiring manager. Our brains prefer things we can easily recognize. You want to make sure that a hiring manager can actually catch a glimpse of who you are during their quick scan of your resume. + +If we’re not relying on design, this hook needs to come from the  _Summary_ section at the top of your resume. + +This section should be done in bullets (not paragraph form) and it should contain 3–4 highlights of the most relevant experience you have for the role. For example, if I was applying for a New Business Sales position, my summary could look like this: + +> Summary + +> Drove quarterly average of $11M in new business with a quota attainment of 128% (#1 on my team) + +> Received award for largest sales deal of the year + +> Developed and trained sales team on new lead generation process that increased total leads by 17% in 3 months, resulting in 4 new deals worth $7M + +Those bullets speak directly to the value I can add to the company if I was hired for the role. + +### An “Interests” Section That’s Quirky, Unique, & Relatable + +This is a little “hack” you can use to instantly build personal connections and positive associations with whomever is reading your resume. + +Most resumes have a skills/interests section, but it’s usually parked at the bottom and offers little to no value. It’s time to change things up. + +[Research shows][3] that people rely on emotions, not information, to make decisions. Big brands use this principle all the time — emotional responses to advertisements are more influential on a person’s intent to buy than the content of an ad. + +You probably remember Apple’s famous “Get A Mac” campaign: + + +When it came to specs and performance, Macs didn’t blow every single PC out of the water. But these ads solidified who was “cool” and who wasn’t, which was worth a few extra bucks to a few million people. + +By tugging at our need to feel “cool,” Apple’s campaign led to a [42% increase in market share][4] and a record sales year for Macbooks. + +Now we’re going to take that same tactic and apply it to your resume. + +If you can invoke an emotional response from your recruiter, you can influence the mental association they assign to you. This gives you a major competitive advantage. + +Let’s start with a question — what could you talk about for hours? + +It could be cryptocurrency, cooking, World War 2, World of Warcraft, or how Google’s bet on segmenting their company under the Alphabet is going to impact the technology sector over the next 5 years. + +Did a topic (or two) pop into year head? Great. + +Now think about what it would be like to have a conversation with someone who was just as passionate and knew just as much as you did on the topic. It’d be pretty awesome, right?  _Finally, _ someone who gets it! + +That’s exactly the kind of emotional response we’re aiming to get from a hiring manager. + +There are five “neutral” topics out there that people enjoy talking about: + +1. Food/Drink + +2. Sports + +3. College + +4. Hobbies + +5. Geography (travel, where people are from, etc.) + +These topics are present in plenty of interest sections but we want to take them one step further. + +Let’s say you had the best night of your life at the Full Moon Party in Thailand. Which of the following two options would you be more excited to read: + +* Traveling + +* Ko Pha Ngan beaches (where the full moon party is held) + +Or, let’s say that you went to Duke (an ACC school) and still follow their basketball team. Which would you be more pumped about: + +* College Sports + +* ACC Basketball (Go Blue Devils!) + +In both cases, the second answer would probably invoke a larger emotional response because it is tied directly to your experience. + +I want you to think about your interests that fit into the five categories I mentioned above. + +Now I want you to write a specific favorite associated with each category in parentheses next to your original list. For example, if you wrote travel you can add (ask me about the time I was chased by an elephant in India) or (specifically meditation in a Tibetan monastery). + +Here is the [exact set of interests][5] I used on my resume when I interviewed at Google, Microsoft, and Twitter: + + _ABC Kitchen’s Atmosphere, Stumptown Coffee (primarily cold brew), Michael Lewis (Liar’s Poker), Fishing (especially fly), Foods That Are Vehicles For Hot Sauce, ACC Sports (Go Deacs!) & The New York Giants_ + + +![](https://cdn-images-1.medium.com/max/1000/1*ONxtGr_xUYmz4_Xe66aeng.jpeg) + +If you want to cheat here, my experience shows that anything about hot sauce is an instant conversation starter. + +### The Proven Plug & Play Resume Template + +Now that we have our strategies down, it’s time to apply these tactics to a real resume. Our goal is to write something that increases your chances of hearing back from companies, enhances your relationships with hiring managers, and ultimately helps you score the job offer. + +The example below is the exact resume that I used to land interviews and offers at Microsoft, Google, and Twitter. I was targeting roles in Account Management and Sales, so this sample is tailored towards those positions. We’ll break down each section below: + + +![](https://cdn-images-1.medium.com/max/1000/1*B2RQ89ue2dGymRdwMY2lBA.png) + +First, I want you to notice how clean this is. Each section is clearly labeled and separated and flows nicely from top to bottom. + +My summary speaks directly to the value I’ve created in the past around company culture and its bottom line: + +* I consistently exceeded expectations + +* I started my own business in the space (and saw real results) + +* I’m a team player who prioritizes culture + +I purposefully include my Interests section right below my Summary. If my hiring manager’s six second scan focused on the summary, I know they’ll be interested. Those bullets cover all the subconscious criteria for qualification in sales. They’re going to be curious to read more in my Experience section. + +By sandwiching my Interests in the middle, I’m upping their visibility and increasing the chance of creating that personal connection. + +You never know — the person reading my resume may also be a hot sauce connoisseur and I don’t want that to be overlooked because my interests were sitting at the bottom. + +Next, my Experience section aims to flesh out the points made in my Summary. I mentioned exceeding my quota up top, so I included two specific initiatives that led to that attainment, including measurable results: + +* A partnership leveraging display advertising to drive users to a gamified experience. The campaign resulted in over 3000 acquisitions and laid the groundwork for the 2nd largest deal in company history. + +* A partnership with a top tier agency aimed at increasing conversions for a client by improving user experience and upgrading tracking during a company-wide website overhaul (the client has ~20 brand sites). Our efforts over 6 months resulted in a contract extension worth 316% more than their original deal. + +Finally, I included my education at the very bottom starting with the most relevant coursework. + +Download My Resume Templates For Free + +You can download a copy of the resume sample above as well as a plug and play template here: + +Austin’s Resume: [Click To Download][6] + +Plug & Play Resume Template: [Click To Download][7] + +### Bonus Tip: An Unconventional Resume “Hack” To Help You Beat Applicant Tracking Software + +If you’re not already familiar, Applicant Tracking Systems are pieces of software that companies use to help “automate” the hiring process. + +After you hit submit on your online application, the ATS software scans your resume looking for specific keywords and phrases (if you want more details, [this article][8] does a good job of explaining ATS). + +If the language in your resume matches up, the software sees it as a good fit for the role and will pass it on to the recruiter. However, even if you’re highly qualified for the role but you don’t use the right wording, your resume can end up sitting in a black hole. + +I’m going to teach you a little hack to help improve your chances of beating the system and getting your resume in the hands of a human: + +Step 1: Highlight and select the entire job description page and copy it to your clipboard. + +Step 2: Head over to [WordClouds.com][9] and click on the “Word List” button at the top. Towards the top of the pop up box, you should see a link for Paste/Type Text. Go ahead and click that. + +Step 3: Now paste the entire job description into the box, then hit “Apply.” + +WordClouds is going to spit out an image that showcases every word in the job description. The larger words are the ones that appear most frequently (and the ones you want to make sure to include when writing your resume). Here’s an example for a data a science role: + + +![](https://cdn-images-1.medium.com/max/1000/1*O7VO1C9nhC9LZct7vexTbA.png) + +You can also get a quantitative view by clicking “Word List” again after creating your cloud. That will show you the number of times each word appeared in the job description: + +9 data + +6 models + +4 experience + +4 learning + +3 Experience + +3 develop + +3 team + +2 Qualifications + +2 statistics + +2 techniques + +2 libraries + +2 preferred + +2 research + +2 business + +When writing your resume, your goal is to include those words in the same proportions as the job description. + +It’s not a guaranteed way to beat the online application process, but it will definitely help improve your chances of getting your foot in the door! + +* * * + +### Want The Inside Info On Landing A Dream Job Without Connections, Without “Experience,” & Without Applying Online? + +[Click here to get the 5 free strategies that my students have used to land jobs at Google, Microsoft, Amazon, and more without applying online.][10] + + _Originally published at _ [_cultivatedculture.com_][11] _._ + +-------------------------------------------------------------------------------- + +作者简介: + +I help people land jobs they love and salaries they deserve at CultivatedCulture.com + +---------- + +via: https://medium.freecodecamp.org/how-to-write-a-really-great-resume-that-actually-gets-you-hired-e18533cd8d17 + +作者:[Austin Belcak ][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/@austin.belcak +[1]:http://www.upwork.com/ +[2]:https://www.thrillist.com/news/nation/this-guy-hides-his-resume-in-boxes-of-donuts-to-score-job-interviews +[3]:https://www.psychologytoday.com/blog/inside-the-consumer-mind/201302/how-emotions-influence-what-we-buy +[4]:https://www.businesswire.com/news/home/20070608005253/en/Apple-Mac-Named-Successful-Marketing-Campaign-2007 +[5]:http://cultivatedculture.com/resume-skills-section/ +[6]:https://drive.google.com/file/d/182gN6Kt1kBCo1LgMjtsGHOQW2lzATpZr/view?usp=sharing +[7]:https://drive.google.com/open?id=0B3WIcEDrxeYYdXFPVlcyQlJIbWc +[8]:https://www.jobscan.co/blog/8-things-you-need-to-know-about-applicant-tracking-systems/ +[9]:https://www.wordclouds.com/ +[10]:https://cultivatedculture.com/dreamjob/ +[11]:https://cultivatedculture.com/write-a-resume/ \ No newline at end of file diff --git a/sources/tech/20180131 What I Learned from Programming Interviews.md b/sources/tech/20180131 What I Learned from Programming Interviews.md new file mode 100644 index 0000000000..17fde91392 --- /dev/null +++ b/sources/tech/20180131 What I Learned from Programming Interviews.md @@ -0,0 +1,140 @@ +What I Learned from Programming Interviews +============================================================ + +![](https://cdn-images-1.medium.com/max/1250/1*DXPdaGPM4oM6p5nSkup7IQ.jpeg) +Whiteboard programming interviews + +In 2017, I went to the [Grace Hopper Celebration][1] of women in computing. It’s the largest gathering of this kind, with 17,000 women attending last year. + +This conference has a huge career fair where companies interview attendees. Some even get offers. Walking around the area, I noticed that some people looked stressed and worried. I overheard conversations, and some talked about how they didn’t do well in the interview. + +I approached a group of people that I overheard and gave them advice. I considered some of the advice I gave to be basic, such as “it’s okay to think of the naive solution first.” But people were surprised by most of the advice I gave them. + +I wanted to help more people with this. I gathered a list of tips that worked for me and published a [podcast episode][2] about them. They’re also the topic of this post. + +I’ve had many programming interviews both for internships and full-time jobs. When I was in college studying Computer Science, there was a career fair every fall semester where the first round of interviews took place. I have failed at the first and final rounds of interviews. After each interview, I reflected on what I could’ve done better and had mock up interviews with friends who gave me feedback. + +Whether we find a job through a job portal, networking, or university recruiting, part of the process involves doing a technical interview. + +In recent years we’ve seen different interview formats emerge: + +* Pair programming with an engineer + +* Online quiz and online coding + +* Whiteboard interviews + +I’ll focus on the whiteboard interview because it’s the one that I have experienced. I’ve had many interviews. Some of them have gone well, while others haven’t. + +### What I did wrong + +First, I want to go over the things I did wrong in my interviews. This helps see the problems and what to improve. + +When an interviewer gave me a technical problem, I immediately went to the whiteboard and started trying to solve it.  _Without saying a word._ + +I made two mistakes here: + +#### Not clarifying information that is crucial to solve a problem + +For example, are we only working with numbers or also strings? Are we supporting multiple data types? If you don’t ask questions before you start working on a question, your interviewer can get the impression that you won’t ask questions before you start working on a project at their company. This is an important skill to have in the workplace. It is not like school anymore. You don’t get an assignment with all the steps detailed for you. You have to find out what those are and define them. + +#### Thinking without writing or communicating + +Often times I stood there thinking without writing. When I was doing a mock interview with a friend, he told me that he knew I was thinking because we had worked together. To a stranger, it can seem that I’m clueless, or that I’m thinking. It is also important not to rush on a solution right away. Take some time to brainstorm ideas. Sometimes the interviewer will gladly participate in this. After all, that’s how it is at work meetings. + +### Coming up with a solution + +Before you begin writing code, it helps if you come up with the algorithm first. Don’t start writing code and hope that you’ll solve the problem as you write. + +This is what has worked for me: + +1. Brainstorm + +2. Coding + +3. Error handling + +4. Testing + +#### 1\. Brainstorm + +For me, it helps to visualize first what the problem is through a series of examples. If it’s a problem related to trees, I would start with the null case, one node, two nodes, three nodes. This can help you generalize a solution. + +On the whiteboard, write down a list of the things the algorithm needs to do. This way, you can find bugs and issues before writing any code. Just keep track of the time. I made a mistake once where I spent too much time asking clarifying questions and brainstorming, and I barely had time to write the code. The downside of this is that your interviewer doesn’t get to see how you code. You can also come off as if you’re trying to avoid the coding portion. It helps to wear a wrist watch, or if there’s a clock in the room, look at it occasionally. Sometimes the interviewer will tell you, “I think we have the necessary information, let’s start coding it.” + +#### 2\. Coding and code walkthrough + +If you don’t have the solution right away, it always helps to point out the obvious naive solution. While you’re explaining this, you should be thinking of how to improve it. When you state the obvious, indicate why it is not the best solution. For this it helps to be familiar with big O notation. It is okay to go over 2–3 solutions first. The interviewer sometimes guides you by saying, “Can we do better?” This can sometimes mean they are looking for a more efficient solution. + +#### 3\. Error handling + +While you’re coding, point out that you’re leaving a code comment for error handling. Once an interviewer said, “That’s a good point. How would you handle it? Would you throw an exception? Or return a specific value?” This can make for a good short discussion about code quality. Mention a few error cases. Other times, the interviewer might say that you can assume that the parameters you’re getting already passed a validation. However, it is still important to bring this up to show that you are aware of error cases and quality. + +#### 4\. Testing + +After you have finished coding the solution, re-use the examples from brainstorming to walk through your code and make sure it works. For example you can say, “Let’s go over the example of a tree with one node, two nodes.” + +After you finish this, the interviewer sometimes asks you how you would test your code, and what your test cases would be. I recommend that you organize your test cases in different categories. + +Some examples are: + +1. Performance + +2. Error cases + +3. Positive expected cases + +For performance, think about extreme quantities. For example, if the problem is about lists, mention that you would have a case with a large list and a really small list. If it’s about numbers, you’ll test the maximum integer number and the smallest. I recommend reading about testing software to get more ideas. My favorite book on this is [How We Test Software at Microsoft][3]. + +For error cases, think about what is expected to fail and list those. + +For positive expected cases, it helps to think of what the user requirements are. What are the cases that this solution is meant to solve? Those are the positive test cases. + +### “Do you have any questions for me?” + +Almost always there will be a few minutes dedicated at the end for you to ask questions. I recommend that you write down the questions you would ask your interviewer before the interview. Don’t say, “I don’t have any questions.” Even if you feel the interview didn’t go well, or you’re not super passionate about the company, there’s always something you can ask. It can be about what the person likes and hates most about his or her job. Or it can be something related to the person’s work, or technologies and practices used at the company. Don’t feel discouraged to ask something even if you feel you didn’t do well. + +### Applying for a job + +As for searching and applying for a job, I’ve been told that you should only apply to a place that you would be truly passionate to work for. They say pick a company that you love, or a product that you enjoy using, and see if you can work there. + +I don’t recommend that you always do this. You can rule out many good options this way, especially if you’re looking for an internship or an entry-level job. + +You can focus on other goals instead. What do I want to get more experience in? Is it cloud computing, web development, or artificial intelligence? When you talk to companies at the career fair, find out if their job openings are in this area. You might find a really good position at a company or a non-profit that wasn’t in your list. + +#### Switching teams + +After a year and a half at my first team, I decided that it was time to explore something different. I found a team I liked and had 4 rounds of interviews. I didn’t do well. + +I didn’t practice anything, not even simply writing on a whiteboard. My logic had been, if I have been working at the company for almost 2 years, why would I need to practice? I was wrong about this. I struggled to write a solution on the whiteboard. Things like my writing being too small and running out of space by not starting at the top left all contributed to not passing. + +I hadn’t brushed up on data structures and algorithms. If I had, I would’ve been more confident. Even if you’ve been working at a company as a Software Engineer, before you do a round of interviews with another team, I strongly recommend you go through practice problems on a whiteboard. + +As for finding a team, if you are looking to switch teams at your company, it helps to talk informally with members of that team. For this, I found that almost everyone is willing to have lunch with you. People are mostly available at noon too, so there is low risk of lack of availability and meeting conflicts. This is an informal way to find out what the team is working on, and see what the personalities of your potential team members are like. You can learn many things from lunch meetings that can help you in the formal interviews. + +It is important to know that at the end of the day, you are interviewing for a specific team. Even if you do really well, you might not get an offer because you are not a culture fit. That’s part of why I try to meet different people in the team first, but this is not always possible. Don’t get discouraged by a rejection, keep your options open, and practice. + +This content is from the [“Programming interviews”][4] episode on [The Women in Tech Show: Technical Interviews with Prominent Women in Tech][5]. + +-------------------------------------------------------------------------------- + +作者简介: + +Software Engineer II at Microsoft Research, opinions are my own, host of www.thewomenintechshow.com + +------------ + +via: https://medium.freecodecamp.org/what-i-learned-from-programming-interviews-29ba49c9b851 + +作者:[Edaena Salinas ][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/@edaenas +[1]:https://anitab.org/event/2017-grace-hopper-celebration-women-computing/ +[2]:https://thewomenintechshow.com/2017/12/18/programming-interviews/ +[3]:https://www.amazon.com/How-We-Test-Software-Microsoft/dp/0735624259 +[4]:https://thewomenintechshow.com/2017/12/18/programming-interviews/ +[5]:https://thewomenintechshow.com/ \ No newline at end of file diff --git a/sources/tech/20180201 Conditional Rendering in React using Ternaries and.md b/sources/tech/20180201 Conditional Rendering in React using Ternaries and.md new file mode 100644 index 0000000000..b5f740c92c --- /dev/null +++ b/sources/tech/20180201 Conditional Rendering in React using Ternaries and.md @@ -0,0 +1,206 @@ +Conditional Rendering in React using Ternaries and Logical AND +============================================================ + + +![](https://cdn-images-1.medium.com/max/2000/1*eASRJrCIVgsy5VbNMAzD9w.jpeg) +Photo by [Brendan Church][1] on [Unsplash][2] + +There are several ways that your React component can decide what to render. You can use the traditional `if` statement or the `switch` statement. In this article, we’ll explore a few alternatives. But be warned that some come with their own gotchas, if you’re not careful. + +### Ternary vs if/else + +Let’s say we have a component that is passed a `name` prop. If the string is non-empty, we display a greeting. Otherwise we tell the user they need to sign in. + +Here’s a Stateless Function Component (SFC) that does just that. + +``` +const MyComponent = ({ name }) => { + if (name) { + return ( +
+ Hello {name} +
+ ); + } + return ( +
+ Please sign in +
+ ); +}; +``` + +Pretty straightforward. But we can do better. Here’s the same component written using a conditional ternary operator. + +``` +const MyComponent = ({ name }) => ( +
+ {name ? `Hello ${name}` : 'Please sign in'} +
+); +``` + +Notice how concise this code is compared to the example above. + +A few things to note. Because we are using the single statement form of the arrow function, the `return` statement is implied. Also, using a ternary allowed us to DRY up the duplicate `
` markup. 🎉 + +### Ternary vs Logical AND + +As you can see, ternaries are wonderful for `if/else` conditions. But what about simple `if` conditions? + +Let’s look at another example. If `isPro` (a boolean) is `true`, we are to display a trophy emoji. We are also to render the number of stars (if not zero). We could go about it like this. + +``` +const MyComponent = ({ name, isPro, stars}) => ( +
+
+ Hello {name} + {isPro ? '🏆' : null} +
+ {stars ? ( +
+ Stars:{'⭐️'.repeat(stars)} +
+ ) : null} +
+); +``` + +But notice the “else” conditions return `null`. This is becasue a ternary expects an else condition. + +For simple `if` conditions, we could use something a little more fitting: the logical AND operator. Here’s the same code written using a logical AND. + +``` +const MyComponent = ({ name, isPro, stars}) => ( +
+
+ Hello {name} + {isPro && '🏆'} +
+ {stars && ( +
+ Stars:{'⭐️'.repeat(stars)} +
+ )} +
+); +``` + +Not too different, but notice how we eliminated the `: null` (i.e. else condition) at the end of each ternary. Everything should render just like it did before. + + +Hey! What gives with John? There is a `0` when nothing should be rendered. That’s the gotcha that I was referring to above. Here’s why. + +[According to MDN][3], a Logical AND (i.e. `&&`): + +> `expr1 && expr2` + +> Returns `expr1` if it can be converted to `false`; otherwise, returns `expr2`. Thus, when used with Boolean values, `&&` returns `true` if both operands are true; otherwise, returns `false`. + +OK, before you start pulling your hair out, let me break it down for you. + +In our case, `expr1` is the variable `stars`, which has a value of `0`. Because zero is falsey, `0` is returned and rendered. See, that wasn’t too bad. + +I would write this simply. + +> If `expr1` is falsey, returns `expr1`, else returns `expr2`. + +So, when using a logical AND with non-boolean values, we must make the falsey value return something that React won’t render. Say, like a value of `false`. + +There are a few ways that we can accomplish this. Let’s try this instead. + +``` +{!!stars && ( +
+ {'⭐️'.repeat(stars)} +
+)} +``` + +Notice the double bang operator (i.e. `!!`) in front of `stars`. (Well, actually there is no “double bang operator”. We’re just using the bang operator twice.) + +The first bang operator will coerce the value of `stars` into a boolean and then perform a NOT operation. If `stars` is `0`, then `!stars` will produce `true`. + +Then we perform a second NOT operation, so if `stars` is 0, `!!stars` would produce `false`. Exactly what we want. + +If you’re not a fan of `!!`, you can also force a boolean like this (which I find a little wordy). + +``` +{Boolean(stars) && ( +``` + +Or simply give a comparator that results in a boolean value (which some might say is even more semantic). + +``` +{stars > 0 && ( +``` + +#### A word on strings + +Empty string values suffer the same issue as numbers. But because a rendered empty string is invisible, it’s not a problem that you will likely have to deal with, or will even notice. However, if you are a perfectionist and don’t want an empty string on your DOM, you should take similar precautions as we did for numbers above. + +### Another solution + +A possible solution, and one that scales to other variables in the future, would be to create a separate `shouldRenderStars` variable. Then you are dealing with boolean values in your logical AND. + +``` +const shouldRenderStars = stars > 0; +``` + +``` +return ( +
+ {shouldRenderStars && ( +
+ {'⭐️'.repeat(stars)} +
+ )} +
+); +``` + +Then, if in the future, the business rule is that you also need to be logged in, own a dog, and drink light beer, you could change how `shouldRenderStars` is computed, and what is returned would remain unchanged. You could also place this logic elsewhere where it’s testable and keep the rendering explicit. + +``` +const shouldRenderStars = + stars > 0 && loggedIn && pet === 'dog' && beerPref === 'light`; +``` + +``` +return ( +
+ {shouldRenderStars && ( +
+ {'⭐️'.repeat(stars)} +
+ )} +
+); +``` + +### Conclusion + +I’m of the opinion that you should make best use of the language. And for JavaScript, this means using conditional ternary operators for `if/else`conditions and logical AND operators for simple `if` conditions. + +While we could just retreat back to our safe comfy place where we use the ternary operator everywhere, you now possess the knowledge and power to go forth AND prosper. + +-------------------------------------------------------------------------------- + +作者简介: + +Managing Editor at the American Express Engineering Blog http://aexp.io and Director of Engineering @AmericanExpress. MyViews !== ThoseOfMyEmployer. + +---------------- + +via: https://medium.freecodecamp.org/conditional-rendering-in-react-using-ternaries-and-logical-and-7807f53b6935 + +作者:[Donavon West][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/@donavon +[1]:https://unsplash.com/photos/pKeF6Tt3c08?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText +[2]:https://unsplash.com/search/photos/road-sign?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText +[3]:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Logical_Operators \ No newline at end of file diff --git a/sources/tech/20180201 Here are some amazing advantages of Go that you dont hear much about.md b/sources/tech/20180201 Here are some amazing advantages of Go that you dont hear much about.md new file mode 100644 index 0000000000..12c581b773 --- /dev/null +++ b/sources/tech/20180201 Here are some amazing advantages of Go that you dont hear much about.md @@ -0,0 +1,223 @@ +Here are some amazing advantages of Go that you don’t hear much about +============================================================ + +![](https://cdn-images-1.medium.com/max/2000/1*NDXd5I87VZG0Z74N7dog0g.png) + +Artwork from [https://github.com/ashleymcnamara/gophers][1] + +In this article, I discuss why you should give Go a chance and where to start. + +Golang is a programming language you might have heard about a lot during the last couple years. Even though it was created back in 2009, it has started to gain popularity only in recent years. + + +![](https://cdn-images-1.medium.com/max/2000/1*cQ8QzhCPiFXqk_oQdUk_zw.png) +Golang popularity according to Google Trends + +This article is not about the main selling points of Go that you usually see. + +Instead, I would like to present to you some rather small but still significant features that you only get to know after you’ve decided to give Go a try. + +These are amazing features that are not laid out on the surface, but they can save you weeks or months of work. They can also make software development more enjoyable. + +Don’t worry if Go is something new for you. This article does not require any prior experience with the language. I have included a few extra links at the bottom, in case you would like to learn a bit more. + +We will go through such topics as: + +* GoDoc + +* Static code analysis + +* Built-in testing and profiling framework + +* Race condition detection + +* Learning curve + +* Reflection + +* Opinionatedness + +* Culture + +Please, note that the list doesn’t follow any particular order. It is also opinionated as hell. + +### GoDoc + +Documentation in code is taken very seriously in Go. So is simplicity. + +[GoDoc][4] is a static code analyzing tool that creates beautiful documentation pages straight out of your code. A remarkable thing about GoDoc is that it doesn’t use any extra languages, like JavaDoc, PHPDoc, or JSDoc to annotate constructions in your code. Just English. + +It uses as much information as it can get from the code to outline, structure, and format the documentation. And it has all the bells and whistles, such as cross-references, code samples, and direct links to your version control system repository. + +All you can do is to add a good old `// MyFunc transforms Foo into Bar` kind of comment which would be reflected in the documentation, too. You can even add [code examples][5] which are actually runnable via the web interface or locally. + +GoDoc is the only documentation engine for Go that is used by the whole community. This means that every library or application written in Go has the same format of documentation. In the long run, it saves you tons of time while browsing those docs. + +Here, for example, is the GoDoc page for my recent pet project: [pullkee — GoDoc][6]. + +### Static code analysis + +Go heavily relies on static code analysis. Examples include [godoc][7] for documentation, [gofmt][8] for code formatting, [golint][9] for code style linting, and many others. + +There are so many of them that there’s even an everything-included-kind-of project called [gometalinter][10] to compose them all into a single utility. + +Those tools are commonly implemented as stand-alone command line applications and integrate easily with any coding environment. + +Static code analysis isn’t actually something new to modern programming, but Go sort of brings it to the absolute. I can’t overestimate how much time it saved me. Also, it gives you a feeling of safety, as though someone is covering your back. + +It’s very easy to create your own analyzers, as Go has dedicated built-in packages for parsing and working with Go sources. + +You can learn more from this talk: [GothamGo Kickoff Meetup: Go Static Analysis Tools by Alan Donovan][11]. + +### Built-in testing and profiling framework + +Have you ever tried to pick a testing framework for a Javascript project you are starting from scratch? If so, you might understand that struggle of going through such an analysis paralysis. You might have also realized that you were not using like 80% of the framework you have chosen. + +The issue repeats over again once you need to do some reliable profiling. + +Go comes with a built-in testing tool designed for simplicity and efficiency. It provides you the simplest API possible, and makes minimum assumptions. You can use it for different kinds of testing, profiling, and even to provide executable code examples. + +It produces CI-friendly output out-of-box, and the usage is usually as easy as running `go test`. Of course, it also supports advanced features like running tests in parallel, marking them skipped, and many more. + +### Race condition detection + +You might already know about Goroutines, which are used in Go to achieve concurrent code execution. If you don’t, [here’s][12] a really brief explanation. + +Concurrent programming in complex applications is never easy regardless of the specific technique, partly due to the possibility of race conditions. + +Simply put, race conditions happen when several concurrent operations finish in an unpredicted order. It might lead to a huge number of bugs, which are particularly hard to chase down. Ever spent a day debugging an integration test which only worked in about 80% of executions? It probably was a race condition. + +All that said, concurrent programming is taken very seriously in Go and, luckily, we have quite a powerful tool to hunt those race conditions down. It is fully integrated into Go’s toolchain. + +You can read more about it and learn how to use it here: [Introducing the Go Race Detector — The Go Blog][13]. + +### Learning curve + +You can learn ALL Go’s language features in one evening. I mean it. Of course, there are also the standard library, and the best practices in different, more specific areas. But two hours would totally be enough time to get you confidently writing a simple HTTP server, or a command-line app. + +The project has [marvelous documentation][14], and most of the advanced topics have already been covered on their blog: [The Go Programming Language Blog][15]. + +Go is much easier to bring to your team than Java (and the family), Javascript, Ruby, Python, or even PHP. The environment is easy to setup, and the investment your team needs to make is much smaller before they can complete your first production code. + +### Reflection + +Code reflection is essentially an ability to sneak under the hood and access different kinds of meta-information about your language constructs, such as variables or functions. + +Given that Go is a statically typed language, it’s exposed to a number of various limitations when it comes to more loosely typed abstract programming. Especially compared to languages like Javascript or Python. + +Moreover, Go [doesn’t implement a concept called Generics][16] which makes it even more challenging to work with multiple types in an abstract way. Nevertheless, many people think it’s actually beneficial for the language because of the amount of complexity Generics bring along. And I totally agree. + +According to Go’s philosophy (which is a separate topic itself), you should try hard to not over-engineer your solutions. And this also applies to dynamically-typed programming. Stick to static types as much as possible, and use interfaces when you know exactly what sort of types you’re dealing with. Interfaces are very powerful and ubiquitous in Go. + +However, there are still cases in which you can’t possibly know what sort of data you are facing. A great example is JSON. You convert all the kinds of data back and forth in your applications. Strings, buffers, all sorts of numbers, nested structs and more. + +In order to pull that off, you need a tool to examine all the data in runtime that acts differently depending on its type and structure. Reflection to rescue! Go has a first-class [reflect][17] package to enable your code to be as dynamic as it would be in a language like Javascript. + +An important caveat is to know what price you pay for using it — and only use it when there is no simpler way. + +You can read more about it here: [The Laws of Reflection — The Go Blog][18]. + +You can also read some real code from the JSON package sources here: [src/encoding/json/encode.go — Source Code][19] + +### Opinionatedness + +Is there such a word, by the way? + +Coming from the Javascript world, one of the most daunting processes I faced was deciding which conventions and tools I needed to use. How should I style my code? What testing library should I use? How should I go about structure? What programming paradigms and approaches should I rely on? + +Which sometimes basically got me stuck. I was doing this instead of writing the code and satisfying the users. + +To begin with, I should note that I totally get where those conventions should come from. It’s always you and your team. Anyway, even a group of experienced Javascript developers can easily find themselves having most of the experience with entirely different tools and paradigms to achieve kind of the same results. + +This makes the analysis paralysis cloud explode over the whole team, and also makes it harder for the individuals to integrate with each other. + +Well, Go is different. You have only one style guide that everyone follows. You have only one testing framework which is built into the basic toolchain. You have a lot of strong opinions on how to structure and maintain your code. How to pick names. What structuring patterns to follow. How to do concurrency better. + +While this might seem too restrictive, it saves tons of time for you and your team. Being somewhat limited is actually a great thing when you are coding. It gives you a more straightforward way to go when architecting new code, and makes it easier to reason about the existing one. + +As a result, most of the Go projects look pretty alike code-wise. + +### Culture + +People say that every time you learn a new spoken language, you also soak in some part of the culture of the people who speak that language. Thus, the more languages you learn, more personal changes you might experience. + +It’s the same with programming languages. Regardless of how you are going to apply a new programming language in the future, it always gives you a new perspective on programming in general, or on some specific techniques. + +Be it functional programming, pattern matching, or prototypal inheritance. Once you’ve learned it, you carry these approaches with you which broadens the problem-solving toolset that you have as a software developer. It also changes the way you see high-quality programming in general. + +And Go is a terrific investment here. The main pillar of Go’s culture is keeping simple, down-to-earth code without creating many redundant abstractions and putting the maintainability at the top. It’s also a part of the culture to spend the most time actually working on the codebase, instead of tinkering with the tools and the environment. Or choosing between different variations of those. + +Go is also all about “there should be only one way of doing a thing.” + +A little side note. It’s also partially true that Go usually gets in your way when you need to build relatively complex abstractions. Well, I’d say that’s the tradeoff for its simplicity. + +If you really need to write a lot of abstract code with complex relationships, you’d be better off using languages like Java or Python. However, even when it’s not obvious, it’s very rarely the case. + +Always use the best tool for the job! + +### Conclusion + +You might have heard of Go before. Or maybe it’s something that has been staying out of your radar for a while. Either way, chances are, Go can be a very decent choice for you or your team when starting a new project or improving the existing one. + +This is not a complete list of all the amazing things about Go. Just the undervalued ones. + +Please, give Go a try with [A Tour of Go][20] which is an incredible place to start. + +If you wish to learn more about Go’s benefits, you can check out these links: + +* [Why should you learn Go? — Keval Patel — Medium][2] + +* [Farewell Node.js — TJ Holowaychuk — Medium][3] + +Share your observations down in the comments! + +Even if you are not specifically looking for a new language to use, it’s worth it to spend an hour or two getting the feel of it. And maybe it can become quite useful for you in the future. + +Always be looking for the best tools for your craft! + +* * * + +If you like this article, please consider following me for more, and clicking on those funny green little hands right below this text for sharing. 👏👏👏 + +Check out my [Github][21] and follow me on [Twitter][22]! + +-------------------------------------------------------------------------------- + +作者简介: + +Software Engineer and Traveler. Coding for fun. Javascript enthusiast. Tinkering with Golang. A lot into SOA and Docker. Architect at Velvica. + +------------ + + +via: https://medium.freecodecamp.org/here-are-some-amazing-advantages-of-go-that-you-dont-hear-much-about-1af99de3b23a + +作者:[Kirill Rogovoy][a] +译者:[译者ID](https://github.com/译者ID) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]: +[1]:https://github.com/ashleymcnamara/gophers +[2]:https://medium.com/@kevalpatel2106/why-should-you-learn-go-f607681fad65 +[3]:https://medium.com/@tjholowaychuk/farewell-node-js-4ba9e7f3e52b +[4]:https://godoc.org/ +[5]:https://blog.golang.org/examples +[6]:https://godoc.org/github.com/kirillrogovoy/pullkee +[7]:https://godoc.org/ +[8]:https://golang.org/cmd/gofmt/ +[9]:https://github.com/golang/lint +[10]:https://github.com/alecthomas/gometalinter#supported-linters +[11]:https://vimeo.com/114736889 +[12]:https://gobyexample.com/goroutines +[13]:https://blog.golang.org/race-detector +[14]:https://golang.org/doc/ +[15]:https://blog.golang.org/ +[16]:https://golang.org/doc/faq#generics +[17]:https://golang.org/pkg/reflect/ +[18]:https://blog.golang.org/laws-of-reflection +[19]:https://golang.org/src/encoding/json/encode.go +[20]:https://tour.golang.org/ +[21]:https://github.com/kirillrogovoy/ +[22]:https://twitter.com/krogovoy \ No newline at end of file diff --git a/sources/tech/20180201 I Built This - Now What How to deploy a React App on a DigitalOcean Droplet.md b/sources/tech/20180201 I Built This - Now What How to deploy a React App on a DigitalOcean Droplet.md new file mode 100644 index 0000000000..befab76fab --- /dev/null +++ b/sources/tech/20180201 I Built This - Now What How to deploy a React App on a DigitalOcean Droplet.md @@ -0,0 +1,199 @@ +I Built This - Now What? How to deploy a React App on a DigitalOcean Droplet. +============================================================ + +![](https://cdn-images-1.medium.com/max/1000/1*6K5vmzalJUxn44v3cm6wBw.jpeg) +Photo by [Thomas Kvistholt][1] + +Most aspiring developers have uploaded static HTML sites before. The process isn’t too daunting, as you’re essentially just moving files from one computer to another, and then BAM! Website. + +But those who have tackled learning React often pour hundreds or even thousands of hours into learning about components, props, and state, only to be left with the question “How do I host this?” Fear not, fellow developer. Deploying your latest masterpiece is a little more in-depth, but not overly difficult. Here’s how: + +### Preparing For Production + +There are a few things you’ll want to do to get your app ready for deployment. + +#### Turn off service workers + +If you’ve used something like create-react-app to bootstrap your project, you’ll want to turn off the built-in service worker if you haven’t specifically integrated it to work with your app. While usually harmless, it can cause some issues, so it’s best to just get rid of it up front. Find these lines in your `src/index.js` file and delete them:`registerServiceWorker();` `import registerServiceWorker from ‘register-service-worker’` + +#### Get your server ready + +To get the most bang for your buck, a production build will minify the code and remove extra white-space and comments so that it’s as fast to download as possible. It creates a new directory called `/build`, and we need to make sure we’re telling Express to use it. On your server page, add this line: `app.use( express.static( `${__dirname}/../build` ) );` + +Next, you’ll need to make sure your routes know how to get to your index.html file. To do this, we need to create an endpoint and place it below all other endpoints in your server file. It should look like this: + +``` +const path = require('path')app.get('*', (req, res)=>{ res.sendFile(path.join(__dirname, '../build/index.html'));}) +``` + +#### Create the production build + +Now that Express knows to use the `/build` directory, it’s time to create it. Open up your terminal, make sure you’re in your project directory, and use the command `npm run build` + +#### Keep your secrets safe + +If you’re using API keys or a database connection string, hopefully you’ve already hidden them in a `.env` file. All the configuration that is different between deployed and local should go into this file as well. Tags cannot be proxied, so we have to hard code in the backend address when using the React dev server, but we want to use relative paths in production. Your resulting `.env` file might look something like this: + +``` +REACT_APP_LOGIN="http://localhost:3030/api/auth/login"REACT_APP_LOGOUT="http://localhost:3030/api/auth/logout"DOMAIN="user4234.auth0.com"ID="46NxlCzM0XDE7T2upOn2jlgvoS"SECRET="0xbTbFK2y3DIMp2TdOgK1MKQ2vH2WRg2rv6jVrMhSX0T39e5_Kd4lmsFz"SUCCESS_REDIRECT="http://localhost:3030/"FAILURE_REDIRECT="http://localhost:3030/api/auth/login" +``` + +``` +AWS_ACCESS_KEY_ID=AKSFDI4KL343K55L3 +AWS_SECRET_ACCESS_KEY=EkjfDzVrG1cw6QFDK4kjKFUa2yEDmPOVzN553kAANcy +``` + +``` +CONNECTION_STRING="postgres://vuigx:k8Io13cePdUorndJAB2ijk_u0r4@stampy.db.elephantsql.com:5432/vuigx"NODE_ENV=development +``` + +#### Push your code + +Test out your app locally by going to `[http://localhost:3030][2]` and replacing 3030 with your server port to make sure everything still runs smoothly. Remember to start your local server with node or nodemon so it’s up and running when you check it. Once everything looks good, we can push it to Github (or Bit Bucket, etc). + +IMPORTANT! Before you do so, double check that your `.gitignore` file contains `.env` and `/build` so you’re not publishing sensitive information or needless files. + +### Setting Up DigitalOcean + +[DigitalOcean][8] is a leading hosting platform, and makes it relatively easy and cost-effective to deploy React sites. They utilize Droplets, which is the term they use for their servers. Before we create our Droplet, we still have a little work to do. + +#### Creating SSH Keys + +Servers are computers that have public IP addresses. Because of this, we need a way to tell the server who we are, so that we can do things we wouldn’t want anyone else doing, like making changes to our files. Your everyday password won’t be secure enough, and a password long and complex enough to protect your Droplet would be nearly impossible to remember. Instead, we’ll use an SSH key. + + ** 此处有Canvas,请手动处理 ** + +![](https://cdn-images-1.medium.com/max/1000/1*qeGqHqXrV22_aBwFQ4WhaA.jpeg) +Photo by [Brenda Clarke][3] + +To create your SSH key, enter this command in your terminal: `ssh-keygen -t rsa` + +This starts the process of SSH key generation. First, you’ll be asked to specify where to save the new key. Unless you already have a key you need to keep, you can keep the default location and simply press enter to continue. + +As an added layer of security in case someone gets ahold of your computer, you’ll have to enter a password to secure your key. Your terminal will not show your keystrokes as you type this password, but it is keeping track of it. Once you hit enter, you’ll have to type it in once more to confirm. If successful, you should now see something like this: + +``` +Generating public/private rsa key pair. +Enter file in which to save the key (/Users/username/.ssh/id_rsa): +Enter passphrase (empty for no passphrase): +Enter same passphrase again: +Your identification has been saved in demo_rsa. +Your public key has been saved in demo_rsa.pub. +The key fingerprint is: +cc:28:30:44:01:41:98:cf:ae:b6:65:2a:f2:32:57:b5 user@user.local +The key's randomart image is: ++--[ RSA 2048]----+ +|=*+. | +|o. | +| oo | +| oo .+ | +| . ....S | +| . ..E | +| . + | +|*.= | +|+Bo | ++-----------------+ +``` + +#### What happened? + +Two files have been created on your computer — `id_rsa` and `id_rsa.pub`. The `id_rsa` file is your private key and is used to verify your signature when you use the `id_rsa.pub` file, or public key. We need to give our public key to DigitalOcean. To get it, enter `cat ~/.ssh/id_rsa.pub`. You should now be looking at a long string of characters, which is the contents of your `id_rsa.pub` file. It looks something like this: + +``` +ssh-rsaAABC3NzaC1yc2EAAAADAQABAAABAQDR5ehyadT9unUcxftJOitl5yOXgSi2Wj/s6ZBudUS5Cex56LrndfP5Uxb8+Qpx1D7gYNFacTIcrNDFjdmsjdDEIcz0WTV+mvMRU1G9kKQC01YeMDlwYCopuENaas5+cZ7DP/qiqqTt5QDuxFgJRTNEDGEebjyr9wYk+mveV/acBjgaUCI4sahij98BAGQPvNS1xvZcLlhYssJSZrSoRyWOHZ/hXkLtq9CvTaqkpaIeqvvmNxQNtzKu7ZwaYWLydEKCKTAe4ndObEfXexQHOOKwwDSyesjaNc6modkZZC+anGLlfwml4IUwGv10nogVg9DTNQQLSPVmnEN3Z User@Computer.local +``` + +Now  _that’s_  a password! Copy the string manually, or use the command `pbcopy < ~/.ssh/id_rsa.pub` to have the terminal copy it for you. + +#### Adding your SSH Key to DigitalOcean + +Login to your DigitalOcean account or sign up if you haven’t already. Go to your [Security Settings][9] and click on Add SSH. Paste in the key you copied and give it a name. You can name it whatever you like, but it’s good idea to reference the computer the key is saved on, especially if you use multiple computers regularly. + +#### Creating a Droplet + + ** 此处有Canvas,请手动处理 ** + +![](https://cdn-images-1.medium.com/max/1000/1*dN9vn7lxBjtK72iV3CZZXw.jpeg) +Photo by [M. Maddo][4] + +With the key in place, we can finally create our Droplet. To get started, click Create Droplet. You’ll be asked to choose an OS, but for our purposes, the default Ubuntu will work just fine. + +You’ll need to select which size Droplet you want to use. In many cases, the smallest Droplet will do. However, review the available options and choose the one that will work best for your project. + +Next, select a data center for your Droplet. Choose a location central to your expected visitor base. New features are rolled out by DigitalOcean in different data centers at different times, but unless you know you want to use a special feature that’s only available in specific locations, this won’t matter. + +If you want to add additional services to your Droplet such as backups or private networking, you have that option here. Be aware, there is an associated cost for these services. + +Finally, make sure your SSH key is selected and give your Droplet a name. It is possible to host multiple projects on a single Droplet, so you may not want to give it a project-specific name. Submit your settings by clicking the Create button at the bottom of the page. + +#### Connecting to your Droplet + +With our Droplet created, we can now connect to it via SSH. Copy the IP address for your Droplet and go back to your terminal. Enter ssh followed by root@youripaddress, where youripaddress is the IP address for your Droplet. It should look something like this: `ssh root@123.45.67.8`. This tells your computer that you want to connect to your IP address as the root user. Alternatively, you can [set up user accounts][10] if you don’t want to login as root, but it’s not necessary. + +#### Installing Node + + +![](https://cdn-images-1.medium.com/max/1000/1*3mKtwxfRWi8zxHs4EGcUMw.png) + +To run React, we’ll need an updated version of Node. First we want to run `apt-get update && apt-get dist-upgrade` to update the Linux software list. Next, enter `apt-get install nodejs -y`, `apt-get install npm -y`, and `npm i -g n` to install Nodejs and npm. + +Your React app dependencies might require a specific version of Node, so check the version that your project is using by running `node -v` in your projects directory. You’ll probably want to do this in a different terminal tab so you don’t have to log in through SSH again. + +Once you know what version you need, go back to your SSH connection and run `n 6.11.2`, replacing 6.11.2 with your specific version number. This ensures your Droplet’s version of Node matches your project and minimizes potential issues. + +### Install your app to the Droplet + +All the groundwork has been laid, and it’s finally time to install our React app! While still connected through SSH, make sure you’re in your home directory. You can enter `cd ~` to take you there if you’re not sure. + +To get the files to your Droplet, you’re going to clone them from your Github repo. Grab the HTTP clone link from Github and in your terminal enter `git clone [https://github.com/username/my-react-project.git][5]`. Just like with your local project, cd into your project folder using `cd my-react-project` and then run `npm install`. + +#### Don’t ignore your ignored files + +Remember that we told Git to ignore the `.env` file, so it won’t be included in the code we just pulled down. We need to add it manually now. `touch .env`will create an empty `.env` file that we can then open in the nano editor using `nano .env`. Copy the contents of your local `.env` file and paste them into the nano editor. + +We also told Git to ignore the build directory. That’s because we were just testing the production build, but now we’re going to build it again on our Droplet. Use `npm run build` to run this process again. If you get an error, check to make sure you have all of your dependencies listed in your `package.json` file. If there are any missing, npm install those packages. + +#### Start it up! + +Run your server with `node server/index.js` (or whatever your server file is named) to make sure everything is working. If it throws an error, check again for any missing dependencies that might not have been caught in the build process. If everything starts up, you should now be able to go to ipaddress:serverport to see your site: `123.45.67.8:3232`. If your server is running on port 80, this is a default port and you can just use the IP address without specifying a port number: `123.45.67.8` + + +![](https://cdn-images-1.medium.com/max/1000/1*Hvs_Dqclz-uajcjmsgH4gA.jpeg) +Photo by [John Baker][6] on [Unsplash][7] + +You now have a space on the internet to call your own! If you have purchased a domain name you’d like to use in place of the IP address, you can follow [DigitalOcean’s instructions][11] on how to set this up. + +#### Keep it running + +Your site is live, but once you close the terminal, your server will stop. This is a problem, so we’ll want to install some more software that will tell the server not to stop once the connection is terminated. There are some options for this, but let’s use Program Manager 2 for the sake of this article. + +Kill your server if you haven’t already and run `npm install -g pm2`. Once installed, we can tell it to run our server using `pm2 start server/index.js` + +### Updating your code + +At some point, you’ll probably want to update your project, but luckily uploading changes is quick and easy. Once you push your code to Github, ssh into your Droplet and cd into your project directory. Because we cloned from Github initially, we don’t need to provide any links this time. You can pull down the new code simply by running `git pull`. + +To incorporate frontend changes, you will need to run the build process again with `npm run build`. If you’ve made changes to the server file, restart PM2 by running `pm2 restart all`. That’s it! Your updates should be live now. + +-------------------------------------------------------------------------------- + +via: https://medium.freecodecamp.org/i-built-this-now-what-how-to-deploy-a-react-app-on-a-digitalocean-droplet-662de0fe3f48 + +作者:[Andrea Stringham ][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/@astringham +[1]:https://unsplash.com/photos/oZPwn40zCK4?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText +[2]:http://localhost:3030/ +[3]:https://www.flickr.com/photos/37753256@N08/ +[4]:https://www.flickr.com/photos/14141796@N05/ +[5]:https://github.com/username/my-react-project.git +[6]:https://unsplash.com/photos/3To9V42K0Ag?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText +[7]:https://unsplash.com/search/photos/key?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText +[8]:https://www.digitalocean.com/ +[9]:https://cloud.digitalocean.com/settings/security +[10]:https://www.digitalocean.com/community/tutorials/initial-server-setup-with-ubuntu-14-04 +[11]:https://www.digitalocean.com/community/tutorials/how-to-point-to-digitalocean-nameservers-from-common-domain-registrars \ No newline at end of file diff --git a/sources/tech/20180201 Rock Solid React.js Foundations A Beginners Guide.md b/sources/tech/20180201 Rock Solid React.js Foundations A Beginners Guide.md new file mode 100644 index 0000000000..b3252dfb75 --- /dev/null +++ b/sources/tech/20180201 Rock Solid React.js Foundations A Beginners Guide.md @@ -0,0 +1,292 @@ +Rock Solid React.js Foundations: A Beginner’s Guide +============================================================ + ** 此处有Canvas,请手动处理 ** + +![](https://cdn-images-1.medium.com/max/1000/1*wj5ujzj5wPQIKb0mIWLgNQ.png) +React.js crash course + +I’ve been working with React and React-Native for the last couple of months. I have already released two apps in production, [Kiven Aa][1] (React) and [Pollen Chat][2] (React Native). When I started learning React, I was searching for something (a blog, a video, a course, whatever) that didn’t only teach me how to write apps in React. I also wanted it to prepare me for interviews. + +Most of the material I found, concentrated on one or the other. So, this post is aimed towards the audience who is looking for a perfect mix of theory and hands-on. I will give you a little bit of theory so that you understand what is happening under the hood and then I will show you how to write some React.js code. + +If you prefer video, I have this entire course up on YouTube as well. Please check that out. + + +Let’s dive in… + +> React.js is a JavaScript library for building user interfaces + +You can build all sorts of single page applications. For example, chat messengers and e-commerce portals where you want to show changes on the user interface in real-time. + +### Everything’s a component + +A React app is comprised of components,  _a lot of them_ , nested into one another.  _But what are components, you may ask?_ + +A component is a reusable piece of code, which defines how certain features should look and behave on the UI. For example, a button is a component. + +Let’s look at the following calculator, which you see on Google when you try to calculate something like 2+2 = 4 –1 = 3 (quick maths!) + + +![](https://cdn-images-1.medium.com/max/1000/1*NS9DykYDyYG7__UXJdysTA.png) +Red markers denote components + +As you can see in the image above, the calculator has many areas — like the  _result display window_  and the  _numpad_ . All of these can be separate components or one giant component. It depends on how comfortable one is in breaking down and abstracting away things in React + +You write code for all such components separately. Then combine those under one container, which in turn is a React component itself. This way you can create reusable components and your final app will be a collection of separate components working together. + +The following is one such way you can write the calculator, shown above, in React. + +``` + + + + + + . + . + . + + + + +``` + +Yes! It looks like HTML code, but it isn’t. We will explore more about it in the later sections. + +### Setting up our Playground + +This tutorial focuses on React’s fundamentals. It is not primarily geared towards React for Web or [React Native][3] (for building mobile apps). So, we will use an online editor so as to avoid web or native specific configurations before even learning what React can do. + +I’ve already set up an environment for you on [codepen.io][4]. Just follow the link and read all the comments in HTML and JavaScript (JS) tabs. + +### Controlling Components + +We’ve learned that a React app is a collection of various components, structured as a nested tree. Thus, we require some sort of mechanism to pass data from one component to other. + +#### Enter “props” + +We can pass arbitrary data to our component using a `props` object. Every component in React gets this `props` object. + +Before learning how to use this `props` object, let’s learn about functional components. + +#### a) Functional component + +A functional component in React consumes arbitrary data that you pass to it using `props` object. It returns an object which describes what UI React should render. Functional components are also known as Stateless components. + +Let’s write our first functional component. + +``` +function Hello(props) { + return
{props.name}
+} +``` + +It’s that simple. We just passed `props` as an argument to a plain JavaScript function and returned,  _umm, well, what was that? That _ `_
{props.name}
_` _thing!_  It’s JSX (JavaScript Extended). We will learn more about it in a later section. + +This above function will render the following HTML in the browser. + +``` + +
+ rajat +
+``` + + +> Read the section below about JSX, where I have explained how did we get this HTML from our JSX code. + +How can you use this functional component in your React app? Glad you asked! It’s as simple as the following. + +``` + +``` + +The attribute `name` in the above code becomes `props.name` inside our `Hello`component. The attribute `age` becomes `props.age` and so on. + +> Remember! You can nest one React component inside other React components. + +Let’s use this `Hello` component in our codepen playground. Replace the `div`inside `ReactDOM.render()` with our `Hello` component, as follows, and see the changes in the bottom window. + +``` +function Hello(props) { + return
{props.name}
+} + +ReactDOM.render(, document.getElementById('root')); +``` + + +> But what if your component has some internal state. For instance, like the following counter component, which has an internal count variable, which changes on + and — key presses. + +A React component with an internal state + +#### b) Class-based component + +The class-based component has an additional property `state` , which you can use to hold a component’s private data. We can rewrite our `Hello` component using class notation as follows. Since these components have a state, these are also known as Stateful components. + +``` +class Counter extends React.Component { + // this method should be present in your component + render() { + return ( +
+ {this.props.name} +
+ ); + } +} +``` + +We extend `React.Component` class of React library to make class-based components in React. Learn more about JavaScript classes [here][5]. + +The `render()` method must be present in your class as React looks for this method in order to know what UI it should render on screen. + +To use this sort of internal state, we first have to initialize the `state` object in the constructor of the component class, in the following way. + +``` +class Counter extends React.Component { + constructor() { + super(); + + // define the internal state of the component + this.state = {name: 'rajat'} + } + + render() { + return ( +
+ {this.state.name} +
+ ); + } +} + +// Usage: +// In your react app: +``` + +Similarly, the `props` can be accessed inside our class-based component using `this.props` object. + +To set the state, you use `React.Component`'s `setState()`. We will see an example of this, in the last part of this tutorial. + +> Tip: Never call `setState()` inside `render()` function, as `setState()` causes component to re-render and this will result in endless loop. + + +![](https://cdn-images-1.medium.com/max/1000/1*rPUhERO1Bnr5XdyzEwNOwg.png) +A class-based component has an optional property “state”. + + _Apart from _ `_state_` _, a class-based component has some life-cycle methods like _ `_componentWillMount()._` _ These you can use to do stuff, like initializing the _ `_state_` _and all but that is out of the scope of this post._ + +### JSX + +JSX is a short form of  _JavaScript Extended_  and it is a way to write `React`components. Using JSX, you get the full power of JavaScript inside XML like tags. + +You put JavaScript expressions inside `{}`. The following are some valid JSX examples. + + ``` + + + ; + +
+ + ``` + +The way it works is you write JSX to describe what your UI should look like. A [transpiler][6] like `Babel` converts that code into a bunch of `React.createElement()` calls. The React library then uses those `React.createElement()` calls to construct a tree-like structure of DOM elements. In case of React for Web or Native views in case of React Native. It keeps it in the memory. + +React then calculates how it can effectively mimic this tree in the memory of the UI displayed to the user. This process is known as [reconciliation][7]. After that calculation is done, React makes the changes to the actual UI on the screen. + + ** 此处有Canvas,请手动处理 ** + +![](https://cdn-images-1.medium.com/max/1000/1*ighKXxBnnSdDlaOr5-ZOPg.png) +How React converts your JSX into a tree which describes your app’s UI + +You can use [Babel’s online REPL][8] to see what React actually outputs when you write some JSX. + + +![](https://cdn-images-1.medium.com/max/1000/1*NRuBKgzNh1nHwXn0JKHafg.png) +Use Babel REPL to transform JSX into plain JavaScript + +> Since JSX is just a syntactic sugar over plain `React.createElement()` calls, React can be used without JSX. + +Now we have every concept in place, so we are well positioned to write a `counter` component that we saw earlier as a GIF. + +The code is as follows and I hope that you already know how to render that in our playground. + +``` +class Counter extends React.Component { + constructor(props) { + super(props); + + this.state = {count: this.props.start || 0} + + // the following bindings are necessary to make `this` work in the callback + this.inc = this.inc.bind(this); + this.dec = this.dec.bind(this); + } + + inc() { + this.setState({ + count: this.state.count + 1 + }); + } + + dec() { + this.setState({ + count: this.state.count - 1 + }); + } + + render() { + return ( +
+ + +
{this.state.count}
+
+ ); + } +} +``` + +The following are some salient points about the above code. + +1. JSX uses `camelCasing` hence `button`'s attribute is `onClick`, not `onclick`, as we use in HTML. + +2. Binding is necessary for `this` to work on callbacks. See line #8 and 9 in the code above. + +The final interactive code is located [here][9]. + +With that, we’ve reached the conclusion of our React crash course. I hope I have shed some light on how React works and how you can use React to build bigger apps, using smaller and reusable components. + +* * * + +If you have any queries or doubts, hit me up on Twitter [@rajat1saxena][10] or write to me at [rajat@raynstudios.com][11]. + +* * * + +#### Please recommend this post, if you liked it and share it with your network. Follow me for more tech related posts and consider subscribing to my channel [Rayn Studios][12] on YouTube. Thanks a lot. + +-------------------------------------------------------------------------------- + +via: https://medium.freecodecamp.org/rock-solid-react-js-foundations-a-beginners-guide-c45c93f5a923 + +作者:[Rajat Saxena ][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/@rajat1saxena +[1]:https://kivenaa.com/ +[2]:https://play.google.com/store/apps/details?id=com.pollenchat.android +[3]:https://facebook.github.io/react-native/ +[4]:https://codepen.io/raynesax/pen/MrNmBM +[5]:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes +[6]:https://en.wikipedia.org/wiki/Source-to-source_compiler +[7]:https://reactjs.org/docs/reconciliation.html +[8]:https://babeljs.io/repl +[9]:https://codepen.io/raynesax/pen/QaROqK +[10]:https://twitter.com/rajat1saxena +[11]:mailto:rajat@raynstudios.com +[12]:https://www.youtube.com/channel/UCUmQhjjF9bsIaVDJUHSIIKw \ No newline at end of file From 9e6729d2cfa1c1276f9f3c3e5b78cfcfe97ae3e8 Mon Sep 17 00:00:00 2001 From: Means Lee Date: Fri, 2 Feb 2018 15:44:47 +0800 Subject: [PATCH 133/272] Leemeans translating --- ... Fully Update And Upgrade Offline Debian-based Systems.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sources/tech/20171103 How To Fully Update And Upgrade Offline Debian-based Systems.md b/sources/tech/20171103 How To Fully Update And Upgrade Offline Debian-based Systems.md index a0fb133043..282b2dc581 100644 --- a/sources/tech/20171103 How To Fully Update And Upgrade Offline Debian-based Systems.md +++ b/sources/tech/20171103 How To Fully Update And Upgrade Offline Debian-based Systems.md @@ -1,5 +1,8 @@ +Leemeans translatting + How To Fully Update And Upgrade Offline Debian-based Systems ====== + ![](https://www.ostechnix.com/wp-content/uploads/2017/11/Upgrade-Offline-Debian-based-Systems-2-720x340.png) A while ago we have shown you how to install softwares in any[ **offline Ubuntu**][1] system and any [**offline Arch Linux**][2] system. Today, we will see how to fully update and upgrade offline Debian-based systems. Unlike the previous methods, we do not update/upgrade a single package, but the whole system. This method can be helpful where you don't have an active Internet connection or slow Internet speed. @@ -122,4 +125,4 @@ via: https://www.ostechnix.com/fully-update-upgrade-offline-debian-based-systems [1]:https://www.ostechnix.com/install-softwares-offline-ubuntu-16-04/ [2]:https://www.ostechnix.com/install-packages-offline-arch-linux/ [3]:data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7 -[4]:http://www.ostechnix.com/wp-content/uploads/2017/11/apt-offline.png () +[4]:http://www.ostechnix.com/wp-content/uploads/2017/11/apt-offline.png From 816ab7ec7776890e78d521f3c38b8abe25132729 Mon Sep 17 00:00:00 2001 From: Ezio Date: Fri, 2 Feb 2018 16:41:32 +0800 Subject: [PATCH 134/272] =?UTF-8?q?20180202-2=20=E9=80=89=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...0180127 Your instant Kubernetes cluster.md | 171 ++++ .../20180129 How programmers learn to code.md | 63 ++ ...ux Kernel 4.15 An Unusual Release Cycle.md | 62 ++ ...security risks in open source libraries.md | 249 +++++ ...he Spectre And Meltdown Performance Hit.md | 85 ++ ...de lets help Batman write a love letter.md | 912 ++++++++++++++++++ ...un Your Own Public Time Server on Linux.md | 117 +++ 7 files changed, 1659 insertions(+) create mode 100644 sources/tech/20180127 Your instant Kubernetes cluster.md create mode 100644 sources/tech/20180129 How programmers learn to code.md create mode 100644 sources/tech/20180130 Linux Kernel 4.15 An Unusual Release Cycle.md create mode 100644 sources/tech/20180130 Mitigating known security risks in open source libraries.md create mode 100644 sources/tech/20180130 Reckoning The Spectre And Meltdown Performance Hit.md create mode 100644 sources/tech/20180131 For your first HTML code lets help Batman write a love letter.md create mode 100644 sources/tech/20180201 How to Run Your Own Public Time Server on Linux.md diff --git a/sources/tech/20180127 Your instant Kubernetes cluster.md b/sources/tech/20180127 Your instant Kubernetes cluster.md new file mode 100644 index 0000000000..b17619762a --- /dev/null +++ b/sources/tech/20180127 Your instant Kubernetes cluster.md @@ -0,0 +1,171 @@ +Your instant Kubernetes cluster +============================================================ + + +This is a condensed and updated version of my previous tutorial [Kubernetes in 10 minutes][10]. I've removed just about everything I can so this guide still makes sense. Use it when you want to create a cluster on the cloud or on-premises as fast as possible. + +### 1.0 Pick a host + +We will be using Ubuntu 16.04 for this guide so that you can copy/paste all the instructions. Here are several environments where I've tested this guide. Just pick where you want to run your hosts. + +* [DigitalOcean][1] - developer cloud + +* [Civo][2] - UK developer cloud + +* [Packet][3] - bare metal cloud + +* 2x Dell Intel i7 boxes - at home + +> Civo is a relatively new developer cloud and one thing that I really liked was how quickly they can bring up hosts - in about 25 seconds. I'm based in the UK so I also get very low latency. + +### 1.1 Provision the machines + +You can get away with a single host for testing but I'd recommend at least three so we have a single master and two worker nodes. + +Here are some other guidelines: + +* Pick dual-core hosts with ideally at least 2GB RAM + +* If you can pick a custom username when provisioning the host then do that rather than root. For example Civo offers an option of `ubuntu`, `civo` or `root`. + +Now run through the following steps on each machine. It should take you less than 5-10 minutes. If that's too slow for you then you can use my utility script [kept in a Gist][11]: + +``` +$ curl -sL https://gist.githubusercontent.com/alexellis/e8bbec45c75ea38da5547746c0ca4b0c/raw/23fc4cd13910eac646b13c4f8812bab3eeebab4c/configure.sh | sh + +``` + +### 1.2 Login and install Docker + +Install Docker from the Ubuntu apt repository. This will be an older version of Docker but as Kubernetes is tested with old versions of Docker it will work in our favour. + +``` +$ sudo apt-get update \ + && sudo apt-get install -qy docker.io + +``` + +### 1.3 Disable the swap file + +This is now a mandatory step for Kubernetes. The easiest way to do this is to edit `/etc/fstab` and to comment out the line referring to swap. + +To save a reboot then type in `sudo swapoff -a`. + +> Disabling swap memory may appear like a strange requirement at first. If you are curious about this step then [read more here][4]. + +### 1.4 Install Kubernetes packages + +``` +$ sudo apt-get update \ + && sudo apt-get install -y apt-transport-https \ + && curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add - + +$ echo "deb http://apt.kubernetes.io/ kubernetes-xenial main" \ + | sudo tee -a /etc/apt/sources.list.d/kubernetes.list \ + && sudo apt-get update + +$ sudo apt-get update \ + && sudo apt-get install -y \ + kubelet \ + kubeadm \ + kubernetes-cni + +``` + +### 1.5 Create the cluster + +At this point we create the cluster by initiating the master with `kubeadm`. Only do this on the master node. + +> Despite any warnings I have been assured by [Weaveworks][5] and Lucas (the maintainer) that `kubeadm` is suitable for production use. + +``` +$ sudo kubeadm init + +``` + +If you missed a step or there's a problem then `kubeadm` will let you know at this point. + +Take a copy of the Kube config: + +``` +mkdir -p $HOME/.kube +sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config +sudo chown $(id -u):$(id -g) $HOME/.kube/config + +``` + +Make sure you note down the join token command i.e. + +``` +$ sudo kubeadm join --token c30633.d178035db2b4bb9a 10.0.0.5:6443 --discovery-token-ca-cert-hash sha256: + +``` + +### 2.0 Install networking + +Many networking providers are available for Kubernetes, but none are included by default, so let's use Weave Net from [Weaveworks][12] which is one of the most popular options in the Kubernetes community. It tends to work out of the box without additional configuration. + +``` +$ kubectl apply -f "https://cloud.weave.works/k8s/net?k8s-version=$(kubectl version | base64 | tr -d '\n')" + +``` + +If you have private networking enabled on your host then you may need to alter the private subnet that Weavenet uses for allocating IP addresses to Pods (containers). Here's an example of how to do that: + +``` +$ curl -SL "https://cloud.weave.works/k8s/net?k8s-version=$(kubectl version | base64 | tr -d '\n')&env.IPALLOC_RANGE=172.16.6.64/27" \ +| kubectl apply -f - + +``` + +> Weave also have a very cool visualisation tool called Weave Cloud. It's free and will show you the path traffic is taking between your Pods. [See here for an example with the OpenFaaS project][6]. + +### 2.2 Join the worker nodes to the cluster + +Now you can switch to each of your workers and use the `kubeadm join` command from 1.5\. Once you run that log out of the workers. + +### 3.0 Profit + +That's it - we're done. You have a cluster up and running and can deploy your applications. If you need to setup a dashboard UI then consult the [Kubernetes documentation][13]. + +``` +$ kubectl get nodes +NAME STATUS ROLES AGE VERSION +openfaas1 Ready master 20m v1.9.2 +openfaas2 Ready 19m v1.9.2 +openfaas3 Ready 19m v1.9.2 + +``` + +If you want to see my running through creating a cluster step-by-step and showing you how `kubectl` works then checkout my video below and make sure you subscribe + + +You can also get an "instant" Kubernetes cluster on your Mac for development using Minikube or Docker for Mac Edge edition. [Read my review and first impressions here][14]. + + +-------------------------------------------------------------------------------- + +via: https://blog.alexellis.io/your-instant-kubernetes-cluster/ + +作者:[Alex Ellis ][a] +译者:[译者ID](https://github.com/译者ID) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://blog.alexellis.io/author/alex/ +[1]:https://www.digitalocean.com/ +[2]:https://www.civo.com/ +[3]:https://packet.net/ +[4]:https://github.com/kubernetes/kubernetes/issues/53533 +[5]:https://weave.works/ +[6]:https://www.weave.works/blog/openfaas-gke +[7]:https://blog.alexellis.io/tag/kubernetes/ +[8]:https://blog.alexellis.io/tag/k8s/ +[9]:https://blog.alexellis.io/tag/cloud-native/ +[10]:https://www.youtube.com/watch?v=6xJwQgDnMFE +[11]:https://gist.github.com/alexellis/e8bbec45c75ea38da5547746c0ca4b0c +[12]:https://weave.works/ +[13]:https://kubernetes.io/docs/tasks/access-application-cluster/web-ui-dashboard/ +[14]:https://blog.alexellis.io/docker-for-mac-with-kubernetes/ +[15]:https://blog.alexellis.io/your-instant-kubernetes-cluster/# \ No newline at end of file diff --git a/sources/tech/20180129 How programmers learn to code.md b/sources/tech/20180129 How programmers learn to code.md new file mode 100644 index 0000000000..c741c01161 --- /dev/null +++ b/sources/tech/20180129 How programmers learn to code.md @@ -0,0 +1,63 @@ +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. + +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. + +### 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.” + +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. + + [![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. + +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. + +“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. + +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] + + [![HackerRank 2018 how to improve work-life balance](https://mybroadband.co.za/news/wp-content/uploads/2018/01/HackerRank-2018-how-to-improve-work-life-balance-378x430.jpg)][7] + +-------------------------------------------------------------------------------- + +via: https://mybroadband.co.za/news/smartphones/246583-how-programmers-learn-to-code.html + +作者:[Staff Writer ][a] +译者:[译者ID](https://github.com/译者ID) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://mybroadband.co.za/news/author/staff-writer +[1]:https://mybroadband.co.za/news/author/staff-writer +[2]:https://twitter.com/intent/tweet/?text=How+programmers+learn+to+code%20https://mybroadband.co.za/news/smartphones/246583-how-programmers-learn-to-code.html&via=mybroadband +[3]:mailto:?subject=How%20programmers%20learn%20to%20code&body=HackerRank%20recently%20published%20the%20results%20of%20its%202018%20Developer%20Skills%20Report.%0A%0Ahttps%3A%2F%2Fmybroadband.co.za%2Fnews%2Fsmartphones%2F246583-how-programmers-learn-to-code.html +[4]:https://mybroadband.co.za/news/smartphones/246583-how-programmers-learn-to-code.html#disqus_thread +[5]:https://mybroadband.co.za/news/wp-content/uploads/2018/01/HackerRank-2018-how-did-you-learn-to-code.jpg +[6]:https://mybroadband.co.za/news/wp-content/uploads/2018/01/HackerRank-2018-what-do-developers-want-most.jpg +[7]:https://mybroadband.co.za/news/wp-content/uploads/2018/01/HackerRank-2018-how-to-improve-work-life-balance.jpg +[8]:https://mybroadband.co.za/news/smartphones/246583-how-programmers-learn-to-code.html \ No newline at end of file diff --git a/sources/tech/20180130 Linux Kernel 4.15 An Unusual Release Cycle.md b/sources/tech/20180130 Linux Kernel 4.15 An Unusual Release Cycle.md new file mode 100644 index 0000000000..062cd3c3ca --- /dev/null +++ b/sources/tech/20180130 Linux Kernel 4.15 An Unusual Release Cycle.md @@ -0,0 +1,62 @@ +Linux Kernel 4.15: 'An Unusual Release Cycle' +============================================================ + + +![Linux](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/background-penguin.png?itok=g8NBQs24 "Linux") +Linus Torvalds released version 4.15 of the Linux Kernel on Sunday, a week later than originally scheduled. Learn about key updates in this latest release.[Creative Commons Zero][1]Pixabay + +Linus Torvalds [released version 4.15 of the Linux Kernel][7] on Sunday, again, and for a second version in a row, a week later than scheduled. The culprits for the late release were the Meltdown and Spectre bugs, as these two vulnerabilities forced developers to submit major patches well into what should have been the last cycle. Torvalds was not comfortable rushing the release, so he gave it another week. + +Unsurprisingly, the first big bunch of patches worth mentioning were those designed to sidestep [Meltdown and Spectre][8]. To avoid Meltdown, a problem that affects Intel chips, [developers have implemented  _Page Table Isolation_  (PTI)][9] for the x86 architecture. If for any reason you want to turn this off, you can use the `pti=off` kernel boot option. + +Spectre v2 affects both Intel and AMD chips and, to avoid it, [the kernel now comes with the  _retpoline_  mechanism][10]. Retpoline requires a version of GCC that supports the `-mindirect-branch=thunk-extern` functionality. As with PTI, the Spectre-inhibiting mechanism can be turned of. To do so, use the `spectre_v2=off` option at boot time. Although developers are working to address Spectre v1, at the moment of writing there is still not a solution, so there is no patch for this bug in 4.15. + +The solution for Meltdown on ARM has also been pushed to the next development cycle, but there is [a remedy for the bug on PowerPC with the  _RFI flush of L1-D cache_ feature][11] included in this release. + +An interesting side affect of all of the above is that new kernels now come with a  _/sys/devices/system/cpu/vulnerabilities/_  virtual directory. This directory shows the vulnerabilities affecting your CPU and the remedies being currently applied. + +The issues with buggy chips (and the manufacturers that keep things like this secret) has revived the call for the development of viable open source alternatives. This brings us to the partial support for [RISC-V][12] chips that has now been merged into the mainline kernel. RISC-V is an open instruction set architecture that allows manufacturers to create their own implementation of RISC-V chips, and it has resulted in several open sourced chips. While RISC-V chips are currently used mainly in embedded devices, powering things like smart hard disks or Arduino-like development boards, RISC-V proponents argue that the architecture is also well-suited for use on personal computers and even in multi-node supercomputers. + +[The support for RISC-V][13], as mentioned above, is still incomplete, and includes the architecture code but no device drivers. This means that, although a Linux kernel will run on RISC-V, there is no significant way to actually interact with the underlying hardware. That said, RISC-V is not vulnerable to any of the bugs that have dogged other closed architectures, and development for its support is progressing at a brisk pace, as [the RISC-V Foundation has the support of some of the industries biggest heavyweights][14]. + +### Other stuff that's new in kernel 4.15 + +Torvalds has often declared he likes things boring. Fortunately for him, he says, apart from the Spectre and Meltdown messes, most of the other things that happened in 4.15 were very much run of the mill, such as incremental improvements for drivers, support for new devices, and so on. However, there were a few more things worth pointing out: + +* [AMD got support for Secure Encrypted Virtualization][3]. This allows the kernel to fence off the memory a virtual machine is using by encrypting it. The encrypted memory can only be decrypted by the virtual machine that is using it. Not even the hypervisor can see inside it. This means that data being worked on by VMs in the cloud, for example, is safe from being spied on by any other process outside the VM. + +* AMD GPUs get a substantial boost thanks to [the inclusion of  _display code_][4] . This gives mainline support to Radeon RX Vega and Raven Ridge cards and also implements HDMI/DP audio for AMD cards. + +* Raspberry Pi aficionados will be glad to know that [the 7'' touchscreen is now natively supported][5], which is guaranteed to lead to hundreds of fun projects. + +To find out more, you can check out the write-ups at [Kernel Newbies][15] and [Phoronix][16]. + + _Learn more about Linux through the free ["Introduction to Linux" ][6]course from The Linux Foundation and edX._ + +-------------------------------------------------------------------------------- + +via: https://www.linux.com/blog/intro-to-linux/2018/1/linux-kernel-415-unusual-release-cycle + +作者:[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]:https://www.linux.com/licenses/category/creative-commons-zero +[2]:https://www.linux.com/files/images/background-penguinpng +[3]:https://git.kernel.org/linus/33e63acc119d15c2fac3e3775f32d1ce7a01021b +[4]:https://git.kernel.org/torvalds/c/f6705bf959efac87bca76d40050d342f1d212587 +[5]:https://git.kernel.org/linus/2f733d6194bd58b26b705698f96b0f0bd9225369 +[6]:https://training.linuxfoundation.org/linux-courses/system-administration-training/introduction-to-linux +[7]:https://lkml.org/lkml/2018/1/28/173 +[8]:https://meltdownattack.com/ +[9]:https://git.kernel.org/linus/5aa90a84589282b87666f92b6c3c917c8080a9bf +[10]:https://git.kernel.org/linus/76b043848fd22dbf7f8bf3a1452f8c70d557b860 +[11]:https://git.kernel.org/linus/aa8a5e0062ac940f7659394f4817c948dc8c0667 +[12]:https://riscv.org/ +[13]:https://git.kernel.org/torvalds/c/b293fca43be544483b6488d33ad4b3ed55881064 +[14]:https://riscv.org/membership/ +[15]:https://kernelnewbies.org/Linux_4.15 +[16]:https://www.phoronix.com/scan.php?page=search&q=Linux+4.15 \ No newline at end of file diff --git a/sources/tech/20180130 Mitigating known security risks in open source libraries.md b/sources/tech/20180130 Mitigating known security risks in open source libraries.md new file mode 100644 index 0000000000..adb1491e7d --- /dev/null +++ b/sources/tech/20180130 Mitigating known security risks in open source libraries.md @@ -0,0 +1,249 @@ +Mitigating known security risks in open source libraries +============================================================ + +>Fixing vulnerable open source packages. + + +![Machine](https://d3tdunqjn7n0wj.cloudfront.net/360x240/machine-2881186_1920-aa3ebed0567d4ab0a107baa640661e35.jpg) + +Machine (source: [Skitterphoto][9]) + + +This is an excerpt from [Securing Open Source Libraries][13], by Guy Podjarny.  +[Read the preceding chapter][14] or [view the full report][15]. + + +### Fixing Vulnerable Packages + +Finding out if you’re using vulnerable packages is an important step, but it’s not the real goal. The real goal is to fix those issues! + +This chapter focuses on all you should know about fixing vulnerable packages, including remediation options, tooling, and various nuances. Note that SCA tools traditionally focused on finding or preventing vulnerabilities, and most put little emphasis on fix beyond providing advisory information or logging an issue. Therefore, you may need to implement some of these remediations yourself, at least until more SCA solutions expand to include them. + +There are several ways to fix vulnerable packages, but upgrading is the best choice. If that is not possible, patching offers a good alternative. The following sections discuss each of these options, and we will later take a look at what you can do in situations where neither of these solutions is possible. + +### Upgrading + +As I’ve previously stated, a vulnerability is a type of bug, and the best way to address a bug is to use a newer version where it is fixed. And so, the best way to fix a vulnerable dependency is to upgrade to a newer version. Statistically, most disclosed vulnerabilities are eventually fixed. In npm, 59% of reported vulnerabilities have a fix. In Maven, 90% are remediable, while that portion is 85% in RubyGems.[1][4] In other words, more often than not, there is a version of your library where the vulnerability is fixed. + +Finding a vulnerable package requires knowledge of which versions are vulnerable. This means that, at the very least, every tool that finds issues can tell which versions are vulnerable, allowing you to look for newer versions of the library and upgrade. Most tools also take the minor extra step of determining the minimal fixed version, and noting it in the advisory. + +Upgrading is therefore the best way to make a vulnerability go away. It’s technically easy (update a manifest or lock file), and it’s something dev teams are very accustomed to doing. That said, upgrading still holds some complexity. + +### Major Upgrades + +While most issues are fixed, very often the fix is only applied to the latest and greatest version of the library. If you’re still using an older version of the library, upgrading may mean switching to a new major version. Major upgrades are typically not backward compatible, introducing more risk and requiring more dev effort. + +Another reason for fixing an issue only in the next major version is that sometimes fixing a vulnerability means reducing functionality. For instance, fixing a certain [XSS vulnerability in a jQuery 2.x codebase][5] requires a change to the way certain selectors are interpreted. The jQuery team determined too many people are relying on this functionality to deem this a non-breaking change, and so only fixed the vulnerability in their 3.x stream. + +For these reasons, a major upgrade can often be difficult, but if you can accept it, it’s still the best way to fix a vulnerability. + +### Indirect Dependency Upgrade + +If you’re consuming a dependency directly, upgrading is relatively straightforward. But what happens when one of your dependencies is the one who pulled in the vulnerable package? Most dependencies are in fact indirect dependencies (a.k.a. transitive dependencies), making upgrades a bit more complex. + +The cleanest way to perform an indirect upgrade is through a direct one. If your app uses `A@1`, which uses a vulnerable `B@1`, it’s possible that upgrading to `A@2` will trigger a downstream upgrade to `B@2` and fix the issue. Applying such an upgrade is easy (it’s essentially a direct upgrade), but discovering  _which_  upgrade to do (and whether one even exists) is time consuming. While not common, some SCA tools can determine and advise on the  _direct_  upgrades you need to make to fix an  _indirect_  vulnerability. If your tooling doesn’t support it, you’ll need to do the searching manually. + +Old vulnerabilities in indirect libraries can often be fixed with a direct upgrade, but such upgrades are frequently unavailable for new issues. When a new vulnerability is disclosed, even if the offending package releases a fix right away, it takes a while for the dependency chain to catch up. If you can’t find a path to an indirect upgrade for a newly disclosed flaw, be sure to recheck frequently as one may show up soon. Once again, some SCA tools will do this monitoring for you and alert you when new remediations are available. + + +![The direct vulnerable EJS can be upgraded, but indirect instance cannot currently be upgraded](https://d3ansictanv2wj.cloudfront.net/sosl_0301-d3ce5b0bf64893e26ee74627bfba5300.png) +Figure 1-1. The direct vulnerable EJS can be upgraded, but indirect instance cannot currently be upgraded + +### Conflicts + +Another potential obstacle to upgrading is a conflict. Many languages, such as Ruby and Python, require dependencies to be global, and clients such as Ruby’s bundler and Python’s pip determine the mix of library versions that can co-exist. As a result, upgrading one library may trigger a conflict with another. While developers are adept at handling such conflicts, there are times when such issues simply cannot be resolved. + +On the positive side, global dependency managers, such as Ruby’s bundler, allow the parent app to add a constraint. For instance, if a downstream `B@1` gem is vulnerable, you can add `B@^2` to your Gemfile, and have bundler sort out the surrounding impact. Adding such constraints is a safe and legitimate solution, as long as your ecosystem tooling can figure out a conflict-free combination of libraries. + +### Is a Newer Version Always Safer? + +The conversation about upgrading begs a question: can a vulnerability also be fixed by downgrading? + +For the most part, the answer is no. Vulnerabilities are bugs, and bugs are typically fixed in a newer version, not an older one. In general, maintaining a good upgrade cadence and keeping your dependencies up to date is a good preventative measure to reduce the risk of vulnerabilities. + +However, in certain cases, code changes or (more often) new features are the ones that trigger a vulnerability. In those cases, it’s indeed possible that downgrading will fix the discovered flaw. The advisory should give you the information you need about which versions are affected by the vulnerability. That said, note that downgrading a package puts you at higher risk of being exposed to new issues, and can make it harder to upgrade when that happens. I suggest you see downgrading as a temporary and rarely used remediation path. + +### There Is No Fixed Version + +Last on the list of reasons preventing you from upgrading to a safe version is such a version not existing in the first place! + +While most vulnerabilities are fixed, many remain unfixed. This is sometimes a temporary situation—for instance, when a vulnerability was made public without waiting for a fix to be released. Other times, it may be a more long-term scenario, as many repositories fall into a poor maintenance state, and don’t fix reported issues nor accept community patches. + +In the following sections I’ll discuss some options for when you cannot upgrade a vulnerability away. + +### Patching + +Despite all the complexity it may involve, upgrading is the best way to fix an issue. However, if you cannot upgrade, patching the vulnerability is the next best option. + +Patching means taking a library as is, including its vulnerabilities, and then modifying it to fix a vulnerability it holds. Patching should apply the minimal set of changes to the library, so as to keep its functionality unharmed and only address the issue at hand. + +Patching inevitably holds a certain amount of risk. When you use a package downloaded millions of time a month, you have some assurance that bugs in it will be discovered, reported, and often fixed. When you download that package and modify it, your version of the code will not be quite as battle tested. + +Patching is therefore an exercise in risk management. What presents a greater risk: having the vulnerability, or applying the patch? For well-managed patches, especially for ones small in scope, I believe it’s almost always better to have a patch than a vulnerability. + +It’s worth noting that patching application dependencies is a relatively new concept, but an old hat in the operating system world. When dealing with operating system dependencies, we’re accustomed to consuming a feed of fixes by running `apt-get upgrade` or an equivalent command, often remaining unaware of which issues we fixed. What most don’t know is that many of the fixes you pull down are in fact back-ported versions of the original OS author code changes, created and tested by Canonical, RedHat, and the like. A safe registry that feeds you the non-vulnerable variants of your dependencies doesn’t exist yet in the application libraries world, but patching is sometimes doable in other ways. + +### Sourcing Patches + +To create a patch, you first need to have a fix for the vulnerability! You could write one yourself, but patches are more often sourced from existing community fixes. + +The first place to look for a patch is a new version of the vulnerable package. Most often the vulnerability  _was_  fixed by the maintainers of the library, but that fix may be in an out-of-reach indirect dependency, or perhaps was only fitted back into the latest major version. Those fixes can be extracted from the original repo and stored into their own patch file, as well as back-ported into older versions if need be. + +Another common source for patches are external pull requests (PRs). Open source maintenance is a complicated topic, and it’s not uncommon for repos to go inactive. In such repos, you may find community pull requests that fix a vulnerability, have been commented on and perhaps vetted by others, but are not merged and published into the main stream. Such PRs are a good starting point—if not the full solution—for creating a patch. For instance, an XSS issue in the popular JavaScript Markdown parsing library marked had an [open fix PR][6] for nearly a year before it was incorporated into a new release. During this period, you could use the fix PR code to patch the issue in your apps. + +Snyk maintains its own set of patches in its [open source database][7]. Most of those patches are captures or back-ports of original fixes, a few are packaged pull requests, and even fewer are written by the Snyk security research team. + +### Depend on GitHub Hash + +In very specific cases, you may be able to patch without storing any code changes. This is only possible if the vulnerable dependency is a direct dependency of your app, and the public repo holding the package has a commit that fixes the issue (often a pull request, as mentioned before). + +If that’s the case, most package managers allow you to change your manifest file to point to the GitHub commit instead of naming your package and version. Git hashes are immutable, so you’ll know exactly what you’re getting, even if the pull request evolved. However, the commit may be deleted, introducing certain reliability concerns. + +### Fork and Patch + +When patching a vulnerability in a direct dependency, assuming you don’t want to depend on an external commit or have none to use, you can create one of your own. Doing so typically means forking the GitHub repository to a user you control, and patching it. Once done, you can modify your manifest to point to your fixed repository. + +Forking is a fairly common way of fixing different bugs in dependencies, and also carries some nice reliability advantages, as the code you use is now in your own control. It has the downside of breaking off the normal version stream of the dependency, but it’s a decent short-term solution to vulnerabilities in direct dependencies. Unfortunately, forking is not a viable option for patching indirect dependencies. + +### Static Patching at Build Time + +Another opportunity to patch a dependency is during build time. This type of patching is more complicated, as it requires: + +1. Storing a patch in a file (often a  _.patch_  file, or an alternative JAR file with the issue fixed) + +2. Installing the dependencies as usual + +3. Determining where the dependency you’d like to patch was installed + +4. Applying the patch by modifying or swapping out the risky code + +These steps are not trivial, but they’re also usually doable using package manager commands. If a vulnerability is worth fixing, and there are no easier means to fix it, this approach should be considered. + +This is a classic problem for tools to address, as patches can be reused and their application can be repeated. However, at the time of this writing, Snyk is the only SCA tool that maintains patches in its DB and lets you apply them in your pipeline. I predict over time more and more tools will adopt this approach. + +### Dynamic Patching at Boot Time + +In certain programming languages, classes can also be modified at runtime, a technique often referred to as "monkey patching." Monkey patching can be used to fix vulnerabilities, though that practice has not become the norm in any ecosystem. The most prevalent use of monkey patching to fix vulnerabilities is in Ruby on Rails, where the Rails team has often released patches for vulnerabilities in the libraries it maintains. + +### Other Remediation Paths + +So far, I’ve stated upgrades are the best way to address a vulnerability, and patching the second best. However, what should you do when you cannot (or will not) upgrade nor patch? + +In those cases, you have no choice but to dig deeper. You need to understand the vulnerability better, and how it plays into your application. If it indeed puts your application at notable risk, there are a few steps you can take. + +### Removal + +Removing a dependency is a very effective way of fixing its vulnerabilities. Unfortunately, you’ll be losing its functionality at the same time. + +Dropping a dependency is often hard, as it by definition requires changes to your actual code. That said, such removal may turn out to be easy—for instance, when a dependency was used for convenience and can be rewritten instead, or when a comparable alternative exists in the ecosystem. + +Easy or hard, removing a dependency should always be considered an option, and weighed against the risk of keeping it. + +### External Mitigation + +If you can’t fix the vulnerable code, you can try to block attacks that attempt to exploit it instead. Introducing a rule in a web app firewall, modifying the parts of your app that accept related user input, or even blocking a port are all potential ways to mitigate a vulnerability. + +Whether you can mitigate and how to do so depends on the specific vulnerability and application, and in many cases such protection is impossible or high risk. That said, the most trivially exploited vulnerabilities, such as the March 2017 Struts2 RCE and ImageTragick, are often the ones most easily identified and blocked, so this approach is definitely worth exploring. + +###### Tip + +### Protecting Against Unknown Vulnerabilities + +Once you’re aware of a known vulnerability, your best move is to fix it, and external mitigation is a last resort. However, security controls that protect against unknown vulnerabilities, ranging from web app firewalls to sandboxed processes to ensuring least privilege, can often protect you from known vulnerabilities as well. + +### Log Issue + +Last but not least, even if you choose not to remediate the issue, the least you can do is create an issue for it. Beyond its risk management advantages, logging the issue will remind you to re-examine the remediation options over time—for instance, looking for newly available upgrades or patches that can help. + +If you have a security operations team, make sure to make them aware of vulnerabilities you are not solving right now. This information can prove useful when they triage suspicious behavior on the network, as such behavior may come down to this security hole being exploited. + +### Remediation Process + +Beyond the specific techniques, there are few broader guidelines when it comes to remediating issues. + +### Ignoring Issues + +If you choose not to fix an issue, or to fix it through a custom path, you’ll need to tell your SCA tool you did. Otherwise, the tool will continue to indicate this problem. + +All OSS security tools support ignoring a vulnerability, but have slightly different capabilities. You should consider the following, and try to note that in your tool of choice: + +* Are you ignoring the issue because it doesn’t affect you (perhaps you’ve mitigated it another way) or because you’ve accepted the risk? This may reflect differently in your top-level reports. + +* Do you want to mute the issue indefinitely, or just "snooze" it? Ignoring temporarily is common for low-severity issues that don’t yet have an upgrade, where you’re comfortable taking the risk for a bit and anticipate an upgrade will show up soon. + +* Do you want to ignore all instances of this known vulnerability (perhaps it doesn’t apply to your system), or only certain vulnerable paths (which, after a careful vetting process, you’ve determined to be non-exploitable)? + +Properly tagging the reason for muting an alert helps manage these vulnerabilities over time and across projects, and reduces the chance of an issue being wrongfully ignored and slipping through the cracks. + +### Fix All Vulnerable Paths + +For all the issues you’re not ignoring, remember that remediation has to be done for  _every vulnerable path_ . + +This is especially true for upgrades, as every path must be assessed for upgrade separately, but also applies to patches in many ecosystems. + +### Track Remediations Over Time + +As already mentioned, a fix is typically issued for the vulnerable package first, and only later propagates through the dependency chain as other libraries upgrade to use the newer (and safer) version. Similarly, community or author code contributions are created constantly, addressing issues that weren’t previously fixable. + +Therefore, it’s worth tracking remediation options over time. For ignored issues, periodically check if an easy fix is now available. For patched issues, track potential updates you can switch to. Certain SCA tools automate this tracking and notify you (or open automated pull requests) when such new remediations are available. + +### Invest in Making Fixing Easy + +The unfortunate reality is that new vulnerabilities in libraries are discovered all the time. This is a fact of life—code will have bugs, some of those bugs are security bugs (vulnerabilities), and some of those are disclosed. Therefore, you and your team should expect to get a constant stream of vulnerability notifications, which you need to act on. + +If fixing these vulnerabilities isn’t easy, your team will not do it. Fixing these issues competes with many priorities, and its oh-so-easy to put off this invisible risk. If each alert requires a lot of time to triage and determine a fix for, the ensuing behavior would likely be to either put it off or try to convince yourself it’s not a real problem. + +In the world of operating systems, fixing has become the default action. In fact, "patching your servers" means taking in a feed of fixes, often without ever knowing which vulnerabilities we fix. We should strive to achieve at least this level of simplicity when dealing with vulnerable app dependencies too. + +Part of this effort is on tooling providers. SCA tools should let you fix vulnerabilities with a click or proactive pull requests, or patch them with a single command like `apt-get upgrade` does on servers. The other part of the effort is on you. Consider it a high priority to make vulnerability remediation easy, choose priority, choose your tools accordingly, and put in the effort to enrich or adapt those tools to fit your workflow. + +### Summary + +You should always keep in mind that finding these vulnerabilities isn’t the goal—fixing them is. Because fixing vulnerabilities is something your team will need to do often, defining the processes and tools to get that done is critical. + +A great way to get started with remediation is to find vulnerabilities that can be fixed with a non-breaking upgrade, and get those upgrades done. While not entirely risk-free, these upgrades should be backward compatible, and getting these security holes fixed gets you off to a very good start. + +[1][8]Stats based on vulnerabilities curated in the Snyk vulnerability DB. + + +This is an excerpt from [Securing Open Source Libraries][16], by Guy Podjarny.  +[Read the preceding chapter][17] or [view the full report][18]. + + + +------------------------------------- + +作者简介: + +Guy Podjarny (Guypo) is a web performance researcher/evangelist and Akamai's Web CTO, focusing primarily on Mobile and Front-End performance. As a researcher, Guy frequently runs large scale tests, exploring performance in the real world and matching it to how browsers behave, and was one of the first to highlight the performance implications of Responsive Web Design. Guy is also the author of Mobitest, a free mobile measurement tool, and contributes to various open source tools. Guy was previously the co-founder and CTO of blaze.io, ac... + +-------------------------------------------------------------------------------- + +via: https://www.oreilly.com/ideas/mitigating-known-security-risks-in-open-source-libraries + +作者:[ Guy Podjarny][a] +译者:[译者ID](https://github.com/译者ID) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://www.oreilly.com/people/4dda0-guy-podjarny +[1]:https://www.safaribooksonline.com/home/?utm_source=newsite&utm_medium=content&utm_campaign=lgen&utm_content=security-post-safari-right-rail-cta +[2]:https://www.safaribooksonline.com/home/?utm_source=newsite&utm_medium=content&utm_campaign=lgen&utm_content=security-post-safari-right-rail-cta +[3]:https://www.safaribooksonline.com/home/?utm_source=newsite&utm_medium=content&utm_campaign=lgen&utm_content=security-post-safari-right-rail-cta +[4]:https://www.oreilly.com/ideas/mitigating-known-security-risks-in-open-source-libraries#id-xJ0u4SBFphz +[5]:https://snyk.io/vuln/npm:jquery:20150627 +[6]:https://github.com/chjj/marked/pull/592 +[7]:https://github.com/snyk/vulnerabilitydb +[8]:https://www.oreilly.com/ideas/mitigating-known-security-risks-in-open-source-libraries#id-xJ0u4SBFphz-marker +[9]:https://pixabay.com/en/machine-mill-industry-steam-2881186/ +[10]:https://www.oreilly.com/ideas/mitigating-known-security-risks-in-open-source-libraries +[11]:https://www.oreilly.com/people/4dda0-guy-podjarny +[12]:https://www.oreilly.com/people/4dda0-guy-podjarny +[13]:https://www.safaribooksonline.com/library/view/securing-open-source/9781491996980/?utm_source=oreilly&utm_medium=newsite&utm_campaign=fixing-vulnerable-open-source-packages +[14]:https://www.oreilly.com/ideas/finding-vulnerable-open-source-packages?utm_source=oreilly&utm_medium=newsite&utm_campaign=fixing-vulnerable-open-source-packages +[15]:https://www.safaribooksonline.com/library/view/securing-open-source/9781491996980/?utm_source=oreilly&utm_medium=newsite&utm_campaign=fixing-vulnerable-open-source-packages +[16]:https://www.safaribooksonline.com/library/view/securing-open-source/9781491996980/?utm_source=oreilly&utm_medium=newsite&utm_campaign=fixing-vulnerable-open-source-packages +[17]:https://www.oreilly.com/ideas/finding-vulnerable-open-source-packages?utm_source=oreilly&utm_medium=newsite&utm_campaign=fixing-vulnerable-open-source-packages +[18]:https://www.safaribooksonline.com/library/view/securing-open-source/9781491996980/?utm_source=oreilly&utm_medium=newsite&utm_campaign=fixing-vulnerable-open-source-packages +[19]:https://pixabay.com/en/machine-mill-industry-steam-2881186/ \ No newline at end of file diff --git a/sources/tech/20180130 Reckoning The Spectre And Meltdown Performance Hit.md b/sources/tech/20180130 Reckoning The Spectre And Meltdown Performance Hit.md new file mode 100644 index 0000000000..d7140a21cf --- /dev/null +++ b/sources/tech/20180130 Reckoning The Spectre And Meltdown Performance Hit.md @@ -0,0 +1,85 @@ +Reckoning The Spectre And Meltdown Performance Hit For HPC +============================================================ + +![](https://3s81si1s5ygj3mzby34dq6qf-wpengine.netdna-ssl.com/wp-content/uploads/2015/03/intel-chip-logo-bw-200x147.jpg) + +While no one has yet created an exploit to take advantage of the Spectre and Meltdown speculative execution vulnerabilities that were exposed by Google six months ago and that were revealed in early January, it is only a matter of time. The [patching frenzy has not settled down yet][2], and a big concern is not just whether these patches fill the security gaps, but at what cost they do so in terms of application performance. + +To try to ascertain the performance impact of the Spectre and Meltdown patches, most people have relied on comments from Google on the negligible nature of the performance hit on its own applications and some tests done by Red Hat on a variety of workloads, [which we profiled in our initial story on the vulnerabilities][3]. This is a good starting point, but what companies really need to do is profile the performance of their applications before and after applying the patches – and in such a fine-grained way that they can use the data to debug the performance hit and see if there is any remediation they can take to alleviate the impact. + +In the meantime, we are relying on researchers and vendors to figure out the performance impacts. Networking chip maker Mellanox Technologies, always eager to promote the benefits of the offload model of its switch and network interface chips, has run some tests to show the effects of the Spectre and Meltdown patches on high performance networking for various workloads and using various networking technologies, including its own Ethernet and InfiniBand devices and Intel’s OmniPath. Some HPC researchers at the University of Buffalo have also done some preliminary benchmarking of selected HPC workloads to see the effect on compute and network performance. This is a good starting point, but is far from a complete picture of the impact that might be seen on HPC workloads after organization deploy the Spectre and Meltdown patches to their systems. + +To recap, here is what Red Hat found out when it tested the initial Spectre and Meltdown patches running its Enterprise Linux 7 release on servers using Intel’s “Haswell” Xeon E5 v3, “Broadwell” Xeon E5 v4, and “Skylake” Xeon SP processors: + +* **Measurable, 8 percent to 19 percent:** Highly cached random memory, with buffered I/O, OLTP database workloads, and benchmarks with high kernel-to-user space transitions are impacted between 8 percent and 19 percent. Examples include OLTP Workloads (TPC), sysbench, pgbench, netperf (< 256 byte), and fio (random I/O to NvME). + +* **Modest, 3 percent to 7 percent:** Database analytics, Decision Support System (DSS), and Java VMs are impacted less than the Measurable category. These applications may have significant sequential disk or network traffic, but kernel/device drivers are able to aggregate requests to moderate level of kernel-to-user transitions. Examples include SPECjbb2005, Queries/Hour and overall analytic timing (sec). + +* **Small, 2 percent to 5 percent:** HPC CPU-intensive workloads are affected the least with only 2 percent to 5 percent performance impact because jobs run mostly in user space and are scheduled using CPU pinning or NUMA control. Examples include Linpack NxN on X86 and SPECcpu2006. + +* **Minimal impact:** Linux accelerator technologies that generally bypass the kernel in favor of user direct access are the least affected, with less than 2% overhead measured. Examples tested include DPDK (VsPERF at 64 byte) and OpenOnload (STAC-N). Userspace accesses to VDSO like get-time-of-day are not impacted. We expect similar minimal impact for other offloads. + +And just to remind you, according to Red Hat containerized applications running atop Linux do not incur an extra Spectre or Meltdown penalty compared to applications running on bare metal because they are implemented as generic Linux processes themselves. But applications running inside virtual machines running atop hypervisors, Red Hat does expect that, thanks to the increase in the frequency of user-to-kernel transitions, the performance hit will be higher. (How much has not yet been revealed.) + +Gilad Shainer, the vice president of marketing for the InfiniBand side of the Mellanox house, shared some initial performance data from the company’s labs with regard to the Spectre and Meltdown patches. ([The presentation is available online here.][4]) + +In general, Shainer tells  _The Next Platform_ , the offload model that Mellanox employs in its InfiniBand switches (RDMA is a big component of this) and in its Ethernet (The RoCE clone of RDMA is used here) are a very big deal given the fact that the network drivers bypass the operating system kernels. The exploits take advantage, in one of three forms, of the porous barrier between the kernel and user spaces in the operating systems, so anything that is kernel heavy will be adversely affected. This, says Shainer, includes the TCP/IP protocol that underpins Ethernet as well as the OmniPath protocol, which by its nature tries to have the CPUs in the system do a lot of the network processing. Intel and others who have used an onload model have contended that this allows for networks to be more scalable, and clearly there are very scalable InfiniBand and OmniPath networks, with many thousands of nodes, so both approaches seem to work in production. + +Here are the feeds and speeds on the systems that Mellanox tested on two sets of networking tests. For the comparison of Ethernet with RoCE added and standard TCP over Ethernet, the hardware was a two-socket server using Intel’s Xeon E5-2697A v4 running at 2.60 GHz. This machine was configured with Red Hat Enterprise Linux 7.4, with kernel versions 3.10.0-693.11.6.el7.x86_64 and 3.10.0-693.el7.x86_64\. (Those numbers  _are_  different – there is an  _11.6_  in the middle of the second one.) The machines were equipped with ConnectX-5 server adapters with firmware 16.22.0170 and the MLNX_OFED_LINUX-4.3-0.0.5.0 driver. The workload that was tested was not a specific HPC application, but rather a very low level, homegrown interconnect benchmark that is used to stress switch chips and NICs to see their peak  _sustained_  performance, as distinct from peak  _theoretical_ performance, which is the absolute ceiling. This particular test was run on a two-node cluster, passing data from one machine to the other. + +Here is how the performance stacked up before and after the Spectre and Meltdown patches were added to the systems: + + [![](https://3s81si1s5ygj3mzby34dq6qf-wpengine.netdna-ssl.com/wp-content/uploads/2018/01/mellanox-spectre-meltdown-roce-versus-tcp.jpg)][5] + +As you can see, at this very low level, there is no impact on network performance between two machines supporting RoCE on Ethernet, but running plain vanilla TCP without an offload on top of Ethernet, there are some big performance hits. Interestingly, on this low-level test, the impact was greatest on small message sizes in the TCP stack and then disappeared as the message sizes got larger. + +On a separate round of tests pitting InfiniBand from Mellanox against OmniPath from Intel, the server nodes were configured with a pair of Intel Xeon SP Gold 6138 processors running at 2 GHz, also with Red Hat Enterprise Linux 7.4 with the 3.10.0-693.el7.x86_64 and 3.10.0-693.11.6.el7.x86_64          kernel versions. The OmniPath adapter uses the IntelOPA-IFS.RHEL74-x86_64.10.6.1.0.2 driver and the Mellanox ConnectX-5 adapter uses the MLNX_OFED 4.2 driver. + +Here is how the InfiniBand and OmniPath protocols did on the tests before and after the patches: + + [![](https://3s81si1s5ygj3mzby34dq6qf-wpengine.netdna-ssl.com/wp-content/uploads/2018/01/mellanox-spectre-meltdown-infiniband-versus-omnipath.jpg)][6] + +Again, thanks to the offload model and the fact that this was a low level benchmark that did not hit the kernel very much (and some HPC applications might cross that boundary and therefore invoke the Spectre and Meltdown performance penalties), there was no real effect on the two-node cluster running InfiniBand. With the OmniPath system, the impact was around 10 percent for small message sizes, and then grew to 25 percent or so once the message sizes transmitted reached 512 bytes. + +We have no idea what the performance implications are for clusters of more than two machines using the Mellanox approach. It would be interesting to see if the degradation compounds or doesn’t. + +### Early HPC Performance Tests + +While such low level benchmarks provide some initial guidance on what the effect might be of the Spectre and Meltdown patches on HPC performance, what you really need is a benchmark run of real HPC applications running on clusters of various sizes, both before and after the Spectre and Meltdown patches are applied to the Linux nodes. A team of researchers led by Nikolay Simakov at the Center For Computational Research at SUNY Buffalo fired up some HPC benchmarks and a performance monitoring tool derived from the National Science Foundation’s Extreme Digital (XSEDE) program to see the effect of the Spectre and Meltdown patches on how much work they could get done as gauged by wall clock time to get that work done. + +The paper that Simakov and his team put together on the initial results [is found here][7]. The tool that was used to monitor the performance of the systems was called XD Metrics on Demand, or XDMoD, and it was open sourced and is available for anyone to use. (You might consider [Open XDMoD][8] for your own metrics to determine the performance implications of the Spectre and Meltdown patches.) The benchmarks tested by the SUNY Buffalo researchers included the NAMD molecular dynamics and NWChem computational chemistry applications, as well as the HPC Challenge suite, which itself includes the STREAM memory bandwidth test and the NASA Parallel Benchmarks (NPB), the Interconnect MPI Benchmarks (IMB). The researchers also tested the IOR file reading and the MDTest metadata benchmark tests from Lawrence Livermore National Laboratory. The IOR and MDTest benchmarks were run in local mode and in conjunction with a GPFS parallel file system running on an external 3 PB storage cluster. (The tests with a “.local” suffix in the table are run on storage in the server nodes themselves.) + +SUNY Buffalo has an experimental cluster with two-socket machines based on Intel “Nehalem” Xeon L5520 processors, which have eight cores and which are, by our reckoning, very long in the tooth indeed in that they are nearly nine years old. Each node has 24 GB of main memory and has 40 Gb/sec QDR InfiniBand links cross connecting them together. The systems are running the latest CentOS 7.4.1708 release, without and then with the patches applied. (The same kernel patches outlined above in the Mellanox test.) Simakov and his team ran each benchmark on a single node configuration and then ran the benchmark on a two node configuration, and it shows the difference between running a low-level benchmark and actual applications when doing tests. Take a look at the table of results: + + [![](https://3s81si1s5ygj3mzby34dq6qf-wpengine.netdna-ssl.com/wp-content/uploads/2018/01/suny-buffalo-spectre-meltdown-test-table.jpg)][9] + +The before runs of each application tested were done on around 20 runs, and the after was done on around 50 runs. For the core HPC applications – NAMD, NWChem, and the elements of HPCC – the performance degradation was between 2 percent and 3 percent, consistent with what Red Hat told people to expect back in the first week that the Spectre and Meltdown vulnerabilities were revealed and the initial patches were available. However, moving on to two-node configurations, where network overhead was taken into account, the performance impact ranged from 5 percent to 11 percent. This is more than you would expect based on the low level benchmarks that Mellanox has done. Just to make things interesting, on the IOR and MDTest benchmarks, moving from one to two nodes actually lessened the performance impact; running the IOR test on the local disks resulted in a smaller performance hit then over the network for a single node, but was not as low as for a two-node cluster running out to the GPFS file system. + +There is a lot of food for thought in this data, to say the least. + +What we want to know – and what the SUNY Buffalo researchers are working on – is what happens to performance on these HPC applications when the cluster is scaled out. + +“We will know that answer soon,” Simakov tells  _The Next Platform_ . “But there are only two scenarios that are possible. Either it is going to get worse or it is going to stay about the same as a two-node cluster. We think that it will most likely stay the same, because all of the MPI communication happens through the shared memory on a single node, and when you get to two nodes, you get it into the network fabric and at that point, you are probably paying all of the extra performance penalties.” + +We will update this story with data on larger scale clusters as soon as Simakov and his team provide the data. + +-------------------------------------------------------------------------------- + +via: https://www.nextplatform.com/2018/01/30/reckoning-spectre-meltdown-performance-hit-hpc/ + +作者:[Timothy Prickett Morgan][a] +译者:[译者ID](https://github.com/译者ID) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://www.nextplatform.com/author/tpmn/ +[1]:https://www.nextplatform.com/author/tpmn/ +[2]:https://www.nextplatform.com/2018/01/18/datacenters-brace-spectre-meltdown-impact/ +[3]:https://www.nextplatform.com/2018/01/08/cost-spectre-meltdown-server-taxes/ +[4]:http://www.mellanox.com/related-docs/presentations/2018/performance/Spectre-and-Meltdown-Performance.pdf?homepage +[5]:https://3s81si1s5ygj3mzby34dq6qf-wpengine.netdna-ssl.com/wp-content/uploads/2018/01/mellanox-spectre-meltdown-roce-versus-tcp.jpg +[6]:https://3s81si1s5ygj3mzby34dq6qf-wpengine.netdna-ssl.com/wp-content/uploads/2018/01/mellanox-spectre-meltdown-infiniband-versus-omnipath.jpg +[7]:https://arxiv.org/pdf/1801.04329.pdf +[8]:http://open.xdmod.org/7.0/index.html +[9]:https://3s81si1s5ygj3mzby34dq6qf-wpengine.netdna-ssl.com/wp-content/uploads/2018/01/suny-buffalo-spectre-meltdown-test-table.jpg \ No newline at end of file diff --git a/sources/tech/20180131 For your first HTML code lets help Batman write a love letter.md b/sources/tech/20180131 For your first HTML code lets help Batman write a love letter.md new file mode 100644 index 0000000000..0cf4ec4040 --- /dev/null +++ b/sources/tech/20180131 For your first HTML code lets help Batman write a love letter.md @@ -0,0 +1,912 @@ +For your first HTML code, let’s help Batman write a love letter +============================================================ + +![](https://cdn-images-1.medium.com/max/1000/1*kZxbQJTdb4jn_frfqpRg9g.jpeg) +[Image Credit][1] + +One fine night, your stomach refuses to digest the large Pizza you had at dinner, and you have to rush to the bathroom in the middle of your sleep. + +In the bathroom, while wondering why this is happening to you, you hear a heavy voice from the vent: “Hey, I am Batman.” + +What would you do? + +Before you panic and stand up in middle of the critical process, Batman says, “I need your help. I am a super geek, but I don’t know HTML. I need to write my love letter in HTML — would you do it for me?” + +Who could refuse a request from Batman, right? Let’s write Batman’s love letter in HTML. + +### Your first HTML file + +An HTML webpage is like other files on your computer. As a .doc file opens in MS Word, a .jpg file opens in Image Viewer, and a .html file opens in your Browser. + +So, let’s create a .html file. You can do this in Notepad, or any other basic editor, but I would recommend using VS Code instead. [Download and install VS Code here][2]. It’s free, and the only Microsoft Product I love. + +Create a directory in your system and name it “HTML Practice” (without quotes). Inside this directory, create one more directory called “Batman’s Love Letter” (without quotes). This will be our project root directory. That means that all our files related to this project will live here. + +Open VS Code and press ctrl+n to create a new file and ctrl+s to save the file. Navigate to the “Batman’s Love Letter” folder and name the file “loveletter.html” and click save. + +Now, if you open this file by double-clicking it from your file explorer, it will open in your default browser. I recommend using Firefox for web development, but Chrome is fine too. + +Let’s relate this process to something we are already familiar with. Remember the first time you got your hands on a computer? The first thing I did was open MS Paint and draw something. You draw something in Paint and save it as an image and then you can view that image in Image Viewer. Then if you want to edit that image again, you re-open it in Paint, edit it, and save it. + +Our current process is quite similar. As we use Paint to create and edit images, we use VS Code to create and edit our HTML files. And as we use Image Viewer to view the images, we use the Browser to view our HTML pages. + +### Your first Paragraph in HTML + +We have our blank HTML file, so here’s the first paragraph Batman wants to write in his love letter + +“After all the battles we fought together, after all the difficult times we saw together, and after all the good and bad moments we’ve been through, I think it’s time I let you know how I feel about you.” + +Copy the paragraph in your loveletter.html in VS Code. Enable word wrap by clicking View -> Toggle Word Wrap (alt+z). + +Save and open the file in your browser. If it’s already open, click refresh on your browser. + +Voila! That’s your first webpage! + +Our first paragraph is ready, but this is not the recommended way of writing a paragraph in HTML. We have a specific way to let the browser know that a text is a paragraph. + +If you wrap the text with `

` and `

`, then the browser will know that the text inside the `

` and `

` is a paragraph. Let’s do this: + +``` +

After all the battles we fought together, after all the difficult times we saw together, after all the good and bad moments we've been through, I think it's time I let you know how I feel about you.

+``` + +By writing the paragraph inside `

` and `

` you created an HTML element. A web page is collection of HTML elements. + +Let’s get some of the terminologies out of the way first: `

` is the opening tag, `

` is the closing tag, and “p” is the tag name. The text inside the opening and closing tag of an element is that element’s content. + +### The “style” attribute + +You will see that the text covers the entire width of the screen. + +We don’t want that. No one want’s to read such long lines. Let’s give a width of, say, 550px to our paragraph. + +We can do that by using the element’s “style” attribute. You can define an element’s style (for example, width in our case), inside its style attribute. The following line will create an empty style attribute on a “p” element: + +``` +

...

+``` + +You see that empty `""`? That’s where we will define the looks of the element. Right now we want to set the width to 550px. Let’s do that: + +``` +

+ After all the battles we fought together, after all the difficult times we saw together, after all the good and bad moments we've been through, I think it's time I let you know how I feel about you. +

+``` + +We set the “width” property to 550px separated by a colon “:” and ended by a semicolon “;”. + +Also, notice how we put the `

` and `

` in separate lines and the text content indented with one tab. Styling your code like this makes it more readable. + +### Lists in HTML + +Next, Batman wants to list some of the virtues of the person that he admires, like this: + +“ You complete my darkness with your light. I love: +- the way you see good in the worst things +- the way you handle emotionally difficult situations +- the way you look at Justice +I have learned a lot from you. You have occupied a special place in my heart over time.” + +This looks simple. + +Let’s go ahead and copy the required text below the `

:` + +``` +

+ After all the battles we faught together, after all the difficult times we saw together, after all the good and bad moments we've been through, I think it's time I let you know how I feel about you. +

+

+ You complete my darkness with your light. I love: + - the way you see good in the worse + - the way you handle emotionally difficult situations + - the way you look at Justice + I have learned a lot from you. You have occupied a special place in my heart over the time. +

+``` + +Save and refresh your browser. + + +![](https://cdn-images-1.medium.com/max/1000/1*M0Ae5ZpRTucNyucfaaz4uw.jpeg) + +Woah! What happened here, where is our list? + +If you look closely, you will observe that line breaks are not displayed. We wrote the list items in new lines in our code, but those are displayed in a single line in the browser. + +If you want to insert a line break in HTML (newline) you have to mention it using `
`. Let’s use `
` and see how it looks: + +``` +

+ After all the battles we faught together, after all the difficult times we saw together, after all the good and bad moments we've been through, I think it's time I let you know how I feel about you. +

+

+ You complete my darkness with your light. I love:
+ - the way you see good in the worse
+ - the way you handle emotionally difficult situations
+ - the way you look at Justice
+ I have learned a lot from you. You have occupied a special place in my heart over the time. +

+``` + +Save and refresh: + + +![](https://cdn-images-1.medium.com/max/1000/1*Mj4Sr_jUliidxFpEtu0pXw.jpeg) + +Okay, now it looks the way we want it to. + +Also, notice that we didn’t write a `
`. Some tags don’t need a closing tag, (and they’re called self-closing tags). + +One more thing: we didn’t use a `
` between the two paragraphs, but still the second paragraph starts from a new line. That’s because the “p” element automatically inserts a line break. + +We wrote our list using plain text, but there are two tags we can use for this same purpose: `
    ` and `
  • `. + +To get the naming out of the way: ul stands for Unordered List, and li stands for List Item. Let’s use these to display our list: + +``` +

    + After all the battles we faught together, after all the difficult times we saw together, after all the good and bad moments we've been through, I think it's time I let you know how I feel about you. +

    +``` + +``` +

    + You complete my darkness with your light. I love: +

      +
    • the way you see good in the worse
    • +
    • the way you handle emotionally difficult situations
    • +
    • the way you look at Justice
    • +
    + I have learned a lot from you. You have occupied a special place in my heart over the time. +

    +``` + +Before copying the code, notice the differences we made: + +* We removed all the `
    `, since each `
  • ` automatically displays in new line + +* We wrapped the individual list items between `
  • ` and `
  • `. + +* We wrapped the collection of all the list items between the `
      ` and `
    ` + +* We didn’t define the width of the “ul” element as we were doing with the “p” element. This is because “ul” is a child of “p” and “p” is already constrained to 550px, so “ul” won’t go beyond that. + +Let’s save the file and refresh the browser to see the results: + + +![](https://cdn-images-1.medium.com/max/1000/1*aPlMpYVZESPwgUO3Iv-qCA.jpeg) + +You will instantly notice that we get bullet points displayed before each list item. We don’t need to write that “-” before each list item now. + +On careful inspection, you will notice that the last line goes beyond 550px width. Why is that? Because a “ul” element is not allowed inside a “p” element in HTML. Let’s put the first and last lines in separate “p” elements: + +``` +

    + After all the battles we faught together, after all the difficult times we saw together, after all the good and bad moments we've been through, I think it's time I let you know how I feel about you. +

    +``` + +``` +

    + You complete my darkness with your light. I love: +

    +``` + +``` +
      +
    • the way you see good in the worse
    • +
    • the way you handle emotionally difficult situations
    • +
    • the way you look at Justice
    • +
    +``` + +``` +

    + I have learned a lot from you. You have occupied a special place in my heart over the time. +

    +``` + +Save and reload. + +Notice that this time we defined the width of the “ul” element also. That’s because we have now moved our “ul” element out of the “p” element. + +Defining the width of all the elements of our letter can become cumbersome. We have a specific element for this purpose: the “div” element. A “div” element is a generic container which is used to group content so it can be easily styled. + +Let’s wrap our entire letter with a div element and give width:550px to that div element: + +``` +
    +

    + After all the battles we faught together, after all the difficult times we saw together, after all the good and bad moments we've been through, I think it's time I let you know how I feel about you. +

    +

    + You complete my darkness with your light. I love: +

    +
      +
    • the way you see good in the worse
    • +
    • the way you handle emotionally difficult situations
    • +
    • the way you look at Justice
    • +
    +

    + I have learned a lot from you. You have occupied a special place in my heart over the time. +

    +
    +``` + +Great. Our code looks much cleaner now. + +### Headings in HTML + +Batman is quite happy looking at the results so far, and he wants a heading on the letter. He wants to make the heading: “Bat Letter”. Of course, you saw this name coming already, didn’t you? :D + +You can add heading using ht, h2, h3, h4, h5, and h6 tags, h1 is the biggest and main heading and h6 the smallest one. + + +![](https://cdn-images-1.medium.com/max/1000/1*Ud-NzfT-SrMgur1WX4LCkQ.jpeg) + +Let’s make the main heading using h1 and a subheading before second paragraph: + +``` +
    +

    Bat Letter

    +

    + After all the battles we faught together, after all the difficult times we saw together, after all the good and bad moments we've been through, I think it's time I let you know how I feel about you. +

    +``` + +``` +

    You are the light of my life

    +

    + You complete my darkness with your light. I love: +

    +
      +
    • the way you see good in the worse
    • +
    • the way you handle emotionally difficult situations
    • +
    • the way you look at Justice
    • +
    +

    + I have learned a lot from you. You have occupied a special place in my heart over the time. +

    +
    +``` + +Save, and reload. + + +![](https://cdn-images-1.medium.com/max/1000/1*rzyIl-gHug3nQChqfscU3w.jpeg) + +### Images in HTML + +Our letter is not complete yet, but before proceeding, one big thing is missing — a Bat logo. Have you ever seen anything Batman owns that doesn’t have a Bat logo? + +Nope. + +So, let’s add a Bat logo to our letter. + +Including an image in HTML is like including an image in a Word file. In MS Word you go to menu -> insert -> image -> then navigate to the location of the image -> select the image -> click on insert. + +In HTML, instead of clicking on the menu, we use `` tag to let the browser know that we need to load an image. We write the location and name of the file inside the “src” attribute. If the image is in the project root directory, we can simply write the name of the image file in the src attribute. + +Before we dive into coding this, download this Bat logo from [here][3]. You might want to crop the extra white space in the image. Copy the image in your project root directory and rename it “bat-logo.jpeg”. + +``` +
    +

    Bat Letter

    + +

    + After all the battles we faught together, after all the difficult times we saw together, after all the good and bad moments we've been through, I think it's time I let you know how I feel about you. +

    +``` + +``` +

    You are the light of my life

    +

    + You complete my darkness with your light. I love: +

    +
      +
    • the way you see good in the worse
    • +
    • the way you handle emotionally difficult situations
    • +
    • the way you look at Justice
    • +
    +

    + I have learned a lot from you. You have occupied a special place in my heart over the time. +

    +
    +``` + +We included the img tag on line 3\. This tag is also a self-closing tag, so we don’t need to write ``. In the src attribute, we give the name of the image file. This name should be exactly same as your image’s name, including the extension (.jpeg) and its case. + +Save and refresh to see the result. + + +![](https://cdn-images-1.medium.com/max/1000/1*uMNWAISOACJlzDOONcrGXw.jpeg) + +Damn! What just happened? + +When you include an image using the img tag, by default the image will be displayed in its original resolution. In our case, the image is much wider than 550px. Let’s define its width using the style attribute: + +``` +
    +

    Bat Letter

    + +

    + After all the battles we faught together, after all the difficult times we saw together, after all the good and bad moments we've been through, I think it's time I let you know how I feel about you. +

    +``` + +``` +

    You are the light of my life

    +

    + You complete my darkness with your light. I love: +

    +
      +
    • the way you see good in the worse
    • +
    • the way you handle emotionally difficult situations
    • +
    • the way you look at Justice
    • +
    +

    + I have learned a lot from you. You have occupied a special place in my heart over the time. +

    +
    +``` + +You will notice that this time we defined width with “%” instead of “px”. When we define a width in “%” it will occupy that % of the parent element’s width. So, 100% of 550px will give us 550px. + +Save and refresh to see the results. + +![](https://cdn-images-1.medium.com/max/1000/1*5c0ngx3BFVlyyP6UNtfYyg.jpeg) + +Fantastic! This brings a timid smile to Batman’s face :) + +### Bold and Italic in HTML + +Now Batman wants to confess his love in the last few paragraphs. He has this text for you to write in HTML: + +“I have a confession to make + +It feels like my chest  _does_  have a heart. You make my heart beat. Your smile brings a smile to my face, your pain brings pain to my heart. + +I don’t show my emotions, but I think this man behind the mask is falling for you.” + +While reading this you ask Batman, “Wait, who is this for?” and Batman replies: + +“It’s for Superman.” + + +![](https://cdn-images-1.medium.com/max/1000/1*UNDvfIZQJ1Q_goHc-F-IPA.jpeg) + +You: Oh! I was going to guess Wonder Woman. + +Batman: No, it’s Sups, please write “I love you Superman” at the end. + +Fine, let’s do it then: + +``` +
    +

    Bat Letter

    + +

    + After all the battles we faught together, after all the difficult times we saw together, after all the good and bad moments we've been through, I think it's time I let you know how I feel about you. +

    +``` + +``` +

    You are the light of my life

    +

    + You complete my darkness with your light. I love: +

    +
      +
    • the way you see good in the worse
    • +
    • the way you handle emotionally difficult situations
    • +
    • the way you look at Justice
    • +
    +

    + I have learned a lot from you. You have occupied a special place in my heart over the time. +

    +

    I have a confession to make

    +

    + It feels like my chest does have a heart. You make my heart beat. Your smile brings smile on my face, your pain brings pain to my heart. +

    +

    + I don't show my emotions, but I think this man behind the mask is falling for you. +

    +

    I love you Superman.

    +

    + Your not-so-secret-lover,
    + Batman +

    +
    +``` + +The letter is almost done, and Batman wants just two more changes. Batman wants the word “does” in the first sentence of the confession paragraph to be italic, and the sentence “I love you Superman” to be in bold. + +We use `` and `` to display text in italic and bold. Let’s update these changes: + +``` +
    +

    Bat Letter

    + +

    + After all the battles we faught together, after all the difficult times we saw together, after all the good and bad moments we've been through, I think it's time I let you know how I feel about you. +

    +``` + +``` +

    You are the light of my life

    +

    + You complete my darkness with your light. I love: +

    +
      +
    • the way you see good in the worse
    • +
    • the way you handle emotionally difficult situations
    • +
    • the way you look at Justice
    • +
    +

    + I have learned a lot from you. You have occupied a special place in my heart over the time. +

    +

    I have a confession to make

    +

    + It feels like my chest does have a heart. You make my heart beat. Your smile brings smile on my face, your pain brings pain to my heart. +

    +

    + I don't show my emotions, but I think this man behind the mask is falling for you. +

    +

    I love you Superman.

    +

    + Your not-so-secret-lover,
    + Batman +

    +
    +``` + + +![](https://cdn-images-1.medium.com/max/1000/1*6hZdQJglbHUcEEHzouk2eA.jpeg) + +### Styling in HTML + +There are three ways you can style or define the look of an HTML element: + +* Inline styling: We write styles using “style” attribute of the elements. This is what we have done up until now. This is not a good practice. + +* Embedded styling: We write all the styles within a “style” element wrapped by . + +* Linked stylesheet: We write styles of all the elements in a separate file with .css extension. This file is called Stylesheet. + +Let’s have a look at how we defined the inline style of the “div” until now: + +``` +
    +``` + +We can write this same style inside `` like this: + +``` +div{ + width:550px; +} +``` + +In embedded styling, the styles we write are separate from the elements. So we need a way to relate the element and its style. The first word “div” does exactly that. It lets the browser know that whatever style is inside the curly braces `{…}` belongs to the “div” element. Since this phrase determines which element to apply the style to, it’s called a selector. + +The way we write style remains same: property(width) and value(550px) separated by a colon(:) and ended by a semicolon(;). + +Let’s remove inline style from our “div” and “img” element and write it inside the ` +``` + +``` +
    +

    Bat Letter

    + +

    + After all the battles we faught together, after all the difficult times we saw together, after all the good and bad moments we've been through, I think it's time I let you know how I feel about you. +

    +``` + +``` +

    You are the light of my life

    +

    + You complete my darkness with your light. I love: +

    +
      +
    • the way you see good in the worse
    • +
    • the way you handle emotionally difficult situations
    • +
    • the way you look at Justice
    • +
    +

    + I have learned a lot from you. You have occupied a special place in my heart over the time. +

    +

    I have a confession to make

    +

    + It feels like my chest does have a heart. You make my heart beat. Your smile brings smile on my face, your pain brings pain to my heart. +

    +

    + I don't show my emotions, but I think this man behind the mask is falling for you. +

    +

    I love you Superman.

    +

    + Your not-so-secret-lover,
    + Batman +

    +
    +``` + +Save and refresh, and the result should remain the same. + +There is one big problem though — what if there is more than one “div” and “img” element in our HTML file? The styles that we defined for div and img inside the “style” element will apply to every div and img on the page. + +If you add another div in your code in the future, then that div will also become 550px wide. We don’t want that. + +We want to apply our styles to the specific div and img that we are using right now. To do this, we need to give our div and img element unique ids. Here’s how you can give an id to an element using its “id” attribute: + +``` +
    +``` + +and here’s how to use this id in our embedded style as a selector: + +``` +#letter-container{ + ... +} +``` + +Notice the “#” symbol. It indicates that it is an id, and the styles inside {…} should apply to the element with that specific id only. + +Let’s apply this to our code: + +``` + +``` + +``` +
    +

    Bat Letter

    + +

    + After all the battles we faught together, after all the difficult times we saw together, after all the good and bad moments we've been through, I think it's time I let you know how I feel about you. +

    +``` + +``` +

    You are the light of my life

    +

    + You complete my darkness with your light. I love: +

    +
      +
    • the way you see good in the worse
    • +
    • the way you handle emotionally difficult situations
    • +
    • the way you look at Justice
    • +
    +

    + I have learned a lot from you. You have occupied a special place in my heart over the time. +

    +

    I have a confession to make

    +

    + It feels like my chest does have a heart. You make my heart beat. Your smile brings smile on my face, your pain brings pain to my heart. +

    +

    + I don't show my emotions, but I think this man behind the mask is falling for you. +

    +

    I love you Superman.

    +

    + Your not-so-secret-lover,
    + Batman +

    +
    +``` + +Our HTML is ready with embedded styling. + +However, you can see that as we include more styles, the will get bigger. This can quickly clutter our main html file. So let’s go one step further and use linked styling by copying the content inside our style tag to a new file. + +Create a new file in the project root directory and save it as style.css: + +``` +#letter-container{ + width:550px; +} +#header-bat-logo{ + width:100%; +} +``` + +We don’t need to write `` in our CSS file. + +We need to link our newly created CSS file to our HTML file using the ``tag in our html file. Here’s how we can do that: + +``` + +``` + +We use the link element to include external resources inside your HTML document. It is mostly used to link Stylesheets. The three attributes that we are using are: + +* rel: Relation. What relationship the linked file has to the document. The file with the .css extension is called a stylesheet, and so we keep rel=“stylesheet”. + +* type: the Type of the linked file; it’s “text/css” for a CSS file. + +* href: Hypertext Reference. Location of the linked file. + +There is no at the end of the link element. So, is also a self-closing tag. + +``` + +``` + +If only getting a Girlfriend was so easy :D + +Nah, that’s not gonna happen, let’s move on. + +Here’s the content of our loveletter.html: + +``` + +
    +

    Bat Letter

    + +

    + After all the battles we faught together, after all the difficult times we saw together, after all the good and bad moments we've been through, I think it's time I let you know how I feel about you. +

    +

    You are the light of my life

    +

    + You complete my darkness with your light. I love: +

    +
      +
    • the way you see good in the worse
    • +
    • the way you handle emotionally difficult situations
    • +
    • the way you look at Justice
    • +
    +

    + I have learned a lot from you. You have occupied a special place in my heart over the time. +

    +

    I have a confession to make

    +

    + It feels like my chest does have a heart. You make my heart beat. Your smile brings smile on my face, your pain brings pain to my heart. +

    +

    + I don't show my emotions, but I think this man behind the mask is falling for you. +

    +

    I love you Superman.

    +

    + Your not-so-secret-lover,
    + Batman +

    +
    +``` + +and our style.css: + +``` +#letter-container{ + width:550px; +} +#header-bat-logo{ + width:100%; +} +``` + +Save both the files and refresh, and your output in the browser should remain the same. + +### A Few Formalities + +Our love letter is almost ready to deliver to Batman, but there are a few formal pieces remaining. + +Like any other programming language, HTML has also gone through many versions since its birth year(1990). The current version of HTML is HTML5. + +So, how would the browser know which version of HTML you are using to code your page? To tell the browser that you are using HTML5, you need to include `` at top of the page. For older versions of HTML, this line used to be different, but you don’t need to learn that because we don’t use them anymore. + +Also, in previous HTML versions, we used to encapsulate the entire document inside `` tag. The entire file was divided into two major sections: Head, inside ``, and Body, inside ``. This is not required in HTML5, but we still do this for compatibility reasons. Let’s update our code with ``, ``, `` and ``: + +``` + + + + + + +
    +

    Bat Letter

    + +

    + After all the battles we faught together, after all the difficult times we saw together, after all the good and bad moments we've been through, I think it's time I let you know how I feel about you. +

    +

    You are the light of my life

    +

    + You complete my darkness with your light. I love: +

    +
      +
    • the way you see good in the worse
    • +
    • the way you handle emotionally difficult situations
    • +
    • the way you look at Justice
    • +
    +

    + I have learned a lot from you. You have occupied a special place in my heart over the time. +

    +

    I have a confession to make

    +

    + It feels like my chest does have a heart. You make my heart beat. Your smile brings smile on my face, your pain brings pain to my heart. +

    +

    + I don't show my emotions, but I think this man behind the mask is falling for you. +

    +

    I love you Superman.

    +

    + Your not-so-secret-lover,
    + Batman +

    +
    + + +``` + +The main content goes inside `` and meta information goes inside ``. So we keep the div inside `` and load the stylesheets inside ``. + +Save and refresh, and your HTML page should display the same as earlier. + +### Title in HTML + +This is the last change. I promise. + +You might have noticed that the title of the tab is displaying the path of the HTML file: + + +![](https://cdn-images-1.medium.com/max/1000/1*PASKm4ji29hbcZXVSP8afg.jpeg) + +We can use `` tag to define a title for our HTML file. The title tag also, like the link tag, goes inside head. Let’s put “Bat Letter” in our title: + +``` +<!DOCTYPE html> +<html> +<head> + <title>Bat Letter + + + +
    +

    Bat Letter

    + +

    + After all the battles we faught together, after all the difficult times we saw together, after all the good and bad moments we've been through, I think it's time I let you know how I feel about you. +

    +

    You are the light of my life

    +

    + You complete my darkness with your light. I love: +

    +
      +
    • the way you see good in the worse
    • +
    • the way you handle emotionally difficult situations
    • +
    • the way you look at Justice
    • +
    +

    + I have learned a lot from you. You have occupied a special place in my heart over the time. +

    +

    I have a confession to make

    +

    + It feels like my chest does have a heart. You make my heart beat. Your smile brings smile on my face, your pain brings pain to my heart. +

    +

    + I don't show my emotions, but I think this man behind the mask is falling for you. +

    +

    I love you Superman.

    +

    + Your not-so-secret-lover,
    + Batman +

    +
    + + +``` + +Save and refresh, and you will see that instead of the file path, “Bat Letter” is now displayed on the tab. + +Batman’s Love Letter is now complete. + +Congratulations! You made Batman’s Love Letter in HTML. + + +![](https://cdn-images-1.medium.com/max/1000/1*qC8qtrYtxAB6cJfm9aVOOQ.jpeg) + +### What we learned + +We learned the following new concepts: + +* The structure of an HTML document + +* How to write elements in HTML (

    ) + +* How to write styles inside the element using the style attribute (this is called inline styling, avoid this as much as you can) + +* How to write styles of an element inside (this is called embedded styling) + +* How to write styles in a separate file and link to it in HTML using (this is called a linked stylesheet) + +* What is a tag name, attribute, opening tag, and closing tag + +* How to give an id to an element using id attribute + +* Tag selectors and id selectors in CSS + +We learned the following HTML tags: + +*

    : for paragraphs + +*
    : for line breaks + +*

      ,
    • : to display lists + +*
      : for grouping elements of our letter + +*

      ,

      : for heading and sub heading + +* : to insert an image + +* , : for bold and italic text styling + +* +``` + + +I also like the short-bindings provided by Vue, ‘:’ for binding data variables into your template and ‘@’ for binding to events. It’s a small thing, but it feels nice to type and keeps your components succinct. + +2\. Single File Components + +When most people write Vue, they do so using ‘single file components’. Essentially it is a file with the suffix .vue containing up to 3 parts (the css, html and javascript) for each component. + +This coupling of technologies feels right. It makes it easy to understand each component in a single place. It also has the nice side effect of encouraging you to keep your code short for each component. If the JavaScript, CSS and HTML for your component is taking up too many lines then it might be time to modularise further. + +When it comes to the