From 8c4cc8d44ae5ebffc1a7667fcf68e1838e739340 Mon Sep 17 00:00:00 2001 From: kokialoves <498497353@qq.com> Date: Thu, 7 Jul 2016 17:40:22 +0800 Subject: [PATCH 001/122] Create Part 12 - How to Explore Linux with Installed Help Documentations and Tools.md --- ...Installed Help Documentations and Tools.md | 178 ++++++++++++++++++ 1 file changed, 178 insertions(+) create mode 100644 translated/tech/LFCS/Part 12 - How to Explore Linux with Installed Help Documentations and Tools.md diff --git a/translated/tech/LFCS/Part 12 - How to Explore Linux with Installed Help Documentations and Tools.md b/translated/tech/LFCS/Part 12 - How to Explore Linux with Installed Help Documentations and Tools.md new file mode 100644 index 0000000000..2d0238becf --- /dev/null +++ b/translated/tech/LFCS/Part 12 - How to Explore Linux with Installed Help Documentations and Tools.md @@ -0,0 +1,178 @@ +LFCS第十二讲: 如何使用Linux的帮助文档和工具 +================================================================================== + +由于 2016 年 2 月 2 号开始启用了新的 LFCS 考试要求, 我们在[LFCS series][1]系列添加了一些必要的内容 . 为了考试的需要, 我们强烈建议你看一下[LFCE series][2] . + +![](http://www.tecmint.com/wp-content/uploads/2016/03/Explore-Linux-with-Documentation-and-Tools.png) +>LFCS: 了解Linux的帮助文档和工具 + +当你习惯了在命令行下进行工作, 你会发现Linux有许多文档需要你去使用和配置Linux系统. + +另一个你必须熟悉命令行帮助工具的理由是,在[LFCS][3] 和 [LFCE][4] 考试中, 你只能靠你自己和命令行工具,没有互联网也没有百度。 + +基于上面的理由, 在这一章里我们将给你一些建议来帮助你通过**Linux Foundation Certification** 考试. + +### Linux 帮助手册 + +man命令, 大体上来说就是一个工具手册. 它包含选项列表(和解释) , 甚至还提供一些例子. + +我们用**man command** 加工具名称来打开一个帮助手册以便获取更多内容. 例如: + +``` +# man diff +``` + +我们将打开`diff`的手册页, 这个工具将一行一行的对比文本文档 (如你想退出只需要轻轻的点一下Q键). + +下面我来比较两个文本文件 `file1` 和 `file2` . 这两个文本文件包含着相同版本Linux的安装包信息. + +输入`diff` 命令它将告诉我们 `file1` 和`file2` 有什么不同: + +``` +# diff file1 file2 +``` + +![](http://www.tecmint.com/wp-content/uploads/2016/03/Compare-Two-Text-Files-in-Linux.png) +>在Linux中比较两个文本文件 + +`<` 这个符号是说`file2`少一行. 如果是 `file1`少一行, 我们将用 `>` 符号来替代. + +接下来说, **7d6** 意思是说 文件1的**#7**行在 `file2`中被删除了 ( **24d22** 和**41d38**是同样的意思), 65,67d61告诉我们移动 **65** 到 **67** . 我们把以上步骤都做了两个文件将完全匹配. + +你还可以通过 `-y` 选项来对比两个文件: + +``` +# diff -y file1 file2 +``` + +![](http://www.tecmint.com/wp-content/uploads/2016/03/Compare-and-List-Difference-of-Two-Files.png) +>通过列表来列出两个文件的不同 + + 当然你也可以用`diff`来比较两个二进制文件 . 如果它们完全一样, `diff` 将什么也不会输出. 否则, 他将会返回如下信息: “**Binary files X and Y differ**”. + +### –help 选项 + +`--help`选项 , 大多数命令都可以用它(并不是所有) , 他可以理解为一个命令的简单介绍. 尽管它不提供工具的详细介绍, 但是确实是一个能够快速列出程序使用信息的不错的方法. + +例如, + +``` +# sed --help +``` + +显示 sed 的每个选项的用法(sed文本流编辑器). + +一个经典的`sed`例子,替换文件字符. 用 `-i` 选项 (描述为 “**编辑文件在指定位置**”), 你可以编辑一个文件而且并不需要打开他. 如果你想要备份一个原始文件, 用 `-i` 选项 加后缀来创建一个原始文件的副本. + +例如, 替换 `lorem.txt`中的`Lorem` 为 `Tecmint` (忽略大小写) 并且创建一个新的原始文件副本, 命令如下: + +``` +# less lorem.txt | grep -i lorem +# sed -i.orig 's/Lorem/Tecmint/gI' lorem.txt +# less lorem.txt | grep -i lorem +# less lorem.txt.orig | grep -i lorem +``` + + 请注意`lorem.txt`文件中`Lorem` 都已经替换为 `Tecmint` , 并且原始的 `lorem.txt` 保存为`lorem.txt.orig`. + +![](http://www.tecmint.com/wp-content/uploads/2016/03/Replace-A-String-in-File.png) +>替换文件文本 + +### /usr/share/doc内的文档 +这可能是我最喜欢的方法. 如果你进入 `/usr/share/doc` 目录, 你可以看到好多Linux已经安装的工具的名称的文件夹. + +根据[Filesystem Hierarchy Standard][5](文件目录标准),这些文件夹包含了许多帮助手册没有的信息, 还有一些模板和配置文件. + +例如, 让我们来看一下 `squid-3.3.8` (版本可能会不同) 一个非常受欢迎的HTTP代理[squid cache server][6]. + +让我们用`cd`命令进入目录 : + +``` +# cd /usr/share/doc/squid-3.3.8 +``` + +列出当前文件夹列表: + +``` +# ls +``` + +![](http://www.tecmint.com/wp-content/uploads/2016/03/List-Files-in-Linux.png) +>ls linux列表命令 + +你应该特别注意 `QUICKSTART` 和 `squid.conf.documented`. 这两个文件包含了Squid许多信息, . 对于别的安装包来说, 他们的名字可能不同 (有可能是 **QuickRef** 或者**00QUICKSTART**), 但原理是一样的. + +对于另外一些安装包, 比如 the Apache web server, 在`/usr/share/doc`目录提供了配置模板, 当你配置独立服务器或者虚拟主机的时候会非常有用. + +### GNU 信息文档 + +你可以把它想象为帮助手册的超级链接形式. 正如上面说的, 他不仅仅提供工具的帮助信息, 而且还是超级链接的形式(是的!在命令行中的超级链接) 你可以通过箭头按钮和回车按钮来浏览你需要的内容. + +一个典型的例子是: + +``` +# info coreutils +``` + +通过coreutils 列出当前系统的 基本文件,shell脚本和文本处理工具[basic file, shell and text manipulation utilities][7] , 你可以得到他们的详细介绍. + +![](http://www.tecmint.com/wp-content/uploads/2016/03/Info-Coreutils.png) +>Info Coreutils + +和帮助手册一样你可以按Q键退出. + +此外, GNU info 还可以像帮助手册一样使用. 例如: + +``` +# info tune2fs +``` + +它将显示 **tune2fs**的帮助手册, ext2/3/4 文件系统管理工具. + +让我们来看看怎么用**tune2fs**: + +显示 **/dev/mapper/vg00-vol_backups**文件系统信息: + +``` +# tune2fs -l /dev/mapper/vg00-vol_backups +``` + +修改文件系统标签 (修改为Backups): + +``` +# tune2fs -L Backups /dev/mapper/vg00-vol_backups +``` + +设置 `/` 自检的挂载次数 (用`-c` 选项设置 `/`的自检的挂载次数 或者用 `-i` 选项设置 自检时间 **d=days, w=weeks, and m=months**). + +``` +# tune2fs -c 150 /dev/mapper/vg00-vol_backups # Check every 150 mounts +# tune2fs -i 6w /dev/mapper/vg00-vol_backups # Check every 6 weeks +``` + +以上这些内容也可以通过 `--help` 选项找到, 或者查看帮助手册. + +### 摘要 + +不管你选择哪种方法,知道并且会使用它们在考试中对你是非常有用的. 你知道其它的一些方法吗? 欢迎给我们留言. + + +-------------------------------------------------------------------------------- + +via: http://www.tecmint.com/linux-basic-shell-scripting-and-linux-filesystem-troubleshooting/ + +作者:[Gabriel Cánepa][a] +译者:[kokialoves](https://github.com/kokialoves) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创翻译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:http://www.tecmint.com/author/gacanepa/ +[1]: http://www.tecmint.com/sed-command-to-create-edit-and-manipulate-files-in-linux/ +[2]: http://www.tecmint.com/installing-network-services-and-configuring-services-at-system-boot/ +[3]: http://www.tecmint.com/sed-command-to-create-edit-and-manipulate-files-in-linux/ +[4]: http://www.tecmint.com/installing-network-services-and-configuring-services-at-system-boot/ +[5]: http://www.tecmint.com/linux-directory-structure-and-important-files-paths-explained/ +[6]: http://www.tecmint.com/configure-squid-server-in-linux/ +[7]: http://www.tecmint.com/sed-command-to-create-edit-and-manipulate-files-in-linux/ +[8]: From 9a0e5ef1a90ee5fe91778e0718585d2fbfb8f5a0 Mon Sep 17 00:00:00 2001 From: kokialoves <498497353@qq.com> Date: Thu, 7 Jul 2016 17:45:41 +0800 Subject: [PATCH 002/122] Delete Part 12 - How to Explore Linux with Installed Help Documentations and Tools.md --- ...Installed Help Documentations and Tools.md | 181 ------------------ 1 file changed, 181 deletions(-) delete mode 100644 sources/tech/LFCS/Part 12 - How to Explore Linux with Installed Help Documentations and Tools.md diff --git a/sources/tech/LFCS/Part 12 - How to Explore Linux with Installed Help Documentations and Tools.md b/sources/tech/LFCS/Part 12 - How to Explore Linux with Installed Help Documentations and Tools.md deleted file mode 100644 index e4cf8cb12d..0000000000 --- a/sources/tech/LFCS/Part 12 - How to Explore Linux with Installed Help Documentations and Tools.md +++ /dev/null @@ -1,181 +0,0 @@ -[translating by kokialoves] -Part 12 - LFCS: How to Explore Linux with Installed Help Documentations and Tools -================================================================================== - -Because of the changes in the LFCS exam requirements effective Feb. 2, 2016, we are adding the necessary topics to the [LFCS series][1] published here. To prepare for this exam, your are highly encouraged to use the [LFCE series][2] as well. - -![](http://www.tecmint.com/wp-content/uploads/2016/03/Explore-Linux-with-Documentation-and-Tools.png) ->LFCS: Explore Linux with Installed Documentations and Tools – Part 12 - -Once you get used to working with the command line and feel comfortable doing so, you realize that a regular Linux installation includes all the documentation you need to use and configure the system. - -Another good reason to become familiar with command line help tools is that in the [LFCS][3] and [LFCE][4] exams, those are the only sources of information you can use – no internet browsing and no googling. It’s just you and the command line. - -For that reason, in this article we will give you some tips to effectively use the installed docs and tools in order to prepare to pass the **Linux Foundation Certification** exams. - -### Linux Man Pages - -A man page, short for manual page, is nothing less and nothing more than what the word suggests: a manual for a given tool. It contains the list of options (with explanation) that the command supports, and some man pages even include usage examples as well. - -To open a man page, use the **man command** followed by the name of the tool you want to learn more about. For example: - -``` -# man diff -``` - -will open the manual page for `diff`, a tool used to compare text files line by line (to exit, simply hit the q key.). - -Let’s say we want to compare two text files named `file1` and `file2` in Linux. These files contain the list of packages that are installed in two Linux boxes with the same distribution and version. - -Doing a `diff` between `file1` and `file2` will tell us if there is a difference between those lists: - -``` -# diff file1 file2 -``` - -![](http://www.tecmint.com/wp-content/uploads/2016/03/Compare-Two-Text-Files-in-Linux.png) ->Compare Two Text Files in Linux - -where the `<` sign indicates lines missing in `file2`. If there were lines missing in `file1`, they would be indicated by the `>` sign instead. - -On the other hand, **7d6** means line **#7** in file should be deleted in order to match `file2` (same with **24d22** and **41d38**), and 65,67d61 tells us we need to remove lines **65** through **67** in file one. If we make these corrections, both files will then be identical. - -Alternatively, you can display both files side by side using the `-y` option, according to the man page. You may find this helpful to more easily identify missing lines in files: - -``` -# diff -y file1 file2 -``` - -![](http://www.tecmint.com/wp-content/uploads/2016/03/Compare-and-List-Difference-of-Two-Files.png) ->Compare and List Difference of Two Files - -Also, you can use `diff` to compare two binary files. If they are identical, `diff` will exit silently without output. Otherwise, it will return the following message: “**Binary files X and Y differ**”. - -### The –help Option - -The `--help` option, available in many (if not all) commands, can be considered a short manual page for that specific command. Although it does not provide a comprehensive description of the tool, it is an easy way to obtain information on the usage of a program and a list of its available options at a quick glance. - -For example, - -``` -# sed --help -``` - -shows the usage of each option available in sed (the stream editor). - -One of the classic examples of using `sed` consists of replacing characters in files. Using the `-i` option (described as “**edit files in place**”), you can edit a file without opening it. If you want to make a backup of the original contents as well, use the `-i` option followed by a SUFFIX to create a separate file with the original contents. - -For example, to replace each occurrence of the word `Lorem` with `Tecmint` (case insensitive) in `lorem.txt` and create a new file with the original contents of the file, do: - -``` -# less lorem.txt | grep -i lorem -# sed -i.orig 's/Lorem/Tecmint/gI' lorem.txt -# less lorem.txt | grep -i lorem -# less lorem.txt.orig | grep -i lorem -``` - -Please note that every occurrence of `Lorem` has been replaced with `Tecmint` in `lorem.txt`, and the original contents of `lorem.txt` has been saved to `lorem.txt.orig`. - -![](http://www.tecmint.com/wp-content/uploads/2016/03/Replace-A-String-in-File.png) ->Replace A String in Files - -### Installed Documentation in /usr/share/doc - -This is probably my favorite pick. If you go to `/usr/share/doc` and do a directory listing, you will see lots of directories with the names of the installed tools in your Linux system. - -According to the [Filesystem Hierarchy Standard][5], these directories contain useful information that might not be in the man pages, along with templates and configuration files to make configuration easier. - -For example, let’s consider `squid-3.3.8` (version may vary from distribution to distribution) for the popular HTTP proxy and [squid cache server][6]. - -Let’s `cd` into that directory: - -``` -# cd /usr/share/doc/squid-3.3.8 -``` - -and do a directory listing: - -``` -# ls -``` - -![](http://www.tecmint.com/wp-content/uploads/2016/03/List-Files-in-Linux.png) ->Linux Directory Listing with ls Command - -You may want to pay special attention to `QUICKSTART` and `squid.conf.documented`. These files contain an extensive documentation about Squid and a heavily commented configuration file, respectively. For other packages, the exact names may differ (as **QuickRef** or **00QUICKSTART**, for example), but the principle is the same. - -Other packages, such as the Apache web server, provide configuration file templates inside `/usr/share/doc`, that will be helpful when you have to configure a standalone server or a virtual host, to name a few cases. - -### GNU info Documentation - -You can think of info documents as man pages on steroids. As such, they not only provide help for a specific tool, but also they do so with hyperlinks (yes, hyperlinks in the command line!) that allow you to navigate from a section to another using the arrow keys and Enter to confirm. - -Perhaps the most illustrative example is: - -``` -# info coreutils -``` - -Since coreutils contains the [basic file, shell and text manipulation utilities][7] which are expected to exist on every operating system, you can reasonably expect a detailed description for each one of those categories in info **coreutils**. - -![](http://www.tecmint.com/wp-content/uploads/2016/03/Info-Coreutils.png) ->Info Coreutils - -As it is the case with man pages, you can exit an info document by pressing the `q` key. - -Additionally, GNU info can be used to display regular man pages as well when followed by the tool name. For example: - -``` -# info tune2fs -``` - -will return the man page of **tune2fs**, the ext2/3/4 filesystems management tool. - -And now that we’re at it, let’s review some of the uses of **tune2fs**: - -Display information about the filesystem on top of **/dev/mapper/vg00-vol_backups**: - -``` -# tune2fs -l /dev/mapper/vg00-vol_backups -``` - -Set a filesystem volume name (Backups in this case): - -``` -# tune2fs -L Backups /dev/mapper/vg00-vol_backups -``` - -Change the check intervals and `/` or mount counts (use the `-c` option to set a number of mount counts and `/` or the `-i` option to set a check interval, where **d=days, w=weeks, and m=months**). - -``` -# tune2fs -c 150 /dev/mapper/vg00-vol_backups # Check every 150 mounts -# tune2fs -i 6w /dev/mapper/vg00-vol_backups # Check every 6 weeks -``` - -All of the above options can be listed with the `--help` option, or viewed in the man page. - -### Summary - -Regardless of the method that you choose to invoke help for a given tool, knowing that they exist and how to use them will certainly come in handy in the exam. Do you know of any other tools that can be used to look up documentation? Feel free to share with the Tecmint community using the form below. - -Questions and other comments are more than welcome as well. - --------------------------------------------------------------------------------- - -via: http://www.tecmint.com/linux-basic-shell-scripting-and-linux-filesystem-troubleshooting/ - -作者:[Gabriel Cánepa][a] -译者:[译者ID](https://github.com/译者ID) -校对:[校对者ID](https://github.com/校对者ID) - -本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创翻译,[Linux中国](https://linux.cn/) 荣誉推出 - -[a]:http://www.tecmint.com/author/gacanepa/ -[1]: http://www.tecmint.com/sed-command-to-create-edit-and-manipulate-files-in-linux/ -[2]: http://www.tecmint.com/installing-network-services-and-configuring-services-at-system-boot/ -[3]: http://www.tecmint.com/sed-command-to-create-edit-and-manipulate-files-in-linux/ -[4]: http://www.tecmint.com/installing-network-services-and-configuring-services-at-system-boot/ -[5]: http://www.tecmint.com/linux-directory-structure-and-important-files-paths-explained/ -[6]: http://www.tecmint.com/configure-squid-server-in-linux/ -[7]: http://www.tecmint.com/sed-command-to-create-edit-and-manipulate-files-in-linux/ -[8]: From 781d751e3718a4ffa4a1d3c341f8b520021959df Mon Sep 17 00:00:00 2001 From: cposture Date: Sat, 9 Jul 2016 21:15:36 +0800 Subject: [PATCH 003/122] Translated by cposture --- .../tech/20160512 Bitmap in Linux Kernel.md | 398 ----------------- .../tech/20160512 Bitmap in Linux Kernel.md | 405 ++++++++++++++++++ 2 files changed, 405 insertions(+), 398 deletions(-) delete mode 100644 sources/tech/20160512 Bitmap in Linux Kernel.md create mode 100644 translated/tech/20160512 Bitmap in Linux Kernel.md diff --git a/sources/tech/20160512 Bitmap in Linux Kernel.md b/sources/tech/20160512 Bitmap in Linux Kernel.md deleted file mode 100644 index adffc9d049..0000000000 --- a/sources/tech/20160512 Bitmap in Linux Kernel.md +++ /dev/null @@ -1,398 +0,0 @@ -[Translating by cposture 2016.06.29] -Data Structures in the Linux Kernel -================================================================================ - -Bit arrays and bit operations in the Linux kernel --------------------------------------------------------------------------------- - -Besides different [linked](https://en.wikipedia.org/wiki/Linked_data_structure) and [tree](https://en.wikipedia.org/wiki/Tree_%28data_structure%29) based data structures, the Linux kernel provides [API](https://en.wikipedia.org/wiki/Application_programming_interface) for [bit arrays](https://en.wikipedia.org/wiki/Bit_array) or `bitmap`. Bit arrays are heavily used in the Linux kernel and following source code files contain common `API` for work with such structures: - -* [lib/bitmap.c](https://github.com/torvalds/linux/blob/master/lib/bitmap.c) -* [include/linux/bitmap.h](https://github.com/torvalds/linux/blob/master/include/linux/bitmap.h) - -Besides these two files, there is also architecture-specific header file which provides optimized bit operations for certain architecture. We consider [x86_64](https://en.wikipedia.org/wiki/X86-64) architecture, so in our case it will be: - -* [arch/x86/include/asm/bitops.h](https://github.com/torvalds/linux/blob/master/arch/x86/include/asm/bitops.h) - -header file. As I just wrote above, the `bitmap` is heavily used in the Linux kernel. For example a `bit array` is used to store set of online/offline processors for systems which support [hot-plug](https://www.kernel.org/doc/Documentation/cpu-hotplug.txt) cpu (more about this you can read in the [cpumasks](https://0xax.gitbooks.io/linux-insides/content/Concepts/cpumask.html) part), a `bit array` stores set of allocated [irqs](https://en.wikipedia.org/wiki/Interrupt_request_%28PC_architecture%29) during initialization of the Linux kernel and etc. - -So, the main goal of this part is to see how `bit arrays` are implemented in the Linux kernel. Let's start. - -Declaration of bit array -================================================================================ - -Before we will look on `API` for bitmaps manipulation, we must know how to declare it in the Linux kernel. There are two common method to declare own bit array. The first simple way to declare a bit array is to array of `unsigned long`. For example: - -```C -unsigned long my_bitmap[8] -``` - -The second way is to use the `DECLARE_BITMAP` macro which is defined in the [include/linux/types.h](https://github.com/torvalds/linux/blob/master/include/linux/types.h) header file: - -```C -#define DECLARE_BITMAP(name,bits) \ - unsigned long name[BITS_TO_LONGS(bits)] -``` - -We can see that `DECLARE_BITMAP` macro takes two parameters: - -* `name` - name of bitmap; -* `bits` - amount of bits in bitmap; - -and just expands to the definition of `unsigned long` array with `BITS_TO_LONGS(bits)` elements, where the `BITS_TO_LONGS` macro converts a given number of bits to number of `longs` or in other words it calculates how many `8` byte elements in `bits`: - -```C -#define BITS_PER_BYTE 8 -#define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d)) -#define BITS_TO_LONGS(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(long)) -``` - -So, for example `DECLARE_BITMAP(my_bitmap, 64)` will produce: - -```python ->>> (((64) + (64) - 1) / (64)) -1 -``` - -and: - -```C -unsigned long my_bitmap[1]; -``` - -After we are able to declare a bit array, we can start to use it. - -Architecture-specific bit operations -================================================================================ - -We already saw above a couple of source code and header files which provide [API](https://en.wikipedia.org/wiki/Application_programming_interface) for manipulation of bit arrays. The most important and widely used API of bit arrays is architecture-specific and located as we already know in the [arch/x86/include/asm/bitops.h](https://github.com/torvalds/linux/blob/master/arch/x86/include/asm/bitops.h) header file. - -First of all let's look at the two most important functions: - -* `set_bit`; -* `clear_bit`. - -I think that there is no need to explain what these function do. This is already must be clear from their name. Let's look on their implementation. If you will look into the [arch/x86/include/asm/bitops.h](https://github.com/torvalds/linux/blob/master/arch/x86/include/asm/bitops.h) header file, you will note that each of these functions represented by two variants: [atomic](https://en.wikipedia.org/wiki/Linearizability) and not. Before we will start to dive into implementations of these functions, first of all we must to know a little about `atomic` operations. - -In simple words atomic operations guarantees that two or more operations will not be performed on the same data concurrently. The `x86` architecture provides a set of atomic instructions, for example [xchg](http://x86.renejeschke.de/html/file_module_x86_id_328.html) instruction, [cmpxchg](http://x86.renejeschke.de/html/file_module_x86_id_41.html) instruction and etc. Besides atomic instructions, some of non-atomic instructions can be made atomic with the help of the [lock](http://x86.renejeschke.de/html/file_module_x86_id_159.html) instruction. It is enough to know about atomic operations for now, so we can begin to consider implementation of `set_bit` and `clear_bit` functions. - -First of all, let's start to consider `non-atomic` variants of this function. Names of non-atomic `set_bit` and `clear_bit` starts from double underscore. As we already know, all of these functions are defined in the [arch/x86/include/asm/bitops.h](https://github.com/torvalds/linux/blob/master/arch/x86/include/asm/bitops.h) header file and the first function is `__set_bit`: - -```C -static inline void __set_bit(long nr, volatile unsigned long *addr) -{ - asm volatile("bts %1,%0" : ADDR : "Ir" (nr) : "memory"); -} -``` - -As we can see it takes two arguments: - -* `nr` - number of bit in a bit array. -* `addr` - address of a bit array where we need to set bit. - -Note that the `addr` parameter is defined with `volatile` keyword which tells to compiler that value maybe changed by the given address. The implementation of the `__set_bit` is pretty easy. As we can see, it just contains one line of [inline assembler](https://en.wikipedia.org/wiki/Inline_assembler) code. In our case we are using the [bts](http://x86.renejeschke.de/html/file_module_x86_id_25.html) instruction which selects a bit which is specified with the first operand (`nr` in our case) from the bit array, stores the value of the selected bit in the [CF](https://en.wikipedia.org/wiki/FLAGS_register) flags register and set this bit. - -Note that we can see usage of the `nr`, but there is `addr` here. You already might guess that the secret is in `ADDR`. The `ADDR` is the macro which is defined in the same header code file and expands to the string which contains value of the given address and `+m` constraint: - -```C -#define ADDR BITOP_ADDR(addr) -#define BITOP_ADDR(x) "+m" (*(volatile long *) (x)) -``` - -Besides the `+m`, we can see other constraints in the `__set_bit` function. Let's look on they and try to understand what do they mean: - -* `+m` - represents memory operand where `+` tells that the given operand will be input and output operand; -* `I` - represents integer constant; -* `r` - represents register operand - -Besides these constraint, we also can see - the `memory` keyword which tells compiler that this code will change value in memory. That's all. Now let's look at the same function but at `atomic` variant. It looks more complex that its `non-atomic` variant: - -```C -static __always_inline void -set_bit(long nr, volatile unsigned long *addr) -{ - if (IS_IMMEDIATE(nr)) { - asm volatile(LOCK_PREFIX "orb %1,%0" - : CONST_MASK_ADDR(nr, addr) - : "iq" ((u8)CONST_MASK(nr)) - : "memory"); - } else { - asm volatile(LOCK_PREFIX "bts %1,%0" - : BITOP_ADDR(addr) : "Ir" (nr) : "memory"); - } -} -``` - -First of all note that this function takes the same set of parameters that `__set_bit`, but additionally marked with the `__always_inline` attribute. The `__always_inline` is macro which defined in the [include/linux/compiler-gcc.h](https://github.com/torvalds/linux/blob/master/include/linux/compiler-gcc.h) and just expands to the `always_inline` attribute: - -```C -#define __always_inline inline __attribute__((always_inline)) -``` - -which means that this function will be always inlined to reduce size of the Linux kernel image. Now let's try to understand implementation of the `set_bit` function. First of all we check a given number of bit at the beginning of the `set_bit` function. The `IS_IMMEDIATE` macro defined in the same [header](https://github.com/torvalds/linux/blob/master/arch/x86/include/asm/bitops.h) file and expands to the call of the builtin [gcc](https://en.wikipedia.org/wiki/GNU_Compiler_Collection) function: - -```C -#define IS_IMMEDIATE(nr) (__builtin_constant_p(nr)) -``` - -The `__builtin_constant_p` builtin function returns `1` if the given parameter is known to be constant at compile-time and returns `0` in other case. We no need to use slow `bts` instruction to set bit if the given number of bit is known in compile time constant. We can just apply [bitwise or](https://en.wikipedia.org/wiki/Bitwise_operation#OR) for byte from the give address which contains given bit and masked number of bits where high bit is `1` and other is zero. In other case if the given number of bit is not known constant at compile-time, we do the same as we did in the `__set_bit` function. The `CONST_MASK_ADDR` macro: - -```C -#define CONST_MASK_ADDR(nr, addr) BITOP_ADDR((void *)(addr) + ((nr)>>3)) -``` - -expands to the give address with offset to the byte which contains a given bit. For example we have address `0x1000` and the number of bit is `0x9`. So, as `0x9` is `one byte + one bit` our address with be `addr + 1`: - -```python ->>> hex(0x1000 + (0x9 >> 3)) -'0x1001' -``` - -The `CONST_MASK` macro represents our given number of bit as byte where high bit is `1` and other bits are `0`: - -```C -#define CONST_MASK(nr) (1 << ((nr) & 7)) -``` - -```python ->>> bin(1 << (0x9 & 7)) -'0b10' -``` - -In the end we just apply bitwise `or` for these values. So, for example if our address will be `0x4097` and we need to set `0x9` bit: - -```python ->>> bin(0x4097) -'0b100000010010111' ->>> bin((0x4097 >> 0x9) | (1 << (0x9 & 7))) -'0b100010' -``` - -the `ninth` bit will be set. - -Note that all of these operations are marked with `LOCK_PREFIX` which is expands to the [lock](http://x86.renejeschke.de/html/file_module_x86_id_159.html) instruction which guarantees atomicity of this operation. - -As we already know, besides the `set_bit` and `__set_bit` operations, the Linux kernel provides two inverse functions to clear bit in atomic and non-atomic context. They are `clear_bit` and `__clear_bit`. Both of these functions are defined in the same [header file](https://github.com/torvalds/linux/blob/master/arch/x86/include/asm/bitops.h) and takes the same set of arguments. But not only arguments are similar. Generally these functions are very similar on the `set_bit` and `__set_bit`. Let's look on the implementation of the non-atomic `__clear_bit` function: - -```C -static inline void __clear_bit(long nr, volatile unsigned long *addr) -{ - asm volatile("btr %1,%0" : ADDR : "Ir" (nr)); -} -``` - -Yes. As we see, it takes the same set of arguments and contains very similar block of inline assembler. It just uses the [btr](http://x86.renejeschke.de/html/file_module_x86_id_24.html) instruction instead of `bts`. As we can understand form the function's name, it clears a given bit by the given address. The `btr` instruction acts like `btr`. This instruction also selects a given bit which is specified in the first operand, stores its value in the `CF` flag register and clears this bit in the given bit array which is specifed with second operand. - -The atomic variant of the `__clear_bit` is `clear_bit`: - -```C -static __always_inline void -clear_bit(long nr, volatile unsigned long *addr) -{ - if (IS_IMMEDIATE(nr)) { - asm volatile(LOCK_PREFIX "andb %1,%0" - : CONST_MASK_ADDR(nr, addr) - : "iq" ((u8)~CONST_MASK(nr))); - } else { - asm volatile(LOCK_PREFIX "btr %1,%0" - : BITOP_ADDR(addr) - : "Ir" (nr)); - } -} -``` - -and as we can see it is very similar on `set_bit` and just contains two differences. The first difference it uses `btr` instruction to clear bit when the `set_bit` uses `bts` instruction to set bit. The second difference it uses negated mask and `and` instruction to clear bit in the given byte when the `set_bit` uses `or` instruction. - -That's all. Now we can set and clear bit in any bit array and and we can go to other operations on bitmasks. - -Most widely used operations on a bit arrays are set and clear bit in a bit array in the Linux kernel. But besides this operations it is useful to do additional operations on a bit array. Yet another widely used operation in the Linux kernel - is to know is a given bit set or not in a bit array. We can achieve this with the help of the `test_bit` macro. This macro is defined in the [arch/x86/include/asm/bitops.h](https://github.com/torvalds/linux/blob/master/arch/x86/include/asm/bitops.h) header file and expands to the call of the `constant_test_bit` or `variable_test_bit` depends on bit number: - -```C -#define test_bit(nr, addr) \ - (__builtin_constant_p((nr)) \ - ? constant_test_bit((nr), (addr)) \ - : variable_test_bit((nr), (addr))) -``` - -So, if the `nr` is known in compile time constant, the `test_bit` will be expanded to the call of the `constant_test_bit` function or `variable_test_bit` in other case. Now let's look at implementations of these functions. Let's start from the `variable_test_bit`: - -```C -static inline int variable_test_bit(long nr, volatile const unsigned long *addr) -{ - int oldbit; - - asm volatile("bt %2,%1\n\t" - "sbb %0,%0" - : "=r" (oldbit) - : "m" (*(unsigned long *)addr), "Ir" (nr)); - - return oldbit; -} -``` - -The `variable_test_bit` function takes similar set of arguments as `set_bit` and other function take. We also may see inline assembly code here which executes [bt](http://x86.renejeschke.de/html/file_module_x86_id_22.html) and [sbb](http://x86.renejeschke.de/html/file_module_x86_id_286.html) instruction. The `bt` or `bit test` instruction selects a given bit which is specified with first operand from the bit array which is specified with the second operand and stores its value in the [CF](https://en.wikipedia.org/wiki/FLAGS_register) bit of flags register. The second `sbb` instruction substracts first operand from second and subscrtact value of the `CF`. So, here write a value of a given bit number from a given bit array to the `CF` bit of flags register and execute `sbb` instruction which calculates: `00000000 - CF` and writes the result to the `oldbit`. - -The `constant_test_bit` function does the same as we saw in the `set_bit`: - -```C -static __always_inline int constant_test_bit(long nr, const volatile unsigned long *addr) -{ - return ((1UL << (nr & (BITS_PER_LONG-1))) & - (addr[nr >> _BITOPS_LONG_SHIFT])) != 0; -} -``` - -It generates a byte where high bit is `1` and other bits are `0` (as we saw in `CONST_MASK`) and applies bitwise [and](https://en.wikipedia.org/wiki/Bitwise_operation#AND) to the byte which contains a given bit number. - -The next widely used bit array related operation is to change bit in a bit array. The Linux kernel provides two helper for this: - -* `__change_bit`; -* `change_bit`. - -As you already can guess, these two variants are atomic and non-atomic as for example `set_bit` and `__set_bit`. For the start, let's look at the implementation of the `__change_bit` function: - -```C -static inline void __change_bit(long nr, volatile unsigned long *addr) -{ - asm volatile("btc %1,%0" : ADDR : "Ir" (nr)); -} -``` - -Pretty easy, is not it? The implementation of the `__change_bit` is the same as `__set_bit`, but instead of `bts` instruction, we are using [btc](http://x86.renejeschke.de/html/file_module_x86_id_23.html). This instruction selects a given bit from a given bit array, stores its value in the `CF` and changes its value by the applying of complement operation. So, a bit with value `1` will be `0` and vice versa: - -```python ->>> int(not 1) -0 ->>> int(not 0) -1 -``` - -The atomic version of the `__change_bit` is the `change_bit` function: - -```C -static inline void change_bit(long nr, volatile unsigned long *addr) -{ - if (IS_IMMEDIATE(nr)) { - asm volatile(LOCK_PREFIX "xorb %1,%0" - : CONST_MASK_ADDR(nr, addr) - : "iq" ((u8)CONST_MASK(nr))); - } else { - asm volatile(LOCK_PREFIX "btc %1,%0" - : BITOP_ADDR(addr) - : "Ir" (nr)); - } -} -``` - -It is similar on `set_bit` function, but also has two differences. The first difference is `xor` operation instead of `or` and the second is `bts` instead of `bts`. - -For this moment we know the most important architecture-specific operations with bit arrays. Time to look at generic bitmap API. - -Common bit operations -================================================================================ - -Besides the architecture-specific API from the [arch/x86/include/asm/bitops.h](https://github.com/torvalds/linux/blob/master/arch/x86/include/asm/bitops.h) header file, the Linux kernel provides common API for manipulation of bit arrays. As we know from the beginning of this part, we can find it in the [include/linux/bitmap.h](https://github.com/torvalds/linux/blob/master/include/linux/bitmap.h) header file and additionally in the * [lib/bitmap.c](https://github.com/torvalds/linux/blob/master/lib/bitmap.c) source code file. But before these source code files let's look into the [include/linux/bitops.h](https://github.com/torvalds/linux/blob/master/include/linux/bitops.h) header file which provides a set of useful macro. Let's look on some of they. - -First of all let's look at following four macros: - -* `for_each_set_bit` -* `for_each_set_bit_from` -* `for_each_clear_bit` -* `for_each_clear_bit_from` - -All of these macros provide iterator over certain set of bits in a bit array. The first macro iterates over bits which are set, the second does the same, but starts from a certain bits. The last two macros do the same, but iterates over clear bits. Let's look on implementation of the `for_each_set_bit` macro: - -```C -#define for_each_set_bit(bit, addr, size) \ - for ((bit) = find_first_bit((addr), (size)); \ - (bit) < (size); \ - (bit) = find_next_bit((addr), (size), (bit) + 1)) -``` - -As we may see it takes three arguments and expands to the loop from first set bit which is returned as result of the `find_first_bit` function and to the last bit number while it is less than given size. - -Besides these four macros, the [arch/x86/include/asm/bitops.h](https://github.com/torvalds/linux/blob/master/arch/x86/include/asm/bitops.h) provides API for rotation of `64-bit` or `32-bit` values and etc. - -The next [header](https://github.com/torvalds/linux/blob/master/include/linux/bitmap.h) file which provides API for manipulation with a bit arrays. For example it provdes two functions: - -* `bitmap_zero`; -* `bitmap_fill`. - -To clear a bit array and fill it with `1`. Let's look on the implementation of the `bitmap_zero` function: - -```C -static inline void bitmap_zero(unsigned long *dst, unsigned int nbits) -{ - if (small_const_nbits(nbits)) - *dst = 0UL; - else { - unsigned int len = BITS_TO_LONGS(nbits) * sizeof(unsigned long); - memset(dst, 0, len); - } -} -``` - -First of all we can see the check for `nbits`. The `small_const_nbits` is macro which defined in the same header [file](https://github.com/torvalds/linux/blob/master/include/linux/bitmap.h) and looks: - -```C -#define small_const_nbits(nbits) \ - (__builtin_constant_p(nbits) && (nbits) <= BITS_PER_LONG) -``` - -As we may see it checks that `nbits` is known constant in compile time and `nbits` value does not overflow `BITS_PER_LONG` or `64`. If bits number does not overflow amount of bits in a `long` value we can just set to zero. In other case we need to calculate how many `long` values do we need to fill our bit array and fill it with [memset](http://man7.org/linux/man-pages/man3/memset.3.html). - -The implementation of the `bitmap_fill` function is similar on implementation of the `biramp_zero` function, except we fill a given bit array with `0xff` values or `0b11111111`: - -```C -static inline void bitmap_fill(unsigned long *dst, unsigned int nbits) -{ - unsigned int nlongs = BITS_TO_LONGS(nbits); - if (!small_const_nbits(nbits)) { - unsigned int len = (nlongs - 1) * sizeof(unsigned long); - memset(dst, 0xff, len); - } - dst[nlongs - 1] = BITMAP_LAST_WORD_MASK(nbits); -} -``` - -Besides the `bitmap_fill` and `bitmap_zero` functions, the [include/linux/bitmap.h](https://github.com/torvalds/linux/blob/master/include/linux/bitmap.h) header file provides `bitmap_copy` which is similar on the `bitmap_zero`, but just uses [memcpy](http://man7.org/linux/man-pages/man3/memcpy.3.html) instead of [memset](http://man7.org/linux/man-pages/man3/memset.3.html). Also it provides bitwise operations for bit array like `bitmap_and`, `bitmap_or`, `bitamp_xor` and etc. We will not consider implementation of these functions because it is easy to understand implementations of these functions if you understood all from this part. Anyway if you are interested how did these function implemented, you may open [include/linux/bitmap.h](https://github.com/torvalds/linux/blob/master/include/linux/bitmap.h) header file and start to research. - -That's all. - -Links -================================================================================ - -* [bitmap](https://en.wikipedia.org/wiki/Bit_array) -* [linked data structures](https://en.wikipedia.org/wiki/Linked_data_structure) -* [tree data structures](https://en.wikipedia.org/wiki/Tree_%28data_structure%29) -* [hot-plug](https://www.kernel.org/doc/Documentation/cpu-hotplug.txt) -* [cpumasks](https://0xax.gitbooks.io/linux-insides/content/Concepts/cpumask.html) -* [IRQs](https://en.wikipedia.org/wiki/Interrupt_request_%28PC_architecture%29) -* [API](https://en.wikipedia.org/wiki/Application_programming_interface) -* [atomic operations](https://en.wikipedia.org/wiki/Linearizability) -* [xchg instruction](http://x86.renejeschke.de/html/file_module_x86_id_328.html) -* [cmpxchg instruction](http://x86.renejeschke.de/html/file_module_x86_id_41.html) -* [lock instruction](http://x86.renejeschke.de/html/file_module_x86_id_159.html) -* [bts instruction](http://x86.renejeschke.de/html/file_module_x86_id_25.html) -* [btr instruction](http://x86.renejeschke.de/html/file_module_x86_id_24.html) -* [bt instruction](http://x86.renejeschke.de/html/file_module_x86_id_22.html) -* [sbb instruction](http://x86.renejeschke.de/html/file_module_x86_id_286.html) -* [btc instruction](http://x86.renejeschke.de/html/file_module_x86_id_23.html) -* [man memcpy](http://man7.org/linux/man-pages/man3/memcpy.3.html) -* [man memset](http://man7.org/linux/man-pages/man3/memset.3.html) -* [CF](https://en.wikipedia.org/wiki/FLAGS_register) -* [inline assembler](https://en.wikipedia.org/wiki/Inline_assembler) -* [gcc](https://en.wikipedia.org/wiki/GNU_Compiler_Collection) - - ------------------------------------------------------------------------------- - -via: https://github.com/0xAX/linux-insides/blob/master/DataStructures/bitmap.md - -作者:[0xAX][a] -译者:[译者ID](https://github.com/译者ID) -校对:[校对者ID](https://github.com/校对者ID) - -本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创翻译,[Linux中国](https://linux.cn/) 荣誉推出 - -[a]: https://twitter.com/0xAX diff --git a/translated/tech/20160512 Bitmap in Linux Kernel.md b/translated/tech/20160512 Bitmap in Linux Kernel.md new file mode 100644 index 0000000000..6475b9260e --- /dev/null +++ b/translated/tech/20160512 Bitmap in Linux Kernel.md @@ -0,0 +1,405 @@ +--- +date: 2016-07-09 14:42 +status: public +title: 20160512 Bitmap in Linux Kernel +--- + +Linux 内核里的数据结构 +================================================================================ + +Linux 内核中的位数组和位操作 +-------------------------------------------------------------------------------- + +除了不同的基于[链式](https://en.wikipedia.org/wiki/Linked_data_structure)和[树](https://en.wikipedia.org/wiki/Tree_%28data_structure%29)的数据结构以外,Linux 内核也为[位数组](https://en.wikipedia.org/wiki/Bit_array)或`位图`提供了 [API](https://en.wikipedia.org/wiki/Application_programming_interface)。位数组在 Linux 内核里被广泛使用,并且在以下的源代码文件中包含了与这样的结构搭配使用的通用 `API`: + +* [lib/bitmap.c](https://github.com/torvalds/linux/blob/master/lib/bitmap.c) +* [include/linux/bitmap.h](https://github.com/torvalds/linux/blob/master/include/linux/bitmap.h) + +除了这两个文件之外,还有体系结构特定的头文件,它们为特定的体系结构提供优化的位操作。我们将探讨 [x86_64](https://en.wikipedia.org/wiki/X86-64) 体系结构,因此在我们的例子里,它会是 + +* [arch/x86/include/asm/bitops.h](https://github.com/torvalds/linux/blob/master/arch/x86/include/asm/bitops.h) + +头文件。正如我上面所写的,`位图`在 Linux 内核中被广泛地使用。例如,`位数组`常常用于保存一组在线/离线处理器,以便系统支持[热插拔](https://www.kernel.org/doc/Documentation/cpu-hotplug.txt)的 CPU(你可以在 [cpumasks](https://0xax.gitbooks.io/linux-insides/content/Concepts/cpumask.html) 部分阅读更多相关知识 ),一个`位数组`可以在 Linux 内核初始化等期间保存一组已分配的中断处理。 + +因此,本部分的主要目的是了解位数组是如何在 Linux 内核中实现的。让我们现在开始吧。 + +位数组声明 +================================================================================ + +在我们开始查看位图操作的 `API` 之前,我们必须知道如何在 Linux 内核中声明它。有两中通用的方法声明位数组。第一种简单的声明一个位数组的方法是,定义一个 unsigned long 的数组,例如: + +```C +unsigned long my_bitmap[8] +``` + +第二种方法,是使用 `DECLARE_BITMAP` 宏,它定义于 [include/linux/types.h](https://github.com/torvalds/linux/blob/master/include/linux/types.h) 头文件: + +```C +#define DECLARE_BITMAP(name,bits) \ + unsigned long name[BITS_TO_LONGS(bits)] +``` + +我们可以看到 `DECLARE_BITMAP` 宏使用两个参数: + +* `name` - 位图名称; +* `bits` - 位图中位数; + +并且只是使用 `BITS_TO_LONGS(bits)` 元素展开 `unsigned long` 数组的定义。 `BITS_TO_LONGS` 宏将一个给定的位数转换为 `longs` 的个数,换言之,就是计算 `bits` 中有多少个 `8` 字节元素: + +```C +#define BITS_PER_BYTE 8 +#define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d)) +#define BITS_TO_LONGS(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(long)) +``` + +因此,例如 `DECLARE_BITMAP(my_bitmap, 64)` 将产生: + +```python +>>> (((64) + (64) - 1) / (64)) +1 +``` + +与: + +```C +unsigned long my_bitmap[1]; +``` + +在能够声明一个位数组之后,我们便可以使用它了。 + +体系结构特定的位操作 +================================================================================ + +我们已经看了以上一对源文件和头文件,它们提供了位数组操作的 [API](https://en.wikipedia.org/wiki/Application_programming_interface)。其中重要且广泛使用的位数组 API 是体系结构特定的且位于已提及的头文件中 [arch/x86/include/asm/bitops.h](https://github.com/torvalds/linux/blob/master/arch/x86/include/asm/bitops.h)。 + +首先让我们查看两个最重要的函数: + +* `set_bit`; +* `clear_bit`. + +我认为没有必要解释这些函数的作用。从它们的名字来看,这已经很清楚了。让我们直接查看它们的实现。如果你浏览 [arch/x86/include/asm/bitops.h](https://github.com/torvalds/linux/blob/master/arch/x86/include/asm/bitops.h) 头文件,你将会注意到这些函数中的每一个都有[原子性](https://en.wikipedia.org/wiki/Linearizability)和非原子性两种变体。在我们开始深入这些函数的实现之前,首先,我们必须了解一些有关原子操作的知识。 + +简而言之,原子操作保证两个或以上的操作不会并发地执行同一数据。`x86` 体系结构提供了一系列原子指令,例如, [xchg](http://x86.renejeschke.de/html/file_module_x86_id_328.html)、[cmpxchg](http://x86.renejeschke.de/html/file_module_x86_id_41.html) 等指令。除了原子指令,一些非原子指令可以在 [lock](http://x86.renejeschke.de/html/file_module_x86_id_159.html) 指令的帮助下具有原子性。目前已经对原子操作有了充分的理解,我们可以接着探讨 `set_bit` 和 `clear_bit` 函数的实现。 + +我们先考虑函数的非原子性变体。非原子性的 `set_bit` 和 `clear_bit` 的名字以双下划线开始。正如我们所知道的,所有这些函数都定义于 [arch/x86/include/asm/bitops.h](https://github.com/torvalds/linux/blob/master/arch/x86/include/asm/bitops.h) 头文件,并且第一个函数就是 `__set_bit`: + +```C +static inline void __set_bit(long nr, volatile unsigned long *addr) +{ + asm volatile("bts %1,%0" : ADDR : "Ir" (nr) : "memory"); +} +``` + +正如我们所看到的,它使用了两个参数: + +* `nr` - 位数组中的位号(从0开始,译者注) +* `addr` - 我们需要置位的位数组地址 + +注意,`addr` 参数使用 `volatile` 关键字定义,以告诉编译器给定地址指向的变量可能会被修改。 `__set_bit` 的实现相当简单。正如我们所看到的,它仅包含一行[内联汇编代码](https://en.wikipedia.org/wiki/Inline_assembler)。在我们的例子中,我们使用 [bts](http://x86.renejeschke.de/html/file_module_x86_id_25.html) 指令,从位数组中选出一个第一操作数(我们的例子中的 `nr`),存储选出的位的值到 [CF](https://en.wikipedia.org/wiki/FLAGS_register) 标志寄存器并设置该位(即 `nr` 指定的位置为1,译者注)。 + +注意,我们了解了 `nr` 的用法,但这里还有一个参数 `addr` 呢!你或许已经猜到秘密就在 `ADDR`。 `ADDR` 是一个定义在同一头文件的宏,它展开为一个包含给定地址和 `+m` 约束的字符串: + +```C +#define ADDR BITOP_ADDR(addr) +#define BITOP_ADDR(x) "+m" (*(volatile long *) (x)) +``` + +除了 `+m` 之外,在 `__set_bit` 函数中我们可以看到其他约束。让我们查看并试图理解它们所表示的意义: + +* `+m` - 表示内存操作数,这里的 `+` 表明给定的操作数为输入输出操作数; +* `I` - 表示整型常量; +* `r` - 表示寄存器操作数 + +除了这些约束之外,我们也能看到 `memory` 关键字,其告诉编译器这段代码会修改内存中的变量。到此为止,现在我们看看相同的原子性变体函数。它看起来比非原子性变体更加复杂: + +```C +static __always_inline void +set_bit(long nr, volatile unsigned long *addr) +{ + if (IS_IMMEDIATE(nr)) { + asm volatile(LOCK_PREFIX "orb %1,%0" + : CONST_MASK_ADDR(nr, addr) + : "iq" ((u8)CONST_MASK(nr)) + : "memory"); + } else { + asm volatile(LOCK_PREFIX "bts %1,%0" + : BITOP_ADDR(addr) : "Ir" (nr) : "memory"); + } +} +``` + +(BITOP_ADDR 的定义为:`#define BITOP_ADDR(x) "=m" (*(volatile long *) (x))`,ORB 为字节按位或,译者注) + +首先注意,这个函数使用了与 `__set_bit` 相同的参数集合,但额外地使用了 `__always_inline` 属性标记。 `__always_inline` 是一个定义于 [include/linux/compiler-gcc.h](https://github.com/torvalds/linux/blob/master/include/linux/compiler-gcc.h) 的宏,并且只是展开为 `always_inline` 属性: + +```C +#define __always_inline inline __attribute__((always_inline)) +``` + +其意味着这个函数总是内联的,以减少 Linux 内核映像的大小。现在我们试着了解 `set_bit` 函数的实现。首先我们在 `set_bit` 函数的开头检查给定的位数量。`IS_IMMEDIATE` 宏定义于相同[头文件](https://github.com/torvalds/linux/blob/master/arch/x86/include/asm/bitops.h),并展开为 gcc 内置函数的调用: + +```C +#define IS_IMMEDIATE(nr) (__builtin_constant_p(nr)) +``` + +如果给定的参数是编译期已知的常量,`__builtin_constant_p` 内置函数则返回 `1`,其他情况返回 `0`。假若给定的位数是编译期已知的常量,我们便无须使用效率低下的 `bts` 指令去设置位。我们可以只需在给定地址指向的字节和和掩码上执行 [按位或](https://en.wikipedia.org/wiki/Bitwise_operation#OR) 操作,其字节包含给定的位,而掩码为位号高位 `1`,其他位为 0。在其他情况下,如果给定的位号不是编译期已知常量,我们便做和 `__set_bit` 函数一样的事。`CONST_MASK_ADDR` 宏: + +```C +#define CONST_MASK_ADDR(nr, addr) BITOP_ADDR((void *)(addr) + ((nr)>>3)) +``` + +展开为带有到包含给定位的字节偏移的给定地址,例如,我们拥有地址 `0x1000` 和 位号是 `0x9`。因为 `0x9` 是 `一个字节 + 一位`,所以我们的地址是 `addr + 1`: + +```python +>>> hex(0x1000 + (0x9 >> 3)) +'0x1001' +``` + +`CONST_MASK` 宏将我们给定的位号表示为字节,位号对应位为高位 `1`,其他位为 `0`: + +```C +#define CONST_MASK(nr) (1 << ((nr) & 7)) +``` + +```python +>>> bin(1 << (0x9 & 7)) +'0b10' +``` + +最后,我们应用 `按位或` 运算到这些变量上面,因此,假如我们的地址是 `0x4097` ,并且我们需要置位号为 `9` 的位 为 1: + +```python +>>> bin(0x4097) +'0b100000010010111' +>>> bin((0x4097 >> 0x9) | (1 << (0x9 & 7))) +'0b100010' +``` + +`第 9 位` 将会被置位。(这里的 9 是从 0 开始计数的,比如0010,按照作者的意思,其中的 1 是第 1 位,译者注) + +注意,所有这些操作使用 `LOCK_PREFIX` 标记,其展开为 [lock](http://x86.renejeschke.de/html/file_module_x86_id_159.html) 指令,保证该操作的原子性。 + +正如我们所知,除了 `set_bit` 和 `__set_bit` 操作之外,Linux 内核还提供了两个功能相反的函数,在原子性和非原子性的上下文中清位。它们为 `clear_bit` 和 `__clear_bit`。这两个函数都定义于同一个[头文件](https://github.com/torvalds/linux/blob/master/arch/x86/include/asm/bitops.h) 并且使用相同的参数集合。不仅参数相似,一般而言,这些函数与 `set_bit` 和 `__set_bit` 也非常相似。让我们查看非原子性 `__clear_bit` 的实现吧: + +```C +static inline void __clear_bit(long nr, volatile unsigned long *addr) +{ + asm volatile("btr %1,%0" : ADDR : "Ir" (nr)); +} +``` + +没错,正如我们所见,`__clear_bit` 使用相同的参数集合,并包含极其相似的内联汇编代码块。它仅仅使用 [btr](http://x86.renejeschke.de/html/file_module_x86_id_24.html) 指令替换 `bts`。正如我们从函数名所理解的一样,通过给定地址,它清除了给定的位。`btr` 指令表现得像 `bts`(原文这里为 btr,可能为笔误,修正为 bts,译者注)。该指令选出第一操作数指定的位,存储它的值到 `CF` 标志寄存器,并且清楚第二操作数指定的位数组中的对应位。 + +`__clear_bit` 的原子性变体为 `clear_bit`: + +```C +static __always_inline void +clear_bit(long nr, volatile unsigned long *addr) +{ + if (IS_IMMEDIATE(nr)) { + asm volatile(LOCK_PREFIX "andb %1,%0" + : CONST_MASK_ADDR(nr, addr) + : "iq" ((u8)~CONST_MASK(nr))); + } else { + asm volatile(LOCK_PREFIX "btr %1,%0" + : BITOP_ADDR(addr) + : "Ir" (nr)); + } +} +``` + +并且正如我们所看到的,它与 `set_bit` 非常相似,同时只包含了两处差异。第一处差异为 `clear_bit` 使用 `btr` 指令来清位,而 `set_bit` 使用 `bts` 指令来置位。第二处差异为 `clear_bit` 使用否定的位掩码和 `按位与` 在给定的字节上置位,而 `set_bit` 使用 `按位或` 指令。 + +到此为止,我们可以在任何位数组置位和清位了,并且能够转到位掩码上的其他操作。 + +在 Linux 内核位数组上最广泛使用的操作是设置和清除位,但是除了这两个操作外,位数组上其他操作也是非常有用的。Linux 内核里另一种广泛使用的操作是知晓位数组中一个给定的位是否被置位。我们能够通过 `test_bit` 宏的帮助实现这一功能。这个宏定义于 [arch/x86/include/asm/bitops.h](https://github.com/torvalds/linux/blob/master/arch/x86/include/asm/bitops.h) 头文件,并展开为 `constant_test_bit` 或 `variable_test_bit` 的调用,这要取决于位号。 + +```C +#define test_bit(nr, addr) \ + (__builtin_constant_p((nr)) \ + ? constant_test_bit((nr), (addr)) \ + : variable_test_bit((nr), (addr))) +``` + +因此,如果 `nr` 是编译期已知常量,`test_bit` 将展开为 `constant_test_bit` 函数的调用,而其他情况则为 `variable_test_bit`。现在让我们看看这些函数的实现,我们从 `variable_test_bit` 开始看起: + +```C +static inline int variable_test_bit(long nr, volatile const unsigned long *addr) +{ + int oldbit; + + asm volatile("bt %2,%1\n\t" + "sbb %0,%0" + : "=r" (oldbit) + : "m" (*(unsigned long *)addr), "Ir" (nr)); + + return oldbit; +} +``` + +`variable_test_bit` 函数调用了与 `set_bit` 及其他函数使用的相似的参数集合。我们也可以看到执行 [bt](http://x86.renejeschke.de/html/file_module_x86_id_22.html) 和 [sbb](http://x86.renejeschke.de/html/file_module_x86_id_286.html) 指令的内联汇编代码。`bt` 或 `bit test` 指令从第二操作数指定的位数组选出第一操作数指定的一个指定位,并且将该位的值存进标志寄存器的 [CF](https://en.wikipedia.org/wiki/FLAGS_register) 位。第二个指令 `sbb` 从第二操作数中减去第一操作数,再减去 `CF` 的值。因此,这里将一个从给定位数组中的给定位号的值写进标志寄存器的 `CF` 位,并且执行 `sbb` 指令计算: `00000000 - CF`,并将结果写进 `oldbit` 变量。 + +`constant_test_bit` 函数做了和我们在 `set_bit` 所看到的一样的事: + +```C +static __always_inline int constant_test_bit(long nr, const volatile unsigned long *addr) +{ + return ((1UL << (nr & (BITS_PER_LONG-1))) & + (addr[nr >> _BITOPS_LONG_SHIFT])) != 0; +} +``` + +它生成了一个位号对应位为高位 `1`,而其他位为 `0` 的字节(正如我们在 `CONST_MASK` 所看到的),并将 [按位与](https://en.wikipedia.org/wiki/Bitwise_operation#AND) 应用于包含给定位号的字节。 + +下一广泛使用的位数组相关操作是改变一个位数组中的位。为此,Linux 内核提供了两个辅助函数: + +* `__change_bit`; +* `change_bit`. + +你可能已经猜测到,就拿 `set_bit` 和 `__set_bit` 例子说,这两个变体分别是原子和非原子版本。首先,让我们看看 `__change_bit` 函数的实现: + +```C +static inline void __change_bit(long nr, volatile unsigned long *addr) +{ + asm volatile("btc %1,%0" : ADDR : "Ir" (nr)); +} +``` + +相当简单,不是吗? `__change_bit` 的实现和 `__set_bit` 一样,只是我们使用 [btc](http://x86.renejeschke.de/html/file_module_x86_id_23.html) 替换 `bts` 指令而已。 该指令从一个给定位数组中选出一个给定位,将该为位的值存进 `CF` 并使用求反操作改变它的值,因此值为 `1` 的位将变为 `0`,反之亦然: + +```python +>>> int(not 1) +0 +>>> int(not 0) +1 +``` + + `__change_bit` 的原子版本为 `change_bit` 函数: + +```C +static inline void change_bit(long nr, volatile unsigned long *addr) +{ + if (IS_IMMEDIATE(nr)) { + asm volatile(LOCK_PREFIX "xorb %1,%0" + : CONST_MASK_ADDR(nr, addr) + : "iq" ((u8)CONST_MASK(nr))); + } else { + asm volatile(LOCK_PREFIX "btc %1,%0" + : BITOP_ADDR(addr) + : "Ir" (nr)); + } +} +``` + +它和 `set_bit` 函数很相似,但也存在两点差异。第一处差异为 `xor` 操作而不是 `or`。第二处差异为 `btc`(原文为 `bts`,为作者笔误,译者注) 而不是 `bts`。 + +目前,我们了解了最重要的体系特定的位数组操作,是时候看看一般的位图 API 了。 + +通用位操作 +================================================================================ + +除了 [arch/x86/include/asm/bitops.h](https://github.com/torvalds/linux/blob/master/arch/x86/include/asm/bitops.h) 中体系特定的 API 外,Linux 内核提供了操作位数组的通用 API。正如我们本部分开头所了解的一样,我们可以在 [include/linux/bitmap.h](https://github.com/torvalds/linux/blob/master/include/linux/bitmap.h) 头文件和* [lib/bitmap.c](https://github.com/torvalds/linux/blob/master/lib/bitmap.c) 源文件中找到它。但在查看这些源文件之前,我们先看看 [include/linux/bitops.h](https://github.com/torvalds/linux/blob/master/include/linux/bitops.h) 头文件,其提供了一系列有用的宏,让我们看看它们当中一部分。 + +首先我们看看以下 4 个 宏: + +* `for_each_set_bit` +* `for_each_set_bit_from` +* `for_each_clear_bit` +* `for_each_clear_bit_from` + +所有这些宏都提供了遍历位数组中某些位集合的迭代器。第一个红迭代那些被置位的位。第二个宏也是一样,但它是从某一确定位开始。最后两个宏做的一样,但是迭代那些被清位的位。让我们看看 `for_each_set_bit` 宏: + +```C +#define for_each_set_bit(bit, addr, size) \ + for ((bit) = find_first_bit((addr), (size)); \ + (bit) < (size); \ + (bit) = find_next_bit((addr), (size), (bit) + 1)) +``` + +正如我们所看到的,它使用了三个参数,并展开为一个循环,该循环从作为 `find_first_bit` 函数返回结果的第一个置位开始到最后一个置位且小于给定大小为止。 + +除了这四个宏, [arch/x86/include/asm/bitops.h](https://github.com/torvalds/linux/blob/master/arch/x86/include/asm/bitops.h) 也提供了 `64-bit` 或 `32-bit` 变量循环的 API 等等。 + +下一个 [头文件](https://github.com/torvalds/linux/blob/master/include/linux/bitmap.h) 提供了操作位数组的 API。例如,它提供了以下两个函数: + +* `bitmap_zero`; +* `bitmap_fill`. + +它们分别可以清除一个位数组和用 `1` 填充位数组。让我们看看 `bitmap_zero` 函数的实现: + +```C +static inline void bitmap_zero(unsigned long *dst, unsigned int nbits) +{ + if (small_const_nbits(nbits)) + *dst = 0UL; + else { + unsigned int len = BITS_TO_LONGS(nbits) * sizeof(unsigned long); + memset(dst, 0, len); + } +} +``` + +首先我们可以看到对 `nbits` 的检查。 `small_const_nbits` 是一个定义在同一[头文件](https://github.com/torvalds/linux/blob/master/include/linux/bitmap.h) 的宏: + +```C +#define small_const_nbits(nbits) \ + (__builtin_constant_p(nbits) && (nbits) <= BITS_PER_LONG) +``` + +正如我们可以看到的,它检查 `nbits` 是否为编译期已知常量,并且其值不超过 `BITS_PER_LONG` 或 `64`。如果位数目没有超过一个 `long` 变量的位数,我们可以仅仅设置为 0。在其他情况,我们需要计算有多少个需要填充位数组的 `long` 变量并且使用 [memset](http://man7.org/linux/man-pages/man3/memset.3.html) 进行填充。 + +`bitmap_fill` 函数的实现和 `biramp_zero` 函数很相似,除了我们需要在给定的位数组中填写 `0xff` 或 `0b11111111`: + +```C +static inline void bitmap_fill(unsigned long *dst, unsigned int nbits) +{ + unsigned int nlongs = BITS_TO_LONGS(nbits); + if (!small_const_nbits(nbits)) { + unsigned int len = (nlongs - 1) * sizeof(unsigned long); + memset(dst, 0xff, len); + } + dst[nlongs - 1] = BITMAP_LAST_WORD_MASK(nbits); +} +``` + +除了 `bitmap_fill` 和 `bitmap_zero`,[include/linux/bitmap.h](https://github.com/torvalds/linux/blob/master/include/linux/bitmap.h) 头文件也提供了和 `bitmap_zero` 很相似的 `bitmap_copy`,只是仅仅使用 [memcpy](http://man7.org/linux/man-pages/man3/memcpy.3.html) 而不是 [memset](http://man7.org/linux/man-pages/man3/memset.3.html) 这点差异而已。它也提供了位数组的按位操作,像 `bitmap_and`, `bitmap_or`, `bitamp_xor`等等。我们不会探讨这些函数的实现了,因为如果你理解了本部分的所有内容,这些函数的实现是很容易理解的。无论如何,如果你对这些函数是如何实现的感兴趣,你可以打开并研究 [include/linux/bitmap.h](https://github.com/torvalds/linux/blob/master/include/linux/bitmap.h) 头文件。 + +本部分到此为止。 + +链接 +================================================================================ + +* [bitmap](https://en.wikipedia.org/wiki/Bit_array) +* [linked data structures](https://en.wikipedia.org/wiki/Linked_data_structure) +* [tree data structures](https://en.wikipedia.org/wiki/Tree_%28data_structure%29) +* [hot-plug](https://www.kernel.org/doc/Documentation/cpu-hotplug.txt) +* [cpumasks](https://0xax.gitbooks.io/linux-insides/content/Concepts/cpumask.html) +* [IRQs](https://en.wikipedia.org/wiki/Interrupt_request_%28PC_architecture%29) +* [API](https://en.wikipedia.org/wiki/Application_programming_interface) +* [atomic operations](https://en.wikipedia.org/wiki/Linearizability) +* [xchg instruction](http://x86.renejeschke.de/html/file_module_x86_id_328.html) +* [cmpxchg instruction](http://x86.renejeschke.de/html/file_module_x86_id_41.html) +* [lock instruction](http://x86.renejeschke.de/html/file_module_x86_id_159.html) +* [bts instruction](http://x86.renejeschke.de/html/file_module_x86_id_25.html) +* [btr instruction](http://x86.renejeschke.de/html/file_module_x86_id_24.html) +* [bt instruction](http://x86.renejeschke.de/html/file_module_x86_id_22.html) +* [sbb instruction](http://x86.renejeschke.de/html/file_module_x86_id_286.html) +* [btc instruction](http://x86.renejeschke.de/html/file_module_x86_id_23.html) +* [man memcpy](http://man7.org/linux/man-pages/man3/memcpy.3.html) +* [man memset](http://man7.org/linux/man-pages/man3/memset.3.html) +* [CF](https://en.wikipedia.org/wiki/FLAGS_register) +* [inline assembler](https://en.wikipedia.org/wiki/Inline_assembler) +* [gcc](https://en.wikipedia.org/wiki/GNU_Compiler_Collection) + + +------------------------------------------------------------------------------ + +via: https://github.com/0xAX/linux-insides/blob/master/DataStructures/bitmap.md + +作者:[0xAX][a] +译者:[cposture](https://github.com/cposture) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创翻译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]: https://twitter.com/0xAX \ No newline at end of file From b1cdc7fcbe2fee9dbb5ad3264d19e028d9f3b818 Mon Sep 17 00:00:00 2001 From: cposture Date: Sat, 9 Jul 2016 21:46:14 +0800 Subject: [PATCH 004/122] Translating by cposture --- .../tech/20160705 Create Your Own Shell in Python - Part I.md | 1 + .../tech/20160706 Create Your Own Shell in Python - Part II.md | 1 + 2 files changed, 2 insertions(+) diff --git a/sources/tech/20160705 Create Your Own Shell in Python - Part I.md b/sources/tech/20160705 Create Your Own Shell in Python - Part I.md index 9c3ffa55dd..48e84381c8 100644 --- a/sources/tech/20160705 Create Your Own Shell in Python - Part I.md +++ b/sources/tech/20160705 Create Your Own Shell in Python - Part I.md @@ -1,3 +1,4 @@ +Translating by cposture 2016.07.09 Create Your Own Shell in Python : Part I I’m curious to know how a shell (like bash, csh, etc.) works internally. So, I implemented one called yosh (Your Own SHell) in Python to answer my own curiosity. The concept I explain in this article can be applied to other languages as well. diff --git a/sources/tech/20160706 Create Your Own Shell in Python - Part II.md b/sources/tech/20160706 Create Your Own Shell in Python - Part II.md index af0ec01b36..3154839443 100644 --- a/sources/tech/20160706 Create Your Own Shell in Python - Part II.md +++ b/sources/tech/20160706 Create Your Own Shell in Python - Part II.md @@ -1,3 +1,4 @@ +Translating by cposture 2016.07.09 Create Your Own Shell in Python - Part II =========================================== From 93bb30d7e4d0f40f711aa8304fbbfa389fba163d Mon Sep 17 00:00:00 2001 From: cposture Date: Tue, 12 Jul 2016 00:41:32 +0800 Subject: [PATCH 005/122] translating partly --- ...reate Your Own Shell in Python - Part I.md | 41 ++++++++++--------- 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/sources/tech/20160705 Create Your Own Shell in Python - Part I.md b/sources/tech/20160705 Create Your Own Shell in Python - Part I.md index 48e84381c8..0b7e415f2a 100644 --- a/sources/tech/20160705 Create Your Own Shell in Python - Part I.md +++ b/sources/tech/20160705 Create Your Own Shell in Python - Part I.md @@ -1,15 +1,15 @@ -Translating by cposture 2016.07.09 -Create Your Own Shell in Python : Part I +使用 Python 创建你自己的 Shell:Part I +========================================== -I’m curious to know how a shell (like bash, csh, etc.) works internally. So, I implemented one called yosh (Your Own SHell) in Python to answer my own curiosity. The concept I explain in this article can be applied to other languages as well. +我很好奇一个 shell (像 bash,csh 等)内部是如何工作的。为了满足自己的好奇心,我使用 Python 实现了一个名为 yosh (Your Own Shell)的 Shell。本文章所介绍的概念也可以应用于其他编程语言。 -(Note: You can find source code used in this blog post here. I distribute it with MIT license.) +(提示:你可以发布于此的博文中找到使用的源代码,代码以 MIT 许可发布) -Let’s start. +让我们开始吧。 -### Step 0: Project Structure +### 步骤 0:项目结构 -For this project, I use the following project structure. +对于此项目,我使用了以下的项目结构。 ``` yosh_project @@ -18,17 +18,17 @@ yosh_project |-- shell.py ``` -`yosh_project` is the root project folder (you can also name it just `yosh`). +`yosh_project` 为项目根目录(你也可以把它简单地命名为 `yosh`)。 -`yosh` is the package folder and `__init__.py` will make it a package named the same as the package folder name. (If you don’t write Python, just ignore it.) +`yosh` 为包目录,并且 `__init__.py` 将会使一个包名等同于包目录名字(如果你不写 Python,可以忽略它) -`shell.py` is our main shell file. +`shell.py` 是我们的主脚本文件。 -### Step 1: Shell Loop +### 步骤 1:Shell 循环 -When you start a shell, it will show a command prompt and wait for your command input. After it receives the command and executes it (the detail will be explained later), your shell will be back to the wait loop for your next command. +当你启动一个 shell,它会显示一个命令提示符同时等待用户输入命令。在接收了输入的命令并执行它之后(稍后文章会进行详细解释),你的 shell 会回到循环,等待下一条指令。 -In `shell.py`, we start by a simple main function calling the shell_loop() function as follows: +在 `shell.py`,我们会以一个简单的 mian 函数开始,该函数调用了 shell_loop() 函数,如下: ``` def shell_loop(): @@ -43,7 +43,7 @@ if __name__ == "__main__": main() ``` -Then, in our `shell_loop()`, we use a status flag to indicate whether the loop should continue or stop. In the beginning of the loop, our shell will show a command prompt and wait to read command input. +接着,在 `shell_loop()`,为了指示循环是否继续或停止,我们使用了一个状态标志。在循环的开始,我们的 shell 将显示一个命令提示符,并等待读取命令输入。 ``` import sys @@ -64,9 +64,9 @@ def shell_loop(): cmd = sys.stdin.readline() ``` -After that, we tokenize the command input and execute it (we’ll implement the tokenize and execute functions soon). +之后,我们切分命令输入并进行执行(我们将马上解释命令切分和执行函数)。 -Therefore, our shell_loop() will be the following. +因此,我们的 shell_loop() 会是如下这样: ``` import sys @@ -93,14 +93,15 @@ def shell_loop(): status = execute(cmd_tokens) ``` -That’s all of our shell loop. If we start our shell with python shell.py, it will show the command prompt. However, it will throw an error if we type a command and hit enter because we don’t define tokenize function yet. +这就是我们整个 shell 循环。如果我们使用 python shell.py 命令启动 shell,它会显示命令提示符。然而如果我们输入命令并按回车,它将会抛出错误,因为我们还没定义命令切分函数。 -To exit the shell, try ctrl-c. I will tell how to exit gracefully later. +为了退出 shell,可以尝试输入 ctrl-c。稍后我将解释如何以优雅的形式退出 shell。 -### Step 2: Tokenization +### 步骤 2:命令切分 -When a user types a command in our shell and hits enter. The command input will be a long string containing both a command name and its arguments. Therefore, we have to tokenize it (split a string into several tokens). +当一个用户在我们的 shell 中输入命令并按下回车键,该命令将会是一个包含命令名称及其参数的很长的字符串。因此,我们必须切分该字符串(分割一个字符串为多个标记)。 +咋一看它似乎很简单。我们或许可以使用 cmd.split(),用空格分割输入。 It seems simple at first glance. We might use cmd.split() to separate the input by spaces. It works well for a command like `ls -a my_folder` because it splits the command into a list `['ls', '-a', 'my_folder']` which we can use them easily. However, there are some cases that some arguments are quoted with single or double quotes like `echo "Hello World"` or `echo 'Hello World'`. If we use cmd.split(), we will get a list of 3 tokens `['echo', '"Hello', 'World"']` instead of 2 tokens `['echo', 'Hello World']`. From bfa39b05dd36e7fbe3b05ba3a25aabca7f47f999 Mon Sep 17 00:00:00 2001 From: cposture Date: Wed, 13 Jul 2016 09:27:55 +0800 Subject: [PATCH 006/122] translating partly 75 --- ...reate Your Own Shell in Python - Part I.md | 27 ++++++++++--------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/sources/tech/20160705 Create Your Own Shell in Python - Part I.md b/sources/tech/20160705 Create Your Own Shell in Python - Part I.md index 0b7e415f2a..67e5809b3d 100644 --- a/sources/tech/20160705 Create Your Own Shell in Python - Part I.md +++ b/sources/tech/20160705 Create Your Own Shell in Python - Part I.md @@ -101,12 +101,12 @@ def shell_loop(): 当一个用户在我们的 shell 中输入命令并按下回车键,该命令将会是一个包含命令名称及其参数的很长的字符串。因此,我们必须切分该字符串(分割一个字符串为多个标记)。 -咋一看它似乎很简单。我们或许可以使用 cmd.split(),用空格分割输入。 -It seems simple at first glance. We might use cmd.split() to separate the input by spaces. It works well for a command like `ls -a my_folder` because it splits the command into a list `['ls', '-a', 'my_folder']` which we can use them easily. +咋一看似乎很简单。我们或许可以使用 cmd.split(),用空格分割输入。它对类似 `ls -a my_folder` 的命令起作用,因为它能够将命令分割为一个列表 `['ls', '-a', 'my_folder']`,这样我们便能轻易处理它们了。 -However, there are some cases that some arguments are quoted with single or double quotes like `echo "Hello World"` or `echo 'Hello World'`. If we use cmd.split(), we will get a list of 3 tokens `['echo', '"Hello', 'World"']` instead of 2 tokens `['echo', 'Hello World']`. +然而,也有一些类似 `echo "Hello World"` 或 `echo 'Hello World'` 以单引号或双引号引用参数的情况。如果我们使用 cmd.spilt,我们将会得到一个存有 3 个标记的列表 `['echo', '"Hello', 'World"']` 而不是 2 个标记 `['echo', 'Hello World']`。 + +幸运的是,Python 提供了一个名为 shlex 的库,能够帮助我们效验如神地分割命令。(提示:我们也可以使用正则表达式,但它不是本文的重点。) -Fortunately, Python provides a library called shlex that helps us split like a charm. (Note: we can also use regular expression but it’s not the main point of this article.) ``` import sys @@ -120,13 +120,13 @@ def tokenize(string): ... ``` -Then, we will send these tokens to the execution process. +然后我们将这些标记发送到执行过程。 -### Step 3: Execution +### 步骤 3:执行 -This is the core and fun part of a shell. What happened when a shell executes mkdir test_dir? (Note: mkdir is a program to be executed with arguments test_dir for creating a directory named test_dir.) +这是 shell 中核心和有趣的一部分。当 shell 执行 mkdir test_dir 时,发生了什么?(提示:midir 是一个带有 test_dir 参数的执行程序,用于创建一个名为 test_dir 的目录。) -The first function involved in this step is execvp. Before I explain what execvp does, let’s see it in action. +execvp 是涉及这一步的首个函数。在我们解释 execvp 所做的事之前,让我们看看它的实际效果。 ``` import os @@ -142,15 +142,16 @@ def execute(cmd_tokens): ... ``` -Try running our shell again and input a command `mkdir test_dir`, then, hit enter. +再次尝试运行我们的 shell,并输入 `mkdir test_dir` 命令,接着按下回车键。 -The problem is, after we hit enter, our shell exits instead of waiting for the next command. However, the directory is correctly created. +在我们敲下回车键之后,问题是我们的 shell 会直接退出而不是等待下一个命令。然而,目标正确地被创建。 -So, what execvp really does? +因此,execvp 实际上做了什么? -execvp is a variant of a system call exec. The first argument is the program name. The v indicates the second argument is a list of program arguments (variable number of arguments). The p indicates the PATH environment will be used for searching for the given program name. In our previous attempt, the mkdir program was found based on your PATH environment variable. +execvp 是系统调用 exec 的一个变体。第一个参数是程序名字。v 表示第二个参数是一个程序参数列表(可变参数)。p 表示环境变量 PATH 会被用于搜索给定的程序名字。在我们上一次的尝试中,可以在你的 PATH 环境变量查找到 mkdir 程序。 + +(还有其他 exec 变体,比如 execv、execvpe、execl、execlp、execlpe;你可以 google 它们获取更多的信息。) -(There are other variants of exec such as execv, execvpe, execl, execlp, execlpe; you can google them for more information.) exec replaces the current memory of a calling process with a new process to be executed. In our case, our shell process memory was replaced by `mkdir` program. Then, mkdir became the main process and created the test_dir directory. Finally, its process exited. From 97bdb52dc246b07480649ea4d70b6c0df55f0e96 Mon Sep 17 00:00:00 2001 From: cposture Date: Wed, 13 Jul 2016 13:48:03 +0800 Subject: [PATCH 007/122] Translated by cposture --- ...reate Your Own Shell in Python - Part I.md | 31 +++++++++---------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/sources/tech/20160705 Create Your Own Shell in Python - Part I.md b/sources/tech/20160705 Create Your Own Shell in Python - Part I.md index 67e5809b3d..74cac3887e 100644 --- a/sources/tech/20160705 Create Your Own Shell in Python - Part I.md +++ b/sources/tech/20160705 Create Your Own Shell in Python - Part I.md @@ -152,16 +152,15 @@ execvp 是系统调用 exec 的一个变体。第一个参数是程序名字。v (还有其他 exec 变体,比如 execv、execvpe、execl、execlp、execlpe;你可以 google 它们获取更多的信息。) +exec 会用即将运行的新进程替换调用进程的当前内存。在我们的例子中,我们的 shell 进程内存会被替换为 `mkdir` 程序。接着,mkdir 成为主进程并创建 test_dir 目录。最后该进程退出。 -exec replaces the current memory of a calling process with a new process to be executed. In our case, our shell process memory was replaced by `mkdir` program. Then, mkdir became the main process and created the test_dir directory. Finally, its process exited. +这里的重点在于我们的 shell 进程已经被 mkdir 进程所替换。这就是我们的 shell 消失且不会等待下一条命令的原因。 -The main point here is that our shell process was replaced by mkdir process already. That’s the reason why our shell disappeared and did not wait for the next command. +因此,我们需要其他的系统调用来解决问题:fork -Therefore, we need another system call to rescue: fork. +fork 会开辟新的内存并拷贝当前进程到一个新的进程。我们称这个新的进程为子进程,调用者进程为父进程。然后,子进程内存会被替换为被执行的程序。因此,我们的 shell,也就是父进程,可以免受内存替换的危险。 -fork will allocate new memory and copy the current process into a new process. We called this new process as child process and the caller process as parent process. Then, the child process memory will be replaced by a execed program. Therefore, our shell, which is a parent process, is safe from memory replacement. - -Let’s see our modified code. +让我们看看已修改的代码。 ``` ... @@ -194,25 +193,25 @@ def execute(cmd_tokens): ... ``` -When the parent process call `os.fork()`, you can imagine that all source code is copied into a new child process. At this point, the parent and child process see the same code and run in parallel. +当我们的父进程调用 `os.fork()`时,你可以想象所有的源代码被拷贝到了新的子进程。此时此刻,父进程和子进程看到的是相同的代码,并且并行运行着。 -If the running code is belong to the child process, pid will be 0. Else, the running code is belong to the parent process, pid will be the process id of the child process. +如果运行的代码属于子进程,pid 将为 0。否则,如果运行的代码属于父进程,pid 将会是子进程的进程 id。 -When os.execvp is invoked in the child process, you can imagine like all the source code of the child process is replaced by the code of a program that is being called. However, the code of the parent process is not changed. +当 os.execvp 在子进程中被调用时,你可以想象子进程的所有源代码被替换为正被调用程序的代码。然而父进程的代码不会被改变。 -When the parent process finishes waiting its child process to exit or be terminated, it returns the status indicating to continue the shell loop. +当父进程完成等待子进程退出或终止时,它会返回一个状态,指示继续 shell 循环。 -### Run +### 运行 -Now, you can try running our shell and enter mkdir test_dir2. It should work properly. Our main shell process is still there and waits for the next command. Try ls and you will see the created directories. +现在,你可以尝试运行我们的 shell 并输入 mkdir test_dir2。它应该可以正确执行。我们的主 shell 进程仍然存在并等待下一条命令。尝试执行 ls,你可以看到已创建的目录。 -However, there are some problems here. +但是,这里仍有许多问题。 -First, try cd test_dir2 and then ls. It’s supposed to enter the directory test_dir2 which is an empty directory. However, you will see that the directory was not changed into test_dir2. +第一,尝试执行 cd test_dir2,接着执行 ls。它应该会进入到一个空的 test_dir2 目录。然而,你将会看到目录没有变为 test_dir2。 -Second, we still have no way to exit from our shell gracefully. +第二,我们仍然没有办法优雅地退出我们的 shell。 -We will continue to solve such problems in [Part 2][1]. +我们将会在 [Part 2][1] 解决诸如此类的问题。 -------------------------------------------------------------------------------- From c544898d9927eb375711356a35cf74c079abe39f Mon Sep 17 00:00:00 2001 From: cposture Date: Wed, 13 Jul 2016 15:03:42 +0800 Subject: [PATCH 008/122] Translated by cposture --- ...reate Your Own Shell in Python - Part I.md | 228 ------------------ ...reate Your Own Shell in Python - Part I.md | 228 ++++++++++++++++++ 2 files changed, 228 insertions(+), 228 deletions(-) delete mode 100644 sources/tech/20160705 Create Your Own Shell in Python - Part I.md create mode 100644 translated/tech/20160705 Create Your Own Shell in Python - Part I.md diff --git a/sources/tech/20160705 Create Your Own Shell in Python - Part I.md b/sources/tech/20160705 Create Your Own Shell in Python - Part I.md deleted file mode 100644 index 74cac3887e..0000000000 --- a/sources/tech/20160705 Create Your Own Shell in Python - Part I.md +++ /dev/null @@ -1,228 +0,0 @@ -使用 Python 创建你自己的 Shell:Part I -========================================== - -我很好奇一个 shell (像 bash,csh 等)内部是如何工作的。为了满足自己的好奇心,我使用 Python 实现了一个名为 yosh (Your Own Shell)的 Shell。本文章所介绍的概念也可以应用于其他编程语言。 - -(提示:你可以发布于此的博文中找到使用的源代码,代码以 MIT 许可发布) - -让我们开始吧。 - -### 步骤 0:项目结构 - -对于此项目,我使用了以下的项目结构。 - -``` -yosh_project -|-- yosh - |-- __init__.py - |-- shell.py -``` - -`yosh_project` 为项目根目录(你也可以把它简单地命名为 `yosh`)。 - -`yosh` 为包目录,并且 `__init__.py` 将会使一个包名等同于包目录名字(如果你不写 Python,可以忽略它) - -`shell.py` 是我们的主脚本文件。 - -### 步骤 1:Shell 循环 - -当你启动一个 shell,它会显示一个命令提示符同时等待用户输入命令。在接收了输入的命令并执行它之后(稍后文章会进行详细解释),你的 shell 会回到循环,等待下一条指令。 - -在 `shell.py`,我们会以一个简单的 mian 函数开始,该函数调用了 shell_loop() 函数,如下: - -``` -def shell_loop(): - # Start the loop here - - -def main(): - shell_loop() - - -if __name__ == "__main__": - main() -``` - -接着,在 `shell_loop()`,为了指示循环是否继续或停止,我们使用了一个状态标志。在循环的开始,我们的 shell 将显示一个命令提示符,并等待读取命令输入。 - -``` -import sys - -SHELL_STATUS_RUN = 1 -SHELL_STATUS_STOP = 0 - - -def shell_loop(): - status = SHELL_STATUS_RUN - - while status == SHELL_STATUS_RUN: - # Display a command prompt - sys.stdout.write('> ') - sys.stdout.flush() - - # Read command input - cmd = sys.stdin.readline() -``` - -之后,我们切分命令输入并进行执行(我们将马上解释命令切分和执行函数)。 - -因此,我们的 shell_loop() 会是如下这样: - -``` -import sys - -SHELL_STATUS_RUN = 1 -SHELL_STATUS_STOP = 0 - - -def shell_loop(): - status = SHELL_STATUS_RUN - - while status == SHELL_STATUS_RUN: - # Display a command prompt - sys.stdout.write('> ') - sys.stdout.flush() - - # Read command input - cmd = sys.stdin.readline() - - # Tokenize the command input - cmd_tokens = tokenize(cmd) - - # Execute the command and retrieve new status - status = execute(cmd_tokens) -``` - -这就是我们整个 shell 循环。如果我们使用 python shell.py 命令启动 shell,它会显示命令提示符。然而如果我们输入命令并按回车,它将会抛出错误,因为我们还没定义命令切分函数。 - -为了退出 shell,可以尝试输入 ctrl-c。稍后我将解释如何以优雅的形式退出 shell。 - -### 步骤 2:命令切分 - -当一个用户在我们的 shell 中输入命令并按下回车键,该命令将会是一个包含命令名称及其参数的很长的字符串。因此,我们必须切分该字符串(分割一个字符串为多个标记)。 - -咋一看似乎很简单。我们或许可以使用 cmd.split(),用空格分割输入。它对类似 `ls -a my_folder` 的命令起作用,因为它能够将命令分割为一个列表 `['ls', '-a', 'my_folder']`,这样我们便能轻易处理它们了。 - -然而,也有一些类似 `echo "Hello World"` 或 `echo 'Hello World'` 以单引号或双引号引用参数的情况。如果我们使用 cmd.spilt,我们将会得到一个存有 3 个标记的列表 `['echo', '"Hello', 'World"']` 而不是 2 个标记 `['echo', 'Hello World']`。 - -幸运的是,Python 提供了一个名为 shlex 的库,能够帮助我们效验如神地分割命令。(提示:我们也可以使用正则表达式,但它不是本文的重点。) - - -``` -import sys -import shlex - -... - -def tokenize(string): - return shlex.split(string) - -... -``` - -然后我们将这些标记发送到执行过程。 - -### 步骤 3:执行 - -这是 shell 中核心和有趣的一部分。当 shell 执行 mkdir test_dir 时,发生了什么?(提示:midir 是一个带有 test_dir 参数的执行程序,用于创建一个名为 test_dir 的目录。) - -execvp 是涉及这一步的首个函数。在我们解释 execvp 所做的事之前,让我们看看它的实际效果。 - -``` -import os -... - -def execute(cmd_tokens): - # Execute command - os.execvp(cmd_tokens[0], cmd_tokens) - - # Return status indicating to wait for next command in shell_loop - return SHELL_STATUS_RUN - -... -``` - -再次尝试运行我们的 shell,并输入 `mkdir test_dir` 命令,接着按下回车键。 - -在我们敲下回车键之后,问题是我们的 shell 会直接退出而不是等待下一个命令。然而,目标正确地被创建。 - -因此,execvp 实际上做了什么? - -execvp 是系统调用 exec 的一个变体。第一个参数是程序名字。v 表示第二个参数是一个程序参数列表(可变参数)。p 表示环境变量 PATH 会被用于搜索给定的程序名字。在我们上一次的尝试中,可以在你的 PATH 环境变量查找到 mkdir 程序。 - -(还有其他 exec 变体,比如 execv、execvpe、execl、execlp、execlpe;你可以 google 它们获取更多的信息。) - -exec 会用即将运行的新进程替换调用进程的当前内存。在我们的例子中,我们的 shell 进程内存会被替换为 `mkdir` 程序。接着,mkdir 成为主进程并创建 test_dir 目录。最后该进程退出。 - -这里的重点在于我们的 shell 进程已经被 mkdir 进程所替换。这就是我们的 shell 消失且不会等待下一条命令的原因。 - -因此,我们需要其他的系统调用来解决问题:fork - -fork 会开辟新的内存并拷贝当前进程到一个新的进程。我们称这个新的进程为子进程,调用者进程为父进程。然后,子进程内存会被替换为被执行的程序。因此,我们的 shell,也就是父进程,可以免受内存替换的危险。 - -让我们看看已修改的代码。 - -``` -... - -def execute(cmd_tokens): - # Fork a child shell process - # If the current process is a child process, its `pid` is set to `0` - # else the current process is a parent process and the value of `pid` - # is the process id of its child process. - pid = os.fork() - - if pid == 0: - # Child process - # Replace the child shell process with the program called with exec - os.execvp(cmd_tokens[0], cmd_tokens) - elif pid > 0: - # Parent process - while True: - # Wait response status from its child process (identified with pid) - wpid, status = os.waitpid(pid, 0) - - # Finish waiting if its child process exits normally - # or is terminated by a signal - if os.WIFEXITED(status) or os.WIFSIGNALED(status): - break - - # Return status indicating to wait for next command in shell_loop - return SHELL_STATUS_RUN - -... -``` - -当我们的父进程调用 `os.fork()`时,你可以想象所有的源代码被拷贝到了新的子进程。此时此刻,父进程和子进程看到的是相同的代码,并且并行运行着。 - -如果运行的代码属于子进程,pid 将为 0。否则,如果运行的代码属于父进程,pid 将会是子进程的进程 id。 - -当 os.execvp 在子进程中被调用时,你可以想象子进程的所有源代码被替换为正被调用程序的代码。然而父进程的代码不会被改变。 - -当父进程完成等待子进程退出或终止时,它会返回一个状态,指示继续 shell 循环。 - -### 运行 - -现在,你可以尝试运行我们的 shell 并输入 mkdir test_dir2。它应该可以正确执行。我们的主 shell 进程仍然存在并等待下一条命令。尝试执行 ls,你可以看到已创建的目录。 - -但是,这里仍有许多问题。 - -第一,尝试执行 cd test_dir2,接着执行 ls。它应该会进入到一个空的 test_dir2 目录。然而,你将会看到目录没有变为 test_dir2。 - -第二,我们仍然没有办法优雅地退出我们的 shell。 - -我们将会在 [Part 2][1] 解决诸如此类的问题。 - - --------------------------------------------------------------------------------- - -via: https://hackercollider.com/articles/2016/07/05/create-your-own-shell-in-python-part-1/ - -作者:[Supasate Choochaisri][a] -译者:[译者ID](https://github.com/译者ID) -校对:[校对者ID](https://github.com/校对者ID) - -本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 - -[a]: https://disqus.com/by/supasate_choochaisri/ -[1]: https://hackercollider.com/articles/2016/07/06/create-your-own-shell-in-python-part-2/ diff --git a/translated/tech/20160705 Create Your Own Shell in Python - Part I.md b/translated/tech/20160705 Create Your Own Shell in Python - Part I.md new file mode 100644 index 0000000000..b54d0bff29 --- /dev/null +++ b/translated/tech/20160705 Create Your Own Shell in Python - Part I.md @@ -0,0 +1,228 @@ +使用 Python 创建你自己的 Shell:Part I +========================================== + +我很想知道一个 shell (像 bash,csh 等)内部是如何工作的。为了满足自己的好奇心,我使用 Python 实现了一个名为 **yosh** (Your Own Shell)的 Shell。本文章所介绍的概念也可以应用于其他编程语言。 + +(提示:你可以在[这里](https://github.com/supasate/yosh)查找本博文使用的源代码,代码以 MIT 许可证发布。在 Mac OS X 10.11.5 上,我使用 Python 2.7.10 和 3.4.3 进行了测试。它应该可以运行在其他类 Unix 环境,比如 Linux 和 Windows 上的 Cygwin。) + +让我们开始吧。 + +### 步骤 0:项目结构 + +对于此项目,我使用了以下的项目结构。 + +``` +yosh_project +|-- yosh + |-- __init__.py + |-- shell.py +``` + +`yosh_project` 为项目根目录(你也可以把它简单命名为 `yosh`)。 + +`yosh` 为包目录,且 `__init__.py` 可以使它成为与包目录名字相同的包(如果你不写 Python,可以忽略它。) + +`shell.py` 是我们主要的脚本文件。 + +### 步骤 1:Shell 循环 + +当启动一个 shell,它会显示一个命令提示符并等待你的命令输入。在接收了输入的命令并执行它之后(稍后文章会进行详细解释),你的 shell 会重新回到循环,等待下一条指令。 + +在 `shell.py`,我们会以一个简单的 mian 函数开始,该函数调用了 shell_loop() 函数,如下: + +``` +def shell_loop(): + # Start the loop here + + +def main(): + shell_loop() + + +if __name__ == "__main__": + main() +``` + +接着,在 `shell_loop()`,为了指示循环是否继续或停止,我们使用了一个状态标志。在循环的开始,我们的 shell 将显示一个命令提示符,并等待读取命令输入。 + +``` +import sys + +SHELL_STATUS_RUN = 1 +SHELL_STATUS_STOP = 0 + + +def shell_loop(): + status = SHELL_STATUS_RUN + + while status == SHELL_STATUS_RUN: + # Display a command prompt + sys.stdout.write('> ') + sys.stdout.flush() + + # Read command input + cmd = sys.stdin.readline() +``` + +之后,我们切分命令输入并进行执行(我们即将实现`命令切分`和`执行`函数)。 + +因此,我们的 shell_loop() 会是如下这样: + +``` +import sys + +SHELL_STATUS_RUN = 1 +SHELL_STATUS_STOP = 0 + + +def shell_loop(): + status = SHELL_STATUS_RUN + + while status == SHELL_STATUS_RUN: + # Display a command prompt + sys.stdout.write('> ') + sys.stdout.flush() + + # Read command input + cmd = sys.stdin.readline() + + # Tokenize the command input + cmd_tokens = tokenize(cmd) + + # Execute the command and retrieve new status + status = execute(cmd_tokens) +``` + +这就是我们整个 shell 循环。如果我们使用 `python shell.py` 启动我们的 shell,它会显示命令提示符。然而如果我们输入命令并按回车,它会抛出错误,因为我们还没定义`命令切分`函数。 + +为了退出 shell,可以尝试输入 ctrl-c。稍后我将解释如何以优雅的形式退出 shell。 + +### 步骤 2:命令切分 + +当用户在我们的 shell 中输入命令并按下回车键,该命令将会是一个包含命令名称及其参数的很长的字符串。因此,我们必须切分该字符串(分割一个字符串为多个标记)。 + +咋一看似乎很简单。我们或许可以使用 `cmd.split()`,以空格分割输入。它对类似 `ls -a my_folder` 的命令起作用,因为它能够将命令分割为一个列表 `['ls', '-a', 'my_folder']`,这样我们便能轻易处理它们了。 + +然而,也有一些类似 `echo "Hello World"` 或 `echo 'Hello World'` 以单引号或双引号引用参数的情况。如果我们使用 cmd.spilt,我们将会得到一个存有 3 个标记的列表 `['echo', '"Hello', 'World"']` 而不是 2 个标记的列表 `['echo', 'Hello World']`。 + +幸运的是,Python 提供了一个名为 `shlex` 的库,它能够帮助我们效验如神地分割命令。(提示:我们也可以使用正则表达式,但它不是本文的重点。) + + +``` +import sys +import shlex + +... + +def tokenize(string): + return shlex.split(string) + +... +``` + +然后我们将这些标记发送到执行进程。 + +### 步骤 3:执行 + +这是 shell 中核心和有趣的一部分。当 shell 执行 `mkdir test_dir` 时,到底发生了什么?(提示: `mkdir` 是一个带有 `test_dir` 参数的执行程序,用于创建一个名为 `test_dir` 的目录。) + +`execvp` 是涉及这一步的首个函数。在我们解释 `execvp` 所做的事之前,让我们看看它的实际效果。 + +``` +import os +... + +def execute(cmd_tokens): + # Execute command + os.execvp(cmd_tokens[0], cmd_tokens) + + # Return status indicating to wait for next command in shell_loop + return SHELL_STATUS_RUN + +... +``` + +再次尝试运行我们的 shell,并输入 `mkdir test_dir` 命令,接着按下回车键。 + +在我们敲下回车键之后,问题是我们的 shell 会直接退出而不是等待下一个命令。然而,目标正确地被创建。 + +因此,`execvp` 实际上做了什么? + +`execvp` 是系统调用 `exec` 的一个变体。第一个参数是程序名字。`v` 表示第二个参数是一个程序参数列表(可变参数)。`p` 表示环境变量 `PATH` 会被用于搜索给定的程序名字。在我们上一次的尝试中,它将会基于我们的 `PATH` 环境变量查找`mkdir` 程序。 + +(还有其他 `exec` 变体,比如 execv、execvpe、execl、execlp、execlpe;你可以 google 它们获取更多的信息。) + +`exec` 会用即将运行的新进程替换调用进程的当前内存。在我们的例子中,我们的 shell 进程内存会被替换为 `mkdir` 程序。接着,`mkdir` 成为主进程并创建 `test_dir` 目录。最后该进程退出。 + +这里的重点在于**我们的 shell 进程已经被 `mkdir` 进程所替换**。这就是我们的 shell 消失且不会等待下一条命令的原因。 + +因此,我们需要其他的系统调用来解决问题:`fork`。 + +`fork` 会开辟新的内存并拷贝当前进程到一个新的进程。我们称这个新的进程为**子进程**,调用者进程为**父进程**。然后,子进程内存会被替换为被执行的程序。因此,我们的 shell,也就是父进程,可以免受内存替换的危险。 + +让我们看看修改的代码。 + +``` +... + +def execute(cmd_tokens): + # Fork a child shell process + # If the current process is a child process, its `pid` is set to `0` + # else the current process is a parent process and the value of `pid` + # is the process id of its child process. + pid = os.fork() + + if pid == 0: + # Child process + # Replace the child shell process with the program called with exec + os.execvp(cmd_tokens[0], cmd_tokens) + elif pid > 0: + # Parent process + while True: + # Wait response status from its child process (identified with pid) + wpid, status = os.waitpid(pid, 0) + + # Finish waiting if its child process exits normally + # or is terminated by a signal + if os.WIFEXITED(status) or os.WIFSIGNALED(status): + break + + # Return status indicating to wait for next command in shell_loop + return SHELL_STATUS_RUN + +... +``` + +当我们的父进程调用 `os.fork()`时,你可以想象所有的源代码被拷贝到了新的子进程。此时此刻,父进程和子进程看到的是相同的代码,且并行运行着。 + +如果运行的代码属于子进程,`pid` 将为 `0`。否则,如果运行的代码属于父进程,`pid` 将会是子进程的进程 id。 + +当 `os.execvp` 在子进程中被调用时,你可以想象子进程的所有源代码被替换为正被调用程序的代码。然而父进程的代码不会被改变。 + +当父进程完成等待子进程退出或终止时,它会返回一个状态,指示继续 shell 循环。 + +### 运行 + +现在,你可以尝试运行我们的 shell 并输入 `mkdir test_dir2`。它应该可以正确执行。我们的主 shell 进程仍然存在并等待下一条命令。尝试执行 `ls`,你可以看到已创建的目录。 + +但是,这里仍有许多问题。 + +第一,尝试执行 `cd test_dir2`,接着执行 `ls`。它应该会进入到一个空的 `test_dir2` 目录。然而,你将会看到目录并没有变为 `test_dir2`。 + +第二,我们仍然没有办法优雅地退出我们的 shell。 + +我们将会在 [Part 2][1] 解决诸如此类的问题。 + + +-------------------------------------------------------------------------------- + +via: https://hackercollider.com/articles/2016/07/05/create-your-own-shell-in-python-part-1/ + +作者:[Supasate Choochaisri][a] +译者:[译者ID](https://github.com/译者ID) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]: https://disqus.com/by/supasate_choochaisri/ +[1]: https://hackercollider.com/articles/2016/07/06/create-your-own-shell-in-python-part-2/ From 1477657f553de2d5556e165483d110908eebde5d Mon Sep 17 00:00:00 2001 From: cposture Date: Wed, 13 Jul 2016 22:56:30 +0800 Subject: [PATCH 009/122] Translating by cposture --- sources/tech/20160309 Let’s Build A Web Server. Part 1.md | 1 + sources/tech/20160406 Let’s Build A Web Server. Part 2.md | 1 + 2 files changed, 2 insertions(+) diff --git a/sources/tech/20160309 Let’s Build A Web Server. Part 1.md b/sources/tech/20160309 Let’s Build A Web Server. Part 1.md index 4c8048786d..47f8bfdcc7 100644 --- a/sources/tech/20160309 Let’s Build A Web Server. Part 1.md +++ b/sources/tech/20160309 Let’s Build A Web Server. Part 1.md @@ -1,3 +1,4 @@ +Translating by cposture 2016.07.13 Let’s Build A Web Server. Part 1. ===================================== diff --git a/sources/tech/20160406 Let’s Build A Web Server. Part 2.md b/sources/tech/20160406 Let’s Build A Web Server. Part 2.md index 482352ac9a..5cba11dd64 100644 --- a/sources/tech/20160406 Let’s Build A Web Server. Part 2.md +++ b/sources/tech/20160406 Let’s Build A Web Server. Part 2.md @@ -1,3 +1,4 @@ +Translating by cposture 2016.07.13 Let’s Build A Web Server. Part 2. =================================== From 2f19bee95fd0bb828463f0f331636d2809b4fc1e Mon Sep 17 00:00:00 2001 From: cposture Date: Fri, 15 Jul 2016 14:11:18 +0800 Subject: [PATCH 010/122] Translating partly 50 --- ...eate Your Own Shell in Python - Part II.md | 38 +++++++++---------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/sources/tech/20160706 Create Your Own Shell in Python - Part II.md b/sources/tech/20160706 Create Your Own Shell in Python - Part II.md index 3154839443..2733288475 100644 --- a/sources/tech/20160706 Create Your Own Shell in Python - Part II.md +++ b/sources/tech/20160706 Create Your Own Shell in Python - Part II.md @@ -1,26 +1,25 @@ -Translating by cposture 2016.07.09 -Create Your Own Shell in Python - Part II +使用 Python 创建你自己的 Shell:Part II =========================================== -In [part 1][1], we already created a main shell loop, tokenized command input, and executed a command by fork and exec. In this part, we will solve the remaining problmes. First, `cd test_dir2` does not change our current directory. Second, we still have no way to exit from our shell gracefully. +在[part 1][1],我们已经创建了一个主要的 shell 循环、切分了的命令输入,以及通过 fork 和 exec 执行命令。在这部分,我们将会解决剩下的问题。首先,`cd test_dir2` 命令无法修改我们的当前目录。其次,我们仍无法优雅地从 shell 中退出。 -### Step 4: Built-in Commands +### 步骤 4:内置命令 -The statement “cd test_dir2 does not change our current directory” is true and false in some senses. It’s true in the sense that after executing the command, we are still at the same directory. However, the directory is actullay changed, but, it’s changed in the child process. +“cd test_dir2 无法修改我们的当前目录” 这句话是对的,但在某种意义上也是错的。在执行完该命令之后,我们仍然处在同一目录,从这个意义上讲,它是对的。然而,目录实际上已经被修改,只不过它是在子进程中被修改。 -Remember that we fork a child process, then, exec the command which does not happen on a parent process. The result is we just change the current directory of a child process, not the directory of a parent process. +还记得我们 fork 了一个子进程,然后执行命令,执行命令的过程没有发生在父进程上。结果是我们只是改变了子进程的当前目录,而不是父进程的目录。 -Then, the child process exits, and the parent process continues with the same intact directory. +然后子进程退出,且父进程在原封不动的目录下继续运行。 -Therefore, this kind of commands must be built-in with the shell itself. It must be executed in the shell process without forking. +因此,这类与 shell 自己相关的命令必须是内置命令。它必须在 shell 进程中执行而没有分叉(forking)。 #### cd -Let’s start with cd command. +让我们从 cd 命令开始。 -We first create a builtins directory. Each built-in command will be put inside this directory. +我们首先创建一个内置目录。每一个内置命令都会被放进这个目录中。 -``` +```shell yosh_project |-- yosh |-- builtins @@ -30,9 +29,9 @@ yosh_project |-- shell.py ``` -In cd.py, we implement our own cd command by using a system call os.chdir. +在 cd.py,我们通过使用系统调用 os.chdir 实现自己的 cd 命令。 -``` +```python import os from yosh.constants import * @@ -43,9 +42,9 @@ def cd(args): return SHELL_STATUS_RUN ``` -Notice that we return shell running status from a built-in function. Therefore, we move constants into yosh/constants.py to be used across the project. +注意,我们会从内置函数返回 shell 的运行状态。所以,为了能够在项目中继续使用常量,我们将它们移至 yosh/constants.py。 -``` +```shell yosh_project |-- yosh |-- builtins @@ -56,16 +55,16 @@ yosh_project |-- shell.py ``` -In constants.py, we put shell status constants here. +在 constants.py,我们将状态常量放在这里。 -``` +```python SHELL_STATUS_STOP = 0 SHELL_STATUS_RUN = 1 ``` -Now, our built-in cd is ready. Let’s modify our shell.py to handle built-in functions. +现在,我们的内置 cd 已经准备好了。让我们修改 shell.py 来处理这些内置函数。 -``` +```python ... # Import constants from yosh.constants import * @@ -90,6 +89,7 @@ def execute(cmd_tokens): ... ``` +我们使用一个 python 字典变量 built_in_cmds 作为哈希映射(a hash map),以存储我们的内置函数。在 execute 函数,我们提取命令的名字和参数。如果该命令在我们的哈希映射中,则调用对应的内置函数。 We use a Python dictionary built_in_cmds as a hash map to store our built-in functions. In execute function, we extract command name and arguments. If the command name is in our hash map, we call that built-in function. (Note: built_in_cmds[cmd_name] returns the function reference that can be invoked with arguments immediately.) From 31a898b314bc71e8638a55df2e9f9822d9008d2f Mon Sep 17 00:00:00 2001 From: cposture Date: Sat, 16 Jul 2016 00:02:06 +0800 Subject: [PATCH 011/122] Translting partly 70 --- .../20160706 Create Your Own Shell in Python - Part II.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sources/tech/20160706 Create Your Own Shell in Python - Part II.md b/sources/tech/20160706 Create Your Own Shell in Python - Part II.md index 2733288475..26f0625368 100644 --- a/sources/tech/20160706 Create Your Own Shell in Python - Part II.md +++ b/sources/tech/20160706 Create Your Own Shell in Python - Part II.md @@ -89,12 +89,11 @@ def execute(cmd_tokens): ... ``` -我们使用一个 python 字典变量 built_in_cmds 作为哈希映射(a hash map),以存储我们的内置函数。在 execute 函数,我们提取命令的名字和参数。如果该命令在我们的哈希映射中,则调用对应的内置函数。 -We use a Python dictionary built_in_cmds as a hash map to store our built-in functions. In execute function, we extract command name and arguments. If the command name is in our hash map, we call that built-in function. +我们使用一个 python 字典变量 built_in_cmds 作为哈希映射(a hash map),以存储我们的内置函数。我们在 execute 函数中提取命令的名字和参数。如果该命令在我们的哈希映射中,则调用对应的内置函数。 -(Note: built_in_cmds[cmd_name] returns the function reference that can be invoked with arguments immediately.) +(提示:built_in_cmds[cmd_name] 返回能直接使用参数调用的函数引用的。) -We are almost ready to use the built-in cd function. The last thing is to add cd function into the built_in_cmds map. +我们差不多准备好使用内置的 cd 函数了。最后一步是将 cd 函数添加到 built_in_cmds 映射中。 ``` ... @@ -119,6 +118,7 @@ def main(): shell_loop() ``` +我们定义 register_command 函数以添加一个内置函数到我们内置的命令哈希映射。 We define register_command function for adding a built-in function to our built-in commmand hash map. Then, we define init function and register the built-in cd function there. Notice the line register_command("cd", cd). The first argument is a command name. The second argument is a reference to a function. In order to let cd, in the second argument, refer to the cd function reference in yosh/builtins/cd.py, we have to put the following line in yosh/builtins/__init__.py. From 0eeb6216837084d151202801bc689acfc4f691c8 Mon Sep 17 00:00:00 2001 From: cposture Date: Sat, 16 Jul 2016 01:04:01 +0800 Subject: [PATCH 012/122] Translating partly 75:wq --- ...20160706 Create Your Own Shell in Python - Part II.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/sources/tech/20160706 Create Your Own Shell in Python - Part II.md b/sources/tech/20160706 Create Your Own Shell in Python - Part II.md index 26f0625368..934011e0cf 100644 --- a/sources/tech/20160706 Create Your Own Shell in Python - Part II.md +++ b/sources/tech/20160706 Create Your Own Shell in Python - Part II.md @@ -118,16 +118,19 @@ def main(): shell_loop() ``` -我们定义 register_command 函数以添加一个内置函数到我们内置的命令哈希映射。 -We define register_command function for adding a built-in function to our built-in commmand hash map. Then, we define init function and register the built-in cd function there. +我们定义 register_command 函数以添加一个内置函数到我们内置的命令哈希映射。接着,我们定义 init 函数并且在这里注册内置的 cd 函数。 -Notice the line register_command("cd", cd). The first argument is a command name. The second argument is a reference to a function. In order to let cd, in the second argument, refer to the cd function reference in yosh/builtins/cd.py, we have to put the following line in yosh/builtins/__init__.py. +注意这行 register_command("cd", cd) 。第一个参数为命令的名字。第二个参数为一个函数引用。为了能够让第二个参数 cd 引用到 yosh/builtins/cd.py 中的cd 函数引用,我们必须将以下这行代码放在 yosh/builtins/__init__.py 文件中。 ``` from yosh.builtins.cd import * ``` + +因此,在 yosh/shell.py 中,当我们从 yosh.builtins 导入 * 时,我们可以得到已经通过 yosh.builtins +被导入的 cd 函数引用。 Therefore, in yosh/shell.py, when we import * from yosh.builtins, we get cd function reference that is already imported by yosh.builtins. +我们已经准备好了代码。 We’ve done preparing our code. Let’s try by running our shell as a module python -m yosh.shell at the same level as the yosh directory. Now, our cd command should change our shell directory correctly while non-built-in commands still work too. Cool. From 89d9ed97814565e48fc03badce1090df909a1b82 Mon Sep 17 00:00:00 2001 From: cposture Date: Sat, 16 Jul 2016 11:03:10 +0800 Subject: [PATCH 013/122] Translated by cposture --- ...eate Your Own Shell in Python - Part II.md | 63 +++++++++---------- 1 file changed, 30 insertions(+), 33 deletions(-) diff --git a/sources/tech/20160706 Create Your Own Shell in Python - Part II.md b/sources/tech/20160706 Create Your Own Shell in Python - Part II.md index 934011e0cf..0f0cd6a878 100644 --- a/sources/tech/20160706 Create Your Own Shell in Python - Part II.md +++ b/sources/tech/20160706 Create Your Own Shell in Python - Part II.md @@ -1,7 +1,7 @@ 使用 Python 创建你自己的 Shell:Part II =========================================== -在[part 1][1],我们已经创建了一个主要的 shell 循环、切分了的命令输入,以及通过 fork 和 exec 执行命令。在这部分,我们将会解决剩下的问题。首先,`cd test_dir2` 命令无法修改我们的当前目录。其次,我们仍无法优雅地从 shell 中退出。 +在[part 1][1] 中,我们已经创建了一个主要的 shell 循环、切分了的命令输入,以及通过 `fork` 和 `exec` 执行命令。在这部分,我们将会解决剩下的问题。首先,`cd test_dir2` 命令无法修改我们的当前目录。其次,我们仍无法优雅地从 shell 中退出。 ### 步骤 4:内置命令 @@ -9,15 +9,15 @@ 还记得我们 fork 了一个子进程,然后执行命令,执行命令的过程没有发生在父进程上。结果是我们只是改变了子进程的当前目录,而不是父进程的目录。 -然后子进程退出,且父进程在原封不动的目录下继续运行。 +然后子进程退出,而父进程在原封不动的目录下继续运行。 因此,这类与 shell 自己相关的命令必须是内置命令。它必须在 shell 进程中执行而没有分叉(forking)。 #### cd -让我们从 cd 命令开始。 +让我们从 `cd` 命令开始。 -我们首先创建一个内置目录。每一个内置命令都会被放进这个目录中。 +我们首先创建一个 `builtins` 目录。每一个内置命令都会被放进这个目录中。 ```shell yosh_project @@ -29,7 +29,7 @@ yosh_project |-- shell.py ``` -在 cd.py,我们通过使用系统调用 os.chdir 实现自己的 cd 命令。 +在 `cd.py` 中,我们通过使用系统调用 `os.chdir` 实现自己的 `cd` 命令。 ```python import os @@ -42,7 +42,7 @@ def cd(args): return SHELL_STATUS_RUN ``` -注意,我们会从内置函数返回 shell 的运行状态。所以,为了能够在项目中继续使用常量,我们将它们移至 yosh/constants.py。 +注意,我们会从内置函数返回 shell 的运行状态。所以,为了能够在项目中继续使用常量,我们将它们移至 `yosh/constants.py`。 ```shell yosh_project @@ -55,14 +55,14 @@ yosh_project |-- shell.py ``` -在 constants.py,我们将状态常量放在这里。 +在 `constants.py` 中,我们将状态常量都放在这里。 ```python SHELL_STATUS_STOP = 0 SHELL_STATUS_RUN = 1 ``` -现在,我们的内置 cd 已经准备好了。让我们修改 shell.py 来处理这些内置函数。 +现在,我们的内置 `cd` 已经准备好了。让我们修改 `shell.py` 来处理这些内置函数。 ```python ... @@ -89,11 +89,11 @@ def execute(cmd_tokens): ... ``` -我们使用一个 python 字典变量 built_in_cmds 作为哈希映射(a hash map),以存储我们的内置函数。我们在 execute 函数中提取命令的名字和参数。如果该命令在我们的哈希映射中,则调用对应的内置函数。 +我们使用一个 python 字典变量 `built_in_cmds` 作为哈希映射(hash map),以存储我们的内置函数。我们在 `execute` 函数中提取命令的名字和参数。如果该命令在我们的哈希映射中,则调用对应的内置函数。 -(提示:built_in_cmds[cmd_name] 返回能直接使用参数调用的函数引用的。) +(提示:`built_in_cmds[cmd_name]` 返回能直接使用参数调用的函数引用的。) -我们差不多准备好使用内置的 cd 函数了。最后一步是将 cd 函数添加到 built_in_cmds 映射中。 +我们差不多准备好使用内置的 `cd` 函数了。最后一步是将 `cd` 函数添加到 `built_in_cmds` 映射中。 ``` ... @@ -118,32 +118,29 @@ def main(): shell_loop() ``` -我们定义 register_command 函数以添加一个内置函数到我们内置的命令哈希映射。接着,我们定义 init 函数并且在这里注册内置的 cd 函数。 +我们定义了 `register_command` 函数,以添加一个内置函数到我们内置的命令哈希映射。接着,我们定义 `init` 函数并且在这里注册内置的 `cd` 函数。 -注意这行 register_command("cd", cd) 。第一个参数为命令的名字。第二个参数为一个函数引用。为了能够让第二个参数 cd 引用到 yosh/builtins/cd.py 中的cd 函数引用,我们必须将以下这行代码放在 yosh/builtins/__init__.py 文件中。 +注意这行 `register_command("cd", cd)` 。第一个参数为命令的名字。第二个参数为一个函数引用。为了能够让第二个参数 `cd` 引用到 `yosh/builtins/cd.py` 中的 `cd` 函数引用,我们必须将以下这行代码放在 `yosh/builtins/__init__.py` 文件中。 ``` from yosh.builtins.cd import * ``` -因此,在 yosh/shell.py 中,当我们从 yosh.builtins 导入 * 时,我们可以得到已经通过 yosh.builtins -被导入的 cd 函数引用。 -Therefore, in yosh/shell.py, when we import * from yosh.builtins, we get cd function reference that is already imported by yosh.builtins. +因此,在 `yosh/shell.py` 中,当我们从 `yosh.builtins` 导入 `*` 时,我们可以得到已经通过 `yosh.builtins` 导入的 `cd` 函数引用。 -我们已经准备好了代码。 -We’ve done preparing our code. Let’s try by running our shell as a module python -m yosh.shell at the same level as the yosh directory. +我们已经准备好了代码。让我们尝试在 `yosh` 同级目录下以模块形式运行我们的 shell,`python -m yosh.shell`。 -Now, our cd command should change our shell directory correctly while non-built-in commands still work too. Cool. +现在,`cd` 命令可以正确修改我们的 shell 目录了,同时非内置命令仍然可以工作。非常好! #### exit -Here comes the last piece: to exit gracefully. +最后一块终于来了:优雅地退出。 -We need a function that changes the shell status to be SHELL_STATUS_STOP. So, the shell loop will naturally break and the shell program will end and exit. +我们需要一个可以修改 shell 状态为 `SHELL_STATUS_STOP` 的函数。这样,shell 循环可以自然地结束,shell 将到达终点而退出。 -As same as cd, if we fork and exec exit in a child process, the parent process will still remain inact. Therefore, the exit function is needed to be a shell built-in function. +和 `cd` 一样,如果我们在子进程中 fork 和执行 `exit` 函数,其对父进程是不起作用的。因此,`exit` 函数需要成为一个 shell 内置函数。 -Let’s start by creating a new file called exit.py in the builtins folder. +让我们从这开始:在 `builtins` 目录下创建一个名为 `exit.py` 的新文件。 ``` yosh_project @@ -157,7 +154,7 @@ yosh_project |-- shell.py ``` -The exit.py defines the exit function that just returns the status to break the main loop. +`exit.py` 定义了一个 `exit` 函数,该函数仅仅返回一个可以退出主循环的状态。 ``` from yosh.constants import * @@ -167,14 +164,14 @@ def exit(args): return SHELL_STATUS_STOP ``` -Then, we import the exit function reference in `yosh/builtins/__init__.py`. +然后,我们导入位于 `yosh/builtins/__init__.py` 文件的 `exit` 函数引用。 ``` from yosh.builtins.cd import * from yosh.builtins.exit import * ``` -Finally, in shell.py, we register the exit command in `init()` function. +最后,我们在 `shell.py` 中的 `init()` 函数注册 `exit` 命令。 ``` @@ -188,17 +185,17 @@ def init(): ... ``` -That’s all! +到此为止! -Try running python -m yosh.shell. Now you can enter exit to quit the program gracefully. +尝试执行 `python -m yosh.shell`。现在你可以输入 `exit` 优雅地退出程序了。 -### Final Thought +### 最后的想法 -I hope you enjoy creating yosh (your own shell) like I do. However, my version of yosh is still in an early stage. I don’t handle several corner cases that can corrupt the shell. There are a lot of built-in commands that I don’t cover. Some non-built-in commands can also be implemented as built-in commands to improve performance (avoid new process creation time). And, a ton of features are not yet implemented (see Common features and Differing features). +我希望你能像我一样享受创建 `yosh` (**y**our **o**wn **sh**ell)的过程。但我的 `yosh` 版本仍处于早期阶段。我没有处理一些会使 shell 崩溃的极端状况。还有很多我没有覆盖的内置命令。为了提高性能,一些非内置命令也可以实现为内置命令(避免新进程创建时间)。同时,大量的功能还没有实现(请看 [公共特性](http://tldp.org/LDP/Bash-Beginners-Guide/html/x7243.html) 和 [不同特性](http://www.tldp.org/LDP/intro-linux/html/x12249.html)) -I’ve provided the source code at github.com/supasate/yosh. Feel free to fork and play around. +我已经在 github.com/supasate/yosh 中提供了源代码。请随意 fork 和尝试。 -Now, it’s your turn to make it real Your Own SHell. +现在该是创建你真正自己拥有的 Shell 的时候了。 Happy Coding! @@ -207,7 +204,7 @@ Happy Coding! via: https://hackercollider.com/articles/2016/07/06/create-your-own-shell-in-python-part-2/ 作者:[Supasate Choochaisri][a] -译者:[译者ID](https://github.com/译者ID) +译者:[cposture](https://github.com/cposture) 校对:[校对者ID](https://github.com/校对者ID) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 From fc7e5a6dec6dea4bc018f29beaca8e944f4594c1 Mon Sep 17 00:00:00 2001 From: cposture Date: Sat, 16 Jul 2016 11:04:29 +0800 Subject: [PATCH 014/122] Translated by cposture --- .../tech/20160706 Create Your Own Shell in Python - Part II.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename {sources => translated}/tech/20160706 Create Your Own Shell in Python - Part II.md (100%) diff --git a/sources/tech/20160706 Create Your Own Shell in Python - Part II.md b/translated/tech/20160706 Create Your Own Shell in Python - Part II.md similarity index 100% rename from sources/tech/20160706 Create Your Own Shell in Python - Part II.md rename to translated/tech/20160706 Create Your Own Shell in Python - Part II.md From bf4f2549256f9facb25f9cb6d8fd8a2a1039dcfd Mon Sep 17 00:00:00 2001 From: cposture Date: Sun, 17 Jul 2016 09:03:58 +0800 Subject: [PATCH 015/122] =?UTF-8?q?=E7=BD=91=E4=B8=8A=E5=B7=B2=E6=9C=89?= =?UTF-8?q?=E7=BF=BB=E8=AF=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sources/tech/20160309 Let’s Build A Web Server. Part 1.md | 1 - sources/tech/20160406 Let’s Build A Web Server. Part 2.md | 1 - 2 files changed, 2 deletions(-) diff --git a/sources/tech/20160309 Let’s Build A Web Server. Part 1.md b/sources/tech/20160309 Let’s Build A Web Server. Part 1.md index 47f8bfdcc7..4c8048786d 100644 --- a/sources/tech/20160309 Let’s Build A Web Server. Part 1.md +++ b/sources/tech/20160309 Let’s Build A Web Server. Part 1.md @@ -1,4 +1,3 @@ -Translating by cposture 2016.07.13 Let’s Build A Web Server. Part 1. ===================================== diff --git a/sources/tech/20160406 Let’s Build A Web Server. Part 2.md b/sources/tech/20160406 Let’s Build A Web Server. Part 2.md index 5cba11dd64..482352ac9a 100644 --- a/sources/tech/20160406 Let’s Build A Web Server. Part 2.md +++ b/sources/tech/20160406 Let’s Build A Web Server. Part 2.md @@ -1,4 +1,3 @@ -Translating by cposture 2016.07.13 Let’s Build A Web Server. Part 2. =================================== From 905d6d43298bf7e2392a5a9c80f743ec426a58e5 Mon Sep 17 00:00:00 2001 From: cvsher <478990879@qq.com> Date: Mon, 18 Jul 2016 10:28:16 +0800 Subject: [PATCH 016/122] Update 20160706 What is Git.md translating --- sources/tech/20160706 What is Git.md | 1 + 1 file changed, 1 insertion(+) diff --git a/sources/tech/20160706 What is Git.md b/sources/tech/20160706 What is Git.md index 5726bce405..f98de42fd3 100644 --- a/sources/tech/20160706 What is Git.md +++ b/sources/tech/20160706 What is Git.md @@ -1,3 +1,4 @@ +translating by cvsher What is Git =========== From a9862bebe083e1006bbd4894f8404116a4baf120 Mon Sep 17 00:00:00 2001 From: Ezio Date: Mon, 25 Jul 2016 13:54:47 +0800 Subject: [PATCH 017/122] =?UTF-8?q?=E7=BF=BB=E8=AF=91=E4=B8=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sources/tech/20160628 Python 101 An Intro to urllib.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sources/tech/20160628 Python 101 An Intro to urllib.md b/sources/tech/20160628 Python 101 An Intro to urllib.md index 38620bf17b..3fb88971db 100644 --- a/sources/tech/20160628 Python 101 An Intro to urllib.md +++ b/sources/tech/20160628 Python 101 An Intro to urllib.md @@ -1,3 +1,5 @@ +ezio is translating + Python 101: An Intro to urllib ================================= From 67e14806563e377a942dac330be9692b9e9c7713 Mon Sep 17 00:00:00 2001 From: Locez Date: Mon, 25 Jul 2016 00:59:28 -0500 Subject: [PATCH 018/122] translating by locez --- .../20160722 HOW TO CHANGE DEFAULT APPLICATIONS IN UBUNTU.md | 1 + 1 file changed, 1 insertion(+) diff --git a/sources/tech/20160722 HOW TO CHANGE DEFAULT APPLICATIONS IN UBUNTU.md b/sources/tech/20160722 HOW TO CHANGE DEFAULT APPLICATIONS IN UBUNTU.md index 37692dfd7b..1b4c576d1b 100644 --- a/sources/tech/20160722 HOW TO CHANGE DEFAULT APPLICATIONS IN UBUNTU.md +++ b/sources/tech/20160722 HOW TO CHANGE DEFAULT APPLICATIONS IN UBUNTU.md @@ -1,3 +1,4 @@ +translating by Locez HOW TO CHANGE DEFAULT APPLICATIONS IN UBUNTU ============================================== From 180ba8b6386a1601e05c8d2ed6cb8395689a330d Mon Sep 17 00:00:00 2001 From: Locez Date: Mon, 25 Jul 2016 15:12:08 +0800 Subject: [PATCH 019/122] translated --- ...O CHANGE DEFAULT APPLICATIONS IN UBUNTU.md | 51 +++++++++---------- 1 file changed, 25 insertions(+), 26 deletions(-) diff --git a/sources/tech/20160722 HOW TO CHANGE DEFAULT APPLICATIONS IN UBUNTU.md b/sources/tech/20160722 HOW TO CHANGE DEFAULT APPLICATIONS IN UBUNTU.md index 1b4c576d1b..b6c9ae0cf7 100644 --- a/sources/tech/20160722 HOW TO CHANGE DEFAULT APPLICATIONS IN UBUNTU.md +++ b/sources/tech/20160722 HOW TO CHANGE DEFAULT APPLICATIONS IN UBUNTU.md @@ -1,64 +1,63 @@ -translating by Locez -HOW TO CHANGE DEFAULT APPLICATIONS IN UBUNTU +怎样在 UBUNTU 中修改默认程序 ============================================== ![](https://itsfoss.com/wp-content/uploads/2016/07/change-default-applications-ubuntu.jpg) -Brief: This beginners guide shows you how to change the default applications in Ubuntu Linux. +简介: 这个新手指南会向你展示如何在 Ubuntu Linux 中修改默认程序 -Installing [VLC media player][1] is one of the first few [things to do after installing Ubuntu 16.04][2] for me. One thing I do after installing VLC is to make it the default application so that I can open video file with VLC when I double click it. +对于我来说,安装 [VLC 多媒体播放器][1]是[安装完 Ubuntu 16.04 该做的事][2]中最先做的几件事之一。为了能够使我双击一个视频就用 VLC 打开,在我安装完 VLC 之后我会设置它为默认程序。 -As a beginner, you may need to know how to change any default application in Ubuntu and this is what I am going to show you in today’s tutorial. +作为一个新手,你需要知道如何在 Ubuntu 中修改任何默认程序,这也是我今天在这篇指南中所要讲的。 -### CHANGE DEFAULT APPLICATIONS IN UBUNTU +### 在 UBUNTU 中修改默认程序 +这里提及的方法适用于所有的 Ubuntu 12.04,Ubuntu 14.04 和Ubuntu 16.04。在 Ubuntu 中,这里有两种基本的方法可以修改默认程序: -The methods mentioned here are valid for all versions of Ubuntu be it Ubuntu 12.04, Ubuntu 14.04 or Ubuntu 16.04. There are basically two ways you can change the default applications in Ubuntu: +- 通过系统设置 +- 通过右键菜单 -- via system settings -- via right click menu +#### 1.通过系统设置修改 Ubuntu 的默认程序 -#### 1. CHANGE DEFAULT APPLICATIONS IN UBUNTU FROM SYSTEM SETTINGS - -Go to Unity Dash and search for System Settings: +进入 Unity 面板并且搜索系统设置(System Settings): ![](https://itsfoss.com/wp-content/uploads/2013/11/System_Settings_Ubuntu.jpeg) -In the System Settings, click on the Details option: +在系统设置(System Settings)中,选择详细选项(Details): ![](https://itsfoss.com/wp-content/uploads/2016/07/System-settings-detail-ubuntu.jpeg) -In here, from the left side pane, select Default Applications. You will see the option to change the default applications in the right side pane. + +在左边的面板中选择默认程序(Default Applications),你会发现在右边的面板中可以修改默认程序。 ![](https://itsfoss.com/wp-content/uploads/2016/07/System-settings-default-applications.jpeg) -As you can see, there are only a few kinds of default applications that can be changed here. You can change the default applications for web browser, email client, calendar app, music, videos and photo here. What about other kinds of applications? +正如看到的那样,这里只有少数几类的默认程序可以被改变。你可以在这里改变浏览器,邮箱客户端,日历,音乐,视频和相册的默认程序。那其他类型的默认程序怎么修改? -Don’t worry. To change the default applications of other kinds, we’ll use the option in the right click menu. +不要担心,为了修改其他类型的默认程序,我们会用到右键菜单。 -#### 2. CHANGE DEFAULT APPLICATIONS IN UBUNTU FROM RIGHT CLICK MENU +#### 2.通过右键菜单修改默认程序 -If you have ever used Windows, you might be aware of the “open with” option in the right click menu that allows changing the default applications. We have something similar in Ubuntu Linux as well. -Right click on the file that you want to open in a non-default application. Go to properties. +如果你使用过 Windows 系统,你应该看见过右键菜单的“打开方式”,可以通过这个来修改默认程序。我们在 Ubuntu 中也有相似的方法。 + +右键一个还没有设置默认打开程序的文件,选择“属性(properties)” ![](https://itsfoss.com/wp-content/uploads/2016/05/WebP-images-Ubuntu-Linux-3.png) ->Select Properties from Right Click menu +>从右键菜单中选择属性 -And in here, you can select the application that you want to use and set it as default. +在这里,你可以选择使用什么程序打开,并且设置为默认程序。 ![](https://itsfoss.com/wp-content/uploads/2016/05/WebP-images-Ubuntu-Linux-4.png) ->Making gThumb the default application for WebP images in Ubuntu +>在 Ubuntu 中设置打开 WebP 图片的默认程序为 gThumb -Easy peasy. Isn’t it? Once you do that, all the files of the same kind will be opened with your chosen default application. - -I hope you found this beginners tutorial to change default applications in Ubuntu helpful. If you have any questions or suggestions, feel free to drop a comment below. +小菜一碟不是么?一旦你做完这些,所有同样类型的文件都会用你选择的默认程序打开。 +我很希望这个新手指南对你在修改 Ubuntu 的默认程序时有帮助。如果你有任何的疑问或者建议,可以随时在下面评论。 -------------------------------------------------------------------------------- via: https://itsfoss.com/change-default-applications-ubuntu/?utm_source=feedburner&utm_medium=feed&utm_campaign=Feed%3A+ItsFoss+%28Its+FOSS%21+An+Open+Source+Blog%29 作者:[Abhishek Prakash][a] -译者:[译者ID](https://github.com/译者ID) +译者:[译者ID](https://github.com/locez) 校对:[校对者ID](https://github.com/校对者ID) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 From b0aacf4336353088db849f02b32e4edfa2562379 Mon Sep 17 00:00:00 2001 From: Locez Date: Mon, 25 Jul 2016 15:13:12 +0800 Subject: [PATCH 020/122] translated --- .../20160722 HOW TO CHANGE DEFAULT APPLICATIONS IN UBUNTU.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sources/tech/20160722 HOW TO CHANGE DEFAULT APPLICATIONS IN UBUNTU.md b/sources/tech/20160722 HOW TO CHANGE DEFAULT APPLICATIONS IN UBUNTU.md index b6c9ae0cf7..2192b71600 100644 --- a/sources/tech/20160722 HOW TO CHANGE DEFAULT APPLICATIONS IN UBUNTU.md +++ b/sources/tech/20160722 HOW TO CHANGE DEFAULT APPLICATIONS IN UBUNTU.md @@ -57,7 +57,7 @@ via: https://itsfoss.com/change-default-applications-ubuntu/?utm_source=feedburner&utm_medium=feed&utm_campaign=Feed%3A+ItsFoss+%28Its+FOSS%21+An+Open+Source+Blog%29 作者:[Abhishek Prakash][a] -译者:[译者ID](https://github.com/locez) +译者:[Locez](https://github.com/locez) 校对:[校对者ID](https://github.com/校对者ID) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 From deb9c2fd5350f642fc2e64b9f1f3bc4e12f54660 Mon Sep 17 00:00:00 2001 From: Locez Date: Mon, 25 Jul 2016 15:19:36 +0800 Subject: [PATCH 021/122] move to translated --- ...O CHANGE DEFAULT APPLICATIONS IN UBUNTU.md | 67 +++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 translated/tech/20160722 HOW TO CHANGE DEFAULT APPLICATIONS IN UBUNTU.md diff --git a/translated/tech/20160722 HOW TO CHANGE DEFAULT APPLICATIONS IN UBUNTU.md b/translated/tech/20160722 HOW TO CHANGE DEFAULT APPLICATIONS IN UBUNTU.md new file mode 100644 index 0000000000..2192b71600 --- /dev/null +++ b/translated/tech/20160722 HOW TO CHANGE DEFAULT APPLICATIONS IN UBUNTU.md @@ -0,0 +1,67 @@ +怎样在 UBUNTU 中修改默认程序 +============================================== + +![](https://itsfoss.com/wp-content/uploads/2016/07/change-default-applications-ubuntu.jpg) + +简介: 这个新手指南会向你展示如何在 Ubuntu Linux 中修改默认程序 + +对于我来说,安装 [VLC 多媒体播放器][1]是[安装完 Ubuntu 16.04 该做的事][2]中最先做的几件事之一。为了能够使我双击一个视频就用 VLC 打开,在我安装完 VLC 之后我会设置它为默认程序。 + +作为一个新手,你需要知道如何在 Ubuntu 中修改任何默认程序,这也是我今天在这篇指南中所要讲的。 + +### 在 UBUNTU 中修改默认程序 +这里提及的方法适用于所有的 Ubuntu 12.04,Ubuntu 14.04 和Ubuntu 16.04。在 Ubuntu 中,这里有两种基本的方法可以修改默认程序: + +- 通过系统设置 +- 通过右键菜单 + +#### 1.通过系统设置修改 Ubuntu 的默认程序 + +进入 Unity 面板并且搜索系统设置(System Settings): + +![](https://itsfoss.com/wp-content/uploads/2013/11/System_Settings_Ubuntu.jpeg) + +在系统设置(System Settings)中,选择详细选项(Details): + +![](https://itsfoss.com/wp-content/uploads/2016/07/System-settings-detail-ubuntu.jpeg) + + +在左边的面板中选择默认程序(Default Applications),你会发现在右边的面板中可以修改默认程序。 + +![](https://itsfoss.com/wp-content/uploads/2016/07/System-settings-default-applications.jpeg) + +正如看到的那样,这里只有少数几类的默认程序可以被改变。你可以在这里改变浏览器,邮箱客户端,日历,音乐,视频和相册的默认程序。那其他类型的默认程序怎么修改? + +不要担心,为了修改其他类型的默认程序,我们会用到右键菜单。 + +#### 2.通过右键菜单修改默认程序 + + +如果你使用过 Windows 系统,你应该看见过右键菜单的“打开方式”,可以通过这个来修改默认程序。我们在 Ubuntu 中也有相似的方法。 + +右键一个还没有设置默认打开程序的文件,选择“属性(properties)” + +![](https://itsfoss.com/wp-content/uploads/2016/05/WebP-images-Ubuntu-Linux-3.png) +>从右键菜单中选择属性 + +在这里,你可以选择使用什么程序打开,并且设置为默认程序。 + +![](https://itsfoss.com/wp-content/uploads/2016/05/WebP-images-Ubuntu-Linux-4.png) +>在 Ubuntu 中设置打开 WebP 图片的默认程序为 gThumb + +小菜一碟不是么?一旦你做完这些,所有同样类型的文件都会用你选择的默认程序打开。 +我很希望这个新手指南对你在修改 Ubuntu 的默认程序时有帮助。如果你有任何的疑问或者建议,可以随时在下面评论。 + +-------------------------------------------------------------------------------- + +via: https://itsfoss.com/change-default-applications-ubuntu/?utm_source=feedburner&utm_medium=feed&utm_campaign=Feed%3A+ItsFoss+%28Its+FOSS%21+An+Open+Source+Blog%29 + +作者:[Abhishek Prakash][a] +译者:[Locez](https://github.com/locez) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]: https://itsfoss.com/author/abhishek/ +[1]: http://www.videolan.org/vlc/index.html +[2]: https://itsfoss.com/things-to-do-after-installing-ubuntu-16-04/ From 28a8b5c6afe4523b8e15c0537dc0fee7974fd76a Mon Sep 17 00:00:00 2001 From: Locez Date: Mon, 25 Jul 2016 15:20:50 +0800 Subject: [PATCH 022/122] translated and delete source --- ...O CHANGE DEFAULT APPLICATIONS IN UBUNTU.md | 67 ------------------- 1 file changed, 67 deletions(-) delete mode 100644 sources/tech/20160722 HOW TO CHANGE DEFAULT APPLICATIONS IN UBUNTU.md diff --git a/sources/tech/20160722 HOW TO CHANGE DEFAULT APPLICATIONS IN UBUNTU.md b/sources/tech/20160722 HOW TO CHANGE DEFAULT APPLICATIONS IN UBUNTU.md deleted file mode 100644 index 2192b71600..0000000000 --- a/sources/tech/20160722 HOW TO CHANGE DEFAULT APPLICATIONS IN UBUNTU.md +++ /dev/null @@ -1,67 +0,0 @@ -怎样在 UBUNTU 中修改默认程序 -============================================== - -![](https://itsfoss.com/wp-content/uploads/2016/07/change-default-applications-ubuntu.jpg) - -简介: 这个新手指南会向你展示如何在 Ubuntu Linux 中修改默认程序 - -对于我来说,安装 [VLC 多媒体播放器][1]是[安装完 Ubuntu 16.04 该做的事][2]中最先做的几件事之一。为了能够使我双击一个视频就用 VLC 打开,在我安装完 VLC 之后我会设置它为默认程序。 - -作为一个新手,你需要知道如何在 Ubuntu 中修改任何默认程序,这也是我今天在这篇指南中所要讲的。 - -### 在 UBUNTU 中修改默认程序 -这里提及的方法适用于所有的 Ubuntu 12.04,Ubuntu 14.04 和Ubuntu 16.04。在 Ubuntu 中,这里有两种基本的方法可以修改默认程序: - -- 通过系统设置 -- 通过右键菜单 - -#### 1.通过系统设置修改 Ubuntu 的默认程序 - -进入 Unity 面板并且搜索系统设置(System Settings): - -![](https://itsfoss.com/wp-content/uploads/2013/11/System_Settings_Ubuntu.jpeg) - -在系统设置(System Settings)中,选择详细选项(Details): - -![](https://itsfoss.com/wp-content/uploads/2016/07/System-settings-detail-ubuntu.jpeg) - - -在左边的面板中选择默认程序(Default Applications),你会发现在右边的面板中可以修改默认程序。 - -![](https://itsfoss.com/wp-content/uploads/2016/07/System-settings-default-applications.jpeg) - -正如看到的那样,这里只有少数几类的默认程序可以被改变。你可以在这里改变浏览器,邮箱客户端,日历,音乐,视频和相册的默认程序。那其他类型的默认程序怎么修改? - -不要担心,为了修改其他类型的默认程序,我们会用到右键菜单。 - -#### 2.通过右键菜单修改默认程序 - - -如果你使用过 Windows 系统,你应该看见过右键菜单的“打开方式”,可以通过这个来修改默认程序。我们在 Ubuntu 中也有相似的方法。 - -右键一个还没有设置默认打开程序的文件,选择“属性(properties)” - -![](https://itsfoss.com/wp-content/uploads/2016/05/WebP-images-Ubuntu-Linux-3.png) ->从右键菜单中选择属性 - -在这里,你可以选择使用什么程序打开,并且设置为默认程序。 - -![](https://itsfoss.com/wp-content/uploads/2016/05/WebP-images-Ubuntu-Linux-4.png) ->在 Ubuntu 中设置打开 WebP 图片的默认程序为 gThumb - -小菜一碟不是么?一旦你做完这些,所有同样类型的文件都会用你选择的默认程序打开。 -我很希望这个新手指南对你在修改 Ubuntu 的默认程序时有帮助。如果你有任何的疑问或者建议,可以随时在下面评论。 - --------------------------------------------------------------------------------- - -via: https://itsfoss.com/change-default-applications-ubuntu/?utm_source=feedburner&utm_medium=feed&utm_campaign=Feed%3A+ItsFoss+%28Its+FOSS%21+An+Open+Source+Blog%29 - -作者:[Abhishek Prakash][a] -译者:[Locez](https://github.com/locez) -校对:[校对者ID](https://github.com/校对者ID) - -本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 - -[a]: https://itsfoss.com/author/abhishek/ -[1]: http://www.videolan.org/vlc/index.html -[2]: https://itsfoss.com/things-to-do-after-installing-ubuntu-16-04/ From 9539049bf2ba6bb2f76aa6020bd954a090e82ea8 Mon Sep 17 00:00:00 2001 From: kokialoves <498497353@qq.com> Date: Mon, 25 Jul 2016 16:21:18 +0800 Subject: [PATCH 023/122] Update 20160628 How To Setup Open Source Discussion Platform Discourse On Ubuntu Linux 16.04.md --- ...Source Discussion Platform Discourse On Ubuntu Linux 16.04.md | 1 + 1 file changed, 1 insertion(+) diff --git a/sources/tech/20160628 How To Setup Open Source Discussion Platform Discourse On Ubuntu Linux 16.04.md b/sources/tech/20160628 How To Setup Open Source Discussion Platform Discourse On Ubuntu Linux 16.04.md index a2521673c9..738c3dbf55 100644 --- a/sources/tech/20160628 How To Setup Open Source Discussion Platform Discourse On Ubuntu Linux 16.04.md +++ b/sources/tech/20160628 How To Setup Open Source Discussion Platform Discourse On Ubuntu Linux 16.04.md @@ -1,3 +1,4 @@ +[translating by kokialoves] How To Setup Open Source Discussion Platform Discourse On Ubuntu Linux 16.04 =============================================================================== From 958f533847bfdded7e8a50d96a853cb932bb0b10 Mon Sep 17 00:00:00 2001 From: ChrisLeeGit Date: Mon, 25 Jul 2016 18:31:51 +0800 Subject: [PATCH 024/122] =?UTF-8?q?=E7=94=B3=E8=AF=B7=E7=BF=BB=E8=AF=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...60621 Container technologies in Fedora - systemd-nspawn.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sources/tech/20160621 Container technologies in Fedora - systemd-nspawn.md b/sources/tech/20160621 Container technologies in Fedora - systemd-nspawn.md index 1ec72a3c90..6d3e08ac91 100644 --- a/sources/tech/20160621 Container technologies in Fedora - systemd-nspawn.md +++ b/sources/tech/20160621 Container technologies in Fedora - systemd-nspawn.md @@ -1,3 +1,5 @@ +Being translated by [ChrisLeeGit](https://github.com/chrisleegit) + Container technologies in Fedora: systemd-nspawn === @@ -97,7 +99,7 @@ $ restorecon -R /home/johnmh/DebianJessie/ via: http://linoxide.com/linux-how-to/set-nginx-reverse-proxy-centos-7-cpanel/ 作者:[John M. Harris, Jr.][a] -译者:[译者ID](https://github.com/译者ID) +译者:[ChrisLeeGit](https://github.com/chrisleegit) 校对:[校对者ID](https://github.com/校对者ID) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 From c7c7ca71ad54930dfa59a2e51d250440f45a6db8 Mon Sep 17 00:00:00 2001 From: Name1e5s <836401406@qq.com> Date: Mon, 25 Jul 2016 20:34:25 +0800 Subject: [PATCH 025/122] name1e5s translating --- ...60627 TOP 5 BEST VIDEO EDITING SOFTWARE FOR LINUX IN 2016.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sources/tech/20160627 TOP 5 BEST VIDEO EDITING SOFTWARE FOR LINUX IN 2016.md b/sources/tech/20160627 TOP 5 BEST VIDEO EDITING SOFTWARE FOR LINUX IN 2016.md index 44c66359f9..4faee7eaef 100644 --- a/sources/tech/20160627 TOP 5 BEST VIDEO EDITING SOFTWARE FOR LINUX IN 2016.md +++ b/sources/tech/20160627 TOP 5 BEST VIDEO EDITING SOFTWARE FOR LINUX IN 2016.md @@ -1,3 +1,5 @@ +name1e5s translating + TOP 5 BEST VIDEO EDITING SOFTWARE FOR LINUX IN 2016 ===================================================== From 85f2b50b2509d313fea84508025a580aee9010e3 Mon Sep 17 00:00:00 2001 From: cinlen <237448382@qq.com> Date: Mon, 25 Jul 2016 22:33:50 +0800 Subject: [PATCH 026/122] [translating]Who needs a GUI? How to live in a Linux terminal (#4219) * [translated]Growing a carrer alongside Linux * [translated]Growing a career alongside Linux * [translating]Who needs a GUI - How to live in a Linux terminal --- ...160606 Who needs a GUI - How to live in a Linux terminal.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sources/talk/20160606 Who needs a GUI - How to live in a Linux terminal.md b/sources/talk/20160606 Who needs a GUI - How to live in a Linux terminal.md index f9633eb966..148d758216 100644 --- a/sources/talk/20160606 Who needs a GUI - How to live in a Linux terminal.md +++ b/sources/talk/20160606 Who needs a GUI - How to live in a Linux terminal.md @@ -1,3 +1,4 @@ +chenxinlong translating Who needs a GUI? How to live in a Linux terminal ================================================= @@ -84,7 +85,7 @@ LibreOffice, Google Slides or, gasp, PowerPoint. I spend a lot of time in presen via: http://www.networkworld.com/article/3091139/linux/who-needs-a-gui-how-to-live-in-a-linux-terminal.html#slide1 作者:[Bryan Lunduke][a] -译者:[译者ID](https://github.com/译者ID) +译者:[译者ID](https://github.com/chenxinlong) 校对:[校对者ID](https://github.com/校对者ID) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创翻译,[Linux中国](https://linux.cn/) 荣誉推出 From 574ae23673ec096484b72043bbe1dda619ef2052 Mon Sep 17 00:00:00 2001 From: ChrisLeeGit Date: Tue, 26 Jul 2016 06:38:14 +0800 Subject: [PATCH 027/122] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=88=9D=E8=AF=91?= =?UTF-8?q?=E6=96=87=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- translated/tech/20160711 Getting started with Git.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/translated/tech/20160711 Getting started with Git.md b/translated/tech/20160711 Getting started with Git.md index 85c159945d..afa6b7382b 100644 --- a/translated/tech/20160711 Getting started with Git.md +++ b/translated/tech/20160711 Getting started with Git.md @@ -1,8 +1,8 @@ -Git 入门指南 +初步了解 Git ========================= ![](https://opensource.com/sites/default/files/styles/image-full-size/public/images/life/get_started_lead.jpeg?itok=r22AKc6P) ->Image by : opensource.com +> 图片来源:opensource.com 在这个系列的介绍中,我们学习到了谁应该使用 Git,以及 Git 是用来做什么的。今天,我们将学习如何克隆公共的 Git 仓库,以及如何提取出独立的文件而不用克隆整个仓库。 @@ -72,7 +72,7 @@ Checking connectivity... done. ![](https://opensource.com/sites/default/files/1_gitlab-zip.jpg) -### 挑选和选择 +### 仔细挑选 另外一种从 Git 仓库中获取文件的方法是找到你想要的文件,然后把它从仓库中拽出来。只有 web 界面才提供这种方法,本质上来说,你看到的是别人仓库的克隆;你可以把它想象成一个 HTTP 共享目录。 使用这种方法的问题是,你也许会发现某些文件并不存在于原始仓库中,因为完整形式的文件可能只有在执行 make 命令后才能构建,那只有你下载了完整的仓库,阅读了 README 或者 INSTALL 文件,然后运行相关命令之后才会产生。不过,假如你确信文件存在,而你只想进入仓库,获取那个文件,然后离开的话,你就可以那样做。 @@ -111,14 +111,14 @@ bar.clone $ git pull ``` -到目前为止,你需要了解的所有终端命令就是那些了,那就出去探索吧。你实践得越多,Git 掌握得就越好(孰能生巧),那就是游戏的名称,至少它教会了你一些基础(give or take a vowel)。 +到目前为止,你需要初步了解的所有终端命令就是那些了,那就去探索吧。你实践得越多,Git 掌握得就越好(孰能生巧),那就是游戏的名称,至少给了或取了一个元音。 -------------------------------------------------------------------------------- via: https://opensource.com/life/16/7/stumbling-git 作者:[Seth Kenlon][a] -译者:[译者ID](https://github.com/chrisleegit) +译者:[ChrisLeeGit](https://github.com/chrisleegit) 校对:[校对者ID](https://github.com/校对者ID) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创翻译,[Linux中国](https://linux.cn/) 荣誉推出 From 2ffb09b907d090d7cdefadaad2b59a94ca4114be Mon Sep 17 00:00:00 2001 From: wxy Date: Tue, 26 Jul 2016 09:00:31 +0800 Subject: [PATCH 028/122] PUB:Part 1 - LXD 2.0--Introduction to LXD MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @oska874 @PurlingNayuki 我说这篇怎么没啥可校对的,原来已经校对过了。 --- .../Part 1 - LXD 2.0--Introduction to LXD.md | 69 +++++++++---------- 1 file changed, 33 insertions(+), 36 deletions(-) rename {translated/tech => published}/LXD/Part 1 - LXD 2.0--Introduction to LXD.md (61%) diff --git a/translated/tech/LXD/Part 1 - LXD 2.0--Introduction to LXD.md b/published/LXD/Part 1 - LXD 2.0--Introduction to LXD.md similarity index 61% rename from translated/tech/LXD/Part 1 - LXD 2.0--Introduction to LXD.md rename to published/LXD/Part 1 - LXD 2.0--Introduction to LXD.md index 011f385881..11c7220964 100644 --- a/translated/tech/LXD/Part 1 - LXD 2.0--Introduction to LXD.md +++ b/published/LXD/Part 1 - LXD 2.0--Introduction to LXD.md @@ -1,4 +1,4 @@ -Part 1 - LXD 2.0: LXD 入门 +LXD 2.0 系列(一):LXD 入门 ====================================== 这是 [LXD 2.0 系列介绍文章][1]的第一篇。 @@ -20,12 +20,11 @@ LXD 最主要的目标就是使用 Linux 容器而不是硬件虚拟化向用户 LXD 聚焦于系统容器,通常也被称为架构容器。这就是说 LXD 容器实际上如在裸机或虚拟机上运行一般运行了一个完整的 Linux 操作系统。 -这些容器一般基于一个干净的发布镜像并会长时间运行。传统的配置管理工具和部署工具可以如在虚拟机、云和物理机器上一样与 LXD 一起使用。 +这些容器一般基于一个干净的发布镜像并会长时间运行。传统的配置管理工具和部署工具可以如在虚拟机、云实例和物理机器上一样与 LXD 一起使用。 -相对的, Docker 关注于短期的、无状态的最小容器,这些容器通常并不会升级或者重新配置,而是作为一个整体被替换掉。这就使得 Docker 及类似项目更像是一种软件发布机制,而不是一个机器管理工具。 - -这两种模型并不是完全互斥的。你完全可以使用 LXD 为你的用户提供一个完整的 Linux 系统,而他们可以在 LXD 内安装 Docker 来运行他们想要的软件。 +相对的, Docker 关注于短期的、无状态的、最小化的容器,这些容器通常并不会升级或者重新配置,而是作为一个整体被替换掉。这就使得 Docker 及类似项目更像是一种软件发布机制,而不是一个机器管理工具。 +这两种模型并不是完全互斥的。你完全可以使用 LXD 为你的用户提供一个完整的 Linux 系统,然后他们可以在 LXD 内安装 Docker 来运行他们想要的软件。 #### 为什么要用 LXD? @@ -35,56 +34,55 @@ LXD 聚焦于系统容器,通常也被称为架构容器。这就是说 LXD 我们把 LXD 作为解决这些缺陷的一个很好的机会。作为一个长时间运行的守护进程, LXD 可以绕开 LXC 的许多限制,比如动态资源限制、无法进行容器迁移和高效的在线迁移;同时,它也为创造新的默认体验提供了机会:默认开启安全特性,对用户更加友好。 - ### LXD 的主要组件 -LXD 是由几个主要组件构成的,这些组件都是 LXD 目录结构、命令行客户端和 API 结构体里下可见的。 +LXD 是由几个主要组件构成的,这些组件都出现在 LXD 目录结构、命令行客户端和 API 结构体里。 #### 容器 LXD 中的容器包括以下及部分: -- 根文件系统 +- 根文件系统(rootfs) +- 配置选项列表,包括资源限制、环境、安全选项等等 - 设备:包括磁盘、unix 字符/块设备、网络接口 - 一组继承而来的容器配置文件 -- 属性(容器架构,暂时的或持久的,容器名) -- 运行时状态(当时为了记录检查点、恢复时用到了 CRIU时) +- 属性(容器架构、暂时的还是持久的、容器名) +- 运行时状态(当用 CRIU 来中断/恢复时) #### 快照 容器快照和容器是一回事,只不过快照是不可修改的,只能被重命名,销毁或者用来恢复系统,但是无论如何都不能被修改。 -值得注意的是,因为我们允许用户保存容器的运行时状态,这就有效的为我们提供了“有状态”的快照的功能。这就是说我们可以使用快照回滚容器的 CPU 和内存。 +值得注意的是,因为我们允许用户保存容器的运行时状态,这就有效的为我们提供了“有状态”的快照的功能。这就是说我们可以使用快照回滚容器的状态,包括快照当时的 CPU 和内存状态。 #### 镜像 LXD 是基于镜像实现的,所有的 LXD 容器都是来自于镜像。容器镜像通常是一些纯净的 Linux 发行版的镜像,类似于你们在虚拟机和云实例上使用的镜像。 -所以就可以「发布」容器:使用容器制作一个镜像并在本地或者远程 LXD 主机上使用。 +所以可以「发布」一个容器:使用容器制作一个镜像并在本地或者远程 LXD 主机上使用。 -镜像通常使用全部或部分 sha256 哈希码来区分。因为输入长长的哈希码对用户来说不好,所以镜像可以使用几个自身的属性来区分,这就使得用户在镜像商店里方便搜索镜像。别名也可以用来 1 对 1 地把对用户友好的名字映射到某个镜像的哈希码。 +镜像通常使用全部或部分 sha256 哈希码来区分。因为输入长长的哈希码对用户来说不方便,所以镜像可以使用几个自身的属性来区分,这就使得用户在镜像商店里方便搜索镜像。也可以使用别名来一对一地将一个用户好记的名字映射到某个镜像的哈希码上。 LXD 安装时已经配置好了三个远程镜像服务器(参见下面的远程一节): -- “ubuntu:” 提供稳定版的 Ubuntu 镜像 -- “ubuntu-daily:” 提供每天构建出来的 Ubuntu -- “images:” 社区维护的镜像服务器,提供一系列的 Linux 发布版,使用的是上游 LXC 的模板 +- “ubuntu”:提供稳定版的 Ubuntu 镜像 +- “ubuntu-daily”:提供 Ubuntu 的每日构建镜像 +- “images”: 社区维护的镜像服务器,提供一系列的其它 Linux 发布版,使用的是上游 LXC 的模板 LXD 守护进程会从镜像上次被使用开始自动缓存远程镜像一段时间(默认是 10 天),超过时限后这些镜像才会失效。 此外, LXD 还会自动更新远程镜像(除非指明不更新),所以本地的镜像会一直是最新版的。 - #### 配置 -配置文件是一种在一处定义容器配置和容器设备,然后应用到一系列容器的方法。 +配置文件是一种在一个地方定义容器配置和容器设备,然后将其应用到一系列容器的方法。 -一个容器可以被应用多个配置文件。当构建最终容器配置时(即通常的扩展配置),这些配置文件都会按照他们定义顺序被应用到容器上,当有重名的配置时,新的会覆盖掉旧的。然后本地容器设置会在这些基础上应用,覆盖所有来自配置文件的选项。 +一个容器可以被应用多个配置文件。当构建最终容器配置时(即通常的扩展配置),这些配置文件都会按照他们定义顺序被应用到容器上,当有重名的配置键或设备时,新的会覆盖掉旧的。然后本地容器设置会在这些基础上应用,覆盖所有来自配置文件的选项。 LXD 自带两种预配置的配置文件: -- 「 default 」配置是自动应用在所有容器之上,除非用户提供了一系列替代的配置文件。目前这个配置文件只做一件事,为容器定义 eth0 网络设备。 -- 「 docker” 」配置是一个允许你在容器里运行 Docker 容器的配置文件。它会要求 LXD 加载一些需要的内核模块以支持容器嵌套并创建一些设备入口。 +- “default”配置是自动应用在所有容器之上,除非用户提供了一系列替代的配置文件。目前这个配置文件只做一件事,为容器定义 eth0 网络设备。 +- “docker”配置是一个允许你在容器里运行 Docker 容器的配置文件。它会要求 LXD 加载一些需要的内核模块以支持容器嵌套并创建一些设备。 #### 远程 @@ -92,14 +90,14 @@ LXD 自带两种预配置的配置文件: 默认情况下,我们的命令行客户端会与下面几个预定义的远程服务器通信: -- local:(默认的远程服务器,使用 UNIX socket 和本地的 LXD 守护进程通信) -- ubuntu:( Ubuntu 镜像服务器,提供稳定版的 Ubuntu 镜像) -- ubuntu-daily:( Ubuntu 镜像服务器,提供每天构建出来的 Ubuntu ) -- images:( images.linuxcontainers.org 镜像服务器) +- local:默认的远程服务器,使用 UNIX socket 和本地的 LXD 守护进程通信 +- ubuntu:Ubuntu 镜像服务器,提供稳定版的 Ubuntu 镜像 +- ubuntu-daily:Ubuntu 镜像服务器,提供 Ubuntu 的每日构建版 +- images:images.linuxcontainers.org 的镜像服务器 所有这些远程服务器的组合都可以在命令行客户端里使用。 -你也可以添加任意数量的远程 LXD 主机来监听网络。匿名的开放镜像服务器,或者通过认证可以管理远程容器的镜像服务器,都可以添加进来。 +你也可以添加任意数量的远程 LXD 主机,并配置它们监听网络。匿名的开放镜像服务器,或者通过认证可以管理远程容器的镜像服务器,都可以添加进来。 正是这种远程机制使得与远程镜像服务器交互及在主机间复制、移动容器成为可能。 @@ -107,30 +105,29 @@ LXD 自带两种预配置的配置文件: 我们设计 LXD 时的一个核心要求,就是在不修改现代 Linux 发行版的前提下,使容器尽可能的安全。 -LXD 使用的、通过使用 LXC 库实现的主要安全特性有: +LXD 通过使用 LXC 库实现的主要安全特性有: -- 内核名字空间。尤其是用户名字空间,它让容器和系统剩余部分完全分离。LXD 默认使用用户名字空间(和 LXC 相反),并允许用户在需要的时候以容器为单位打开或关闭。 +- 内核名字空间。尤其是用户名字空间,它让容器和系统剩余部分完全分离。LXD 默认使用用户名字空间(和 LXC 相反),并允许用户在需要的时候以容器为单位关闭(将容器标为“特权的”)。 - Seccomp 系统调用。用来隔离潜在危险的系统调用。 -- AppArmor:对 mount、socket、ptrace 和文件访问提供额外的限制。特别是限制跨容器通信。 +- AppArmor。对 mount、socket、ptrace 和文件访问提供额外的限制。特别是限制跨容器通信。 - Capabilities。阻止容器加载内核模块,修改主机系统时间,等等。 -- CGroups。限制资源使用,防止对主机的 DoS 攻击。 +- CGroups。限制资源使用,防止针对主机的 DoS 攻击。 +为了对用户友好,LXD 构建了一个新的配置语言把大部分的这些特性都抽象封装起来,而不是如 LXC 一般直接将这些特性暴露出来。举了例子,一个用户可以告诉 LXD 把主机设备放进容器而不需要手动检查他们的主/次设备号来手动更新 CGroup 策略。 -为了对用户友好 , LXD 构建了一个新的配置语言把大部分的这些特性都抽象封装起来,而不是如 LXC 一般直接将这些特性暴露出来。举了例子,一个用户可以告诉 LXD 把主机设备放进容器而不需要手动检查他们的主/次设备号来更新 CGroup 策略。 - -和 LXD 本身通信是基于使用 TLS 1.2 保护的链路,这些链路只允许使用有限的几个被允许的密钥。当和那些经过系统证书认证之外的主机通信时, LXD 会提示用户验证主机的远程足迹(SSH 方式),然后把足迹缓存起来以供以后使用。 +和 LXD 本身通信是基于使用 TLS 1.2 保护的链路,只允许使用有限的几个被允许的密钥算法。当和那些经过系统证书认证之外的主机通信时, LXD 会提示用户验证主机的远程指纹(SSH 方式),然后把指纹缓存起来以供以后使用。 ### REST 接口 -LXD 的工作都是通过 REST 接口实现的。在客户端和守护进程之间并没有其他的通讯手段。 +LXD 的工作都是通过 REST 接口实现的。在客户端和守护进程之间并没有其他的通讯渠道。 -REST 接口可以通过本地的 unix socket 访问,这只需要经过组认证,或者经过 HTTP 套接字使用客户端认证进行通信。 +REST 接口可以通过本地的 unix socket 访问,这只需要经过用户组认证,或者经过 HTTP 套接字使用客户端认证进行通信。 REST 接口的结构能够和上文所说的不同的组件匹配,是一种简单、直观的使用方法。 当需要一种复杂的通信机制时, LXD 将会进行 websocket 协商完成剩余的通信工作。这主要用于交互式终端会话、容器迁移和事件通知。 -LXD 2.0 附带了 1.0 版的稳定 API。虽然我们在 1.0 版 API 添加了额外的特性,但是这不会在 1.0 版 API 的端点里破坏向后兼容性,因为我们会声明额外的 API 扩展使得客户端可以找到新的接口。 +LXD 2.0 附带了 1.0 版的稳定 API。虽然我们在 1.0 版 API 添加了额外的特性,但是这不会在 1.0 版 API 端点里破坏向后兼容性,因为我们会声明额外的 API 扩展使得客户端可以找到新的接口。 ### 容器规模化 From 170200ad4e794553e1410982afc6d2b213e547d3 Mon Sep 17 00:00:00 2001 From: wxy Date: Tue, 26 Jul 2016 09:03:56 +0800 Subject: [PATCH 029/122] =?UTF-8?q?=E8=BF=99=E7=AF=87=E5=B7=B2=E7=BB=8F?= =?UTF-8?q?=E5=8F=91=E5=B8=83=E8=BF=87=EF=BC=8C=E5=B9=B6=E7=A7=BB=E5=8A=A8?= =?UTF-8?q?=E5=88=B0=20PUB=20=E4=B8=8B=E4=BA=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @kokialoves @locez --- ...Installed Help Documentations and Tools.md | 178 ------------------ 1 file changed, 178 deletions(-) delete mode 100644 translated/tech/LFCS/Part 12 - How to Explore Linux with Installed Help Documentations and Tools.md diff --git a/translated/tech/LFCS/Part 12 - How to Explore Linux with Installed Help Documentations and Tools.md b/translated/tech/LFCS/Part 12 - How to Explore Linux with Installed Help Documentations and Tools.md deleted file mode 100644 index 2d0238becf..0000000000 --- a/translated/tech/LFCS/Part 12 - How to Explore Linux with Installed Help Documentations and Tools.md +++ /dev/null @@ -1,178 +0,0 @@ -LFCS第十二讲: 如何使用Linux的帮助文档和工具 -================================================================================== - -由于 2016 年 2 月 2 号开始启用了新的 LFCS 考试要求, 我们在[LFCS series][1]系列添加了一些必要的内容 . 为了考试的需要, 我们强烈建议你看一下[LFCE series][2] . - -![](http://www.tecmint.com/wp-content/uploads/2016/03/Explore-Linux-with-Documentation-and-Tools.png) ->LFCS: 了解Linux的帮助文档和工具 - -当你习惯了在命令行下进行工作, 你会发现Linux有许多文档需要你去使用和配置Linux系统. - -另一个你必须熟悉命令行帮助工具的理由是,在[LFCS][3] 和 [LFCE][4] 考试中, 你只能靠你自己和命令行工具,没有互联网也没有百度。 - -基于上面的理由, 在这一章里我们将给你一些建议来帮助你通过**Linux Foundation Certification** 考试. - -### Linux 帮助手册 - -man命令, 大体上来说就是一个工具手册. 它包含选项列表(和解释) , 甚至还提供一些例子. - -我们用**man command** 加工具名称来打开一个帮助手册以便获取更多内容. 例如: - -``` -# man diff -``` - -我们将打开`diff`的手册页, 这个工具将一行一行的对比文本文档 (如你想退出只需要轻轻的点一下Q键). - -下面我来比较两个文本文件 `file1` 和 `file2` . 这两个文本文件包含着相同版本Linux的安装包信息. - -输入`diff` 命令它将告诉我们 `file1` 和`file2` 有什么不同: - -``` -# diff file1 file2 -``` - -![](http://www.tecmint.com/wp-content/uploads/2016/03/Compare-Two-Text-Files-in-Linux.png) ->在Linux中比较两个文本文件 - -`<` 这个符号是说`file2`少一行. 如果是 `file1`少一行, 我们将用 `>` 符号来替代. - -接下来说, **7d6** 意思是说 文件1的**#7**行在 `file2`中被删除了 ( **24d22** 和**41d38**是同样的意思), 65,67d61告诉我们移动 **65** 到 **67** . 我们把以上步骤都做了两个文件将完全匹配. - -你还可以通过 `-y` 选项来对比两个文件: - -``` -# diff -y file1 file2 -``` - -![](http://www.tecmint.com/wp-content/uploads/2016/03/Compare-and-List-Difference-of-Two-Files.png) ->通过列表来列出两个文件的不同 - - 当然你也可以用`diff`来比较两个二进制文件 . 如果它们完全一样, `diff` 将什么也不会输出. 否则, 他将会返回如下信息: “**Binary files X and Y differ**”. - -### –help 选项 - -`--help`选项 , 大多数命令都可以用它(并不是所有) , 他可以理解为一个命令的简单介绍. 尽管它不提供工具的详细介绍, 但是确实是一个能够快速列出程序使用信息的不错的方法. - -例如, - -``` -# sed --help -``` - -显示 sed 的每个选项的用法(sed文本流编辑器). - -一个经典的`sed`例子,替换文件字符. 用 `-i` 选项 (描述为 “**编辑文件在指定位置**”), 你可以编辑一个文件而且并不需要打开他. 如果你想要备份一个原始文件, 用 `-i` 选项 加后缀来创建一个原始文件的副本. - -例如, 替换 `lorem.txt`中的`Lorem` 为 `Tecmint` (忽略大小写) 并且创建一个新的原始文件副本, 命令如下: - -``` -# less lorem.txt | grep -i lorem -# sed -i.orig 's/Lorem/Tecmint/gI' lorem.txt -# less lorem.txt | grep -i lorem -# less lorem.txt.orig | grep -i lorem -``` - - 请注意`lorem.txt`文件中`Lorem` 都已经替换为 `Tecmint` , 并且原始的 `lorem.txt` 保存为`lorem.txt.orig`. - -![](http://www.tecmint.com/wp-content/uploads/2016/03/Replace-A-String-in-File.png) ->替换文件文本 - -### /usr/share/doc内的文档 -这可能是我最喜欢的方法. 如果你进入 `/usr/share/doc` 目录, 你可以看到好多Linux已经安装的工具的名称的文件夹. - -根据[Filesystem Hierarchy Standard][5](文件目录标准),这些文件夹包含了许多帮助手册没有的信息, 还有一些模板和配置文件. - -例如, 让我们来看一下 `squid-3.3.8` (版本可能会不同) 一个非常受欢迎的HTTP代理[squid cache server][6]. - -让我们用`cd`命令进入目录 : - -``` -# cd /usr/share/doc/squid-3.3.8 -``` - -列出当前文件夹列表: - -``` -# ls -``` - -![](http://www.tecmint.com/wp-content/uploads/2016/03/List-Files-in-Linux.png) ->ls linux列表命令 - -你应该特别注意 `QUICKSTART` 和 `squid.conf.documented`. 这两个文件包含了Squid许多信息, . 对于别的安装包来说, 他们的名字可能不同 (有可能是 **QuickRef** 或者**00QUICKSTART**), 但原理是一样的. - -对于另外一些安装包, 比如 the Apache web server, 在`/usr/share/doc`目录提供了配置模板, 当你配置独立服务器或者虚拟主机的时候会非常有用. - -### GNU 信息文档 - -你可以把它想象为帮助手册的超级链接形式. 正如上面说的, 他不仅仅提供工具的帮助信息, 而且还是超级链接的形式(是的!在命令行中的超级链接) 你可以通过箭头按钮和回车按钮来浏览你需要的内容. - -一个典型的例子是: - -``` -# info coreutils -``` - -通过coreutils 列出当前系统的 基本文件,shell脚本和文本处理工具[basic file, shell and text manipulation utilities][7] , 你可以得到他们的详细介绍. - -![](http://www.tecmint.com/wp-content/uploads/2016/03/Info-Coreutils.png) ->Info Coreutils - -和帮助手册一样你可以按Q键退出. - -此外, GNU info 还可以像帮助手册一样使用. 例如: - -``` -# info tune2fs -``` - -它将显示 **tune2fs**的帮助手册, ext2/3/4 文件系统管理工具. - -让我们来看看怎么用**tune2fs**: - -显示 **/dev/mapper/vg00-vol_backups**文件系统信息: - -``` -# tune2fs -l /dev/mapper/vg00-vol_backups -``` - -修改文件系统标签 (修改为Backups): - -``` -# tune2fs -L Backups /dev/mapper/vg00-vol_backups -``` - -设置 `/` 自检的挂载次数 (用`-c` 选项设置 `/`的自检的挂载次数 或者用 `-i` 选项设置 自检时间 **d=days, w=weeks, and m=months**). - -``` -# tune2fs -c 150 /dev/mapper/vg00-vol_backups # Check every 150 mounts -# tune2fs -i 6w /dev/mapper/vg00-vol_backups # Check every 6 weeks -``` - -以上这些内容也可以通过 `--help` 选项找到, 或者查看帮助手册. - -### 摘要 - -不管你选择哪种方法,知道并且会使用它们在考试中对你是非常有用的. 你知道其它的一些方法吗? 欢迎给我们留言. - - --------------------------------------------------------------------------------- - -via: http://www.tecmint.com/linux-basic-shell-scripting-and-linux-filesystem-troubleshooting/ - -作者:[Gabriel Cánepa][a] -译者:[kokialoves](https://github.com/kokialoves) -校对:[校对者ID](https://github.com/校对者ID) - -本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创翻译,[Linux中国](https://linux.cn/) 荣誉推出 - -[a]:http://www.tecmint.com/author/gacanepa/ -[1]: http://www.tecmint.com/sed-command-to-create-edit-and-manipulate-files-in-linux/ -[2]: http://www.tecmint.com/installing-network-services-and-configuring-services-at-system-boot/ -[3]: http://www.tecmint.com/sed-command-to-create-edit-and-manipulate-files-in-linux/ -[4]: http://www.tecmint.com/installing-network-services-and-configuring-services-at-system-boot/ -[5]: http://www.tecmint.com/linux-directory-structure-and-important-files-paths-explained/ -[6]: http://www.tecmint.com/configure-squid-server-in-linux/ -[7]: http://www.tecmint.com/sed-command-to-create-edit-and-manipulate-files-in-linux/ -[8]: From 4702262225de41e4eb8d7bbabce1711f968f976f Mon Sep 17 00:00:00 2001 From: kokialoves <498497353@qq.com> Date: Tue, 26 Jul 2016 09:47:57 +0800 Subject: [PATCH 030/122] =?UTF-8?q?=E7=BF=BB=E8=AF=91=E5=AE=8C=E6=88=90=20?= =?UTF-8?q?(#4222)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Delete 20160628 How To Setup Open Source Discussion Platform Discourse On Ubuntu Linux 16.04.md * Create 20160628 How To Setup Open Source Discussion Platform Discourse On Ubuntu Linux 16.04.md --- ...latform Discourse On Ubuntu Linux 16.04.md | 102 ------------------ ...latform Discourse On Ubuntu Linux 16.04.md | 101 +++++++++++++++++ 2 files changed, 101 insertions(+), 102 deletions(-) delete mode 100644 sources/tech/20160628 How To Setup Open Source Discussion Platform Discourse On Ubuntu Linux 16.04.md create mode 100644 translated/tech/20160628 How To Setup Open Source Discussion Platform Discourse On Ubuntu Linux 16.04.md diff --git a/sources/tech/20160628 How To Setup Open Source Discussion Platform Discourse On Ubuntu Linux 16.04.md b/sources/tech/20160628 How To Setup Open Source Discussion Platform Discourse On Ubuntu Linux 16.04.md deleted file mode 100644 index 738c3dbf55..0000000000 --- a/sources/tech/20160628 How To Setup Open Source Discussion Platform Discourse On Ubuntu Linux 16.04.md +++ /dev/null @@ -1,102 +0,0 @@ -[translating by kokialoves] -How To Setup Open Source Discussion Platform Discourse On Ubuntu Linux 16.04 -=============================================================================== - -Discourse is an open source discussion platform, that can work as a mailing list, a chat room and a forum as well. It is a popular tool and modern day implementation of a successful discussion platform. On server side, it is built using Ruby on Rails and uses Postgres on the backend, it also makes use of Redis caching to reduce the loading times, while on client’s side end, it runs in browser using Java Script. It is a pretty well optimized and well structured tool. It also offers converter plugins to migrate your existing discussion boards / forums like vBulletin, phpBB, Drupal, SMF etc to Discourse. In this article, we will be learning how to install Discourse on Ubuntu operating system. - -It is developed by keeping security in mind, so spammers and hackers might not be lucky with this application. It works well with all modern devices, and adjusts its display setting accordingly for mobile devices and tablets. - -### Installing Discourse on Ubuntu 16.04 - -Let’s get started ! the minimum system RAM to run Discourse is 1 GB and the officially supported installation process for Discourse requires dockers to be installed on our Linux system. Besides dockers, it also requires Git. We can fulfill these two requirements by simply running the following command on our system’s terminal. - -``` -wget -qO- https://get.docker.com/ | sh -``` - -![](http://linuxpitstop.com/wp-content/uploads/2016/06/124.png) - -It shouldn’t take longer to complete the installation for Docker and Git, as soon its installation process is complete, create a directory for Discourse inside /var partition of your system (You can choose any other partition here too). - -``` -mkdir /var/discourse -``` - -Now clone the Discourse’s Github repository to this newly created directory. - -``` -git clone https://github.com/discourse/discourse_docker.git /var/discourse -``` - -Go into the cloned directory. - -``` -cd /var/discourse -``` - -![](http://linuxpitstop.com/wp-content/uploads/2016/06/314.png) - -You should be able to locate “discourse-setup” script file here, simply run this script to initiate the installation wizard for Discourse. - -``` -./discourse-setup -``` - -**Side note: Please make sure you have a ready email server setup before attempting install for discourse.** - -Installation wizard will ask you following six questions. - -``` -Hostname for your Discourse? -Email address for admin account? -SMTP server address? -SMTP user name? -SMTP port [587]: -SMTP password? []: -``` - -![](http://linuxpitstop.com/wp-content/uploads/2016/06/411.png) - -Once you supply these information, it will ask for the confirmation, if everything is fine, hit “Enter” and installation process will take off. - -![](http://linuxpitstop.com/wp-content/uploads/2016/06/511.png) - -Sit back and relax! it will take sweet amount of time to complete the installation, grab a cup of coffee, and keep an eye for any error messages. - -![](http://linuxpitstop.com/wp-content/uploads/2016/06/610.png) - -Here is how the successful completion of the installation process should look alike. - -![](http://linuxpitstop.com/wp-content/uploads/2016/06/710.png) - -Now launch your web browser, if the hostname for discourse installation resolves properly to IP, then you can use your hostname in browser , otherwise use your IP address to launch the Discourse page. Here is what you should see: - -![](http://linuxpitstop.com/wp-content/uploads/2016/06/85.png) - -That’s it, create new account by using “Sign Up” option and you should be good to go with your Discourse setup. - -![](http://linuxpitstop.com/wp-content/uploads/2016/06/106.png) - -### Conclusion - -It is an easy to setup application and works flawlessly. It is equipped with all required features of modern day discussion board. It is available under General Public License and is 100% open source product. The simplicity, easy of use, powerful and long feature list are the most important feathers of this tool. Hope you enjoyed this article, Question? do let us know in comments please. - --------------------------------------------------------------------------------- - -via: http://linuxpitstop.com/install-discourse-on-ubuntu-linux-16-04/ - -作者:[Aun][a] -译者:[译者ID](https://github.com/译者ID) -校对:[校对者ID](https://github.com/校对者ID) - -本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 - -[a]: http://linuxpitstop.com/author/aun/ - - - - - - - - diff --git a/translated/tech/20160628 How To Setup Open Source Discussion Platform Discourse On Ubuntu Linux 16.04.md b/translated/tech/20160628 How To Setup Open Source Discussion Platform Discourse On Ubuntu Linux 16.04.md new file mode 100644 index 0000000000..742fd381dd --- /dev/null +++ b/translated/tech/20160628 How To Setup Open Source Discussion Platform Discourse On Ubuntu Linux 16.04.md @@ -0,0 +1,101 @@ +如何在 Ubuntu Linux 16.04上安装开源的Discourse论坛 +=============================================================================== + +Discourse 是一个开源的论坛, 它可以以邮件列表, 聊天室或者论坛等多种形式工作. 它是一个广受欢迎的现代的论坛工具. 在服务端,它使用Ruby on Rails 和 Postgres 搭建, 并且使用Redis caching 减少读取时间 , 在客户端, 它用浏览器的Java Script运行. 它是一个非常好的定制和构架工具. 并且它提供了转换插件对你现存的论坛进行转换例如: vBulletin, phpBB, Drupal, SMF 等等. 在这篇文章中, 我们将学习在Ubuntu操作系统下安装 Discourse. + +它是基于安全开发的, 黑客们不能轻易的发现漏洞. 它能很好的支持各个平台, 相应的调整手机和平板的显示设置. + +### Installing Discourse on Ubuntu 16.04 + +让我们开始吧 ! 最少需要1G的内存并且你要保证dockers已经安装了. 说到dockers, 它还需要安装Git. 要达到以上的两点要求我们只需要运行下面的命令. + +``` +wget -qO- https://get.docker.com/ | sh +``` + +![](http://linuxpitstop.com/wp-content/uploads/2016/06/124.png) + +用不了多久就安装好了Docker 和 Git, 安装结束以后, 创建一个 Discourse 文件夹在 /var 分区 (当然你也可以选择其他的分区). + +``` +mkdir /var/discourse +``` + +现在我们来克隆 Discourse’s Github 项目到这个新建的文件夹. + +``` +git clone https://github.com/discourse/discourse_docker.git /var/discourse +``` + +进入克隆文件夹. + +``` +cd /var/discourse +``` + +![](http://linuxpitstop.com/wp-content/uploads/2016/06/314.png) + +你将 看到“discourse-setup” 脚本文件, 运行这个脚本文件进行Discourse的初始化. + +``` +./discourse-setup +``` + +**Side note: 在安装discourse之前请确保你已经安装了邮件服务器.** + +安装向导将会问你以下六个问题. + +``` +Hostname for your Discourse? +Email address for admin account? +SMTP server address? +SMTP user name? +SMTP port [587]: +SMTP password? []: +``` + +![](http://linuxpitstop.com/wp-content/uploads/2016/06/411.png) + +当你提交了以上信息以后, 它会让你提交确认, 恩一切都很正常, 点击回车以后安装开始. + +![](http://linuxpitstop.com/wp-content/uploads/2016/06/511.png) + +现在坐下来,倒杯茶,看看有什么错误信息没有. + +![](http://linuxpitstop.com/wp-content/uploads/2016/06/610.png) + +安装成功以后看起来应该像这样. + +![](http://linuxpitstop.com/wp-content/uploads/2016/06/710.png) + +现在打开浏览器, 如果已经做了域名解析, 你可以使用你的域名来连接Discourse页面 , 否则你只能使用IP地址了. 你讲看到如下信息: + +![](http://linuxpitstop.com/wp-content/uploads/2016/06/85.png) + +就是这个, 用 “Sign Up” 选项创建一个新管理账户. + +![](http://linuxpitstop.com/wp-content/uploads/2016/06/106.png) + +### 结论 + +它是安装简便安全易用的. 它拥有当前所有论坛功能. 它支持所有的开源产品. 简单, 易用, 各类实用的功能. 希望你喜欢这篇文章你可以给我们留言. + +-------------------------------------------------------------------------------- + +via: http://linuxpitstop.com/install-discourse-on-ubuntu-linux-16-04/ + +作者:[Aun][a] +译者:[kokialoves](https://github.com/kokialoves) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]: http://linuxpitstop.com/author/aun/ + + + + + + + + From 57c3eb5ad1532b0e8ff0ade934aaf318536e3cb2 Mon Sep 17 00:00:00 2001 From: Ezio Date: Tue, 26 Jul 2016 09:51:57 +0800 Subject: [PATCH 031/122] =?UTF-8?q?20160726-1=20=E9=80=89=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...60722 7 Best Markdown Editors for Linux.md | 155 ++++++++++++++++++ 1 file changed, 155 insertions(+) create mode 100644 sources/tech/20160722 7 Best Markdown Editors for Linux.md diff --git a/sources/tech/20160722 7 Best Markdown Editors for Linux.md b/sources/tech/20160722 7 Best Markdown Editors for Linux.md new file mode 100644 index 0000000000..afe303021d --- /dev/null +++ b/sources/tech/20160722 7 Best Markdown Editors for Linux.md @@ -0,0 +1,155 @@ +7 Best Markdown Editors for Linux +====================================== + +In this article, we shall review some of the best Markdown editors you can install and use on your Linux desktop. There are numerous Markdown editors you can find for Linux but here, we want to unveil possibly the best you may choose to work with. + +![](http://www.tecmint.com/wp-content/uploads/2016/07/Best-Linux-Markdown-Editors.png) +>Best Linux Markdown Editors + +For starters, Markdown is a simple and lightweight tool written in Perl, that enables users to write plain text format and covert it to valid HTML (or XHTML). It is literally an easy-to-read, easy-to-write plain text language and a software tool for text-to-HTML conversion. + +Hoping that you have a slight understanding of what Markdown is, let us proceed to list the editors. + +### 1. Atom + +Atom is a modern, cross-platform, open-source and very powerful text editor that can work on Linux, Windows and Mac OS X operating systems. Users can customize it down to its base, minus altering any configuration files. + +It is designed with some illustrious features and these include: + +- Comes with a built-in package manager +- Smart auto-completion functionality +- Offers multiple panes +- Supports find and replace functionality +- Includes a file system browser +- Easily customizable themes +- Highly extensible using open-source packages and many more + +![](http://www.tecmint.com/wp-content/uploads/2016/07/Atom-Markdown-Editor-for-Linux.png) + +Visit Homepage: + +### 2. GNU Emacs + +Emacs is one of the popular open-source text editors you can find on the Linux platform today. It is a great editor for Markdown language, which is highly extensible and customizable. + +It’s comprehensively developed with the following amazing features: + +- Comes with an extensive built-in documentation including tutorials for beginners +- Full Unicode support for probably all human scripts +- Supports content-aware text-editing modes +- Includes syntax coloring for multiple file types +- Its highly customizable using Emacs Lisp code or GUI +- Offers a packaging system for downloading and installing various extensions plus so much more + +![](http://www.tecmint.com/wp-content/uploads/2016/07/Emacs-Markdown-Editor-for-Linux.png) +>Emacs Markdown Editor for Linux + +Visit Homepage: + +### 3. Remarkable + +Remarkable is possibly the best Markdown editor you can find on Linux, it also works on Windows operating system. It is indeed a remarkable and fully featured Markdown editor that offers users some exciting features. + +Some of its remarkable features include: + +- Supports live preview +- Supports exporting to PDF and HTML +- Also offers Github Markdown +- Supports custom CSS +- It also supports syntax highlighting +- Offers keyboard shortcuts +- Highly customizable plus and many more + +![](http://www.tecmint.com/wp-content/uploads/2016/07/Remarkable-Markdown-Editor-for-Linux.png) +>Remarkable Markdown Editor for Linux + +Visit Homepage: + +### 4. Haroopad + +Haroopad is an extensively built, cross-platform Markdown document processor for Linux, Windows and Mac OS X. It enables users to write expert-level documents of numerous formats including email, reports, blogs, presentations, blog posts and many more. + +It is fully featured with the following notable features: + +- Easily imports content +- Also exports to numerous formats +- Broadly supports blogging and mailing +- Supports several mathematical expressions +- Supports Github flavored Markdown and extensions +- Offers users some exciting themes, skins and UI components plus so much more + +![](http://www.tecmint.com/wp-content/uploads/2016/07/Haroopad-Markdown-Editor-for-Linux.png) +>Haroopad Markdown Editor for Linux + +Visit Homepage: + +### 5. ReText + +ReText is a simple, lightweight and powerful Markdown editor for Linux and several other POSIX-compatible operating systems. It also doubles as a reStructuredText editor, and has the following attributes: + +- Simple and intuitive GUI +- It is highly customizable, users can customize file syntax and configuration options +- Also supports several color schemes +- Supports use of multiple mathematical formulas +- Enables export extensions and many more + +![](http://www.tecmint.com/wp-content/uploads/2016/07/ReText-Markdown-Editor-for-Linux.png) +>ReText Markdown Editor for Linux + +Visit Homepage: + +### 6. UberWriter + +UberWriter is a simple and easy-to-use Markdown editor for Linux, it’s development was highly influenced by iA writer for Mac OS X. It is also feature rich with these remarkable features: + +- Uses pandoc to perform all text-to-HTML conversions +- Offers a clean UI +- Offers a distraction free mode, highlighting a users last sentence +- Supports spellcheck +- Also supports full screen mode +- Supports exporting to PDF, HTML and RTF using pandoc +- Enables syntax highlighting and mathematical functions plus many more + +![](http://www.tecmint.com/wp-content/uploads/2016/07/UberWriter-Markdown-Editor-for-Linux.png) +>UberWriter Markdown Editor for Linux + +Visit Homepage: + +### 7. Mark My Words + +Mark My Words is a also lightweight yet powerful Markdown editor. It’s a relatively new editor, therefore offers a handful of features including syntax highlighting, simple and intuitive GUI. + +The following are some of the awesome features yet to be bundled into the application: + +- Live preview support +- Markdown parsing and file IO +- State management +- Support for exporting to PDF and HTML +- Monitoring files for changes +- Support for preferences + +![](http://www.tecmint.com/wp-content/uploads/2016/07/MarkMyWords-Markdown-Editor-for-Linux.png) +>MarkMyWords Markdown Editor for-Linux + +Visit Homepage: + +### Conclusion + +Having walked through the list above, you probably know what Markdown editors and document processors to download and install on your Linux desktop for now. + +Note that what we consider to be the best here may reasonably not be the best for you, therefore, you can reveal to us exciting Markdown editors that you think are missing in the list and have earned the right to be mentioned here by sharing your thoughts via the feedback section below. + + +-------------------------------------------------------------------------------- + +via: http://www.tecmint.com/best-markdown-editors-for-linux/ + +作者:[Aaron Kili |][a] +译者:[译者ID](https://github.com/译者ID) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]: http://www.tecmint.com/author/aaronkili/ + + From 1d3df1c128a5b8ee6957c16a32f7f1a34ab4739f Mon Sep 17 00:00:00 2001 From: Ezio Date: Tue, 26 Jul 2016 10:26:40 +0800 Subject: [PATCH 032/122] =?UTF-8?q?=E7=BF=BB=E8=AF=91=E5=AE=8C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../20160628 Python 101 An Intro to urllib.md | 200 ------------------ .../20160628 Python 101 An Intro to urllib.md | 193 +++++++++++++++++ 2 files changed, 193 insertions(+), 200 deletions(-) delete mode 100644 sources/tech/20160628 Python 101 An Intro to urllib.md create mode 100644 translated/tech/20160628 Python 101 An Intro to urllib.md diff --git a/sources/tech/20160628 Python 101 An Intro to urllib.md b/sources/tech/20160628 Python 101 An Intro to urllib.md deleted file mode 100644 index 3fb88971db..0000000000 --- a/sources/tech/20160628 Python 101 An Intro to urllib.md +++ /dev/null @@ -1,200 +0,0 @@ -ezio is translating - -Python 101: An Intro to urllib -================================= - -The urllib module in Python 3 is a collection of modules that you can use for working with URLs. If you are coming from a Python 2 background you will note that in Python 2 you had urllib and urllib2. These are now a part of the urllib package in Python 3. The current version of urllib is made up of the following modules: - -- urllib.request -- urllib.error -- urllib.parse -- urllib.rebotparser - -We will be covering each part individually except for urllib.error. The official documentation actually recommends that you might want to check out the 3rd party library, requests, for a higher-level HTTP client interface. However, I believe that it can be useful to know how to open URLs and interact with them without using a 3rd party and it may also help you appreciate why the requests package is so popular. - ---- - -### urllib.request - -The urllib.request module is primarily used for opening and fetching URLs. Let’s take a look at some of the things you can do with the urlopen function: - -``` ->>> import urllib.request ->>> url = urllib.request.urlopen('https://www.google.com/') ->>> url.geturl() -'https://www.google.com/' ->>> url.info() - ->>> header = url.info() ->>> header.as_string() -('Date: Fri, 24 Jun 2016 18:21:19 GMT\n' - 'Expires: -1\n' - 'Cache-Control: private, max-age=0\n' - 'Content-Type: text/html; charset=ISO-8859-1\n' - 'P3P: CP="This is not a P3P policy! See ' - 'https://www.google.com/support/accounts/answer/151657?hl=en for more info."\n' - 'Server: gws\n' - 'X-XSS-Protection: 1; mode=block\n' - 'X-Frame-Options: SAMEORIGIN\n' - 'Set-Cookie: ' - 'NID=80=tYjmy0JY6flsSVj7DPSSZNOuqdvqKfKHDcHsPIGu3xFv41LvH_Jg6LrUsDgkPrtM2hmZ3j9V76pS4K_cBg7pdwueMQfr0DFzw33SwpGex5qzLkXUvUVPfe9g699Qz4cx9ipcbU3HKwrRYA; ' - 'expires=Sat, 24-Dec-2016 18:21:19 GMT; path=/; domain=.google.com; HttpOnly\n' - 'Alternate-Protocol: 443:quic\n' - 'Alt-Svc: quic=":443"; ma=2592000; v="34,33,32,31,30,29,28,27,26,25"\n' - 'Accept-Ranges: none\n' - 'Vary: Accept-Encoding\n' - 'Connection: close\n' - '\n') ->>> url.getcode() -200 -``` - -Here we import our module and ask it to open Google’s URL. Now we have an HTTPResponse object that we can interact with. The first thing we do is call the geturl method which will return the URL of the resource that was retrieved. This is useful for finding out if we followed a redirect. - -Next we call info, which will return meta-data about the page, such as headers. Because of this, we assign that result to our headers variable and then call its as_string method. This prints out the header we received from Google. You can also get the HTTP response code by calling getcode, which in this case was 200, which means it worked successfully. - -If you’d like to see the HTML of the page, you can call the read method on the url variable we created. I am not reproducing that here as the output will be quite long. - -Please note that the request object defaults to a GET request unless you specify the data parameter. Should you pass in the data parameter, then the request object will issue a POST request instead. - ---- - -### Downloading a file - -A typical use case for the urllib package is for downloading a file. Let’s find out a couple of ways we can accomplish this task: - -``` ->>> import urllib.request ->>> url = 'http://www.blog.pythonlibrary.org/wp-content/uploads/2012/06/wxDbViewer.zip' ->>> response = urllib.request.urlopen(url) ->>> data = response.read() ->>> with open('/home/mike/Desktop/test.zip', 'wb') as fobj: -... fobj.write(data) -... -``` - -Here we just open a URL that leads us to a zip file stored on my blog. Then we read the data and write it out to disk. An alternate way to accomplish this is to use urlretrieve: - -``` ->>> import urllib.request ->>> url = 'http://www.blog.pythonlibrary.org/wp-content/uploads/2012/06/wxDbViewer.zip' ->>> tmp_file, header = urllib.request.urlretrieve(url) ->>> with open('/home/mike/Desktop/test.zip', 'wb') as fobj: -... with open(tmp_file, 'rb') as tmp: -... fobj.write(tmp.read()) -``` - -The urlretrieve method will copy a network object to a local file. The file it copies to is randomly named and goes into the temp directory unless you use the second parameter to urlretrieve where you can actually specify where you want the file saved. This will save you a step and make your code much simpler: - -``` ->>> import urllib.request ->>> url = 'http://www.blog.pythonlibrary.org/wp-content/uploads/2012/06/wxDbViewer.zip' ->>> urllib.request.urlretrieve(url, '/home/mike/Desktop/blog.zip') -('/home/mike/Desktop/blog.zip', - ) -``` - -As you can see, it returns the location of where it saved the file and the header information from the request. - -### Specifying Your User Agent - -When you visit a website with your browser, the browser tells the website who it is. This is called the user-agent string. Python’s urllib identifies itself as Python-urllib/x.y where the x and y are major and minor version numbers of Python. Some websites won’t recognize this user-agent string and will behave in strange ways or not work at all. Fortunately, it’s easy for you to set up your own custom user-agent string: - -``` ->>> import urllib.request ->>> user_agent = ' Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:47.0) Gecko/20100101 Firefox/47.0' ->>> url = 'http://www.whatsmyua.com/' ->>> headers = {'User-Agent': user_agent} ->>> request = urllib.request.Request(url, headers=headers) ->>> with urllib.request.urlopen(request) as response: -... with open('/home/mdriscoll/Desktop/user_agent.html', 'wb') as out: -... out.write(response.read()) -``` - -Here we set up our user agent to Mozilla FireFox and we set out URL to which will tell us what it thinks our user-agent string is. Then we create a Request instance using our url and headers and pass that to urlopen. Finally we save the result. If you open the result file, you will see that we successfully changed our user-agent string. Feel free to try out a few different strings with this code to see how it will change. - ---- - -### urllib.parse - -The urllib.parse library is your standard interface for breaking up URL strings and combining them back together. You can use it to convert a relative URL to an absolute URL, for example. Let’s try using it to parse a URL that includes a query: - -``` ->>> from urllib.parse import urlparse ->>> result = urlparse('https://duckduckgo.com/?q=python+stubbing&t=canonical&ia=qa') ->>> result -ParseResult(scheme='https', netloc='duckduckgo.com', path='/', params='', query='q=python+stubbing&t=canonical&ia=qa', fragment='') ->>> result.netloc -'duckduckgo.com' ->>> result.geturl() -'https://duckduckgo.com/?q=python+stubbing&t=canonical&ia=qa' ->>> result.port -None -``` - -Here we import the urlparse function and pass it an URL that contains a search query to the duckduckgo website. My query was to look up articles on “python stubbing”. As you can see, it returned a ParseResult object that you can use to learn more about the URL. For example, you can get the port information (None in this case), the network location, path and much more. - -### Submitting a Web Form - -This module also holds the urlencode method, which is great for passing data to a URL. A typical use case for the urllib.parse library is submitting a web form. Let’s find out how you might do that by having the duckduckgo search engine look for Python: - -``` ->>> import urllib.request ->>> import urllib.parse ->>> data = urllib.parse.urlencode({'q': 'Python'}) ->>> data -'q=Python' ->>> url = 'http://duckduckgo.com/html/' ->>> full_url = url + '?' + data ->>> response = urllib.request.urlopen(full_url) ->>> with open('/home/mike/Desktop/results.html', 'wb') as f: -... f.write(response.read()) -``` - -This is pretty straightforward. Basically we want to submit a query to duckduckgo ourselves using Python instead of a browser. To do that, we need to construct our query string using urlencode. Then we put that together to create a fully qualified URL and use urllib.request to submit the form. We then grab the result and save it to disk. - ---- - -### urllib.robotparser - -The robotparser module is made up of a single class, RobotFileParser. This class will answer questions about whether or not a specific user agent can fetch a URL that has a published robot.txt file. The robots.txt file will tell a web scraper or robot what parts of the server should not be accessed. Let’s take a look at a simple example using ArsTechnica’s website: - -``` ->>> import urllib.robotparser ->>> robot = urllib.robotparser.RobotFileParser() ->>> robot.set_url('http://arstechnica.com/robots.txt') -None ->>> robot.read() -None ->>> robot.can_fetch('*', 'http://arstechnica.com/') -True ->>> robot.can_fetch('*', 'http://arstechnica.com/cgi-bin/') -False -``` - -Here we import the robot parser class and create an instance of it. Then we pass it a URL that specifies where the website’s robots.txt file resides. Next we tell our parser to read the file. Now that that’s done, we give it a couple of different URLs to find out which ones we can crawl and which ones we can’t. We quickly see that we can access the main site, but not the cgi-bin. - ---- - -### Wrapping Up - -You have reached the point that you should be able to use Python’s urllib package competently. We learned how to download a file, submit a web form, change our user agent and access a robots.txt file in this chapter. The urllib has a lot of additional functionality that is not covered here, such as website authentication. However, you might want to consider switching to the requests library before trying to do authentication with urllib as the requests implementation is a lot easier to understand and debug. I also want to note that Python has support for Cookies via its http.cookies module although that is also wrapped quite well in the requests package. You should probably consider trying both to see which one makes the most sense to you. - --------------------------------------------------------------------------------- - -via: http://www.blog.pythonlibrary.org/2016/06/28/python-101-an-intro-to-urllib/ - -作者:[Mike][a] -译者:[译者ID](https://github.com/译者ID) -校对:[校对者ID](https://github.com/校对者ID) - -本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创翻译,[Linux中国](https://linux.cn/) 荣誉推出 - -[a]: http://www.blog.pythonlibrary.org/author/mld/ - - - - - - - diff --git a/translated/tech/20160628 Python 101 An Intro to urllib.md b/translated/tech/20160628 Python 101 An Intro to urllib.md new file mode 100644 index 0000000000..641ac2baf1 --- /dev/null +++ b/translated/tech/20160628 Python 101 An Intro to urllib.md @@ -0,0 +1,193 @@ +Python 101: urllib 简介 +================================= + +Python 3 的 urllib 模块是一堆可以处理 URL 的组件集合。如果你有 Python 2 背景,那么你就会注意到 Python 2 中有 urllib 和 urllib2 两个版本的模块。这些现在都是 Python 3 的 urllib 包的一部分。当前版本的 urllib 包括下面几部分: + +- urllib.request +- urllib.error +- urllib.parse +- urllib.rebotparser + +接下来我们会分开讨论除了 urllib.error 以外的几部分。官方文档实际推荐你尝试第三方库, requests,一个高级的 HTTP 客户端接口。然而我依然认为知道如何不依赖第三方库打开 URL 并与之进行交互是很有用的,而且这也可以帮助你理解为什么 requests 包是如此的流行。 + +--- + +### urllib.request + +urllib.request 模块期初是用来打开和获取 URL 的。让我们看看你可以用函数 urlopen可以做的事: + + +``` +>>> import urllib.request +>>> url = urllib.request.urlopen('https://www.google.com/') +>>> url.geturl() +'https://www.google.com/' +>>> url.info() + +>>> header = url.info() +>>> header.as_string() +('Date: Fri, 24 Jun 2016 18:21:19 GMT\n' + 'Expires: -1\n' + 'Cache-Control: private, max-age=0\n' + 'Content-Type: text/html; charset=ISO-8859-1\n' + 'P3P: CP="This is not a P3P policy! See ' + 'https://www.google.com/support/accounts/answer/151657?hl=en for more info."\n' + 'Server: gws\n' + 'X-XSS-Protection: 1; mode=block\n' + 'X-Frame-Options: SAMEORIGIN\n' + 'Set-Cookie: ' + 'NID=80=tYjmy0JY6flsSVj7DPSSZNOuqdvqKfKHDcHsPIGu3xFv41LvH_Jg6LrUsDgkPrtM2hmZ3j9V76pS4K_cBg7pdwueMQfr0DFzw33SwpGex5qzLkXUvUVPfe9g699Qz4cx9ipcbU3HKwrRYA; ' + 'expires=Sat, 24-Dec-2016 18:21:19 GMT; path=/; domain=.google.com; HttpOnly\n' + 'Alternate-Protocol: 443:quic\n' + 'Alt-Svc: quic=":443"; ma=2592000; v="34,33,32,31,30,29,28,27,26,25"\n' + 'Accept-Ranges: none\n' + 'Vary: Accept-Encoding\n' + 'Connection: close\n' + '\n') +>>> url.getcode() +200 +``` + +在这里我们包含了需要的模块,然后告诉它打开 Google 的 URL。现在我们就有了一个可以交互的 HTTPResponse 对象。我们要做的第一件事是调用方法 geturl ,它会返回根据 URL 获取的资源。这可以让我们发现 URL 是否进行了重定向。 + +接下来调用 info ,它会返回网页的元数据,比如头信息。因此,我们可以将结果赋给我们的 headers 变量,然后调用它的方法 as_string 。就可以打印出我们从 Google 收到的头信息。你也可以通过 getcode 得到网页的 HTTP 响应码,当前情况下就是 200,意思是正常工作。 + +如果你想看看网页的 HTML 代码,你可以调用变量 url 的方法 read。我不准备再现这个过程,因为输出结果太长了。 + +请注意 request 对象默认是 GET 请求,除非你指定它的 data 参数。你应该给它传递 data 参数,这样 request 对象才会变成 POST 请求。 + +--- + +### 下载文件 + +urllib 一个典型的应用场景是下载文件。让我们看看几种可以完成这个任务的方法: + +``` +>>> import urllib.request +>>> url = 'http://www.blog.pythonlibrary.org/wp-content/uploads/2012/06/wxDbViewer.zip' +>>> response = urllib.request.urlopen(url) +>>> data = response.read() +>>> with open('/home/mike/Desktop/test.zip', 'wb') as fobj: +... fobj.write(data) +... +``` + +这个例子中我们打开一个保存在我的博客上的 zip 压缩文件的 URL。然后我们读出数据并将数据写到磁盘。一个替代方法是使用 urlretrieve : + +``` +>>> import urllib.request +>>> url = 'http://www.blog.pythonlibrary.org/wp-content/uploads/2012/06/wxDbViewer.zip' +>>> tmp_file, header = urllib.request.urlretrieve(url) +>>> with open('/home/mike/Desktop/test.zip', 'wb') as fobj: +... with open(tmp_file, 'rb') as tmp: +... fobj.write(tmp.read()) +``` + +方法 urlretrieve 会把网络对象拷贝到本地文件。除非你在使用 urlretrieve 的第二个参数指定你要保存文件的路径,否则这个文件在本地是随机命名的并且是保存在临时文件夹。这个可以为你节省一步操作,并且使代码开起来更简单: + +``` +>>> import urllib.request +>>> url = 'http://www.blog.pythonlibrary.org/wp-content/uploads/2012/06/wxDbViewer.zip' +>>> urllib.request.urlretrieve(url, '/home/mike/Desktop/blog.zip') +('/home/mike/Desktop/blog.zip', + ) +``` + +如你所见,它返回了文件保存的路径,以及从请求得来的头信息。 + +### 设置你的用户代理 + +当你使用浏览器访问网页时,浏览器会告诉网站它是谁。这就是所谓的 user-agent 字段。Python 的 urllib 会表示他自己为 Python-urllib/x.y , 其中 x 和 y 是你使用的 Python 的主、次版本号。有一些网站不认识这个用户代理字段,然后网站的可能会有奇怪的表现或者根本不能正常工作。辛运的是你可以很轻松的设置你自己的 user-agent 字段。 + +``` +>>> import urllib.request +>>> user_agent = ' Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:47.0) Gecko/20100101 Firefox/47.0' +>>> url = 'http://www.whatsmyua.com/' +>>> headers = {'User-Agent': user_agent} +>>> request = urllib.request.Request(url, headers=headers) +>>> with urllib.request.urlopen(request) as response: +... with open('/home/mdriscoll/Desktop/user_agent.html', 'wb') as out: +... out.write(response.read()) +``` + +这里设置我们的用户代理为 Mozilla FireFox ,然后我们访问 , 它会告诉我们它识别出的我们的 user-agent 字段。之后我们将 url 和我们的头信息传给 urlopen 创建一个 Request 实例。最后我们保存这个结果。如果你打开这个结果,你会看到我们成功的修改了自己的 user-agent 字段。使用这段代码尽情的尝试不同的值来看看它是如何改变的。 + +--- + +### urllib.parse + +urllib.parse 库是用来拆分和组合 URL 字符串的标准接口。比如,你可以使用它来转换一个相对的 URL 为绝对的 URL。让我们试试用它来转换一个包含查询的 URL : + + +``` +>>> from urllib.parse import urlparse +>>> result = urlparse('https://duckduckgo.com/?q=python+stubbing&t=canonical&ia=qa') +>>> result +ParseResult(scheme='https', netloc='duckduckgo.com', path='/', params='', query='q=python+stubbing&t=canonical&ia=qa', fragment='') +>>> result.netloc +'duckduckgo.com' +>>> result.geturl() +'https://duckduckgo.com/?q=python+stubbing&t=canonical&ia=qa' +>>> result.port +None +``` + +这里我们导入了函数 urlparse , 并且把一个包含搜索查询 duckduckgo 的 URL 作为参数传给它。我的查询的关于 “python stubbing” 的文章。如你所见,它返回了一个 ParseResult 对象,你可以用这个对象了解更多关于 URL 的信息。举个例子,你可以获取到短信息(此处的没有端口信息),网络位置,路径和很多其他东西。 + +### 提交一个 Web 表单 + +这个模块还有一个方法 urlencode 可以向 URL 传输数据。 urllib.parse 的一个典型使用场景是提交 Web 表单。让我们通过搜索引擎 duckduckgo 搜索 Python 来看看这个功能是怎么工作的。 + +``` +>>> import urllib.request +>>> import urllib.parse +>>> data = urllib.parse.urlencode({'q': 'Python'}) +>>> data +'q=Python' +>>> url = 'http://duckduckgo.com/html/' +>>> full_url = url + '?' + data +>>> response = urllib.request.urlopen(full_url) +>>> with open('/home/mike/Desktop/results.html', 'wb') as f: +... f.write(response.read()) +``` + +这个例子很直接。基本上我们想使用 Python 而不是浏览器向 duckduckgo 提交一个查询。要完成这个我们需要使用 urlencode 构建我们的查询字符串。然后我们把这个字符串和网址拼接成一个完整的正确 URL ,然后使用 urllib.request 提交这个表单。最后我们就获取到了结果然后保存到磁盘上。 + +--- + +### urllib.robotparser + +robotparser 模块是由一个单独的类 —— RobotFileParser —— 构成的。这个类会回答诸如一个特定的用户代理可以获取已经设置 robot.txt 的网站。 robot.txt 文件会告诉网络爬虫或者机器人当前网站的那些部分是不允许被访问的。让我们看一个简单的例子: + +``` +>>> import urllib.robotparser +>>> robot = urllib.robotparser.RobotFileParser() +>>> robot.set_url('http://arstechnica.com/robots.txt') +None +>>> robot.read() +None +>>> robot.can_fetch('*', 'http://arstechnica.com/') +True +>>> robot.can_fetch('*', 'http://arstechnica.com/cgi-bin/') +False +``` + +这里我们导入了 robot 分析器类,然后创建一个实例。然后我们给它传递一个表明网站 robots.txt 位置的 URL 。接下来我们告诉分析器来读取这个文件。现在就完成了,我们给它了一组不同的 URL 让它找出那些我们可以爬取而那些不能爬取。我们很快就看到我们可以访问主站但是不包括 cgi-bin 路径。 + +--- + +### 总结一下 + +现在你就有能力使用 Python 的 urllib 包了。在这一节里,我们学习了如何下载文件,提交 Web 表单,修改自己的用户代理以及访问 robots.txt。 urllib 还有一大堆附加功能没有在这里提及,比如网站授权。然后你可能会考虑在使用 urllib 进行认证之前切换到 requests 库,因为 requests 已经以更易用和易调试的方式实现了这些功能。我同时也希望提醒你 Python 已经通过 http.cookies 模块支持 Cookies 了,虽然在 request 包里也很好的封装了这个功能。你应该可能考虑同时试试两个来决定那个最适合你。 + +-------------------------------------------------------------------------------- + +via: http://www.blog.pythonlibrary.org/2016/06/28/python-101-an-intro-to-urllib/ + +作者:[Mike][a] +译者:[Ezio](https://github.com/oska874) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创翻译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]: http://www.blog.pythonlibrary.org/author/mld/ From 91e04d1ca4ec0b72dc404850c2f08f921615d20c Mon Sep 17 00:00:00 2001 From: Mike Date: Tue, 26 Jul 2016 16:32:01 +0800 Subject: [PATCH 033/122] translated/tech/20160706 Doing for User Space What We Did for Kernel Space.md (#4223) --- ...User Space What We Did for Kernel Space.md | 96 ------------------- ...User Space What We Did for Kernel Space.md | 95 ++++++++++++++++++ 2 files changed, 95 insertions(+), 96 deletions(-) delete mode 100644 sources/tech/20160706 Doing for User Space What We Did for Kernel Space.md create mode 100644 translated/tech/20160706 Doing for User Space What We Did for Kernel Space.md diff --git a/sources/tech/20160706 Doing for User Space What We Did for Kernel Space.md b/sources/tech/20160706 Doing for User Space What We Did for Kernel Space.md deleted file mode 100644 index 743114c481..0000000000 --- a/sources/tech/20160706 Doing for User Space What We Did for Kernel Space.md +++ /dev/null @@ -1,96 +0,0 @@ -MikeCoder Translating... - -Doing for User Space What We Did for Kernel Space -======================================================= - -I believe the best and worst thing about Linux is its hard distinction between kernel space and user space. - -Without that distinction, Linux never would have become the most leveraged operating system in the world. Today, Linux has the largest range of uses for the largest number of users—most of whom have no idea they are using Linux when they search for something on Google or poke at their Android phones. Even Apple stuff wouldn't be what it is (for example, using BSD in its computers) were it not for Linux's success. - -Not caring about user space is a feature of Linux kernel development, not a bug. As Linus put it on our 2003 Geek Cruise, "I only do kernel stuff...I don't know what happens outside the kernel, and I don't much care. What happens inside the kernel I care about." After Andrew Morton gave me additional schooling on the topic a couple years later on another Geek Cruise, I wrote: - ->Kernel space is where the Linux species lives. User space is where Linux gets put to use, along with a lot of other natural building materials. The division between kernel space and user space is similar to the division between natural materials and stuff humans make out of those materials. - -A natural outcome of this distinction, however, is for Linux folks to stay relatively small as a community while the world outside depends more on Linux every second. So, in hope that we can enlarge our number a bit, I want to point us toward two new things. One is already hot, and the other could be. - -The first is [blockchain][1], made famous as the distributed ledger used by Bitcoin, but useful for countless other purposes as well. At the time of this writing, interest in blockchain is [trending toward the vertical][2]. - -![](http://www.linuxjournal.com/files/linuxjournal.com/ufiles/imagecache/large-550px-centered/u1000009/12042f1.png) ->Figure 1. Google Trends for Blockchain - -The second is self-sovereign identity. To explain that, let me ask who and what you are. - -If your answers come from your employer, your doctor, the Department of Motor Vehicles, Facebook, Twitter or Google, they are each administrative identifiers: entries in namespaces each of those organizations control, entirely for their own convenience. As Timothy Ruff of [Evernym][3] explains, "You don't exist for them. Only your identifier does." It's the dependent variable. The independent variable—the one controlling the identifier—is the organization. - -If your answer comes from your self, we have a wide-open area for a new development category—one where, finally, we can be set fully free in the connected world. - -The first person to explain this, as far as I know, was [Devon Loffreto][4] He wrote "What is 'Sovereign Source Authority'?" in February 2012, on his blog, [The Moxy Tongue][5]. In "[Self-Sovereign Identity][6]", published in February 2016, he writes: - ->Self-Sovereign Identity must emit directly from an individual human life, and not from within an administrative mechanism...self-Sovereign Identity references every individual human identity as the origin of source authority. A self-Sovereign identity produces an administrative trail of data relations that begin and resolve to individual humans. Every individual human may possess a self-Sovereign identity, and no person or abstraction of any type created may alter this innate human Right. A self-Sovereign identity is the root of all participation as a valued social being within human societies of any type. - -To put this in Linux terms, only the individual has root for his or her own source identity. In the physical world, this is a casual thing. For example, my own portfolio of identifiers includes: - -- David Allen Searls, which my parents named me. -- David Searls, the name I tend to use when I suspect official records are involved. -- Dave, which is what most of my relatives and old friends call me. -- Doc, which is what most people call me. - -As the sovereign source authority over the use of those, I can jump from one to another in different contexts and get along pretty well. But, that's in the physical world. In the virtual one, it gets much more complicated. In addition to all the above, I am @dsearls (my Twitter handle) and dsearls (my handle in many other net-based services). I am also burdened by having my ability to relate contained within hundreds of different silos, each with their own logins and passwords. - -You can get a sense of how bad this is by checking the list of logins and passwords on your browser. On Firefox alone, I have hundreds of them. Many are defunct (since my collection dates back to Netscape days), but I would guess that I still have working logins to hundreds of companies I need to deal with from time to time. For all of them, I'm the dependent variable. It's not the other way around. Even the term "user" testifies to the subordinate dependency that has become a primary fact of life in the connected world. - -Today, the only easy way to bridge namespaces is via the compromised convenience of "Log in with Facebook" or "Log in with Twitter". In both of those cases, each of us is even less ourselves or in any kind of personal control over how we are known (if we wish to be knowable at all) to other entities in the connected world. - -What we have needed from the start are personal systems for instantiating our sovereign selves and choosing how to reveal and protect ourselves when dealing with others in the connected world. For lack of that ability, we are deep in a metastasized mess that Shoshana Zuboff calls "surveillance capitalism", which she says is: - ->...unimaginable outside the inscrutable high velocity circuits of Google's digital universe, whose signature feature is the Internet and its successors. While the world is riveted by the showdown between Apple and the FBI, the real truth is that the surveillance capabilities being developed by surveillance capitalists are the envy of every state security agency. - -Then she asks, "How can we protect ourselves from its invasive power?" - -I suggest self-sovereign identity. I believe it is only there that we have both safety from unwelcome surveillance and an Archimedean place to stand in the world. From that place, we can assert full agency in our dealings with others in society, politics and business. - -I came to this provisional conclusion during [ID2020][7], a gathering at the UN on May. It was gratifying to see Devon Loffreto there, since he's the guy who got the sovereign ball rolling in 2013. Here's [what I wrote about][8] it at the time, with pointers to Devon's earlier posts (such as one sourced above). - -Here are three for the field's canon: - -- "[Self-Sovereign Identity][9]" by Devon Loffreto. -- "[System or Human First][10]" by Devon Loffreto. -- "[The Path to Self-Sovereign Identity][11]" by Christopher Allen. - -A one-pager from Evernym, [digi.me][12], [iRespond][13] and [Respect Network][14] also was circulated there, contrasting administrative identity (which it calls the "current model") with the self-sovereign one. In it is the graphic shown in Figure 2. - -![](http://www.linuxjournal.com/files/linuxjournal.com/ufiles/imagecache/large-550px-centered/u1000009/12042f2.jpg) ->Figure 2. Current Model of Identity vs. Self-Sovereign Identity - -The [platform][15] for this is Sovrin, explained as a "Fully open-source, attribute-based, sovereign identity graph platform on an advanced, dedicated, permissioned, distributed ledger" There's a [white paper][16] too. The code is called [plenum][17], and it's at GitHub. - -Here—and places like it—we can do for user space what we've done for the last quarter century for kernel space. - --------------------------------------------------------------------------------- - -via: https://www.linuxjournal.com/content/doing-user-space-what-we-did-kernel-space - -作者:[Doc Searls][a] -译者:[译者ID](https://github.com/译者ID) -校对:[校对者ID](https://github.com/校对者ID) - -本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 - -[a]: https://www.linuxjournal.com/users/doc-searls -[1]: https://en.wikipedia.org/wiki/Block_chain_%28database%29 -[2]: https://www.google.com/trends/explore#q=blockchain -[3]: http://evernym.com/ -[4]: https://twitter.com/nzn -[5]: http://www.moxytongue.com/2012/02/what-is-sovereign-source-authority.html -[6]: http://www.moxytongue.com/2016/02/self-sovereign-identity.html -[7]: http://www.id2020.org/ -[8]: http://blogs.harvard.edu/doc/2013/10/14/iiw-challenge-1-sovereign-identity-in-the-great-silo-forest -[9]: http://www.moxytongue.com/2016/02/self-sovereign-identity.html -[10]: http://www.moxytongue.com/2016/05/system-or-human.html -[11]: http://www.lifewithalacrity.com/2016/04/the-path-to-self-soverereign-identity.html -[12]: https://get.digi.me/ -[13]: http://irespond.com/ -[14]: https://www.respectnetwork.com/ -[15]: http://evernym.com/technology -[16]: http://evernym.com/assets/doc/Identity-System-Essentials.pdf?v=167284fd65 -[17]: https://github.com/evernym/plenum diff --git a/translated/tech/20160706 Doing for User Space What We Did for Kernel Space.md b/translated/tech/20160706 Doing for User Space What We Did for Kernel Space.md new file mode 100644 index 0000000000..0b31016003 --- /dev/null +++ b/translated/tech/20160706 Doing for User Space What We Did for Kernel Space.md @@ -0,0 +1,95 @@ +在用户空间做我们会在内核空间做的事情 +======================================================= + +我相信,Linux 最好也是最坏的事情,就是内核空间和用户空间之间的巨大差别。 + +但是如果抛开这个区别,Linux 可能也不会成为世界上影响力最大的操作系统。如今,Linux 已经拥有世界上最大数量的用户,和最大范围的应用。尽管大多数用户并不知道,当他们进行谷歌搜索,或者触摸安卓手机的时候,他们其实正在使用 Linux。如果不是 Linux 的巨大成功,Apple 公司也可能并不会成为现在这样(苹果在他们的电脑产品中使用 BSD 发行版)。 + +不用担心,用户空间是 Linux 内核开发中的一个特性,并不是一个缺陷。正如 Linus 在 2003 的极客巡航中提到的那样,“”我只做内核相关技术……我并不知道内核之外发生的事情,而且我并不关心。我只关注内核部分发生的事情。” 在 Andrew Morton 在多年之后的另一个极客巡航上给我上了另外的一课,我写到: + +> 内核空间是 Linux 核心存在的地方。用户空间是使用 Linux 时使用的空间,和其他的自然的建筑材料一样。内核空间和用户空间的区别,和自然材料和人类从中生产的人造材料的区别很类似。 + +这个区别的自然而然的结果,就是尽管外面的世界一刻也离不开 Linux, 但是 Linux 社区还是保持相对较小。所以,为了增加我们社区团体的数量,我希望指出两件事情。第一件已经非常火热,另外一件可能热门。 + +第一件事情就是 [blockchain][1],出自著名的分布式货币,比特币之手。当你正在阅读这篇文章的同时,对 blockchain 的[兴趣已经直线上升][2]。 + +![](http://www.linuxjournal.com/files/linuxjournal.com/ufiles/imagecache/large-550px-centered/u1000009/12042f1.png) +> 图1. 谷歌 Blockchain 的趋势 + +第二件事就是自主身份。为了解释这个,让我先来问你,你是谁或者你是什么。 + +如果你从你的雇员,你的医生,或者车管所,Facebook,Twitter 或者谷歌上得到答案,你就会发现他们每一个都有明显的社会性: 为了他们自己的便利,在进入这些机构的控制前,他们都会添加自己的命名空间。正如 Timothy Ruff 在 [Evernym][3] 中解释的,”你并不为了他们而存在,你只为了自己的身份而活。“。你的身份可能会变化,但是唯一不变的就是控制着身份的人,也就是这个组织。 + +如果你的答案出自你自己,我们就有一个广大空间来发展一个新的领域,在这个领域中,我们完全自由。 + +第一个解释这个的人,据我所知,是 [Devon Loffreto][4]。在 2012 年 2 月,在的他的博客中,他写道 ”什么是' Sovereign Source Authority'?“,[Moxy Tongue][5]。在他发表在 2016 年 2 月的 "[Self-Sovereign Identity][6]" 中,他写道: + +> 自主身份必须是独立个人提出的,并且不包含社会因素。。。自主身份源于每个个体对其自身本源的认识。 一个自主身份可以为个体带来新的社会面貌。每个个体都可能为自己生成一个自主身份,并且这并不会改变固有的人权。使用自主身份机制是所有参与者参与的基石,并且 依旧可以同各种形式的人类社会保持联系。 + +为了将这个发布在 Linux 条款中,只有个人才能为他或她设定一个自己的开源社区身份。这在现实实践中,这只是一个非常偶然的事件。举个例子,我自己的身份包括: + +- David Allen Searls,我父母会这样叫我。 +- David Searls,正式场合下我会这么称呼自己。 +- Dave,我的亲戚和好朋友会这么叫我。 +- Doc,大多数人会这么叫我。 + +在上述提到的身份认证中,我可以在不同的情景中轻易的转换。但是,这只是在现实世界中。在虚拟世界中,这就变得非常困难。除了上述的身份之外,我还可以是 @dsearls(我的 twitter 账号) 和 dsearls (其他的网络账号)。然而为了记住成百上千的不同账号的登录名和密码,我已经不堪重负。 + +你可以在你的浏览器上感受到这个糟糕的体验。在火狐上,我有成百上千个用户名密码。很多已经废弃(很多都是从 Netscape 时代遗留下来的),但是我依旧假设我有时会有大量的工作账号需要处理。对于这些,我只是被动接受者。没有其他的解决方法。甚至一些安全较低的用户认证,已经成为了现实世界中不可缺少的一环。 + +现在,最简单的方式来联系账号,就是通过 "Log in with Facebook" 或者 "Login in with Twitter" 来进行身份认证。在这些例子中,我们中的每一个甚至并不是真正意义上的自己,或者某种程度上是我们希望被大家认识的自己(如果我们希望被其他人认识的话)。 + +我们从一开始就需要的是一个可以实体化我们的自主身份和交流时选择如何保护和展示自身的个人系统。因为缺少这个能力,我们现在陷入混乱。Shoshana Zuboff 称之为 "监视资本主义",她如此说道: + +>...难以想象,在见证了互联网和获得了的巨大成功的谷歌背后。世界因 Apple 和 FBI 的对决而紧密联系在一起。真相就是,被热衷于监视的资本家开发监视系统,是每一个国家安全机构真正的恶。 + +然后,她问道,”我们怎样才能保护自己远离他人的影响?“ + +我建议使用自主身份。我相信这是我们唯一的方式,来保证我们从一个被监视的世界中脱离出来。以此为基础,我们才可以完全无顾忌的和社会,政治,商业上的人交流。 + +我在五月联合国举行的 [ID2020][7] 会议中总结了这个临时的结论。很高兴,Devon Loffreto 也在那,自从他在2013年被选为作为轮值主席之后。这就是[我曾经写的一些文章][8],引用了 Devon 的早期博客(比如上面的原文)。 + +这有三篇这个领域的准则: + +- "[Self-Sovereign Identity][9]" - Devon Loffreto. +- "[System or Human First][10]" - Devon Loffreto. +- "[The Path to Self-Sovereign Identity][11]" - Christopher Allen. + +从Evernym 的简要说明中,[digi.me][12], [iRespond][13] 和 [Respect Network][14] 也被包括在内。自主身份和社会身份 (也被称为”current model“) 的对比结果,显示在图二中。 + +![](http://www.linuxjournal.com/files/linuxjournal.com/ufiles/imagecache/large-550px-centered/u1000009/12042f2.jpg) +> 图 2. Current Model 身份 vs. 自主身份 + +为此而生的[平台][15]就是 Sovrin,也被解释为“”依托于先进技术的,授权机制的,分布式货币上的一个完全开源,基于标识,声明身份的图平台“ 同时,这也有一本[白皮书][16]。代号为 [plenum][17],而且它在 Github 上。 + +在这-或者其他类似的地方-我们就可以在用户空间中重现我们在上一个的四分之一世纪中已经做过的事情。 + + +-------------------------------------------------------------------------------- + +via: https://www.linuxjournal.com/content/doing-user-space-what-we-did-kernel-space + +作者:[Doc Searls][a] +译者:[译者ID](https://github.com/MikeCoder) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]: https://www.linuxjournal.com/users/doc-searls +[1]: https://en.wikipedia.org/wiki/Block_chain_%28database%29 +[2]: https://www.google.com/trends/explore#q=blockchain +[3]: http://evernym.com/ +[4]: https://twitter.com/nzn +[5]: http://www.moxytongue.com/2012/02/what-is-sovereign-source-authority.html +[6]: http://www.moxytongue.com/2016/02/self-sovereign-identity.html +[7]: http://www.id2020.org/ +[8]: http://blogs.harvard.edu/doc/2013/10/14/iiw-challenge-1-sovereign-identity-in-the-great-silo-forest +[9]: http://www.moxytongue.com/2016/02/self-sovereign-identity.html +[10]: http://www.moxytongue.com/2016/05/system-or-human.html +[11]: http://www.lifewithalacrity.com/2016/04/the-path-to-self-soverereign-identity.html +[12]: https://get.digi.me/ +[13]: http://irespond.com/ +[14]: https://www.respectnetwork.com/ +[15]: http://evernym.com/technology +[16]: http://evernym.com/assets/doc/Identity-System-Essentials.pdf?v=167284fd65 +[17]: https://github.com/evernym/plenum From 2982eaea05cd7496e216a36e0f3e4662418905ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=91=A8=E5=AE=B6=E6=9C=AA?= Date: Tue, 26 Jul 2016 17:12:11 +0800 Subject: [PATCH 034/122] Translating by GitFuture [07.26] --- .../20160705 How to Encrypt a Flash Drive Using VeraCrypt.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sources/tech/20160705 How to Encrypt a Flash Drive Using VeraCrypt.md b/sources/tech/20160705 How to Encrypt a Flash Drive Using VeraCrypt.md index 2dd2ae024f..27a0b950bd 100644 --- a/sources/tech/20160705 How to Encrypt a Flash Drive Using VeraCrypt.md +++ b/sources/tech/20160705 How to Encrypt a Flash Drive Using VeraCrypt.md @@ -1,3 +1,5 @@ +Translating by GitFuture [07.26] + How to Encrypt a Flash Drive Using VeraCrypt ============================================ From 9e955cfb872c86914a5e2693803b1ddad52a77eb Mon Sep 17 00:00:00 2001 From: Locez Date: Tue, 26 Jul 2016 07:36:41 -0500 Subject: [PATCH 035/122] translating by locez --- sources/tech/20160722 7 Best Markdown Editors for Linux.md | 1 + 1 file changed, 1 insertion(+) diff --git a/sources/tech/20160722 7 Best Markdown Editors for Linux.md b/sources/tech/20160722 7 Best Markdown Editors for Linux.md index afe303021d..b4b05a41f5 100644 --- a/sources/tech/20160722 7 Best Markdown Editors for Linux.md +++ b/sources/tech/20160722 7 Best Markdown Editors for Linux.md @@ -1,3 +1,4 @@ +translating by Locez 7 Best Markdown Editors for Linux ====================================== From f50bf5b4f7d953ca0aa23b4822adbf3326fa59e3 Mon Sep 17 00:00:00 2001 From: ChrisLeeGit Date: Wed, 27 Jul 2016 15:36:59 +0800 Subject: [PATCH 036/122] =?UTF-8?q?=E5=AE=8C=E6=88=90=E7=BF=BB=E8=AF=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...technologies in Fedora - systemd-nspawn.md | 108 ------------------ ...technologies in Fedora - systemd-nspawn.md | 99 ++++++++++++++++ 2 files changed, 99 insertions(+), 108 deletions(-) delete mode 100644 sources/tech/20160621 Container technologies in Fedora - systemd-nspawn.md create mode 100644 translated/tech/20160621 Container technologies in Fedora - systemd-nspawn.md diff --git a/sources/tech/20160621 Container technologies in Fedora - systemd-nspawn.md b/sources/tech/20160621 Container technologies in Fedora - systemd-nspawn.md deleted file mode 100644 index 6d3e08ac91..0000000000 --- a/sources/tech/20160621 Container technologies in Fedora - systemd-nspawn.md +++ /dev/null @@ -1,108 +0,0 @@ -Being translated by [ChrisLeeGit](https://github.com/chrisleegit) - -Container technologies in Fedora: systemd-nspawn -=== - -Welcome to the “Container technologies in Fedora” series! This is the first article in a series of articles that will explain how you can use the various container technologies available in Fedora. This first article will deal with `systemd-nspawn`. - -### What is a container? - -A container is a user-space instance which can be used to run a program or an operating system in isolation from the system hosting the container (called the host system). The idea is very similar to a `chroot` or a [virtual machine][1]. The processes running in a container are managed by the same kernel as the host operating system, but they are isolated from the host file system, and from the other processes. - - -### What is systemd-nspawn? - -The systemd project considers container technologies as something that should fundamentally be part of the desktop and that should integrate with the rest of the user’s systems. To this end, systemd provides `systemd-nspawn`, a tool which is able to create containers using various Linux technologies. It also provides some container management tools. - -In many ways, `systemd-nspawn` is similar to `chroot`, but is much more powerful. It virtualizes the file system, process tree, and inter-process communication of the guest system. Much of its appeal lies in the fact that it provides a number of tools, such as `machinectl`, for managing containers. Containers run by `systemd-nspawn` will integrate with the systemd components running on the host system. As an example, journal entries can be logged from a container in the host system’s journal. - -In Fedora 24, `systemd-nspawn` has been split out from the systemd package, so you’ll need to install the `systemd-container` package. As usual, you can do that with a `dnf install systemd-container`. - -### Creating the container - -Creating a container with `systemd-nspawn` is easy. Let’s say you have an application made for Debian, and it doesn’t run well anywhere else. That’s not a problem, we can make a container! To set up a container with the latest version of Debian (at this point in time, Jessie), you need to pick a directory to set up your system in. I’ll be using `~/DebianJessie` for now. - -Once the directory has been created, you need to run `debootstrap`, which you can install from the Fedora repositories. For Debian Jessie, you run the following command to initialize a Debian file system. - -``` -$ debootstrap --arch=amd64 stable ~/DebianJessie -``` - -This assumes your architecture is x86_64. If it isn’t, you must change `amd64` to the name of your architecture. You can find your machine’s architecture with `uname -m`. - -Once your root directory is set up, you will start your container with the following command. - -``` -$ systemd-nspawn -bD ~/DebianJessie -``` - -You’ll be up and running within seconds. You’ll notice something as soon as you try to log in: you can’t use any accounts on your system. This is because systemd-nspawn virtualizes users. The fix is simple: remove -b from the previous command. You’ll boot directly to the root shell in the container. From there, you can just use passwd to set a password for root, or you can use adduser to add a new user. As soon as you’re done with that, go ahead and put the -b flag back. You’ll boot to the familiar login console and you log in with the credentials you set. - -All of this applies for any distribution you would want to run in the container, but you need to create the system using the correct package manager. For Fedora, you would use DNF instead of debootstrap. To set up a minimal Fedora system, you can run the following command, replacing the absolute path with wherever you want the container to be. - -``` -$ sudo dnf --releasever=24 --installroot=/absolute/path/ install systemd passwd dnf fedora-release -``` - -![](https://cdn.fedoramagazine.org/wp-content/uploads/2016/06/Screenshot-from-2016-06-17-15-04-14.png) - -### Setting up the network - -You’ll notice an issue if you attempt to start a service that binds to a port currently in use on your host system. Your container is using the same network interface. Luckily, `systemd-nspawn` provides several ways to achieve separate networking from the host machine. - -#### Local networking - -The first method uses the `--private-network` flag, which only creates a loopback device by default. This is ideal for environments where you don’t need networking, such as build systems and other continuous integration systems. - -#### Multiple networking interfaces - -If you have multiple network devices, you can give one to the container with the `--network-interface` flag. To give `eno1` to my container, I would add the flag `--network-interface=eno1`. While an interface is assigned to a container, the host can’t use it at the same time. When the container is completely shut down, it will be available to the host again. - -#### Sharing network interfaces - -For those of us who don’t have spare network devices, there are other options for providing access to the container. One of those is the `--port` flag. This forwards a port on the container to the host. The format is `protocol:host:container`, where protocol is either `tcp` or `udp`, `host` is a valid port number on the host, and `container` is a valid port on the container. You can omit the protocol and specify only `host:container`. I often use something similar to `--port=2222:22`. - -You can enable complete, host-only networking with the `--network-veth` flag, which creates a virtual Ethernet interface between the host and the container. You can also bridge two connections with `--network-bridge`. - -### Using systemd components - -If the system in your container has D-Bus, you can use systemd’s provided utilities to control and monitor your container. Debian doesn’t include dbus in the base install. If you want to use it with Debian Jessie, you’ll want to run `apt install dbus`. - -#### machinectl - -To easily manage containers, systemd provides the machinectl utility. Using machinectl, you can log in to a container with machinectl login name, check the status with machinectl status name, reboot with machinectl reboot name, or power it off with machinectl poweroff name. - -### Other systemd commands - -Most systemd commands, such as journalctl, systemd-analyze, and systemctl, support containers with the `--machine` option. For example, if you want to see the journals of a container named “foobar”, you can use journalctl `--machine=foobar`. You can also see the status of a service running in this container with `systemctl --machine=foobar` status service. - -![](https://cdn.fedoramagazine.org/wp-content/uploads/2016/06/Screenshot-from-2016-06-17-15-09-25.png) - -### Working with SELinux - -If you’re running with SELinux enforcing (the default in Fedora), you’ll need to set the SELinux context for your container. To do that, you need to run the following two commands on the host system. - -``` -$ semanage fcontext -a -t svirt_sandbox_file_t "/path/to/container(/.*)?" -$ restorecon -R /path/to/container/ -``` - -Make sure you replace “/path/to/container” with the path to your container. For my container, “DebianJessie”, I would run the following: - -``` -$ semanage fcontext -a -t svirt_sandbox_file_t "/home/johnmh/DebianJessie(/.*)?" -$ restorecon -R /home/johnmh/DebianJessie/ -``` - --------------------------------------------------------------------------------- - -via: http://linoxide.com/linux-how-to/set-nginx-reverse-proxy-centos-7-cpanel/ - -作者:[John M. Harris, Jr.][a] -译者:[ChrisLeeGit](https://github.com/chrisleegit) -校对:[校对者ID](https://github.com/校对者ID) - -本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 - -[a]: http://linoxide.com/linux-how-to/set-nginx-reverse-proxy-centos-7-cpanel/ -[1]: https://en.wikipedia.org/wiki/Virtual_machine diff --git a/translated/tech/20160621 Container technologies in Fedora - systemd-nspawn.md b/translated/tech/20160621 Container technologies in Fedora - systemd-nspawn.md new file mode 100644 index 0000000000..f47d17556a --- /dev/null +++ b/translated/tech/20160621 Container technologies in Fedora - systemd-nspawn.md @@ -0,0 +1,99 @@ +Fedora 中的容器技术:systemd-nspawn +=== + +欢迎来到“Fedora 中的容器技术”系列!本文是该系列文章中的第一篇,它将说明你可以怎样使用 Fedora 中各种可用的容器技术。本文将学习 `systemd-nspawn` 的相关知识。 + +### 容器是什么? +一个容器就是一个用户空间实例,它能够在与托管容器的系统(叫做宿主系统)隔离的环境中运行一个程序或者一个操作系统。这和 `chroot` 或 [虚拟机][1] 的思想非常类似。 +运行在容器中的进程是由与宿主操作系统相同的内核来管理的,但它们是与宿主文件系统以及其它进程隔离开的。 + + +### 什么是 systemd-nspawn? +systemd 项目认为应当将容器技术变成桌面的基础部分,并且应当和剩余的用户系统集成在一起。为此,systemd 提供了 `systemd-nspawn`,这款工具能够使用多种 Linux 技术创建容器。它也提供了一些容器管理工具。 + +`systemd-nspawn` 和 `chroot` 在许多方面都是类似的,但是前者更加强大。它虚拟化了文件系统、进程树以及客户系统中的进程间通信。它的引力在于它提供了很多用于管理容器的工具,例如 `machinectl`。由 `systemd-nspawn` 运行的容器将会与 systemd 组件一同运行在宿主系统上。举例来说,一个容器的日志可以输出到宿主系统的日志中。 + +在 Fedora 24 上,`systemd-nspawn` 已经和 systemd 软件包分开了,所以你需要安装 `systemd-container` 软件包。一如往常,你可以使用 `dnf install systemd-container` 进行安装。 + +### 创建容器 +使用 `systemd-nspawn` 创建一个容器是很容易的。假设你有一个专门为 Debian 创造的应用,并且无法在其它地方正常运行。那并不是一个问题,我们可以创造一个容器!为了设置容器使用最新版本的 Debian(此时是 Jessie),你需要挑选一个目录来放置你的系统。我暂时将使用目录 `~/DebianJessie`。 + +一旦你创建完目录,你需要运行 `debootstrap`,你可以从 Fedora 仓库中安装它。对于 Debian Jessie,你运行下面的命令来初始化一个 Debian 文件系统。 + +``` +$ debootstrap --arch=amd64 stable ~/DebianJessie +``` + +以上默认你的架构是 x86_64。如果不是的话,你必须将架构的名称改为 `amd64`。你可以使用 `uname -m` 得知你的机器架构。 + +一旦设置好你的根目录,你就可以使用下面的命令来启动你的容器。 + +``` +$ systemd-nspawn -bD ~/DebianJessie +``` + +容器将会在数秒后准备好并运行,当你一尝试登录就会注意到:你无法在你的系统上使用任何账户。这是因为 `systemd-nspawn` 虚拟化了用户。修复的方法很简单:将之前的命令中的 `-b` 移除即可。你将直接进入容器的 root shell。此时,你只能使用 `passwd` 命令为 root 设置密码,或者使用 `adduser` 命令添加一个新用户。一旦设置好密码或添加好用户,你就可以把 `-b` 标志添加回去然后继续了。你会进入到熟悉的登录控制台,然后你使用设置好的认证信息登录进去。 + +以上对于任意你想在容器中运行的发行版都适用,但前提是你需要使用正确的包管理器创建系统。对于 Fedora,你应使用 DNF 而非 `debootstrap`。想要设置一个最小化的 Fedora 系统,你可以运行下面的命令,要将绝对路径替换成任何你希望容器存放的位置。 + +``` +$ sudo dnf --releasever=24 --installroot=/absolute/path/ install systemd passwd dnf fedora-release +``` + +![](https://cdn.fedoramagazine.org/wp-content/uploads/2016/06/Screenshot-from-2016-06-17-15-04-14.png) + +### 设置网络 +如果你尝试启动一个服务,但它绑定了你宿主机正在使用的端口,你将会注意到这个问题:你的容器正在使用和宿主机相同的网络接口。 +幸运的是,`systemd-nspawn` 提供了几种方法可以将网络从宿主机分开。 + +#### 本地网络 + +第一种方法是使用 `--private-network` 标志,它默认仅创建一个回环设备。这对于你不需要使用网络的环境是非常理想的,例如构建系统和其它持续集成系统。 + +#### 多个网络接口 + +如果你有多个网络接口设备,你可以使用 `--network-interface` 标志给容器分配一个接口。想要给我的容器分配 `eno1`,我会添加标志 `--network-interface=eno1`。当某个接口分配给一个容器后,宿主机就不能同时使用那个接口了。只有当容器彻底关闭后,宿主机才可以使用那个接口。 + + +#### 共享网络接口 +对于我们中那些并没有额外的网络设备的人来说,还有其它方法可以访问容器。一种就是使用 `--port` 标志。这会将容器中的一个端口定向到宿主机。使用格式是 `协议:宿主机:容器`,这里的协议可以是 `tcp` 或者 `udp`,`宿主机` 是宿主机的一个合法端口,`容器` 则是容器中的一个合法端口。你可以省略协议,只指定 `宿主机:容器`。我通常的用法类似 `--port=2222:22`。 + +你可以使用 `--network-veth` 启用完全的、仅宿主机模式的网络,这会在宿主机和容器之间创建一个虚拟的网络接口。你也可以使用 `--network-bridge` 桥接二者的连接。 + +### 使用 systemd 组件 +如果你容器中的系统含有 D-Bus,你可以使用 systemd 提供的实用工具来控制并监视你的容器。基础安装的 Debian 并不包含 `dbus`。如果你想在 Debian Jessie 中使用 `dbus`,你需要运行命令 `apt install dbus`。 + +#### machinectl +为了能够轻松地管理容器,systemd 提供了 `machinectl` 实用工具。使用 `machinectl`,你可以使用 `machinectl login name` 登录到一个容器中、使用 `machinectl status name`检查状态、使用 `machinectl reboot name` 启动容器或者使用 `machinectl poweroff name` 关闭容器。 + +### 其它 systemd 命令 +多数 systemd 命令,例如 `journalctl`, `systemd-analyze` 和 `systemctl`,都支持使用了 `--machine` 选项的容器。例如,如果你想查看一个名为 "foobar" 的容器日志,你可以使用 `journalctl --machine=foobar`。你也可以使用 `systemctl --machine=foobar status service` 来查看运行在这个容器中的服务状态。 + +![](https://cdn.fedoramagazine.org/wp-content/uploads/2016/06/Screenshot-from-2016-06-17-15-09-25.png) + +### 和 SELinux 一起工作 +如果你要使用 SELinux 强制模式(Fedora 默认模式),你需要为你的容器设置 SELinux 环境。想要那样的话,你需要在宿主系统上运行下面两行命令。 + +``` +$ semanage fcontext -a -t svirt_sandbox_file_t "/path/to/container(/.*)?" +$ restorecon -R /path/to/container/ +``` +确保使用你的容器路径替换 "/path/to/container"。对于我的容器 "DebianJessie",我会运行下面的命令: + +``` +$ semanage fcontext -a -t svirt_sandbox_file_t "/home/johnmh/DebianJessie(/.*)?" +$ restorecon -R /home/johnmh/DebianJessie/ +``` + +-------------------------------------------------------------------------------- + +via: https://fedoramagazine.org/container-technologies-fedora-systemd-nspawn/ + +作者:[John M. Harris, Jr.][a] +译者:[ChrisLeeGit](https://github.com/chrisleegit) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]: https://fedoramagazine.org/container-technologies-fedora-systemd-nspawn/ +[1]: https://en.wikipedia.org/wiki/Virtual_machine From a10295803858cb583d50738335458f194fb47a99 Mon Sep 17 00:00:00 2001 From: Locez Date: Wed, 27 Jul 2016 21:34:49 +0800 Subject: [PATCH 037/122] translated and delete source --- ...60722 7 Best Markdown Editors for Linux.md | 156 ------------------ 1 file changed, 156 deletions(-) delete mode 100644 sources/tech/20160722 7 Best Markdown Editors for Linux.md diff --git a/sources/tech/20160722 7 Best Markdown Editors for Linux.md b/sources/tech/20160722 7 Best Markdown Editors for Linux.md deleted file mode 100644 index b4b05a41f5..0000000000 --- a/sources/tech/20160722 7 Best Markdown Editors for Linux.md +++ /dev/null @@ -1,156 +0,0 @@ -translating by Locez -7 Best Markdown Editors for Linux -====================================== - -In this article, we shall review some of the best Markdown editors you can install and use on your Linux desktop. There are numerous Markdown editors you can find for Linux but here, we want to unveil possibly the best you may choose to work with. - -![](http://www.tecmint.com/wp-content/uploads/2016/07/Best-Linux-Markdown-Editors.png) ->Best Linux Markdown Editors - -For starters, Markdown is a simple and lightweight tool written in Perl, that enables users to write plain text format and covert it to valid HTML (or XHTML). It is literally an easy-to-read, easy-to-write plain text language and a software tool for text-to-HTML conversion. - -Hoping that you have a slight understanding of what Markdown is, let us proceed to list the editors. - -### 1. Atom - -Atom is a modern, cross-platform, open-source and very powerful text editor that can work on Linux, Windows and Mac OS X operating systems. Users can customize it down to its base, minus altering any configuration files. - -It is designed with some illustrious features and these include: - -- Comes with a built-in package manager -- Smart auto-completion functionality -- Offers multiple panes -- Supports find and replace functionality -- Includes a file system browser -- Easily customizable themes -- Highly extensible using open-source packages and many more - -![](http://www.tecmint.com/wp-content/uploads/2016/07/Atom-Markdown-Editor-for-Linux.png) - -Visit Homepage: - -### 2. GNU Emacs - -Emacs is one of the popular open-source text editors you can find on the Linux platform today. It is a great editor for Markdown language, which is highly extensible and customizable. - -It’s comprehensively developed with the following amazing features: - -- Comes with an extensive built-in documentation including tutorials for beginners -- Full Unicode support for probably all human scripts -- Supports content-aware text-editing modes -- Includes syntax coloring for multiple file types -- Its highly customizable using Emacs Lisp code or GUI -- Offers a packaging system for downloading and installing various extensions plus so much more - -![](http://www.tecmint.com/wp-content/uploads/2016/07/Emacs-Markdown-Editor-for-Linux.png) ->Emacs Markdown Editor for Linux - -Visit Homepage: - -### 3. Remarkable - -Remarkable is possibly the best Markdown editor you can find on Linux, it also works on Windows operating system. It is indeed a remarkable and fully featured Markdown editor that offers users some exciting features. - -Some of its remarkable features include: - -- Supports live preview -- Supports exporting to PDF and HTML -- Also offers Github Markdown -- Supports custom CSS -- It also supports syntax highlighting -- Offers keyboard shortcuts -- Highly customizable plus and many more - -![](http://www.tecmint.com/wp-content/uploads/2016/07/Remarkable-Markdown-Editor-for-Linux.png) ->Remarkable Markdown Editor for Linux - -Visit Homepage: - -### 4. Haroopad - -Haroopad is an extensively built, cross-platform Markdown document processor for Linux, Windows and Mac OS X. It enables users to write expert-level documents of numerous formats including email, reports, blogs, presentations, blog posts and many more. - -It is fully featured with the following notable features: - -- Easily imports content -- Also exports to numerous formats -- Broadly supports blogging and mailing -- Supports several mathematical expressions -- Supports Github flavored Markdown and extensions -- Offers users some exciting themes, skins and UI components plus so much more - -![](http://www.tecmint.com/wp-content/uploads/2016/07/Haroopad-Markdown-Editor-for-Linux.png) ->Haroopad Markdown Editor for Linux - -Visit Homepage: - -### 5. ReText - -ReText is a simple, lightweight and powerful Markdown editor for Linux and several other POSIX-compatible operating systems. It also doubles as a reStructuredText editor, and has the following attributes: - -- Simple and intuitive GUI -- It is highly customizable, users can customize file syntax and configuration options -- Also supports several color schemes -- Supports use of multiple mathematical formulas -- Enables export extensions and many more - -![](http://www.tecmint.com/wp-content/uploads/2016/07/ReText-Markdown-Editor-for-Linux.png) ->ReText Markdown Editor for Linux - -Visit Homepage: - -### 6. UberWriter - -UberWriter is a simple and easy-to-use Markdown editor for Linux, it’s development was highly influenced by iA writer for Mac OS X. It is also feature rich with these remarkable features: - -- Uses pandoc to perform all text-to-HTML conversions -- Offers a clean UI -- Offers a distraction free mode, highlighting a users last sentence -- Supports spellcheck -- Also supports full screen mode -- Supports exporting to PDF, HTML and RTF using pandoc -- Enables syntax highlighting and mathematical functions plus many more - -![](http://www.tecmint.com/wp-content/uploads/2016/07/UberWriter-Markdown-Editor-for-Linux.png) ->UberWriter Markdown Editor for Linux - -Visit Homepage: - -### 7. Mark My Words - -Mark My Words is a also lightweight yet powerful Markdown editor. It’s a relatively new editor, therefore offers a handful of features including syntax highlighting, simple and intuitive GUI. - -The following are some of the awesome features yet to be bundled into the application: - -- Live preview support -- Markdown parsing and file IO -- State management -- Support for exporting to PDF and HTML -- Monitoring files for changes -- Support for preferences - -![](http://www.tecmint.com/wp-content/uploads/2016/07/MarkMyWords-Markdown-Editor-for-Linux.png) ->MarkMyWords Markdown Editor for-Linux - -Visit Homepage: - -### Conclusion - -Having walked through the list above, you probably know what Markdown editors and document processors to download and install on your Linux desktop for now. - -Note that what we consider to be the best here may reasonably not be the best for you, therefore, you can reveal to us exciting Markdown editors that you think are missing in the list and have earned the right to be mentioned here by sharing your thoughts via the feedback section below. - - --------------------------------------------------------------------------------- - -via: http://www.tecmint.com/best-markdown-editors-for-linux/ - -作者:[Aaron Kili |][a] -译者:[译者ID](https://github.com/译者ID) -校对:[校对者ID](https://github.com/校对者ID) - -本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 - -[a]: http://www.tecmint.com/author/aaronkili/ - - From 4bbcd800086bb809f2aad07b403f3378d3ef229b Mon Sep 17 00:00:00 2001 From: Locez Date: Wed, 27 Jul 2016 21:38:07 +0800 Subject: [PATCH 038/122] [translated] 7 Best Markdown Editors for Linux.md --- .../tech/7 Best Markdown Editors for Linux.md | 158 ++++++++++++++++++ 1 file changed, 158 insertions(+) create mode 100644 translated/tech/7 Best Markdown Editors for Linux.md diff --git a/translated/tech/7 Best Markdown Editors for Linux.md b/translated/tech/7 Best Markdown Editors for Linux.md new file mode 100644 index 0000000000..8cf7cdd45f --- /dev/null +++ b/translated/tech/7 Best Markdown Editors for Linux.md @@ -0,0 +1,158 @@ +Linux 上 7 个最好的 Markdown 编辑器 +====================================== + +在这篇文章中,我们会重温一些可以在 Linux 上安装使用的最好的 Markdown 编辑器。 你可以找到非常多的 Linux 平台上的 Markdown 编辑器,但是在这里我们将尽可能地推荐你选择最好的。 + +![](http://www.tecmint.com/wp-content/uploads/2016/07/Best-Linux-Markdown-Editors.png) +>Best Linux Markdown Editors + + +首先,Markdown 是一个用 Perl 写的简单、轻量的工具。它可以将用户写的纯文本转为可用的 HTML (或 XHTML)。它实际上是一门易读,易写的纯文本语言,以及一个用于将文本转为 HTML 的转换工具。 + + +希望你先对 Markdown 有一个稍微的了解,接下来让我们逐一列出这些编辑器。 +### 1. Atom + + + +Atom 是一个现代的,跨平台,开源且强有力的文本编辑器,它可以运行在 Linux, Windows 和 MAC OS X 等操作系统上。用户可以在它的基础上进行定制,删减修改任何配置文件。 + +它包含了一些非常杰出的特性: + + +- 内置软件包管理器 +- 智能自动补全功能 +- 提供多窗口操作 +- 支持查找替换功能 +- 包含一个文件系统浏览器 +- 轻松自定义主题 +- 开源、高度扩展性的软件包等 + +![](http://www.tecmint.com/wp-content/uploads/2016/07/Atom-Markdown-Editor-for-Linux.png) + + +访问主页: + +### 2. GNU Emacs + +Emacs 是 Linux 平台上一款的流行文本编辑器。它是一个非常棒的,具备高扩展性和定制性的 Markdown 语言编辑器。 + + +它综合了以下这些神奇的特性: + +- 带有丰富的内置文档,包括适合初学者的教程 +- 有完整的 UnicodeU支持,可显示所有的人类符号 +- 支持内容识别的文本编辑模式 +- 包括多种文件类型的语法高亮 +- 可用 Emacs Lisp 或 GUI 对其进行高度定制 +- 提供了一个包系统可用来下载安装各种扩展等 + +![](http://www.tecmint.com/wp-content/uploads/2016/07/Emacs-Markdown-Editor-for-Linux.png) +>Emacs Markdown Editor for Linux + +访问主页: + +### 3. Remarkable + +Remarkable 可能是 Linux 上最好的 Markdown 编辑器了,它也适用于 Windows 操作系统。它的确是是一个卓越且功能齐全的 Markdown 编辑器,为用户提供了一些令人兴奋的特性。 + +一些卓越的特性: + +- 支持实时预览 +- 支持导出 PDF 和 HTML +- 支持 Github Markdown 语法 +- 支持定制 CSS +- 支持语法高亮 +- 提供键盘快捷键 +- 高可定制性和其他 + +![](http://www.tecmint.com/wp-content/uploads/2016/07/Remarkable-Markdown-Editor-for-Linux.png) +>Remarkable Markdown Editor for Linux + +访问主页: + +### 4. Haroopad + +Haroopad 是为 Linux,Windows 和 Mac OS X 构建的跨平台 Markdown 文档处理程序。用户可以用它来书写许多专家级格式的文档,包括电子邮件、报告、博客、演示文稿和博客文章等等。 + + +功能齐全且具备以下的亮点: + +- 轻松导入内容 +- 支持导出多种格式 +- 广泛支持博客和邮件 +- 支持许多数学表达式 +- 支持 Github Markdown 扩展 +- 为用户提供了一些令人兴奋的主题、皮肤和 UI 组件等等 + +![](http://www.tecmint.com/wp-content/uploads/2016/07/Haroopad-Markdown-Editor-for-Linux.png) +>Haroopad Markdown Editor for Linux + +访问主页: +### 5. ReText + +ReText 是为 Linux 和其它几个 POSIX 兼容操作系统提供的简单、轻量、强大的 Markdown 编辑器。它还可以作为一个 reStructuredText 编辑器,并且具有以下的特性: + +- 简单直观的 GUI +- 具备高定制性,用户可以自定义语法文件和配置选项 +- 支持多种配色方案 +- 支持使用多种数学公式 +- 启用导出扩展等等 + +![](http://www.tecmint.com/wp-content/uploads/2016/07/ReText-Markdown-Editor-for-Linux.png) +>ReText Markdown Editor for Linux + +访问主页: +### 6. UberWriter + +UberWriter 是一个简单、易用的 Linux Markdown 编辑器。它的开发受 Mac OS X 上的 iA writer 影响很大,同样它也具备这些卓越的特性: + +- 使用 pandoc 将所有的文本转为 HTML +- 提供了一个简洁的 UI 界面 +- 提供了一种自由的分发模式,高亮用户的最后一句话 +- 支持拼写检查 +- 支持全屏模式 +- 支持用 pandoc 导出 PDF、HTML 和 RTF +- 启用语法高亮和数学函数等等 + +![](http://www.tecmint.com/wp-content/uploads/2016/07/UberWriter-Markdown-Editor-for-Linux.png) +>UberWriter Markdown Editor for Linux + +访问主页: +### 7. Mark My Words + +Mark My Words 同样也是一个轻量、强大的 Markdown 编辑器。它是一个相对比较新的编辑器,因此提供了大量的功能,包含语法高亮、简单和直观的 UI 等。 + + +下面是一些棒极了,但还未捆绑到应用中的功能: + +- 实时预览 +- Markdown 解析和文件 IO +- 状态管理 +- 支持导出 PDF 和 HTML +- 监测文件的修改 +- 支持首选项 + +![](http://www.tecmint.com/wp-content/uploads/2016/07/MarkMyWords-Markdown-Editor-for-Linux.png) +>MarkMyWords Markdown Editor for-Linux + +访问主页: + +### 结论 + +通过上面的列表,你大概已经知道要为你的 Linux 桌面下载、安装什么样的 Markdown 编辑器和文档处理程序了。 + +请注意,这里提到的最好的 Markdown 编辑器可能对你来说并不是最好的选择。因此你可以通过下面的反馈部分,为我们展示你认为列表中未提及的,并且具备足够的资格的,令人兴奋的 Markdown 编辑器。 + + +-------------------------------------------------------------------------------- + +via: http://www.tecmint.com/best-markdown-editors-for-linux/ + +作者:[Aaron Kili |][a] +译者:[Locez](https://github.com/locez) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]: http://www.tecmint.com/author/aaronkili/ From 6553b0e28615ddd39e2f8b16a87230a3ed05c1c8 Mon Sep 17 00:00:00 2001 From: Locez Date: Wed, 27 Jul 2016 21:40:28 +0800 Subject: [PATCH 039/122] Rename 7 Best Markdown Editors for Linux.md to 20160722 7 Best Markdown Editors for Linux.md --- ...for Linux.md => 20160722 7 Best Markdown Editors for Linux.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename translated/tech/{7 Best Markdown Editors for Linux.md => 20160722 7 Best Markdown Editors for Linux.md} (100%) diff --git a/translated/tech/7 Best Markdown Editors for Linux.md b/translated/tech/20160722 7 Best Markdown Editors for Linux.md similarity index 100% rename from translated/tech/7 Best Markdown Editors for Linux.md rename to translated/tech/20160722 7 Best Markdown Editors for Linux.md From e896363804f9995a08c681206cef2c15d77fec99 Mon Sep 17 00:00:00 2001 From: wxy Date: Wed, 27 Jul 2016 22:27:56 +0800 Subject: [PATCH 040/122] PUB:20160722 HOW TO CHANGE DEFAULT APPLICATIONS IN UBUNTU @locez --- ...O CHANGE DEFAULT APPLICATIONS IN UBUNTU.md | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) rename {translated/tech => published}/20160722 HOW TO CHANGE DEFAULT APPLICATIONS IN UBUNTU.md (81%) diff --git a/translated/tech/20160722 HOW TO CHANGE DEFAULT APPLICATIONS IN UBUNTU.md b/published/20160722 HOW TO CHANGE DEFAULT APPLICATIONS IN UBUNTU.md similarity index 81% rename from translated/tech/20160722 HOW TO CHANGE DEFAULT APPLICATIONS IN UBUNTU.md rename to published/20160722 HOW TO CHANGE DEFAULT APPLICATIONS IN UBUNTU.md index 2192b71600..b485632d6c 100644 --- a/translated/tech/20160722 HOW TO CHANGE DEFAULT APPLICATIONS IN UBUNTU.md +++ b/published/20160722 HOW TO CHANGE DEFAULT APPLICATIONS IN UBUNTU.md @@ -1,15 +1,16 @@ -怎样在 UBUNTU 中修改默认程序 +怎样在 Ubuntu 中修改默认程序 ============================================== ![](https://itsfoss.com/wp-content/uploads/2016/07/change-default-applications-ubuntu.jpg) -简介: 这个新手指南会向你展示如何在 Ubuntu Linux 中修改默认程序 +> 简介: 这个新手指南会向你展示如何在 Ubuntu Linux 中修改默认程序 对于我来说,安装 [VLC 多媒体播放器][1]是[安装完 Ubuntu 16.04 该做的事][2]中最先做的几件事之一。为了能够使我双击一个视频就用 VLC 打开,在我安装完 VLC 之后我会设置它为默认程序。 作为一个新手,你需要知道如何在 Ubuntu 中修改任何默认程序,这也是我今天在这篇指南中所要讲的。 ### 在 UBUNTU 中修改默认程序 + 这里提及的方法适用于所有的 Ubuntu 12.04,Ubuntu 14.04 和Ubuntu 16.04。在 Ubuntu 中,这里有两种基本的方法可以修改默认程序: - 通过系统设置 @@ -25,43 +26,44 @@ ![](https://itsfoss.com/wp-content/uploads/2016/07/System-settings-detail-ubuntu.jpeg) - 在左边的面板中选择默认程序(Default Applications),你会发现在右边的面板中可以修改默认程序。 ![](https://itsfoss.com/wp-content/uploads/2016/07/System-settings-default-applications.jpeg) -正如看到的那样,这里只有少数几类的默认程序可以被改变。你可以在这里改变浏览器,邮箱客户端,日历,音乐,视频和相册的默认程序。那其他类型的默认程序怎么修改? +正如看到的那样,这里只有少数几类的默认程序可以被改变。你可以在这里改变浏览器、邮箱客户端、日历、音乐、视频和相册的默认程序。那其他类型的默认程序怎么修改? 不要担心,为了修改其他类型的默认程序,我们会用到右键菜单。 #### 2.通过右键菜单修改默认程序 - 如果你使用过 Windows 系统,你应该看见过右键菜单的“打开方式”,可以通过这个来修改默认程序。我们在 Ubuntu 中也有相似的方法。 右键一个还没有设置默认打开程序的文件,选择“属性(properties)” ![](https://itsfoss.com/wp-content/uploads/2016/05/WebP-images-Ubuntu-Linux-3.png) ->从右键菜单中选择属性 + +*从右键菜单中选择属性* 在这里,你可以选择使用什么程序打开,并且设置为默认程序。 ![](https://itsfoss.com/wp-content/uploads/2016/05/WebP-images-Ubuntu-Linux-4.png) ->在 Ubuntu 中设置打开 WebP 图片的默认程序为 gThumb + +*在 Ubuntu 中设置打开 WebP 图片的默认程序为 gThumb* 小菜一碟不是么?一旦你做完这些,所有同样类型的文件都会用你选择的默认程序打开。 + 我很希望这个新手指南对你在修改 Ubuntu 的默认程序时有帮助。如果你有任何的疑问或者建议,可以随时在下面评论。 -------------------------------------------------------------------------------- -via: https://itsfoss.com/change-default-applications-ubuntu/?utm_source=feedburner&utm_medium=feed&utm_campaign=Feed%3A+ItsFoss+%28Its+FOSS%21+An+Open+Source+Blog%29 +via: https://itsfoss.com/change-default-applications-ubuntu/ 作者:[Abhishek Prakash][a] 译者:[Locez](https://github.com/locez) -校对:[校对者ID](https://github.com/校对者ID) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 [a]: https://itsfoss.com/author/abhishek/ [1]: http://www.videolan.org/vlc/index.html -[2]: https://itsfoss.com/things-to-do-after-installing-ubuntu-16-04/ +[2]: https://linux.cn/article-7453-1.html From 89182f569304b02318986dc0bedf1db13f6d94ad Mon Sep 17 00:00:00 2001 From: ChrisLeeGit Date: Wed, 27 Jul 2016 22:56:09 +0800 Subject: [PATCH 041/122] =?UTF-8?q?=E7=BF=BB=E8=AF=91=E7=94=B3=E8=AF=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sources/tech/20160630 What makes up the Fedora kernel.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sources/tech/20160630 What makes up the Fedora kernel.md b/sources/tech/20160630 What makes up the Fedora kernel.md index 95b61a201a..603aefa575 100644 --- a/sources/tech/20160630 What makes up the Fedora kernel.md +++ b/sources/tech/20160630 What makes up the Fedora kernel.md @@ -1,3 +1,5 @@ +Being translated by ChrisLeeGit + What makes up the Fedora kernel? ==================================== @@ -22,7 +24,7 @@ The Fedora kernel contains code from many places. All of it is necessary to give via: https://fedoramagazine.org/makes-fedora-kernel/ 作者:[Laura Abbott][a] -译者:[译者ID](https://github.com/译者ID) +译者:[ChrisLeeGit](https://github.com/chrisleegit) 校对:[校对者ID](https://github.com/校对者ID) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 From ffef0b3a3d2629298a21cb3b75422fb8fad419b2 Mon Sep 17 00:00:00 2001 From: wxy Date: Wed, 27 Jul 2016 23:22:16 +0800 Subject: [PATCH 042/122] PUB:20160722 7 Best Markdown Editors for Linux @locez --- ...60722 7 Best Markdown Editors for Linux.md | 96 +++++++++++++------ 1 file changed, 69 insertions(+), 27 deletions(-) rename {translated/tech => published}/20160722 7 Best Markdown Editors for Linux.md (59%) diff --git a/translated/tech/20160722 7 Best Markdown Editors for Linux.md b/published/20160722 7 Best Markdown Editors for Linux.md similarity index 59% rename from translated/tech/20160722 7 Best Markdown Editors for Linux.md rename to published/20160722 7 Best Markdown Editors for Linux.md index 8cf7cdd45f..7d1ffe0c86 100644 --- a/translated/tech/20160722 7 Best Markdown Editors for Linux.md +++ b/published/20160722 7 Best Markdown Editors for Linux.md @@ -1,25 +1,22 @@ -Linux 上 7 个最好的 Markdown 编辑器 +Linux 上 10 个最好的 Markdown 编辑器 ====================================== -在这篇文章中,我们会重温一些可以在 Linux 上安装使用的最好的 Markdown 编辑器。 你可以找到非常多的 Linux 平台上的 Markdown 编辑器,但是在这里我们将尽可能地推荐你选择最好的。 +在这篇文章中,我们会点评一些可以在 Linux 上安装使用的最好的 Markdown 编辑器。 你可以找到非常多的 Linux 平台上的 Markdown 编辑器,但是在这里我们将尽可能地为您推荐那些最好的。 ![](http://www.tecmint.com/wp-content/uploads/2016/07/Best-Linux-Markdown-Editors.png) ->Best Linux Markdown Editors +*Best Linux Markdown Editors* -首先,Markdown 是一个用 Perl 写的简单、轻量的工具。它可以将用户写的纯文本转为可用的 HTML (或 XHTML)。它实际上是一门易读,易写的纯文本语言,以及一个用于将文本转为 HTML 的转换工具。 - +对于不了解 Markdown 的人做个简单介绍,Markdown 是由著名的 Aaron Swartz 和 John Gruber 发明的标记语言,其最初的解析器是一个用 Perl 写的简单、轻量的[同名工具][1]。它可以将用户写的纯文本转为可用的 HTML(或 XHTML)。它实际上是一门易读,易写的纯文本语言,以及一个用于将文本转为 HTML 的转换工具。 希望你先对 Markdown 有一个稍微的了解,接下来让我们逐一列出这些编辑器。 + ### 1. Atom - - -Atom 是一个现代的,跨平台,开源且强有力的文本编辑器,它可以运行在 Linux, Windows 和 MAC OS X 等操作系统上。用户可以在它的基础上进行定制,删减修改任何配置文件。 +Atom 是一个现代的、跨平台、开源且强大的文本编辑器,它可以运行在 Linux、Windows 和 MAC OS X 等操作系统上。用户可以在它的基础上进行定制,删减修改任何配置文件。 它包含了一些非常杰出的特性: - - 内置软件包管理器 - 智能自动补全功能 - 提供多窗口操作 @@ -30,31 +27,32 @@ Atom 是一个现代的,跨平台,开源且强有力的文本编辑器,它 ![](http://www.tecmint.com/wp-content/uploads/2016/07/Atom-Markdown-Editor-for-Linux.png) +*Atom Markdown Editor for Linux* 访问主页: ### 2. GNU Emacs -Emacs 是 Linux 平台上一款的流行文本编辑器。它是一个非常棒的,具备高扩展性和定制性的 Markdown 语言编辑器。 - +Emacs 是 Linux 平台上一款的流行文本编辑器。它是一个非常棒的、具备高扩展性和定制性的 Markdown 语言编辑器。 它综合了以下这些神奇的特性: - 带有丰富的内置文档,包括适合初学者的教程 -- 有完整的 UnicodeU支持,可显示所有的人类符号 +- 有完整的 Unicode 支持,可显示所有的人类符号 - 支持内容识别的文本编辑模式 - 包括多种文件类型的语法高亮 - 可用 Emacs Lisp 或 GUI 对其进行高度定制 - 提供了一个包系统可用来下载安装各种扩展等 ![](http://www.tecmint.com/wp-content/uploads/2016/07/Emacs-Markdown-Editor-for-Linux.png) ->Emacs Markdown Editor for Linux + +*Emacs Markdown Editor for Linux* 访问主页: ### 3. Remarkable -Remarkable 可能是 Linux 上最好的 Markdown 编辑器了,它也适用于 Windows 操作系统。它的确是是一个卓越且功能齐全的 Markdown 编辑器,为用户提供了一些令人兴奋的特性。 +Remarkable 可能是 Linux 上最好的 Markdown 编辑器了,它也适用于 Windows 操作系统。它的确是是一个卓越且功能齐全的 Markdown 编辑器,为用户提供了一些令人激动的特性。 一些卓越的特性: @@ -67,7 +65,8 @@ Remarkable 可能是 Linux 上最好的 Markdown 编辑器了,它也适用于 - 高可定制性和其他 ![](http://www.tecmint.com/wp-content/uploads/2016/07/Remarkable-Markdown-Editor-for-Linux.png) ->Remarkable Markdown Editor for Linux + +*Remarkable Markdown Editor for Linux* 访问主页: @@ -75,7 +74,6 @@ Remarkable 可能是 Linux 上最好的 Markdown 编辑器了,它也适用于 Haroopad 是为 Linux,Windows 和 Mac OS X 构建的跨平台 Markdown 文档处理程序。用户可以用它来书写许多专家级格式的文档,包括电子邮件、报告、博客、演示文稿和博客文章等等。 - 功能齐全且具备以下的亮点: - 轻松导入内容 @@ -86,9 +84,11 @@ Haroopad 是为 Linux,Windows 和 Mac OS X 构建的跨平台 Markdown 文档 - 为用户提供了一些令人兴奋的主题、皮肤和 UI 组件等等 ![](http://www.tecmint.com/wp-content/uploads/2016/07/Haroopad-Markdown-Editor-for-Linux.png) ->Haroopad Markdown Editor for Linux + +*Haroopad Markdown Editor for Linux* 访问主页: + ### 5. ReText ReText 是为 Linux 和其它几个 POSIX 兼容操作系统提供的简单、轻量、强大的 Markdown 编辑器。它还可以作为一个 reStructuredText 编辑器,并且具有以下的特性: @@ -100,29 +100,32 @@ ReText 是为 Linux 和其它几个 POSIX 兼容操作系统提供的简单、 - 启用导出扩展等等 ![](http://www.tecmint.com/wp-content/uploads/2016/07/ReText-Markdown-Editor-for-Linux.png) ->ReText Markdown Editor for Linux + +*ReText Markdown Editor for Linux* 访问主页: + ### 6. UberWriter UberWriter 是一个简单、易用的 Linux Markdown 编辑器。它的开发受 Mac OS X 上的 iA writer 影响很大,同样它也具备这些卓越的特性: -- 使用 pandoc 将所有的文本转为 HTML +- 使用 pandoc 进行所有的文本到 HTML 的转换 - 提供了一个简洁的 UI 界面 -- 提供了一种自由的分发模式,高亮用户的最后一句话 +- 提供了一种专心(distraction free)模式,高亮用户最后的句子 - 支持拼写检查 - 支持全屏模式 - 支持用 pandoc 导出 PDF、HTML 和 RTF - 启用语法高亮和数学函数等等 ![](http://www.tecmint.com/wp-content/uploads/2016/07/UberWriter-Markdown-Editor-for-Linux.png) ->UberWriter Markdown Editor for Linux + +*UberWriter Markdown Editor for Linux* 访问主页: + ### 7. Mark My Words -Mark My Words 同样也是一个轻量、强大的 Markdown 编辑器。它是一个相对比较新的编辑器,因此提供了大量的功能,包含语法高亮、简单和直观的 UI 等。 - +Mark My Words 同样也是一个轻量、强大的 Markdown 编辑器。它是一个相对比较新的编辑器,因此提供了包含语法高亮在内的大量的功能,简单和直观的 UI。 下面是一些棒极了,但还未捆绑到应用中的功能: @@ -131,13 +134,47 @@ Mark My Words 同样也是一个轻量、强大的 Markdown 编辑器。它是 - 状态管理 - 支持导出 PDF 和 HTML - 监测文件的修改 -- 支持首选项 +- 支持首选项设置 ![](http://www.tecmint.com/wp-content/uploads/2016/07/MarkMyWords-Markdown-Editor-for-Linux.png) ->MarkMyWords Markdown Editor for-Linux + +*MarkMyWords Markdown Editor for-Linux* 访问主页: +### 8. Vim-Instant-Markdown 插件 + +Vim 是 Linux 上的一个久经考验的强大、流行而开源的文本编辑器。它用于编程极棒。它也高度支持插件功能,可以让用户为其增加一些其它功能,包括 Markdown 预览。 + +有好几种 Vim 的 Markdown 预览插件,但是 [Vim-Instant-Markdown][2] 的表现最佳。 + +###9. Bracket-MarkdownPreview 插件 + +Brackets 是一个现代、轻量、开源且跨平台的文本编辑器。它特别为 Web 设计和开发而构建。它的一些重要功能包括:支持内联编辑器、实时预览、预处理支持及更多。 + +它也是通过插件高度可扩展的,你可以使用 [Bracket-MarkdownPreview][3] 插件来编写和预览 Markdown 文档。 + +![](http://www.tecmint.com/wp-content/uploads/2016/07/Brackets-Markdown-Plugin.png) + +*Brackets Markdown Plugin Preview* + +### 10. SublimeText-Markdown 插件 + +Sublime Text 是一个精心打造的、流行的、跨平台文本编辑器,用于代码、markdown 和普通文本。它的表现极佳,包括如下令人兴奋的功能: + +- 简洁而美观的 GUI +- 支持多重选择 +- 提供专心模式 +- 支持窗体分割编辑 +- 通过 Python 插件 API 支持高度插件化 +- 完全可定制化,提供命令查找模式 + +[SublimeText-Markdown][4] 插件是一个支持格式高亮的软件包,带有一些漂亮的颜色方案。 + +![](http://www.tecmint.com/wp-content/uploads/2016/07/SublimeText-Markdown-Plugin-Preview.png) + +*SublimeText Markdown Plugin Preview* + ### 结论 通过上面的列表,你大概已经知道要为你的 Linux 桌面下载、安装什么样的 Markdown 编辑器和文档处理程序了。 @@ -149,10 +186,15 @@ Mark My Words 同样也是一个轻量、强大的 Markdown 编辑器。它是 via: http://www.tecmint.com/best-markdown-editors-for-linux/ -作者:[Aaron Kili |][a] +作者:[Aaron Kili][a] 译者:[Locez](https://github.com/locez) -校对:[校对者ID](https://github.com/校对者ID) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 [a]: http://www.tecmint.com/author/aaronkili/ +[1]: https://daringfireball.net/projects/markdown/ +[2]: https://github.com/suan/vim-instant-markdown +[3]: https://github.com/gruehle/MarkdownPreview +[4]: https://github.com/SublimeText-Markdown/MarkdownEditing + From 090244d91cd3d38f2be5d62ff01961ad25359e1d Mon Sep 17 00:00:00 2001 From: Ezio Date: Thu, 28 Jul 2016 09:35:02 +0800 Subject: [PATCH 043/122] =?UTF-8?q?20160728-1=20=E9=80=89=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...ic Expressions and Assignment Operators.md | 271 ++++++++++++++++++ 1 file changed, 271 insertions(+) create mode 100644 sources/tech/awk/20160714 Part 8 - Learn How to Use Awk Variables, Numeric Expressions and Assignment Operators.md diff --git a/sources/tech/awk/20160714 Part 8 - Learn How to Use Awk Variables, Numeric Expressions and Assignment Operators.md b/sources/tech/awk/20160714 Part 8 - Learn How to Use Awk Variables, Numeric Expressions and Assignment Operators.md new file mode 100644 index 0000000000..be536df74f --- /dev/null +++ b/sources/tech/awk/20160714 Part 8 - Learn How to Use Awk Variables, Numeric Expressions and Assignment Operators.md @@ -0,0 +1,271 @@ +Learn How to Use Awk Variables, Numeric Expressions and Assignment Operators – part8 +======================================================================================= + +The [Awk command series][1] is getting exciting I believe, in the previous seven parts, we walked through some fundamentals of Awk that you need to master to enable you perform some basic text or string filtering in Linux. + +Starting with this part, we shall dive into advance areas of Awk to handle more complex text or string filtering operations. Therefore, we are going to cover Awk features such as variables, numeric expressions and assignment operators. + +![](http://www.tecmint.com/wp-content/uploads/2016/07/Learn-Awk-Variables-Numeric-Expressions-Assignment-Operators.png) +>Learn Awk Variables, Numeric Expressions and Assignment Operators + +These concepts are not comprehensively distinct from the ones you may have probably encountered in many programming languages before such shell, C, Python plus many others, so there is no need to worry much about this topic, we are simply revising the common ideas of using these mentioned features. + +This will probably be one of the easiest Awk command sections to understand, so sit back and lets get going. + +### 1. Awk Variables + +In any programming language, a variable is a place holder which stores a value, when you create a variable in a program file, as the file is executed, some space is created in memory that will store the value you specify for the variable. + +You can define Awk variables in the same way you define shell variables as follows: + +``` +variable_name=value +``` + +In the syntax above: + +- `variable_name`: is the name you give a variable +- `value`: the value stored in the variable + +Let’s look at some examples below: + +``` +computer_name=”tecmint.com” +port_no=”22” +email=”admin@tecmint.com” +server=”computer_name” +``` + +Take a look at the simple examples above, in the first variable definition, the value `tecmint.com` is assigned to the variable `computer_name`. + +Furthermore, the value 22 is assigned to the variable port_no, it is also possible to assign the value of one variable to another variable as in the last example where we assigned the value of computer_name to the variable server. + +If you can recall, right from [part 2 of this Awk series][2] were we covered field editing, we talked about how Awk divides input lines into fields and uses standard field access operator, $ to read the different fields that have been parsed. We can also use variables to store the values of fields as follows. + +``` +first_name=$2 +second_name=$3 +``` + +In the examples above, the value of first_name is set to second field and second_name is set to the third field. + +As an illustration, consider a file named names.txt which contains a list of an application’s users indicating their first and last names plus gender. Using the [cat command][3], we can view the contents of the file as follows: + +``` +$ cat names.txt +``` + +![](http://www.tecmint.com/wp-content/uploads/2016/07/List-File-Content-Using-cat-Command.png) +>List File Content Using cat Command + +Then, we can also use the variables first_name and second_name to store the first and second names of the first user on the list as by running the Awk command below: + +``` +$ awk '/Aaron/{ first_name=$2 ; second_name=$3 ; print first_name, second_name ; }' names.txt +``` + +![](http://www.tecmint.com/wp-content/uploads/2016/07/Store-Variables-Using-Awk-Command.png) +>Store Variables Using Awk Command + +Let us also take a look at another case, when you issue the command `uname -a` on your terminal, it prints out all your system information. + +The second field contains your `hostname`, therefore we can store the hostname in a variable called hostname and print it using Awk as follows: + +``` +$ uname -a +$ uname -a | awk '{hostname=$2 ; print hostname ; }' +``` + +![](http://www.tecmint.com/wp-content/uploads/2016/07/Store-Command-Output-to-Variable-Using-Awk.png) +>Store Command Output to Variable Using Awk + +### 2. Numeric Expressions + +In Awk, numeric expressions are built using the following numeric operators: + +- `*` : multiplication operator +- `+` : addition operator +- `/` : division operator +- `-` : subtraction operator +- `%` : modulus operator +- `^` : exponentiation operator + +The syntax for a numeric expressions is: + +``` +$ operand1 operator operand2 +``` + +In the form above, operand1 and operand2 can be numbers or variable names, and operator is any of the operators above. + +Below are some examples to demonstrate how to build numeric expressions: + +``` +counter=0 +num1=5 +num2=10 +num3=num2-num1 +counter=counter+1 +``` + +To understand the use of numeric expressions in Awk, we shall consider the following example below, with the file domains.txt which contains all domains owned by Tecmint. + +``` +news.tecmint.com +tecmint.com +linuxsay.com +windows.tecmint.com +tecmint.com +news.tecmint.com +tecmint.com +linuxsay.com +tecmint.com +news.tecmint.com +tecmint.com +linuxsay.com +windows.tecmint.com +tecmint.com +``` + +To view the contents of the file, use the command below: + +``` +$ cat domains.txt +``` + +![](http://www.tecmint.com/wp-content/uploads/2016/07/View-Contents-of-File.png) +>View Contents of File + +If we want to count the number of times the domain tecmint.com appears in the file, we can write a simple script to do that as follows: + +``` +#!/bin/bash +for file in $@; do +if [ -f $file ] ; then +#print out filename +echo "File is: $file" +#print a number incrementally for every line containing tecmint.com +awk '/^tecmint.com/ { counter=counter+1 ; printf "%s\n", counter ; }' $file +else +#print error info incase input is not a file +echo "$file is not a file, please specify a file." >&2 && exit 1 +fi +done +#terminate script with exit code 0 in case of successful execution +exit 0 +``` + +![](http://www.tecmint.com/wp-content/uploads/2016/07/Shell-Script-to-Count-a-String-in-File.png) +>Shell Script to Count a String or Text in File + +After creating the script, save it and make it executable, when we run it with the file, domains.txt as out input, we get the following output: + +``` +$ ./script.sh ~/domains.txt +``` + +![](http://www.tecmint.com/wp-content/uploads/2016/07/Script-To-Count-String.png) +>Script to Count String or Text + +From the output of the script, there are 6 lines in the file domains.txt which contain tecmint.com, to confirm that you can manually count them. + +### 3. Assignment Operators + +The last Awk feature we shall cover is assignment operators, there are several assignment operators in Awk and these include the following: + +- `*=` : multiplication assignment operator +- `+=` : addition assignment operator +- `/=` : division assignment operator +- `-=` : subtraction assignment operator +- `%=` : modulus assignment operator +- `^=` : exponentiation assignment operator + +The simplest syntax of an assignment operation in Awk is as follows: + +``` +$ variable_name=variable_name operator operand +``` + +Examples: + +``` +counter=0 +counter=counter+1 +num=20 +num=num-1 +``` + +You can use the assignment operators above to shorten assignment operations in Awk, consider the previous examples, we could perform the assignment in the following form: + +``` +variable_name operator=operand +counter=0 +counter+=1 +num=20 +num-=1 +``` + +Therefore, we can alter the Awk command in the shell script we just wrote above using += assignment operator as follows: + +``` +#!/bin/bash +for file in $@; do +if [ -f $file ] ; then +#print out filename +echo "File is: $file" +#print a number incrementally for every line containing tecmint.com +awk '/^tecmint.com/ { counter+=1 ; printf "%s\n", counter ; }' $file +else +#print error info incase input is not a file +echo "$file is not a file, please specify a file." >&2 && exit 1 +fi +done +#terminate script with exit code 0 in case of successful execution +exit 0 +``` + + +![](http://www.tecmint.com/wp-content/uploads/2016/07/Alter-Shell-Script.png) +>Alter Shell Script + +In this segment of the [Awk series][4], we covered some powerful Awk features, that is variables, building numeric expressions and using assignment operators, plus some few illustrations of how we can actually use them. + +These concepts are not any different from the one in other programming languages but there may be some significant distinctions under Awk programming. + +In part 9, we shall look at more Awk features that is special patterns: BEGIN and END. Until then, stay connected to Tecmint. + + +-------------------------------------------------------------------------------- + +via: http://www.tecmint.com/learn-awk-variables-numeric-expressions-and-assignment-operators/ + +作者:[Aaron Kili][a] +译者:[译者ID](https://github.com/译者ID) +校对:[校对ID](https://github.com/校对ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]: http://www.tecmint.com/author/aaronkili/ + + + + + + + + + + + + + + + + + + + +[1]: http://www.tecmint.com/category/awk-command/ +[2]: http://www.tecmint.com/awk-print-fields-columns-with-space-separator/ +[3]: http://www.tecmint.com/13-basic-cat-command-examples-in-linux/ +[4]: http://www.tecmint.com/category/awk-command/ From 3e3543ad84824a7684ebb75023f4371533738a78 Mon Sep 17 00:00:00 2001 From: range Date: Thu, 28 Jul 2016 09:41:43 +0800 Subject: [PATCH 044/122] =?UTF-8?q?=E7=BF=BB=E8=AF=91=E4=B8=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...Variables, Numeric Expressions and Assignment Operators.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sources/tech/awk/20160714 Part 8 - Learn How to Use Awk Variables, Numeric Expressions and Assignment Operators.md b/sources/tech/awk/20160714 Part 8 - Learn How to Use Awk Variables, Numeric Expressions and Assignment Operators.md index be536df74f..d7cfd4c064 100644 --- a/sources/tech/awk/20160714 Part 8 - Learn How to Use Awk Variables, Numeric Expressions and Assignment Operators.md +++ b/sources/tech/awk/20160714 Part 8 - Learn How to Use Awk Variables, Numeric Expressions and Assignment Operators.md @@ -1,4 +1,8 @@ +vim-kakali translating + + Learn How to Use Awk Variables, Numeric Expressions and Assignment Operators – part8 + ======================================================================================= The [Awk command series][1] is getting exciting I believe, in the previous seven parts, we walked through some fundamentals of Awk that you need to master to enable you perform some basic text or string filtering in Linux. From 0212c3012db43a18551f8a5355028eef4bae7680 Mon Sep 17 00:00:00 2001 From: Ezio Date: Thu, 28 Jul 2016 09:47:33 +0800 Subject: [PATCH 045/122] =?UTF-8?q?20160728-2=20=E9=80=89=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ... A DEMO UBUNTU VERSION IN A WEB BROWSER.md | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 sources/tech/20160721 YOU CAN TRY A DEMO UBUNTU VERSION IN A WEB BROWSER.md diff --git a/sources/tech/20160721 YOU CAN TRY A DEMO UBUNTU VERSION IN A WEB BROWSER.md b/sources/tech/20160721 YOU CAN TRY A DEMO UBUNTU VERSION IN A WEB BROWSER.md new file mode 100644 index 0000000000..7c40028c60 --- /dev/null +++ b/sources/tech/20160721 YOU CAN TRY A DEMO UBUNTU VERSION IN A WEB BROWSER.md @@ -0,0 +1,37 @@ +YOU CAN TRY A DEMO UBUNTU VERSION IN A WEB BROWSER +===================================================== + +Canonical, the parent company of Ubuntu, has put a lot of effort in popularizing Linux. No matter how much you dislike Ubuntu, but you have to accept that it has actually helped to make “Linux for human beings”. Ubuntu and its derivatives are the most used Linux distributions. + +In an effort to further popularize Ubuntu Linux, Canonical has put a website in place where you can use a [demo version of Ubuntu][1]. It will help you get the look and feel of Ubuntu. With that, it will be a little easier to make a decision about using Ubuntu for new users. + +You may argue that a live USB of Ubuntu will be better as it provides a far better experience without installing. I agree to that but keep in mind the effort to download the ISO, to create a live USB, change boot configuration and then using the live USB to experience. It’s tedious and not everyone is going to do that. An online tour is a simpler way out. + +So, what do you see in this online Ubuntu demo tour. Not a lot actually. + +You can browse files, you can use Unity Dash, you can experience Ubuntu Software Center, even install a few apps (they won’t be really installed), browse the File Manager and other such things. But that’s all. But in my opinion, it’s pretty nifty and does what it intends to do and that is provide a quick look at this popular OS. + +![](https://itsfoss.com/wp-content/uploads/2016/07/Ubuntu-online-demo.jpeg) + +![](https://itsfoss.com/wp-content/uploads/2016/07/Ubuntu-online-demo-1.jpeg) + +![](https://itsfoss.com/wp-content/uploads/2016/07/Ubuntu-online-demo-2.jpeg) + +If a friend or family ever asks you that he is interested in trying Linux and would like to experience it before installing, you can send her/him this link below: + +[Ubuntu Online Tour][0] + + +-------------------------------------------------------------------------------- + +via: https://itsfoss.com/ubuntu-online-demo/?utm_source=newsletter&utm_medium=email&utm_campaign=linux_and_open_source_stories_this_week + +作者:[Abhishek Prakash][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/abhishek/ +[0]: http://tour.ubuntu.com/en/ +[1]: http://tour.ubuntu.com/en/ From b8628099334cba9e402d33d92f4ce65584c5506f Mon Sep 17 00:00:00 2001 From: kokialoves <498497353@qq.com> Date: Thu, 28 Jul 2016 10:04:41 +0800 Subject: [PATCH 046/122] Update 20160721 YOU CAN TRY A DEMO UBUNTU VERSION IN A WEB BROWSER.md --- ...0160721 YOU CAN TRY A DEMO UBUNTU VERSION IN A WEB BROWSER.md | 1 + 1 file changed, 1 insertion(+) diff --git a/sources/tech/20160721 YOU CAN TRY A DEMO UBUNTU VERSION IN A WEB BROWSER.md b/sources/tech/20160721 YOU CAN TRY A DEMO UBUNTU VERSION IN A WEB BROWSER.md index 7c40028c60..6f52422a06 100644 --- a/sources/tech/20160721 YOU CAN TRY A DEMO UBUNTU VERSION IN A WEB BROWSER.md +++ b/sources/tech/20160721 YOU CAN TRY A DEMO UBUNTU VERSION IN A WEB BROWSER.md @@ -1,3 +1,4 @@ +[translating by kokialoves] YOU CAN TRY A DEMO UBUNTU VERSION IN A WEB BROWSER ===================================================== From e3e519c8a808f9d2d2be7bcafdbc4e9009162c6b Mon Sep 17 00:00:00 2001 From: wxy Date: Thu, 28 Jul 2016 11:13:49 +0800 Subject: [PATCH 047/122] PUB:20160705 Create Your Own Shell in Python - Part I @cposture --- ...reate Your Own Shell in Python - Part I.md | 82 +++++++++---------- 1 file changed, 41 insertions(+), 41 deletions(-) rename {translated/tech => published}/20160705 Create Your Own Shell in Python - Part I.md (67%) diff --git a/translated/tech/20160705 Create Your Own Shell in Python - Part I.md b/published/20160705 Create Your Own Shell in Python - Part I.md similarity index 67% rename from translated/tech/20160705 Create Your Own Shell in Python - Part I.md rename to published/20160705 Create Your Own Shell in Python - Part I.md index b54d0bff29..3aee650db0 100644 --- a/translated/tech/20160705 Create Your Own Shell in Python - Part I.md +++ b/published/20160705 Create Your Own Shell in Python - Part I.md @@ -1,7 +1,7 @@ -使用 Python 创建你自己的 Shell:Part I +使用 Python 创建你自己的 Shell (一) ========================================== -我很想知道一个 shell (像 bash,csh 等)内部是如何工作的。为了满足自己的好奇心,我使用 Python 实现了一个名为 **yosh** (Your Own Shell)的 Shell。本文章所介绍的概念也可以应用于其他编程语言。 +我很想知道一个 shell (像 bash,csh 等)内部是如何工作的。于是为了满足自己的好奇心,我使用 Python 实现了一个名为 **yosh** (Your Own Shell)的 Shell。本文章所介绍的概念也可以应用于其他编程语言。 (提示:你可以在[这里](https://github.com/supasate/yosh)查找本博文使用的源代码,代码以 MIT 许可证发布。在 Mac OS X 10.11.5 上,我使用 Python 2.7.10 和 3.4.3 进行了测试。它应该可以运行在其他类 Unix 环境,比如 Linux 和 Windows 上的 Cygwin。) @@ -20,15 +20,15 @@ yosh_project `yosh_project` 为项目根目录(你也可以把它简单命名为 `yosh`)。 -`yosh` 为包目录,且 `__init__.py` 可以使它成为与包目录名字相同的包(如果你不写 Python,可以忽略它。) +`yosh` 为包目录,且 `__init__.py` 可以使它成为与包的目录名字相同的包(如果你不用 Python 编写的话,可以忽略它。) `shell.py` 是我们主要的脚本文件。 ### 步骤 1:Shell 循环 -当启动一个 shell,它会显示一个命令提示符并等待你的命令输入。在接收了输入的命令并执行它之后(稍后文章会进行详细解释),你的 shell 会重新回到循环,等待下一条指令。 +当启动一个 shell,它会显示一个命令提示符并等待你的命令输入。在接收了输入的命令并执行它之后(稍后文章会进行详细解释),你的 shell 会重新回到这里,并循环等待下一条指令。 -在 `shell.py`,我们会以一个简单的 mian 函数开始,该函数调用了 shell_loop() 函数,如下: +在 `shell.py` 中,我们会以一个简单的 main 函数开始,该函数调用了 shell_loop() 函数,如下: ``` def shell_loop(): @@ -43,7 +43,7 @@ if __name__ == "__main__": main() ``` -接着,在 `shell_loop()`,为了指示循环是否继续或停止,我们使用了一个状态标志。在循环的开始,我们的 shell 将显示一个命令提示符,并等待读取命令输入。 +接着,在 `shell_loop()` 中,为了指示循环是否继续或停止,我们使用了一个状态标志。在循环的开始,我们的 shell 将显示一个命令提示符,并等待读取命令输入。 ``` import sys @@ -56,15 +56,15 @@ def shell_loop(): status = SHELL_STATUS_RUN while status == SHELL_STATUS_RUN: - # Display a command prompt + ### 显示命令提示符 sys.stdout.write('> ') sys.stdout.flush() - # Read command input + ### 读取命令输入 cmd = sys.stdin.readline() ``` -之后,我们切分命令输入并进行执行(我们即将实现`命令切分`和`执行`函数)。 +之后,我们切分命令(tokenize)输入并进行执行(execute)(我们即将实现 `tokenize` 和 `execute` 函数)。 因此,我们的 shell_loop() 会是如下这样: @@ -79,33 +79,33 @@ def shell_loop(): status = SHELL_STATUS_RUN while status == SHELL_STATUS_RUN: - # Display a command prompt + ### 显示命令提示符 sys.stdout.write('> ') sys.stdout.flush() - # Read command input + ### 读取命令输入 cmd = sys.stdin.readline() - # Tokenize the command input + ### 切分命令输入 cmd_tokens = tokenize(cmd) - # Execute the command and retrieve new status + ### 执行该命令并获取新的状态 status = execute(cmd_tokens) ``` -这就是我们整个 shell 循环。如果我们使用 `python shell.py` 启动我们的 shell,它会显示命令提示符。然而如果我们输入命令并按回车,它会抛出错误,因为我们还没定义`命令切分`函数。 +这就是我们整个 shell 循环。如果我们使用 `python shell.py` 启动我们的 shell,它会显示命令提示符。然而如果我们输入命令并按回车,它会抛出错误,因为我们还没定义 `tokenize` 函数。 为了退出 shell,可以尝试输入 ctrl-c。稍后我将解释如何以优雅的形式退出 shell。 -### 步骤 2:命令切分 +### 步骤 2:命令切分(tokenize) -当用户在我们的 shell 中输入命令并按下回车键,该命令将会是一个包含命令名称及其参数的很长的字符串。因此,我们必须切分该字符串(分割一个字符串为多个标记)。 +当用户在我们的 shell 中输入命令并按下回车键,该命令将会是一个包含命令名称及其参数的长字符串。因此,我们必须切分该字符串(分割一个字符串为多个元组)。 咋一看似乎很简单。我们或许可以使用 `cmd.split()`,以空格分割输入。它对类似 `ls -a my_folder` 的命令起作用,因为它能够将命令分割为一个列表 `['ls', '-a', 'my_folder']`,这样我们便能轻易处理它们了。 然而,也有一些类似 `echo "Hello World"` 或 `echo 'Hello World'` 以单引号或双引号引用参数的情况。如果我们使用 cmd.spilt,我们将会得到一个存有 3 个标记的列表 `['echo', '"Hello', 'World"']` 而不是 2 个标记的列表 `['echo', 'Hello World']`。 -幸运的是,Python 提供了一个名为 `shlex` 的库,它能够帮助我们效验如神地分割命令。(提示:我们也可以使用正则表达式,但它不是本文的重点。) +幸运的是,Python 提供了一个名为 `shlex` 的库,它能够帮助我们如魔法般地分割命令。(提示:我们也可以使用正则表达式,但它不是本文的重点。) ``` @@ -120,23 +120,23 @@ def tokenize(string): ... ``` -然后我们将这些标记发送到执行进程。 +然后我们将这些元组发送到执行进程。 ### 步骤 3:执行 -这是 shell 中核心和有趣的一部分。当 shell 执行 `mkdir test_dir` 时,到底发生了什么?(提示: `mkdir` 是一个带有 `test_dir` 参数的执行程序,用于创建一个名为 `test_dir` 的目录。) +这是 shell 中核心而有趣的一部分。当 shell 执行 `mkdir test_dir` 时,到底发生了什么?(提示: `mkdir` 是一个带有 `test_dir` 参数的执行程序,用于创建一个名为 `test_dir` 的目录。) -`execvp` 是涉及这一步的首个函数。在我们解释 `execvp` 所做的事之前,让我们看看它的实际效果。 +`execvp` 是这一步的首先需要的函数。在我们解释 `execvp` 所做的事之前,让我们看看它的实际效果。 ``` import os ... def execute(cmd_tokens): - # Execute command + ### 执行命令 os.execvp(cmd_tokens[0], cmd_tokens) - # Return status indicating to wait for next command in shell_loop + ### 返回状态以告知在 shell_loop 中等待下一个命令 return SHELL_STATUS_RUN ... @@ -144,11 +144,11 @@ def execute(cmd_tokens): 再次尝试运行我们的 shell,并输入 `mkdir test_dir` 命令,接着按下回车键。 -在我们敲下回车键之后,问题是我们的 shell 会直接退出而不是等待下一个命令。然而,目标正确地被创建。 +在我们敲下回车键之后,问题是我们的 shell 会直接退出而不是等待下一个命令。然而,目录正确地创建了。 因此,`execvp` 实际上做了什么? -`execvp` 是系统调用 `exec` 的一个变体。第一个参数是程序名字。`v` 表示第二个参数是一个程序参数列表(可变参数)。`p` 表示环境变量 `PATH` 会被用于搜索给定的程序名字。在我们上一次的尝试中,它将会基于我们的 `PATH` 环境变量查找`mkdir` 程序。 +`execvp` 是系统调用 `exec` 的一个变体。第一个参数是程序名字。`v` 表示第二个参数是一个程序参数列表(参数数量可变)。`p` 表示将会使用环境变量 `PATH` 搜索给定的程序名字。在我们上一次的尝试中,它将会基于我们的 `PATH` 环境变量查找`mkdir` 程序。 (还有其他 `exec` 变体,比如 execv、execvpe、execl、execlp、execlpe;你可以 google 它们获取更多的信息。) @@ -158,7 +158,7 @@ def execute(cmd_tokens): 因此,我们需要其他的系统调用来解决问题:`fork`。 -`fork` 会开辟新的内存并拷贝当前进程到一个新的进程。我们称这个新的进程为**子进程**,调用者进程为**父进程**。然后,子进程内存会被替换为被执行的程序。因此,我们的 shell,也就是父进程,可以免受内存替换的危险。 +`fork` 会分配新的内存并拷贝当前进程到一个新的进程。我们称这个新的进程为**子进程**,调用者进程为**父进程**。然后,子进程内存会被替换为被执行的程序。因此,我们的 shell,也就是父进程,可以免受内存替换的危险。 让我们看看修改的代码。 @@ -166,34 +166,34 @@ def execute(cmd_tokens): ... def execute(cmd_tokens): - # Fork a child shell process - # If the current process is a child process, its `pid` is set to `0` - # else the current process is a parent process and the value of `pid` - # is the process id of its child process. + ### 分叉一个子 shell 进程 + ### 如果当前进程是子进程,其 `pid` 被设置为 `0` + ### 否则当前进程是父进程的话,`pid` 的值 + ### 是其子进程的进程 ID。 pid = os.fork() if pid == 0: - # Child process - # Replace the child shell process with the program called with exec + ### 子进程 + ### 用被 exec 调用的程序替换该子进程 os.execvp(cmd_tokens[0], cmd_tokens) elif pid > 0: - # Parent process + ### 父进程 while True: - # Wait response status from its child process (identified with pid) + ### 等待其子进程的响应状态(以进程 ID 来查找) wpid, status = os.waitpid(pid, 0) - # Finish waiting if its child process exits normally - # or is terminated by a signal + ### 当其子进程正常退出时 + ### 或者其被信号中断时,结束等待状态 if os.WIFEXITED(status) or os.WIFSIGNALED(status): break - # Return status indicating to wait for next command in shell_loop + ### 返回状态以告知在 shell_loop 中等待下一个命令 return SHELL_STATUS_RUN ... ``` -当我们的父进程调用 `os.fork()`时,你可以想象所有的源代码被拷贝到了新的子进程。此时此刻,父进程和子进程看到的是相同的代码,且并行运行着。 +当我们的父进程调用 `os.fork()` 时,你可以想象所有的源代码被拷贝到了新的子进程。此时此刻,父进程和子进程看到的是相同的代码,且并行运行着。 如果运行的代码属于子进程,`pid` 将为 `0`。否则,如果运行的代码属于父进程,`pid` 将会是子进程的进程 id。 @@ -205,13 +205,13 @@ def execute(cmd_tokens): 现在,你可以尝试运行我们的 shell 并输入 `mkdir test_dir2`。它应该可以正确执行。我们的主 shell 进程仍然存在并等待下一条命令。尝试执行 `ls`,你可以看到已创建的目录。 -但是,这里仍有许多问题。 +但是,这里仍有一些问题。 第一,尝试执行 `cd test_dir2`,接着执行 `ls`。它应该会进入到一个空的 `test_dir2` 目录。然而,你将会看到目录并没有变为 `test_dir2`。 第二,我们仍然没有办法优雅地退出我们的 shell。 -我们将会在 [Part 2][1] 解决诸如此类的问题。 +我们将会在 [第二部分][1] 解决诸如此类的问题。 -------------------------------------------------------------------------------- @@ -219,8 +219,8 @@ def execute(cmd_tokens): via: https://hackercollider.com/articles/2016/07/05/create-your-own-shell-in-python-part-1/ 作者:[Supasate Choochaisri][a] -译者:[译者ID](https://github.com/译者ID) -校对:[校对者ID](https://github.com/校对者ID) +译者:[cposture](https://github.com/cposture) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 From 2ab589bf9da6bf62162970e1dc9c2d6ca150a810 Mon Sep 17 00:00:00 2001 From: wxy Date: Thu, 28 Jul 2016 11:44:36 +0800 Subject: [PATCH 048/122] PUB:20160706 Create Your Own Shell in Python - Part II @cposture --- ...eate Your Own Shell in Python - Part II.md | 43 ++++++++----------- 1 file changed, 19 insertions(+), 24 deletions(-) rename {translated/tech => published}/20160706 Create Your Own Shell in Python - Part II.md (76%) diff --git a/translated/tech/20160706 Create Your Own Shell in Python - Part II.md b/published/20160706 Create Your Own Shell in Python - Part II.md similarity index 76% rename from translated/tech/20160706 Create Your Own Shell in Python - Part II.md rename to published/20160706 Create Your Own Shell in Python - Part II.md index 0f0cd6a878..9e66d5643c 100644 --- a/translated/tech/20160706 Create Your Own Shell in Python - Part II.md +++ b/published/20160706 Create Your Own Shell in Python - Part II.md @@ -1,17 +1,17 @@ -使用 Python 创建你自己的 Shell:Part II +使用 Python 创建你自己的 Shell(下) =========================================== -在[part 1][1] 中,我们已经创建了一个主要的 shell 循环、切分了的命令输入,以及通过 `fork` 和 `exec` 执行命令。在这部分,我们将会解决剩下的问题。首先,`cd test_dir2` 命令无法修改我们的当前目录。其次,我们仍无法优雅地从 shell 中退出。 +在[上篇][1]中,我们已经创建了一个 shell 主循环、切分了命令输入,以及通过 `fork` 和 `exec` 执行命令。在这部分,我们将会解决剩下的问题。首先,`cd test_dir2` 命令无法修改我们的当前目录。其次,我们仍无法优雅地从 shell 中退出。 ### 步骤 4:内置命令 -“cd test_dir2 无法修改我们的当前目录” 这句话是对的,但在某种意义上也是错的。在执行完该命令之后,我们仍然处在同一目录,从这个意义上讲,它是对的。然而,目录实际上已经被修改,只不过它是在子进程中被修改。 +“`cd test_dir2` 无法修改我们的当前目录” 这句话是对的,但在某种意义上也是错的。在执行完该命令之后,我们仍然处在同一目录,从这个意义上讲,它是对的。然而,目录实际上已经被修改,只不过它是在子进程中被修改。 -还记得我们 fork 了一个子进程,然后执行命令,执行命令的过程没有发生在父进程上。结果是我们只是改变了子进程的当前目录,而不是父进程的目录。 +还记得我们分叉(fork)了一个子进程,然后执行命令,执行命令的过程没有发生在父进程上。结果是我们只是改变了子进程的当前目录,而不是父进程的目录。 然后子进程退出,而父进程在原封不动的目录下继续运行。 -因此,这类与 shell 自己相关的命令必须是内置命令。它必须在 shell 进程中执行而没有分叉(forking)。 +因此,这类与 shell 自己相关的命令必须是内置命令。它必须在 shell 进程中执行而不是在分叉中(forking)。 #### cd @@ -35,7 +35,6 @@ yosh_project import os from yosh.constants import * - def cd(args): os.chdir(args[0]) @@ -66,23 +65,21 @@ SHELL_STATUS_RUN = 1 ```python ... -# Import constants +### 导入常量 from yosh.constants import * -# Hash map to store built-in function name and reference as key and value +### 使用哈希映射来存储内建的函数名及其引用 built_in_cmds = {} - def tokenize(string): return shlex.split(string) - def execute(cmd_tokens): - # Extract command name and arguments from tokens + ### 从元组中分拆命令名称与参数 cmd_name = cmd_tokens[0] cmd_args = cmd_tokens[1:] - # If the command is a built-in command, invoke its function with arguments + ### 如果该命令是一个内建命令,使用参数调用该函数 if cmd_name in built_in_cmds: return built_in_cmds[cmd_name](cmd_args) @@ -91,29 +88,29 @@ def execute(cmd_tokens): 我们使用一个 python 字典变量 `built_in_cmds` 作为哈希映射(hash map),以存储我们的内置函数。我们在 `execute` 函数中提取命令的名字和参数。如果该命令在我们的哈希映射中,则调用对应的内置函数。 -(提示:`built_in_cmds[cmd_name]` 返回能直接使用参数调用的函数引用的。) +(提示:`built_in_cmds[cmd_name]` 返回能直接使用参数调用的函数引用。) 我们差不多准备好使用内置的 `cd` 函数了。最后一步是将 `cd` 函数添加到 `built_in_cmds` 映射中。 ``` ... -# Import all built-in function references +### 导入所有内建函数引用 from yosh.builtins import * ... -# Register a built-in function to built-in command hash map +### 注册内建函数到内建命令的哈希映射中 def register_command(name, func): built_in_cmds[name] = func -# Register all built-in commands here +### 在此注册所有的内建命令 def init(): register_command("cd", cd) def main(): - # Init shell before starting the main loop + ###在开始主循环之前初始化 shell init() shell_loop() ``` @@ -138,7 +135,7 @@ from yosh.builtins.cd import * 我们需要一个可以修改 shell 状态为 `SHELL_STATUS_STOP` 的函数。这样,shell 循环可以自然地结束,shell 将到达终点而退出。 -和 `cd` 一样,如果我们在子进程中 fork 和执行 `exit` 函数,其对父进程是不起作用的。因此,`exit` 函数需要成为一个 shell 内置函数。 +和 `cd` 一样,如果我们在子进程中分叉并执行 `exit` 函数,其对父进程是不起作用的。因此,`exit` 函数需要成为一个 shell 内置函数。 让我们从这开始:在 `builtins` 目录下创建一个名为 `exit.py` 的新文件。 @@ -159,7 +156,6 @@ yosh_project ``` from yosh.constants import * - def exit(args): return SHELL_STATUS_STOP ``` @@ -173,11 +169,10 @@ from yosh.builtins.exit import * 最后,我们在 `shell.py` 中的 `init()` 函数注册 `exit` 命令。 - ``` ... -# Register all built-in commands here +### 在此注册所有的内建命令 def init(): register_command("cd", cd) register_command("exit", exit) @@ -193,7 +188,7 @@ def init(): 我希望你能像我一样享受创建 `yosh` (**y**our **o**wn **sh**ell)的过程。但我的 `yosh` 版本仍处于早期阶段。我没有处理一些会使 shell 崩溃的极端状况。还有很多我没有覆盖的内置命令。为了提高性能,一些非内置命令也可以实现为内置命令(避免新进程创建时间)。同时,大量的功能还没有实现(请看 [公共特性](http://tldp.org/LDP/Bash-Beginners-Guide/html/x7243.html) 和 [不同特性](http://www.tldp.org/LDP/intro-linux/html/x12249.html)) -我已经在 github.com/supasate/yosh 中提供了源代码。请随意 fork 和尝试。 +我已经在 https://github.com/supasate/yosh 中提供了源代码。请随意 fork 和尝试。 现在该是创建你真正自己拥有的 Shell 的时候了。 @@ -205,12 +200,12 @@ via: https://hackercollider.com/articles/2016/07/06/create-your-own-shell-in-pyt 作者:[Supasate Choochaisri][a] 译者:[cposture](https://github.com/cposture) -校对:[校对者ID](https://github.com/校对者ID) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 [a]: https://disqus.com/by/supasate_choochaisri/ -[1]: https://hackercollider.com/articles/2016/07/05/create-your-own-shell-in-python-part-1/ +[1]: https://linux.cn/article-7624-1.html [2]: http://tldp.org/LDP/Bash-Beginners-Guide/html/x7243.html [3]: http://www.tldp.org/LDP/intro-linux/html/x12249.html [4]: https://github.com/supasate/yosh From dab654979b756ec209e172a61a2b1c1840940130 Mon Sep 17 00:00:00 2001 From: kokialoves <498497353@qq.com> Date: Thu, 28 Jul 2016 11:54:39 +0800 Subject: [PATCH 049/122] =?UTF-8?q?=E7=BF=BB=E8=AF=91=E5=AE=8C=E6=88=90=20?= =?UTF-8?q?(#4233)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Delete 20160721 YOU CAN TRY A DEMO UBUNTU VERSION IN A WEB BROWSER.md * Create 20160721 YOU CAN TRY A DEMO UBUNTU VERSION IN A WEB BROWSER.md --- ... A DEMO UBUNTU VERSION IN A WEB BROWSER.md | 38 ------------------- ... A DEMO UBUNTU VERSION IN A WEB BROWSER.md | 37 ++++++++++++++++++ 2 files changed, 37 insertions(+), 38 deletions(-) delete mode 100644 sources/tech/20160721 YOU CAN TRY A DEMO UBUNTU VERSION IN A WEB BROWSER.md create mode 100644 translated/tech/20160721 YOU CAN TRY A DEMO UBUNTU VERSION IN A WEB BROWSER.md diff --git a/sources/tech/20160721 YOU CAN TRY A DEMO UBUNTU VERSION IN A WEB BROWSER.md b/sources/tech/20160721 YOU CAN TRY A DEMO UBUNTU VERSION IN A WEB BROWSER.md deleted file mode 100644 index 6f52422a06..0000000000 --- a/sources/tech/20160721 YOU CAN TRY A DEMO UBUNTU VERSION IN A WEB BROWSER.md +++ /dev/null @@ -1,38 +0,0 @@ -[translating by kokialoves] -YOU CAN TRY A DEMO UBUNTU VERSION IN A WEB BROWSER -===================================================== - -Canonical, the parent company of Ubuntu, has put a lot of effort in popularizing Linux. No matter how much you dislike Ubuntu, but you have to accept that it has actually helped to make “Linux for human beings”. Ubuntu and its derivatives are the most used Linux distributions. - -In an effort to further popularize Ubuntu Linux, Canonical has put a website in place where you can use a [demo version of Ubuntu][1]. It will help you get the look and feel of Ubuntu. With that, it will be a little easier to make a decision about using Ubuntu for new users. - -You may argue that a live USB of Ubuntu will be better as it provides a far better experience without installing. I agree to that but keep in mind the effort to download the ISO, to create a live USB, change boot configuration and then using the live USB to experience. It’s tedious and not everyone is going to do that. An online tour is a simpler way out. - -So, what do you see in this online Ubuntu demo tour. Not a lot actually. - -You can browse files, you can use Unity Dash, you can experience Ubuntu Software Center, even install a few apps (they won’t be really installed), browse the File Manager and other such things. But that’s all. But in my opinion, it’s pretty nifty and does what it intends to do and that is provide a quick look at this popular OS. - -![](https://itsfoss.com/wp-content/uploads/2016/07/Ubuntu-online-demo.jpeg) - -![](https://itsfoss.com/wp-content/uploads/2016/07/Ubuntu-online-demo-1.jpeg) - -![](https://itsfoss.com/wp-content/uploads/2016/07/Ubuntu-online-demo-2.jpeg) - -If a friend or family ever asks you that he is interested in trying Linux and would like to experience it before installing, you can send her/him this link below: - -[Ubuntu Online Tour][0] - - --------------------------------------------------------------------------------- - -via: https://itsfoss.com/ubuntu-online-demo/?utm_source=newsletter&utm_medium=email&utm_campaign=linux_and_open_source_stories_this_week - -作者:[Abhishek Prakash][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/abhishek/ -[0]: http://tour.ubuntu.com/en/ -[1]: http://tour.ubuntu.com/en/ diff --git a/translated/tech/20160721 YOU CAN TRY A DEMO UBUNTU VERSION IN A WEB BROWSER.md b/translated/tech/20160721 YOU CAN TRY A DEMO UBUNTU VERSION IN A WEB BROWSER.md new file mode 100644 index 0000000000..d79969e3e7 --- /dev/null +++ b/translated/tech/20160721 YOU CAN TRY A DEMO UBUNTU VERSION IN A WEB BROWSER.md @@ -0,0 +1,37 @@ +你能在浏览器中运行UBUNTU +===================================================== + +Canonical, Ubuntu的母公司, 为Linux推广做了很多努力. 无论你有多么不喜欢 Ubuntu, 你必须承认它对 “Linux 易用性”的影响. Ubuntu 以及其衍生是应用最多的Linux版本 . + +为了进一步推广 Ubuntu Linux, Canonical 把它放到了浏览器里你可以再任何地方使用 [demo version of Ubuntu][1]. 它将帮你更好的体验 Ubuntu. 以便让新人更容易决定是否使用. + +你可能争辩说USB版的linux更好. 我同意但是你要知道你要下载ISO, 创建USB驱动, 修改配置文件. 并不是每个人都乐意这么干的. 在线体验是一个更好的选择. + +因此, 你能在Ubuntu在线看到什么. 实际上并不多. + +你可以浏览文件, 你可以使用 Unity Dash, 浏览 Ubuntu Software Center, 甚至装几个 apps (当然它们不会真的安装), 看一看文件浏览器 和其它一些东西. 以上就是全部了. 但是在我看来, 它是非常漂亮的 + +![](https://itsfoss.com/wp-content/uploads/2016/07/Ubuntu-online-demo.jpeg) + +![](https://itsfoss.com/wp-content/uploads/2016/07/Ubuntu-online-demo-1.jpeg) + +![](https://itsfoss.com/wp-content/uploads/2016/07/Ubuntu-online-demo-2.jpeg) + +如果你的朋友或者家人想试试Linux又不乐意安装, 你可以给他们以下链接: + +[Ubuntu Online Tour][0] + + +-------------------------------------------------------------------------------- + +via: https://itsfoss.com/ubuntu-online-demo/?utm_source=newsletter&utm_medium=email&utm_campaign=linux_and_open_source_stories_this_week + +作者:[Abhishek Prakash][a] +译者:[kokialoves](https://github.com/kokialoves) +校对:[校对ID](https://github.com/校对ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]: https://itsfoss.com/author/abhishek/ +[0]: http://tour.ubuntu.com/en/ +[1]: http://tour.ubuntu.com/en/ From 49dde28c2e619cee0d8d541d3c8016af0b40379c Mon Sep 17 00:00:00 2001 From: KS Date: Thu, 28 Jul 2016 11:55:18 +0800 Subject: [PATCH 050/122] =?UTF-8?q?=E5=AE=8C=E6=88=90=E7=BF=BB=E8=AF=91=20?= =?UTF-8?q?(#4232)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Create 20160602 How to build and deploy a Facebook Messenger bot with Python and Flask.md * Delete 20160602 How to build and deploy a Facebook Messenger bot with Python and Flask.md --- ...ook Messenger bot with Python and Flask.md | 320 ------------------ ...ook Messenger bot with Python and Flask.md | 319 +++++++++++++++++ 2 files changed, 319 insertions(+), 320 deletions(-) delete mode 100644 sources/tech/20160602 How to build and deploy a Facebook Messenger bot with Python and Flask.md create mode 100644 translated/tech/20160602 How to build and deploy a Facebook Messenger bot with Python and Flask.md diff --git a/sources/tech/20160602 How to build and deploy a Facebook Messenger bot with Python and Flask.md b/sources/tech/20160602 How to build and deploy a Facebook Messenger bot with Python and Flask.md deleted file mode 100644 index 6ab74e3527..0000000000 --- a/sources/tech/20160602 How to build and deploy a Facebook Messenger bot with Python and Flask.md +++ /dev/null @@ -1,320 +0,0 @@ -wyangsun translating -How to build and deploy a Facebook Messenger bot with Python and Flask, a tutorial -========================================================================== - -This is my log of how I built a simple Facebook Messenger bot. The functionality is really simple, it’s an echo bot that will just print back to the user what they write. - -This is something akin to the Hello World example for servers, the echo server. - -The goal of the project is not to build the best Messenger bot, but rather to get a feel for what it takes to build a minimal bot and how everything comes together. - -- [Tech Stack][1] -- [Bot Architecture][2] -- [The Bot Server][3] -- [Deploying to Heroku][4] -- [Creating the Facebook App][5] -- [Conclusion][6] - -### Tech Stack - -The tech stack that was used is: - -- [Heroku][7] for back end hosting. The free-tier is more than enough for a tutorial of this level. The echo bot does not require any sort of data persistence so a database was not used. -- [Python][8] was the language of choice. The version that was used is 2.7 however it can easily be ported to Python 3 with minor alterations. -- [Flask][9] as the web development framework. It’s a very lightweight framework that’s perfect for small scale projects/microservices. -- Finally the [Git][10] version control system was used for code maintenance and to deploy to Heroku. -- Worth mentioning: [Virtualenv][11]. This python tool is used to create “environments” clean of python libraries so you can only install the necessary requirements and minimize the app footprint. - -### Bot Architecture - -Messenger bots are constituted by a server that responds to two types of requests: - -- GET requests are being used for authentication. They are sent by Messenger with an authentication code that you register on FB. -- POST requests are being used for the actual communication. The typical workflow is that the bot will initiate the communication by sending the POST request with the data of the message sent by the user, we will handle it, send a POST request of our own back. If that one is completed successfully (a 200 OK status is returned) we also respond with a 200 OK code to the initial Messenger request. -For this tutorial the app will be hosted on Heroku, which provides a nice and easy interface to deploy apps. As mentioned the free tier will suffice for this tutorial. - -After the app has been deployed and is running, we’ll create a Facebook app and link it to our app so that messenger knows where to send the requests that are meant for our bot. - -### The Bot Server -The basic server code was taken from the following [Chatbot][12] project by Github user [hult (Magnus Hult)][13], with a few modifications to the code to only echo messages and a couple bugfixes I came across. This is the final version of the server code: - -``` -from flask import Flask, request -import json -import requests - -app = Flask(__name__) - -# This needs to be filled with the Page Access Token that will be provided -# by the Facebook App that will be created. -PAT = '' - -@app.route('/', methods=['GET']) -def handle_verification(): - print "Handling Verification." - if request.args.get('hub.verify_token', '') == 'my_voice_is_my_password_verify_me': - print "Verification successful!" - return request.args.get('hub.challenge', '') - else: - print "Verification failed!" - return 'Error, wrong validation token' - -@app.route('/', methods=['POST']) -def handle_messages(): - print "Handling Messages" - payload = request.get_data() - print payload - for sender, message in messaging_events(payload): - print "Incoming from %s: %s" % (sender, message) - send_message(PAT, sender, message) - return "ok" - -def messaging_events(payload): - """Generate tuples of (sender_id, message_text) from the - provided payload. - """ - data = json.loads(payload) - messaging_events = data["entry"][0]["messaging"] - for event in messaging_events: - if "message" in event and "text" in event["message"]: - yield event["sender"]["id"], event["message"]["text"].encode('unicode_escape') - else: - yield event["sender"]["id"], "I can't echo this" - - -def send_message(token, recipient, text): - """Send the message text to recipient with id recipient. - """ - - r = requests.post("https://graph.facebook.com/v2.6/me/messages", - params={"access_token": token}, - data=json.dumps({ - "recipient": {"id": recipient}, - "message": {"text": text.decode('unicode_escape')} - }), - headers={'Content-type': 'application/json'}) - if r.status_code != requests.codes.ok: - print r.text - -if __name__ == '__main__': - app.run() -``` - -Let’s break down the code. The first part is the imports that will be needed: - -``` -from flask import Flask, request -import json -import requests -``` - -Next we define the two functions (using the Flask specific app.route decorators) that will handle the GET and POST requests to our bot. - -``` -@app.route('/', methods=['GET']) -def handle_verification(): - print "Handling Verification." - if request.args.get('hub.verify_token', '') == 'my_voice_is_my_password_verify_me': - print "Verification successful!" - return request.args.get('hub.challenge', '') - else: - print "Verification failed!" - return 'Error, wrong validation token' -``` - -The verify_token object that is being sent by Messenger will be declared by us when we create the Facebook app. We have to validate the one we are being have against itself. Finally we return the “hub.challenge” back to Messenger. - -The function that handles the POST requests is a bit more interesting. - -``` -@app.route('/', methods=['POST']) -def handle_messages(): - print "Handling Messages" - payload = request.get_data() - print payload - for sender, message in messaging_events(payload): - print "Incoming from %s: %s" % (sender, message) - send_message(PAT, sender, message) - return "ok" -``` - -When called we grab the massage payload, use function messaging_events to break it down and extract the sender user id and the actual message sent, generating a python iterator that we can loop over. Notice that in each request sent by Messenger it is possible to have more than one messages. - -``` -def messaging_events(payload): - """Generate tuples of (sender_id, message_text) from the - provided payload. - """ - data = json.loads(payload) - messaging_events = data["entry"][0]["messaging"] - for event in messaging_events: - if "message" in event and "text" in event["message"]: - yield event["sender"]["id"], event["message"]["text"].encode('unicode_escape') - else: - yield event["sender"]["id"], "I can't echo this" -``` - -While iterating over each message we call the send_message function and we perform the POST request back to Messnger using the Facebook Graph messages API. During this time we still have not responded to the original Messenger request which we are blocking. This can lead to timeouts and 5XX errors. - -The above was spotted during an outage due to a bug I came across, which was occurred when the user was sending emojis which are actual unicode ids, however Python was miss-encoding. We ended up sending back garbage. - -This POST request back to Messenger would never finish, and that in turn would cause 5XX status codes to be returned to the original request, rendering the service unusable. - -This was fixed by escaping the messages with `encode('unicode_escape')` and then just before we sent back the message decode it with `decode('unicode_escape')`. - -``` -def send_message(token, recipient, text): - """Send the message text to recipient with id recipient. - """ - - r = requests.post("https://graph.facebook.com/v2.6/me/messages", - params={"access_token": token}, - data=json.dumps({ - "recipient": {"id": recipient}, - "message": {"text": text.decode('unicode_escape')} - }), - headers={'Content-type': 'application/json'}) - if r.status_code != requests.codes.ok: - print r.text -``` - -### Deploying to Heroku - -Once the code was built to my liking it was time for the next step. -Deploy the app. - -Sure, but how? - -I have deployed apps before to Heroku (mainly Rails) however I was always following a tutorial of some sort, so the configuration has already been created. In this case though I had to start from scratch. - -Fortunately it was the official [Heroku documentation][14] to the rescue. The article explains nicely the bare minimum required for running an app. - -Long story short, what we need besides our code are two files. The first file is the “requirements.txt” file which is a list of of the library dependencies required to run the application. - -The second file required is the “Procfile”. This file is there to inform the Heroku how to run our service. Again the bare minimum needed for this file is the following: - ->web: gunicorn echoserver:app - -The way this will be interpreted by heroku is that our app is started by running the echoserver.py file and the app will be using gunicorn as the web server. The reason we are using an additional webserver is performance related and is explained in the above Heroku documentation: - ->Web applications that process incoming HTTP requests concurrently make much more efficient use of dyno resources than web applications that only process one request at a time. Because of this, we recommend using web servers that support concurrent request processing whenever developing and running production services. - ->The Django and Flask web frameworks feature convenient built-in web servers, but these blocking servers only process a single request at a time. If you deploy with one of these servers on Heroku, your dyno resources will be underutilized and your application will feel unresponsive. - ->Gunicorn is a pure-Python HTTP server for WSGI applications. It allows you to run any Python application concurrently by running multiple Python processes within a single dyno. It provides a perfect balance of performance, flexibility, and configuration simplicity. - -Going back to our “requirements.txt” file let’s see how it binds with the Virtualenv tool that was mentioned. - -At anytime, your developement machine may have a number of python libraries installed. When deploying applications you don’t want to have these libraries loaded as it makes it hard to make out which ones you actually use. - -What Virtualenv does is create a new blank virtual enviroment so that you can only install the libraries that your app requires. - -You can check which libraries are currently installed by running the following command: - -``` -kostis@KostisMBP ~ $ pip freeze -cycler==0.10.0 -Flask==0.10.1 -gunicorn==19.6.0 -itsdangerous==0.24 -Jinja2==2.8 -MarkupSafe==0.23 -matplotlib==1.5.1 -numpy==1.10.4 -pyparsing==2.1.0 -python-dateutil==2.5.0 -pytz==2015.7 -requests==2.10.0 -scipy==0.17.0 -six==1.10.0 -virtualenv==15.0.1 -Werkzeug==0.11.10 -``` - -Note: The pip tool should already be installed on your machine along with Python. - -If not check the [official site][15] for how to install it. - -Now let’s use Virtualenv to create a new blank enviroment. First we create a new folder for our project, and change dir into it: - -``` -kostis@KostisMBP projects $ mkdir echoserver -kostis@KostisMBP projects $ cd echoserver/ -kostis@KostisMBP echoserver $ -``` - -Now let’s create a new enviroment called echobot. To activate it you run the following source command, and checking with pip freeze we can see that it’s now empty. - -``` -kostis@KostisMBP echoserver $ virtualenv echobot -kostis@KostisMBP echoserver $ source echobot/bin/activate -(echobot) kostis@KostisMBP echoserver $ pip freeze -(echobot) kostis@KostisMBP echoserver $ -``` - -We can start installing the libraries required. The ones we’ll need are flask, gunicorn, and requests and with them installed we create the requirements.txt file: - -``` -(echobot) kostis@KostisMBP echoserver $ pip install flask -(echobot) kostis@KostisMBP echoserver $ pip install gunicorn -(echobot) kostis@KostisMBP echoserver $ pip install requests -(echobot) kostis@KostisMBP echoserver $ pip freeze -click==6.6 -Flask==0.11 -gunicorn==19.6.0 -itsdangerous==0.24 -Jinja2==2.8 -MarkupSafe==0.23 -requests==2.10.0 -Werkzeug==0.11.10 -(echobot) kostis@KostisMBP echoserver $ pip freeze > requirements.txt -``` - -After all the above have been run, we create the echoserver.py file with the python code and the Procfile with the command that was mentioned, and we should end up with the following files/folders: - -``` -(echobot) kostis@KostisMBP echoserver $ ls -Procfile echobot echoserver.py requirements.txt -``` - -We are now ready to upload to Heroku. We need to do two things. The first is to install the Heroku toolbet if it’s not already installed on your system (go to [Heroku][16] for details). The second is to create a new Heroku app through the [web interface][17]. - -Click on the big plus sign on the top right and select “Create new app”. - - - - - - - - --------------------------------------------------------------------------------- - -via: http://tsaprailis.com/2016/06/02/How-to-build-and-deploy-a-Facebook-Messenger-bot-with-Python-and-Flask-a-tutorial/ - -作者:[Konstantinos Tsaprailis][a] -译者:[译者ID](https://github.com/译者ID) -校对:[校对者ID](https://github.com/校对者ID) - -本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创翻译,[Linux中国](https://linux.cn/) 荣誉推出 - -[a]: https://github.com/kostistsaprailis -[1]: http://tsaprailis.com/2016/06/02/How-to-build-and-deploy-a-Facebook-Messenger-bot-with-Python-and-Flask-a-tutorial/#tech-stack -[2]: http://tsaprailis.com/2016/06/02/How-to-build-and-deploy-a-Facebook-Messenger-bot-with-Python-and-Flask-a-tutorial/#bot-architecture -[3]: http://tsaprailis.com/2016/06/02/How-to-build-and-deploy-a-Facebook-Messenger-bot-with-Python-and-Flask-a-tutorial/#the-bot-server -[4]: http://tsaprailis.com/2016/06/02/How-to-build-and-deploy-a-Facebook-Messenger-bot-with-Python-and-Flask-a-tutorial/#deploying-to-heroku -[5]: http://tsaprailis.com/2016/06/02/How-to-build-and-deploy-a-Facebook-Messenger-bot-with-Python-and-Flask-a-tutorial/#creating-the-facebook-app -[6]: http://tsaprailis.com/2016/06/02/How-to-build-and-deploy-a-Facebook-Messenger-bot-with-Python-and-Flask-a-tutorial/#conclusion -[7]: https://www.heroku.com -[8]: https://www.python.org -[9]: http://flask.pocoo.org -[10]: https://git-scm.com -[11]: https://virtualenv.pypa.io/en/stable -[12]: https://github.com/hult/facebook-chatbot-python -[13]: https://github.com/hult -[14]: https://devcenter.heroku.com/articles/python-gunicorn -[15]: https://pip.pypa.io/en/stable/installing -[16]: https://toolbelt.heroku.com -[17]: https://dashboard.heroku.com/apps - - diff --git a/translated/tech/20160602 How to build and deploy a Facebook Messenger bot with Python and Flask.md b/translated/tech/20160602 How to build and deploy a Facebook Messenger bot with Python and Flask.md new file mode 100644 index 0000000000..5ad4e62816 --- /dev/null +++ b/translated/tech/20160602 How to build and deploy a Facebook Messenger bot with Python and Flask.md @@ -0,0 +1,319 @@ +如何用Python和Flask建立部署一个Facebook信使机器人教程 +========================================================================== + +这是我建立一个简单的Facebook信使机器人的记录。功能很简单,他是一个回显机器人,只是打印回用户写了什么。 + +回显服务器类似于服务器的“Hello World”例子。 + +这个项目的目的不是建立最好的信使机器人,而是获得建立一个小型机器人和每个事物是如何整合起来的感觉。 + +- [技术栈][1] +- [机器人架构][2] +- [机器人服务器][3] +- [部署到 Heroku][4] +- [创建 Facebook 应用][5] +- [结论][6] + +### 技术栈 + +使用到的技术栈: + +- [Heroku][7] 做后端主机。免费层足够这个等级的教程。回显机器人不需要任何种类的数据持久,所以不需要数据库。 +- [Python][8] 是选择的一个语言。版本选择2.7,虽然它移植到 Pyhton 3 很容易,只需要很少的改动。 +- [Flask][9] 作为网站开发框架。它是非常轻量的框架,用在小型工程或微服务是完美的。 +- 最后 [Git][10] 版本控制系统用来维护代码和部署到 Heroku。 +- 值得一提:[Virtualenv][11]。这个 python 工具是用来创建清洁的 python 库“环境”的,你只用安装必要的需求和最小化的应用封装。 + +### 机器人架构 + +信使机器人是由一个服务器组成,响应两种请求: + +- GET 请求被用来认证。他们与你注册的 FB 认证码一同被信使发出。 +- POST 请求被用来真实的通信。传统的工作流是,机器人将通过发送 POST 请求与用户发送的消息数据建立通信,我们将处理它,发送一个我们自己的 POST 请求回去。如果这一个完全成功(返回一个200 OK 状态)我们也响应一个200 OK 码给初始信使请求。 +这个教程应用将托管到Heroku,他提供了一个很好并且简单的接口来部署应用。如前所述,免费层可以满足这个教程。 + +在应用已经部署并且运行后,我们将创建一个 Facebook 应用然后连接它到我们的应用,以便信使知道发送请求到哪,这就是我们的机器人。 + +### 机器人服务器 + +基本的服务器代码可以在Github用户 [hult(Magnus Hult)][13] 的 [Chatbot][12] 工程上获取,经过一些代码修改只回显消息和一些我遇到的错误更正。最终版本的服务器代码: + +``` +from flask import Flask, request +import json +import requests + +app = Flask(__name__) + +# 这需要填写被授予的页面通行令牌 +# 通过 Facebook 应用创建令牌。 +PAT = '' + +@app.route('/', methods=['GET']) +def handle_verification(): + print "Handling Verification." + if request.args.get('hub.verify_token', '') == 'my_voice_is_my_password_verify_me': + print "Verification successful!" + return request.args.get('hub.challenge', '') + else: + print "Verification failed!" + return 'Error, wrong validation token' + +@app.route('/', methods=['POST']) +def handle_messages(): + print "Handling Messages" + payload = request.get_data() + print payload + for sender, message in messaging_events(payload): + print "Incoming from %s: %s" % (sender, message) + send_message(PAT, sender, message) + return "ok" + +def messaging_events(payload): + """Generate tuples of (sender_id, message_text) from the + provided payload. + """ + data = json.loads(payload) + messaging_events = data["entry"][0]["messaging"] + for event in messaging_events: + if "message" in event and "text" in event["message"]: + yield event["sender"]["id"], event["message"]["text"].encode('unicode_escape') + else: + yield event["sender"]["id"], "I can't echo this" + + +def send_message(token, recipient, text): + """Send the message text to recipient with id recipient. + """ + + r = requests.post("https://graph.facebook.com/v2.6/me/messages", + params={"access_token": token}, + data=json.dumps({ + "recipient": {"id": recipient}, + "message": {"text": text.decode('unicode_escape')} + }), + headers={'Content-type': 'application/json'}) + if r.status_code != requests.codes.ok: + print r.text + +if __name__ == '__main__': + app.run() +``` + +让我们分解代码。第一部分是引入所需: + +``` +from flask import Flask, request +import json +import requests +``` + +接下来我们定义两个函数(使用 Flask 特定的 app.route 装饰器),用来处理到我们的机器人的 GET 和 POST 请求。 + +``` +@app.route('/', methods=['GET']) +def handle_verification(): + print "Handling Verification." + if request.args.get('hub.verify_token', '') == 'my_voice_is_my_password_verify_me': + print "Verification successful!" + return request.args.get('hub.challenge', '') + else: + print "Verification failed!" + return 'Error, wrong validation token' +``` + +当我们创建 Facebook 应用时声明由信使发送的 verify_token 对象。我们必须对自己进行认证。最后我们返回“hub.challenge”给信使。 + +处理 POST 请求的函数更有趣 + +``` +@app.route('/', methods=['POST']) +def handle_messages(): + print "Handling Messages" + payload = request.get_data() + print payload + for sender, message in messaging_events(payload): + print "Incoming from %s: %s" % (sender, message) + send_message(PAT, sender, message) + return "ok" +``` + +当调用我们抓取的消息负载时,使用函数 messaging_events 来中断它并且提取发件人身份和真实发送消息,生成一个 python 迭代器循环遍历。请注意信使发送的每个请求有可能多于一个消息。 + +``` +def messaging_events(payload): + """Generate tuples of (sender_id, message_text) from the + provided payload. + """ + data = json.loads(payload) + messaging_events = data["entry"][0]["messaging"] + for event in messaging_events: + if "message" in event and "text" in event["message"]: + yield event["sender"]["id"], event["message"]["text"].encode('unicode_escape') + else: + yield event["sender"]["id"], "I can't echo this" +``` + +迭代完每个消息时我们调用send_message函数然后我们执行POST请求回给使用Facebook图形消息接口信使。在这期间我们一直没有回应我们阻塞的原始信使请求。这会导致超时和5XX错误。 + +上述的发现错误是中断期间我偶然发现的,当用户发送表情时其实的是当成了 unicode 标识,无论如何 Python 发生了误编码。我们以发送回垃圾结束。 + +这个 POST 请求回到信使将不会结束,这会导致发生5xx状态返回给原始的请求,显示服务不可用。 + +通过使用`encode('unicode_escape')`转义消息然后在我们发送回消息前用`decode('unicode_escape')`解码消息就可以解决。 + +``` +def send_message(token, recipient, text): + """Send the message text to recipient with id recipient. + """ + + r = requests.post("https://graph.facebook.com/v2.6/me/messages", + params={"access_token": token}, + data=json.dumps({ + "recipient": {"id": recipient}, + "message": {"text": text.decode('unicode_escape')} + }), + headers={'Content-type': 'application/json'}) + if r.status_code != requests.codes.ok: + print r.text +``` + +### 部署到 Heroku + +一旦代码已经建立成我想要的样子时就可以进行下一步。部署应用。 + +当然,但是怎么做? + +我之前已经部署了应用到 Heroku (主要是 Rails)然而我总是遵循某种教程,所以配置已经创建。在这种情况下,尽管我必须从头开始。 + +幸运的是有官方[Heroku文档][14]来帮忙。这篇文章很好地说明了运行应用程序所需的最低限度。 + +长话短说,我们需要的除了我们的代码还有两个文件。第一个文件是“requirements.txt”他列出了运行应用所依赖的库。 + +需要的第二个文件是“Procfile”。这个文件通知 Heroku 如何运行我们的服务。此外这个文件最低限度如下: + +>web: gunicorn echoserver:app + +heroku解读他的方式是我们的应用通过运行 echoserver.py 开始并且应用将使用 gunicorn 作为网站服务器。我们使用一个额外的网站服务器是因为与性能相关并在上面的Heroku文档里解释了: + +>Web 应用程序并发处理传入的HTTP请求比一次只处理一个请求的Web应用程序,更有效利地用动态资源。由于这个原因,我们建议使用支持并发请求的 web 服务器处理开发和生产运行的服务。 + +>Django 和 Flask web 框架特性方便内建 web 服务器,但是这些阻塞式服务器一个时刻只处理一个请求。如果你部署这种服务到 Heroku上,你的动态资源不会充分使用并且你的应用会感觉迟钝。 + +>Gunicorn 是一个纯 Python HTTP 的 WSGI 引用服务器。允许你在单独一个动态资源内通过并发运行多 Python 进程的方式运行任一 Python 应用。它提供了一个完美性能,弹性,简单配置的平衡。 + +回到我们提到的“requirements.txt”文件,让我们看看它如何结合 Virtualenv 工具。 + +在任何时候,你的开发机器也许有若干已安装的 python 库。当部署应用时你不想这些库被加载因为很难辨认出你实际使用哪些库。 + +Virtualenv 创建一个新的空白虚拟环境,因此你可以只安装你应用需要的库。 + +你可以检查当前安装使用哪些库的命令如下: + +``` +kostis@KostisMBP ~ $ pip freeze +cycler==0.10.0 +Flask==0.10.1 +gunicorn==19.6.0 +itsdangerous==0.24 +Jinja2==2.8 +MarkupSafe==0.23 +matplotlib==1.5.1 +numpy==1.10.4 +pyparsing==2.1.0 +python-dateutil==2.5.0 +pytz==2015.7 +requests==2.10.0 +scipy==0.17.0 +six==1.10.0 +virtualenv==15.0.1 +Werkzeug==0.11.10 +``` + +注意:pip 工具应该已经与 Python 一起安装在你的机器上。 + +如果没有,查看[官方网站][15]如何安装他。 + +现在让我们使用 Virtualenv 来创建一个新的空白环境。首先我们给我们的工程创建一个新文件夹,然后进到目录下: + +``` +kostis@KostisMBP projects $ mkdir echoserver +kostis@KostisMBP projects $ cd echoserver/ +kostis@KostisMBP echoserver $ +``` + +现在来创建一个叫做 echobot 新的环境。运行下面的 source 命令激活它,然后使用 pip freeze 检查,我们能看到现在是空的。 + +``` +kostis@KostisMBP echoserver $ virtualenv echobot +kostis@KostisMBP echoserver $ source echobot/bin/activate +(echobot) kostis@KostisMBP echoserver $ pip freeze +(echobot) kostis@KostisMBP echoserver $ +``` + +我们可以安装需要的库。我们需要是 flask,gunicorn,和 requests,他们被安装完我们就创建 requirements.txt 文件: + +``` +(echobot) kostis@KostisMBP echoserver $ pip install flask +(echobot) kostis@KostisMBP echoserver $ pip install gunicorn +(echobot) kostis@KostisMBP echoserver $ pip install requests +(echobot) kostis@KostisMBP echoserver $ pip freeze +click==6.6 +Flask==0.11 +gunicorn==19.6.0 +itsdangerous==0.24 +Jinja2==2.8 +MarkupSafe==0.23 +requests==2.10.0 +Werkzeug==0.11.10 +(echobot) kostis@KostisMBP echoserver $ pip freeze > requirements.txt +``` + +毕竟上文已经被运行,我们用 python 代码创建 echoserver.py 文件然后用之前提到的命令创建 Procfile,我们应该以下面的文件/文件夹结束: + +``` +(echobot) kostis@KostisMBP echoserver $ ls +Procfile echobot echoserver.py requirements.txt +``` + +我们现在准备上传到 Heroku。我们需要做两件事。第一是安装 Heroku toolbet 如果你还没安装到你的系统中(详细看[Heroku][16])。第二通过[网页接口][17]创建一个新的 Heroku 应用。 + +点击右上的大加号然后选择“Create new app”。 + + + + + + + + +-------------------------------------------------------------------------------- + +via: http://tsaprailis.com/2016/06/02/How-to-build-and-deploy-a-Facebook-Messenger-bot-with-Python-and-Flask-a-tutorial/ + +作者:[Konstantinos Tsaprailis][a] +译者:[wyangsun](https://github.com/wyangsun) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创翻译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]: https://github.com/kostistsaprailis +[1]: http://tsaprailis.com/2016/06/02/How-to-build-and-deploy-a-Facebook-Messenger-bot-with-Python-and-Flask-a-tutorial/#tech-stack +[2]: http://tsaprailis.com/2016/06/02/How-to-build-and-deploy-a-Facebook-Messenger-bot-with-Python-and-Flask-a-tutorial/#bot-architecture +[3]: http://tsaprailis.com/2016/06/02/How-to-build-and-deploy-a-Facebook-Messenger-bot-with-Python-and-Flask-a-tutorial/#the-bot-server +[4]: http://tsaprailis.com/2016/06/02/How-to-build-and-deploy-a-Facebook-Messenger-bot-with-Python-and-Flask-a-tutorial/#deploying-to-heroku +[5]: http://tsaprailis.com/2016/06/02/How-to-build-and-deploy-a-Facebook-Messenger-bot-with-Python-and-Flask-a-tutorial/#creating-the-facebook-app +[6]: http://tsaprailis.com/2016/06/02/How-to-build-and-deploy-a-Facebook-Messenger-bot-with-Python-and-Flask-a-tutorial/#conclusion +[7]: https://www.heroku.com +[8]: https://www.python.org +[9]: http://flask.pocoo.org +[10]: https://git-scm.com +[11]: https://virtualenv.pypa.io/en/stable +[12]: https://github.com/hult/facebook-chatbot-python +[13]: https://github.com/hult +[14]: https://devcenter.heroku.com/articles/python-gunicorn +[15]: https://pip.pypa.io/en/stable/installing +[16]: https://toolbelt.heroku.com +[17]: https://dashboard.heroku.com/apps + + From d31c18f5a45e58df54066e34310a58ad2efe2836 Mon Sep 17 00:00:00 2001 From: range Date: Thu, 28 Jul 2016 12:53:36 +0800 Subject: [PATCH 051/122] =?UTF-8?q?=E7=BF=BB=E8=AF=91=E5=AE=8C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...0718 Creating your first Git repository.md | 181 ---------------- ...0718 Creating your first Git repository.md | 199 ++++++++++++++++++ 2 files changed, 199 insertions(+), 181 deletions(-) delete mode 100644 sources/tech/20160718 Creating your first Git repository.md create mode 100644 translated/tech/20160718 Creating your first Git repository.md diff --git a/sources/tech/20160718 Creating your first Git repository.md b/sources/tech/20160718 Creating your first Git repository.md deleted file mode 100644 index 4ec9b0aace..0000000000 --- a/sources/tech/20160718 Creating your first Git repository.md +++ /dev/null @@ -1,181 +0,0 @@ -vim-kakali translating - - - -Creating your first Git repository -====================================== - -![](https://opensource.com/sites/default/files/styles/image-full-size/public/images/life/open_abstract_pieces.jpg?itok=ZRt0Db00) - -Now it is time to learn how to create your own Git repository, and how to add files and make commits. - -In the previous installments in this series, you learned how to interact with Git as an end user; you were the aimless wanderer who stumbled upon an open source project's website, cloned a repository, and moved on with your life. You learned that interacting with Git wasn't as confusing as you may have thought it would be, and maybe you've been convinced that it's time to start leveraging Git for your own work. - -While Git is definitely the tool of choice for major software projects, it doesn't only work with major software projects. It can manage your grocery lists (if they're that important to you, and they may be!), your configuration files, a journal or diary, a novel in progress, and even source code! - -And it is well worth doing; after all, when have you ever been angry that you have a backup copy of something that you've just mangled beyond recognition? - -Git can't work for you unless you use it, and there's no time like the present. Or, translated to Git, "There is no push like origin HEAD". You'll understand that later, I promise. - -### The audio recording analogy - -We tend to speak of computer imaging in terms of snapshots because most of us can identify with the idea of having a photo album filled with particular moments in time. It may be more useful, however, to think of Git more like an analogue audio recording. - -A traditional studio tape deck, in case you're unfamiliar, has a few components: it contains the reels that turn either forward or in reverse, tape to preserve sound waves, and a playhead to record or detect sound waves on tape and present them to the listener. - -In addition to playing a tape forward, you can rewind it to get back to a previous point in the tape, or fast-forward to skip ahead to a later point. - -Imagine a band in the 1970s recording to tape. You can imagine practising a song over and over until all the parts are perfect, and then laying down a track. First, you record the drums, and then the bass, and then the guitar, and then the vocals. Each time you record, the studio engineer rewinds the tape and puts it into loop mode so that it plays the previous part as you play yours; that is, if you're on bass, you get to hear the drums in the background as you play, and then the guitarist hears the drums and bass (and cowbell) and so on. On each loop, you play over the part, and then on the following loop, the engineer hits the record button and lays the performance down on tape. - -You can also copy and swap out a reel of tape entirely, should you decide to do a re-mix of something you're working on. - -Now that I've hopefully painted a vivid Roger Dean-quality image of studio life in the 70s, let's translate that into Git. - -### Create a Git repository - -The first step is to go out and buy some tape for our virtual tape deck. In Git terms, that's the repository ; it's the medium or domain where all the work is going to live. - -Any directory can become a Git repository, but to begin with let's start a fresh one. It takes three commands: - -- Create the directory (you can do that in your GUI file manager, if you prefer). -- Visit that directory in a terminal. -- Initialise it as a directory managed by Git. - -Specifically, run these commands: - -``` -$ mkdir ~/jupiter # make directory -$ cd ~/jupiter # change into the new directory -$ git init . # initialise your new Git repo -``` - -Is this example, the folder jupiter is now an empty but valid Git repository. - -That's all it takes. You can clone the repository, you can go backward and forward in history (once it has a history), create alternate timelines, and everything else Git can normally do. - -Working inside the Git repository is the same as working in any directory; create files, copy files into the directory, save files into it. You can do everything as normal; Git doesn't get involved until you involve it. - -In a local Git repository, a file can have one of three states: - -- Untracked: a file you create in a repository, but not yet added to Git. -- Tracked: a file that has been added to Git. -- Staged: a tracked file that has been changed and added to Git's commit queue. - -Any file that you add to a Git repository starts life out as an untracked file. The file exists on your computer, but you have not told Git about it yet. In our tape deck analogy, the tape deck isn't even turned on yet; the band is just noodling around in the studio, nowhere near ready to record yet. - -That is perfectly acceptable, and Git will let you know when it happens: - -``` -$ echo "hello world" > foo -$ git status -On branch master -Untracked files: -(use "git add ..." to include in what will be committed) - foo -nothing added but untracked files present (use "git add" to track) -``` - -As you can see, Git also tells you how to start tracking files. - -### Git without Git - -Creating a repository in GitHub or GitLab is a lot more clicky and pointy. It isn't difficult; you click the New Repository button and follow the prompts. - -It is a good practice to include a README file so that people wandering by have some notion of what your repository is for, and it is a little more satisfying to clone a non-empty repository. - -Cloning the repository is no different than usual, but obtaining permission to write back into that repository on GitHub is slightly more complex, because in order to authenticate to GitHub you must have an SSH key. If you're on Linux, create one with this command: - -``` -$ ssh-keygen -``` - -Then copy your new key, which is plain text. You can open it in a plain text editor, or use the cat command: - -``` -$ cat ~/.ssh/id_rsa.pub -``` - -Now paste your key into [GitHub's SSH configuration][1], or your [GitLab configuration][2]. - -As long as you clone your GitHub project via SSH, you'll be able to write back to your repository. - -Alternately, you can use GitHub's file uploader interface to add files without even having Git on your system. - -![](https://opensource.com/sites/default/files/2_githubupload.jpg) - -### Tracking files - -As the output of git status tells you, if you want Git to start tracking a file, you must git add it. The git add action places a file in a special staging area, where files wait to be committed, or preserved for posterity in a snapshot. The point of a git add is to differentiate between files that you want to have included in a snapshot, and the new or temporary files you want Git to, at least for now, ignore. - -In our tape deck analogy, this action turns the tape deck on and arms it for recording. You can picture the tape deck with the record and pause button pushed, or in a playback loop awaiting the next track to be laid down. - -Once you add a file, Git will identify it as a tracked file: - -``` -$ git add foo -$ git status -On branch master -Changes to be committed: -(use "git reset HEAD ..." to unstage) -new file: foo -``` - -Adding a file to Git's tracking system is not making a recording. It just puts a file on the stage in preparation for recording. You can still change a file after you've added it; it's being tracked and remains staged, so you can continue to refine it or change it before committing it to tape (but be warned; you're NOT recording yet, so if you break something in a file that was perfect, there's no going back in time yet, because you never got that perfect moment on tape). - -If you decide that the file isn't really ready to be recorded in the annals of Git history, then you can unstage something, just as the Git message described: - -``` -$ git reset HEAD foo -``` - -This, in effect, disarms the tape deck from being ready to record, and you're back to just noodling around in the studio. - -### The big commit - -At some point, you're going to want to commit something; in our tape deck analogy, that means finally pressing record and laying a track down on tape. - -At different stages of a project's life, how often you press that record button varies. For example, if you're hacking your way through a new Python toolkit and finally manage to get a window to appear, then you'll certainly want to commit so you have something to fall back on when you inevitably break it later as you try out new display options. But if you're working on a rough draft of some new graphics in Inkscape, you might wait until you have something you want to develop from before committing. Ultimately, though, it's up to you how often you commit; Git doesn't "cost" that much and hard drives these days are big, so in my view, the more the better. - -A commit records all staged files in a repository. Git only records files that are tracked, that is, any file that you did a git add on at some point in the past. and that have been modified since the previous commit. If no previous commit exists, then all tracked files are included in the commit because they went from not existing to existing, which is a pretty major modification from Git's point-of-view. - -To make a commit, run this command: - -``` -$ git commit -m 'My great project, first commit.' -``` - -This preserves all files committed for posterity (or, if you speak Gallifreyan, they become "fixed points in time"). You can see not only the commit event, but also the reference pointer back to that commit in your Git log: - -``` -$ git log --oneline -55df4c2 My great project, first commit. -``` - -For a more detailed report, just use git log without the --oneline option. - -The reference number for the commit in this example is 55df4c2. It's called a commit hash and it represents all of the new material you just recorded, overlaid onto previous recordings. If you need to "rewind" back to that point in history, you can use that hash as a reference. - -You can think of a commit hash as [SMPTE timecode][3] on an audio tape, or if we bend the analogy a little, one of those big gaps between songs on a vinyl record, or track numbers on a CD. - -As you change files further and add them to the stage, and ultimately commit them, you accrue new commit hashes, each of which serve as pointers to different versions of your production. - -And that's why they call Git a version control system, Charlie Brown. - -In the next article, we'll explore everything you need to know about the Git HEAD, and we'll nonchalantly reveal the secret of time travel. No big deal, but you'll want to read it (or maybe you already have?). - - - --------------------------------------------------------------------------------- - -via: https://opensource.com/life/16/7/creating-your-first-git-repository - -作者:[Seth Kenlon][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/seth -[1]: https://github.com/settings/keys -[2]: https://gitlab.com/profile/keys -[3]: http://slackermedia.ml/handbook/doku.php?id=timecode diff --git a/translated/tech/20160718 Creating your first Git repository.md b/translated/tech/20160718 Creating your first Git repository.md new file mode 100644 index 0000000000..35382aba55 --- /dev/null +++ b/translated/tech/20160718 Creating your first Git repository.md @@ -0,0 +1,199 @@ + + +建立你的第一个仓库 +====================================== + +![](https://opensource.com/sites/default/files/styles/image-full-size/public/images/life/open_abstract_pieces.jpg?itok=ZRt0Db00) + + +现在是时候学习怎样创建你自己的仓库了,还有怎样增加文件和完成提交。 + +在本系列前面文章的安装过程中,你已经学习了作为一个目标用户怎样与 Git 进行交互;你就像一个漫无目的的流浪者一样偶然发现了一个开源项目网站,然后克隆了仓库,Git 走进了你的生活。学习怎样和 Git 进行交互并不像你想的那样困难,或许你并不确信现在是否应该使用 Git 完成你的工作。 + + +Git 被认为是选择大多软件项目的工具,它不仅能够完成大多软件项目的工作;它也能管理你杂乱项目的列表(如果他们不重要,也可以这样说!),你的配置文件,一个日记,项目进展日志,甚至源代码! + +使用 Git 是很有必要的,毕竟,你肯定有因为一个备份文件不能够辨认出版本信息而烦恼的时候。 + +你不使用 Git,它也就不会为你工作,或者也可以把 Git 理解为“没有任何推送就像源头指针一样”【译注: HEAD 可以理解为“头指针”,是当前工作区的“基础版本”,当执行提交时, HEAD 指向的提交将作为新提交的父提交。】。我保证,你很快就会对 Git 有所了解 。 + + +### 类比于录音 + + +我们更喜欢谈论快照上的图像,因为很多人都可以通过一个相册很快辨认出每个照片上特有的信息。这可能很有用,然而,我认为 Git 更像是在进行声音的记录。 + +传统的录音机,可能你对于它的部件不是很清楚:它包含转轴并且正转或反转,使用磁带保存声音波形,通过放音头记录声音并保存到磁带上然后播放给收听者。 + + +除了往前退磁带,你也可以把磁带多绕几圈到磁带前面的部分,或快进跳过前面的部分到最后。 + +想象一下 70 年代的磁带录制的声音。你可能想到那会正在反复练习一首歌直到非常完美,它们最终被记录下来了。起初,你记录了鼓声,低音,然后是吉他声,还有其他的声音。每次你录音,工作人员都会把磁带重绕并设置为环绕模式,这样在你演唱的时候录音磁带就会播放之前录制的声音。如果你是低音歌唱,你唱歌的时候就需要把有鼓声的部分作为背景音乐,然后就是吉他声、鼓声、低音(和牛铃声【译注:一种打击乐器,状如四棱锥。】)等等。在每一环,你完成了整个部分,到了下一环,工作人员就开始在磁带上制作你的演唱作品。 + + +你也可以拷贝或换出整个磁带,这是你需要继续录音并且进行多次混合的时候需要做的。 + + +现在我希望对于上述 70 年代的录音工作的描述足够生动,我们就可以把 Git 的工作想象成一个录音磁带了。 + + +### 新建一个 Git 仓库 + + +首先得为我们的虚拟的录音机买一些磁带。在 Git 术语中,这就是仓库;它是完成所有工作的基础,也就是说这里是存放 Git 文件的地方(即 Git 工作区)。 + +任何目录都可以是一个 Git 仓库,但是在开始的时候需要进行一次更新。需要下面三个命令: + + +- 创建目录(如果你喜欢的话,你可以在你的 GUI 文件管理器里面完成。) +- 在终端里查看目录。 +- 初始化这个目录使它可以被 Git管理。 + + +特别是运行如下代码: + +``` +$ mkdir ~/jupiter # 创建目录 +$ cd ~/jupiter # 进入目录 +$ git init . # 初始化你的新 Git 工作区 +``` + + +在这个例子中,文件夹 jupiter 是空的但却成为了你的 Git 仓库。 + +有了仓库接下来的事件就按部就班了。你可以克隆项目仓库,你可以在一个历史点前后来回穿梭(前提是你有一个历史点),创建可交替时间线,然后剩下的工作 Git 就都能正常完成了。 + + +在 Git 仓库里面工作和在任何目录里面工作都是一样的;在仓库中新建文件,复制文件,保存文件。你可以像平常一样完成工作;Git 并不复杂,除非你把它想复杂了。 + +在本地的 Git 仓库中,一个文件可以有下面这三种状态: +- 未跟踪文件:你在仓库里新建了一个文件,但是你没有把文件加入到 Git 的提交任务(提交暂存区,stage)中。 +- 已跟踪文件:已经加入到 Git 暂存区的文件。 +- 暂存区文件:存在于暂存区的文件已经加入到 Git 的提交队列中。 + + +任何你新加入到 Git 仓库中的文件都是未跟踪文件。文件还保存在你的电脑硬盘上,但是你没有告诉 Git 这是需要提交的文件,就像我们的录音机,如果你没有打开录音机;乐队开始演唱了,但是录音机并没有准备录音。 + +不用担心,Git 会告诉你存在的问题并提示你怎么解决: +``` +$ echo "hello world" > foo +$ git status +位于您当前工作的分支 master 上 +未跟踪文件: +(使用 "git add " 更新要提交的内容) + foo +没有任何提交任务,但是存在未跟踪文件(用 "git add" 命令加入到提交任务) +``` + + +你看到了,Git 会提醒你怎样把文件加入到提交任务中。 + +### 不使用 Git 命令进行 Git 操作 + + +在 GitHub 或 GitLab(译注:GitLab 是一个用于仓库管理系统的开源项目。使用Git作为代码管理工具,并在此基础上搭建起来的web服务。)上创建一个仓库大多是使用鼠标点击完成的。这不会很难,你单击 New Repository 这个按钮就会很快创建一个仓库。 + +在仓库中新建一个 README 文件是一个好习惯,这样人们在浏览你的仓库的时候就可以知道你的仓库基于什么项目,更有用的是通过 README 文件可以确定克隆的是否为一个非空仓库。 + + +克隆仓库通常很简单,但是在 GitHub 上获取仓库改动权限就不简单了,为了进行用户验证你必须有一个 SSH 秘钥。如果你使用 Linux 系统,通过下面的命令可以生成一个秘钥: +``` +$ ssh-keygen +``` + + +复制纯文本文件里的秘钥。你可以使用一个文本编辑器打开它,也可以使用 cat 命令: + +``` +$ cat ~/.ssh/id_rsa.pub +``` + + +现在把你的秘钥拷贝到 [GitHub SSH 配置文件][1] 中,或者 [GitLab 配置文件[2]。 + +如果你通过使用 SSH 模式克隆了你的项目,就可以在你的仓库开始工作了。 + +另外,如果你的系统上没有安装 Git 的话也可以使用 GitHub 的文件上传接口来克隆仓库。 + +![](https://opensource.com/sites/default/files/2_githubupload.jpg) + + +### 跟踪文件 + +命令 git status 的输出会告诉你如果你想让 git 跟踪一个文件,你必须使用命令 git add 把它加入到提交任务中。这个命令把文件存在了暂存区,暂存区存放的都是等待提交的文件,或者把仓库保存为一个快照。git add 命令的最主要目的是为了区分你已经保存在仓库快照里的文件,还有新建的或你想提交的临时文件,至少现在,你都不用为它们之间的不同之处而费神了。 + +类比大型录音机,这个动作就像打开录音机开始准备录音一样。你可以按已经录音的录音机上的 pause 按钮来完成推送,或者拉下重置环等待开始跟踪下一个文件。 + +如果你把文件加入到提交任务中,Git 会自动标识为跟踪文件: + +``` +$ git add foo +$ git status +位于您当前工作的分支 master 上 +下列修改将被提交: +(使用 "git reset HEAD ..." 将下列改动撤出提交任务) +新增文件:foo +``` + + +加入文件到提交任务中并不会生成一个记录。这仅仅是为了之后方便记录而把文件存放到暂存区。在你把文件加入到提交任务后仍然可以修改文件;文件会被标记为跟踪文件并且存放到暂存区,所以你在最终提交之前都可以改动文件或撤出提交任务(但是请注意:你并没有记录文件,所以如果你完全改变了文件就没有办法撤销了,因为你没有记住最终修改的准确时间。)。 + +如果你决定不把文件记录到 Git 历史列表中,那么你可以撤出提交任务,在 Git 中是这样做的: +``` +$ git reset HEAD foo +``` + + +这实际上就是删除了录音机里面的录音,你只是在工作区转了一圈而已而已。 + +### 大型提交 + +有时候,你会需要完成很多提交;我们以录音机类比,这就好比按下录音键并最终按下保存键一样。 + +在一个项目从建立到完成,你会按记录键无数次。比如,如果你通过你的方式使用一个新的 Python 工具包并且最终实现了窗口展示,然后你就很肯定的提交了文件,但是不可避免的你最后会发生一些错误,现在你却不能撤销你的提交操作了。 + +一次提交会记录仓库中所有的暂存区文件。Git 只记录加入到提交任务中的文件,也就是说在过去某个时刻你使用 git add 命令加入到暂存区的所有文件。还有从先前的提交开始被改动的文件。如果没有其他的提交,所有的跟踪文件都包含在这次提交中,因为在浏览 Git 历史点的时候,它们没有存在于仓库中。 + +完成一次提交需要运行下面的命令: +``` +$ git commit -m 'My great project, first commit.' +``` + +这就保存了所有需要在仓库中提交的文件(或者,如果你说到 Gallifreyan【译注:英国电视剧《神秘博士》里的时间领主使用的一种优雅的语言,】,它们可能就是“固定的时间点” )。你不仅能看到整个提交记录,还能通过 git log 命令查看修改日志找到提交时的版本号: +``` +$ git log --oneline +55df4c2 My great project, first commit. +``` + + +如果想浏览更多信息,只需要使用不带 --oneline 选项的 git log 命令。 + + +在这个例子中提交时的版本号是 55df4c2。它被叫做 commit hash(译注:一个SHA-1生成的哈希码,用于表示一个git commit对象。),它表示着刚才你的提交包含的所有改动,覆盖了先前的记录。如果你想要“倒回”到你的提交历史点上就可以用这个 commit hash 作为依据。 + +你可以把 commit hash 想象成一个声音磁带上的 [SMPTE timecode][3],或者再夸张一点,这就是好比一个黑胶唱片两首不同的歌之间的不同点,或是一个 CD 上的轨段编号。 + + +你在很久前改动了文件并且把它们加入到提交任务中,最终完成提交,这就会生成新的 commit hashes,每个 commit hashes 标示的历史点都代表着你的产品不同的版本。 + + +这就是 Charlie Brown 把 Git 称为版本控制系统的原因。 + +在接下来的文章中,我们将会讨论你需要知道的关于 Git HEAD 的一切,我们不准备讨论关于 Git 的提交历史问题。基本不会提及,但是你可能会需要了解它(或许你已经有所了解?)。 + + + +-------------------------------------------------------------------------------- + +via: https://opensource.com/life/16/7/creating-your-first-git-repository + +作者:[Seth Kenlon][a] +译者:[vim-kakali](https://github.com/vim-kakali) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]: https://opensource.com/users/seth +[1]: https://github.com/settings/keys +[2]: https://gitlab.com/profile/keys +[3]: http://slackermedia.ml/handbook/doku.php?id=timecode From e05b6e265869065180e827fe2b02da50377036ed Mon Sep 17 00:00:00 2001 From: ChrisLeeGit Date: Thu, 28 Jul 2016 15:55:58 +0800 Subject: [PATCH 052/122] =?UTF-8?q?=E5=AE=8C=E6=88=90=E7=BF=BB=E8=AF=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...0160630 What makes up the Fedora kernel.md | 35 ------------------- ...0160630 What makes up the Fedora kernel.md | 31 ++++++++++++++++ 2 files changed, 31 insertions(+), 35 deletions(-) delete mode 100644 sources/tech/20160630 What makes up the Fedora kernel.md create mode 100644 translated/tech/20160630 What makes up the Fedora kernel.md diff --git a/sources/tech/20160630 What makes up the Fedora kernel.md b/sources/tech/20160630 What makes up the Fedora kernel.md deleted file mode 100644 index 603aefa575..0000000000 --- a/sources/tech/20160630 What makes up the Fedora kernel.md +++ /dev/null @@ -1,35 +0,0 @@ -Being translated by ChrisLeeGit - -What makes up the Fedora kernel? -==================================== - -![](https://cdn.fedoramagazine.org/wp-content/uploads/2016/06/kernel-945x400.png) - -Every Fedora system runs a kernel. Many pieces of code come together to make this a reality. - -Each release of the Fedora kernel starts with a baseline release from the [upstream community][1]. This is often called a ‘vanilla’ kernel. The upstream kernel is the standard. The goal is to have as much code upstream as possible. This makes it easier for bug fixes and API updates to happen as well as having more people review the code. In an ideal world, Fedora would be able to to take the kernel straight from kernel.org and send that out to all users. - -Realistically, using the vanilla kernel isn’t complete enough for Fedora. Some features Fedora users want may not be available. The [Fedora kernel][2] that users actually receive contains a number of patches on top of the vanilla kernel. These patches are considered ‘out of tree’. Many of these patches will not exist out of tree patches very long. If patches are available to fix an issue, the patches may be pulled in to the Fedora tree so the fix can go out to users faster. When the kernel is rebased to a new version, the patches will be removed if they are in the new version. - -Some patches remain in the Fedora kernel tree for an extended period of time. A good example of patches that fall into this category are the secure boot patches. These patches provide a feature Fedora wants to support even though the upstream community has not yet accepted them. It takes effort to keep these patches up to date so Fedora tries to minimize the number of patches that are carried without being accepted by an upstream kernel maintainer. - -Generally, the best way to get a patch included in the Fedora kernel is to send it to the ]Linux Kernel Mailing List (LKML)][3] first and then ask for it to be included in Fedora. If a patch has been accepted by a maintainer it stands a very high chance of being included in the Fedora kernel tree. Patches that come from places like github which have not been submitted to LKML are unlikely to be taken into the tree. It’s important to send the patches to LKML first to ensure Fedora is carrying the correct patches in its tree. Without the community review, Fedora could end up carrying patches which are buggy and cause problems. - -The Fedora kernel contains code from many places. All of it is necessary to give the best experience possible. - - - --------------------------------------------------------------------------------- - -via: https://fedoramagazine.org/makes-fedora-kernel/ - -作者:[Laura Abbott][a] -译者:[ChrisLeeGit](https://github.com/chrisleegit) -校对:[校对者ID](https://github.com/校对者ID) - -本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 - -[a]: https://fedoramagazine.org/makes-fedora-kernel/ -[1]: http://www.kernel.org/ -[2]: http://pkgs.fedoraproject.org/cgit/rpms/kernel.git/ -[3]: http://www.labbott.name/blog/2015/10/02/the-art-of-communicating-with-lkml/ diff --git a/translated/tech/20160630 What makes up the Fedora kernel.md b/translated/tech/20160630 What makes up the Fedora kernel.md new file mode 100644 index 0000000000..954c4cb440 --- /dev/null +++ b/translated/tech/20160630 What makes up the Fedora kernel.md @@ -0,0 +1,31 @@ +Fedora 内核是由什么构成的? +==================================== + +![](https://cdn.fedoramagazine.org/wp-content/uploads/2016/06/kernel-945x400.png) + +每个 Fedora 系统都运行着一个内核。许多代码段组合在一起使之成为现实。 + +每个 Fedora 内核都起始于一个来自于 [上游社区][1] 的基线版本,通常称之为 vanilla 内核。上游内核就是标准。(Fedora 的)目标是包含尽可能多的上游代码,这样使得 bug 修复和 API 更新更加容易,同时也会有更多的人审查代码。理想情况下,Fedora 能够直接从 kernel.org 获得内核,然后发送给所有用户。 + +现实情况是,使用 vanilla 内核并不能完全满足 Fedora。Vanilla 内核可能并不支持一些 Fedora 用户希望拥有的功能。用户接收的 [Fedora 内核] 是在 vanilla 内核之上打了很多补丁的内核。这些补丁被认为“不在树上”。许多这些位于补丁树之外的补丁都不会存在太久。如果某补丁能够修复一个问题,那么该补丁可能会被合并到 Fedora 树,以便用户能够更快地收到修复。当内核变基到一个新版本时,在新版本中的补丁都将被清除。 + +一些补丁会在 Fedora 内核树上存在很长时间。一个很好的例子是,安全启动补丁就是这类补丁。这些补丁提供了 Fedora 希望支持的功能,即使上游社区还没有接受它们。保持这些补丁更新是需要付出很多努力的,所以 Fedora 尝试减少不被上游内核维护者接受的补丁数量。 + +通常来说,想要在 Fedora 内核中获得一个补丁的最佳方法是先给 [Linux 内核邮件列表(LKML)][3] 发送补丁,然后请求将该补丁包含到 Fedora 中。如果某个维护者接受了补丁,就意味着 Fedora 内核树中将来很有可能会包含该补丁。一些来自于 GitHub 等地方的还没有提交给 LKML 的补丁是不可能进入内核树的。首先向 LKML 发送补丁是非常重要的,它能确保 Fedora 内核树中携带的补丁是功能正常的。如果没有社区审查,Fedora 最终携带的补丁将会充满 bug 并会导致问题。 + +Fedora 内核中包含的代码来自许多地方。一切都需要提供最佳的体验。 + +-------------------------------------------------------------------------------- + +via: https://fedoramagazine.org/makes-fedora-kernel/ + +作者:[Laura Abbott][a] +译者:[ChrisLeeGit](https://github.com/chrisleegit) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]: https://fedoramagazine.org/makes-fedora-kernel/ +[1]: http://www.kernel.org/ +[2]: http://pkgs.fedoraproject.org/cgit/rpms/kernel.git/ +[3]: http://www.labbott.name/blog/2015/10/02/the-art-of-communicating-with-lkml/ From 018abadd1c026f23d7607880765102b4546b840f Mon Sep 17 00:00:00 2001 From: wxy Date: Thu, 28 Jul 2016 16:55:15 +0800 Subject: [PATCH 053/122] PUB:20160621 Container technologies in Fedora - systemd-nspawn MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @ChrisLeeGit 翻译的很好! --- ...technologies in Fedora - systemd-nspawn.md | 38 +++++++++++-------- 1 file changed, 22 insertions(+), 16 deletions(-) rename {translated/tech => published}/20160621 Container technologies in Fedora - systemd-nspawn.md (61%) diff --git a/translated/tech/20160621 Container technologies in Fedora - systemd-nspawn.md b/published/20160621 Container technologies in Fedora - systemd-nspawn.md similarity index 61% rename from translated/tech/20160621 Container technologies in Fedora - systemd-nspawn.md rename to published/20160621 Container technologies in Fedora - systemd-nspawn.md index f47d17556a..69cbf688d8 100644 --- a/translated/tech/20160621 Container technologies in Fedora - systemd-nspawn.md +++ b/published/20160621 Container technologies in Fedora - systemd-nspawn.md @@ -4,19 +4,20 @@ Fedora 中的容器技术:systemd-nspawn 欢迎来到“Fedora 中的容器技术”系列!本文是该系列文章中的第一篇,它将说明你可以怎样使用 Fedora 中各种可用的容器技术。本文将学习 `systemd-nspawn` 的相关知识。 ### 容器是什么? -一个容器就是一个用户空间实例,它能够在与托管容器的系统(叫做宿主系统)隔离的环境中运行一个程序或者一个操作系统。这和 `chroot` 或 [虚拟机][1] 的思想非常类似。 -运行在容器中的进程是由与宿主操作系统相同的内核来管理的,但它们是与宿主文件系统以及其它进程隔离开的。 +一个容器就是一个用户空间实例,它能够在与托管容器的系统(叫做宿主系统)相隔离的环境中运行一个程序或者一个操作系统。这和 `chroot` 或 [虚拟机][1] 的思想非常类似。运行在容器中的进程是由与宿主操作系统相同的内核来管理的,但它们是与宿主文件系统以及其它进程隔离开的。 ### 什么是 systemd-nspawn? -systemd 项目认为应当将容器技术变成桌面的基础部分,并且应当和剩余的用户系统集成在一起。为此,systemd 提供了 `systemd-nspawn`,这款工具能够使用多种 Linux 技术创建容器。它也提供了一些容器管理工具。 -`systemd-nspawn` 和 `chroot` 在许多方面都是类似的,但是前者更加强大。它虚拟化了文件系统、进程树以及客户系统中的进程间通信。它的引力在于它提供了很多用于管理容器的工具,例如 `machinectl`。由 `systemd-nspawn` 运行的容器将会与 systemd 组件一同运行在宿主系统上。举例来说,一个容器的日志可以输出到宿主系统的日志中。 +systemd 项目认为应当将容器技术变成桌面的基础部分,并且应当和用户的其余系统集成在一起。为此,systemd 提供了 `systemd-nspawn`,这款工具能够使用多种 Linux 技术创建容器。它也提供了一些容器管理工具。 -在 Fedora 24 上,`systemd-nspawn` 已经和 systemd 软件包分开了,所以你需要安装 `systemd-container` 软件包。一如往常,你可以使用 `dnf install systemd-container` 进行安装。 +`systemd-nspawn` 和 `chroot` 在许多方面都是类似的,但是前者更加强大。它虚拟化了文件系统、进程树以及客户系统中的进程间通信。它的吸引力在于它提供了很多用于管理容器的工具,例如用来管理容器的 `machinectl`。由 `systemd-nspawn` 运行的容器将会与 systemd 组件一同运行在宿主系统上。举例来说,一个容器的日志可以输出到宿主系统的日志中。 + +在 Fedora 24 上,`systemd-nspawn` 已经从 systemd 软件包分离出来了,所以你需要安装 `systemd-container` 软件包。一如往常,你可以使用 `dnf install systemd-container` 进行安装。 ### 创建容器 -使用 `systemd-nspawn` 创建一个容器是很容易的。假设你有一个专门为 Debian 创造的应用,并且无法在其它地方正常运行。那并不是一个问题,我们可以创造一个容器!为了设置容器使用最新版本的 Debian(此时是 Jessie),你需要挑选一个目录来放置你的系统。我暂时将使用目录 `~/DebianJessie`。 + +使用 `systemd-nspawn` 创建一个容器是很容易的。假设你有一个专门为 Debian 创造的应用,并且无法在其它发行版中正常运行。那并不是一个问题,我们可以创造一个容器!为了设置容器使用最新版本的 Debian(现在是 Jessie),你需要挑选一个目录来放置你的系统。我暂时将使用目录 `~/DebianJessie`。 一旦你创建完目录,你需要运行 `debootstrap`,你可以从 Fedora 仓库中安装它。对于 Debian Jessie,你运行下面的命令来初始化一个 Debian 文件系统。 @@ -32,9 +33,9 @@ $ debootstrap --arch=amd64 stable ~/DebianJessie $ systemd-nspawn -bD ~/DebianJessie ``` -容器将会在数秒后准备好并运行,当你一尝试登录就会注意到:你无法在你的系统上使用任何账户。这是因为 `systemd-nspawn` 虚拟化了用户。修复的方法很简单:将之前的命令中的 `-b` 移除即可。你将直接进入容器的 root shell。此时,你只能使用 `passwd` 命令为 root 设置密码,或者使用 `adduser` 命令添加一个新用户。一旦设置好密码或添加好用户,你就可以把 `-b` 标志添加回去然后继续了。你会进入到熟悉的登录控制台,然后你使用设置好的认证信息登录进去。 +容器将会在数秒后准备好并运行,当你试图登录时就会注意到:你无法使用你的系统上任何账户。这是因为 `systemd-nspawn` 虚拟化了用户。修复的方法很简单:将之前的命令中的 `-b` 移除即可。你将直接进入容器的 root 用户的 shell。此时,你只能使用 `passwd` 命令为 root 设置密码,或者使用 `adduser` 命令添加一个新用户。一旦设置好密码或添加好用户,你就可以把 `-b` 标志添加回去然后继续了。你会进入到熟悉的登录控制台,然后你使用设置好的认证信息登录进去。 -以上对于任意你想在容器中运行的发行版都适用,但前提是你需要使用正确的包管理器创建系统。对于 Fedora,你应使用 DNF 而非 `debootstrap`。想要设置一个最小化的 Fedora 系统,你可以运行下面的命令,要将绝对路径替换成任何你希望容器存放的位置。 +以上对于任意你想在容器中运行的发行版都适用,但前提是你需要使用正确的包管理器创建系统。对于 Fedora,你应使用 DNF 而非 `debootstrap`。想要设置一个最小化的 Fedora 系统,你可以运行下面的命令,要将“/absolute/path/”替换成任何你希望容器存放的位置。 ``` $ sudo dnf --releasever=24 --installroot=/absolute/path/ install systemd passwd dnf fedora-release @@ -43,8 +44,8 @@ $ sudo dnf --releasever=24 --installroot=/absolute/path/ install systemd passwd ![](https://cdn.fedoramagazine.org/wp-content/uploads/2016/06/Screenshot-from-2016-06-17-15-04-14.png) ### 设置网络 -如果你尝试启动一个服务,但它绑定了你宿主机正在使用的端口,你将会注意到这个问题:你的容器正在使用和宿主机相同的网络接口。 -幸运的是,`systemd-nspawn` 提供了几种方法可以将网络从宿主机分开。 + +如果你尝试启动一个服务,但它绑定了你宿主机正在使用的端口,你将会注意到这个问题:你的容器正在使用和宿主机相同的网络接口。幸运的是,`systemd-nspawn` 提供了几种可以将网络从宿主机分开的方法。 #### 本地网络 @@ -52,33 +53,38 @@ $ sudo dnf --releasever=24 --installroot=/absolute/path/ install systemd passwd #### 多个网络接口 -如果你有多个网络接口设备,你可以使用 `--network-interface` 标志给容器分配一个接口。想要给我的容器分配 `eno1`,我会添加标志 `--network-interface=eno1`。当某个接口分配给一个容器后,宿主机就不能同时使用那个接口了。只有当容器彻底关闭后,宿主机才可以使用那个接口。 - +如果你有多个网络接口设备,你可以使用 `--network-interface` 标志给容器分配一个接口。想要给我的容器分配 `eno1`,我会添加选项 `--network-interface=eno1`。当某个接口分配给一个容器后,宿主机就不能同时使用那个接口了。只有当容器彻底关闭后,宿主机才可以使用那个接口。 #### 共享网络接口 -对于我们中那些并没有额外的网络设备的人来说,还有其它方法可以访问容器。一种就是使用 `--port` 标志。这会将容器中的一个端口定向到宿主机。使用格式是 `协议:宿主机:容器`,这里的协议可以是 `tcp` 或者 `udp`,`宿主机` 是宿主机的一个合法端口,`容器` 则是容器中的一个合法端口。你可以省略协议,只指定 `宿主机:容器`。我通常的用法类似 `--port=2222:22`。 + +对于我们中那些并没有额外的网络设备的人来说,还有其它方法可以访问容器。一种就是使用 `--port` 选项。这会将容器中的一个端口定向到宿主机。使用格式是 `协议:宿主机端口:容器端口`,这里的协议可以是 `tcp` 或者 `udp`,`宿主机端口` 是宿主机的一个合法端口,`容器端口` 则是容器中的一个合法端口。你可以省略协议,只指定 `宿主机端口:容器端口`。我通常的用法类似 `--port=2222:22`。 你可以使用 `--network-veth` 启用完全的、仅宿主机模式的网络,这会在宿主机和容器之间创建一个虚拟的网络接口。你也可以使用 `--network-bridge` 桥接二者的连接。 ### 使用 systemd 组件 + 如果你容器中的系统含有 D-Bus,你可以使用 systemd 提供的实用工具来控制并监视你的容器。基础安装的 Debian 并不包含 `dbus`。如果你想在 Debian Jessie 中使用 `dbus`,你需要运行命令 `apt install dbus`。 #### machinectl + 为了能够轻松地管理容器,systemd 提供了 `machinectl` 实用工具。使用 `machinectl`,你可以使用 `machinectl login name` 登录到一个容器中、使用 `machinectl status name`检查状态、使用 `machinectl reboot name` 启动容器或者使用 `machinectl poweroff name` 关闭容器。 ### 其它 systemd 命令 -多数 systemd 命令,例如 `journalctl`, `systemd-analyze` 和 `systemctl`,都支持使用了 `--machine` 选项的容器。例如,如果你想查看一个名为 "foobar" 的容器日志,你可以使用 `journalctl --machine=foobar`。你也可以使用 `systemctl --machine=foobar status service` 来查看运行在这个容器中的服务状态。 + +多数 systemd 命令,例如 `journalctl`, `systemd-analyze` 和 `systemctl`,都支持使用 `--machine` 选项来指定容器。例如,如果你想查看一个名为 “foobar” 的容器的日志,你可以使用 `journalctl --machine=foobar`。你也可以使用 `systemctl --machine=foobar status service` 来查看运行在这个容器中的服务状态。 ![](https://cdn.fedoramagazine.org/wp-content/uploads/2016/06/Screenshot-from-2016-06-17-15-09-25.png) ### 和 SELinux 一起工作 + 如果你要使用 SELinux 强制模式(Fedora 默认模式),你需要为你的容器设置 SELinux 环境。想要那样的话,你需要在宿主系统上运行下面两行命令。 ``` $ semanage fcontext -a -t svirt_sandbox_file_t "/path/to/container(/.*)?" $ restorecon -R /path/to/container/ ``` -确保使用你的容器路径替换 "/path/to/container"。对于我的容器 "DebianJessie",我会运行下面的命令: + +确保使用你的容器路径替换 “/path/to/container”。对于我的容器 "DebianJessie",我会运行下面的命令: ``` $ semanage fcontext -a -t svirt_sandbox_file_t "/home/johnmh/DebianJessie(/.*)?" @@ -91,7 +97,7 @@ via: https://fedoramagazine.org/container-technologies-fedora-systemd-nspawn/ 作者:[John M. Harris, Jr.][a] 译者:[ChrisLeeGit](https://github.com/chrisleegit) -校对:[校对者ID](https://github.com/校对者ID) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 From 6bd966ef31cf12b07239b3dcc946d3a671c2e350 Mon Sep 17 00:00:00 2001 From: kakali <1799225723@qq.com> Date: Thu, 28 Jul 2016 17:49:55 +0800 Subject: [PATCH 054/122] vim-kakali translated (#4236) * vim-kakali translated * vim-kakali translating --- ...riables, Numeric Expressions and Assignment Operators.md | 2 +- .../tech/20160718 Creating your first Git repository.md | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/sources/tech/awk/20160714 Part 8 - Learn How to Use Awk Variables, Numeric Expressions and Assignment Operators.md b/sources/tech/awk/20160714 Part 8 - Learn How to Use Awk Variables, Numeric Expressions and Assignment Operators.md index d7cfd4c064..dd2494529d 100644 --- a/sources/tech/awk/20160714 Part 8 - Learn How to Use Awk Variables, Numeric Expressions and Assignment Operators.md +++ b/sources/tech/awk/20160714 Part 8 - Learn How to Use Awk Variables, Numeric Expressions and Assignment Operators.md @@ -1,4 +1,4 @@ -vim-kakali translating +translating by vim-kakali Learn How to Use Awk Variables, Numeric Expressions and Assignment Operators – part8 diff --git a/translated/tech/20160718 Creating your first Git repository.md b/translated/tech/20160718 Creating your first Git repository.md index 35382aba55..722fe2ea56 100644 --- a/translated/tech/20160718 Creating your first Git repository.md +++ b/translated/tech/20160718 Creating your first Git repository.md @@ -122,7 +122,7 @@ $ cat ~/.ssh/id_rsa.pub 命令 git status 的输出会告诉你如果你想让 git 跟踪一个文件,你必须使用命令 git add 把它加入到提交任务中。这个命令把文件存在了暂存区,暂存区存放的都是等待提交的文件,或者把仓库保存为一个快照。git add 命令的最主要目的是为了区分你已经保存在仓库快照里的文件,还有新建的或你想提交的临时文件,至少现在,你都不用为它们之间的不同之处而费神了。 -类比大型录音机,这个动作就像打开录音机开始准备录音一样。你可以按已经录音的录音机上的 pause 按钮来完成推送,或者拉下重置环等待开始跟踪下一个文件。 +类比大型录音机,这个动作就像打开录音机开始准备录音一样。你可以按已经录音的录音机上的 pause 按钮来完成推送,或者按下重置按钮等待开始跟踪下一个文件。 如果你把文件加入到提交任务中,Git 会自动标识为跟踪文件: @@ -150,7 +150,7 @@ $ git reset HEAD foo 有时候,你会需要完成很多提交;我们以录音机类比,这就好比按下录音键并最终按下保存键一样。 -在一个项目从建立到完成,你会按记录键无数次。比如,如果你通过你的方式使用一个新的 Python 工具包并且最终实现了窗口展示,然后你就很肯定的提交了文件,但是不可避免的你最后会发生一些错误,现在你却不能撤销你的提交操作了。 +在一个项目从建立到完成,你会按记录键无数次。比如,如果你通过你的方式使用一个新的 Python 工具包并且最终实现了窗口展示,然后你就很肯定的提交了文件,但是不可避免的会发生一些错误,现在你却不能撤销你的提交操作了。 一次提交会记录仓库中所有的暂存区文件。Git 只记录加入到提交任务中的文件,也就是说在过去某个时刻你使用 git add 命令加入到暂存区的所有文件。还有从先前的提交开始被改动的文件。如果没有其他的提交,所有的跟踪文件都包含在这次提交中,因为在浏览 Git 历史点的时候,它们没有存在于仓库中。 @@ -171,7 +171,7 @@ $ git log --oneline 在这个例子中提交时的版本号是 55df4c2。它被叫做 commit hash(译注:一个SHA-1生成的哈希码,用于表示一个git commit对象。),它表示着刚才你的提交包含的所有改动,覆盖了先前的记录。如果你想要“倒回”到你的提交历史点上就可以用这个 commit hash 作为依据。 -你可以把 commit hash 想象成一个声音磁带上的 [SMPTE timecode][3],或者再夸张一点,这就是好比一个黑胶唱片两首不同的歌之间的不同点,或是一个 CD 上的轨段编号。 +你可以把 commit hash 想象成一个声音磁带上的 [SMPTE timecode][3],或者再夸张一点,这就是好比一个黑胶唱片上两首不同的歌之间的不同点,或是一个 CD 上的轨段编号。 你在很久前改动了文件并且把它们加入到提交任务中,最终完成提交,这就会生成新的 commit hashes,每个 commit hashes 标示的历史点都代表着你的产品不同的版本。 From 6c6fff61eff8c6e703f58d33164f9973ae6815fe Mon Sep 17 00:00:00 2001 From: Christopher L Date: Thu, 28 Jul 2016 21:57:04 +0800 Subject: [PATCH 055/122] =?UTF-8?q?=E7=94=B3=E8=AF=B7=E7=BF=BB=E8=AF=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...figure and Troubleshoot Grand Unified Bootloader (GRUB).md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sources/tech/LFCS/Part 13 - How to Configure and Troubleshoot Grand Unified Bootloader (GRUB).md b/sources/tech/LFCS/Part 13 - How to Configure and Troubleshoot Grand Unified Bootloader (GRUB).md index cf24c51b58..2d1cbef467 100644 --- a/sources/tech/LFCS/Part 13 - How to Configure and Troubleshoot Grand Unified Bootloader (GRUB).md +++ b/sources/tech/LFCS/Part 13 - How to Configure and Troubleshoot Grand Unified Bootloader (GRUB).md @@ -1,3 +1,5 @@ +Being translated by ChrisLeeGit + Part 13 - LFCS: How to Configure and Troubleshoot Grand Unified Bootloader (GRUB) ===================================================================================== @@ -167,7 +169,7 @@ Do you have questions or comments? Don’t hesitate to let us know using the com via: http://www.tecmint.com/linux-basic-shell-scripting-and-linux-filesystem-troubleshooting/ 作者:[Gabriel Cánepa][a] -译者:[译者ID](https://github.com/译者ID) +译者:[ChrisLeeGit](https://github.com/chrisleegit) 校对:[校对者ID](https://github.com/校对者ID) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创翻译,[Linux中国](https://linux.cn/) 荣誉推出 From 89de15b01650ef16a9110a53ffa168f8a7c1379f Mon Sep 17 00:00:00 2001 From: Mike Tang Date: Fri, 29 Jul 2016 00:42:03 +0800 Subject: [PATCH 056/122] OPEN SOURCE ACCOUNTING SOFTWARE --- sources/tech/20160718 OPEN SOURCE ACCOUNTING SOFTWARE.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sources/tech/20160718 OPEN SOURCE ACCOUNTING SOFTWARE.md b/sources/tech/20160718 OPEN SOURCE ACCOUNTING SOFTWARE.md index 4232e6cda8..edc260a1bc 100644 --- a/sources/tech/20160718 OPEN SOURCE ACCOUNTING SOFTWARE.md +++ b/sources/tech/20160718 OPEN SOURCE ACCOUNTING SOFTWARE.md @@ -1,3 +1,5 @@ +MikeCoder Translating... + GNU KHATA: OPEN SOURCE ACCOUNTING SOFTWARE ============================================ From 193ab20ecbba980fd60b06b3a1a0a1ae5279e184 Mon Sep 17 00:00:00 2001 From: gitfuture Date: Fri, 29 Jul 2016 11:21:35 +0800 Subject: [PATCH 057/122] Finished Translating --- ...o Encrypt a Flash Drive Using VeraCrypt.md | 102 ------------------ ...o Encrypt a Flash Drive Using VeraCrypt.md | 100 +++++++++++++++++ 2 files changed, 100 insertions(+), 102 deletions(-) delete mode 100644 sources/tech/20160705 How to Encrypt a Flash Drive Using VeraCrypt.md create mode 100644 translated/tech/20160705 How to Encrypt a Flash Drive Using VeraCrypt.md diff --git a/sources/tech/20160705 How to Encrypt a Flash Drive Using VeraCrypt.md b/sources/tech/20160705 How to Encrypt a Flash Drive Using VeraCrypt.md deleted file mode 100644 index 27a0b950bd..0000000000 --- a/sources/tech/20160705 How to Encrypt a Flash Drive Using VeraCrypt.md +++ /dev/null @@ -1,102 +0,0 @@ -Translating by GitFuture [07.26] - -How to Encrypt a Flash Drive Using VeraCrypt -============================================ - -Many security experts prefer open source software like VeraCrypt, which can be used to encrypt flash drives, because of its readily available source code. - -Encryption is a smart idea for protecting data on a USB flash drive, as we covered in our piece that described ]how to encrypt a flash drive][1] using Microsoft BitLocker. - -But what if you do not want to use BitLocker? - -You may be concerned that because Microsoft's source code is not available for inspection, it could be susceptible to security "backdoors" used by the government or others. Because source code for open source software is widely shared, many security experts feel open source software is far less likely to have any backdoors. - -Fortunately, there are several open source encryption alternatives to BitLocker. - -If you need to be able to encrypt and access files on any Windows machine, as well as computers running Apple OS X or Linux, the open source [VeraCrypt][2] offers an excellent alternative. - -VeraCrypt is derived from TrueCrypt, a well-regarded open source encryption software product that has now been discontinued. But the code for TrueCrypt was audited and no major security flaws were found. In addition, it has since been improved in VeraCrypt. - -Versions exist for Windows, OS X and Linux. - -Encrypting a USB flash drive with VeraCrypt is not as straightforward as it is with BitLocker, but it still only takes a few minutes. - -### Encrypting Flash Drive with VeraCrypt in 8 Steps - -After [downloading VeraCrypt][3] for your operating system: - -Start VeraCrypt, and click on Create Volume to start the VeraCrypt Volume Creation Wizard. - -![](http://www.esecurityplanet.com/imagesvr_ce/6246/Vera0.jpg) - -The VeraCrypt Volume Creation Wizard allows you to create an encrypted file container on the flash drive which sits along with other unencrypted files, or you can choose to encrypt the entire flash drive. For the moment, we will choose to encrypt the entire flash drive. - -![](http://www.esecurityplanet.com/imagesvr_ce/6703/Vera1.jpg) - -On the next screen, choose Standard VeraCrypt Volume. - -![](http://www.esecurityplanet.com/imagesvr_ce/835/Vera2.jpg) - -Select the drive letter of the flash drive you want to encrypt (in this case O:). - -![](http://www.esecurityplanet.com/imagesvr_ce/9427/Vera3.jpg) - -Choose the Volume Creation Mode. If your flash drive is empty or you want to delete everything it contains, choose the first option. If you want to keep any existing files, choose the second option. - -![](http://www.esecurityplanet.com/imagesvr_ce/7828/Vera4.jpg) - -This screen allows you to choose your encryption options. If you are unsure of which to choose, leave the default settings of AES and SHA-512. - -![](http://www.esecurityplanet.com/imagesvr_ce/5918/Vera5.jpg) - -After confirming the Volume Size screen, enter and re-enter the password you want to use to encrypt your data. - -![](http://www.esecurityplanet.com/imagesvr_ce/3850/Vera6.jpg) - -To work effectively, VeraCrypt must draw from a pool of entropy or "randomness." To generate this pool, you'll be asked to move your mouse around in a random fashion for about a minute. Once the bar has turned green, or preferably when it reaches the far right of the screen, click Format to finish creating your encrypted drive. - -![](http://www.esecurityplanet.com/imagesvr_ce/7468/Vera8.jpg) - -### Using a Flash Drive Encrypted with VeraCrypt - -When you want to use an encrypted flash drive, first insert the drive in the computer and start VeraCrypt. - -Then select an unused drive letter (such as z:) and click Auto-Mount Devices. - -![](http://www.esecurityplanet.com/imagesvr_ce/2016/Vera10.jpg) - -Enter your password and click OK. - -![](http://www.esecurityplanet.com/imagesvr_ce/8222/Vera11.jpg) - -The mounting process may take a few minutes, after which your unencrypted drive will become available with the drive letter you selected previously. - -### VeraCrypt Traveler Disk Setup - -If you set up a flash drive with an encrypted container rather than encrypting the whole drive, you also have the option to create what VeraCrypt calls a traveler disk. This installs a copy of VeraCrypt on the USB flash drive itself, so when you insert the drive in another Windows computer you can run VeraCrypt automatically from the flash drive; there is no need to install it on the computer. - -You can set up a flash drive to be a Traveler Disk by choosing Traveler Disk SetUp from the Tools menu of VeraCrypt. - -![](http://www.esecurityplanet.com/imagesvr_ce/5812/Vera12.jpg) - -It is worth noting that in order to run VeraCrypt from a Traveler Disk on a computer, you must have administrator privileges on that computer. While that may seem to be a limitation, no confidential files can be opened safely on a computer that you do not control, such as one in a business center. - ->Paul Rubens has been covering enterprise technology for over 20 years. In that time he has written for leading UK and international publications including The Economist, The Times, Financial Times, the BBC, Computing and ServerWatch. - --------------------------------------------------------------------------------- - -via: http://www.esecurityplanet.com/open-source-security/how-to-encrypt-flash-drive-using-veracrypt.html - -作者:[Paul Rubens ][a] -译者:[译者ID](https://github.com/译者ID) -校对:[校对者ID](https://github.com/校对者ID) - -本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 - -[a]: http://www.esecurityplanet.com/author/3700/Paul-Rubens -[1]: http://www.esecurityplanet.com/views/article.php/3880616/How-to-Encrypt-a-USB-Flash-Drive.htm -[2]: http://www.esecurityplanet.com/open-source-security/veracrypt-a-worthy-truecrypt-alternative.html -[3]: https://veracrypt.codeplex.com/releases/view/619351 - - - diff --git a/translated/tech/20160705 How to Encrypt a Flash Drive Using VeraCrypt.md b/translated/tech/20160705 How to Encrypt a Flash Drive Using VeraCrypt.md new file mode 100644 index 0000000000..a049bfd73c --- /dev/null +++ b/translated/tech/20160705 How to Encrypt a Flash Drive Using VeraCrypt.md @@ -0,0 +1,100 @@ +用 VeraCrypt 加密闪存盘 +============================================ + +很多安全专家偏好像 VeraCrypt 这类能够用来加密闪存盘的开源软件。因为获取它的源代码很简单。 + +保护 USB闪存盘里的数据,加密是一个聪明的方法,正如我们在使用 Microsoft 的 BitLocker [加密闪存盘][1] 一文中提到的。 + +但是如果你不想用 BitLocker 呢? + +你可能有顾虑,因为你不能够查看 Microsoft 的程序源码,那么它容易被植入用于政府或其它用途的“后门”。由于开源软件的源码是公开的,很多安全专家认为开源软件很少藏有后门。 + +还好,有几个开源加密软件能作为 BitLocker 的替代。 + +要是你需要在 Windows 系统,苹果的 OS X 系统或者 Linux 系统上加密以及访问文件,开源软件 [VeraCrypt][2] 提供绝佳的选择。 + +VeraCrypt 源于 TrueCrypt。TrueCrypt是一个备受好评的开源加密软件,尽管它现在已经停止维护了。但是 TrueCrypt 的代码通过了审核,没有发现什么重要的安全漏洞。另外,它已经在 VeraCrypt 中进行了改善。 + +Windows,OS X 和 Linux 系统的版本都有。 + +用 VeraCrypt 加密 USB 闪存盘不像用 BitLocker 那么简单,但是它只要几分钟就好了。 + +### 用 VeraCrypt 加密闪存盘的 8 个步骤 + +对应操作系统 [下载 VeraCrypt][3] 之后: + +打开 VeraCrypt,点击 Create Volume,进入 VeraCrypt 的创建卷的向导程序(VeraCrypt Volume Creation Wizard)。(注:VeraCrypt Volume Creation Wizard 首字母全大写,不清楚是否需要翻译,之后有很多首字母大写的词,都以括号标出) + +![](http://www.esecurityplanet.com/imagesvr_ce/6246/Vera0.jpg) + +VeraCrypt 创建卷向导(VeraCrypt Volume Creation Wizard)允许你在闪存盘里新建一个加密文件容器,这与其它未加密文件是独立的。或者你也可以选择加密整个闪存盘。这个时候你就选加密整个闪存盘就行。 + +![](http://www.esecurityplanet.com/imagesvr_ce/6703/Vera1.jpg) + +然后选择标准模式(Standard VeraCrypt Volume)。 + +![](http://www.esecurityplanet.com/imagesvr_ce/835/Vera2.jpg) + +选择你想加密的闪存盘的驱动器卷标(这里是 O:)。 + +![](http://www.esecurityplanet.com/imagesvr_ce/9427/Vera3.jpg) + +选择创建卷标模式(Volume Creation Mode)。如果你的闪存盘是空的,或者你想要删除它里面的所有东西,选第一个。要么你想保持所有现存的文件,选第二个就好了。 + +![](http://www.esecurityplanet.com/imagesvr_ce/7828/Vera4.jpg) + +这一步允许你选择加密选项。要是你不确定选哪个,就用默认的 AES 和 SHA-512 设置。 + +![](http://www.esecurityplanet.com/imagesvr_ce/5918/Vera5.jpg) + +确定了卷标容量后,输入并确认你想要用来加密数据密码。 + +![](http://www.esecurityplanet.com/imagesvr_ce/3850/Vera6.jpg) + +要有效工作,VeraCrypt 要从一个熵或者“随机数”池中取出一个随机数。要初始化这个池,你将被要求随机地移动鼠标一分钟。一旦进度条变绿了,或者更方便的是等到进度条到了屏幕右边足够远的时候,点击 “Format” 来结束创建加密盘。 + +![](http://www.esecurityplanet.com/imagesvr_ce/7468/Vera8.jpg) + +### 用 VeraCrypt 使用加密过的闪存盘 + +当你想要使用一个加密了的闪存盘,先插入闪存盘到电脑上,启动 VeraCrypt。 + +然后选择一个没有用过的卷标(比如 z:),点击自动挂载设备(Auto-Mount Devices)。 + +![](http://www.esecurityplanet.com/imagesvr_ce/2016/Vera10.jpg) + +输入密码,点击确定。 + +![](http://www.esecurityplanet.com/imagesvr_ce/8222/Vera11.jpg) + +挂载过程需要几分钟,这之后你的解密盘就能通过你先前选择的盘符进行访问了。 + +### VeraCrypt 移动硬盘安装步骤 + +如果你设置闪存盘的时候,选择的是加密过的容器而不是加密整个盘,你可以选择创建 VeraCrypt 称为移动盘(Traveler Disk)的设备。这会复制安装一个 VeraCrypt 在 USB 闪存盘。当你在别的 Windows 电脑上插入 U 盘时,就能从 U 盘自动运行 VeraCrypt;也就是说没必要在新电脑上安装 VeraCrypt。 + +你可以设置闪存盘作为一个移动硬盘(Traveler Disk),在 VeraCrypt 的工具栏(Tools)菜单里选择 Traveler Disk SetUp 就行了。 + +![](http://www.esecurityplanet.com/imagesvr_ce/5812/Vera12.jpg) + +要从移动盘(Traveler Disk)上运行 VeraCrypt,你必须要有那台电脑的管理员权限,这不足为奇。尽管这看起来是个限制,机密文件无法在不受控制的电脑上安全打开,比如在一个商务中心的电脑上。 + +>Paul Rubens 从事技术行业已经超过 20 年。这期间他为英国和国际主要的出版社,包括 《The Economist》《The Times》《Financial Times》《The BBC》《Computing》和《ServerWatch》等出版社写过文章, + +-------------------------------------------------------------------------------- + +via: http://www.esecurityplanet.com/open-source-security/how-to-encrypt-flash-drive-using-veracrypt.html + +作者:[Paul Rubens ][a] +译者:[GitFuture](https://github.com/GitFuture) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]: http://www.esecurityplanet.com/author/3700/Paul-Rubens +[1]: http://www.esecurityplanet.com/views/article.php/3880616/How-to-Encrypt-a-USB-Flash-Drive.htm +[2]: http://www.esecurityplanet.com/open-source-security/veracrypt-a-worthy-truecrypt-alternative.html +[3]: https://veracrypt.codeplex.com/releases/view/619351 + + + From 0921361a3fd8732a180d5b748fb721086bd3d7a9 Mon Sep 17 00:00:00 2001 From: Ezio Date: Fri, 29 Jul 2016 13:35:24 +0800 Subject: [PATCH 058/122] =?UTF-8?q?20160729-1=20=E9=80=89=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...f Earth as Your Linux Desktop Wallpaper.md | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 sources/tech/20160726 Set a Real Time Photo of Earth as Your Linux Desktop Wallpaper.md diff --git a/sources/tech/20160726 Set a Real Time Photo of Earth as Your Linux Desktop Wallpaper.md b/sources/tech/20160726 Set a Real Time Photo of Earth as Your Linux Desktop Wallpaper.md new file mode 100644 index 0000000000..1fd552e70c --- /dev/null +++ b/sources/tech/20160726 Set a Real Time Photo of Earth as Your Linux Desktop Wallpaper.md @@ -0,0 +1,38 @@ +Set a Real Time Photo of Earth as Your Linux Desktop Wallpaper +================================================================= + +![](http://www.omgubuntu.co.uk/wp-content/uploads/2016/07/Screen-Shot-2016-07-26-at-16.36.47-1.jpg) + +Bored of looking at the same desktop background? Here’s something that’s (almost) out of this world. + +‘[Himawaripy][1]‘ is a small Python 3 script that fetches a near-real time picture of Earth taken by the [Japanese Himawari 8 weather satellite][2] and sets it as your desktop background. + +Once installed you can set the app to run as a cron job every 10 minutes (in the background, naturally) so that it can fetch and set a realtime picture of Earth as your desktop wallpaper. + +Because Himawari-8 is a geostationary satellite you’re only ever going to images of the earth as seen from above Australasia — but with real time weather patterns, cloud formations and lighting it’s still makes for spectacular scene, even if seeing things above the UK would be better for me! + +Advanced settings allow you to configure the quality of the images pulled from the satellite , but keep in mind that any increase in quality will result in an increased file size, and a longer download wait! + +Lastly, while this script is very similar to many others that we’ve covered over the years it is up-to-date and working. + +Get Himawaripy +Himawaripy has been tested on a range of desktop environments, including Unity, LXDE, i3, MATE and a host of other desktop environments. It is free, open-source software but is not entirely straightforward to set up and configure. + +Find all instructions on getting the app installed and set up (hint: there’s no one-click installer) on the project’s GitHub page. + +[Real time earth wallpaper script on GitHub][0] + +-------------------------------------------------------------------------------- + +via: http://www.tecmint.com/mandatory-access-control-with-selinux-or-apparmor-linux/ + +作者:[ JOEY-ELIJAH SNEDDON][a] +译者:[译者ID](https://github.com/译者ID) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]: https://plus.google.com/117485690627814051450/?rel=author +[1]: https://github.com/boramalper/himawaripy +[2]: https://en.wikipedia.org/wiki/Himawari_8 +[0]: https://github.com/boramalper/himawaripy From 27b76b256636123ea14f7d823615ec8dd158f5db Mon Sep 17 00:00:00 2001 From: Ezio Date: Fri, 29 Jul 2016 13:43:09 +0800 Subject: [PATCH 059/122] =?UTF-8?q?20160729-2=20=E9=80=89=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../20160715 bc - Command line calculator.md | 131 ++++++++++++++++++ 1 file changed, 131 insertions(+) create mode 100644 sources/tech/20160715 bc - Command line calculator.md diff --git a/sources/tech/20160715 bc - Command line calculator.md b/sources/tech/20160715 bc - Command line calculator.md new file mode 100644 index 0000000000..adf854e468 --- /dev/null +++ b/sources/tech/20160715 bc - Command line calculator.md @@ -0,0 +1,131 @@ +bc: Command line calculator +============================ + +![](https://cdn.fedoramagazine.org/wp-content/uploads/2016/07/bc-calculator-945x400.jpg) + +If you run a graphical desktop environment, you probably point and click your way to a calculator when you need one. The Fedora Workstation, for example, includes the Calculator tool. It features several different operating modes that allow you to do, for example, complex math or financial calculations. But did you know the command line also offers a similar calculator called bc? + +The bc utility gives you everything you expect from a scientific, financial, or even simple calculator. What’s more, it can be scripted from the command line if needed. This allows you to use it in shell scripts, in case you need to do more complex math. + +Because bc is used by some other system software, like CUPS printing services, it’s probably installed on your Fedora system already. You can check with this command: + +``` +dnf list installed bc +``` + +If you don’t see it for some reason, you can install the package with this command: + +``` +sudo dnf install bc +``` + +### Doing simple math with bc + +One way to use bc is to enter the calculator’s own shell. There you can run many calculations in a row. When you enter, the first thing that appears is a notice about the program: + +``` +$ bc +bc 1.06.95 +Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006 Free Software Foundation, Inc. +This is free software with ABSOLUTELY NO WARRANTY. +For details type `warranty'. +``` + +Now you can type in calculations or commands, one per line: + +``` +1+1 +``` + +The calculator helpfully answers: + +``` +2 +``` + +You can perform other commands here. You can use addition (+), subtraction (-), multiplication (*), division (/), parentheses, exponents (^), and so forth. Note that the calculator respects all expected conventions such as order of operations. Try these examples: + +``` +(4+7)*2 +4+7*2 +``` + +To exit, send the “end of input” signal with the key combination Ctrl+D. + +Another way is to use the echo command to send calculations or commands. Here’s the calculator equivalent of “Hello, world,” using the shell’s pipe function (|) to send output from echo into bc: + +``` +echo '1+1' | bc +``` + +You can send more than one calculation using the shell pipe, with a semicolon to separate entries. The results are returned on separate lines. + +``` +echo '1+1; 2+2' | bc +``` + +### Scale + +The bc calculator uses the concept of scale, or the number of digits after a decimal point, in some calculations. The default scale is 0. Division operations always use the scale setting. So if you don’t set scale, you may get unexpected answers: + +``` +echo '3/2' | bc +echo 'scale=3; 3/2' | bc +``` + +Multiplication uses a more complex decision for scale: + +``` +echo '3*2' | bc +echo '3*2.0' | bc +``` + +Meanwhile, addition and subtraction are more as expected: + +``` +echo '7-4.15' | bc +``` + +### Other base number systems + +Another useful function is the ability to use number systems other than base-10 (decimal). For instance, you can easily do hexadecimal or binary math. Use the ibase and obase commands to set input and output base systems between base-2 and base-16. Remember that once you use ibase, any number you enter is expected to be in the new declared base. + +To do hexadecimal to decimal conversions or math, you can use a command like this. Note the hexadecimal digits above 9 must be in uppercase (A-F): + +``` +echo 'ibase=16; A42F' | bc +echo 'ibase=16; 5F72+C39B' | bc +``` + +To get results in hexadecimal, set the obase as well: + +``` +echo 'obase=16; ibase=16; 5F72+C39B' | bc +``` + +Here’s a trick, though. If you’re doing these calculations in the shell, how do you switch back to input in base-10? The answer is to use ibase, but you must set it to the equivalent of decimal number 10 in the current input base. For instance, if ibase was set to hexadecimal, enter: + +``` +ibase=A +``` + +Once you do this, all input numbers are now decimal again, so you can enter obase=10 to reset the output base system. + +### Conclusion + +This is only the beginning of what bc can do. It also allows you to define functions, variables, and loops for complex calculations and programs. You can save these programs as text files on your system to run whenever you need. You can find numerous resources on the web that offer examples and additional function libraries. Happy calculating! + + + +-------------------------------------------------------------------------------- + +via: http://www.tecmint.com/mandatory-access-control-with-selinux-or-apparmor-linux/ + +作者:[Paul W. Frields][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/author/pfrields/ +[1]: http://phodd.net/gnu-bc/ From 8236318652e2e8187e386b6eb97bbcba8fe62114 Mon Sep 17 00:00:00 2001 From: Ezio Date: Fri, 29 Jul 2016 13:49:10 +0800 Subject: [PATCH 060/122] =?UTF-8?q?20160729-3=20=E9=80=89=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...0160722 Keeweb A Linux Password Manager.md | 62 +++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 sources/tech/20160722 Keeweb A Linux Password Manager.md diff --git a/sources/tech/20160722 Keeweb A Linux Password Manager.md b/sources/tech/20160722 Keeweb A Linux Password Manager.md new file mode 100644 index 0000000000..b829ea107e --- /dev/null +++ b/sources/tech/20160722 Keeweb A Linux Password Manager.md @@ -0,0 +1,62 @@ +Keeweb A Linux Password Manager +================================ + +![](http://www.linuxandubuntu.com/uploads/2/1/1/5/21152474/keeweb_1.png?608) + +Today we are depending on more and more online services. Each online service we sign up for, let us set a password and this way we have to remember hundreds of passwords. In this case, it is easy for anyone to forget passwords. In this article I am going to talk about Keeweb, a Linux password manager that can store all your passwords securely either online or offline. + +When we talk about Linux password managers, there are so many. Password managers like, [Keepass][1] and [Encryptr, a Zero-knowledge system based password manager][2] have already been talked about on LinuxAndUbuntu. Keeweb is another password manager for Linux that we are going to see in this article. + +### Keeweb can store passwords offline or online + +Keeweb is a cross-platform password manager. It can store all your passwords offline and sync it with your own cloud storage services like OneDrive, Google Drive, Dropbox etc. Keeweb does not have online database of its own to sync your passwords. + +To connect your online storage with Keeweb, just click more and click the service that you want to use. + +![](http://www.linuxandubuntu.com/uploads/2/1/1/5/21152474/keeweb.png?685) + +Now Keeweb will prompt you to sign in to your drive. After sign in authenticate Keeweb to use your account. + +![](http://www.linuxandubuntu.com/uploads/2/1/1/5/21152474/authenticate-dropbox-with-keeweb_orig.jpg?649) + +### Store passwords with Keeweb + +It is very easy to store your passwords with Keeweb. You can encrypt your password file with a complex password. Keeweb also allows you to lock file with a key file but I don't recommend it. If somebody gets your key file, it takes only a click to unlock your passwords file. + +#### Create Passwords + +To create a new password simply click the '+' sign and you will be presented all entries to fill up. You can create more entries if you want. + +#### Search Passwords + +![](http://www.linuxandubuntu.com/uploads/2/1/1/5/21152474/search-passwords_orig.png) + +Keeweb has a library of icons so that you can find any particular password entry easily. You can change the color of icons, download more icons and even import icons from your computer. When talking about finding passwords the search comes very handy. ​ + +Passwords of similar services can be grouped so that you can find them all at one place in one folder. You can also tag passwords to store them all in different categories. + +![](http://www.linuxandubuntu.com/uploads/2/1/1/5/21152474/tags-passwords-in-keeweb.png?283) + +### Themes + +![](http://www.linuxandubuntu.com/uploads/2/1/1/5/21152474/themes.png?304) + +If you like light themes like white or high contrast then you can change theme from Settings > General > Themes. There are four themes available, two are dark and two are light. + +### Dont' you Like Linux Passwords Manager? No problem! + +I have already posted about two other Linux password managers, Keepass and Encryptr and there were arguments on Reddit, and other social media. There were people against using any password manager and vice-versa. In this article I want to clear out that it is our responsibility to save the file that passwords are stored in. I think Password managers like Keepass and Keeweb are good to use as they don't store your passwords in the cloud. These password managers create a file and you can store it on your hard drive or encrypt it with apps like VeraCrypt. I myself don't use or recommend to use services that store passwords in their own database. + +-------------------------------------------------------------------------------- + +via: http://www.tecmint.com/mandatory-access-control-with-selinux-or-apparmor-linux/ + +作者:[author][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/home/keeweb-a-linux-password-manager +[1]: http://www.linuxandubuntu.com/home/keepass-password-management-tool-creates-strong-passwords-and-keeps-them-secure +[2]: http://www.linuxandubuntu.com/home/encryptr-zero-knowledge-system-based-password-manager-for-linux From 231a1636b91ee1568c7aac5f6681f3101e3d4661 Mon Sep 17 00:00:00 2001 From: Ezio Date: Fri, 29 Jul 2016 13:55:13 +0800 Subject: [PATCH 061/122] =?UTF-8?q?20160729-4=20=E9=80=89=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...r With Multiple Terminals In One Window.md | 85 +++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 sources/tech/20160724 Terminator A Linux Terminal Emulator With Multiple Terminals In One Window.md diff --git a/sources/tech/20160724 Terminator A Linux Terminal Emulator With Multiple Terminals In One Window.md b/sources/tech/20160724 Terminator A Linux Terminal Emulator With Multiple Terminals In One Window.md new file mode 100644 index 0000000000..eb50d539a1 --- /dev/null +++ b/sources/tech/20160724 Terminator A Linux Terminal Emulator With Multiple Terminals In One Window.md @@ -0,0 +1,85 @@ +Terminator A Linux Terminal Emulator With Multiple Terminals In One Window +============================================================================= + +![](http://www.linuxandubuntu.com/uploads/2/1/1/5/21152474/lots-of-terminals-in-terminator_1.jpg?659) + +Each Linux distribution has a default terminal emulator for interacting with system through commands. But the default terminal app might not be perfect for you. There are so many terminal apps that will provide you more functionalities to perform more tasks simultaneously to sky-rocket speed of your work. Such useful terminal emulators include Terminator, a multi-windows supported free terminal emulator for your Linux system. + +### What Is Linux Terminal Emulator? + +A Linux terminal emulator is a program that lets you interact with the shell. All Linux distributions come with a default Linux terminal app that let you pass commands to the shell. + +### Terminator, A Free Linux Terminal App + +Terminator is a Linux terminal emulator that provides several features that your default terminal app does not support. It provides the ability to create multiple terminals in one window and faster your work progress. Other than multiple windows, it allows you to change other properties such as, terminal fonts, fonts colour, background colour and so on. Let's see how we can install and use Terminator in different Linux distributions. + +### How To Install Terminator In Linux? + +#### Install Terminator In Ubuntu Based Distributions + +Terminator is available in the default Ubuntu repository. So you don't require to add any additional PPA. Just use APT or Software App to install it in Ubuntu. + +``` +sudo apt-get install terminator +``` + +In case Terminator is not available in your default repository, just compile Terminator from source code. + +[DOWNLOAD SOURCE CODE][1] + +Download Terminator source code and extract it on your desktop. Now open your default terminal & cd into the extracted folder. + +Now use the following command to install Terminator - + +``` +sudo ./setup.py install +``` + +#### Install Terminator In Fedora & Other Derivatives + +``` +dnf install terminator +``` + +#### Install Terminator In OpenSuse + +[INSTALL IN OPENSUSE][2] + +### How To Use Multiple Terminals In One Window? + +After you have installed Terminator, simply open multiple terminals in one window. Simply right click and divide. + +![](http://www.linuxandubuntu.com/uploads/2/1/1/5/21152474/multiple-terminals-in-terminator_orig.jpg) + +![](http://www.linuxandubuntu.com/uploads/2/1/1/5/21152474/multiple-terminals-in-terminator-emulator.jpg?697) + +You can create as many terminals as you want, if you can manage them. + +![](http://www.linuxandubuntu.com/uploads/2/1/1/5/21152474/lots-of-terminals-in-terminator.jpg?706) + +### Customise Terminals + +Right click the terminal and click Properties. Now you can customise fonts, fonts colour, title colour & background and terminal fonts colour & background. + +![](http://www.linuxandubuntu.com/uploads/2/1/1/5/21152474/customize-terminator-interface.jpg?702) + +![](http://www.linuxandubuntu.com/uploads/2/1/1/5/21152474/free-terminal-emulator_orig.jpg) + +### Conclusion & What Is Your Favorite Terminal Emulator? + +Terminator is an advanced terminal emulator and it also let you customize the interface. If you have not yet switched from your default terminal emulator then just try this one. I know you'll like it. If you're using any other free terminal emulator, then let us know your favorite terminal emulator. Also don't forget to share this article with your friends. Perhaps your friends are searching for something like this. + + +-------------------------------------------------------------------------------- + +via: http://www.tecmint.com/mandatory-access-control-with-selinux-or-apparmor-linux/ + +作者:[author][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/home/terminator-a-linux-terminal-emulator-with-multiple-terminals-in-one-window +[1]: https://launchpad.net/terminator/+download +[2]: http://software.opensuse.org/download.html?project=home%3AKorbi123&package=terminator From 1b6e4f293dda28a37848ae4453c060efa8dbaad6 Mon Sep 17 00:00:00 2001 From: Ezio Date: Fri, 29 Jul 2016 14:15:33 +0800 Subject: [PATCH 062/122] =?UTF-8?q?20160729-4=20=E9=80=89=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...pt-get on Ubuntu Linux 16.04 LTS server.md | 218 ++++++++++++++++++ 1 file changed, 218 insertions(+) create mode 100644 sources/tech/20160727-How-to-use-multiple-connections-to-speed-up-apt-get on Ubuntu Linux 16.04 LTS server.md diff --git a/sources/tech/20160727-How-to-use-multiple-connections-to-speed-up-apt-get on Ubuntu Linux 16.04 LTS server.md b/sources/tech/20160727-How-to-use-multiple-connections-to-speed-up-apt-get on Ubuntu Linux 16.04 LTS server.md new file mode 100644 index 0000000000..460dabc03c --- /dev/null +++ b/sources/tech/20160727-How-to-use-multiple-connections-to-speed-up-apt-get on Ubuntu Linux 16.04 LTS server.md @@ -0,0 +1,218 @@ +How to use multiple connections to speed up apt-get/apt on Ubuntu Linux 16.04 LTS server +========================================================================================= + +ow do I speed up my apt-get or apt command to download packages from multiple repos on a Ubuntu Linux 16.04 or 14.04 LTS server? + +You need to use apt-fast shell script wrapper. It should speed up apt-get command/apt command and aptitude command by downloading packages with multiple connections per package. All packages are downloaded simultaneously in parallel. It uses aria2c as default download accelerator. + +### Install apt-fast tool + +Type the following command on Ubuntu Linux 14.04 and later versions: + +``` +$ sudo add-apt-repository ppa:saiarcot895/myppa +``` + +Sample outputs: + +![](http://s0.cyberciti.org/uploads/faq/2016/07/install-apt-fast-repo.jpg) + +Update your repo: + +``` +$ sudo apt-get update +``` + +OR + +``` +$ sudo apt update +``` + +![](http://s0.cyberciti.org/uploads/faq/2016/07/install-apt-fast-command.jpg) + +Install apt-fast shell wrapper: + +``` +$ sudo apt-get -y install apt-fast +``` + +OR + +``` +$ sudo apt -y install apt-fast +``` + +Sample outputs: + + +``` +Reading package lists... Done +Building dependency tree +Reading state information... Done +The following additional packages will be installed: + aria2 libc-ares2 libssh2-1 +Suggested packages: + aptitude +The following NEW packages will be installed: + apt-fast aria2 libc-ares2 libssh2-1 +0 upgraded, 4 newly installed, 0 to remove and 0 not upgraded. +Need to get 1,282 kB of archives. +After this operation, 4,786 kB of additional disk space will be used. +Do you want to continue? [Y/n] y +Get:1 http://01.archive.ubuntu.com/ubuntu xenial/universe amd64 libssh2-1 amd64 1.5.0-2 [70.3 kB] +Get:2 http://ppa.launchpad.net/saiarcot895/myppa/ubuntu xenial/main amd64 apt-fast all 1.8.3~137+git7b72bb7-0ubuntu1~ppa3~xenial1 [34.4 kB] +Get:3 http://01.archive.ubuntu.com/ubuntu xenial/main amd64 libc-ares2 amd64 1.10.0-3 [33.9 kB] +Get:4 http://01.archive.ubuntu.com/ubuntu xenial/universe amd64 aria2 amd64 1.19.0-1build1 [1,143 kB] +54% [4 aria2 486 kB/1,143 kB 42%] 20.4 kB/s 32s +``` + +### Configure apt-fast + +You will be prompted as follows (a value between 5 and 16 must be entered): + +![](http://s0.cyberciti.org/uploads/faq/2016/07/max-connection-10.jpg) + +And: + +![](http://s0.cyberciti.org/uploads/faq/2016/07/apt-fast-confirmation-box.jpg) + +You can edit settings directly too: + +``` +$ sudo vi /etc/apt-fast.conf +``` + +>**Please note that this tool is not for slow network connections; it is for fast network connections. If you have a slow connection to the Internet, you are not going to benefit by this tool.** + +### How do I use apt-fast command? + +The syntax is: + +``` +apt-fast command +apt-fast [options] command +``` + +#### To retrieve new lists of packages using apt-fast + +``` +sudo apt-fast update +``` + +#### To perform an upgrade using apt-fast + +``` +sudo apt-fast upgrade +``` + + +#### To perform distribution upgrade (release or force kernel upgrade), enter: + +``` +$ sudo apt-fast dist-upgrade +``` + +#### To install new packages + +The syntax is: + +``` +sudo apt-fast install pkg +``` + +For example, install nginx package, enter: + +``` +$ sudo apt-fast install nginx +``` + +Sample outputs: + +![](http://s0.cyberciti.org/uploads/faq/2016/07/sudo-apt-fast-install.jpg) + +#### To remove packages + +``` +$ sudo apt-fast remove pkg +$ sudo apt-fast remove nginx +``` + +#### To remove packages and its config files too + +``` +$ sudo apt-fast purge pkg +$ sudo apt-fast purge nginx +``` + +#### To remove automatically all unused packages, enter: + +``` +$ sudo apt-fast autoremove +``` + +#### To Download source archives + +``` +$ sudo apt-fast source pkgNameHere +``` + +#### To erase downloaded archive files + +``` +$ sudo apt-fast clean +``` + +#### To erase old downloaded archive files + +``` +$ sudo apt-fast autoclean +``` + +#### To verify that there are no broken dependencies + +``` +$ sudo apt-fast check +``` + +#### To download the binary package into the current directory + +``` +$ sudo apt-fast download pkgNameHere +$ sudo apt-fast download nginx +``` + +Sample outputs: + +``` +[#7bee0c 0B/0B CN:1 DL:0B] +07/26 15:35:42 [NOTICE] Verification finished successfully. file=/home/vivek/nginx_1.10.0-0ubuntu0.16.04.2_all.deb +07/26 15:35:42 [NOTICE] Download complete: /home/vivek/nginx_1.10.0-0ubuntu0.16.04.2_all.deb +Download Results: +gid |stat|avg speed |path/URI +======+====+===========+======================================================= +7bee0c|OK | n/a|/home/vivek/nginx_1.10.0-0ubuntu0.16.04.2_all.deb +Status Legend: +(OK):download completed. +``` + +#### To download and display the changelog for the given package + +``` +$ sudo apt-fast changelog pkgNameHere +$ sudo apt-fast changelog nginx +``` + + + +-------------------------------------------------------------------------------- + +via: https://fedoramagazine.org/introducing-flatpak/ + +作者:[VIVEK GITE][a] +译者:[zky001](https://github.com/zky001) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]: http://www.cyberciti.biz/tips/about-us From bd4ec60a566239d0d14beee337f7939d6e51f157 Mon Sep 17 00:00:00 2001 From: wxy Date: Fri, 29 Jul 2016 14:41:49 +0800 Subject: [PATCH 063/122] PUB:20160630 What makes up the Fedora kernel MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @ChrisLeeGit 好棒!翻译的精确而优雅。 --- .../20160630 What makes up the Fedora kernel.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) rename {translated/tech => published}/20160630 What makes up the Fedora kernel.md (70%) diff --git a/translated/tech/20160630 What makes up the Fedora kernel.md b/published/20160630 What makes up the Fedora kernel.md similarity index 70% rename from translated/tech/20160630 What makes up the Fedora kernel.md rename to published/20160630 What makes up the Fedora kernel.md index 954c4cb440..67c26ee93c 100644 --- a/translated/tech/20160630 What makes up the Fedora kernel.md +++ b/published/20160630 What makes up the Fedora kernel.md @@ -3,11 +3,11 @@ Fedora 内核是由什么构成的? ![](https://cdn.fedoramagazine.org/wp-content/uploads/2016/06/kernel-945x400.png) -每个 Fedora 系统都运行着一个内核。许多代码段组合在一起使之成为现实。 +每个 Fedora 系统都运行着一个内核。许多代码片段组合在一起使之成为现实。 -每个 Fedora 内核都起始于一个来自于 [上游社区][1] 的基线版本,通常称之为 vanilla 内核。上游内核就是标准。(Fedora 的)目标是包含尽可能多的上游代码,这样使得 bug 修复和 API 更新更加容易,同时也会有更多的人审查代码。理想情况下,Fedora 能够直接从 kernel.org 获得内核,然后发送给所有用户。 +每个 Fedora 内核都起始于一个来自于[上游社区][1]的基线版本——通常称之为 vanilla 内核。上游内核就是标准。(Fedora 的)目标是包含尽可能多的上游代码,这样使得 bug 修复和 API 更新更加容易,同时也会有更多的人审查代码。理想情况下,Fedora 能够直接获取 kernel.org 的内核,然后发送给所有用户。 -现实情况是,使用 vanilla 内核并不能完全满足 Fedora。Vanilla 内核可能并不支持一些 Fedora 用户希望拥有的功能。用户接收的 [Fedora 内核] 是在 vanilla 内核之上打了很多补丁的内核。这些补丁被认为“不在树上”。许多这些位于补丁树之外的补丁都不会存在太久。如果某补丁能够修复一个问题,那么该补丁可能会被合并到 Fedora 树,以便用户能够更快地收到修复。当内核变基到一个新版本时,在新版本中的补丁都将被清除。 +现实情况是,使用 vanilla 内核并不能完全满足 Fedora。Vanilla 内核可能并不支持一些 Fedora 用户希望拥有的功能。用户接收的 [Fedora 内核] 是在 vanilla 内核之上打了很多补丁的内核。这些补丁被认为“不在树上(out of tree)”。许多这些位于补丁树之外的补丁都不会存在太久。如果某补丁能够修复一个问题,那么该补丁可能会被合并到 Fedora 树,以便用户能够更快地收到修复。当内核变基到一个新版本时,在新版本中的补丁都将被清除。 一些补丁会在 Fedora 内核树上存在很长时间。一个很好的例子是,安全启动补丁就是这类补丁。这些补丁提供了 Fedora 希望支持的功能,即使上游社区还没有接受它们。保持这些补丁更新是需要付出很多努力的,所以 Fedora 尝试减少不被上游内核维护者接受的补丁数量。 @@ -21,7 +21,7 @@ via: https://fedoramagazine.org/makes-fedora-kernel/ 作者:[Laura Abbott][a] 译者:[ChrisLeeGit](https://github.com/chrisleegit) -校对:[校对者ID](https://github.com/校对者ID) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 From a8048d99cc63ff10bbbf7e7676ba43274a08d195 Mon Sep 17 00:00:00 2001 From: Mike Date: Fri, 29 Jul 2016 16:08:32 +0800 Subject: [PATCH 064/122] translated/tech/20160718 OPEN SOURCE ACCOUNTING SOFTWARE.md (#4240) * translated/tech/20160718 OPEN SOURCE ACCOUNTING SOFTWARE.md * translated/tech/20160718 OPEN SOURCE ACCOUNTING SOFTWARE.md --- ...0160718 OPEN SOURCE ACCOUNTING SOFTWARE.md | 73 ------------------- ...0160718 OPEN SOURCE ACCOUNTING SOFTWARE.md | 71 ++++++++++++++++++ 2 files changed, 71 insertions(+), 73 deletions(-) delete mode 100644 sources/tech/20160718 OPEN SOURCE ACCOUNTING SOFTWARE.md create mode 100644 translated/tech/20160718 OPEN SOURCE ACCOUNTING SOFTWARE.md diff --git a/sources/tech/20160718 OPEN SOURCE ACCOUNTING SOFTWARE.md b/sources/tech/20160718 OPEN SOURCE ACCOUNTING SOFTWARE.md deleted file mode 100644 index edc260a1bc..0000000000 --- a/sources/tech/20160718 OPEN SOURCE ACCOUNTING SOFTWARE.md +++ /dev/null @@ -1,73 +0,0 @@ -MikeCoder Translating... - -GNU KHATA: OPEN SOURCE ACCOUNTING SOFTWARE -============================================ - -Being an active Linux enthusiast, I usually introduce my friends to Linux, help them choose the best distro to suit their needs, and finally get them set with open source alternative software for their work. - -But in one case, I was pretty helpless. My uncle, who is a freelance accountant, uses a set of some pretty sophisticated paid software for work. And I wasn’t sure if I’d find anything under FOSS for him, until Yesterday. - -Abhishek was suggesting me some [cool apps][1] to check out and this particular one, GNU Khata stuck out. - -[GNU Khata][2] is an accounting tool. Or shall I say a collection of accounting tools? It is like the [Evernote][3] of economy management. It is so versatile that it can be used from personal Finance management to large scale business management, from store inventory management to corporate tax works. - -One interesting fact for you. ‘Khata’ in Hindi and other Indian languages means account and hence this accounting software is called GNU Khata. - -### INSTALLATION - -There are many installation instructions floating around the internet which actually install the older web app version of GNU Khata. Currently, GNU Khata is available only for Debian/Ubuntu and their derivatives. I suggest you follow the steps given in GNU Khata official Website to install the updated standalone. Let me give them out real quick. - -- Download the installer [here][4]. -- Open the terminal in download location. -- Copy and paste the below code in terminal and run. - -``` -sudo chmod 755 GNUKhatasetup.run -sudo ./GNUKhatasetup.run -``` - -- That’s it. Open the GNU Khata from the dash or the application menu. -### FIRST LAUNCH - -GNU Khata opens up in the browser and displays the following page. - -![](https://itsfoss.com/wp-content/uploads/2016/07/GNU-khata-1.jpg) - -Fill in the Organization name, case and organization type, financial year and click on proceed to go to the admin setup page. - -![](https://itsfoss.com/wp-content/uploads/2016/07/GNU-khata-2.jpg) - -Carefully feed in your name, password, security question and the answer and click on “create and login”. - -![](https://itsfoss.com/wp-content/uploads/2016/07/GNU-khata-3.jpg) - -You’re all set now. Use the Menu bar to start using GNU Khata to manage your finances. It’s that easy. - -### DOES GNU KHATA REALLY RIVAL THE PAID ACCOUNTING SOFTWARE IN THE MARKET? - -To begin with, GNU Khata keeps it all simple. The menu bar up top is very conveniently organized to help you work faster and better. You can choose to manage different accounts and projects and access them easily. [Their Website][5] states that GNU Khata can be “easily transformed into Indian languages”. Also, did you know that GNU Khata can be used on the cloud too? - -All the major accounting tools like ledgers, project statements, statement of affairs etc are formatted in a professional manner and are made available in both instantly presentable as well as customizable formats. It makes accounting and inventory management look so easy. - -The Project is very actively evolving, seeks feedback and guidance from practicing accountants to make improvements in the software. Considering the maturity, ease of use and the absence of a price tag, GNU Khata can be the perfect assistant in bookkeeping. - -Let us know what you think about GNU Khata in the comments below. - - - --------------------------------------------------------------------------------- - -via: https://itsfoss.com/using-gnu-khata/?utm_source=feedburner&utm_medium=feed&utm_campaign=Feed%3A+ItsFoss+%28Its+FOSS%21+An+Open+Source+Blog%29 - -作者:[Aquil Roshan][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/aquil/ -[1]: https://itsfoss.com/category/apps/ -[2]: http://www.gnukhata.in/ -[3]: https://evernote.com/ -[4]: https://cloud.openmailbox.org/index.php/s/L8ppsxtsFq1345E/download -[5]: http://www.gnukhata.in/ diff --git a/translated/tech/20160718 OPEN SOURCE ACCOUNTING SOFTWARE.md b/translated/tech/20160718 OPEN SOURCE ACCOUNTING SOFTWARE.md new file mode 100644 index 0000000000..8093f8eae2 --- /dev/null +++ b/translated/tech/20160718 OPEN SOURCE ACCOUNTING SOFTWARE.md @@ -0,0 +1,71 @@ +GNU KHATA:开源的会计管理软件 +============================================ + +作为一个活跃的 Linux 爱好者,我经常向我的朋友们介绍 Linux,帮助他们选择最适合他们的发行版本,同时也会帮助他们安装一些适用于他们工作的开源软件。 + +但是,又一次,我就变得很无奈。我的叔叔,他是一个自由职业的会计师。他会有一系列的为了会计工作的付费软件。我就不那么确定,我能在在开软软件中找到这么一款可以替代的软件。直到昨天。 + +Abhishek 给我推荐了一些[很酷的软件][1],并且,GNU Khata 这个特殊的一款,脱颖而出。 + +[GNU Khata][2] 是一个会计工具。 或者,我可以说成是一系列的会计工具集合?这像经济管理方面的[Evernote][3]。他的应用是如此之广,以至于他可以处理个人的财务管理,到大型公司的管理,从店铺存货管理到税率计算,都可以有效处理。 + +对你来说一个有趣的点,'Khata' 在印度或者是其他的印度语国家中意味着账户,所以这个会计软件叫做 GNU Khata。 + +### 安装 + +互联网上有很多关于老旧版本的 Khata 安装的介绍。现在,GNU Khata 已经可以在 Debian/Ubuntu 和他们的衍生产中得到。我建议你按照如下 GNU Khata 官网的步骤来安装。我们来一次快速的入门。 + +- 从[这][4]下载安装器。 +- 在下载目录打开终端。 +- 粘贴复制以下的代码到终端,并且执行。 + +``` +sudo chmod 755 GNUKhatasetup.run +sudo ./GNUKhatasetup.run +``` + +- 这就结束了,从你的 Dash 或者是应用菜单中启动 GNU Khata 吧。 +### 第一次启动 + +GNU Khata 在浏览器中打开,并且展现以下的画面。 + +![](https://itsfoss.com/wp-content/uploads/2016/07/GNU-khata-1.jpg) + +填写组织的名字和组织形式,经济年份并且点击 proceed 按钮进入管理设置页面。 + +![](https://itsfoss.com/wp-content/uploads/2016/07/GNU-khata-2.jpg) + +仔细填写你的姓名,密码,安全问题和他的答案,并且点击“create and login”。 + +![](https://itsfoss.com/wp-content/uploads/2016/07/GNU-khata-3.jpg) + +你已经全部设置完成了。使用菜单栏来开始使用 GNU Khata 来管理你的经济吧。这很容易。 + +### GNU KHATA 真的是市面上付费会计应用的竞争对手吗? + +首先,GNU Khata 让所有的事情变得简单。顶部的菜单栏被方便的组织,可以帮助你有效的进行工作。 你可以选择管理不同的账户和项目,并且切换非常容易。[他们的官网][5]表明,GNU Khata 可以“方便的转变成印度语”。同时,你知道 GNU Khata 也可以在云端使用吗? + +所有的主流的账户管理工具,将账簿分类,项目介绍,法规介绍等等用专业的方式整理,并且支持自定义整理和实时显示。这让会计和进存储管理看起来如此的简单。 + +这个项目正在积极的发展,从实际的操作中提交反馈来帮助这个软件更加进步。考虑到软件的成熟性,使用的便利性还有免费的 tag。GNU Khata 可能会成为最好的账簿助手。 + +请在评论框里留言吧,让我们知道你是如何看待 GNU Khata 的。 + + + +-------------------------------------------------------------------------------- + +via: https://itsfoss.com/using-gnu-khata/?utm_source=feedburner&utm_medium=feed&utm_campaign=Feed%3A+ItsFoss+%28Its+FOSS%21+An+Open+Source+Blog%29 + +作者:[Aquil Roshan][a] +译者:[MikeCoder](https://github.com/MikeCoder) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]: https://itsfoss.com/author/aquil/ +[1]: https://itsfoss.com/category/apps/ +[2]: http://www.gnukhata.in/ +[3]: https://evernote.com/ +[4]: https://cloud.openmailbox.org/index.php/s/L8ppsxtsFq1345E/download +[5]: http://www.gnukhata.in/ From cfe454e814f9ca9d3e27151870871b5840e9b257 Mon Sep 17 00:00:00 2001 From: geekpi Date: Fri, 29 Jul 2016 19:11:15 +0800 Subject: [PATCH 065/122] translating --- ... Real Time Photo of Earth as Your Linux Desktop Wallpaper.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sources/tech/20160726 Set a Real Time Photo of Earth as Your Linux Desktop Wallpaper.md b/sources/tech/20160726 Set a Real Time Photo of Earth as Your Linux Desktop Wallpaper.md index 1fd552e70c..9c0f673900 100644 --- a/sources/tech/20160726 Set a Real Time Photo of Earth as Your Linux Desktop Wallpaper.md +++ b/sources/tech/20160726 Set a Real Time Photo of Earth as Your Linux Desktop Wallpaper.md @@ -1,3 +1,5 @@ +Translating---geekpi + Set a Real Time Photo of Earth as Your Linux Desktop Wallpaper ================================================================= From 6a44b74276c3da5d38d03d3265a919d6c9263537 Mon Sep 17 00:00:00 2001 From: geekpi Date: Fri, 29 Jul 2016 19:11:51 +0800 Subject: [PATCH 066/122] translating --- ...ions-to-speed-up-apt-get on Ubuntu Linux 16.04 LTS server.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sources/tech/20160727-How-to-use-multiple-connections-to-speed-up-apt-get on Ubuntu Linux 16.04 LTS server.md b/sources/tech/20160727-How-to-use-multiple-connections-to-speed-up-apt-get on Ubuntu Linux 16.04 LTS server.md index 460dabc03c..6803f2ec47 100644 --- a/sources/tech/20160727-How-to-use-multiple-connections-to-speed-up-apt-get on Ubuntu Linux 16.04 LTS server.md +++ b/sources/tech/20160727-How-to-use-multiple-connections-to-speed-up-apt-get on Ubuntu Linux 16.04 LTS server.md @@ -1,3 +1,5 @@ +translating---geekpi + How to use multiple connections to speed up apt-get/apt on Ubuntu Linux 16.04 LTS server ========================================================================================= From f8ad5216d1ca06009f04d4bf180a6ad9e127efc7 Mon Sep 17 00:00:00 2001 From: geekpi Date: Fri, 29 Jul 2016 20:45:47 +0800 Subject: [PATCH 067/122] translated --- ...f Earth as Your Linux Desktop Wallpaper.md | 40 ------------------- ...f Earth as Your Linux Desktop Wallpaper.md | 39 ++++++++++++++++++ 2 files changed, 39 insertions(+), 40 deletions(-) delete mode 100644 sources/tech/20160726 Set a Real Time Photo of Earth as Your Linux Desktop Wallpaper.md create mode 100644 translated/tech/20160726 Set a Real Time Photo of Earth as Your Linux Desktop Wallpaper.md diff --git a/sources/tech/20160726 Set a Real Time Photo of Earth as Your Linux Desktop Wallpaper.md b/sources/tech/20160726 Set a Real Time Photo of Earth as Your Linux Desktop Wallpaper.md deleted file mode 100644 index 9c0f673900..0000000000 --- a/sources/tech/20160726 Set a Real Time Photo of Earth as Your Linux Desktop Wallpaper.md +++ /dev/null @@ -1,40 +0,0 @@ -Translating---geekpi - -Set a Real Time Photo of Earth as Your Linux Desktop Wallpaper -================================================================= - -![](http://www.omgubuntu.co.uk/wp-content/uploads/2016/07/Screen-Shot-2016-07-26-at-16.36.47-1.jpg) - -Bored of looking at the same desktop background? Here’s something that’s (almost) out of this world. - -‘[Himawaripy][1]‘ is a small Python 3 script that fetches a near-real time picture of Earth taken by the [Japanese Himawari 8 weather satellite][2] and sets it as your desktop background. - -Once installed you can set the app to run as a cron job every 10 minutes (in the background, naturally) so that it can fetch and set a realtime picture of Earth as your desktop wallpaper. - -Because Himawari-8 is a geostationary satellite you’re only ever going to images of the earth as seen from above Australasia — but with real time weather patterns, cloud formations and lighting it’s still makes for spectacular scene, even if seeing things above the UK would be better for me! - -Advanced settings allow you to configure the quality of the images pulled from the satellite , but keep in mind that any increase in quality will result in an increased file size, and a longer download wait! - -Lastly, while this script is very similar to many others that we’ve covered over the years it is up-to-date and working. - -Get Himawaripy -Himawaripy has been tested on a range of desktop environments, including Unity, LXDE, i3, MATE and a host of other desktop environments. It is free, open-source software but is not entirely straightforward to set up and configure. - -Find all instructions on getting the app installed and set up (hint: there’s no one-click installer) on the project’s GitHub page. - -[Real time earth wallpaper script on GitHub][0] - --------------------------------------------------------------------------------- - -via: http://www.tecmint.com/mandatory-access-control-with-selinux-or-apparmor-linux/ - -作者:[ JOEY-ELIJAH SNEDDON][a] -译者:[译者ID](https://github.com/译者ID) -校对:[校对者ID](https://github.com/校对者ID) - -本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 - -[a]: https://plus.google.com/117485690627814051450/?rel=author -[1]: https://github.com/boramalper/himawaripy -[2]: https://en.wikipedia.org/wiki/Himawari_8 -[0]: https://github.com/boramalper/himawaripy diff --git a/translated/tech/20160726 Set a Real Time Photo of Earth as Your Linux Desktop Wallpaper.md b/translated/tech/20160726 Set a Real Time Photo of Earth as Your Linux Desktop Wallpaper.md new file mode 100644 index 0000000000..8dc73bf150 --- /dev/null +++ b/translated/tech/20160726 Set a Real Time Photo of Earth as Your Linux Desktop Wallpaper.md @@ -0,0 +1,39 @@ +为你的Linux桌面设置一张真实的地球照片 +================================================================= + +![](http://www.omgubuntu.co.uk/wp-content/uploads/2016/07/Screen-Shot-2016-07-26-at-16.36.47-1.jpg) + +厌倦了看同样的桌面背景了么?这里有一个几乎这世界上最好的东西。 + +‘[Himawaripy][1]‘是一个Python 3脚本,它会接近实时抓取由[日本Himawari 8气象卫星][2]拍摄的地球照片,并将它设置成你的桌面背景。 + +安装完成后,你可以将它设置成每10分钟运行的任务(自然地它是在后台运行),这样它就可以实时地取回地球的照片并设置成背景了。 + +因为Himawari-8是一颗同步轨道卫星,你只能看到澳大利亚上空的地球的图片-但是它实时的天气形态、云团和光线仍使它很壮丽,即使对我而言在看到英国上方的更好! + +高级设置允许你配置从卫星取回的图片质量,但是要记住增加图片质量会增加文件大小及更长的下载等待! + +最后,虽然这个脚本与其他我们提到过的其他类似,它还仍保持更新及可用。 + +获取Himawaripy + +Himawaripy已经在一系列的桌面环境中都测试过了,包括Unity、LXDE、i3、MATE和其他桌面环境。它是免费、开源软件但是并不能直接设置及配置。 + +在Github上查找获取安装的应用程序和设置的所有指令()提示:有没有一键安装)上。 + +[GitHub上的实时地球壁纸脚本][0] + +-------------------------------------------------------------------------------- + +via: http://www.tecmint.com/mandatory-access-control-with-selinux-or-apparmor-linux/ + +作者:[ JOEY-ELIJAH SNEDDON][a] +译者:[译者ID](https://github.com/译者ID) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]: https://plus.google.com/117485690627814051450/?rel=author +[1]: https://github.com/boramalper/himawaripy +[2]: https://en.wikipedia.org/wiki/Himawari_8 +[0]: https://github.com/boramalper/himawaripy From b2d8ab5f01db13d78b83987fe8fb9812692f652a Mon Sep 17 00:00:00 2001 From: wxy Date: Sat, 30 Jul 2016 00:03:05 +0800 Subject: [PATCH 068/122] PUB:20160628 How To Setup Open Source Discussion Platform Discourse On Ubuntu Linux 16.04 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @kokialoves 请注意标点符号。 --- ...latform Discourse On Ubuntu Linux 16.04.md | 101 ++++++++++++++++++ ...latform Discourse On Ubuntu Linux 16.04.md | 101 ------------------ 2 files changed, 101 insertions(+), 101 deletions(-) create mode 100644 published/20160628 How To Setup Open Source Discussion Platform Discourse On Ubuntu Linux 16.04.md delete mode 100644 translated/tech/20160628 How To Setup Open Source Discussion Platform Discourse On Ubuntu Linux 16.04.md diff --git a/published/20160628 How To Setup Open Source Discussion Platform Discourse On Ubuntu Linux 16.04.md b/published/20160628 How To Setup Open Source Discussion Platform Discourse On Ubuntu Linux 16.04.md new file mode 100644 index 0000000000..45c5d634dc --- /dev/null +++ b/published/20160628 How To Setup Open Source Discussion Platform Discourse On Ubuntu Linux 16.04.md @@ -0,0 +1,101 @@ +如何在 Ubuntu Linux 16.04上安装开源的 Discourse 论坛 +=============================================================================== + +Discourse 是一个开源的论坛,它可以以邮件列表、聊天室或者论坛等多种形式工作。它是一个广受欢迎的现代的论坛工具。在服务端,它使用 Ruby on Rails 和 Postgres 搭建, 并且使用 Redis 缓存来减少读取时间 , 在客户端,它使用支持 Java Script 的浏览器。它非常容易定制,结构良好,并且它提供了转换插件,可以对你现存的论坛、公告板进行转换,例如: vBulletin、phpBB、Drupal、SMF 等等。在这篇文章中,我们将学习在 Ubuntu 操作系统下安装 Discourse。 + +它以安全作为设计思想,所以发垃圾信息的人和黑客们不能轻易的实现其企图。它能很好的支持各种现代设备,并可以相应的调整以手机和平板的显示。 + +### 在 Ubuntu 16.04 上安装 Discourse + +让我们开始吧 ! 最少需要 1G 的内存,并且官方支持的安装过程需要已经安装了 docker。 说到 docker,它还需要安装Git。要满足以上的两点要求我们只需要运行下面的命令: + +``` +wget -qO- https://get.docker.com/ | sh +``` + +![](http://linuxpitstop.com/wp-content/uploads/2016/06/124.png) + +用不了多久就安装好了 docker 和 Git,安装结束以后,在你的系统上的 /var 分区创建一个 Discourse 文件夹(当然你也可以选择其他的分区)。 + +``` +mkdir /var/discourse +``` + +现在我们来克隆 Discourse 的 Github 仓库到这个新建的文件夹。 + +``` +git clone https://github.com/discourse/discourse_docker.git /var/discourse +``` + +进入这个克隆的文件夹。 + +``` +cd /var/discourse +``` + +![](http://linuxpitstop.com/wp-content/uploads/2016/06/314.png) + +你将看到“discourse-setup” 脚本文件,运行这个脚本文件进行 Discourse 的初始化。 + +``` +./discourse-setup +``` + +**备注: 在安装 discourse 之前请确保你已经安装好了邮件服务器。** + +安装向导将会问你以下六个问题: + +``` +Hostname for your Discourse? +Email address for admin account? +SMTP server address? +SMTP user name? +SMTP port [587]: +SMTP password? []: +``` + +![](http://linuxpitstop.com/wp-content/uploads/2016/06/411.png) + +当你提交了以上信息以后, 它会让你提交确认, 如果一切都很正常,点击回车以后安装开始。 + +![](http://linuxpitstop.com/wp-content/uploads/2016/06/511.png) + +现在“坐等放宽”,需要花费一些时间来完成安装,倒杯咖啡,看看有什么错误信息没有。 + +![](http://linuxpitstop.com/wp-content/uploads/2016/06/610.png) + +安装成功以后看起来应该像这样。 + +![](http://linuxpitstop.com/wp-content/uploads/2016/06/710.png) + +现在打开浏览器,如果已经做了域名解析,你可以使用你的域名来连接 Discourse 页面 ,否则你只能使用IP地址了。你将看到如下信息: + +![](http://linuxpitstop.com/wp-content/uploads/2016/06/85.png) + +就是这个,点击 “Sign Up” 选项创建一个新的账户,然后进行你的 Discourse 设置。 + +![](http://linuxpitstop.com/wp-content/uploads/2016/06/106.png) + +### 结论 + +它安装简便,运行完美。 它拥有现代论坛所有必备功能。它以 GPL 发布,是完全开源的产品。简单、易用、以及特性丰富是它的最大特点。希望你喜欢这篇文章,如果有问题,你可以给我们留言。 + +-------------------------------------------------------------------------------- + +via: http://linuxpitstop.com/install-discourse-on-ubuntu-linux-16-04/ + +作者:[Aun][a] +译者:[kokialoves](https://github.com/kokialoves) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]: http://linuxpitstop.com/author/aun/ + + + + + + + + diff --git a/translated/tech/20160628 How To Setup Open Source Discussion Platform Discourse On Ubuntu Linux 16.04.md b/translated/tech/20160628 How To Setup Open Source Discussion Platform Discourse On Ubuntu Linux 16.04.md deleted file mode 100644 index 742fd381dd..0000000000 --- a/translated/tech/20160628 How To Setup Open Source Discussion Platform Discourse On Ubuntu Linux 16.04.md +++ /dev/null @@ -1,101 +0,0 @@ -如何在 Ubuntu Linux 16.04上安装开源的Discourse论坛 -=============================================================================== - -Discourse 是一个开源的论坛, 它可以以邮件列表, 聊天室或者论坛等多种形式工作. 它是一个广受欢迎的现代的论坛工具. 在服务端,它使用Ruby on Rails 和 Postgres 搭建, 并且使用Redis caching 减少读取时间 , 在客户端, 它用浏览器的Java Script运行. 它是一个非常好的定制和构架工具. 并且它提供了转换插件对你现存的论坛进行转换例如: vBulletin, phpBB, Drupal, SMF 等等. 在这篇文章中, 我们将学习在Ubuntu操作系统下安装 Discourse. - -它是基于安全开发的, 黑客们不能轻易的发现漏洞. 它能很好的支持各个平台, 相应的调整手机和平板的显示设置. - -### Installing Discourse on Ubuntu 16.04 - -让我们开始吧 ! 最少需要1G的内存并且你要保证dockers已经安装了. 说到dockers, 它还需要安装Git. 要达到以上的两点要求我们只需要运行下面的命令. - -``` -wget -qO- https://get.docker.com/ | sh -``` - -![](http://linuxpitstop.com/wp-content/uploads/2016/06/124.png) - -用不了多久就安装好了Docker 和 Git, 安装结束以后, 创建一个 Discourse 文件夹在 /var 分区 (当然你也可以选择其他的分区). - -``` -mkdir /var/discourse -``` - -现在我们来克隆 Discourse’s Github 项目到这个新建的文件夹. - -``` -git clone https://github.com/discourse/discourse_docker.git /var/discourse -``` - -进入克隆文件夹. - -``` -cd /var/discourse -``` - -![](http://linuxpitstop.com/wp-content/uploads/2016/06/314.png) - -你将 看到“discourse-setup” 脚本文件, 运行这个脚本文件进行Discourse的初始化. - -``` -./discourse-setup -``` - -**Side note: 在安装discourse之前请确保你已经安装了邮件服务器.** - -安装向导将会问你以下六个问题. - -``` -Hostname for your Discourse? -Email address for admin account? -SMTP server address? -SMTP user name? -SMTP port [587]: -SMTP password? []: -``` - -![](http://linuxpitstop.com/wp-content/uploads/2016/06/411.png) - -当你提交了以上信息以后, 它会让你提交确认, 恩一切都很正常, 点击回车以后安装开始. - -![](http://linuxpitstop.com/wp-content/uploads/2016/06/511.png) - -现在坐下来,倒杯茶,看看有什么错误信息没有. - -![](http://linuxpitstop.com/wp-content/uploads/2016/06/610.png) - -安装成功以后看起来应该像这样. - -![](http://linuxpitstop.com/wp-content/uploads/2016/06/710.png) - -现在打开浏览器, 如果已经做了域名解析, 你可以使用你的域名来连接Discourse页面 , 否则你只能使用IP地址了. 你讲看到如下信息: - -![](http://linuxpitstop.com/wp-content/uploads/2016/06/85.png) - -就是这个, 用 “Sign Up” 选项创建一个新管理账户. - -![](http://linuxpitstop.com/wp-content/uploads/2016/06/106.png) - -### 结论 - -它是安装简便安全易用的. 它拥有当前所有论坛功能. 它支持所有的开源产品. 简单, 易用, 各类实用的功能. 希望你喜欢这篇文章你可以给我们留言. - --------------------------------------------------------------------------------- - -via: http://linuxpitstop.com/install-discourse-on-ubuntu-linux-16-04/ - -作者:[Aun][a] -译者:[kokialoves](https://github.com/kokialoves) -校对:[校对者ID](https://github.com/校对者ID) - -本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 - -[a]: http://linuxpitstop.com/author/aun/ - - - - - - - - From 8c8bba067989fd9c536a9aaf7bc118f3bc1c2033 Mon Sep 17 00:00:00 2001 From: geekpi Date: Sat, 30 Jul 2016 06:32:57 +0800 Subject: [PATCH 069/122] translated --- ...f Earth as Your Linux Desktop Wallpaper.md | 2 +- ...pt-get on Ubuntu Linux 16.04 LTS server.md | 74 +++++++++---------- 2 files changed, 37 insertions(+), 39 deletions(-) rename {sources => translated}/tech/20160727-How-to-use-multiple-connections-to-speed-up-apt-get on Ubuntu Linux 16.04 LTS server.md (64%) diff --git a/translated/tech/20160726 Set a Real Time Photo of Earth as Your Linux Desktop Wallpaper.md b/translated/tech/20160726 Set a Real Time Photo of Earth as Your Linux Desktop Wallpaper.md index 8dc73bf150..d05fd97eb2 100644 --- a/translated/tech/20160726 Set a Real Time Photo of Earth as Your Linux Desktop Wallpaper.md +++ b/translated/tech/20160726 Set a Real Time Photo of Earth as Your Linux Desktop Wallpaper.md @@ -28,7 +28,7 @@ Himawaripy已经在一系列的桌面环境中都测试过了,包括Unity、LX via: http://www.tecmint.com/mandatory-access-control-with-selinux-or-apparmor-linux/ 作者:[ JOEY-ELIJAH SNEDDON][a] -译者:[译者ID](https://github.com/译者ID) +译者:[geekpi](https://github.com/geekpi) 校对:[校对者ID](https://github.com/校对者ID) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 diff --git a/sources/tech/20160727-How-to-use-multiple-connections-to-speed-up-apt-get on Ubuntu Linux 16.04 LTS server.md b/translated/tech/20160727-How-to-use-multiple-connections-to-speed-up-apt-get on Ubuntu Linux 16.04 LTS server.md similarity index 64% rename from sources/tech/20160727-How-to-use-multiple-connections-to-speed-up-apt-get on Ubuntu Linux 16.04 LTS server.md rename to translated/tech/20160727-How-to-use-multiple-connections-to-speed-up-apt-get on Ubuntu Linux 16.04 LTS server.md index 6803f2ec47..4824bd7f7d 100644 --- a/sources/tech/20160727-How-to-use-multiple-connections-to-speed-up-apt-get on Ubuntu Linux 16.04 LTS server.md +++ b/translated/tech/20160727-How-to-use-multiple-connections-to-speed-up-apt-get on Ubuntu Linux 16.04 LTS server.md @@ -1,31 +1,29 @@ -translating---geekpi - -How to use multiple connections to speed up apt-get/apt on Ubuntu Linux 16.04 LTS server +如何在Ubuntu Linux 16.04 LTS中使用多条连接加速apt-get/apt ========================================================================================= -ow do I speed up my apt-get or apt command to download packages from multiple repos on a Ubuntu Linux 16.04 or 14.04 LTS server? +我该如何在Ubuntu Linux 16.04或者14.04 LTS中从多个仓库中下载包来加速apt-get或者apt命令? -You need to use apt-fast shell script wrapper. It should speed up apt-get command/apt command and aptitude command by downloading packages with multiple connections per package. All packages are downloaded simultaneously in parallel. It uses aria2c as default download accelerator. +你需要使用到apt-fast这个脚本。它会通过多个连接同时下载一个包来加速apt-get/apt和aptitude命令。所有的包都会同时下载。它使用aria2c作为默认的下载加速。 -### Install apt-fast tool +### 安装 apt-fast 工具 -Type the following command on Ubuntu Linux 14.04 and later versions: +在Ubuntu Linux 14.04或者之后的版本尝试下面的命令: ``` $ sudo add-apt-repository ppa:saiarcot895/myppa ``` -Sample outputs: +示例输出: ![](http://s0.cyberciti.org/uploads/faq/2016/07/install-apt-fast-repo.jpg) -Update your repo: +更新你的仓库: ``` $ sudo apt-get update ``` -OR +或者 ``` $ sudo apt update @@ -33,19 +31,19 @@ $ sudo apt update ![](http://s0.cyberciti.org/uploads/faq/2016/07/install-apt-fast-command.jpg) -Install apt-fast shell wrapper: +安装 apt-fast: ``` $ sudo apt-get -y install apt-fast ``` -OR +或者 ``` $ sudo apt -y install apt-fast ``` -Sample outputs: +示例输出: ``` @@ -69,122 +67,122 @@ Get:4 http://01.archive.ubuntu.com/ubuntu xenial/universe amd64 aria2 amd64 1.19 54% [4 aria2 486 kB/1,143 kB 42%] 20.4 kB/s 32s ``` -### Configure apt-fast +### 配置 apt-fast -You will be prompted as follows (a value between 5 and 16 must be entered): +你将会得到下面的提示(必须输入一个5到16的数值): ![](http://s0.cyberciti.org/uploads/faq/2016/07/max-connection-10.jpg) -And: +并且 ![](http://s0.cyberciti.org/uploads/faq/2016/07/apt-fast-confirmation-box.jpg) -You can edit settings directly too: +你可以直接编辑设置: ``` $ sudo vi /etc/apt-fast.conf ``` ->**Please note that this tool is not for slow network connections; it is for fast network connections. If you have a slow connection to the Internet, you are not going to benefit by this tool.** +>**请注意这个工具并不是给慢速网络连接的,它是给快速网络连接的。如果你的网速慢,那么你将无法从这个工具中得到好处。** -### How do I use apt-fast command? +### 我该怎么使用 apt-fast 命令? -The syntax is: +语法是: ``` apt-fast command apt-fast [options] command ``` -#### To retrieve new lists of packages using apt-fast +#### 使用apt-fast取回新的包列表 ``` sudo apt-fast update ``` -#### To perform an upgrade using apt-fast +#### 使用apt-fast执行升级 ``` sudo apt-fast upgrade ``` -#### To perform distribution upgrade (release or force kernel upgrade), enter: +#### 执行发行版升级(发布或者强制内核升级),输入: ``` $ sudo apt-fast dist-upgrade ``` -#### To install new packages +#### 安装新的包 -The syntax is: +语法是: ``` sudo apt-fast install pkg ``` -For example, install nginx package, enter: +比如要安装nginx,输入: ``` $ sudo apt-fast install nginx ``` -Sample outputs: +示例输出: ![](http://s0.cyberciti.org/uploads/faq/2016/07/sudo-apt-fast-install.jpg) -#### To remove packages +#### 删除包 ``` $ sudo apt-fast remove pkg $ sudo apt-fast remove nginx ``` -#### To remove packages and its config files too +#### 删除包和它的配置文件 ``` $ sudo apt-fast purge pkg $ sudo apt-fast purge nginx ``` -#### To remove automatically all unused packages, enter: +#### 删除所有未使用的包 ``` $ sudo apt-fast autoremove ``` -#### To Download source archives +#### 下载源码包 ``` $ sudo apt-fast source pkgNameHere ``` -#### To erase downloaded archive files +#### 清理下载的文件 ``` $ sudo apt-fast clean ``` -#### To erase old downloaded archive files +#### 清理旧的下载文件 ``` $ sudo apt-fast autoclean ``` -#### To verify that there are no broken dependencies +#### 验证没有破坏的依赖 ``` $ sudo apt-fast check ``` -#### To download the binary package into the current directory +#### 下载二进制包到当前目录 ``` $ sudo apt-fast download pkgNameHere $ sudo apt-fast download nginx ``` -Sample outputs: +示例输出: ``` [#7bee0c 0B/0B CN:1 DL:0B] @@ -198,7 +196,7 @@ Status Legend: (OK):download completed. ``` -#### To download and display the changelog for the given package +#### 下载并显示指定包的changelog ``` $ sudo apt-fast changelog pkgNameHere @@ -212,7 +210,7 @@ $ sudo apt-fast changelog nginx via: https://fedoramagazine.org/introducing-flatpak/ 作者:[VIVEK GITE][a] -译者:[zky001](https://github.com/zky001) +译者:[geekpi](https://github.com/geekpi) 校对:[校对者ID](https://github.com/校对者ID) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 From 59a3e3f759a1d8a72857f77c2600391f290ba036 Mon Sep 17 00:00:00 2001 From: geekpi Date: Sat, 30 Jul 2016 06:41:09 +0800 Subject: [PATCH 070/122] Update 20160727-How-to-use-multiple-connections-to-speed-up-apt-get on Ubuntu Linux 16.04 LTS server.md --- ...ions-to-speed-up-apt-get on Ubuntu Linux 16.04 LTS server.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/translated/tech/20160727-How-to-use-multiple-connections-to-speed-up-apt-get on Ubuntu Linux 16.04 LTS server.md b/translated/tech/20160727-How-to-use-multiple-connections-to-speed-up-apt-get on Ubuntu Linux 16.04 LTS server.md index 4824bd7f7d..e36813cdc9 100644 --- a/translated/tech/20160727-How-to-use-multiple-connections-to-speed-up-apt-get on Ubuntu Linux 16.04 LTS server.md +++ b/translated/tech/20160727-How-to-use-multiple-connections-to-speed-up-apt-get on Ubuntu Linux 16.04 LTS server.md @@ -3,7 +3,7 @@ 我该如何在Ubuntu Linux 16.04或者14.04 LTS中从多个仓库中下载包来加速apt-get或者apt命令? -你需要使用到apt-fast这个脚本。它会通过多个连接同时下载一个包来加速apt-get/apt和aptitude命令。所有的包都会同时下载。它使用aria2c作为默认的下载加速。 +你需要使用到apt-fast这个shell封装器。它会通过多个连接同时下载一个包来加速apt-get/apt和aptitude命令。所有的包都会同时下载。它使用aria2c作为默认的下载加速。 ### 安装 apt-fast 工具 From 89dd3858da807582e575a98b2c97759976278ee2 Mon Sep 17 00:00:00 2001 From: Christopher L Date: Sat, 30 Jul 2016 16:02:11 +0800 Subject: [PATCH 071/122] =?UTF-8?q?=E7=94=B3=E8=AF=B7=E7=BF=BB=E8=AF=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sources/tech/20160722 Keeweb A Linux Password Manager.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sources/tech/20160722 Keeweb A Linux Password Manager.md b/sources/tech/20160722 Keeweb A Linux Password Manager.md index b829ea107e..b55de2a4cb 100644 --- a/sources/tech/20160722 Keeweb A Linux Password Manager.md +++ b/sources/tech/20160722 Keeweb A Linux Password Manager.md @@ -1,3 +1,5 @@ +Being translated by ChrisLeeGit + Keeweb A Linux Password Manager ================================ @@ -52,7 +54,7 @@ I have already posted about two other Linux password managers, Keepass and Encry via: http://www.tecmint.com/mandatory-access-control-with-selinux-or-apparmor-linux/ 作者:[author][a] -译者:[译者ID](https://github.com/译者ID) +译者:[ChrisLeeGit](https://github.com/chrisleegit) 校对:[校对者ID](https://github.com/校对者ID) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 From e0a9969aac1cd53e6b47fef5fa67f0f4ae8e92ac Mon Sep 17 00:00:00 2001 From: cposture Date: Sat, 30 Jul 2016 22:09:51 +0800 Subject: [PATCH 072/122] Translating 20%: --- ...18 An Introduction to Mocking in Python.md | 138 +++++++++--------- 1 file changed, 67 insertions(+), 71 deletions(-) diff --git a/sources/tech/20160618 An Introduction to Mocking in Python.md b/sources/tech/20160618 An Introduction to Mocking in Python.md index 182f596431..9c6c912b60 100644 --- a/sources/tech/20160618 An Introduction to Mocking in Python.md +++ b/sources/tech/20160618 An Introduction to Mocking in Python.md @@ -1,34 +1,36 @@ -Translating by cposture 2016-07-29 -An Introduction to Mocking in Python +Mock 在 Python 中的使用介绍 ===================================== +http://www.oschina.net/translate/an-introduction-to-mocking-in-python?cmp +本文讲述的是 Python 中 Mock 的使用 -This article is about mocking in python, +**如何在避免测试你的耐心的情景下执行单元测试** -**How to Run Unit Tests Without Testing Your Patience** +通常,我们编写的软件会直接与我们称之为肮脏无比的服务交互。用外行人的话说:交互已设计好的服务对我们的应用程序很重要,但是这会带来我们不希望的副作用,也就是那些在我们自己测试的时候不希望的功能。例如:我们正在写一个社交 app,并且想要测试一下我们 "发布到 Facebook" 的新功能,但是不想每次运行测试集的时候真的发布到 Facebook。 -More often than not, the software we write directly interacts with what we would label as “dirty” services. In layman’s terms: services that are crucial to our application, but whose interactions have intended but undesired side-effects—that is, undesired in the context of an autonomous test run.For example: perhaps we’re writing a social app and want to test out our new ‘Post to Facebook feature’, but don’t want to actually post to Facebook every time we run our test suite. -The Python unittest library includes a subpackage named unittest.mock—or if you declare it as a dependency, simply mock—which provides extremely powerful and useful means by which to mock and stub out these undesired side-effects. +Python 的单元测试库包含了一个名为 unittest.mock 或者可以称之为依赖的子包,简言之为 mock——其提供了极其强大和有用的方法,通过它们可以模拟和打桩我们不希望的副作用。 + >Source | -Note: mock is [newly included][1] in the standard library as of Python 3.3; prior distributions will have to use the Mock library downloadable via [PyPI][2]. +注意:mock [最近收录][1]到了 Python 3.3 的标准库中;先前发布的版本必须通过 [PyPI][2] 下载 Mock 库。 +### ### Fear System Calls -To give you another example, and one that we’ll run with for the rest of the article, consider system calls. It’s not difficult to see that these are prime candidates for mocking: whether you’re writing a script to eject a CD drive, a web server which removes antiquated cache files from /tmp, or a socket server which binds to a TCP port, these calls all feature undesired side-effects in the context of your unit-tests. +再举另一个例子,思考一个我们会在余文讨论的系统调用。不难发现,这些系统调用都是主要的模拟对象:无论你是正在写一个可以弹出 CD 驱动的脚本,还是一个用来删除 /tmp 下过期的缓存文件的 Web 服务,这些调用都是在你的单元测试上下文中不希望的副作用。 ->As a developer, you care more that your library successfully called the system function for ejecting a CD as opposed to experiencing your CD tray open every time a test is run. +> 作为一个开发者,你需要更关心你的库是否成功地调用了一个可以弹出 CD 的系统函数,而不是切身经历 CD 托盘每次在测试执行的时候都打开了。 -As a developer, you care more that your library successfully called the system function for ejecting a CD (with the correct arguments, etc.) as opposed to actually experiencing your CD tray open every time a test is run. (Or worse, multiple times, as multiple tests reference the eject code during a single unit-test run!) +作为一个开发者,你需要更关心你的库是否成功地调用了一个可以弹出 CD 的系统函数(使用了正确的参数等等),而不是切身经历 CD 托盘每次在测试执行的时候都打开了。(或者更糟糕的是,很多次,在一个单元测试运行期间多个测试都引用了弹出代码!) -Likewise, keeping your unit-tests efficient and performant means keeping as much “slow code” out of the automated test runs, namely filesystem and network access. +同样,保持你的单元测试的效率和性能意味着需要让如此多的 "缓慢代码" 远离自动测试,比如文件系统和网络访问。 -For our first example, we’ll refactor a standard Python test case from original form to one using mock. We’ll demonstrate how writing a test case with mocks will make our tests smarter, faster, and able to reveal more about how the software works. +对于我们首个例子,我们要从原始形式到使用 mock 地重构一个标准 Python 测试用例。我们会演示如何使用 mock 写一个测试用例使我们的测试更加智能、快速,并且能展示更多关于我们软件的工作原理。 -### A Simple Delete Function +### 一个简单的删除函数 -We all need to delete files from our filesystem from time to time, so let’s write a function in Python which will make it a bit easier for our scripts to do so. +有时,我们都需要从文件系统中删除文件,因此,让我们在 Python 中写一个可以使我们的脚本更加轻易完成此功能的函数。 ``` #!/usr/bin/env python @@ -40,9 +42,9 @@ def rm(filename): os.remove(filename) ``` -Obviously, our rm method at this point in time doesn’t provide much more than the underlying os.remove method, but our codebase will improve, allowing us to add more functionality here. +很明显,我们的 rm 方法此时无法提供比相关 os.remove 方法更多的功能,但我们的基础代码会逐步改善,允许我们在这里添加更多的功能。 -Let’s write a traditional test case, i.e., without mocks: +让我们写一个传统的测试用例,即,没有使用 mock: ``` #!/usr/bin/env python @@ -61,7 +63,7 @@ class RmTestCase(unittest.TestCase): def setUp(self): with open(self.tmpfilepath, "wb") as f: f.write("Delete me!") - + def test_rm(self): # remove the file rm(self.tmpfilepath) @@ -69,9 +71,11 @@ class RmTestCase(unittest.TestCase): self.assertFalse(os.path.isfile(self.tmpfilepath), "Failed to remove the file.") ``` -Our test case is pretty simple, but every time it is run, a temporary file is created and then deleted. Additionally, we have no way of testing whether our rm method properly passes the argument down to the os.remove call. We can assume that it does based on the test above, but much is left to be desired. +我们的测试用例相当简单,但是当它每次运行的时候,它都会创建一个临时文件并且随后删除。此外,我们没有办法测试我们的 rm 方法是否正确地将我们的参数向下传递给 os.remove 调用。我们可以基于以上的测试认为它做到了,但还有很多需要改进的地方。 -Refactoring with MocksLet’s refactor our test case using mock: +### 使用 Mock 重构 + +让我们使用 mock 重构我们的测试用例: ``` #!/usr/bin/env python @@ -83,7 +87,7 @@ import mock import unittest class RmTestCase(unittest.TestCase): - + @mock.patch('mymodule.os') def test_rm(self, mock_os): rm("any path") @@ -91,10 +95,11 @@ class RmTestCase(unittest.TestCase): mock_os.remove.assert_called_with("any path") ``` -With these refactors, we have fundamentally changed the way that the test operates. Now, we have an insider, an object we can use to verify the functionality of another. +使用这些重构,我们从根本上改变了该测试用例的运行方式。现在,我们有一个可以用于验证其他功能的内部对象。 -### Potential Pitfalls +### 潜在陷阱 +第一件需要注意的事情就是,我们使用了用于模拟 mock.patch 方法的装饰器位于mymodule.os One of the first things that should stick out is that we’re using the mock.patch method decorator to mock an object located at mymodule.os, and injecting that mock into our test case method. Wouldn’t it make more sense to just mock os itself, rather than the reference to it at mymodule.os? Well, Python is somewhat of a sneaky snake when it comes to imports and managing modules. At runtime, the mymodule module has its own os which is imported into its own local scope in the module. Thus, if we mock os, we won’t see the effects of the mock in the mymodule module. @@ -135,23 +140,23 @@ import mock import unittest class RmTestCase(unittest.TestCase): - + @mock.patch('mymodule.os.path') @mock.patch('mymodule.os') def test_rm(self, mock_os, mock_path): # set up the mock mock_path.isfile.return_value = False - + rm("any path") - + # test that the remove call was NOT called. self.assertFalse(mock_os.remove.called, "Failed to not remove the file if not present.") - + # make the file 'exist' mock_path.isfile.return_value = True - + rm("any path") - + mock_os.remove.assert_called_with("any path") ``` @@ -190,26 +195,26 @@ import mock import unittest class RemovalServiceTestCase(unittest.TestCase): - + @mock.patch('mymodule.os.path') @mock.patch('mymodule.os') def test_rm(self, mock_os, mock_path): # instantiate our service reference = RemovalService() - + # set up the mock mock_path.isfile.return_value = False - + reference.rm("any path") - + # test that the remove call was NOT called. self.assertFalse(mock_os.remove.called, "Failed to not remove the file if not present.") - + # make the file 'exist' mock_path.isfile.return_value = True - + reference.rm("any path") - + mock_os.remove.assert_called_with("any path") ``` @@ -228,13 +233,13 @@ class RemovalService(object): def rm(self, filename): if os.path.isfile(filename): os.remove(filename) - + class UploadService(object): def __init__(self, removal_service): self.removal_service = removal_service - + def upload_complete(self, filename): self.removal_service.rm(filename) ``` @@ -262,29 +267,29 @@ import mock import unittest class RemovalServiceTestCase(unittest.TestCase): - + @mock.patch('mymodule.os.path') @mock.patch('mymodule.os') def test_rm(self, mock_os, mock_path): # instantiate our service reference = RemovalService() - + # set up the mock mock_path.isfile.return_value = False - + reference.rm("any path") - + # test that the remove call was NOT called. self.assertFalse(mock_os.remove.called, "Failed to not remove the file if not present.") - + # make the file 'exist' mock_path.isfile.return_value = True - + reference.rm("any path") - + mock_os.remove.assert_called_with("any path") - - + + class UploadServiceTestCase(unittest.TestCase): @mock.patch.object(RemovalService, 'rm') @@ -292,13 +297,13 @@ class UploadServiceTestCase(unittest.TestCase): # build our dependencies removal_service = RemovalService() reference = UploadService(removal_service) - + # call upload_complete, which should, in turn, call `rm`: reference.upload_complete("my uploaded file") - + # check that it called the rm method of any RemovalService mock_rm.assert_called_with("my uploaded file") - + # check that it called the rm method of _our_ removal_service removal_service.rm.assert_called_with("my uploaded file") ``` @@ -339,39 +344,39 @@ import mock import unittest class RemovalServiceTestCase(unittest.TestCase): - + @mock.patch('mymodule.os.path') @mock.patch('mymodule.os') def test_rm(self, mock_os, mock_path): # instantiate our service reference = RemovalService() - + # set up the mock mock_path.isfile.return_value = False - + reference.rm("any path") - + # test that the remove call was NOT called. self.assertFalse(mock_os.remove.called, "Failed to not remove the file if not present.") - + # make the file 'exist' mock_path.isfile.return_value = True - + reference.rm("any path") - + mock_os.remove.assert_called_with("any path") - - + + class UploadServiceTestCase(unittest.TestCase): def test_upload_complete(self, mock_rm): # build our dependencies mock_removal_service = mock.create_autospec(RemovalService) reference = UploadService(mock_removal_service) - + # call upload_complete, which should, in turn, call `rm`: reference.upload_complete("my uploaded file") - + # test that it called the rm method mock_removal_service.rm.assert_called_with("my uploaded file") ``` @@ -427,7 +432,7 @@ To finish up, let’s write a more applicable real-world example, one which we m import facebook class SimpleFacebook(object): - + def __init__(self, oauth_token): self.graph = facebook.GraphAPI(oauth_token) @@ -445,7 +450,7 @@ import mock import unittest class SimpleFacebookTestCase(unittest.TestCase): - + @mock.patch.object(facebook.GraphAPI, 'put_object', autospec=True) def test_post_message(self, mock_put_object): sf = simple_facebook.SimpleFacebook("fake oauth token") @@ -480,12 +485,3 @@ via: http://slviki.com/index.php/2016/06/18/introduction-to-mocking-in-python/ [6]: http://www.voidspace.org.uk/python/mock/mock.html [7]: http://www.toptal.com/qa/how-to-write-testable-code-and-why-it-matters [8]: http://www.toptal.com/python - - - - - - - - - From 9f91c8b545c4e0d0f3d9080e8ecbcb1fe4b35167 Mon Sep 17 00:00:00 2001 From: cposture Date: Sat, 30 Jul 2016 23:38:30 +0800 Subject: [PATCH 073/122] Translating 21% --- .../tech/20160618 An Introduction to Mocking in Python.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/sources/tech/20160618 An Introduction to Mocking in Python.md b/sources/tech/20160618 An Introduction to Mocking in Python.md index 9c6c912b60..64c26b8ec5 100644 --- a/sources/tech/20160618 An Introduction to Mocking in Python.md +++ b/sources/tech/20160618 An Introduction to Mocking in Python.md @@ -99,15 +99,19 @@ class RmTestCase(unittest.TestCase): ### 潜在陷阱 -第一件需要注意的事情就是,我们使用了用于模拟 mock.patch 方法的装饰器位于mymodule.os +第一件需要注意的事情就是,我们使用了位于 mymodule.os 且用于模拟对象的 mock.patch 方法装饰器,并且将该 mock 注入到我们的测试用例方法。相比在 mymodule.os 引用它,那么只是模拟 os 本身,会不会更有意义? One of the first things that should stick out is that we’re using the mock.patch method decorator to mock an object located at mymodule.os, and injecting that mock into our test case method. Wouldn’t it make more sense to just mock os itself, rather than the reference to it at mymodule.os? +当然,当涉及到导入和管理模块,Python 的用法非常灵活。在运行时,mymodule 模块拥有被导入到本模块局部作用域的 os。因此,如果我们模拟 os,我们是看不到模拟在 mymodule 模块中的作用的。 Well, Python is somewhat of a sneaky snake when it comes to imports and managing modules. At runtime, the mymodule module has its own os which is imported into its own local scope in the module. Thus, if we mock os, we won’t see the effects of the mock in the mymodule module. +这句话需要深刻地记住: The mantra to keep repeating is this: +> 模拟测试一个项目,只需要了解它用在哪里,而不是它从哪里来。 > Mock an item where it is used, not where it came from. + If you need to mock the tempfile module for myproject.app.MyElaborateClass, you probably need to apply the mock to myproject.app.tempfile, as each module keeps its own imports. With that pitfall out of the way, let’s keep mocking. From a236f0fac4ec7d07f9c3bc8924f96e5039d5082b Mon Sep 17 00:00:00 2001 From: maywanting Date: Sun, 31 Jul 2016 00:11:26 +0800 Subject: [PATCH 074/122] finish the translation of 20160721 5 tricks for getting started with Vim.md --- ...1 5 tricks for getting started with Vim.md | 60 +++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 translated/tech/20160721 5 tricks for getting started with Vim.md diff --git a/translated/tech/20160721 5 tricks for getting started with Vim.md b/translated/tech/20160721 5 tricks for getting started with Vim.md new file mode 100644 index 0000000000..7e9808d6d0 --- /dev/null +++ b/translated/tech/20160721 5 tricks for getting started with Vim.md @@ -0,0 +1,60 @@ +Vim 学习的 5 个技巧 +===================================== + +![](https://opensource.com/sites/default/files/styles/image-full-size/public/images/education/BUSINESS_peloton.png?itok=nuMbW9d3) + +多年来,我一直想学 Vim 。如今 Vim 是我最喜欢的 Linux 文本编辑器,也是开发者和系统管理者最喜爱的开源工具。我说的学习,指的是真正意义上的学习。想要精通确实很难,所以我只想要达到熟练的水平。根据我多年使用 Linux 的经验,我会的也仅仅只是打开一个文件,使用上下左右箭头按键来移动光标,切换到 insert 模式,更改一些文本,保存,然后退出。 + +但那只是 Vim 的最基本操作。我可以在终端修改文本文档,但是无法使用任何一个我想象中强大的文本处理功能。这样我无法说明 Vim 完全优于 Pico 和 Nano 。 + +所以到底为什么要学习 Vim ?因为我需要花费相当多的时间用于编辑文本,而且有很大的效率提升空间。为什么不选择 Emacs ,或者是更为现代化的编辑器例如 Atom ?因为 Vim 适合我,至少我有一丁点的使用经验。而且,很重要的一点就是,在我需要处理的系统上很少碰见没有装 Vim 或者它的简化版(Vi)。如果你有强烈的欲望想学习 Emacs ,我希望这些对于 Emacs 同类编辑器的建议能对你有所帮助。 + +花了几周的时间专注提高我的 Vim 使用技巧之后,我想分享的第一个建议就是必须使用工具。虽然这看起来就是明知故问的回答,但事实上比我所想的在代码层面上还要困难。我的大多数工作是在网页浏览器上进行的,而且我每次都得有针对性的用 Gedit 打开并修改一段浏览器之外的文本。Gedit 需要快捷键来启动,所以第一步就是移出快捷键然后替换成 Vim 的快捷键。 + +为了跟更好的学习 Vim ,我尝试了很多。如果你也正想学习,以下列举了一些作为推荐。 + +### Vimtutor + +通常如何开始学习最好就是使用应用本身。我找到一个小的应用叫 Vimtutor ,当你在学习编辑一个文本时它能辅导你一些基础知识,它向我展示了很多我这些年都忽视的基础命令。Vimtutor 上到处都是 Vim 影子,如果你的系统上没有 Vim ,Vimtutor可以很容易从你的包管理器上下载。 + +### GVim + +我知道并不是每个人都看好这个,但就是它让我从使用在终端的 Vim 转战到使用 GVim 来满足我基本编辑需求。反对者表示 GVim 鼓励使用鼠标,而 Vim 主要是为键盘党设计的。但是我能通过 GVim 的下拉菜单快速找到想找的指令,并且 GVim 可以提醒我正确的指令然后通过敲键盘执行它。努力学习一个新的编辑器然后陷入无法解决的困境,这种感觉并不好受。每隔几分钟读一下 man 出来的文字或者使用搜索引擎来提醒你指令也并不是最好的学习新事务的方法。 + +### Keyboard maps + +当我转战 GVim ,我发现有一个键盘的“作弊表”来提醒我最基础的按键很是便利。网上有很多这种可用的表,你可以下载,打印,然后贴在你身边的某一处地方。但是为了我的笔记本键盘,我选择买一沓便签纸。这些便签纸在美国不到10美元,而且当我使用键盘编辑文本尝试新的命令的时候,可以随时提醒我。 + +### Vimium + +上文提到,我工作都在浏览器上进行。其中一条我觉得很有帮助的建议就是,使用 [Vimium](1)来用增强使用 Vim 的体验。Vimium 是 Chrome 浏览器上的一个开源插件,能用 Vim 的指令快捷操作 Chrome。当我有意识的使用快捷键切换文本的次数越少时,这说明我越来越多的使用这些快捷键。同样的扩展 Firefox 上也有,例如 [Vimerator](2)。 + +### 人 + +毫无疑问,最好的学习方法就是求助于在你之前探索过的人,让他给你建议、反馈和解决方法。 + +如果你住在一个大城市,那么附近可能会有一个 Vim meetup 组,不然就是在 Freenode IRC 上的 #vim 频道。#vim 频道是 Freenode 上最活跃的频道之一,那上面可以针对你个人的问题来提供帮助。听上面的人发发牢骚或者看看别人尝试解决自己没有遇到过的问题,仅仅是这样我都觉得很有趣。 + +------ + +所以是什么成就了现在?如今便是极好。为它所花的时间是否值得就在于之后它为你节省了多少时间。但是我经常收到意外的惊喜与快乐,当我发现一个新的按键指令来复制、跳过词,或者一些相似的小技巧。每天我至少可以看见,一点点回报,正在逐渐配得上当初的付出。 + +学习 Vim 并不仅仅只有这些建议,还有很多。我很喜欢指引别人去 [Vim Advantures](3),它是一种只能使用 Vim 的快捷键的在线游戏。而且某天我发现了一个非常神奇的虚拟学习工具,在 [Vimgifts.com](4),那上面有明确的你想要的:用一个 gif 动图来描述,使用一点点 Vim 操作来达到他们想要的。 + +你有花时间学习 Vim 吗?或者有遇到任何关于按键复杂的插件的问题吗?什么适合你,你认为这些努力值得吗?效率的提高有达到你的预期?分享你们的故事在下面的评论区吧。 + +-------------------------------------------------------------------------------- + +via: https://opensource.com/life/16/7/tips-getting-started-vim + +作者:[Jason Baker ][a] +译者:[maywanting](https://github.com/maywanting) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]: https://opensource.com/users/jason-baker +[1]: https://github.com/philc/vimium +[2]: http://www.vimperator.org/ +[3]: http://vim-adventures.com/ +[4]: http://vimgifs.com/ From 15019d3beb05f47dfafc302ec178301df9506e5e Mon Sep 17 00:00:00 2001 From: maywanting Date: Sun, 31 Jul 2016 00:22:24 +0800 Subject: [PATCH 075/122] change the small sign --- ...1 5 tricks for getting started with Vim.md | 62 ------------------- ...1 5 tricks for getting started with Vim.md | 14 ++--- 2 files changed, 7 insertions(+), 69 deletions(-) delete mode 100644 sources/tech/20160721 5 tricks for getting started with Vim.md diff --git a/sources/tech/20160721 5 tricks for getting started with Vim.md b/sources/tech/20160721 5 tricks for getting started with Vim.md deleted file mode 100644 index 417b51ed45..0000000000 --- a/sources/tech/20160721 5 tricks for getting started with Vim.md +++ /dev/null @@ -1,62 +0,0 @@ -maywanting - -5 tricks for getting started with Vim -===================================== - -![](https://opensource.com/sites/default/files/styles/image-full-size/public/images/education/BUSINESS_peloton.png?itok=nuMbW9d3) - -For years, I've wanted to learn Vim, now my preferred Linux text editor and a favorite open source tool among developers and system administrators. And when I say learn, I mean really learn. Master is probably too strong a word, but I'd settle for advanced proficiency. For most of my years using Linux, my skillset included the ability to open a file, use the arrow keys to navigate up and down, switch into insert mode, change some text, save, and exit. - -But that's like minimum-viable-Vim. My skill level enabled me edit text documents from the terminal, but hasn't actually empowered me with any of the text editing super powers I've always imagined were possible. And it didn't justify using Vim over the totally capable Pico or Nano. - -So why learn Vim at all? Because I do spend an awful lot of time editing text, and I know I could be more efficient at it. And why not Emacs, or a more modern editor like Atom? Because Vim works for me, and at least I have some minimal experience in it. And perhaps, importantly, because it's rare that I encounter a system that I'm working on which doesn't have Vim or it's less-improved cousin (vi) available on it already. If you've always had a desire to learn Emacs, more power to you—I hope the Emacs-analog of these tips will prove useful to you, too. - -A few weeks in to this concentrated effort to up my Vim-use ability, the number one tip I have to share is that you actually must use the tool. While it seems like a piece of advice straight from Captain Obvious, I actually found it considerably harder than I expected to stay in the program. Most of my work happens inside of a web browser, and I had to untrain my trigger-like opening of (Gedit) every time I needed to edit a block of text outside of a browser. Gedit had made its way to my quick launcher, and so step one was removing this shortcut and putting Vim there instead. - -I've tried a number of things that have helped me learn. Here's a few of them I would recommend if you're looking to learn as well. - -### Vimtutor - -Sometimes the best place to get started isn't far from the application itself. I found Vimtutor, a tiny application that is basically a tutorial in a text file that you edit as you learn, to be as helpful as anything else in showing me the basics of the commands I had skipped learning through the years. Vimtutor is typically found everywhere Vim is, and is an easy install from your package manager if it's not already on your system. - -### GVim - -I know not everyone will agree with this one, but I found it useful to stop using the version of Vim that lives in my terminal and start using GVim for my basic editing needs. Naysayers will argue that it encourages using the mouse in an environment designed for keyboards, but I found it helpful to be able to quickly find the command I was looking for in a drop-down menu, reminding myself of the correct command, and then executing it with a keyboard. The alternative was often frustration at the inability to figure out how to do something, which is not a good feeling to be under constantly as you struggle to learn a new editor. No, stopping every few minutes to read a man page or use a search engine to remind you of a key sequence is not the best way to learn something new. - -### Keyboard maps - -Along with switching to GVim, I also found it handy to have a keyboard "cheat sheet" handy to remind me of the basic keystrokes. There are many available on the web that you can download, print, and set beside your station, but I opted for buying a set of stickers for my laptop keyboard. They were less than ten dollars US and had the added bonus of being a subtle reminder every time I used the laptop to at least try out one new thing as I edited. - -### Vimium - -As I mentioned, I live in the web browser most of the day. One of the tricks I've found helpful to reinforce the Vim way of navigation is to use [Vimium][1], an open source extension for Chrome that makes Chrome mimick the shortcuts used by Vim. I've found the fewer times I switch contexts for the keyboard shortcuts I'm using, the more likely I am to actually use them. Similar extensions, like [Vimerator][2], exist for Firefox. - -### Other human beings - -Without a doubt, there's no better way to get help learning something new than to get advice, feedback, and solutions from other people who have gone down a path before you. - -If you live in a larger urban area, there might be a Vim meetup group near you. Otherwise, the place to be is the #vim channel on Freenode IRC. One of the more popular channels on Freenode, the #vim channel is always full of helpful individuals willing to offer help with your problems. I find it interesting just to listen to the chatter and see what sorts of problems others are trying to solve to see what I'm missing out on. - ------- - -And so what to make of this effort? So far, so good. The time spent has probably yet to pay for itself in terms of time saved, but I'm always mildly surprised and amused when I find myself with a new reflex, jumping words with the right keypress sequence, or some similarly small feat. I can at least see that every day, the investment is bringing itself a little closer to payoff. - -These aren't the only tricks for learning Vim, by far. I also like to point people towards [Vim Adventures][3], an online game in which you navigate using the Vim keystrokes. And just the other day I came across a marvelous visual learning tool at [Vimgifs.com][4], which is exactly what you might expect it to be: illustrated examples with Vim so small they fit nicely in a gif. - -Have you invested the time to learn Vim, or really, any program with a keyboard-heavy interface? What worked for you, and, did you think the effort was worth it? Has your productivity changed as much as you thought it would? Lets share stories in the comments below. - --------------------------------------------------------------------------------- - -via: https://opensource.com/life/16/7/tips-getting-started-vim - -作者:[Jason Baker ][a] -译者:[译者ID](https://github.com/译者ID) -校对:[校对者ID](https://github.com/校对者ID) - -本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 - -[a]: https://opensource.com/users/jason-baker -[1]: https://github.com/philc/vimium -[2]: http://www.vimperator.org/ -[3]: http://vim-adventures.com/ -[4]: http://vimgifs.com/ diff --git a/translated/tech/20160721 5 tricks for getting started with Vim.md b/translated/tech/20160721 5 tricks for getting started with Vim.md index 7e9808d6d0..3dbc910d8d 100644 --- a/translated/tech/20160721 5 tricks for getting started with Vim.md +++ b/translated/tech/20160721 5 tricks for getting started with Vim.md @@ -3,19 +3,19 @@ Vim 学习的 5 个技巧 ![](https://opensource.com/sites/default/files/styles/image-full-size/public/images/education/BUSINESS_peloton.png?itok=nuMbW9d3) -多年来,我一直想学 Vim 。如今 Vim 是我最喜欢的 Linux 文本编辑器,也是开发者和系统管理者最喜爱的开源工具。我说的学习,指的是真正意义上的学习。想要精通确实很难,所以我只想要达到熟练的水平。根据我多年使用 Linux 的经验,我会的也仅仅只是打开一个文件,使用上下左右箭头按键来移动光标,切换到 insert 模式,更改一些文本,保存,然后退出。 +多年来,我一直想学 Vim。如今 Vim 是我最喜欢的 Linux 文本编辑器,也是开发者和系统管理者最喜爱的开源工具。我说的学习,指的是真正意义上的学习。想要精通确实很难,所以我只想要达到熟练的水平。根据我多年使用 Linux 的经验,我会的也仅仅只是打开一个文件,使用上下左右箭头按键来移动光标,切换到 insert 模式,更改一些文本,保存,然后退出。 -但那只是 Vim 的最基本操作。我可以在终端修改文本文档,但是无法使用任何一个我想象中强大的文本处理功能。这样我无法说明 Vim 完全优于 Pico 和 Nano 。 +但那只是 Vim 的最基本操作。我可以在终端修改文本文档,但是无法使用任何一个我想象中强大的文本处理功能。这样我无法说明 Vim 完全优于 Pico 和 Nano。 -所以到底为什么要学习 Vim ?因为我需要花费相当多的时间用于编辑文本,而且有很大的效率提升空间。为什么不选择 Emacs ,或者是更为现代化的编辑器例如 Atom ?因为 Vim 适合我,至少我有一丁点的使用经验。而且,很重要的一点就是,在我需要处理的系统上很少碰见没有装 Vim 或者它的简化版(Vi)。如果你有强烈的欲望想学习 Emacs ,我希望这些对于 Emacs 同类编辑器的建议能对你有所帮助。 +所以到底为什么要学习 Vim?因为我需要花费相当多的时间用于编辑文本,而且有很大的效率提升空间。为什么不选择 Emacs,或者是更为现代化的编辑器例如 Atom?因为 Vim 适合我,至少我有一丁点的使用经验。而且,很重要的一点就是,在我需要处理的系统上很少碰见没有装 Vim 或者它的简化版(Vi)。如果你有强烈的欲望想学习 Emacs,我希望这些对于 Emacs 同类编辑器的建议能对你有所帮助。 花了几周的时间专注提高我的 Vim 使用技巧之后,我想分享的第一个建议就是必须使用工具。虽然这看起来就是明知故问的回答,但事实上比我所想的在代码层面上还要困难。我的大多数工作是在网页浏览器上进行的,而且我每次都得有针对性的用 Gedit 打开并修改一段浏览器之外的文本。Gedit 需要快捷键来启动,所以第一步就是移出快捷键然后替换成 Vim 的快捷键。 -为了跟更好的学习 Vim ,我尝试了很多。如果你也正想学习,以下列举了一些作为推荐。 +为了跟更好的学习 Vim,我尝试了很多。如果你也正想学习,以下列举了一些作为推荐。 ### Vimtutor -通常如何开始学习最好就是使用应用本身。我找到一个小的应用叫 Vimtutor ,当你在学习编辑一个文本时它能辅导你一些基础知识,它向我展示了很多我这些年都忽视的基础命令。Vimtutor 上到处都是 Vim 影子,如果你的系统上没有 Vim ,Vimtutor可以很容易从你的包管理器上下载。 +通常如何开始学习最好就是使用应用本身。我找到一个小的应用叫 Vimtutor,当你在学习编辑一个文本时它能辅导你一些基础知识,它向我展示了很多我这些年都忽视的基础命令。Vimtutor 上到处都是 Vim 影子,如果你的系统上没有 Vim,Vimtutor可以很容易从你的包管理器上下载。 ### GVim @@ -23,11 +23,11 @@ Vim 学习的 5 个技巧 ### Keyboard maps -当我转战 GVim ,我发现有一个键盘的“作弊表”来提醒我最基础的按键很是便利。网上有很多这种可用的表,你可以下载,打印,然后贴在你身边的某一处地方。但是为了我的笔记本键盘,我选择买一沓便签纸。这些便签纸在美国不到10美元,而且当我使用键盘编辑文本尝试新的命令的时候,可以随时提醒我。 +当我转战 GVim,我发现有一个键盘的“作弊表”来提醒我最基础的按键很是便利。网上有很多这种可用的表,你可以下载,打印,然后贴在你身边的某一处地方。但是为了我的笔记本键盘,我选择买一沓便签纸。这些便签纸在美国不到10美元,而且当我使用键盘编辑文本尝试新的命令的时候,可以随时提醒我。 ### Vimium -上文提到,我工作都在浏览器上进行。其中一条我觉得很有帮助的建议就是,使用 [Vimium](1)来用增强使用 Vim 的体验。Vimium 是 Chrome 浏览器上的一个开源插件,能用 Vim 的指令快捷操作 Chrome。当我有意识的使用快捷键切换文本的次数越少时,这说明我越来越多的使用这些快捷键。同样的扩展 Firefox 上也有,例如 [Vimerator](2)。 +上文提到,我工作都在浏览器上进行。其中一条我觉得很有帮助的建议就是,使用 [Vimium](1) 来用增强使用 Vim 的体验。Vimium 是 Chrome 浏览器上的一个开源插件,能用 Vim 的指令快捷操作 Chrome。当我有意识的使用快捷键切换文本的次数越少时,这说明我越来越多的使用这些快捷键。同样的扩展 Firefox 上也有,例如 [Vimerator](2)。 ### 人 From e0444ab80940a97472434d38e7f235e9f4a6a219 Mon Sep 17 00:00:00 2001 From: cvsher <478990879@qq.com> Date: Sun, 31 Jul 2016 00:26:03 +0800 Subject: [PATCH 076/122] Create 20160706 What is Git.md --- translated/tech/20160706 What is Git.md | 118 ++++++++++++++++++++++++ 1 file changed, 118 insertions(+) create mode 100644 translated/tech/20160706 What is Git.md diff --git a/translated/tech/20160706 What is Git.md b/translated/tech/20160706 What is Git.md new file mode 100644 index 0000000000..8a43ef717d --- /dev/null +++ b/translated/tech/20160706 What is Git.md @@ -0,0 +1,118 @@ +什么是Git +=========== + +欢迎阅读本系列关于Git版本控制系统的教程!通过本文的介绍,你将会了解到Git的用途及谁该使用Git。 + +如果你刚步入开源的世界,你很有可能会遇到一些在Git上托管代码或者发布使用版本的开源软件。事实上,不管你知道与否,你都在使用基于Git进行版本管理的软件:linux内核(就算你没有在手机或者电脑上使用linux,你正在访问的网站也是运行在linux系统上的),Firefox,Chrome等其他很多项目都在Git上和世界各地开发者共享他们的代码。 + +换个角度来说,你是否仅仅通过Git就可以和其他人共享你的代码?你是否可以在家里或者企业里私有化的使用Git?你必须要通过一个GitHub账号来使用Git吗?为什么要使用Git呢?Git的优势又是什么?Git是我唯一的选择吗?这对Git所有的疑问都会把我们搞的一脑浆糊。 + +因此,忘记你以前所知的Git,我们从新走进Git世界的大门。 + +### 什么是版本控制系统? + +现在市面上有很多不同的版本控制系统:CVS,SVN,Mercurial,Fossil 当然还有 Git。 + +很多像 GitHub 和 GitLab 这样的服务是以Git为基础的,但是你也可以只使用Git而无需使用其他额外的服务。这意味着你可以以私有或者公有的方式来使用Git。 + +如果你曾经和其他人有过任何数字方面的合作,你就会知道传统版本管理的工作流程。开始是很简单的:你有一个原始的版本,你把这个版本发送给你的同事,他们在接收到的版本上做了些修改,现在你们有两个版本了,然后他们把他们手上修改过的版本发回来给你。你把他们的修改合并到你手上的版本中,现在两个版本又合并成一个最新的版本了。 + +然后,你修改了你手上最新的版本,同时,你的同事也修改了他们手上合并前的版本。现在你们有3个不同的版本了,分别是合并后最新的版本,你修改后的版本,你同事手上继续修改过的版本。至此,你们的版本管理工作开始变得越来越混乱了。 + +正如 Jason van Gumster 在他的文章中指出 [即使是艺术家也需要版本控制][1],而且这也有向个人设置方向发展的趋势。无论是艺术家还是科学家,在一些想法上开发出实验版本都是比较常见的;在你的项目中,可能有某个版本大获成功,把项目推向一个新的高度,也可能有某个版本惨遭失败。因此,最终你不可避免的会创建出一堆名为project_justTesting.kdenlive、project_betterVersion.kdenlive、project_best_FINAL.kdenlive、project_FINAL-alternateVersion.kdenlive等类似名称的文件。 + +不管你是修改一个for循环,还是一些简单的文本编辑,一个好的版本控制系统都会让我们的生活更加的轻松。 + +### Git快照 + +Git会为每个项目创建快照,并且为项目的每个版本都保存一个唯一的快照。 + +如果你将项目带领到了一个错误的方向上,你可以回退到上一个正确的版本,并且 开始尝试另一个可行的方向。 + +如果你是和别人合作开发,当有人向你发送他们的修改时,你可以将这些修改合并到你的工作分支中,然后你的同事就可以获取到合并后的最新版本,并在此基础上继续工作。 + +Git并不是魔法,因此冲突还是会发生的(“你修改了某文件的最后一行,但是我把这行整行都删除了;我们怎样处理这些冲突呢?”),但是总体而言,Git会为你保留了所有更改的历史版本,甚至允许并行版本。这为你保留了以任何方式处理冲突的能力。 + +### 分布式Git + +在不同的机器上为同一个项目工作是一件复杂的事情。因为在你开始工作时,你想要获得项目的最新版本,然后此基础上进行修改,最后向你的同事共享这些改动。传统的方法是通过笨重的在线文件共享服务或者老旧的电邮附件,但是这两种方式都是效率低下且容易出错。 + +Git天生是为分布式工作设计的。如果你要参与到某个项目中,你可以克隆(clone)该项目的Git仓库,然后就像这个项目只有你本地一个版本一样对项目进行修改。最后使用一些简单的命令你就可以拉取(pull)其他开发者的修改,或者你可以把你的修改推送(push)给别人。现在不用担心谁手上的是最新的版本,或者谁的版本又存放在哪里等这些问题了。全部人都是在本地进行开发,然后向共同的目标推送或者拉取更新。(或者不是共同的目标,这取决于项目的开发方式)。 + +### Git 界面 + +最原始的Git是运行在Linux终端上的应用软件。然而,得益于Git是开源的,并且拥有良好的设计,世界各地的开发者都可以为Git设计不同的问接入界面。 + +Git完全是免费的,并且附带在Linux,BSD,Illumos 和其他类unix系统中,Git命令看起来像: + +``` +$ git --version +git version 2.5.3 +``` + +可能最著名的Git访问界面是基于网页的,像GitHub,开源的GitLab,Savannah,BitBucket和SourceForge这些网站都是基于网页端的Git界面。这些站点为面向公众和面向社会的开源软件提供了最大限度的代码托管服务。在一定程度上,基于浏览器的图形界面(GUI)可以尽量的减缓Git的学习曲线。下面的GitLab接口的截图: + +![](https://opensource.com/sites/default/files/0_gitlab.png) + +再者,第三方Git服务提供商或者独立开发者甚至在Git的基础上开发出不是基于HTML的定制化前端接口。此类接口让你可以不用打开浏览器就可以方便的使用Git进行版本管理。其中对用户最透明的方式是直接集成到文件管理器中。KDE文件管理器,Dolphin 可以直接在目录中显示Git状态,甚至支持提交,推送和拉取更新操作。 + +![](https://opensource.com/sites/default/files/0_dolphin.jpg) + +[Sparkleshare][2]使用Git作为其Dropbox类文件共享接口的基础。 + +![](https://opensource.com/sites/default/files/0_sparkleshare_1.jpg) + +想了解更多的内容,可以查看[Git wiki][3],此页面中展示了很多Git的图形界面项目。 + +### 谁应该使用Git? + +就是你!我们更应该关心的问题是什么时候使用Git?和用Git来干嘛? + +### 我应该在什么时候使用Git呢?我要用Git来干嘛呢? + +想更深入的学习Git,我们必须比平常考虑更多关于文件格式的问题。 + +Git是为了管理源代码而设计的,在大多数编程语言中,源代码就意味者一行行的文本。当然,Git并不知道你把这些文本当成是源代码还是下一部伟大的美式小说。因此,只要文件内容是以文本构成的,使用Git来跟踪和管理其版本就是一个很好的选择了。 + +但是什么是文本呢?如果你在像Libre Office这类办公软件中编辑一些内容,通常并不会产生纯文本内容。因为通常复杂的应用软件都会对原始的文本内容进行一层封装,就如把原始文本内容用XML标记语言包装起来,然后封装在Zip容器中。这种对原始文本内容进行一层封装的做法可以保证当你把文件发送给其他人时,他们可以看到你在办公软件中编辑的内容及特定的文本效果。奇怪的是,虽然,通常你的需求可能会很复杂,就像保存[Kdenlive][4]项目文件,或者保存从[Inkscape][5]导出的SVG文件,但是,事实上使用Git管理像XML文本这样的纯文本类容是最简单的。 + +如果你在使用Unix系统,你可以使用 file 命令来查看文件内容构成: + +``` +$ file ~/path/to/my-file.blah +my-file.blah: ASCII text +$ file ~/path/to/different-file.kra: Zip data (MIME type "application/x-krita") +``` + +如果还是不确定,你可以使用 head 命令来查看文件内容: + +``` +$ head ~/path/to/my-file.blah +``` + +如果输出的文本你基本能看懂,这个文件就很有可能是文本文件。如果你仅仅在一堆乱码中偶尔看到几个熟悉的字符,那么这个文件就可能不是文本文件了。 + +准确的说:Git可以管理其他格式的文件,但是它会把这些文件当成二进制大对象(blob)。两者的区别是,在文本文件中,Git可以明确的告诉你在这两个快照(或者说提交)间有3行是修改过的。但是如果你在两个提交间对一张图片进行的编辑操作,Git会怎么指出这种修改呢?实际上,因为图片并不是以某种可以增加或删除的有意义的文本构成,因此Git并不能明确的描述这种变化。当然我个人是非常希望图片的编辑可以像把本文"丑陋的蓝绿色"修改成"漂浮着蓬松白云的天蓝色"一样的简单,但是事实上图片的编辑并没有这么简单。 + +经常有人在Git上记录png图标、电子表格或者流程图这类二进制大型对象。尽管,我们知道在Git上管理此类大型文件并不直观,但是,如果你需要使用Git来管理此类文件,你也并不需要过多的担心。如果你参与的项目同时生成文本文件和二进制大文件对象(如视频游戏中常见的场景,这些和源代码同样重要的图像和音频材料),那么你有两条路可以走:要么开发出你自己的解决方案,就如使用指向共享网络驱动器的指针;要么使用Git插件,如Joey Hess开发的[git annex][6], 或者 [Git-Media][7] 项目。 + +你看,Git真的是一个任何人都可以使用的工具。它是你进行文件版本管理的一个强大而且好用工具,同时它并没有你开始认为的那么可怕。 + +-------------------------------------------------------------------------------- + +via: https://opensource.com/resources/what-is-git + +作者:[Seth Kenlon ][a] +译者:[cvsher](https://github.com/cvsher) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]: https://opensource.com/users/seth +[1]: https://opensource.com/life/16/2/version-control-isnt-just-programmers +[2]: http://sparkleshare.org/ +[3]: https://git.wiki.kernel.org/index.php/InterfacesFrontendsAndTools#Graphical_Interfaces +[4]: https://opensource.com/life/11/11/introduction-kdenlive +[5]: http://inkscape.org/ +[6]: https://git-annex.branchable.com/ +[7]: https://github.com/alebedev/git-media From 82d69780088789c52fd132ca3c2e8b69820ba9d7 Mon Sep 17 00:00:00 2001 From: cvsher <478990879@qq.com> Date: Sun, 31 Jul 2016 00:38:49 +0800 Subject: [PATCH 077/122] Update 20160706 What is Git.md --- translated/tech/20160706 What is Git.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/translated/tech/20160706 What is Git.md b/translated/tech/20160706 What is Git.md index 8a43ef717d..f2f01b8d39 100644 --- a/translated/tech/20160706 What is Git.md +++ b/translated/tech/20160706 What is Git.md @@ -41,7 +41,7 @@ Git天生是为分布式工作设计的。如果你要参与到某个项目中 ### Git 界面 -最原始的Git是运行在Linux终端上的应用软件。然而,得益于Git是开源的,并且拥有良好的设计,世界各地的开发者都可以为Git设计不同的问接入界面。 +最原始的Git是运行在Linux终端上的应用软件。然而,得益于Git是开源的,并且拥有良好的设计,世界各地的开发者都可以为Git设计不同的接入界面。 Git完全是免费的,并且附带在Linux,BSD,Illumos 和其他类unix系统中,Git命令看起来像: @@ -54,7 +54,7 @@ git version 2.5.3 ![](https://opensource.com/sites/default/files/0_gitlab.png) -再者,第三方Git服务提供商或者独立开发者甚至在Git的基础上开发出不是基于HTML的定制化前端接口。此类接口让你可以不用打开浏览器就可以方便的使用Git进行版本管理。其中对用户最透明的方式是直接集成到文件管理器中。KDE文件管理器,Dolphin 可以直接在目录中显示Git状态,甚至支持提交,推送和拉取更新操作。 +再者,第三方Git服务提供商或者独立开发者甚至可以在Git的基础上开发出不是基于HTML的定制化前端接口。此类接口让你可以不用打开浏览器就可以方便的使用Git进行版本管理。其中对用户最透明的方式是直接集成到文件管理器中。KDE文件管理器,Dolphin 可以直接在目录中显示Git状态,甚至支持提交,推送和拉取更新操作。 ![](https://opensource.com/sites/default/files/0_dolphin.jpg) From 5260df0109f620e8362516743bb1fcb7464a37ec Mon Sep 17 00:00:00 2001 From: maywanting Date: Sun, 31 Jul 2016 01:13:30 +0800 Subject: [PATCH 078/122] the last version --- ...20160721 5 tricks for getting started with Vim.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/translated/tech/20160721 5 tricks for getting started with Vim.md b/translated/tech/20160721 5 tricks for getting started with Vim.md index 3dbc910d8d..67d64ced2f 100644 --- a/translated/tech/20160721 5 tricks for getting started with Vim.md +++ b/translated/tech/20160721 5 tricks for getting started with Vim.md @@ -5,7 +5,7 @@ Vim 学习的 5 个技巧 多年来,我一直想学 Vim。如今 Vim 是我最喜欢的 Linux 文本编辑器,也是开发者和系统管理者最喜爱的开源工具。我说的学习,指的是真正意义上的学习。想要精通确实很难,所以我只想要达到熟练的水平。根据我多年使用 Linux 的经验,我会的也仅仅只是打开一个文件,使用上下左右箭头按键来移动光标,切换到 insert 模式,更改一些文本,保存,然后退出。 -但那只是 Vim 的最基本操作。我可以在终端修改文本文档,但是无法使用任何一个我想象中强大的文本处理功能。这样我无法说明 Vim 完全优于 Pico 和 Nano。 +但那只是 Vim 的最基本操作。Vim 可以让我在终端修改文本,但是它并没有任何一个我想象中强大的文本处理功能。这样我无法说明 Vim 完全优于 Pico 和 Nano。 所以到底为什么要学习 Vim?因为我需要花费相当多的时间用于编辑文本,而且有很大的效率提升空间。为什么不选择 Emacs,或者是更为现代化的编辑器例如 Atom?因为 Vim 适合我,至少我有一丁点的使用经验。而且,很重要的一点就是,在我需要处理的系统上很少碰见没有装 Vim 或者它的简化版(Vi)。如果你有强烈的欲望想学习 Emacs,我希望这些对于 Emacs 同类编辑器的建议能对你有所帮助。 @@ -15,11 +15,11 @@ Vim 学习的 5 个技巧 ### Vimtutor -通常如何开始学习最好就是使用应用本身。我找到一个小的应用叫 Vimtutor,当你在学习编辑一个文本时它能辅导你一些基础知识,它向我展示了很多我这些年都忽视的基础命令。Vimtutor 上到处都是 Vim 影子,如果你的系统上没有 Vim,Vimtutor可以很容易从你的包管理器上下载。 +通常如何开始学习最好就是使用应用本身。我找到一个小的应用叫 Vimtutor,当你在学习编辑一个文本时它能辅导你一些基础知识,它向我展示了很多我这些年都忽视的基础命令。Vimtutor 上到处都是 Vim 影子,如果你的系统上没有 Vimtutor,Vimtutor可以很容易从你的包管理器上下载。 ### GVim -我知道并不是每个人都看好这个,但就是它让我从使用在终端的 Vim 转战到使用 GVim 来满足我基本编辑需求。反对者表示 GVim 鼓励使用鼠标,而 Vim 主要是为键盘党设计的。但是我能通过 GVim 的下拉菜单快速找到想找的指令,并且 GVim 可以提醒我正确的指令然后通过敲键盘执行它。努力学习一个新的编辑器然后陷入无法解决的困境,这种感觉并不好受。每隔几分钟读一下 man 出来的文字或者使用搜索引擎来提醒你指令也并不是最好的学习新事务的方法。 +我知道并不是每个人都认同这个,但就是它让我从使用在终端的 Vim 转战到使用 GVim 来满足我基本编辑需求。反对者表示 GVim 鼓励使用鼠标,而 Vim 主要是为键盘党设计的。但是我能通过 GVim 的下拉菜单快速找到想找的指令,并且 GVim 可以提醒我正确的指令然后通过敲键盘执行它。努力学习一个新的编辑器然后陷入无法解决的困境,这种感觉并不好受。每隔几分钟读一下 man 出来的文字或者使用搜索引擎来提醒你指令也并不是最好的学习新事务的方法。 ### Keyboard maps @@ -27,7 +27,7 @@ Vim 学习的 5 个技巧 ### Vimium -上文提到,我工作都在浏览器上进行。其中一条我觉得很有帮助的建议就是,使用 [Vimium](1) 来用增强使用 Vim 的体验。Vimium 是 Chrome 浏览器上的一个开源插件,能用 Vim 的指令快捷操作 Chrome。当我有意识的使用快捷键切换文本的次数越少时,这说明我越来越多的使用这些快捷键。同样的扩展 Firefox 上也有,例如 [Vimerator](2)。 +上文提到,我工作都在浏览器上进行。其中一条我觉得很有帮助的建议就是,使用 [Vimium][1] 来用增强使用 Vim 的体验。Vimium 是 Chrome 浏览器上的一个开源插件,能用 Vim 的指令快捷操作 Chrome。当我有意识的使用快捷键切换文本的次数越少时,这说明我越来越多的使用这些快捷键。同样的扩展 Firefox 上也有,例如 [Vimerator][2]。 ### 人 @@ -39,9 +39,9 @@ Vim 学习的 5 个技巧 所以是什么成就了现在?如今便是极好。为它所花的时间是否值得就在于之后它为你节省了多少时间。但是我经常收到意外的惊喜与快乐,当我发现一个新的按键指令来复制、跳过词,或者一些相似的小技巧。每天我至少可以看见,一点点回报,正在逐渐配得上当初的付出。 -学习 Vim 并不仅仅只有这些建议,还有很多。我很喜欢指引别人去 [Vim Advantures](3),它是一种只能使用 Vim 的快捷键的在线游戏。而且某天我发现了一个非常神奇的虚拟学习工具,在 [Vimgifts.com](4),那上面有明确的你想要的:用一个 gif 动图来描述,使用一点点 Vim 操作来达到他们想要的。 +学习 Vim 并不仅仅只有这些建议,还有很多。我很喜欢指引别人去 [Vim Advantures][3],它是一种只能使用 Vim 的快捷键的在线游戏。而且某天我发现了一个非常神奇的虚拟学习工具,在 [Vimgifts.com][4],那上面有明确的你想要的:用一个 gif 动图来描述,使用一点点 Vim 操作来达到他们想要的。 -你有花时间学习 Vim 吗?或者有遇到任何关于按键复杂的插件的问题吗?什么适合你,你认为这些努力值得吗?效率的提高有达到你的预期?分享你们的故事在下面的评论区吧。 +你有花时间学习 Vim 吗?或者有大量键盘操作交互体验的程序上投资时间吗?那些经过你努力后掌握的工具,你认为这些努力值得吗?效率的提高有达到你的预期?分享你们的故事在下面的评论区吧。 -------------------------------------------------------------------------------- From 28f0a31b6e1057c66a4971c26fb3a0495ab3324f Mon Sep 17 00:00:00 2001 From: sevenot <469147394@qq.com> Date: Sun, 31 Jul 2016 01:45:28 +0800 Subject: [PATCH 079/122] sevenot translating --- ...ux Terminal Emulator With Multiple Terminals In One Window.md | 1 + 1 file changed, 1 insertion(+) diff --git a/sources/tech/20160724 Terminator A Linux Terminal Emulator With Multiple Terminals In One Window.md b/sources/tech/20160724 Terminator A Linux Terminal Emulator With Multiple Terminals In One Window.md index eb50d539a1..2f1b393c80 100644 --- a/sources/tech/20160724 Terminator A Linux Terminal Emulator With Multiple Terminals In One Window.md +++ b/sources/tech/20160724 Terminator A Linux Terminal Emulator With Multiple Terminals In One Window.md @@ -1,3 +1,4 @@ +sevenot translating Terminator A Linux Terminal Emulator With Multiple Terminals In One Window ============================================================================= From 35dea8011103be3f36c44ac055622f2e9163f74c Mon Sep 17 00:00:00 2001 From: cvsher <478990879@qq.com> Date: Sun, 31 Jul 2016 07:24:44 +0800 Subject: [PATCH 080/122] Delete 20160706 What is Git.md --- sources/tech/20160706 What is Git.md | 123 --------------------------- 1 file changed, 123 deletions(-) delete mode 100644 sources/tech/20160706 What is Git.md diff --git a/sources/tech/20160706 What is Git.md b/sources/tech/20160706 What is Git.md deleted file mode 100644 index f98de42fd3..0000000000 --- a/sources/tech/20160706 What is Git.md +++ /dev/null @@ -1,123 +0,0 @@ -translating by cvsher -What is Git -=========== - -Welcome to my series on learning how to use the Git version control system! In this introduction to the series, you will learn what Git is for and who should use it. - -If you're just starting out in the open source world, you're likely to come across a software project that keeps its code in, and possibly releases it for use, by way of Git. In fact, whether you know it or not, you're certainly using software right now that is developed using Git: the Linux kernel (which drives the website you're on right now, if not the desktop or mobile phone you're accessing it on), Firefox, Chrome, and many more projects share their codebase with the world in a Git repository. - -On the other hand, all the excitement and hype over Git tends to make things a little muddy. Can you only use Git to share your code with others, or can you use Git in the privacy of your own home or business? Do you have to have a GitHub account to use Git? Why use Git at all? What are the benefits of Git? Is Git the only option? - -So forget what you know or what you think you know about Git, and let's take it from the beginning. - -### What is version control? - -Git is, first and foremost, a version control system (VCS). There are many version control systems out there: CVS, SVN, Mercurial, Fossil, and, of course, Git. - -Git serves as the foundation for many services, like GitHub and GitLab, but you can use Git without using any other service. This means that you can use Git privately or publicly. - -If you have ever collaborated on anything digital with anyone, then you know how it goes. It starts out simple: you have your version, and you send it to your partner. They make some changes, so now there are two versions, and send the suggestions back to you. You integrate their changes into your version, and now there is one version again. - -Then it gets worse: while you change your version further, your partner makes more changes to their version. Now you have three versions; the merged copy that you both worked on, the version you changed, and the version your partner has changed. - -As Jason van Gumster points out in his article, 【Even artists need version control][1], this syndrome tends to happen in individual settings as well. In both art and science, it's not uncommon to develop a trial version of something; a version of your project that might make it a lot better, or that might fail miserably. So you create file names like project_justTesting.kdenlive and project_betterVersion.kdenlive, and then project_best_FINAL.kdenlive, but with the inevitable allowance for project_FINAL-alternateVersion.kdenlive, and so on. - -Whether it's a change to a for loop or an editing change, it happens to the best of us. That is where a good version control system makes life easier. - -### Git snapshots - -Git takes snapshots of a project, and stores those snapshots as unique versions. - -If you go off in a direction with your project that you decide was the wrong direction, you can just roll back to the last good version and continue along an alternate path. - -If you're collaborating, then when someone sends you changes, you can merge those changes into your working branch, and then your collaborator can grab the merged version of the project and continue working from the new current version. - -Git isn't magic, so conflicts do occur ("You changed the last line of the book, but I deleted that line entirely; how do we resolve that?"), but on the whole, Git enables you to manage the many potential variants of a single work, retaining the history of all the changes, and even allows for parallel versions. - -### Git distributes - -Working on a project on separate machines is complex, because you want to have the latest version of a project while you work, makes your own changes, and share your changes with your collaborators. The default method of doing this tends to be clunky online file sharing services, or old school email attachments, both of which are inefficient and error-prone. - -Git is designed for distributed development. If you're involved with a project you can clone the project's Git repository, and then work on it as if it was the only copy in existence. Then, with a few simple commands, you can pull in any changes from other contributors, and you can also push your changes over to someone else. Now there is no confusion about who has what version of a project, or whose changes exist where. It is all locally developed, and pushed and pulled toward a common target (or not, depending on how the project chooses to develop). - -### Git interfaces - -In its natural state, Git is an application that runs in the Linux terminal. However, as it is well-designed and open source, developers all over the world have designed other ways to access it. - -It is free, available to anyone for $0, and comes in packages on Linux, BSD, Illumos, and other Unix-like operating systems. It looks like this: - -``` -$ git --version -git version 2.5.3 -``` - -Probably the most well-known Git interfaces are web-based: sites like GitHub, the open source GitLab, Savannah, BitBucket, and SourceForge all offer online code hosting to maximise the public and social aspect of open source along with, in varying degrees, browser-based GUIs to minimise the learning curve of using Git. This is what the GitLab interface looks like: - -![](https://opensource.com/sites/default/files/0_gitlab.png) - -Additionally, it is possible that a Git service or independent developer may even have a custom Git frontend that is not HTML-based, which is particularly handy if you don't live with a browser eternally open. The most transparent integration comes in the form of file manager support. The KDE file manager, Dolphin, can show the Git status of a directory, and even generate commits, pushes, and pulls. - -![](https://opensource.com/sites/default/files/0_dolphin.jpg) - -[Sparkleshare][2] uses Git as a foundation for its own Dropbox-style file sharing interface. - -![](https://opensource.com/sites/default/files/0_sparkleshare_1.jpg) - -For more, see the (long) page on the official [Git wiki][3] listing projects with graphical interfaces to Git. - -### Who should use Git? - -You should! The real question is when? And what for? - -### When should I use Git, and what should I use it for? - -To get the most out of Git, you need to think a little bit more than usual about file formats. - -Git is designed to manage source code, which in most languages consists of lines of text. Of course, Git doesn't know if you're feeding it source code or the next Great American Novel, so as long as it breaks down to text, Git is a great option for managing and tracking versions. - -But what is text? If you write something in an office application like Libre Office, then you're probably not generating raw text. There is usually a wrapper around complex applications like that which encapsulate the raw text in XML markup and then in a zip container, as a way to ensure that all of the assets for your office file are available when you send that file to someone else. Strangely, though, something that you might expect to be very complex, like the save files for a [Kdenlive][4] project, or an SVG from [Inkscape][5], are actually raw XML files that can easily be managed by Git. - -If you use Unix, you can check to see what a file is made of with the file command: - -``` -$ file ~/path/to/my-file.blah -my-file.blah: ASCII text -$ file ~/path/to/different-file.kra: Zip data (MIME type "application/x-krita") -``` - -If unsure, you can view the contents of a file with the head command: - -``` -$ head ~/path/to/my-file.blah -``` - -If you see text that is mostly readable by you, then it is probably a file made of text. If you see garbage with some familiar text characters here and there, it is probably not made of text. - -Make no mistake: Git can manage other formats of files, but it treats them as blobs. The difference is that in a text file, two Git snapshots (or commits, as we call them) might be, say, three lines different from each other. If you have a photo that has been altered between two different commits, how can Git express that change? It can't, really, because photographs are not made of any kind of sensible text that can just be inserted or removed. I wish photo editing were as easy as just changing some text from "ugly greenish-blue" to "blue-with-fluffy-clouds" but it truly is not. - -People check in blobs, like PNG icons or a speadsheet or a flowchart, to Git all the time, so if you're working in Git then don't be afraid to do that. Know that it's not sensible to do that with huge files, though. If you are working on a project that does generate both text files and large blobs (a common scenario with video games, which have equal parts source code to graphical and audio assets), then you can do one of two things: either invent your own solution, such as pointers to a shared network drive, or use a Git add-on like Joey Hess's excellent [git annex][6], or the [Git-Media][7] project. - -So you see, Git really is for everyone. It is a great way to manage versions of your files, it is a powerful tool, and it is not as scary as it first seems. - --------------------------------------------------------------------------------- - -via: https://opensource.com/resources/what-is-git - -作者:[Seth Kenlon ][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/seth -[1]: https://opensource.com/life/16/2/version-control-isnt-just-programmers -[2]: http://sparkleshare.org/ -[3]: https://git.wiki.kernel.org/index.php/InterfacesFrontendsAndTools#Graphical_Interfaces -[4]: https://opensource.com/life/11/11/introduction-kdenlive -[5]: http://inkscape.org/ -[6]: https://git-annex.branchable.com/ -[7]: https://github.com/alebedev/git-media - - - - From fafb7ca2a5cb862f22497fd03586cd18bd9566a2 Mon Sep 17 00:00:00 2001 From: Ezio Date: Sun, 31 Jul 2016 11:52:41 +0800 Subject: [PATCH 081/122] =?UTF-8?q?20160731-1=20=E9=80=89=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...160509 Android vs. iPhone Pros and Cons.md | 86 +++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 sources/talk/20160509 Android vs. iPhone Pros and Cons.md diff --git a/sources/talk/20160509 Android vs. iPhone Pros and Cons.md b/sources/talk/20160509 Android vs. iPhone Pros and Cons.md new file mode 100644 index 0000000000..92feeba307 --- /dev/null +++ b/sources/talk/20160509 Android vs. iPhone Pros and Cons.md @@ -0,0 +1,86 @@ +Android vs. iPhone: Pros and Cons +=================================== + +>When comparing Android vs. iPhone, clearly Android has certain advantages even as the iPhone is superior in some key ways. But ultimately, which is better? + +The question of Android vs. iPhone is a personal one. + +Take myself, for example. I'm someone who has used both Android and the iPhone iOS. I'm well aware of the strengths of both platforms along with their weaknesses. Because of this, I decided to share my perspective regarding these two mobile platforms. Additionally, we'll take a look at my impressions of the new Ubuntu mobile platform and where it stacks up. + +### What iPhone gets right + +Even though I'm a full time Android user these days, I do recognize the areas where the iPhone got it right. First, Apple has a better record in updating their devices. This is especially true for older devices running iOS. With Android, if it's not a “Google blessed” Nexus...it better be a higher end carrier supported phone. Otherwise, you're going to find updates are either sparse or non-existent. + +Another area where the iPhone does well is apps availability. Expanding on that: iPhone apps almost always have a cleaner look to them. This isn't to say that Android apps are ugly, rather, they may not have an expected flow and consistency found with iOS. Two examples of exclusivity and great iOS-only layout would have to be [Dark Sky][1] (weather) and [Facebook Paper][2]. + +Then there is the backup process. Android can, by default, back stuff up to Google. But that doesn't help much with application data! By contrast, iCloud can essentially make a full backup of your iOS device. + +### Where iPhone loses me + +The biggest indisputable issue I have with the iPhone is more of a hardware limitation than a software one. That issue is storage. + +Look, with most Android phones, I can buy a smaller capacity phone and then add an SD card later. This does two things: First, I can use the SD card to store a lot of media files. Second, I can even use the SD card to store "some" of my apps. Apple has nothing that will touch this. + +Another area where the iPhone loses me is in the lack of choice it provides. Backing up your device? Hope you like iTunes or iCloud. For someone like myself who uses Linux, this means my ONLY option would be to use iCloud. + +To be ultimately fair, there are additional solutions for your iPhone if you're willing to jailbreak it. But that's not what this article is about. Same goes for rooting Android. This article is addressing a vanilla setup for both platforms. + +Finally, let us not forget this little treat – [iTunes decides to delete a user's music][3] because it was seen as a duplication of Apple Music contents...or something along those lines. Not iPhone specific? I disagree, as that music would have very well ended up onto the iPhone at some point. I can say with great certainty that in no universe would I ever put up with this kind of nonsense! + +![](http://www.datamation.com/imagesvr_ce/5552/mobile-abstract-icon-200x150.jpg) +>The Android vs. iPhone debate depends on what features matter the most to you. + +### What Android gets right + +The biggest thing Android gives me that the iPhone doesn't: choice. Choices in applications, devices and overall layout of how my phone works. + +I love desktop widgets! To iPhone users, they may seem really silly. But I can tell you that they save me from opening up applications as I can see the desired data without the extra hassle. Another similar feature I love is being able to install custom launchers instead of my phone's default! + +Finally, I can utilize tools like [Airdroid][4] and [Tasker][5] to add full computer-like functionality to my smart phone. Airdroid allows me treat my Android phone like a computer with file management and SMS with anyone – this becomes a breeze to use with my mouse and keyboard. Tasker is awesome in that I can setup "recipes" to connect/disconnect, put my phone into meeting mode or even put itself into power saving mode when I set the parameters to do so. I can even set it to launch applications when I arrive at specific destinations. + +### Where Android loses me + +Backup options are limited to specific user data, not a full clone of your phone. Without rooting, you're either left out in the wind or you must look to the Android SDK for solutions. Expecting casual users to either root their phone or run the SDK for a complete (I mean everything) Android backup is a joke. + +Yes, Google's backup service will backup Google app data, along with other related customizations. But it's nowhere near as complete as what we see with the iPhone. To accomplish something similar to what the iPhone enjoys, I've found you're going to either be rooting your Android phone or connecting it to a Windows PC to utilize some random program. + +To be fair, however, I believe Nexus owners benefit from a [full backup service][6] that is device specific. Sorry, but Google's default backup is not cutting it. Same applies for adb backups via your PC – they don't always restore things as expected. + +Wait, it gets better. Now after a lot of failed let downs and frustration, I found that there was one app that looked like it "might" offer a glimmer of hope, it's called Helium. Unlike other applications I found to be misleading and frustrating with their limitations, [Helium][7] initially looked like it was the backup application Google should have been offering all along -- emphasis on "looked like." Sadly, it was a huge let down. Not only did I need to connect it to my computer for a first run, it didn't even work using their provided Linux script. After removing their script, I settling for a good old fashioned adb backup...to my Linux PC. Fun facts: You will need to turn on a laundry list of stuff in developer tools, plus if you run the Twilight app, that needs to be turned off. It took me a bit to put this together when the backup option for adb on my phone wasn't responding. + +At the end of the day, Android has ample options for non-rooted users to backup superficial stuff like contacts, SMS and other data easily. But a deep down phone backup is best left to a wired connection and adb from my experience. + +### Ubuntu will save us? + +With the good and the bad examined between the two major players in the mobile space, there's a lot of hope that we're going to see good things from Ubuntu on the mobile front. Well, thus far, it's been pretty lackluster. + +I like what the developers are doing with the OS and I certainly love the idea of a third option for mobile besides iPhone and Android. Unfortunately, though, it's not that popular on the phone and the tablet received a lot of bad press due to subpar hardware and a lousy demonstration that made its way onto YouTube. + +To be fair, I've had subpar experiences with iPhone and Android, too, in the past. So this isn't a dig on Ubuntu. But until it starts showing up with a ready to go ecosystem of functionality that matches what Android and iOS offer, it's not something I'm terribly interested in yet. At a later date, perhaps, I'll feel like the Ubuntu phones are ready to meet my needs. + +### Android vs. iPhone bottom line: Why Android wins long term + +Despite its painful shortcomings, Android treats me like an adult. It doesn't lock me into only two methods for backing up my data. Yes, some of Android's limitations are due to the fact that it's focused on letting me choose how to handle my data. But, I also get to choose my own device, add storage on a whim. Android enables me to do a lot of cool stuff that the iPhone simply isn't capable of doing. + +At its core, Android gives non-root users greater access to the phone's functionality. For better or worse, it's a level of freedom that I think people are gravitating towards. Now there are going to be many of you who swear by the iPhone thanks to efforts like the [libimobiledevice][8] project. But take a long hard look at all the stuff Apple blocks Linux users from doing...then ask yourself – is it really worth it as a Linux user? Hit the Comments, share your thoughts on Android, iPhone or Ubuntu. + +------------------------------------------------------------------------------ + +via: http://www.datamation.com/mobile-wireless/android-vs.-iphone-pros-and-cons.html + +作者:[Matt Hartley][a] +译者:[译者ID](https://github.com/译者ID) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创翻译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]: http://www.datamation.com/author/Matt-Hartley-3080.html +[1]: http://darkskyapp.com/ +[2]: https://www.facebook.com/paper/ +[3]: https://blog.vellumatlanta.com/2016/05/04/apple-stole-my-music-no-seriously/ +[4]: https://www.airdroid.com/ +[5]: http://tasker.dinglisch.net/ +[6]: https://support.google.com/nexus/answer/2819582?hl=en +[7]: https://play.google.com/store/apps/details?id=com.koushikdutta.backup&hl=en +[8]: http://www.libimobiledevice.org/ + From 419bb28718c5277cf84db526207d2cf63f23dde1 Mon Sep 17 00:00:00 2001 From: Ezio Date: Sun, 31 Jul 2016 12:01:35 +0800 Subject: [PATCH 082/122] =?UTF-8?q?20160731-2=20=E9=80=89=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ... Use Awk Special Patterns begin and end.md | 166 ++++++++++++++++++ 1 file changed, 166 insertions(+) create mode 100644 sources/tech/awk/20160719 Part 9 - Learn How to Use Awk Special Patterns begin and end.md diff --git a/sources/tech/awk/20160719 Part 9 - Learn How to Use Awk Special Patterns begin and end.md b/sources/tech/awk/20160719 Part 9 - Learn How to Use Awk Special Patterns begin and end.md new file mode 100644 index 0000000000..f64e834ca1 --- /dev/null +++ b/sources/tech/awk/20160719 Part 9 - Learn How to Use Awk Special Patterns begin and end.md @@ -0,0 +1,166 @@ +Learn How to Use Awk Special Patterns ‘BEGIN and END’ – Part 9 +=============================================================== + +In Part 8 of this Awk series, we introduced some powerful Awk command features, that is variables, numeric expressions and assignment operators. + +As we advance, in this segment, we shall cover more Awk features, and that is the special patterns: `BEGIN` and `END`. + +![](http://www.tecmint.com/wp-content/uploads/2016/07/Learn-Awk-Patterns-BEGIN-and-END.png) +>Learn Awk Patterns BEGIN and END + +These special features will prove helpful as we try to expand on and explore more methods of building complex Awk operations. + +To get started, let us drive our thoughts back to the introduction of the Awk series, remember when we started this series, I pointed out that the general syntax of a running an Awk command is: + +``` +# awk 'script' filenames +``` + +And in the syntax above, the Awk script has the form: + +``` +/pattern/ { actions } +``` + +When you consider the pattern in the script, it is normally a regular expression, additionally, you can also think of pattern as special patterns `BEGIN` and `END`. Therefore, we can also write an Awk command in the form below: + +``` +awk ' +BEGIN { actions } +/pattern/ { actions } +/pattern/ { actions } +………. +END { actions } +' filenames +``` + +In the event that you use the special patterns: `BEGIN` and `END` in an Awk script, this is what each of them means: + +- `BEGIN` pattern: means that Awk will execute the action(s) specified in `BEGIN` once before any input lines are read. +- `END` pattern: means that Awk will execute the action(s) specified in `END` before it actually exits. + +And the flow of execution of the an Awk command script which contains these special patterns is as follows: + +- When the `BEGIN` pattern is used in a script, all the actions for `BEGIN` are executed once before any input line is read. +- Then an input line is read and parsed into the different fields. +- Next, each of the non-special patterns specified is compared with the input line for a match, when a match is found, the action(s) for that pattern are then executed. This stage will be repeated for all the patterns you have specified. +- Next, stage 2 and 3 are repeated for all input lines. +- When all input lines have been read and dealt with, in case you specify the `END` pattern, the action(s) will be executed. + +You should always remember this sequence of execution when working with the special patterns to achieve the best results in an Awk operation. + +To understand it all, let us illustrate using the example from part 8, about the list of domains owned by Tecmint, as stored in a file named domains.txt. + +``` +news.tecmint.com +tecmint.com +linuxsay.com +windows.tecmint.com +tecmint.com +news.tecmint.com +tecmint.com +linuxsay.com +tecmint.com +news.tecmint.com +tecmint.com +linuxsay.com +windows.tecmint.com +tecmint.com +``` + +``` +$ cat ~/domains.txt +``` + +![](http://www.tecmint.com/wp-content/uploads/2016/07/View-Contents-of-File.png) +>View Contents of File + +In this example, we want to count the number of times the domain `tecmint.com` is listed in the file domains.txt. So we wrote a small shell script to help us do that using the idea of variables, numeric expressions and assignment operators which has the following content: + +``` +#!/bin/bash +for file in $@; do +if [ -f $file ] ; then +#print out filename +echo "File is: $file" +#print a number incrementally for every line containing tecmint.com +awk '/^tecmint.com/ { counter+=1 ; printf "%s\n", counter ; }' $file +else +#print error info incase input is not a file +echo "$file is not a file, please specify a file." >&2 && exit 1 +fi +done +#terminate script with exit code 0 in case of successful execution +exit 0 +``` + +Let us now employ the two special patterns: `BEGIN` and `END` in the Awk command in the script above as follows: + +We shall alter the script: + +``` +awk '/^tecmint.com/ { counter+=1 ; printf "%s\n", counter ; }' $file +``` + +To: + +``` +awk ' BEGIN { print "The number of times tecmint.com appears in the file is:" ; } +/^tecmint.com/ { counter+=1 ; } +END { printf "%s\n", counter ; } +' $file +``` + +After making the changes to the Awk command, the complete shell script now looks like this: + +``` +#!/bin/bash +for file in $@; do +if [ -f $file ] ; then +#print out filename +echo "File is: $file" +#print the total number of times tecmint.com appears in the file +awk ' BEGIN { print "The number of times tecmint.com appears in the file is:" ; } +/^tecmint.com/ { counter+=1 ; } +END { printf "%s\n", counter ; } +' $file +else +#print error info incase input is not a file +echo "$file is not a file, please specify a file." >&2 && exit 1 +fi +done +#terminate script with exit code 0 in case of successful execution +exit 0 +``` + +![](http://www.tecmint.com/wp-content/uploads/2016/07/Awk-BEGIN-and-END-Patterns.png) +>Awk BEGIN and END Patterns + +When we run the script above, it will first of all print the location of the file domains.txt, then the Awk command script is executed, where the `BEGIN` special pattern helps us print out the message “`The number of times tecmint.com appears in the file is:`” before any input lines are read from the file. + +Then our pattern, `/^tecmint.com/` is compared against every input line and the action, `{ counter+=1 ; }` is executed for each input line, which counts the number of times `tecmint.com` appears in the file. + +Finally, the `END` pattern will print the total the number of times the domain `tecmint.com` appears in the file. + +``` +$ ./script.sh ~/domains.txt +``` +![](http://www.tecmint.com/wp-content/uploads/2016/07/Script-to-Count-Number-of-Times-String-Appears.png) +>Script to Count Number of Times String Appears + +To conclude, we walked through more Awk features exploring on the concepts of special pattern: `BEGIN` and `END`. + +As I pointed out before, these Awk features will help us build more complex text filtering operations, there is more to cover under Awk features and in part 10, we shall approach the idea of Awk built-in variables, so stay connected. + + +-------------------------------------------------------------------------------- + +via: http://www.tecmint.com/learn-use-awk-special-patterns-begin-and-end/ + +作者:[Aaron Kili][a] +译者:[译者ID](https://github.com/译者ID) +校对:[校对ID](https://github.com/校对ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]: http://www.tecmint.com/author/aaronkili/ From 4a6dae274e72492ba7c2bfcbcdbecf3e7dc54541 Mon Sep 17 00:00:00 2001 From: Ezio Date: Sun, 31 Jul 2016 12:07:54 +0800 Subject: [PATCH 083/122] =?UTF-8?q?20160731-3=20=E9=80=89=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...Learn How to Use Awk Built-in Variables.md | 119 ++++++++++++++++++ 1 file changed, 119 insertions(+) create mode 100644 sources/tech/awk/20160725 Part 10 - Learn How to Use Awk Built-in Variables.md diff --git a/sources/tech/awk/20160725 Part 10 - Learn How to Use Awk Built-in Variables.md b/sources/tech/awk/20160725 Part 10 - Learn How to Use Awk Built-in Variables.md new file mode 100644 index 0000000000..4cbecac8c9 --- /dev/null +++ b/sources/tech/awk/20160725 Part 10 - Learn How to Use Awk Built-in Variables.md @@ -0,0 +1,119 @@ +Learn How to Use Awk Built-in Variables – Part 10 +================================================= + +As we uncover the section of Awk features, in this part of the series, we shall walk through the concept of built-in variables in Awk. There are two types of variables you can use in Awk, these are; user-defined variables, which we covered in Part 8 and built-in variables. + +![](http://www.tecmint.com/wp-content/uploads/2016/07/Awk-Built-in-Variables-Examples.png) +>Awk Built in Variables Examples + +Built-in variables have values already defined in Awk, but we can also carefully alter those values, the built-in variables include: + +- `FILENAME` : current input file name( do not change variable name) +- `FR` : number of the current input line (that is input line 1, 2, 3… so on, do not change variable name) +- `NF` : number of fields in current input line (do not change variable name) +- `OFS` : output field separator +- `FS` : input field separator +- `ORS` : output record separator +- `RS` : input record separator + +Let us proceed to illustrate the use of some of the Awk built-in variables above: + +To read the filename of the current input file, you can use the `FILENAME` built-in variable as follows: + +``` +$ awk ' { print FILENAME } ' ~/domains.txt +``` + +![](http://www.tecmint.com/wp-content/uploads/2016/07/Awk-FILENAME-Variable.png) +>Awk FILENAME Variable + +You will realize that, the filename is printed out for each input line, that is the default behavior of Awk when you use `FILENAME` built-in variable. + +Using `NR` to count the number of lines (records) in an input file, remember that, it also counts the empty lines, as we shall see in the example below. + +When we view the file domains.txt using cat command, it contains 14 lines with text and empty 2 lines: + +``` +$ cat ~/domains.txt +``` + +![](http://www.tecmint.com/wp-content/uploads/2016/07/Print-Contents-of-File.png) +>Print Contents of File + + +``` +$ awk ' END { print "Number of records in file is: ", NR } ' ~/domains.txt +``` + +![](http://www.tecmint.com/wp-content/uploads/2016/07/Awk-Count-Number-of-Lines.png) +>Awk Count Number of Lines + +To count the number of fields in a record or line, we use the NR built-in variable as follows: + +``` +$ cat ~/names.txt +``` + +![](http://www.tecmint.com/wp-content/uploads/2016/07/List-File-Contents.png) +>List File Contents + +``` +$ awk '{ print "Record:",NR,"has",NF,"fields" ; }' ~/names.txt +``` + +![](http://www.tecmint.com/wp-content/uploads/2016/07/Awk-Count-Number-of-Fields-in-File.png) +>Awk Count Number of Fields in File + +Next, you can also specify an input field separator using the FS built-in variable, it defines how Awk divides input lines into fields. + +The default value for FS is space and tab, but we can change the value of FS to any character that will instruct Awk to divide input lines accordingly. + +There are two methods to do this: + +- one method is to use the FS built-in variable +- and the second is to invoke the -F Awk option + +Consider the file /etc/passwd on a Linux system, the fields in this file are divided using the : character, so we can specify it as the new input field separator when we want to filter out certain fields as in the following examples: + +We can use the `-F` option as follows: + +``` +$ awk -F':' '{ print $1, $4 ;}' /etc/passwd +``` + +![](http://www.tecmint.com/wp-content/uploads/2016/07/Awk-Filter-Fields-in-Password-File.png) +>Awk Filter Fields in Password File + +Optionally, we can also take advantage of the FS built-in variable as below: + +``` +$ awk ' BEGIN { FS=“:” ; } { print $1, $4 ; } ' /etc/passwd +``` + +![](http://www.tecmint.com/wp-content/uploads/2016/07/Filter-Fields-in-File-Using-Awk.png) +>Filter Fields in File Using Awk + +To specify an output field separator, use the OFS built-in variable, it defines how the output fields will be separated using the character we use as in the example below: + +``` +$ awk -F':' ' BEGIN { OFS="==>" ;} { print $1, $4 ;}' /etc/passwd +``` + +![](http://www.tecmint.com/wp-content/uploads/2016/07/Add-Separator-to-Field-in-File.png) +>Add Separator to Field in File + +In this Part 10, we have explored the idea of using Awk built-in variables which come with predefined values. But we can also change these values, though, it is not recommended to do so unless you know what you are doing, with adequate understanding. + +After this, we shall progress to cover how we can use shell variables in Awk command operations, therefore, stay connected to Tecmint. + +-------------------------------------------------------------------------------- + +via: http://www.tecmint.com/awk-built-in-variables-examples/?utm_source=feedburner&utm_medium=feed&utm_campaign=Feed%3A+tecmint+%28Tecmint%3A+Linux+Howto%27s+Guide%29 + +作者:[Aaron Kili][a] +译者:[译者ID](https://github.com/译者ID) +校对:[校对ID](https://github.com/校对ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]: http://www.tecmint.com/author/aaronkili/ From b6f2ecb0404edbd7074f9ffd3da07bd5f421a55f Mon Sep 17 00:00:00 2001 From: Ezio Date: Sun, 31 Jul 2016 12:19:36 +0800 Subject: [PATCH 084/122] =?UTF-8?q?20160731-4=20=E9=80=89=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...Audio files with Octave 4.0.0 on Ubuntu.md | 138 ++++++++++++++++++ 1 file changed, 138 insertions(+) create mode 100644 sources/tech/20160616 Part 1 - Scientific Audio Processing How to read and write Audio files with Octave 4.0.0 on Ubuntu.md diff --git a/sources/tech/20160616 Part 1 - Scientific Audio Processing How to read and write Audio files with Octave 4.0.0 on Ubuntu.md b/sources/tech/20160616 Part 1 - Scientific Audio Processing How to read and write Audio files with Octave 4.0.0 on Ubuntu.md new file mode 100644 index 0000000000..80300deb6b --- /dev/null +++ b/sources/tech/20160616 Part 1 - Scientific Audio Processing How to read and write Audio files with Octave 4.0.0 on Ubuntu.md @@ -0,0 +1,138 @@ +Scientific Audio Processing, Part I - How to read and write Audio files with Octave 4.0.0 on Ubuntu +================ + +Octave, the equivalent software to Matlab in Linux, has a number of functions and commands that allow the acquisition, recording, playback and digital processing of audio signals for entertainment applications, research, medical, or any other science areas. In this tutorial, we will use Octave V4.0.0 in Ubuntu and will start reading from audio files through writing and playing signals to emulate sounds used in a wide range of activities. + +Note that the main focus of this tutorial is not to install or learn to use an audio processing software already established, but rather to understand how it works from the point of view of design and audio engineering. + +### Prerequisites + +The first step is to install octave. Run the following commands in a terminal to add the Octave PPA in Ubuntu and install the software. + +``` +sudo apt-add-repository ppa:octave/stable +sudo apt-get update +sudo apt-get install octave +``` + +### Step 1: Opening Octave. + +In this step we open the software by clicking on its icon, we can change the work directory by clicking on the File Browser dropdown. + +![](https://www.howtoforge.com/images/how-to-read-and-write-audio-files-with-octave-4-in-ubuntu/initial.png) + +### Step 2: Audio Info + +The command "audioinfo" shows us relevant information about the audio file that we will process. + +``` +>> info = audioinfo ('testing.ogg') +``` + +![](https://www.howtoforge.com/images/how-to-read-and-write-audio-files-with-octave-4-in-ubuntu/audioinfo.png) + +### Step 3: Reading an audio File + +In this tutorial I will read and use ogg files for which it is feasible to read characteristics like sampling , audio type (stereo or mono), number of channels, etc. I should mention that for purposes of this tutorial, all the commands used will be executed in the terminal window of Octave. First, we have to save the ogg file in a variable. Note: it´s important that the file must be in the work path of Octave + +``` +>> file='yourfile.ogg' +``` + +``` +>> [M, fs] = audioread(file) +``` + +Where M is a matrix of one or two columns, depending on the number of channels and fs is the sampling frequency. + +![](https://www.howtoforge.com/images/how-to-read-and-write-audio-files-with-octave-4-in-ubuntu/reading.png) + +![](https://www.howtoforge.com/images/how-to-read-and-write-audio-files-with-octave-4-in-ubuntu/matrix.png) + +![](https://www.howtoforge.com/images/how-to-read-and-write-audio-files-with-octave-4-in-ubuntu/big/frequency.png) + +There are some options that we can use for reading audio files, such as: + +``` +>> [y, fs] = audioread (filename, samples) + +>> [y, fs] = audioread (filename, datatype) + +>> [y, fs] = audioread (filename, samples, datatype) +``` + +Where samples specifies starting and ending frames and datatype specifies the data type to return. We can assign values to any variable: + +``` +>> samples = [1, fs) + +>> [y, fs] = audioread (filename, samples) +``` + +And about datatype: + +``` +>> [y,Fs] = audioread(filename,'native') +``` + +If the value is 'native' then the type of data depends on how the data is stored in the audio file. + +### Step 4: Writing an audio file + +Creating the ogg file: + +For this purpose, we are going to generate an ogg file with values from a cosine. The sampling frequency that I will use is 44100 samples per second and the file will last for 10 seconds. The frequency of the cosine signal is 440 Hz. + +``` +>> filename='cosine.ogg'; +>> fs=44100; +>> t=0:1/fs:10; +>> w=2*pi*440*t; +>> signal=cos(w); +>> audiowrite(filename, signal, fs); +``` + +This creates a file named 'cosine.ogg' in our workspace that contains the cosine signal. + +![](https://www.howtoforge.com/images/how-to-read-and-write-audio-files-with-octave-4-in-ubuntu/cosinefile.png) + +If we play the 'cosine.ogg' file then this will reproduce a 440Hz tone which is equivalent to an 'A' musical tone. If we want to see the values saved in the file we have to 'read' the file with the 'audioread' function. In a further tutorial, we will see how to write an audio file with two channels. + +### Step 5: Playing an audio file + +Octave, by default, has an audio player that we can use for testing purposes. Use the following functions as example: + +``` + >> [y,fs]=audioread('yourfile.ogg'); +>> player=audioplayer(y, fs, 8) + + scalar structure containing the fields: + + BitsPerSample = 8 + CurrentSample = 0 + DeviceID = -1 + NumberOfChannels = 1 + Running = off + SampleRate = 44100 + TotalSamples = 236473 + Tag = + Type = audioplayer + UserData = [](0x0) +>> play(player); +``` + +In the next parts of the tutorial, we will see advanced audio processing features and possible use cases for scientific and commercial use. + +-------------------------------------------------------------------------------- + +via: https://www.howtoforge.com/tutorial/how-to-read-and-write-audio-files-with-octave-4-in-ubuntu/ + +作者:[David Duarte][a] +译者:[译者ID](https://github.com/译者ID) +校对:[校对ID](https://github.com/校对ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]: https://twitter.com/intent/follow?original_referer=https%3A%2F%2Fwww.howtoforge.com%2Ftutorial%2Fhow-to-read-and-write-audio-files-with-octave-4-in-ubuntu%2F&ref_src=twsrc%5Etfw®ion=follow_link&screen_name=howtoforgecom&tw_p=followbutton + + From db95b0e90111e70434454575b4790dc94557bce4 Mon Sep 17 00:00:00 2001 From: Ezio Date: Sun, 31 Jul 2016 13:16:10 +0800 Subject: [PATCH 085/122] =?UTF-8?q?20160731-0=20=E9=80=89=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 长文,机器学习 --- ...ce portfolio - Machine learning project.md | 845 ++++++++++++++++++ 1 file changed, 845 insertions(+) create mode 100644 sources/tech/20160705 Building a data science portfolio - Machine learning project.md diff --git a/sources/tech/20160705 Building a data science portfolio - Machine learning project.md b/sources/tech/20160705 Building a data science portfolio - Machine learning project.md new file mode 100644 index 0000000000..ca57b2e83c --- /dev/null +++ b/sources/tech/20160705 Building a data science portfolio - Machine learning project.md @@ -0,0 +1,845 @@ +Building a data science portfolio: Machine learning project +=========================================================== + +>This is the third in a series of posts on how to build a Data Science Portfolio. If you like this and want to know when the next post in the series is released, you can [subscribe at the bottom of the page][1]. + +Data science companies are increasingly looking at portfolios when making hiring decisions. One of the reasons for this is that a portfolio is the best way to judge someone’s real-world skills. The good news for you is that a portfolio is entirely within your control. If you put some work in, you can make a great portfolio that companies are impressed by. + +The first step in making a high-quality portfolio is to know what skills to demonstrate. The primary skills that companies want in data scientists, and thus the primary skills they want a portfolio to demonstrate, are: + +- Ability to communicate +- Ability to collaborate with others +- Technical competence +- Ability to reason about data +- Motivation and ability to take initiative + +Any good portfolio will be composed of multiple projects, each of which may demonstrate 1-2 of the above points. This is the third post in a series that will cover how to make a well-rounded data science portfolio. In this post, we’ll cover how to make the second project in your portfolio, and how to build an end to end machine learning project. At the end, you’ll have a project that shows your ability to reason about data, and your technical competence. [Here’s][2] the completed project if you want to take a look. + +### An end to end project + +As a data scientist, there are times when you’ll be asked to take a dataset and figure out how to [tell a story with it][3]. In times like this, it’s important to communicate very well, and walk through your process. Tools like Jupyter notebook, which we used in a previous post, are very good at helping you do this. The expectation here is that the deliverable is a presentation or document summarizing your findings. + +However, there are other times when you’ll be asked to create a project that has operational value. A project with operational value directly impacts the day-to-day operations of a company, and will be used more than once, and often by multiple people. A task like this might be “create an algorithm to forecast our churn rate”, or “create a model that can automatically tag our articles”. In cases like this, storytelling is less important than technical competence. You need to be able to take a dataset, understand it, then create a set of scripts that can process that data. It’s often important that these scripts run quickly, and use minimal system resources like memory. It’s very common that these scripts will be run several times, so the deliverable becomes the scripts themselves, not a presentation. The deliverable is often integrated into operational flows, and may even be user-facing. + +The main components of building an end to end project are: + +- Understanding the context +- Exploring the data and figuring out the nuances +- Creating a well-structured project, so its easy to integrate into operational flows +- Writing high-performance code that runs quickly and uses minimal system resources +- Documenting the installation and usage of your code well, so others can use it + +In order to effectively create a project of this kind, we’ll need to work with multiple files. Using a text editor like [Atom][4], or an IDE like [PyCharm][5] is highly recommended. These tools will allow you to jump between files, and edit files of different types, like markdown files, Python files, and csv files. Structuring your project so it’s easy to version control and upload to collaborative coding tools like [Github][6] is also useful. + +![](https://www.dataquest.io/blog/images/end_to_end/github.png) +>This project on Github. + +We’ll use our editing tools along with libraries like [Pandas][7] and [scikit-learn][8] in this post. We’ll make extensive use of Pandas [DataFrames][9], which make it easy to read in and work with tabular data in Python. + +### Finding good datasets + +A good dataset for an end to end portfolio project can be hard to find. [The dataset][10] needs to be sufficiently large that memory and performance constraints come into play. It also needs to potentially be operationally useful. For instance, this dataset, which contains data on the admission criteria, graduation rates, and graduate future earnings for US colleges would be a great dataset to use to tell a story. However, as you think about the dataset, it becomes clear that there isn’t enough nuance to build a good end to end project with it. For example, you could tell someone their potential future earnings if they went to a specific college, but that would be a quick lookup without enough nuance to demonstrate technical competence. You could also figure out if colleges with higher admissions standards tend to have graduates who earn more, but that would be more storytelling than operational. + +These memory and performance constraints tend to come into play when you have more than a gigabyte of data, and when you have some nuance to what you want to predict, which involves running algorithms over the dataset. + +A good operational dataset enables you to build a set of scripts that transform the data, and answer dynamic questions. A good example would be a dataset of stock prices. You would be able to predict the prices for the next day, and keep feeding new data to the algorithm as the markets closed. This would enable you to make trades, and potentially even profit. This wouldn’t be telling a story – it would be adding direct value. + +Some good places to find datasets like this are: + +- [/r/datasets][11] – a subreddit that has hundreds of interesting datasets. +- [Google Public Datasets][12] – public datasets available through Google BigQuery. +- [Awesome datasets][13] – a list of datasets, hosted on Github. + +As you look through these datasets, think about what questions someone might want answered with the dataset, and think if those questions are one-time (“how did housing prices correlate with the S&P 500?”), or ongoing (“can you predict the stock market?”). The key here is to find questions that are ongoing, and require the same code to be run multiple times with different inputs (different data). + +For the purposes of this post, we’ll look at [Fannie Mae Loan Data][14]. Fannie Mae is a government sponsored enterprise in the US that buys mortgage loans from other lenders. It then bundles these loans up into mortgage-backed securities and resells them. This enables lenders to make more mortgage loans, and creates more liquidity in the market. This theoretically leads to more homeownership, and better loan terms. From a borrowers perspective, things stay largely the same, though. + +Fannie Mae releases two types of data – data on loans it acquires, and data on how those loans perform over time. In the ideal case, someone borrows money from a lender, then repays the loan until the balance is zero. However, some borrowers miss multiple payments, which can cause foreclosure. Foreclosure is when the house is seized by the bank because mortgage payments cannot be made. Fannie Mae tracks which loans have missed payments on them, and which loans needed to be foreclosed on. This data is published quarterly, and lags the current date by 1 year. As of this writing, the most recent dataset that’s available is from the first quarter of 2015. + +Acquisition data, which is published when the loan is acquired by Fannie Mae, contains information on the borrower, including credit score, and information on their loan and home. Performance data, which is published every quarter after the loan is acquired, contains information on the payments being made by the borrower, and the foreclosure status, if any. A loan that is acquired may have dozens of rows in the performance data. A good way to think of this is that the acquisition data tells you that Fannie Mae now controls the loan, and the performance data contains a series of status updates on the loan. One of the status updates may tell us that the loan was foreclosed on during a certain quarter. + +![](https://www.dataquest.io/blog/images/end_to_end/foreclosure.jpg) +>A foreclosed home being sold. + +### Picking an angle + +There are a few directions we could go in with the Fannie Mae dataset. We could: + +- Try to predict the sale price of a house after it’s foreclosed on. +- Predict the payment history of a borrower. +- Figure out a score for each loan at acquisition time. + +The important thing is to stick to a single angle. Trying to focus on too many things at once will make it hard to make an effective project. It’s also important to pick an angle that has sufficient nuance. Here are examples of angles without much nuance: + +- Figuring out which banks sold loans to Fannie Mae that were foreclosed on the most. +- Figuring out trends in borrower credit scores. +- Exploring which types of homes are foreclosed on most often. +- Exploring the relationship between loan amounts and foreclosure sale prices + +All of the above angles are interesting, and would be great if we were focused on storytelling, but aren’t great fits for an operational project. + +With the Fannie Mae dataset, we’ll try to predict whether a loan will be foreclosed on in the future by only using information that was available when the loan was acquired. In effect, we’ll create a “score” for any mortgage that will tell us if Fannie Mae should buy it or not. This will give us a nice foundation to build on, and will be a great portfolio piece. + +### Understanding the data + +Let’s take a quick look at the raw data files. Here are the first few rows of the acquisition data from quarter 1 of 2012: + +``` +100000853384|R|OTHER|4.625|280000|360|02/2012|04/2012|31|31|1|23|801|N|C|SF|1|I|CA|945||FRM| +100003735682|R|SUNTRUST MORTGAGE INC.|3.99|466000|360|01/2012|03/2012|80|80|2|30|794|N|P|SF|1|P|MD|208||FRM|788 +100006367485|C|PHH MORTGAGE CORPORATION|4|229000|360|02/2012|04/2012|67|67|2|36|802|N|R|SF|1|P|CA|959||FRM|794 +``` + +Here are the first few rows of the performance data from quarter 1 of 2012: + +``` +100000853384|03/01/2012|OTHER|4.625||0|360|359|03/2042|41860|0|N|||||||||||||||| +100000853384|04/01/2012||4.625||1|359|358|03/2042|41860|0|N|||||||||||||||| +100000853384|05/01/2012||4.625||2|358|357|03/2042|41860|0|N|||||||||||||||| +``` + +Before proceeding too far into coding, it’s useful to take some time and really understand the data. This is more critical in operational projects – because we aren’t interactively exploring the data, it can be harder to spot certain nuances unless we find them upfront. In this case, the first step is to read the materials on the Fannie Mae site: + +- [Overview][15] +- [Glossary of useful terms][16] +- [FAQs][17] +- [Columns in the Acquisition and Performance files][18] +- [Sample Acquisition data file][19] +- [Sample Performance data file][20] + +After reading through these files, we know some key facts that will help us: + +- There’s an Acquisition file and a Performance file for each quarter, starting from the year 2000 to present. There’s a 1 year lag in the data, so the most recent data is from 2015 as of this writing. +- The files are in text format, with a pipe (|) as a delimiter. +- The files don’t have headers, but we have a list of what each column is. +- All together, the files contain data on 22 million loans. +- Because the Performance files contain information on loans acquired in previous years, there will be more performance data for loans acquired in earlier years (ie loans acquired in 2014 won’t have much performance history). + +These small bits of information will save us a ton of time as we figure out how to structure our project and work with the data. + +### Structuring the project + +Before we start downloading and exploring the data, it’s important to think about how we’ll structure the project. When building an end-to-end project, our primary goals are: + +- Creating a solution that works +- Having a solution that runs quickly and uses minimal resources +- Enabling others to easily extend our work +- Making it easy for others to understand our code +- Writing as little code as possible + +In order to achieve these goals, we’ll need to structure our project well. A well structured project follows a few principles: + +- Separates data files and code files. +- Separates raw data from generated data. +- Has a README.md file that walks people through installing and using the project. +- Has a requirements.txt file that contains all the packages needed to run the project. +- Has a single settings.py file that contains any settings that are used in other files. + - For example, if you are reading the same file from multiple Python scripts, it’s useful to have them all import settings and get the file name from a centralized place. +- Has a .gitignore file that prevents large or secret files from being committed. +- Breaks each step in our task into a separate file that can be executed separately. + - For example, we may have one file for reading in the data, one for creating features, and one for making predictions. +- Stores intermediate values. For example, one script may output a file that the next script can read. + - This enables us to make changes in our data processing flow without recalculating everything. + +Our file structure will look something like this shortly: + +``` +loan-prediction +├── data +├── processed +├── .gitignore +├── README.md +├── requirements.txt +├── settings.py +``` + +### Creating the initial files + +To start with, we’ll need to create a loan-prediction folder. Inside that folder, we’ll need to make a data folder and a processed folder. The first will store our raw data, and the second will store any intermediate calculated values. + +Next, we’ll make a .gitignore file. A .gitignore file will make sure certain files are ignored by git and not pushed to Github. One good example of such a file is the .DS_Store file created by OSX in every folder. A good starting point for a .gitignore file is here. We’ll also want to ignore the data files because they are very large, and the Fannie Mae terms prevent us from redistributing them, so we should add two lines to the end of our file: + +``` +data +processed +``` + +[Here’s][21] an example .gitignore file for this project. + +Next, we’ll need to create README.md, which will help people understand the project. .md indicates that the file is in markdown format. Markdown enables you write plain text, but also add some fancy formatting if you want. [Here’s][22] a guide on markdown. If you upload a file called README.md to Github, Github will automatically process the markdown, and show it to anyone who views the project. [Here’s][23] an example. + +For now, we just need to put a simple description in README.md: + +``` +Loan Prediction +----------------------- + +Predict whether or not loans acquired by Fannie Mae will go into foreclosure. Fannie Mae acquires loans from other lenders as a way of inducing them to lend more. Fannie Mae releases data on the loans it has acquired and their performance afterwards [here](http://www.fanniemae.com/portal/funding-the-market/data/loan-performance-data.html). +``` + +Now, we can create a requirements.txt file. This will make it easy for other people to install our project. We don’t know exactly what libraries we’ll be using yet, but here’s a good starting point: + +``` +pandas +matplotlib +scikit-learn +numpy +ipython +scipy +``` + +The above libraries are the most commonly used for data analysis tasks in Python, and its fair to assume that we’ll be using most of them. [Here’s][24] an example requirements file for this project. + +After creating requirements.txt, you should install the packages. For this post, we’ll be using Python 3. If you don’t have Python installed, you should look into using [Anaconda][25], a Python installer that also installs all the packages listed above. + +Finally, we can just make a blank settings.py file, since we don’t have any settings for our project yet. + +### Acquiring the data + +Once we have the skeleton of our project, we can get the raw data. + +Fannie Mae has some restrictions around acquiring the data, so you’ll need to sign up for an account. You can find the download page [here][26]. After creating an account, you’ll be able to download as few or as many loan data files as you want. The files are in zip format, and are reasonably large after decompression. + +For the purposes of this blog post, we’ll download everything from Q1 2012 to Q1 2015, inclusive. We’ll then need to unzip all of the files. After unzipping the files, remove the original .zip files. At the end, the loan-prediction folder should look something like this: + +``` +loan-prediction +├── data +│ ├── Acquisition_2012Q1.txt +│ ├── Acquisition_2012Q2.txt +│ ├── Performance_2012Q1.txt +│ ├── Performance_2012Q2.txt +│ └── ... +├── processed +├── .gitignore +├── README.md +├── requirements.txt +├── settings.py +``` + +After downloading the data, you can use the head and tail shell commands to look at the lines in the files. Do you see any columns that aren’t needed? It might be useful to consult the [pdf of column names][27] while doing this. + +### Reading in the data + +There are two issues that make our data hard to work with right now: + +- The acquisition and performance datasets are segmented across multiple files. +- Each file is missing headers. + +Before we can get started on working with the data, we’ll need to get to the point where we have one file for the acquisition data, and one file for the performance data. Each of the files will need to contain only the columns we care about, and have the proper headers. One wrinkle here is that the performance data is quite large, so we should try to trim some of the columns if we can. + +The first step is to add some variables to settings.py, which will contain the paths to our raw data and our processed data. We’ll also add a few other settings that will be useful later on: + +``` +DATA_DIR = "data" +PROCESSED_DIR = "processed" +MINIMUM_TRACKING_QUARTERS = 4 +TARGET = "foreclosure_status" +NON_PREDICTORS = [TARGET, "id"] +CV_FOLDS = 3 +``` + +Putting the paths in settings.py will put them in a centralized place and make them easy to change down the line. When referring to the same variables in multiple files, it’s easier to put them in a central place than edit them in every file when you want to change them. [Here’s][28] an example settings.py file for this project. + +The second step is to create a file called assemble.py that will assemble all the pieces into 2 files. When we run python assemble.py, we’ll get 2 data files in the processed directory. + +We’ll then start writing code in assemble.py. We’ll first need to define the headers for each file, so we’ll need to look at [pdf of column names][29] and create lists of the columns in each Acquisition and Performance file: + +``` +HEADERS = { + "Acquisition": [ + "id", + "channel", + "seller", + "interest_rate", + "balance", + "loan_term", + "origination_date", + "first_payment_date", + "ltv", + "cltv", + "borrower_count", + "dti", + "borrower_credit_score", + "first_time_homebuyer", + "loan_purpose", + "property_type", + "unit_count", + "occupancy_status", + "property_state", + "zip", + "insurance_percentage", + "product_type", + "co_borrower_credit_score" + ], + "Performance": [ + "id", + "reporting_period", + "servicer_name", + "interest_rate", + "balance", + "loan_age", + "months_to_maturity", + "maturity_date", + "msa", + "delinquency_status", + "modification_flag", + "zero_balance_code", + "zero_balance_date", + "last_paid_installment_date", + "foreclosure_date", + "disposition_date", + "foreclosure_costs", + "property_repair_costs", + "recovery_costs", + "misc_costs", + "tax_costs", + "sale_proceeds", + "credit_enhancement_proceeds", + "repurchase_proceeds", + "other_foreclosure_proceeds", + "non_interest_bearing_balance", + "principal_forgiveness_balance" + ] +} +``` + +The next step is to define the columns we want to keep. Since all we’re measuring on an ongoing basis about the loan is whether or not it was ever foreclosed on, we can discard many of the columns in the performance data. We’ll need to keep all the columns in the acquisition data, though, because we want to maximize the information we have about when the loan was acquired (after all, we’re predicting if the loan will ever be foreclosed or not at the point it’s acquired). Discarding columns will enable us to save disk space and memory, while also speeding up our code. + +``` +SELECT = { + "Acquisition": HEADERS["Acquisition"], + "Performance": [ + "id", + "foreclosure_date" + ] +} +``` + +Next, we’ll write a function to concatenate the data sets. The below code will: + +- Import a few needed libraries, including settings. +- Define a function concatenate, that: + - Gets the names of all the files in the data directory. + - Loops through each file. + - If the file isn’t the right type (doesn’t start with the prefix we want), we ignore it. + - Reads the file into a [DataFrame][30] with the right settings using the Pandas [read_csv][31] function. + - Sets the separator to | so the fields are read in correctly. + - The data has no header row, so sets header to None to indicate this. + - Sets names to the right value from the HEADERS dictionary – these will be the column names of our DataFrame. + - Picks only the columns from the DataFrame that we added in SELECT. +- Concatenates all the DataFrames together. +- Writes the concatenated DataFrame back to a file. + +``` +import os +import settings +import pandas as pd + +def concatenate(prefix="Acquisition"): + files = os.listdir(settings.DATA_DIR) + full = [] + for f in files: + if not f.startswith(prefix): + continue + + data = pd.read_csv(os.path.join(settings.DATA_DIR, f), sep="|", header=None, names=HEADERS[prefix], index_col=False) + data = data[SELECT[prefix]] + full.append(data) + + full = pd.concat(full, axis=0) + + full.to_csv(os.path.join(settings.PROCESSED_DIR, "{}.txt".format(prefix)), sep="|", header=SELECT[prefix], index=False) +``` + +We can call the above function twice with the arguments Acquisition and Performance to concatenate all the acquisition and performance files together. The below code will: + +- Only execute if the script is called from the command line with python assemble.py. +- Concatenate all the files, and result in two files: + - `processed/Acquisition.txt` + - `processed/Performance.txt` + +``` +if __name__ == "__main__": + concatenate("Acquisition") + concatenate("Performance") +``` + +We now have a nice, compartmentalized assemble.py that’s easy to execute, and easy to build off of. By decomposing the problem into pieces like this, we make it easy to build our project. Instead of one messy script that does everything, we define the data that will pass between the scripts, and make them completely separate from each other. When you’re working on larger projects, it’s a good idea to do this, because it makes it much easier to change individual pieces without having unexpected consequences on unrelated pieces of the project. + +Once we finish the assemble.py script, we can run python assemble.py. You can find the complete assemble.py file [here][32]. + +This will result in two files in the processed directory: + +``` +loan-prediction +├── data +│ ├── Acquisition_2012Q1.txt +│ ├── Acquisition_2012Q2.txt +│ ├── Performance_2012Q1.txt +│ ├── Performance_2012Q2.txt +│ └── ... +├── processed +│ ├── Acquisition.txt +│ ├── Performance.txt +├── .gitignore +├── assemble.py +├── README.md +├── requirements.txt +├── settings.py +``` + +### Computing values from the performance data + +The next step we’ll take is to calculate some values from processed/Performance.txt. All we want to do is to predict whether or not a property is foreclosed on. To figure this out, we just need to check if the performance data associated with a loan ever has a foreclosure_date. If foreclosure_date is None, then the property was never foreclosed on. In order to avoid including loans with little performance history in our sample, we’ll also want to count up how many rows exist in the performance file for each loan. This will let us filter loans without much performance history from our training data. + +One way to think of the loan data and the performance data is like this: + +![](https://github.com/LCTT/wiki-images/blob/master/TranslateProject/ref_img/001.png) + +As you can see above, each row in the Acquisition data can be related to multiple rows in the Performance data. In the Performance data, foreclosure_date will appear in the quarter when the foreclosure happened, so it should be blank prior to that. Some loans are never foreclosed on, so all the rows related to them in the Performance data have foreclosure_date blank. + +We need to compute foreclosure_status, which is a Boolean that indicates whether a particular loan id was ever foreclosed on, and performance_count, which is the number of rows in the performance data for each loan id. + +There are a few different ways to compute the counts we want: + +- We could read in all the performance data, then use the Pandas groupby method on the DataFrame to figure out the number of rows associated with each loan id, and also if the foreclosure_date is ever not None for the id. + - The upside of this method is that it’s easy to implement from a syntax perspective. + - The downside is that reading in all 129236094 lines in the data will take a lot of memory, and be extremely slow. +- We could read in all the performance data, then use apply on the acquisition DataFrame to find the counts for each id. + - The upside is that it’s easy to conceptualize. + - The downside is that reading in all 129236094 lines in the data will take a lot of memory, and be extremely slow. +- We could iterate over each row in the performance dataset, and keep a separate dictionary of counts. + - The upside is that the dataset doesn’t need to be loaded into memory, so it’s extremely fast and memory-efficient. + - The downside is that it will take slightly longer to conceptualize and implement, and we need to parse the rows manually. + +Loading in all the data will take quite a bit of memory, so let’s go with the third option above. All we need to do is to iterate through all the rows in the Performance data, while keeping a dictionary of counts per loan id. In the dictionary, we’ll keep track of how many times the id appears in the performance data, as well as if foreclosure_date is ever not None. This will give us foreclosure_status and performance_count. + +We’ll create a new file called annotate.py, and add in code that will enable us to compute these values. In the below code, we’ll: + +- Import needed libraries. +- Define a function called count_performance_rows. + - Open processed/Performance.txt. This doesn’t read the file into memory, but instead opens a file handler that can be used to read in the file line by line. + - Loop through each line in the file. + - Split the line on the delimiter (|) + - Check if the loan_id is not in the counts dictionary. + - If not, add it to counts. + - Increment performance_count for the given loan_id because we’re on a row that contains it. + - If date is not None, then we know that the loan was foreclosed on, so set foreclosure_status appropriately. + +``` +import os +import settings +import pandas as pd + +def count_performance_rows(): + counts = {} + with open(os.path.join(settings.PROCESSED_DIR, "Performance.txt"), 'r') as f: + for i, line in enumerate(f): + if i == 0: + # Skip header row + continue + loan_id, date = line.split("|") + loan_id = int(loan_id) + if loan_id not in counts: + counts[loan_id] = { + "foreclosure_status": False, + "performance_count": 0 + } + counts[loan_id]["performance_count"] += 1 + if len(date.strip()) > 0: + counts[loan_id]["foreclosure_status"] = True + return counts +``` + +### Getting the values + +Once we create our counts dictionary, we can make a function that will extract values from the dictionary if a loan_id and a key are passed in: + +``` +def get_performance_summary_value(loan_id, key, counts): + value = counts.get(loan_id, { + "foreclosure_status": False, + "performance_count": 0 + }) + return value[key] +``` + +The above function will return the appropriate value from the counts dictionary, and will enable us to assign a foreclosure_status value and a performance_count value to each row in the Acquisition data. The [get][33] method on dictionaries returns a default value if a key isn’t found, so this enables us to return sensible default values if a key isn’t found in the counts dictionary. + +### Annotating the data + +We’ve already added a few functions to annotate.py, but now we can get into the meat of the file. We’ll need to convert the acquisition data into a training dataset that can be used in a machine learning algorithm. This involves a few things: + +- Converting all columns to numeric. +- Filling in any missing values. +- Assigning a performance_count and a foreclosure_status to each row. +- Removing any rows that don’t have a lot of performance history (where performance_count is low). + +Several of our columns are strings, which aren’t useful to a machine learning algorithm. However, they are actually categorical variables, where there are a few different category codes, like R, S, and so on. We can convert these columns to numeric by assigning a number to each category label: + +![](https://github.com/LCTT/wiki-images/blob/master/TranslateProject/ref_img/002.png) + +Converting the columns this way will allow us to use them in our machine learning algorithm. + +Some of the columns also contain dates (first_payment_date and origination_date). We can split these dates into 2 columns each: + +![](https://github.com/LCTT/wiki-images/blob/master/TranslateProject/ref_img/003.png) +In the below code, we’ll transform the Acquisition data. We’ll define a function that: + +- Creates a foreclosure_status column in acquisition by getting the values from the counts dictionary. +- Creates a performance_count column in acquisition by getting the values from the counts dictionary. +- Converts each of the following columns from a string column to an integer column: + - channel + - seller + - first_time_homebuyer + - loan_purpose + - property_type + - occupancy_status + - property_state + - product_type +- Converts first_payment_date and origination_date to 2 columns each: + - Splits the column on the forward slash. + - Assigns the first part of the split list to a month column. + - Assigns the second part of the split list to a year column. + - Deletes the column. + - At the end, we’ll have first_payment_month, first_payment_year, origination_month, and origination_year. +- Fills any missing values in acquisition with -1. + +``` +def annotate(acquisition, counts): + acquisition["foreclosure_status"] = acquisition["id"].apply(lambda x: get_performance_summary_value(x, "foreclosure_status", counts)) + acquisition["performance_count"] = acquisition["id"].apply(lambda x: get_performance_summary_value(x, "performance_count", counts)) + for column in [ + "channel", + "seller", + "first_time_homebuyer", + "loan_purpose", + "property_type", + "occupancy_status", + "property_state", + "product_type" + ]: + acquisition[column] = acquisition[column].astype('category').cat.codes + + for start in ["first_payment", "origination"]: + column = "{}_date".format(start) + acquisition["{}_year".format(start)] = pd.to_numeric(acquisition[column].str.split('/').str.get(1)) + acquisition["{}_month".format(start)] = pd.to_numeric(acquisition[column].str.split('/').str.get(0)) + del acquisition[column] + + acquisition = acquisition.fillna(-1) + acquisition = acquisition[acquisition["performance_count"] > settings.MINIMUM_TRACKING_QUARTERS] + return acquisition +``` + +### Pulling everything together + +We’re almost ready to pull everything together, we just need to add a bit more code to annotate.py. In the below code, we: + +- Define a function to read in the acquisition data. +- Define a function to write the processed data to processed/train.csv +- If this file is called from the command line, like python annotate.py: + - Read in the acquisition data. + - Compute the counts for the performance data, and assign them to counts. + - Annotate the acquisition DataFrame. + - Write the acquisition DataFrame to train.csv. + +``` +def read(): + acquisition = pd.read_csv(os.path.join(settings.PROCESSED_DIR, "Acquisition.txt"), sep="|") + return acquisition + +def write(acquisition): + acquisition.to_csv(os.path.join(settings.PROCESSED_DIR, "train.csv"), index=False) + +if __name__ == "__main__": + acquisition = read() + counts = count_performance_rows() + acquisition = annotate(acquisition, counts) + write(acquisition) +``` + +Once you’re done updating the file, make sure to run it with python annotate.py, to generate the train.csv file. You can find the complete annotate.py file [here][34]. + +The folder should now look like this: + +``` +loan-prediction +├── data +│ ├── Acquisition_2012Q1.txt +│ ├── Acquisition_2012Q2.txt +│ ├── Performance_2012Q1.txt +│ ├── Performance_2012Q2.txt +│ └── ... +├── processed +│ ├── Acquisition.txt +│ ├── Performance.txt +│ ├── train.csv +├── .gitignore +├── annotate.py +├── assemble.py +├── README.md +├── requirements.txt +├── settings.py +``` + +### Finding an error metric + +We’re done with generating our training dataset, and now we’ll just need to do the final step, generating predictions. We’ll need to figure out an error metric, as well as how we want to evaluate our data. In this case, there are many more loans that aren’t foreclosed on than are, so typical accuracy measures don’t make much sense. + +If we read in the training data, and check the counts in the foreclosure_status column, here’s what we get: + +``` +import pandas as pd +import settings + +train = pd.read_csv(os.path.join(settings.PROCESSED_DIR, "train.csv")) +train["foreclosure_status"].value_counts() +``` + +``` +False 4635982 +True 1585 +Name: foreclosure_status, dtype: int64 +``` + +Since so few of the loans were foreclosed on, just checking the percentage of labels that were correctly predicted will mean that we can make a machine learning model that predicts False for every row, and still gets a very high accuracy. Instead, we’ll want to use a metric that takes the class imbalance into account, and ensures that we predict foreclosures accurately. We don’t want too many false positives, where we make predict that a loan will be foreclosed on even though it won’t, or too many false negatives, where we predict that a loan won’t be foreclosed on, but it is. Of these two, false negatives are more costly for Fannie Mae, because they’re buying loans where they may not be able to recoup their investment. + +We’ll define false negative rate as the number of loans where the model predicts no foreclosure but the the loan was actually foreclosed on, divided by the number of total loans that were actually foreclosed on. This is the percentage of actual foreclosures that the model “Missed”. Here’s a diagram: + +![](https://github.com/LCTT/wiki-images/blob/master/TranslateProject/ref_img/004.png) + +In the diagram above, 1 loan was predicted as not being foreclosed on, but it actually was. If we divide this by the number of loans that were actually foreclosed on, 2, we get the false negative rate, 50%. We’ll use this as our error metric, so we can evaluate our model’s performance. + +### Setting up the classifier for machine learning + +We’ll use cross validation to make predictions. With cross validation, we’ll divide our data into 3 groups. Then we’ll do the following: + +- Train a model on groups 1 and 2, and use the model to make predictions for group 3. +- Train a model on groups 1 and 3, and use the model to make predictions for group 2. +- Train a model on groups 2 and 3, and use the model to make predictions for group 1. + +Splitting it up into groups this way means that we never train a model using the same data we’re making predictions for. This avoids overfitting. If we overfit, we’ll get a falsely low false negative rate, which makes it hard to improve our algorithm or use it in the real world. + +[Scikit-learn][35] has a function called [cross_val_predict][36] which will make it easy to perform cross validation. + +We’ll also need to pick an algorithm to use to make predictions. We need a classifier that can do [binary classification][37]. The target variable, foreclosure_status only has two values, True and False. + +We’ll use [logistic regression][38], because it works well for binary classification, runs extremely quickly, and uses little memory. This is due to how the algorithm works – instead of constructing dozens of trees, like a random forest, or doing expensive transformations, like a support vector machine, logistic regression has far fewer steps involving fewer matrix operations. + +We can use the [logistic regression classifier][39] algorithm that’s implemented in scikit-learn. The only thing we need to pay attention to is the weights of each class. If we weight the classes equally, the algorithm will predict False for every row, because it is trying to minimize errors. However, we care much more about foreclosures than we do about loans that aren’t foreclosed on. Thus, we’ll pass balanced to the class_weight keyword argument of the [LogisticRegression][40] class, to get the algorithm to weight the foreclosures more to account for the difference in the counts of each class. This will ensure that the algorithm doesn’t predict False for every row, and instead is penalized equally for making errors in predicting either class. + +### Making predictions + +Now that we have the preliminaries out of the way, we’re ready to make predictions. We’ll create a new file called predict.py that will use the train.csv file we created in the last step. The below code will: + +- Import needed libraries. +- Create a function called cross_validate that: + - Creates a logistic regression classifier with the right keyword arguments. + - Creates a list of columns that we want to use to train the model, removing id and foreclosure_status. + - Run cross validation across the train DataFrame. + - Return the predictions. + + +``` +import os +import settings +import pandas as pd +from sklearn import cross_validation +from sklearn.linear_model import LogisticRegression +from sklearn import metrics + +def cross_validate(train): + clf = LogisticRegression(random_state=1, class_weight="balanced") + + predictors = train.columns.tolist() + predictors = [p for p in predictors if p not in settings.NON_PREDICTORS] + + predictions = cross_validation.cross_val_predict(clf, train[predictors], train[settings.TARGET], cv=settings.CV_FOLDS) + return predictions +``` + +### Predicting error + +Now, we just need to write a few functions to compute error. The below code will: + +- Create a function called compute_error that: + - Uses scikit-learn to compute a simple accuracy score (the percentage of predictions that matched the actual foreclosure_status values). +- Create a function called compute_false_negatives that: + - Combines the target and the predictions into a DataFrame for convenience. + - Finds the false negative rate. +- Create a function called compute_false_positives that: + - Combines the target and the predictions into a DataFrame for convenience. + - Finds the false positive rate. + - Finds the number of loans that weren’t foreclosed on that the model predicted would be foreclosed on. + - Divide by the total number of loans that weren’t foreclosed on. + +``` +def compute_error(target, predictions): + return metrics.accuracy_score(target, predictions) + +def compute_false_negatives(target, predictions): + df = pd.DataFrame({"target": target, "predictions": predictions}) + return df[(df["target"] == 1) & (df["predictions"] == 0)].shape[0] / (df[(df["target"] == 1)].shape[0] + 1) + +def compute_false_positives(target, predictions): + df = pd.DataFrame({"target": target, "predictions": predictions}) + return df[(df["target"] == 0) & (df["predictions"] == 1)].shape[0] / (df[(df["target"] == 0)].shape[0] + 1) +``` + +### Putting it all together + +Now, we just have to put the functions together in predict.py. The below code will: + +- Read in the dataset. +- Compute cross validated predictions. +- Compute the 3 error metrics above. +- Print the error metrics. + +``` +def read(): + train = pd.read_csv(os.path.join(settings.PROCESSED_DIR, "train.csv")) + return train + +if __name__ == "__main__": + train = read() + predictions = cross_validate(train) + error = compute_error(train[settings.TARGET], predictions) + fn = compute_false_negatives(train[settings.TARGET], predictions) + fp = compute_false_positives(train[settings.TARGET], predictions) + print("Accuracy Score: {}".format(error)) + print("False Negatives: {}".format(fn)) + print("False Positives: {}".format(fp)) +``` + +Once you’ve added the code, you can run python predict.py to generate predictions. Running everything shows that our false negative rate is .26, which means that of the foreclosed loans, we missed predicting 26% of them. This is a good start, but can use a lot of improvement! + +You can find the complete predict.py file [here][41]. + +Your file tree should now look like this: + +``` +loan-prediction +├── data +│ ├── Acquisition_2012Q1.txt +│ ├── Acquisition_2012Q2.txt +│ ├── Performance_2012Q1.txt +│ ├── Performance_2012Q2.txt +│ └── ... +├── processed +│ ├── Acquisition.txt +│ ├── Performance.txt +│ ├── train.csv +├── .gitignore +├── annotate.py +├── assemble.py +├── predict.py +├── README.md +├── requirements.txt +├── settings.py +``` + +### Writing up a README + +Now that we’ve finished our end to end project, we just have to write up a README.md file so that other people know what we did, and how to replicate it. A typical README.md for a project should include these sections: + +- A high level overview of the project, and what the goals are. +- Where to download any needed data or materials. +- Installation instructions. + - How to install the requirements. +- Usage instructions. + - How to run the project. + - What you should see after each step. +- How to contribute to the project. + - Good next steps for extending the project. + +[Here’s][42] a sample README.md for this project. + +### Next steps + +Congratulations, you’re done making an end to end machine learning project! You can find a complete example project [here][43]. It’s a good idea to upload your project to [Github][44] once you’ve finished it, so others can see it as part of your portfolio. + +There are still quite a few angles left to explore with this data. Broadly, we can split them up into 3 categories – extending this project and making it more accurate, finding other columns to predict, and exploring the data. Here are some ideas: + +- Generate more features in annotate.py. +- Switch algorithms in predict.py. +- Try using more data from Fannie Mae than we used in this post. +- Add in a way to make predictions on future data. The code we wrote will still work if we add more data, so we can add more past or future data. +- Try seeing if you can predict if a bank should have issued the loan originally (vs if Fannie Mae should have acquired the loan). + - Remove any columns from train that the bank wouldn’t have known at the time of issuing the loan. + - Some columns are known when Fannie Mae bought the loan, but not before. + - Make predictions. +- Explore seeing if you can predict columns other than foreclosure_status. + - Can you predict how much the property will be worth at sale time? +- Explore the nuances between performance updates. + - Can you predict how many times the borrower will be late on payments? + - Can you map out the typical loan lifecycle? +- Map out data on a state by state or zip code by zip code level. + - Do you see any interesting patterns? + +If you build anything interesting, please let us know in the comments! + +If you liked this, you might like to read the other posts in our ‘Build a Data Science Porfolio’ series: + +- [Storytelling with data][45]. +- [How to setup up a data science blog][46]. + + +-------------------------------------------------------------------------------- + +via: https://www.dataquest.io/blog/data-science-portfolio-machine-learning/ + +作者:[Vik Paruchuri][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 +[1]: https://www.dataquest.io/blog/data-science-portfolio-machine-learning/#email-signup +[2]: https://github.com/dataquestio/loan-prediction +[3]: https://www.dataquest.io/blog/data-science-portfolio-project/ +[4]: https://atom.io/ +[5]: https://www.jetbrains.com/pycharm/ +[6]: https://github.com/ +[7]: http://pandas.pydata.org/ +[8]: http://scikit-learn.org/ +[9]: http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.html +[10]: https://collegescorecard.ed.gov/data/ +[11]: https://reddit.com/r/datasets +[12]: https://cloud.google.com/bigquery/public-data/#usa-names +[13]: https://github.com/caesar0301/awesome-public-datasets +[14]: http://www.fanniemae.com/portal/funding-the-market/data/loan-performance-data.html +[15]: http://www.fanniemae.com/portal/funding-the-market/data/loan-performance-data.html +[16]: https://loanperformancedata.fanniemae.com/lppub-docs/lppub_glossary.pdf +[17]: https://loanperformancedata.fanniemae.com/lppub-docs/lppub_faq.pdf +[18]: https://loanperformancedata.fanniemae.com/lppub-docs/lppub_file_layout.pdf +[19]: https://loanperformancedata.fanniemae.com/lppub-docs/acquisition-sample-file.txt +[20]: https://loanperformancedata.fanniemae.com/lppub-docs/performance-sample-file.txt +[21]: https://github.com/dataquestio/loan-prediction/blob/master/.gitignore +[22]: https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet +[23]: https://github.com/dataquestio/loan-prediction +[24]: https://github.com/dataquestio/loan-prediction/blob/master/requirements.txt +[25]: https://www.continuum.io/downloads +[26]: https://loanperformancedata.fanniemae.com/lppub/index.html +[27]: https://loanperformancedata.fanniemae.com/lppub-docs/lppub_file_layout.pdf +[28]: https://github.com/dataquestio/loan-prediction/blob/master/settings.py +[29]: https://loanperformancedata.fanniemae.com/lppub-docs/lppub_file_layout.pdf +[30]: http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.html +[31]: http://pandas.pydata.org/pandas-docs/stable/generated/pandas.read_csv.html +[32]: https://github.com/dataquestio/loan-prediction/blob/master/assemble.py +[33]: https://docs.python.org/3/library/stdtypes.html#dict.get +[34]: https://github.com/dataquestio/loan-prediction/blob/master/annotate.py +[35]: http://scikit-learn.org/ +[36]: http://scikit-learn.org/stable/modules/generated/sklearn.cross_validation.cross_val_predict.html +[37]: https://en.wikipedia.org/wiki/Binary_classification +[38]: https://en.wikipedia.org/wiki/Logistic_regression +[39]: http://scikit-learn.org/stable/modules/generated/sklearn.linear_model.LogisticRegression.html +[40]: http://scikit-learn.org/stable/modules/generated/sklearn.linear_model.LogisticRegression.html +[41]: https://github.com/dataquestio/loan-prediction/blob/master/predict.py +[42]: https://github.com/dataquestio/loan-prediction/blob/master/README.md +[43]: https://github.com/dataquestio/loan-prediction +[44]: https://www.github.com/ +[45]: https://www.dataquest.io/blog/data-science-portfolio-project/ +[46]: https://www.dataquest.io/blog/how-to-setup-a-data-science-blog/ From 6d8fcc7fc1ff9f72e367c960e1b4e2105bf00fb2 Mon Sep 17 00:00:00 2001 From: cposture Date: Sun, 31 Jul 2016 13:18:35 +0800 Subject: [PATCH 086/122] Translating 50% --- ...18 An Introduction to Mocking in Python.md | 24 ++++++++++--------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/sources/tech/20160618 An Introduction to Mocking in Python.md b/sources/tech/20160618 An Introduction to Mocking in Python.md index 64c26b8ec5..d28fae272d 100644 --- a/sources/tech/20160618 An Introduction to Mocking in Python.md +++ b/sources/tech/20160618 An Introduction to Mocking in Python.md @@ -99,26 +99,26 @@ class RmTestCase(unittest.TestCase): ### 潜在陷阱 -第一件需要注意的事情就是,我们使用了位于 mymodule.os 且用于模拟对象的 mock.patch 方法装饰器,并且将该 mock 注入到我们的测试用例方法。相比在 mymodule.os 引用它,那么只是模拟 os 本身,会不会更有意义? +第一件需要注意的事情就是,我们使用了位于 mymodule.os 且用于模拟对象的 mock.patch 方法装饰器,并且将该 mock 注入到我们的测试用例方法。相比在 mymodule.os 引用它,那么只是模拟 os 本身,会不会更有意义呢? One of the first things that should stick out is that we’re using the mock.patch method decorator to mock an object located at mymodule.os, and injecting that mock into our test case method. Wouldn’t it make more sense to just mock os itself, rather than the reference to it at mymodule.os? 当然,当涉及到导入和管理模块,Python 的用法非常灵活。在运行时,mymodule 模块拥有被导入到本模块局部作用域的 os。因此,如果我们模拟 os,我们是看不到模拟在 mymodule 模块中的作用的。 -Well, Python is somewhat of a sneaky snake when it comes to imports and managing modules. At runtime, the mymodule module has its own os which is imported into its own local scope in the module. Thus, if we mock os, we won’t see the effects of the mock in the mymodule module. 这句话需要深刻地记住: -The mantra to keep repeating is this: > 模拟测试一个项目,只需要了解它用在哪里,而不是它从哪里来。 > Mock an item where it is used, not where it came from. - +如果你需要为 myproject.app.MyElaborateClass 模拟 tempfile 模块,你可能需要 If you need to mock the tempfile module for myproject.app.MyElaborateClass, you probably need to apply the mock to myproject.app.tempfile, as each module keeps its own imports. +先将那个陷阱置身事外,让我们继续模拟。 With that pitfall out of the way, let’s keep mocking. -### Adding Validation to ‘rm’ +### 向 ‘rm’ 中加入验证 + +之前定义的 rm 方法相当的简单。在盲目地删除之前,我们倾向于拿它来验证一个路径是否存在,并验证其是否是一个文件。让我们重构 rm 使其变得更加智能: -The rm method defined earlier is quite oversimplified. We’d like to have it validate that a path exists and is a file before just blindly attempting to remove it. Let’s refactor rm to be a bit smarter: ``` #!/usr/bin/env python @@ -132,7 +132,7 @@ def rm(filename): os.remove(filename) ``` -Great. Now, let’s adjust our test case to keep coverage up. +很好。现在,让我们调整测试用例来保持测试的覆盖程度。 ``` #!/usr/bin/env python @@ -164,13 +164,13 @@ class RmTestCase(unittest.TestCase): mock_os.remove.assert_called_with("any path") ``` -Our testing paradigm has completely changed. We now can verify and validate internal functionality of methods without any side-effects. +我们的测试用例完全改变了。现在我们可以在没有任何副作用下核实并验证方法的内部功能。 -### File-Removal as a Service +### 将文件删除作为服务 -So far, we’ve only been working with supplying mocks for functions, but not for methods on objects or cases where mocking is necessary for sending parameters. Let’s cover object methods first. +到目前为止,我们只是对函数功能提供模拟测试,并没对需要传递参数的对象和实例的方法进行模拟测试。接下来我们将介绍如何对对象的方法进行模拟测试。 -We’ll begin with a refactor of the rm method into a service class. There really isn’t a justifiable need, per se, to encapsulate such a simple function into an object, but it will at the very least help us demonstrate key concepts in mock. Let’s refactor: +首先,我们将rm方法重构成一个服务类。实际上将这样一个简单的函数转换成一个对象,在本质上,这不是一个合理的需求,但它能够帮助我们了解mock的关键概念。让我们开始重构: ``` #!/usr/bin/env python @@ -187,6 +187,7 @@ class RemovalService(object): os.remove(filename) ``` +### 你会注意到我们的测试用例没有太大的变化 ### You’ll notice that not much has changed in our test case: ``` @@ -222,6 +223,7 @@ class RemovalServiceTestCase(unittest.TestCase): mock_os.remove.assert_called_with("any path") ``` +很好,我们知道 RemovalService 会如期工作。接下来让我们创建另一个服务,将其声明为一个依赖 Great, so we now know that the RemovalService works as planned. Let’s create another service which declares it as a dependency: ``` From c716df7f93993b1e043e0e53a2bc68dcae5cc4b0 Mon Sep 17 00:00:00 2001 From: wxy Date: Sun, 31 Jul 2016 15:23:05 +0800 Subject: [PATCH 087/122] PUB:20160104 What is good stock portfolio management software on Linux MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @ivo-wang 翻译中要采用中文的语句习惯。 --- ... portfolio management software on Linux.md | 111 ++++++++++++++++++ ... portfolio management software on Linux.md | 109 ----------------- 2 files changed, 111 insertions(+), 109 deletions(-) create mode 100644 published/20160104 What is good stock portfolio management software on Linux.md delete mode 100644 translated/tech/20160104 What is good stock portfolio management software on Linux.md diff --git a/published/20160104 What is good stock portfolio management software on Linux.md b/published/20160104 What is good stock portfolio management software on Linux.md new file mode 100644 index 0000000000..15c5091b6a --- /dev/null +++ b/published/20160104 What is good stock portfolio management software on Linux.md @@ -0,0 +1,111 @@ +JStock:Linux 上不错的股票投资组合管理软件 +================================================================================ + +如果你在股票市场做投资,那么你可能非常清楚投资组合管理计划有多重要。管理投资组合的目标是依据你能承受的风险,时间层面的长短和资金盈利的目标去为你量身打造的一种投资计划。鉴于这类软件的重要性,因此从来不会缺乏商业性的 app 和股票行情检测软件,每一个都可以兜售复杂的投资组合以及跟踪报告功能。 + +对于我们这些 Linux 爱好者们,我也找到了一些**好用的开源投资组合管理工具**,用来在 Linux 上管理和跟踪股票的投资组合,这里高度推荐一个基于 java 编写的管理软件 [JStock][1]。如果你不是一个 java 粉,也许你会放弃它,JStock 需要运行在沉重的 JVM 环境上。但同时,在每一个安装了 JRE 的环境中它都可以马上运行起来,在你的 Linux 环境中它会运行的很顺畅。 + +“开源”就意味着免费或标准低下的时代已经过去了。鉴于 JStock 只是一个个人完成的产物,作为一个投资组合管理软件它最令人印象深刻的是包含了非常多实用的功能,以上所有的荣誉属于它的作者 Yan Cheng Cheok!例如,JStock 支持通过监视列表去监控价格,多种投资组合,自选/内置的股票指标与相关监测,支持27个不同的股票市场和跨平台的云端备份/还原。JStock 支持多平台部署(Linux, OS X, Android 和 Windows),你可以通过云端保存你的 JStock 投资组合,并通过云平台无缝的备份/还原到其他的不同平台上面。 + +现在我将向你展示如何安装以及使用过程的一些具体细节。 + +### 在 Linux 上安装 JStock ### + +因为 JStock 使用Java编写,所以必须[安装 JRE][2]才能让它运行起来。小提示,JStock 需要 JRE1.7 或更高版本。如你的 JRE 版本不能满足这个需求,JStock 将会运行失败然后出现下面的报错。 + + Exception in thread "main" java.lang.UnsupportedClassVersionError: org/yccheok/jstock/gui/JStock : Unsupported major.minor version 51.0 + + +在你的 Linux 上安装好了 JRE 之后,从其官网下载最新的发布的 JStock,然后加载启动它。 + + $ wget https://github.com/yccheok/jstock/releases/download/release_1-0-7-13/jstock-1.0.7.13-bin.zip + $ unzip jstock-1.0.7.13-bin.zip + $ cd jstock + $ chmod +x jstock.sh + $ ./jstock.sh + +教程的其他部分,让我来给大家展示一些 JStock 的实用功能 + +### 监视监控列表中股票价格的波动 ### + +使用 JStock 你可以创建一个或多个监视列表,它可以自动的监视股票价格的波动并给你提供相应的通知。在每一个监视列表里面你可以添加多个感兴趣的股票进去。之后在“Fall Below”和“Rise Above”的表格里添加你的警戒值,分别设定该股票的最低价格和最高价格。 + +![](https://c2.staticflickr.com/2/1588/23795349969_37f4b0f23c_c.jpg) + +例如你设置了 AAPL 股票的最低/最高价格分别是 $102 和 $115.50,只要在价格低于 $102 或高于 $115.50 时你就得到桌面通知。 + +你也可以设置邮件通知,这样你将收到一些价格信息的邮件通知。设置邮件通知在“Options”菜单里,在“Alert”标签中国,打开“Send message to email(s)”,填入你的 Gmail 账户。一旦完成 Gmail 认证步骤,JStock 就会开始发送邮件通知到你的 Gmail 账户(也可以设置其他的第三方邮件地址)。 + +![](https://c2.staticflickr.com/2/1644/24080560491_3aef056e8d_b.jpg) + +### 管理多个投资组合 ### + +JStock 允许你管理多个投资组合。这个功能对于你使用多个股票经纪人时是非常实用的。你可以为每个经纪人创建一个投资组合去管理你的“买入/卖出/红利”用来了解每一个经纪人的业务情况。你也可以在“Portfolio”菜单里面选择特定的投资组合来切换不同的组合项目。下面是一张截图用来展示一个假设的投资组合。 + +![](https://c2.staticflickr.com/2/1646/23536385433_df6c036c9a_c.jpg) + +你也可以设置付给中介费,你可以为每个买卖交易设置中介费、印花税以及结算费。如果你比较懒,你也可以在选项菜单里面启用自动费用计算,并提前为每一家经济事务所设置费用方案。当你为你的投资组合增加交易之后,JStock 将自动的计算并计入费用。 + +![](https://c2.staticflickr.com/2/1653/24055085262_0e315c3691_b.jpg) + +### 使用内置/自选股票指标来监控 ### + +如果你要做一些股票的技术分析,你可能需要基于各种不同的标准来监控股票(这里叫做“股票指标”)。对于股票的跟踪,JStock提供多个[预设的技术指示器][3] 去获得股票上涨/下跌/逆转指数的趋势。下面的列表里面是一些可用的指标。 + +- 平滑异同移动平均线(MACD) +- 相对强弱指标 (RSI) +- 资金流向指标 (MFI) +- 顺势指标 (CCI) +- 十字线 +- 黄金交叉线,死亡交叉线 +- 涨幅/跌幅 + +开启预设指示器能需要在 JStock 中点击“Stock Indicator Editor”标签。之后点击右侧面板中的安装按钮。选择“Install from JStock server”选项,之后安装你想要的指示器。 + +![](https://c2.staticflickr.com/2/1476/23867534660_b6a9c95a06_c.jpg) + +一旦安装了一个或多个指示器,你可以用他们来扫描股票。选择“Stock Indicator Scanner”标签,点击底部的“Scan”按钮,选择需要的指示器。 + +![](https://c2.staticflickr.com/2/1653/24137054996_e8fcd10393_c.jpg) + +当你选择完需要扫描的股票(例如, NYSE, NASDAQ)以后,JStock 将执行该扫描,并将该指示器捕获的结果通过列表展现。 + +![](https://c2.staticflickr.com/2/1446/23795349889_0f1aeef608_c.jpg) + +除了预设指示器以外,你也可以使用一个图形化的工具来定义自己的指示器。下面这张图例用于监控当前价格小于或等于60天平均价格的股票。 + +![](https://c2.staticflickr.com/2/1605/24080560431_3d26eac6b5_c.jpg) + +### 通过云在 Linux 和 Android JStock 之间备份/恢复### + +另一个非常棒的功能是 JStock 支持云备份恢复。Jstock 可以通过 Google Drive 把你的投资组合/监视列表在云上备份和恢复,这个功能可以实现在不同平台上无缝穿梭。如果你在两个不同的平台之间来回切换使用 Jstock,这种跨平台备份和还原非常有用。我在 Linux 桌面和 Android 手机上测试过我的 Jstock 投资组合,工作的非常漂亮。我在 Android 上将 Jstock 投资组合信息保存到 Google Drive 上,然后我可以在我的 Linux 版的 Jstock 上恢复它。如果能够自动同步到云上,而不用我手动地触发云备份/恢复就更好了,十分期望这个功能出现。 + +![](https://c2.staticflickr.com/2/1537/24163165565_bb47e04d6c_c.jpg) + +![](https://c2.staticflickr.com/2/1556/23536385333_9ed1a75d72_c.jpg) + +如果你在从 Google Drive 还原之后不能看到你的投资信息以及监视列表,请确认你的国家信息与“Country”菜单里面设置的保持一致。 + +JStock 的安卓免费版可以从 [Google Play Store][4] 获取到。如果你需要完整的功能(比如云备份,通知,图表等),你需要一次性支付费用升级到高级版。我认为高级版物有所值。 + +![](https://c2.staticflickr.com/2/1687/23867534720_18b917028c_c.jpg) + +写在最后,我应该说一下它的作者,Yan Cheng Cheok,他是一个十分活跃的开发者,有bug及时反馈给他。这一切都要感谢他!!! + +关于 JStock 这个投资组合跟踪软件你有什么想法呢? + +-------------------------------------------------------------------------------- + +via: http://xmodulo.com/stock-portfolio-management-software-Linux.html + +作者:[Dan Nanni][a] +译者:[ivo-wang](https://github.com/ivo-wang) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://Linux.cn/) 荣誉推出 + +[a]:http://xmodulo.com/author/nanni +[1]:http://jstock.org/ +[2]:http://ask.xmodulo.com/install-java-runtime-Linux.html +[3]:http://jstock.org/ma_indicator.html +[4]:https://play.google.com/store/apps/details?id=org.yccheok.jstock.gui diff --git a/translated/tech/20160104 What is good stock portfolio management software on Linux.md b/translated/tech/20160104 What is good stock portfolio management software on Linux.md deleted file mode 100644 index 7e0c8a05fd..0000000000 --- a/translated/tech/20160104 What is good stock portfolio management software on Linux.md +++ /dev/null @@ -1,109 +0,0 @@ -Translating by ivo-wang -What is good stock portfolio management software on Linux -linux上那些不错的管理股票组合投资软件 -================================================================================ -如果你在股票市场做投资,那么你可能非常清楚管理组合投资的计划有多重要。管理组合投资的目标是依据你能承受的风险,时间层面的长短和资金盈利的目标去为你量身打造的一种投资计划。鉴于这类软件的重要性,难怪从不缺乏商业性质的app和股票行情检测软件,每一个都可以兜售复杂的组合投资以及跟踪报告功能。 - -对于这些linux爱好者们,我们找到了一些 **好用的开源组合投资管理工具** 用来在linux上管理和跟踪股票的组合投资,这里高度推荐一个基于java编写的管理软件[JStock][1]。如果你不是一个java粉,你不得不面对这样一个事实JStock需要运行在重型的JVM环境上。同时我相信许多人非常欣赏JStock,安装JRE以后它可以非常迅速的安装在各个linux平台上。没有障碍能阻止你将它安装在你的linux环境中。 - -开源就意味着免费或标准低下的时代已经过去了。鉴于JStock只是一个个人完成的产物,作为一个组合投资管理软件它最令人印象深刻的是包含了非常多实用的功能,以上所有的荣誉属于它的作者Yan Cheng Cheok!例如,JStock 支持通过监视列表去监控价格,多种组合投资,按习惯/按固定 做股票指示与相关扫描,支持27个不同的股票市场和交易平台云端备份/还原。JStock支持多平台部署(Linux, OS X, Android 和 Windows),你可以通过云端保存你的JStock记录,它可以无缝的备份还原到其他的不同平台上面。 - -现在我将向你展示如何安装以及使用过程的一些具体细节。 - -### 在Linux上安装JStock ### - -因为JStock使用Java编写,所以必须[安装 JRE][2]才能让它运行起来.小提示JStock 需要JRE1.7或更高版本。如你的JRE版本不能满足这个需求,JStock将会安装失败然后出现下面的报错。 - - Exception in thread "main" java.lang.UnsupportedClassVersionError: org/yccheok/jstock/gui/JStock : Unsupported major.minor version 51.0 - - -一旦你安装了JRE在你的linux上,从官网下载最新的发布的JStock,然后加载启动它。 - - $ wget https://github.com/yccheok/jstock/releases/download/release_1-0-7-13/jstock-1.0.7.13-bin.zip - $ unzip jstock-1.0.7.13-bin.zip - $ cd jstock - $ chmod +x jstock.sh - $ ./jstock.sh - -教程的其他部分,让我来给大家展示一些JStock的实用功能 - -### 监视监控列表股票价格的波动 ### - -使用JStock你可以创建一个或多个监视列表,它可以自动的监视股票价格的波动并给你提供相应的通知。在每一个监视列表里面你可以添加多个感兴趣的股票进去。之后添加你的警戒值在"Fall Below"和"Rise Above"的表格里,分别是在设定最低价格和最高价格。 - -![](https://c2.staticflickr.com/2/1588/23795349969_37f4b0f23c_c.jpg) - -例如你设置了AAPL股票的最低/最高价格分别是$102 和 $115.50,你将在价格低于$102或高于$115.50的任意时间在桌面得到通知。 - -你也可以设置邮件通知,之后你将收到一些价格信息的邮件通知。设置邮件通知在栏的"Options"选项。在"Alert"标签,打开"Send message to email(s)",填入你的Gmail账户。一旦完成Gmail认证步骤,JStock将开始发送邮件通知到你的Gmail账户(也可以设置其他的第三方邮件地址) -![](https://c2.staticflickr.com/2/1644/24080560491_3aef056e8d_b.jpg) - -### 管理多个组合投资 ### - -JStock能够允许你管理多个组合投资。这个功能对于股票经纪人是非常实用的。你可以为经纪人创建一个投资项去管理你的 买入/卖出/红利 用来了解每一个经纪人的业务情况。你也可以切换不同的组合项目通过选择一个特殊项目在"Portfolio"菜单里面。下面是一张截图用来展示一个意向投资 -![](https://c2.staticflickr.com/2/1646/23536385433_df6c036c9a_c.jpg) - -因为能够设置付给经纪人小费的选项,所以你能付给经纪人任意的小费,印花税以及清空每一比交易的小费。如果你非常懒,你也可以在菜单里面设置自动计算小费和给每一个经纪人固定的小费。在完成交易之后JStock将自动的计算并发送小费。 - -![](https://c2.staticflickr.com/2/1653/24055085262_0e315c3691_b.jpg) - -### 显示固定/自选股票提示 ### - -如果你要做一些股票的技术分析,你可能需要不同股票的指数(这里叫做“平均股指”),对于股票的跟踪,JStock提供多个[预设技术指示器][3] 去获得股票上涨/下跌/逆转指数的趋势。下面的列表里面是一些可用的指示。 -- 异同平均线(MACD) -- 相对强弱指数 (RSI) -- 货币流通指数 (MFI) -- 顺势指标 (CCI) -- 十字线 -- 黄金交叉线, 死亡交叉线 -- 涨幅/跌幅 - -开启预设指示器能需要在JStock中点击"Stock Indicator Editor"标签。之后点击右侧面板中的安装按钮。选择"Install from JStock server"选项,之后安装你想要的指示器。 - -![](https://c2.staticflickr.com/2/1476/23867534660_b6a9c95a06_c.jpg) - -一旦安装了一个或多个指示器,你可以用他们来扫描股票。选择"Stock Indicator Scanner"标签,点击底部的"Scan"按钮,选择需要的指示器。 - -![](https://c2.staticflickr.com/2/1653/24137054996_e8fcd10393_c.jpg) - -当你选择完需要扫描的股票(例如e.g., NYSE, NASDAQ)以后,JStock将执行扫描,并将捕获的结果通过列表的形式展现在指示器上面。 - -![](https://c2.staticflickr.com/2/1446/23795349889_0f1aeef608_c.jpg) - -除了预设指示器以外,你也可以使用一个图形化的工具来定义自己的指示器。下面这张图例中展示的是当前价格小于或等于60天平均价格 - -![](https://c2.staticflickr.com/2/1605/24080560431_3d26eac6b5_c.jpg) - -### 云备份还原Linux 和 Android JStock ### - -另一个非常棒的功能是JStock可以支持云备份还原。Jstock也可以把你的组合投资/监视列表备份还原在 Google Drive,这个功能可以实现在不同平台(例如Linux和Android)上无缝穿梭。举个例子,如果你把Android Jstock组合投资的信息保存在Google Drive上,你可以在Linux班级本上还原他们。 - -![](https://c2.staticflickr.com/2/1537/24163165565_bb47e04d6c_c.jpg) - -![](https://c2.staticflickr.com/2/1556/23536385333_9ed1a75d72_c.jpg) - -如果你在从Google Drive还原之后不能看到你的投资信息以及监视列表,请确认你的国家信息与“Country”菜单里面设置的保持一致。 - -JStock的安卓免费版可以从[Google Play Store][4]获取到。如果你需要完整的功能(比如云备份,通知,图表等),你需要一次性支付费用升级到高级版。我想高级版肯定有它的价值所在。 - -![](https://c2.staticflickr.com/2/1687/23867534720_18b917028c_c.jpg) - -写在最后,我应该说一下它的作者,Yan Cheng Cheok,他是一个十分活跃的开发者,有bug及时反馈给他。最后多有的荣耀都属于他一个人!!! - -关于JStock这个组合投资跟踪软件你有什么想法呢? - --------------------------------------------------------------------------------- - -via: http://xmodulo.com/stock-portfolio-management-software-linux.html - -作者:[Dan Nanni][a] -译者:[ivo-wang](https://github.com/ivo-wang) -校对:[校对者ID](https://github.com/校对者ID) - -本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 - -[a]:http://xmodulo.com/author/nanni -[1]:http://jstock.org/ -[2]:http://ask.xmodulo.com/install-java-runtime-linux.html -[3]:http://jstock.org/ma_indicator.html -[4]:https://play.google.com/store/apps/details?id=org.yccheok.jstock.gui From 60ba5b6d27f61fdea3cabf8a1669f707ca9f92f5 Mon Sep 17 00:00:00 2001 From: wxy Date: Sun, 31 Jul 2016 18:06:20 +0800 Subject: [PATCH 088/122] PUB:20160721 YOU CAN TRY A DEMO UBUNTU VERSION IN A WEB BROWSER @kokialoves --- ... A DEMO UBUNTU VERSION IN A WEB BROWSER.md | 36 ++++++++++++++++++ ... A DEMO UBUNTU VERSION IN A WEB BROWSER.md | 37 ------------------- 2 files changed, 36 insertions(+), 37 deletions(-) create mode 100644 published/20160721 YOU CAN TRY A DEMO UBUNTU VERSION IN A WEB BROWSER.md delete mode 100644 translated/tech/20160721 YOU CAN TRY A DEMO UBUNTU VERSION IN A WEB BROWSER.md diff --git a/published/20160721 YOU CAN TRY A DEMO UBUNTU VERSION IN A WEB BROWSER.md b/published/20160721 YOU CAN TRY A DEMO UBUNTU VERSION IN A WEB BROWSER.md new file mode 100644 index 0000000000..0fd776c078 --- /dev/null +++ b/published/20160721 YOU CAN TRY A DEMO UBUNTU VERSION IN A WEB BROWSER.md @@ -0,0 +1,36 @@ +在浏览器中体验 Ubuntu +===================================================== + +[Ubuntu][2] 的背后的公司 [Canonical][1] 为 Linux 推广做了很多努力。无论你有多么不喜欢 Ubuntu,你必须承认它对 “Linux 易用性”的影响。Ubuntu 以及其衍生是使用最多的 Linux 版本。 + +为了进一步推广 Ubuntu Linux,Canonical 把它放到了浏览器里,你可以在任何地方使用这个 [Ubuntu 演示版][0]。 它将帮你更好的体验 Ubuntu,以便让新人更容易决定是否使用它。 + +你可能争辩说 USB 版的 Linux 更好。我同意,但是你要知道你要下载 ISO,创建 USB 启动盘,修改配置文件,然后才能使用这个 USB 启动盘来体验。这么乏味并不是每个人都乐意这么干的。 在线体验是一个更好的选择。 + +那么,你能在 Ubuntu 在线看到什么。实际上并不多。 + +你可以浏览文件,你可以使用 Unity Dash,浏览 Ubuntu 软件中心,甚至装几个应用(当然它们不会真的安装),看一看文件浏览器和其它一些东西。以上就是全部了。但是在我看来,这已经做的很好了,让你知道它是个什么,对这个流行的操作系统有个直接感受。 + +![](https://itsfoss.com/wp-content/uploads/2016/07/Ubuntu-online-demo.jpeg) + +![](https://itsfoss.com/wp-content/uploads/2016/07/Ubuntu-online-demo-1.jpeg) + +![](https://itsfoss.com/wp-content/uploads/2016/07/Ubuntu-online-demo-2.jpeg) + +如果你的朋友或者家人对试试 Linux 抱有兴趣,但是想在安装前想体验一下 Linux 。你可以给他们以下链接:[Ubuntu 在线导览][0] 。 + + +-------------------------------------------------------------------------------- + +via: https://itsfoss.com/ubuntu-online-demo/ + +作者:[Abhishek Prakash][a] +译者:[kokialoves](https://github.com/kokialoves) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]: https://itsfoss.com/author/abhishek/ +[0]: http://tour.ubuntu.com/en/ +[1]: http://www.canonical.com/ +[2]: http://www.ubuntu.com/ diff --git a/translated/tech/20160721 YOU CAN TRY A DEMO UBUNTU VERSION IN A WEB BROWSER.md b/translated/tech/20160721 YOU CAN TRY A DEMO UBUNTU VERSION IN A WEB BROWSER.md deleted file mode 100644 index d79969e3e7..0000000000 --- a/translated/tech/20160721 YOU CAN TRY A DEMO UBUNTU VERSION IN A WEB BROWSER.md +++ /dev/null @@ -1,37 +0,0 @@ -你能在浏览器中运行UBUNTU -===================================================== - -Canonical, Ubuntu的母公司, 为Linux推广做了很多努力. 无论你有多么不喜欢 Ubuntu, 你必须承认它对 “Linux 易用性”的影响. Ubuntu 以及其衍生是应用最多的Linux版本 . - -为了进一步推广 Ubuntu Linux, Canonical 把它放到了浏览器里你可以再任何地方使用 [demo version of Ubuntu][1]. 它将帮你更好的体验 Ubuntu. 以便让新人更容易决定是否使用. - -你可能争辩说USB版的linux更好. 我同意但是你要知道你要下载ISO, 创建USB驱动, 修改配置文件. 并不是每个人都乐意这么干的. 在线体验是一个更好的选择. - -因此, 你能在Ubuntu在线看到什么. 实际上并不多. - -你可以浏览文件, 你可以使用 Unity Dash, 浏览 Ubuntu Software Center, 甚至装几个 apps (当然它们不会真的安装), 看一看文件浏览器 和其它一些东西. 以上就是全部了. 但是在我看来, 它是非常漂亮的 - -![](https://itsfoss.com/wp-content/uploads/2016/07/Ubuntu-online-demo.jpeg) - -![](https://itsfoss.com/wp-content/uploads/2016/07/Ubuntu-online-demo-1.jpeg) - -![](https://itsfoss.com/wp-content/uploads/2016/07/Ubuntu-online-demo-2.jpeg) - -如果你的朋友或者家人想试试Linux又不乐意安装, 你可以给他们以下链接: - -[Ubuntu Online Tour][0] - - --------------------------------------------------------------------------------- - -via: https://itsfoss.com/ubuntu-online-demo/?utm_source=newsletter&utm_medium=email&utm_campaign=linux_and_open_source_stories_this_week - -作者:[Abhishek Prakash][a] -译者:[kokialoves](https://github.com/kokialoves) -校对:[校对ID](https://github.com/校对ID) - -本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 - -[a]: https://itsfoss.com/author/abhishek/ -[0]: http://tour.ubuntu.com/en/ -[1]: http://tour.ubuntu.com/en/ From 1132d343cdc7f88dcfc3f8ac8a09a712fe2df86e Mon Sep 17 00:00:00 2001 From: Mike Date: Sun, 31 Jul 2016 18:17:42 +0800 Subject: [PATCH 089/122] What containers and unikernels can learn from Arduino and Raspberry Pi (#4251) * translated/tech/20160718 OPEN SOURCE ACCOUNTING SOFTWARE.md * translated/tech/20160718 OPEN SOURCE ACCOUNTING SOFTWARE.md * sources/talk/20160525 What containers and unikernels can learn from Arduino and Raspberry Pi.md --- ...rs and unikernels can learn from Arduino and Raspberry Pi.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sources/talk/20160525 What containers and unikernels can learn from Arduino and Raspberry Pi.md b/sources/talk/20160525 What containers and unikernels can learn from Arduino and Raspberry Pi.md index a1d6257d4d..ff81871630 100644 --- a/sources/talk/20160525 What containers and unikernels can learn from Arduino and Raspberry Pi.md +++ b/sources/talk/20160525 What containers and unikernels can learn from Arduino and Raspberry Pi.md @@ -1,3 +1,5 @@ +MikeCoder Translating... + What containers and unikernels can learn from Arduino and Raspberry Pi ========================================================================== From 601aec7515ab2e66e3e16b4c4945e76e3c12cc36 Mon Sep 17 00:00:00 2001 From: wxy Date: Sun, 31 Jul 2016 18:40:17 +0800 Subject: [PATCH 090/122] PUB:20160718 OPEN SOURCE ACCOUNTING SOFTWARE @MikeCoder --- ...0160718 OPEN SOURCE ACCOUNTING SOFTWARE.md | 80 +++++++++++++++++++ ...0160718 OPEN SOURCE ACCOUNTING SOFTWARE.md | 71 ---------------- 2 files changed, 80 insertions(+), 71 deletions(-) create mode 100644 published/20160718 OPEN SOURCE ACCOUNTING SOFTWARE.md delete mode 100644 translated/tech/20160718 OPEN SOURCE ACCOUNTING SOFTWARE.md diff --git a/published/20160718 OPEN SOURCE ACCOUNTING SOFTWARE.md b/published/20160718 OPEN SOURCE ACCOUNTING SOFTWARE.md new file mode 100644 index 0000000000..7598de6bf1 --- /dev/null +++ b/published/20160718 OPEN SOURCE ACCOUNTING SOFTWARE.md @@ -0,0 +1,80 @@ +GNU KHATA:开源的会计管理软件 +============================================ + +作为一个活跃的 Linux 爱好者,我经常向我的朋友们介绍 Linux,帮助他们选择最适合他们的发行版本,同时也会帮助他们安装一些适用于他们工作的开源软件。 + +但是在这一次,我就变得很无奈。我的叔叔,他是一个自由职业的会计师。他会有一系列的为了会计工作的漂亮而成熟的付费软件。我不那么确定我能在在开源软件中找到这么一款可以替代的软件——直到昨天。 + +Abhishek 给我推荐了一些[很酷的软件][1],而其中 GNU Khata 脱颖而出。 + +[GNU Khata][2] 是一个会计工具。 或者,我应该说成是一系列的会计工具集合?它就像经济管理方面的 [Evernote][3] 一样。它的应用是如此之广,以至于它不但可以用于个人的财务管理,也可以用于大型公司的管理,从店铺存货管理到税率计算,都可以有效处理。 + +有个有趣的地方,Khata 这个词在印度或者是其他的印度语国家中意味着账户,所以这个会计软件叫做 GNU Khata。 + +### 安装 + +互联网上有很多关于旧的 Web 版本的 Khata 安装介绍。现在,GNU Khata 只能用在 Debian/Ubuntu 和它们的衍生版本中。我建议你按照 GNU Khata 官网给出的如下步骤来安装。我们来快速过一下。 + +- 从[这里][4]下载安装器。 +- 在下载目录打开终端。 +- 粘贴复制以下的代码到终端,并且执行。 + +``` +sudo chmod 755 GNUKhatasetup.run +sudo ./GNUKhatasetup.run +``` + +这就结束了,从你的 Dash 或者是应用菜单中启动 GNU Khata 吧。 + +### 第一次启动 + +GNU Khata 在浏览器中打开,并且展现以下的画面。 + +![](https://itsfoss.com/wp-content/uploads/2016/07/GNU-khata-1.jpg) + +填写组织的名字、组织形式,财务年度并且点击 proceed 按钮进入管理设置页面。 + +![](https://itsfoss.com/wp-content/uploads/2016/07/GNU-khata-2.jpg) + +仔细填写你的用户名、密码、安全问题及其答案,并且点击“create and login”。 + +![](https://itsfoss.com/wp-content/uploads/2016/07/GNU-khata-3.jpg) + +你已经全部设置完成了。使用菜单栏来开始使用 GNU Khata 来管理你的财务吧。这很容易。 + +### 移除 GNU KHATA + +如果你不想使用 GNU Khata 了,你可以执行如下命令移除: + +``` +sudo apt-get remove --auto-remove gnukhata-core-engine +``` + +你也可以通过新立得软件管理来删除它。 + +### GNU KHATA 真的是市面上付费会计应用的竞争对手吗? + +首先,GNU Khata 以简化为设计原则。顶部的菜单栏组织的很方便,可以帮助你有效的进行工作。你可以选择管理不同的账户和项目,并且切换非常容易。[它们的官网][5]表明,GNU Khata 可以“像说印度语一样方便”(LCTT 译注:原谅我,这个软件作者和本文作者是印度人……)。同时,你知道 GNU Khata 也可以在云端使用吗? + +所有的主流的账户管理工具,比如分类账簿、项目报表、财务报表等等都用专业的方式整理,并且支持自定义格式和即时展示。这让会计和仓储管理看起来如此的简单。 + +这个项目正在积极的发展,正在寻求实操中的反馈以帮助这个软件更加进步。考虑到软件的成熟性、使用的便利性还有免费的情况,GNU Khata 可能会成为你最好的账簿助手。 + +请在评论框里留言吧,让我们知道你是如何看待 GNU Khata 的。 + +-------------------------------------------------------------------------------- + +via: https://itsfoss.com/using-gnu-khata/ + +作者:[Aquil Roshan][a] +译者:[MikeCoder](https://github.com/MikeCoder) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]: https://itsfoss.com/author/aquil/ +[1]: https://itsfoss.com/category/apps/ +[2]: http://www.gnukhata.in/ +[3]: https://evernote.com/ +[4]: https://cloud.openmailbox.org/index.php/s/L8ppsxtsFq1345E/download +[5]: http://www.gnukhata.in/ diff --git a/translated/tech/20160718 OPEN SOURCE ACCOUNTING SOFTWARE.md b/translated/tech/20160718 OPEN SOURCE ACCOUNTING SOFTWARE.md deleted file mode 100644 index 8093f8eae2..0000000000 --- a/translated/tech/20160718 OPEN SOURCE ACCOUNTING SOFTWARE.md +++ /dev/null @@ -1,71 +0,0 @@ -GNU KHATA:开源的会计管理软件 -============================================ - -作为一个活跃的 Linux 爱好者,我经常向我的朋友们介绍 Linux,帮助他们选择最适合他们的发行版本,同时也会帮助他们安装一些适用于他们工作的开源软件。 - -但是,又一次,我就变得很无奈。我的叔叔,他是一个自由职业的会计师。他会有一系列的为了会计工作的付费软件。我就不那么确定,我能在在开软软件中找到这么一款可以替代的软件。直到昨天。 - -Abhishek 给我推荐了一些[很酷的软件][1],并且,GNU Khata 这个特殊的一款,脱颖而出。 - -[GNU Khata][2] 是一个会计工具。 或者,我可以说成是一系列的会计工具集合?这像经济管理方面的[Evernote][3]。他的应用是如此之广,以至于他可以处理个人的财务管理,到大型公司的管理,从店铺存货管理到税率计算,都可以有效处理。 - -对你来说一个有趣的点,'Khata' 在印度或者是其他的印度语国家中意味着账户,所以这个会计软件叫做 GNU Khata。 - -### 安装 - -互联网上有很多关于老旧版本的 Khata 安装的介绍。现在,GNU Khata 已经可以在 Debian/Ubuntu 和他们的衍生产中得到。我建议你按照如下 GNU Khata 官网的步骤来安装。我们来一次快速的入门。 - -- 从[这][4]下载安装器。 -- 在下载目录打开终端。 -- 粘贴复制以下的代码到终端,并且执行。 - -``` -sudo chmod 755 GNUKhatasetup.run -sudo ./GNUKhatasetup.run -``` - -- 这就结束了,从你的 Dash 或者是应用菜单中启动 GNU Khata 吧。 -### 第一次启动 - -GNU Khata 在浏览器中打开,并且展现以下的画面。 - -![](https://itsfoss.com/wp-content/uploads/2016/07/GNU-khata-1.jpg) - -填写组织的名字和组织形式,经济年份并且点击 proceed 按钮进入管理设置页面。 - -![](https://itsfoss.com/wp-content/uploads/2016/07/GNU-khata-2.jpg) - -仔细填写你的姓名,密码,安全问题和他的答案,并且点击“create and login”。 - -![](https://itsfoss.com/wp-content/uploads/2016/07/GNU-khata-3.jpg) - -你已经全部设置完成了。使用菜单栏来开始使用 GNU Khata 来管理你的经济吧。这很容易。 - -### GNU KHATA 真的是市面上付费会计应用的竞争对手吗? - -首先,GNU Khata 让所有的事情变得简单。顶部的菜单栏被方便的组织,可以帮助你有效的进行工作。 你可以选择管理不同的账户和项目,并且切换非常容易。[他们的官网][5]表明,GNU Khata 可以“方便的转变成印度语”。同时,你知道 GNU Khata 也可以在云端使用吗? - -所有的主流的账户管理工具,将账簿分类,项目介绍,法规介绍等等用专业的方式整理,并且支持自定义整理和实时显示。这让会计和进存储管理看起来如此的简单。 - -这个项目正在积极的发展,从实际的操作中提交反馈来帮助这个软件更加进步。考虑到软件的成熟性,使用的便利性还有免费的 tag。GNU Khata 可能会成为最好的账簿助手。 - -请在评论框里留言吧,让我们知道你是如何看待 GNU Khata 的。 - - - --------------------------------------------------------------------------------- - -via: https://itsfoss.com/using-gnu-khata/?utm_source=feedburner&utm_medium=feed&utm_campaign=Feed%3A+ItsFoss+%28Its+FOSS%21+An+Open+Source+Blog%29 - -作者:[Aquil Roshan][a] -译者:[MikeCoder](https://github.com/MikeCoder) -校对:[校对者ID](https://github.com/校对者ID) - -本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 - -[a]: https://itsfoss.com/author/aquil/ -[1]: https://itsfoss.com/category/apps/ -[2]: http://www.gnukhata.in/ -[3]: https://evernote.com/ -[4]: https://cloud.openmailbox.org/index.php/s/L8ppsxtsFq1345E/download -[5]: http://www.gnukhata.in/ From 9c8a11a995865b85bf04bbdb59d7b7b582da1de5 Mon Sep 17 00:00:00 2001 From: wxy Date: Sun, 31 Jul 2016 19:07:19 +0800 Subject: [PATCH 091/122] PUB:20160726 Set a Real Time Photo of Earth as Your Linux Desktop Wallpaper @geekpi --- ...f Earth as Your Linux Desktop Wallpaper.md | 90 +++++++++++++++++++ ...f Earth as Your Linux Desktop Wallpaper.md | 39 -------- 2 files changed, 90 insertions(+), 39 deletions(-) create mode 100644 published/20160726 Set a Real Time Photo of Earth as Your Linux Desktop Wallpaper.md delete mode 100644 translated/tech/20160726 Set a Real Time Photo of Earth as Your Linux Desktop Wallpaper.md diff --git a/published/20160726 Set a Real Time Photo of Earth as Your Linux Desktop Wallpaper.md b/published/20160726 Set a Real Time Photo of Earth as Your Linux Desktop Wallpaper.md new file mode 100644 index 0000000000..40ba237020 --- /dev/null +++ b/published/20160726 Set a Real Time Photo of Earth as Your Linux Desktop Wallpaper.md @@ -0,0 +1,90 @@ +为你的 Linux 桌面设置一张实时的地球照片 +================================================================= + +![](http://www.omgubuntu.co.uk/wp-content/uploads/2016/07/Screen-Shot-2016-07-26-at-16.36.47-1.jpg) + +厌倦了看同样的桌面背景了么?这里有一个(可能是)世界上最棒的东西。 + +‘[Himawaripy][1]’ 是一个 Python 3 小脚本,它会抓取由[日本 Himawari 8 气象卫星][2]拍摄的接近实时的地球照片,并将它设置成你的桌面背景。 + +安装完成后,你可以将它设置成每 10 分钟运行的定时任务(自然,它要在后台运行),这样它就可以实时地取回地球的照片并设置成背景了。 + +因为 Himawari-8 是一颗同步轨道卫星,你只能看到澳大利亚上空的地球的图片——但是它实时的天气形态、云团和光线仍使它很壮丽,对我而言要是看到英国上方的就更好了! + +高级设置允许你配置从卫星取回的图片质量,但是要记住增加图片质量会增加文件大小及更长的下载等待! + +最后,虽然这个脚本与其他我们提到过的其他脚本类似,它还仍保持更新及可用。 + +###获取 Himawaripy + +Himawaripy 已经在一系列的桌面环境中都测试过了,包括 Unity、LXDE、i3、MATE 和其他桌面环境。它是自由开源软件,但是整体来说安装及配置不太简单。 + +在该项目的 [Github 主页][0]上可以找到安装和设置该应用程序的所有指导(提示:没有一键安装功能)。 + +- [实时地球壁纸脚本的 GitHub 主页][0] + +### 安装及使用 + +![](http://www.omgubuntu.co.uk/wp-content/uploads/2016/07/Screen-Shot-2016-07-26-at-16.46.13-750x143.png) + +一些读者请我在本文中补充一下一步步安装该应用的步骤。以下所有步骤都在其 GitHub 主页上,这里再贴一遍。 + +1、下载及解压 Himawaripy + +这是最容易的步骤。点击下面的下载链接,然后下载最新版本,并解压到你的下载目录里面。 + + - [下载 Himawaripy 主干文件(.zip 格式)][3] + +2、安装 python3-setuptools + +你需要手工来安装主干软件包,Ubuntu 里面默认没有安装它: + +``` +sudo apt install python3-setuptools +``` + +3、安装 Himawaripy + +在终端中,你需要切换到之前解压的目录中,并运行如下安装命令: + +``` +cd ~/Downloads/himawaripy-master +sudo python3 setup.py install +``` + +4、 看看它是否可以运行并下载最新的实时图片: +``` +himawaripy +``` +5、 设置定时任务 + +如果你希望该脚本可以在后台自动运行并更新(如果你需要手动更新,只需要运行 ‘himarwaripy’ 即可) + +在终端中运行: +``` +crontab -e +``` +在其中新加一行(默认每10分钟运行一次) +``` +*/10 * * * * /usr/local/bin/himawaripy +``` +关于[配置定时任务][4]可以在 Ubuntu Wiki 上找到更多信息。 + +该脚本安装后你不需要不断运行它,它会自动的每十分钟在后台运行一次。 + +-------------------------------------------------------------------------------- + +via: http://www.omgubuntu.co.uk/2016/07/set-real-time-earth-wallpaper-ubuntu-desktop + +作者:[JOEY-ELIJAH SNEDDON][a] +译者:[geekpi](https://github.com/geekpi) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]: https://plus.google.com/117485690627814051450/?rel=author +[1]: https://github.com/boramalper/himawaripy +[2]: https://en.wikipedia.org/wiki/Himawari_8 +[0]: https://github.com/boramalper/himawaripy +[3]: https://github.com/boramalper/himawaripy/archive/master.zip +[4]: https://help.ubuntu.com/community/CronHowto \ No newline at end of file diff --git a/translated/tech/20160726 Set a Real Time Photo of Earth as Your Linux Desktop Wallpaper.md b/translated/tech/20160726 Set a Real Time Photo of Earth as Your Linux Desktop Wallpaper.md deleted file mode 100644 index d05fd97eb2..0000000000 --- a/translated/tech/20160726 Set a Real Time Photo of Earth as Your Linux Desktop Wallpaper.md +++ /dev/null @@ -1,39 +0,0 @@ -为你的Linux桌面设置一张真实的地球照片 -================================================================= - -![](http://www.omgubuntu.co.uk/wp-content/uploads/2016/07/Screen-Shot-2016-07-26-at-16.36.47-1.jpg) - -厌倦了看同样的桌面背景了么?这里有一个几乎这世界上最好的东西。 - -‘[Himawaripy][1]‘是一个Python 3脚本,它会接近实时抓取由[日本Himawari 8气象卫星][2]拍摄的地球照片,并将它设置成你的桌面背景。 - -安装完成后,你可以将它设置成每10分钟运行的任务(自然地它是在后台运行),这样它就可以实时地取回地球的照片并设置成背景了。 - -因为Himawari-8是一颗同步轨道卫星,你只能看到澳大利亚上空的地球的图片-但是它实时的天气形态、云团和光线仍使它很壮丽,即使对我而言在看到英国上方的更好! - -高级设置允许你配置从卫星取回的图片质量,但是要记住增加图片质量会增加文件大小及更长的下载等待! - -最后,虽然这个脚本与其他我们提到过的其他类似,它还仍保持更新及可用。 - -获取Himawaripy - -Himawaripy已经在一系列的桌面环境中都测试过了,包括Unity、LXDE、i3、MATE和其他桌面环境。它是免费、开源软件但是并不能直接设置及配置。 - -在Github上查找获取安装的应用程序和设置的所有指令()提示:有没有一键安装)上。 - -[GitHub上的实时地球壁纸脚本][0] - --------------------------------------------------------------------------------- - -via: http://www.tecmint.com/mandatory-access-control-with-selinux-or-apparmor-linux/ - -作者:[ JOEY-ELIJAH SNEDDON][a] -译者:[geekpi](https://github.com/geekpi) -校对:[校对者ID](https://github.com/校对者ID) - -本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 - -[a]: https://plus.google.com/117485690627814051450/?rel=author -[1]: https://github.com/boramalper/himawaripy -[2]: https://en.wikipedia.org/wiki/Himawari_8 -[0]: https://github.com/boramalper/himawaripy From d592e68b58f12b4f81d258e424941677c22030a5 Mon Sep 17 00:00:00 2001 From: ChrisLeeGit Date: Sun, 31 Jul 2016 19:24:56 +0800 Subject: [PATCH 092/122] =?UTF-8?q?=E5=AE=8C=E6=88=90=E7=BF=BB=E8=AF=91?= =?UTF-8?q?=EF=BC=9AHow=20to=20Configure=20and=20Troubleshoot=20Grand=20Un?= =?UTF-8?q?ified=20Bootloader=20(GRUB)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...leshoot Grand Unified Bootloader (GRUB).md | 187 ------------------ ...leshoot Grand Unified Bootloader (GRUB).md | 184 +++++++++++++++++ 2 files changed, 184 insertions(+), 187 deletions(-) delete mode 100644 sources/tech/LFCS/Part 13 - How to Configure and Troubleshoot Grand Unified Bootloader (GRUB).md create mode 100644 translated/tech/LFCS/Part 13 - How to Configure and Troubleshoot Grand Unified Bootloader (GRUB).md diff --git a/sources/tech/LFCS/Part 13 - How to Configure and Troubleshoot Grand Unified Bootloader (GRUB).md b/sources/tech/LFCS/Part 13 - How to Configure and Troubleshoot Grand Unified Bootloader (GRUB).md deleted file mode 100644 index 2d1cbef467..0000000000 --- a/sources/tech/LFCS/Part 13 - How to Configure and Troubleshoot Grand Unified Bootloader (GRUB).md +++ /dev/null @@ -1,187 +0,0 @@ -Being translated by ChrisLeeGit - -Part 13 - LFCS: How to Configure and Troubleshoot Grand Unified Bootloader (GRUB) -===================================================================================== - -Because of the changes in the LFCS exam requirements effective Feb. 2, 2016, we are adding the necessary topics to the [LFCS series][1] published here. To prepare for this exam, your are highly encouraged to use the [LFCE series][2] as well. - -![](http://www.tecmint.com/wp-content/uploads/2016/03/Configure-Troubleshoot-Grub-Boot-Loader.png) ->LFCS: Configure and Troubleshoot Grub Boot Loader – Part 13 - -In this article we will introduce you to GRUB and explain why a boot loader is necessary, and how it adds versatility to the system. - -The [Linux boot process][3] from the time you press the power button of your computer until you get a fully-functional system follows this high-level sequence: - -* 1. A process known as **POST** (**Power-On Self Test**) performs an overall check on the hardware components of your computer. -* 2. When **POST** completes, it passes the control over to the boot loader, which in turn loads the Linux kernel in memory (along with **initramfs**) and executes it. The most used boot loader in Linux is the **GRand Unified Boot loader**, or **GRUB** for short. -* 3. The kernel checks and accesses the hardware, and then runs the initial process (mostly known by its generic name “**init**”) which in turn completes the system boot by starting services. - -In Part 7 of this series (“[SysVinit, Upstart, and Systemd][4]”) we introduced the [service management systems and tools][5] used by modern Linux distributions. You may want to review that article before proceeding further. - -### Introducing GRUB Boot Loader - -Two major **GRUB** versions (**v1** sometimes called **GRUB Legacy** and **v2**) can be found in modern systems, although most distributions use **v2** by default in their latest versions. Only **Red Hat Enterprise Linux 6** and its derivatives still use **v1** today. - -Thus, we will focus primarily on the features of **v2** in this guide. - -Regardless of the **GRUB** version, a boot loader allows the user to: - -* 1). modify the way the system behaves by specifying different kernels to use, -* 2). choose between alternate operating systems to boot, and -* 3). add or edit configuration stanzas to change boot options, among other things. - -Today, **GRUB** is maintained by the **GNU** project and is well documented in their website. You are encouraged to use the [GNU official documentation][6] while going through this guide. - -When the system boots you are presented with the following **GRUB** screen in the main console. Initially, you are prompted to choose between alternate kernels (by default, the system will boot using the latest kernel) and are allowed to enter a **GRUB** command line (with `c`) or edit the boot options (by pressing the `e` key). - -![](http://www.tecmint.com/wp-content/uploads/2016/03/GRUB-Boot-Screen.png) ->GRUB Boot Screen - -One of the reasons why you would consider booting with an older kernel is a hardware device that used to work properly and has started “acting up” after an upgrade (refer to [this link][7] in the AskUbuntu forums for an example). - -The **GRUB v2** configuration is read on boot from `/boot/grub/grub.cfg` or `/boot/grub2/grub.cfg`, whereas `/boot/grub/grub.conf` or `/boot/grub/menu.lst` are used in **v1**. These files are NOT to be edited by hand, but are modified based on the contents of `/etc/default/grub` and the files found inside `/etc/grub.d`. - -In a **CentOS 7**, here’s the configuration file that is created when the system is first installed: - -``` -GRUB_TIMEOUT=5 -GRUB_DISTRIBUTOR="$(sed 's, release .*$,,g' /etc/system-release)" -GRUB_DEFAULT=saved -GRUB_DISABLE_SUBMENU=true -GRUB_TERMINAL_OUTPUT="console" -GRUB_CMDLINE_LINUX="vconsole.keymap=la-latin1 rd.lvm.lv=centos_centos7-2/swap crashkernel=auto vconsole.font=latarcyrheb-sun16 rd.lvm.lv=centos_centos7-2/root rhgb quiet" -GRUB_DISABLE_RECOVERY="true" -``` - -In addition to the online documentation, you can also find the GNU GRUB manual using info as follows: - -``` -# info grub -``` - -If you’re interested specifically in the options available for /etc/default/grub, you can invoke the configuration section directly: - -``` -# info -f grub -n 'Simple configuration' -``` - -Using the command above you will find out that `GRUB_TIMEOUT` sets the time between the moment when the initial screen appears and the system automatic booting begins unless interrupted by the user. When this variable is set to `-1`, boot will not be started until the user makes a selection. - -When multiple operating systems or kernels are installed in the same machine, `GRUB_DEFAULT` requires an integer value that indicates which OS or kernel entry in the GRUB initial screen should be selected to boot by default. The list of entries can be viewed not only in the splash screen shown above, but also using the following command: - -### In CentOS and openSUSE: - -``` -# awk -F\' '$1=="menuentry " {print $2}' /boot/grub2/grub.cfg -``` - -### In Ubuntu: - -``` -# awk -F\' '$1=="menuentry " {print $2}' /boot/grub/grub.cfg -``` - -In the example shown in the below image, if we wish to boot with the kernel version **3.10.0-123.el7.x86_64** (4th entry), we need to set `GRUB_DEFAULT` to `3` (entries are internally numbered beginning with zero) as follows: - -``` -GRUB_DEFAULT=3 -``` - -![](http://www.tecmint.com/wp-content/uploads/2016/03/Boot-System-with-Old-Kernel-Version.png) ->Boot System with Old Kernel Version - -One final GRUB configuration variable that is of special interest is `GRUB_CMDLINE_LINUX`, which is used to pass options to the kernel. The options that can be passed through GRUB to the kernel are well documented in the [Kernel Parameters file][8] and in [man 7 bootparam][9]. - -Current options in my **CentOS 7** server are: - -``` -GRUB_CMDLINE_LINUX="vconsole.keymap=la-latin1 rd.lvm.lv=centos_centos7-2/swap crashkernel=auto vconsole.font=latarcyrheb-sun16 rd.lvm.lv=centos_centos7-2/root rhgb quiet" -``` - -Why would you want to modify the default kernel parameters or pass extra options? In simple terms, there may be times when you need to tell the kernel certain hardware parameters that it may not be able to determine on its own, or to override the values that it would detect. - -This happened to me not too long ago when I tried **Vector Linux**, a derivative of **Slackware**, on my 10-year old laptop. After installation it did not detect the right settings for my video card so I had to modify the kernel options passed through GRUB in order to make it work. - -Another example is when you need to bring the system to single-user mode to perform maintenance tasks. You can do this by appending the word single to `GRUB_CMDLINE_LINUX` and rebooting: - -``` -GRUB_CMDLINE_LINUX="vconsole.keymap=la-latin1 rd.lvm.lv=centos_centos7-2/swap crashkernel=auto vconsole.font=latarcyrheb-sun16 rd.lvm.lv=centos_centos7-2/root rhgb quiet single" -``` - -After editing `/etc/defalt/grub`, you will need to run `update-grub` (Ubuntu) or `grub2-mkconfig -o /boot/grub2/grub.cfg` (**CentOS** and **openSUSE**) afterwards to update `grub.cfg` (otherwise, changes will be lost upon boot). - -This command will process the boot configuration files mentioned earlier to update `grub.cfg`. This method ensures changes are permanent, while options passed through GRUB at boot time will only last during the current session. - -### Fixing Linux GRUB Issues - -If you install a second operating system or if your GRUB configuration file gets corrupted due to human error, there are ways you can get your system back on its feet and be able to boot again. - -In the initial screen, press `c` to get a GRUB command line (remember that you can also press `e` to edit the default boot options), and use help to bring the available commands in the GRUB prompt: - -![](http://www.tecmint.com/wp-content/uploads/2016/03/Fix-Grub-Issues-in-Linux.png) ->Fix Grub Configuration Issues in Linux - -We will focus on **ls**, which will list the installed devices and filesystems, and we will examine what it finds. In the image below we can see that there are 4 hard drives (`hd0` through `hd3`). - -Only `hd0` seems to have been partitioned (as evidenced by msdos1 and msdos2, where 1 and 2 are the partition numbers and msdos is the partitioning scheme). - -Let’s now examine the first partition on `hd0` (**msdos1**) to see if we can find GRUB there. This approach will allow us to boot Linux and there use other high level tools to repair the configuration file or reinstall GRUB altogether if it is needed: - -``` -# ls (hd0,msdos1)/ -``` - -As we can see in the highlighted area, we found the `grub2` directory in this partition: - -![](http://www.tecmint.com/wp-content/uploads/2016/03/Find-Grub-Configuration.png) ->Find Grub Configuration - -Once we are sure that GRUB resides in (**hd0,msdos1**), let’s tell GRUB where to find its configuration file and then instruct it to attempt to launch its menu: - -``` -set prefix=(hd0,msdos1)/grub2 -set root=(hd0,msdos1) -insmod normal -normal -``` - -![](http://www.tecmint.com/wp-content/uploads/2016/03/Find-and-Launch-Grub-Menu.png) ->Find and Launch Grub Menu - -Then in the GRUB menu, choose an entry and press **Enter** to boot using it. Once the system has booted you can issue the `grub2-install /dev/sdX` command (change `sdX` with the device you want to install GRUB on). The boot information will then be updated and all related files be restored. - -``` -# grub2-install /dev/sdX -``` - -Other more complex scenarios are documented, along with their suggested fixes, in the [Ubuntu GRUB2 Troubleshooting guide][10]. The concepts explained there are valid for other distributions as well. - -### Summary - -In this article we have introduced you to GRUB, indicated where you can find documentation both online and offline, and explained how to approach an scenario where a system has stopped booting properly due to a bootloader-related issue. - -Fortunately, GRUB is one of the tools that is best documented and you can easily find help either in the installed docs or online using the resources we have shared in this article. - -Do you have questions or comments? Don’t hesitate to let us know using the comment form below. We look forward to hearing from you! - --------------------------------------------------------------------------------- - -via: http://www.tecmint.com/linux-basic-shell-scripting-and-linux-filesystem-troubleshooting/ - -作者:[Gabriel Cánepa][a] -译者:[ChrisLeeGit](https://github.com/chrisleegit) -校对:[校对者ID](https://github.com/校对者ID) - -本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创翻译,[Linux中国](https://linux.cn/) 荣誉推出 - -[a]: http://www.tecmint.com/author/gacanepa/ -[1]: http://www.tecmint.com/sed-command-to-create-edit-and-manipulate-files-in-linux/ -[2]: http://www.tecmint.com/installing-network-services-and-configuring-services-at-system-boot/ -[3]: http://www.tecmint.com/linux-boot-process/ -[4]: http://www.tecmint.com/linux-boot-process-and-manage-services/ -[5]: http://www.tecmint.com/best-linux-log-monitoring-and-management-tools/ -[6]: http://www.gnu.org/software/grub/manual/ -[7]: http://askubuntu.com/questions/82140/how-can-i-boot-with-an-older-kernel-version -[8]: https://www.kernel.org/doc/Documentation/kernel-parameters.txt -[9]: http://man7.org/linux/man-pages/man7/bootparam.7.html -[10]: https://help.ubuntu.com/community/Grub2/Troubleshooting diff --git a/translated/tech/LFCS/Part 13 - How to Configure and Troubleshoot Grand Unified Bootloader (GRUB).md b/translated/tech/LFCS/Part 13 - How to Configure and Troubleshoot Grand Unified Bootloader (GRUB).md new file mode 100644 index 0000000000..d8b7b294e2 --- /dev/null +++ b/translated/tech/LFCS/Part 13 - How to Configure and Troubleshoot Grand Unified Bootloader (GRUB).md @@ -0,0 +1,184 @@ +LFCS 系列第十三讲:如何配置并排除 GNU 引导加载程序(GRUB)故障 +===================================================================================== + +由于 LFCS 考试需求的变动已于 2016 年 2 月 2 日生效,因此我们向 [LFCS 系列][1] 添加了一些必要的话题。为了准备认证考试,我们也强烈推荐你去看 [LFCE 系列][2]。 + +![](http://www.tecmint.com/wp-content/uploads/2016/03/Configure-Troubleshoot-Grub-Boot-Loader.png) +>LFCS 系列第十三讲:配置并排除 Grub 引导加载程序故障。 + +本文将会向你介绍 GRUB 的知识,并会说明你为什么需要一个引导加载程序,以及它是如何增强系统通用性的。 + +[Linux 引导过程][3] 是从你按下你的电脑电源键开始,直到你拥有一个全功能的系统为止,整个过程遵循着这样的高层次顺序: + +* 1. 一个叫做 **POST**(**上电自检**)的过程会对你的电脑硬件组件做全面的检查。 +* 2. 当 **POST** 完成后,它会把控制权转交给引导加载程序,接下来引导加载程序会将 Linux 内核(以及 **initramfs**)加载到内存中并执行。 +* 3. 内核首先检查并访问硬件,然后运行初始进程(主要以它的通用名 **init** 而为人熟知),接下来初始进程会启动一些服务,最后完成系统启动过程。 + +在该系列的第七讲(“[SysVinit, Upstart, 和 Systemd][4]”)中,我们介绍了现代 Linux 发行版使用的一些服务管理系统和工具。在继续学习之前,你可能想要回顾一下那一讲的知识。 + +### GRUB 引导装载程序介绍 + +在现代系统中,你会发现有两种主要的 **GRUB** 版本(一种是偶尔被成为 **GRUB Legacy** 的 **v1** 版本,另一种则是 **v2** 版本),虽说多数最新版本的发行版系统都默认使用了 **v2** 版本。如今,只有 **红帽企业版 Linux 6** 及其衍生系统仍在使用 **v1** 版本。 + +因此,在本指南中,我们将着重关注 **v2** 版本的功能。 + +不管 **GRUB** 的版本是什么,一个引导加载程序都允许用户: + +* 1). 通过指定使用不同的内核来修改系统的表现方式; +* 2). 从多个操作系统中选择一个启动; +* 3). 添加或编辑配置节点来改变启动选项等。 + +如今,**GNU** 项目负责维护 **GRUB**,并在它们的网站上提供了丰富的文档。当你在阅读这篇指南时,我们强烈建议你看下 [GNU 官方文档][6]。 + +当系统引导时,你会在主控制台看到如下的 **GRUB** 画面。最开始,你可以根据提示在多个内核版本中选择一个内核(默认情况下,系统将会使用最新的内核启动),并且可以进入 **GRUB** 命令行模式(使用 `c` 键),或者编辑启动项(按下 `e` 键)。 + +![](http://www.tecmint.com/wp-content/uploads/2016/03/GRUB-Boot-Screen.png) +> GRUB 启动画面 + +你会考虑使用一个旧版内核启动的原因之一是之前工作正常的某个硬件设备在一次升级后出现了“怪毛病(acting up)”(例如,你可以参考 AskUbuntu 论坛中的 [这条链接][7])。 + +**GRUB v2** 的配置文件会在启动时从 `/boot/grub/grub.cfg` 或 `/boot/grub2/grub.cfg` 文件中读取,而 **GRUB v1** 使用的配置文件则来自 `/boot/grub/grub.conf` 或 `/boot/grub/menu.lst`。这些文件不能直接手动编辑,而是根据 `/etc/default/grub` 的内容和 `/etc/grub.d` 目录中的文件来修改的。 + +在 **CentOS 7** 上,当系统最初完成安装后,会生成如下的配置文件: + +``` +GRUB_TIMEOUT=5 +GRUB_DISTRIBUTOR="$(sed 's, release .*$,,g' /etc/system-release)" +GRUB_DEFAULT=saved +GRUB_DISABLE_SUBMENU=true +GRUB_TERMINAL_OUTPUT="console" +GRUB_CMDLINE_LINUX="vconsole.keymap=la-latin1 rd.lvm.lv=centos_centos7-2/swap crashkernel=auto vconsole.font=latarcyrheb-sun16 rd.lvm.lv=centos_centos7-2/root rhgb quiet" +GRUB_DISABLE_RECOVERY="true" +``` + +除了在线文档外,你也可以使用下面的命令查阅 GNU GRUB 手册: + +``` +# info grub +``` + +如果你对 `/etc/default/grub` 文件中的可用选项特别感兴趣的话,你可以直接查阅配置一节的帮助文档: + +``` +# info -f grub -n 'Simple configuration' +``` + +使用上述命令,你会发现 `GRUB_TIMEOUT` 用于设置启动画面出现和系统自动开始启动(除非被用户中断)之间的时间。当该变量值为 `-1` 时,除非用户主动做出选择,否则不会开始启动。 + +当同一台机器上安装了多个操作系统或内核后,`GRUB_DEFAULT` 就需要用一个整数来指定 GRUB 启动画面默认选择启动的操作系统或内核条目。我们既可以通过上述启动画查看启动条目列表,也可以使用下面的命令: + +### 在 CentOS 和 openSUSE 系统上 + +``` +# awk -F\' '$1=="menuentry " {print $2}' /boot/grub2/grub.cfg +``` + +### 在 Ubuntu 系统上 + +``` +# awk -F\' '$1=="menuentry " {print $2}' /boot/grub/grub.cfg +``` + +如下图所示的例子中,如果我们想要使用版本为 `3.10.0-123.el7.x86_64` 的内核(第四个条目),我们需要将 `GRUB_DEFAULT` 设置为 `3`(条目从零开始编号),如下所示: + +``` +GRUB_DEFAULT=3 +``` + +![](http://www.tecmint.com/wp-content/uploads/2016/03/Boot-System-with-Old-Kernel-Version.png) +> 使用旧版内核启动系统 + +最后一个需要特别关注的 GRUB 配置变量是 `GRUB_CMDLINE_LINUX`,它是用来给内核传递选项的。我们可以在 [内核变量文件][8] 和 [man 7 bootparam][9] 中找到能够通过 GRUB 传递给内核的选项的详细文档。 + +我的 **CentOS 7** 服务器上当前的选项是: + +``` +GRUB_CMDLINE_LINUX="vconsole.keymap=la-latin1 rd.lvm.lv=centos_centos7-2/swap crashkernel=auto vconsole.font=latarcyrheb-sun16 rd.lvm.lv=centos_centos7-2/root rhgb quiet" +``` +为什么你希望修改默认的内核参数或者传递额外的选项呢?简单来说,在很多情况下,你需要告诉内核某些由内核自身无法判断的硬件参数,或者是覆盖一些内核会检测的值。 + +不久之前,就在我身上发生过这样的事情,当时我在自己已用了 10 年的老笔记本上尝试衍生自 **Slackware** 的 **Vector Linux**。完成安装后,内核并没有检测出我的显卡的正确配置,所以我不得不通过 GRUB 传递修改过的内核选项来让它工作。 + +另外一个例子是当你需要将系统切换到单用户模式以执行维护工作时。为此,你可以直接在 `GRUB_CMDLINE_LINUX` 变量中直接追加 `single` 并重启即可: + +``` +GRUB_CMDLINE_LINUX="vconsole.keymap=la-latin1 rd.lvm.lv=centos_centos7-2/swap crashkernel=auto vconsole.font=latarcyrheb-sun16 rd.lvm.lv=centos_centos7-2/root rhgb quiet single" +``` + +编辑完 `/etc/default/grub` 之后,你需要运行 `update-grub` (在 Ubuntu 上)或者 `grub2-mkconfig -o /boot/grub2/grub.cfg` (在 **CentOS** 和 **openSUSE** 上)命令来更新 `grub.cfg` 文件(否则,改动会在系统启动时丢失)。 + +这条命令会处理早先提到的一些启动配置文件来更新 `grub.cfg` 文件。这种方法可以确保改动持久化,而在启动时刻通过 GRUB 传递的选项仅在当前会话期间有效。 + +### 修复 Linux GRUB 问题 + +如果你安装了第二个操作系统,或者由于人为失误而导致你的 GRUB 配置文件损坏了,依然有一些方法可以让你恢复并能够再次启动系统。 + +在启动画面中按下 `c` 键进入 GRUB 命令行模式(记住,你也可以按下 `e` 键编辑默认启动选项),并可以在 GRUB 提示中输入 `help` 命令获得可用命令: + +![](http://www.tecmint.com/wp-content/uploads/2016/03/Fix-Grub-Issues-in-Linux.png) +> 修复 Linux 的 Grub 配置问题 + +我们将会着重关注 **ls** 命令,它会列出已安装的设备和文件系统,并且我们将会看看它可以查找什么。在下面的图片中,我们可以看到有 4 块硬盘(`hd0` 到 `hd3`)。 + +貌似只有 `hd0` 已经分区了(msdos1 和 msdos2 可以证明,这里的 1 和 2 是分区号,msdos 则是分区方案)。 + +现在我们来看看能否在第一个分区 `hd0`(**msdos1**)上找到 GRUB。这种方法允许我们启动 Linux,并且使用高级工具修复配置文件或者如果有必要的话,干脆重新安装 GRUB: + +``` +# ls (hd0,msdos1)/ +``` + +从高亮区域可以发现,`grub2` 目录就在这个分区: + +![](http://www.tecmint.com/wp-content/uploads/2016/03/Find-Grub-Configuration.png) +> 查找 Grub 配置 + +一旦我们确信了 GRUB 位于 (**hd0, msdos1**),那就让我们告诉 GRUB 该去哪儿查找它的配置文件并指示它去尝试启动它的菜单: + +``` +set prefix=(hd0,msdos1)/grub2 +set root=(hd0,msdos1) +insmod normal +normal +``` + +![](http://www.tecmint.com/wp-content/uploads/2016/03/Find-and-Launch-Grub-Menu.png) +> 查找并启动 Grub 菜单 + +然后,在 GRUB 菜单中,选择一个条目并按下 **Enter** 键以使用它启动。一旦系统成功启动后,你就可以运行 `grub2-install /dev/sdX` 命令修复问题了(将 `sdX` 改成你想要安装 GRUB 的设备)。然后启动信息将会更新,并且所有相关文件都会得到恢复。 + +``` +# grub2-install /dev/sdX +``` + +其它更加复杂的情景及其修复建议都记录在 [Ubuntu GRUB2 故障排除指南][10] 中。该指南中阐述的概念对于其它发行版也是有效的。 + +### 总结 + +本文向你介绍了 GRUB,并指导你可以在何处找到线上和线下的文档,同时说明了如何面对由于引导加载相关的问题而导致系统无法正常启动的情况。 + +幸运的是,GRUB 是文档支持非常丰富的工具之一,你可以使用我们在文中分享的资源非常轻松地获取已安装的文档或在线文档。 + +你有什么问题或建议吗?请不要犹豫,使用下面的评论框告诉我们吧。我们期待着来自你的回复! + +-------------------------------------------------------------------------------- + +via: http://www.tecmint.com/configure-and-troubleshoot-grub-boot-loader-linux/ + +作者:[Gabriel Cánepa][a] +译者:[ChrisLeeGit](https://github.com/chrisleegit) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创翻译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]: http://www.tecmint.com/author/gacanepa/ +[1]: http://www.tecmint.com/sed-command-to-create-edit-and-manipulate-files-in-linux/ +[2]: http://www.tecmint.com/installing-network-services-and-configuring-services-at-system-boot/ +[3]: http://www.tecmint.com/linux-boot-process/ +[4]: http://www.tecmint.com/linux-boot-process-and-manage-services/ +[5]: http://www.tecmint.com/best-linux-log-monitoring-and-management-tools/ +[6]: http://www.gnu.org/software/grub/manual/ +[7]: http://askubuntu.com/questions/82140/how-can-i-boot-with-an-older-kernel-version +[8]: https://www.kernel.org/doc/Documentation/kernel-parameters.txt +[9]: http://man7.org/linux/man-pages/man7/bootparam.7.html +[10]: https://help.ubuntu.com/community/Grub2/Troubleshooting From a99e94384d18bc39e73223dc62b37d182c897909 Mon Sep 17 00:00:00 2001 From: ChrisLeeGit Date: Sun, 31 Jul 2016 21:51:00 +0800 Subject: [PATCH 093/122] =?UTF-8?q?=E5=AE=8C=E6=88=90=E7=BF=BB=E8=AF=91?= =?UTF-8?q?=EF=BC=9AKeeweb=20A=20Linux=20Password=20Manager?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...0160722 Keeweb A Linux Password Manager.md | 64 ------------------- ...0160722 Keeweb A Linux Password Manager.md | 62 ++++++++++++++++++ 2 files changed, 62 insertions(+), 64 deletions(-) delete mode 100644 sources/tech/20160722 Keeweb A Linux Password Manager.md create mode 100644 translated/tech/20160722 Keeweb A Linux Password Manager.md diff --git a/sources/tech/20160722 Keeweb A Linux Password Manager.md b/sources/tech/20160722 Keeweb A Linux Password Manager.md deleted file mode 100644 index b55de2a4cb..0000000000 --- a/sources/tech/20160722 Keeweb A Linux Password Manager.md +++ /dev/null @@ -1,64 +0,0 @@ -Being translated by ChrisLeeGit - -Keeweb A Linux Password Manager -================================ - -![](http://www.linuxandubuntu.com/uploads/2/1/1/5/21152474/keeweb_1.png?608) - -Today we are depending on more and more online services. Each online service we sign up for, let us set a password and this way we have to remember hundreds of passwords. In this case, it is easy for anyone to forget passwords. In this article I am going to talk about Keeweb, a Linux password manager that can store all your passwords securely either online or offline. - -When we talk about Linux password managers, there are so many. Password managers like, [Keepass][1] and [Encryptr, a Zero-knowledge system based password manager][2] have already been talked about on LinuxAndUbuntu. Keeweb is another password manager for Linux that we are going to see in this article. - -### Keeweb can store passwords offline or online - -Keeweb is a cross-platform password manager. It can store all your passwords offline and sync it with your own cloud storage services like OneDrive, Google Drive, Dropbox etc. Keeweb does not have online database of its own to sync your passwords. - -To connect your online storage with Keeweb, just click more and click the service that you want to use. - -![](http://www.linuxandubuntu.com/uploads/2/1/1/5/21152474/keeweb.png?685) - -Now Keeweb will prompt you to sign in to your drive. After sign in authenticate Keeweb to use your account. - -![](http://www.linuxandubuntu.com/uploads/2/1/1/5/21152474/authenticate-dropbox-with-keeweb_orig.jpg?649) - -### Store passwords with Keeweb - -It is very easy to store your passwords with Keeweb. You can encrypt your password file with a complex password. Keeweb also allows you to lock file with a key file but I don't recommend it. If somebody gets your key file, it takes only a click to unlock your passwords file. - -#### Create Passwords - -To create a new password simply click the '+' sign and you will be presented all entries to fill up. You can create more entries if you want. - -#### Search Passwords - -![](http://www.linuxandubuntu.com/uploads/2/1/1/5/21152474/search-passwords_orig.png) - -Keeweb has a library of icons so that you can find any particular password entry easily. You can change the color of icons, download more icons and even import icons from your computer. When talking about finding passwords the search comes very handy. ​ - -Passwords of similar services can be grouped so that you can find them all at one place in one folder. You can also tag passwords to store them all in different categories. - -![](http://www.linuxandubuntu.com/uploads/2/1/1/5/21152474/tags-passwords-in-keeweb.png?283) - -### Themes - -![](http://www.linuxandubuntu.com/uploads/2/1/1/5/21152474/themes.png?304) - -If you like light themes like white or high contrast then you can change theme from Settings > General > Themes. There are four themes available, two are dark and two are light. - -### Dont' you Like Linux Passwords Manager? No problem! - -I have already posted about two other Linux password managers, Keepass and Encryptr and there were arguments on Reddit, and other social media. There were people against using any password manager and vice-versa. In this article I want to clear out that it is our responsibility to save the file that passwords are stored in. I think Password managers like Keepass and Keeweb are good to use as they don't store your passwords in the cloud. These password managers create a file and you can store it on your hard drive or encrypt it with apps like VeraCrypt. I myself don't use or recommend to use services that store passwords in their own database. - --------------------------------------------------------------------------------- - -via: http://www.tecmint.com/mandatory-access-control-with-selinux-or-apparmor-linux/ - -作者:[author][a] -译者:[ChrisLeeGit](https://github.com/chrisleegit) -校对:[校对者ID](https://github.com/校对者ID) - -本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 - -[a]: http://www.linuxandubuntu.com/home/keeweb-a-linux-password-manager -[1]: http://www.linuxandubuntu.com/home/keepass-password-management-tool-creates-strong-passwords-and-keeps-them-secure -[2]: http://www.linuxandubuntu.com/home/encryptr-zero-knowledge-system-based-password-manager-for-linux diff --git a/translated/tech/20160722 Keeweb A Linux Password Manager.md b/translated/tech/20160722 Keeweb A Linux Password Manager.md new file mode 100644 index 0000000000..3e32d1001c --- /dev/null +++ b/translated/tech/20160722 Keeweb A Linux Password Manager.md @@ -0,0 +1,62 @@ +Linux 密码管理器:Keeweb +================================ + +![](http://www.linuxandubuntu.com/uploads/2/1/1/5/21152474/keeweb_1.png?608) + +如今,我们依赖于越来越多的线上服务。我们每注册一个线上服务,就要设置一个密码;如此,我们就不得不记住数以百计的密码。这样对于每个人来说,都很容易忘记密码。我将在本文中介绍 Keeweb,它是一款 Linux 密码管理器,可以将你所有的密码安全地存储在线上或线下。 + +当谈及 Linux 密码管理器时,我们会发现有很多这样的软件。我们已经在 LinuxAndUbuntu 上讨论过像 [Keepass][1] 和 [Encryptr,一个基于零知识系统的密码管理器][2] 这样的密码管理器。Keeweb 则是另外一款我们将在本文讲解的 Linux 密码管理器。 + +### Keeweb 可以在线下或线上存储密码 + +Keeweb 是一款跨平台的密码管理器。它可以在线下存储你所有的密码,并且能够同步到你自己的云存储服务上,例如 OneDrive, Google Drive, Dropbox 等。Keeweb 并没有它自己的用于同步你密码的在线数据库。 + +要使用 Keeweb 连接你的线上存储服务,只需要点击更多,然后再点击你想要使用的服务即可。 + +![](http://www.linuxandubuntu.com/uploads/2/1/1/5/21152474/keeweb.png?685) + +现在,Keeweb 会提示你登录到你的云盘。登录成功后,给 Keeweb 授权使用你的账户。 + +![](http://www.linuxandubuntu.com/uploads/2/1/1/5/21152474/authenticate-dropbox-with-keeweb_orig.jpg?649) + +### 使用 Keeweb 存储密码 + +使用 Keeweb 存储你的密码是非常容易的。你可以使用一个复杂的密码加密你的密码文件。Keeweb 也允许你使用一个秘钥文件来锁定密码文件,但是我并不推荐这种方式。如果某个家伙拿到了你的秘钥文件,他只需要简单点击一下就可以解锁你的密码文件。 + +#### 创建密码 + +想要创建一个新的密码,你只需要简单地点击 `+` 号,然后你就会看到所有需要填充的输入框。如果你想的话,可以创建更多的输入框。 + +#### 搜索密码 + +![](http://www.linuxandubuntu.com/uploads/2/1/1/5/21152474/search-passwords_orig.png) + +Keeweb 拥有一个图标库,这样你就可以轻松地找到任何特定的密码入口。你可以改变图标的颜色、下载更多的图标,甚至可以直接从你的电脑中导入图标。这对于密码搜索来说,异常好使。 + +相似服务的密码可以分组,这样你就可以在一个文件夹的一个地方同时找到它们。你也可以给密码打上标签并把它们存放在不同分类中。 + +![](http://www.linuxandubuntu.com/uploads/2/1/1/5/21152474/tags-passwords-in-keeweb.png?283) + +### 主题 + +![](http://www.linuxandubuntu.com/uploads/2/1/1/5/21152474/themes.png?304) + +如果你喜欢类似于白色或者高对比度的亮色主题,你可以在“设置 > 通用 > 主题”中修改。(Keeweb)有四款可供选择的主题,其中两款为暗色,另外两款为亮色。 + +### 不喜欢 Linux 密码管理器?没问题! + +我已经发表过文章介绍了另外两款 Linux 密码管理器,它们分别是 Keepass 和 Encryptr,在 Reddit 和其它社交媒体上有些关于它们的争论。有些人反对使用任何密码管理器,反之亦然。在本文中,我想要澄清的是,存放密码文件是我们自己的责任。我认为像 keepass 和 Keeweb 这样的密码管理器是非常好用的,因为它们并没有自己的云来存放你的密码。这些密码管理器会创建一个文件,然后你可以将它存放在你的硬盘上,或者使用像 VeraCrypt 这样的应用给它加密。我个人不使用也不推荐使用那些将密码存储在它们自己数据库的服务。 + +-------------------------------------------------------------------------------- + +via: http://www.linuxandubuntu.com/home/keeweb-a-linux-password-manager + +作者:[author][a] +译者:[ChrisLeeGit](https://github.com/chrisleegit) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]: http://www.linuxandubuntu.com/home/keeweb-a-linux-password-manager +[1]: http://www.linuxandubuntu.com/home/keepass-password-management-tool-creates-strong-passwords-and-keeps-them-secure +[2]: http://www.linuxandubuntu.com/home/encryptr-zero-knowledge-system-based-password-manager-for-linux From 35a7b4b8d36880eccc22b65d2540d1afdf04e5d5 Mon Sep 17 00:00:00 2001 From: alim0x Date: Sun, 31 Jul 2016 22:20:32 +0800 Subject: [PATCH 094/122] [translating]Implementing Mandatory Access Control with SELinux or AppArmor in Linux --- ...andatory Access Control with SELinux or AppArmor in Linux.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sources/tech/20160608 Implementing Mandatory Access Control with SELinux or AppArmor in Linux.md b/sources/tech/20160608 Implementing Mandatory Access Control with SELinux or AppArmor in Linux.md index 65c8657dff..c4c6aecec6 100644 --- a/sources/tech/20160608 Implementing Mandatory Access Control with SELinux or AppArmor in Linux.md +++ b/sources/tech/20160608 Implementing Mandatory Access Control with SELinux or AppArmor in Linux.md @@ -1,3 +1,5 @@ +alim0x translating + Implementing Mandatory Access Control with SELinux or AppArmor in Linux =========================================================================== From b6719d8cc4c0c141c014628b89c5ae2cec9accab Mon Sep 17 00:00:00 2001 From: ChrisLeeGit Date: Sun, 31 Jul 2016 22:58:17 +0800 Subject: [PATCH 095/122] =?UTF-8?q?=E7=94=B3=E8=AF=B7=E7=BF=BB=E8=AF=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...9 - Learn How to Use Awk Special Patterns begin and end.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sources/tech/awk/20160719 Part 9 - Learn How to Use Awk Special Patterns begin and end.md b/sources/tech/awk/20160719 Part 9 - Learn How to Use Awk Special Patterns begin and end.md index f64e834ca1..b3f99e6d4f 100644 --- a/sources/tech/awk/20160719 Part 9 - Learn How to Use Awk Special Patterns begin and end.md +++ b/sources/tech/awk/20160719 Part 9 - Learn How to Use Awk Special Patterns begin and end.md @@ -1,3 +1,5 @@ +Being translated by ChrisLeeGit + Learn How to Use Awk Special Patterns ‘BEGIN and END’ – Part 9 =============================================================== @@ -158,7 +160,7 @@ As I pointed out before, these Awk features will help us build more complex text via: http://www.tecmint.com/learn-use-awk-special-patterns-begin-and-end/ 作者:[Aaron Kili][a] -译者:[译者ID](https://github.com/译者ID) +译者:[ChrisLeeGit](https://github.com/chrisleegit) 校对:[校对ID](https://github.com/校对ID) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 From 705f188aa63789937172d89bf488e737c1979aa3 Mon Sep 17 00:00:00 2001 From: vim-kakali <1799225723@qq.com> Date: Mon, 1 Aug 2016 02:07:10 +0800 Subject: [PATCH 096/122] translated --- ...ic Expressions and Assignment Operators.md | 275 ------------------ ...ic Expressions and Assignment Operators.md | 275 ++++++++++++++++++ 2 files changed, 275 insertions(+), 275 deletions(-) delete mode 100644 sources/tech/awk/20160714 Part 8 - Learn How to Use Awk Variables, Numeric Expressions and Assignment Operators.md create mode 100644 translated/tech/awk/20160714 Part 8 - Learn How to Use Awk Variables, Numeric Expressions and Assignment Operators.md diff --git a/sources/tech/awk/20160714 Part 8 - Learn How to Use Awk Variables, Numeric Expressions and Assignment Operators.md b/sources/tech/awk/20160714 Part 8 - Learn How to Use Awk Variables, Numeric Expressions and Assignment Operators.md deleted file mode 100644 index dd2494529d..0000000000 --- a/sources/tech/awk/20160714 Part 8 - Learn How to Use Awk Variables, Numeric Expressions and Assignment Operators.md +++ /dev/null @@ -1,275 +0,0 @@ -translating by vim-kakali - - -Learn How to Use Awk Variables, Numeric Expressions and Assignment Operators – part8 - -======================================================================================= - -The [Awk command series][1] is getting exciting I believe, in the previous seven parts, we walked through some fundamentals of Awk that you need to master to enable you perform some basic text or string filtering in Linux. - -Starting with this part, we shall dive into advance areas of Awk to handle more complex text or string filtering operations. Therefore, we are going to cover Awk features such as variables, numeric expressions and assignment operators. - -![](http://www.tecmint.com/wp-content/uploads/2016/07/Learn-Awk-Variables-Numeric-Expressions-Assignment-Operators.png) ->Learn Awk Variables, Numeric Expressions and Assignment Operators - -These concepts are not comprehensively distinct from the ones you may have probably encountered in many programming languages before such shell, C, Python plus many others, so there is no need to worry much about this topic, we are simply revising the common ideas of using these mentioned features. - -This will probably be one of the easiest Awk command sections to understand, so sit back and lets get going. - -### 1. Awk Variables - -In any programming language, a variable is a place holder which stores a value, when you create a variable in a program file, as the file is executed, some space is created in memory that will store the value you specify for the variable. - -You can define Awk variables in the same way you define shell variables as follows: - -``` -variable_name=value -``` - -In the syntax above: - -- `variable_name`: is the name you give a variable -- `value`: the value stored in the variable - -Let’s look at some examples below: - -``` -computer_name=”tecmint.com” -port_no=”22” -email=”admin@tecmint.com” -server=”computer_name” -``` - -Take a look at the simple examples above, in the first variable definition, the value `tecmint.com` is assigned to the variable `computer_name`. - -Furthermore, the value 22 is assigned to the variable port_no, it is also possible to assign the value of one variable to another variable as in the last example where we assigned the value of computer_name to the variable server. - -If you can recall, right from [part 2 of this Awk series][2] were we covered field editing, we talked about how Awk divides input lines into fields and uses standard field access operator, $ to read the different fields that have been parsed. We can also use variables to store the values of fields as follows. - -``` -first_name=$2 -second_name=$3 -``` - -In the examples above, the value of first_name is set to second field and second_name is set to the third field. - -As an illustration, consider a file named names.txt which contains a list of an application’s users indicating their first and last names plus gender. Using the [cat command][3], we can view the contents of the file as follows: - -``` -$ cat names.txt -``` - -![](http://www.tecmint.com/wp-content/uploads/2016/07/List-File-Content-Using-cat-Command.png) ->List File Content Using cat Command - -Then, we can also use the variables first_name and second_name to store the first and second names of the first user on the list as by running the Awk command below: - -``` -$ awk '/Aaron/{ first_name=$2 ; second_name=$3 ; print first_name, second_name ; }' names.txt -``` - -![](http://www.tecmint.com/wp-content/uploads/2016/07/Store-Variables-Using-Awk-Command.png) ->Store Variables Using Awk Command - -Let us also take a look at another case, when you issue the command `uname -a` on your terminal, it prints out all your system information. - -The second field contains your `hostname`, therefore we can store the hostname in a variable called hostname and print it using Awk as follows: - -``` -$ uname -a -$ uname -a | awk '{hostname=$2 ; print hostname ; }' -``` - -![](http://www.tecmint.com/wp-content/uploads/2016/07/Store-Command-Output-to-Variable-Using-Awk.png) ->Store Command Output to Variable Using Awk - -### 2. Numeric Expressions - -In Awk, numeric expressions are built using the following numeric operators: - -- `*` : multiplication operator -- `+` : addition operator -- `/` : division operator -- `-` : subtraction operator -- `%` : modulus operator -- `^` : exponentiation operator - -The syntax for a numeric expressions is: - -``` -$ operand1 operator operand2 -``` - -In the form above, operand1 and operand2 can be numbers or variable names, and operator is any of the operators above. - -Below are some examples to demonstrate how to build numeric expressions: - -``` -counter=0 -num1=5 -num2=10 -num3=num2-num1 -counter=counter+1 -``` - -To understand the use of numeric expressions in Awk, we shall consider the following example below, with the file domains.txt which contains all domains owned by Tecmint. - -``` -news.tecmint.com -tecmint.com -linuxsay.com -windows.tecmint.com -tecmint.com -news.tecmint.com -tecmint.com -linuxsay.com -tecmint.com -news.tecmint.com -tecmint.com -linuxsay.com -windows.tecmint.com -tecmint.com -``` - -To view the contents of the file, use the command below: - -``` -$ cat domains.txt -``` - -![](http://www.tecmint.com/wp-content/uploads/2016/07/View-Contents-of-File.png) ->View Contents of File - -If we want to count the number of times the domain tecmint.com appears in the file, we can write a simple script to do that as follows: - -``` -#!/bin/bash -for file in $@; do -if [ -f $file ] ; then -#print out filename -echo "File is: $file" -#print a number incrementally for every line containing tecmint.com -awk '/^tecmint.com/ { counter=counter+1 ; printf "%s\n", counter ; }' $file -else -#print error info incase input is not a file -echo "$file is not a file, please specify a file." >&2 && exit 1 -fi -done -#terminate script with exit code 0 in case of successful execution -exit 0 -``` - -![](http://www.tecmint.com/wp-content/uploads/2016/07/Shell-Script-to-Count-a-String-in-File.png) ->Shell Script to Count a String or Text in File - -After creating the script, save it and make it executable, when we run it with the file, domains.txt as out input, we get the following output: - -``` -$ ./script.sh ~/domains.txt -``` - -![](http://www.tecmint.com/wp-content/uploads/2016/07/Script-To-Count-String.png) ->Script to Count String or Text - -From the output of the script, there are 6 lines in the file domains.txt which contain tecmint.com, to confirm that you can manually count them. - -### 3. Assignment Operators - -The last Awk feature we shall cover is assignment operators, there are several assignment operators in Awk and these include the following: - -- `*=` : multiplication assignment operator -- `+=` : addition assignment operator -- `/=` : division assignment operator -- `-=` : subtraction assignment operator -- `%=` : modulus assignment operator -- `^=` : exponentiation assignment operator - -The simplest syntax of an assignment operation in Awk is as follows: - -``` -$ variable_name=variable_name operator operand -``` - -Examples: - -``` -counter=0 -counter=counter+1 -num=20 -num=num-1 -``` - -You can use the assignment operators above to shorten assignment operations in Awk, consider the previous examples, we could perform the assignment in the following form: - -``` -variable_name operator=operand -counter=0 -counter+=1 -num=20 -num-=1 -``` - -Therefore, we can alter the Awk command in the shell script we just wrote above using += assignment operator as follows: - -``` -#!/bin/bash -for file in $@; do -if [ -f $file ] ; then -#print out filename -echo "File is: $file" -#print a number incrementally for every line containing tecmint.com -awk '/^tecmint.com/ { counter+=1 ; printf "%s\n", counter ; }' $file -else -#print error info incase input is not a file -echo "$file is not a file, please specify a file." >&2 && exit 1 -fi -done -#terminate script with exit code 0 in case of successful execution -exit 0 -``` - - -![](http://www.tecmint.com/wp-content/uploads/2016/07/Alter-Shell-Script.png) ->Alter Shell Script - -In this segment of the [Awk series][4], we covered some powerful Awk features, that is variables, building numeric expressions and using assignment operators, plus some few illustrations of how we can actually use them. - -These concepts are not any different from the one in other programming languages but there may be some significant distinctions under Awk programming. - -In part 9, we shall look at more Awk features that is special patterns: BEGIN and END. Until then, stay connected to Tecmint. - - --------------------------------------------------------------------------------- - -via: http://www.tecmint.com/learn-awk-variables-numeric-expressions-and-assignment-operators/ - -作者:[Aaron Kili][a] -译者:[译者ID](https://github.com/译者ID) -校对:[校对ID](https://github.com/校对ID) - -本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 - -[a]: http://www.tecmint.com/author/aaronkili/ - - - - - - - - - - - - - - - - - - - -[1]: http://www.tecmint.com/category/awk-command/ -[2]: http://www.tecmint.com/awk-print-fields-columns-with-space-separator/ -[3]: http://www.tecmint.com/13-basic-cat-command-examples-in-linux/ -[4]: http://www.tecmint.com/category/awk-command/ diff --git a/translated/tech/awk/20160714 Part 8 - Learn How to Use Awk Variables, Numeric Expressions and Assignment Operators.md b/translated/tech/awk/20160714 Part 8 - Learn How to Use Awk Variables, Numeric Expressions and Assignment Operators.md new file mode 100644 index 0000000000..a5eb6b6df4 --- /dev/null +++ b/translated/tech/awk/20160714 Part 8 - Learn How to Use Awk Variables, Numeric Expressions and Assignment Operators.md @@ -0,0 +1,275 @@ + + +第 8 节--学习怎样使用 Awk 变量,数值表达式以及赋值运算符 + +======================================================================================= + + +我相信 [Awk 命令系列][1] 将会令人兴奋不已,在系列的前几节我们讨论了在 Linux 中处理文件和筛选字符串需要的基本 Awk 命令。 + + +在这一部分,我们会对处理更复杂的文件和筛选字符串操作需要的更高级的命令进行讨论。因此,我们将会看到关于 Awk 的一些特性诸如变量,数值表达式和赋值运算符。 +![](http://www.tecmint.com/wp-content/uploads/2016/07/Learn-Awk-Variables-Numeric-Expressions-Assignment-Operators.png) +>学习 Awk 变量,数值表达式和赋值运算符 + +你可能已经在很多编程语言中接触过它们,比如 shell,C,Python等;这些概念在理解上和这些语言没有什么不同,所以在这一小节中你不用担心很难理解,我们将会简短的提及常用的一些 Awk 特性。 + +这一小节可能是 Awk 命令里最容易理解的部分,所以放松点,我们开始吧。 +### 1. Awk 变量 + + +在任何编程语言中,当你在程序中新建一个变量的时候这个变量就是一个存储了值的占位符,程序一运行就占用了一些内存空间,你为变量赋的值会存储在这些内存空间上。 + + +你可以像下面这样定义 shell 变量一样定义 Awk 变量: +``` +variable_name=value +``` + +上面的语法: + +- `variable_name`: 为定义的变量的名字 +- `value`: 为变量赋的值 + +再看下面的一些例子: +``` +computer_name=”tecmint.com” +port_no=”22” +email=”admin@tecmint.com” +server=”computer_name” +``` + +观察上面的简单的例子,在定义第一个变量的时候,值 'tecmint.com' 被赋给了 'computer_name' 变量。 + + +此外,值 22 也被赋给了 port_no 变量,把一个变量的值赋给另一个变量也是可以的,在最后的例子中我们把变量 computer_name 的值赋给了变量 server。 + +你可以看看 [本系列的第 2 节][2] 中提到的字段编辑,我们讨论了 Awk 怎样将输入的行分隔为若干字段并且使用标准的字段进行输入操作 ,$ 访问不同的被分配的字段。我们也可以像下面这样使用变量为字段赋值。 + +``` +first_name=$2 +second_name=$3 +``` + +在上面的例子中,变量 first_name 的值设置为第二个字段,second_name 的值设置为第三个字段。 + + +再举个例子,有一个名为 names.txt 的文件,这个文件包含了一个应用程序的用户列表,这个用户列表显示了用户的名字和曾用名以及性别。可以使用 [cat 命令][3] 查看文件内容: +``` +$ cat names.txt +``` + +![](http://www.tecmint.com/wp-content/uploads/2016/07/List-File-Content-Using-cat-Command.png) +>使用 cat 命令查看列表文件内容 + + +然后,我们也可以使用下面的 Awk 命令把列表中第一个用户的第一个和第二个名字分别存储到变量 first_name 和 second_name 上: +``` +$ awk '/Aaron/{ first_name=$2 ; second_name=$3 ; print first_name, second_name ; }' names.txt +``` + +![](http://www.tecmint.com/wp-content/uploads/2016/07/Store-Variables-Using-Awk-Command.png) +>使用 Awk 命令为变量赋值 + + +再看一个例子,当你在终端运行 'uname -a' 时,它可以打印出所有的系统信息。 + +第二个字段包含了你的 'hostname',因此,我们可以像下面这样把它赋给一个叫做 hostname 的变量并且用 Awk 打印出来。 +``` +$ uname -a +$ uname -a | awk '{hostname=$2 ; print hostname ; }' +``` + +![](http://www.tecmint.com/wp-content/uploads/2016/07/Store-Command-Output-to-Variable-Using-Awk.png) +>使用 Awk 把命令的输出赋给变量 + +### 2. 数值表达式 + +在 Awk 中,数值表达式使用下面的数值运算符组成: + +- `*` : 乘法运算符 +- `+` : 加法运算符 +- `/` : 除法运算符 +- `-` : 减法运算符 +- `%` : 取模运算符 +- `^` : 指数运算符 + + +数值表达式的语法是: +``` +$ operand1 operator operand2 +``` + +上面的 operand1 和 operand2 可以是数值和变量,运算符可以是上面列出的任意一种。 + +下面是一些展示怎样使用数值表达式的例子: +``` +counter=0 +num1=5 +num2=10 +num3=num2-num1 +counter=counter+1 +``` + + +理解了 Awk 中数值表达式的用法,我们就可以看下面的例子了,文件 domians.txt 里包括了所有属于 Tecmint 的域名。 +``` +news.tecmint.com +tecmint.com +linuxsay.com +windows.tecmint.com +tecmint.com +news.tecmint.com +tecmint.com +linuxsay.com +tecmint.com +news.tecmint.com +tecmint.com +linuxsay.com +windows.tecmint.com +tecmint.com +``` + +可以使用下面的命令查看文件的内容; +``` +$ cat domains.txt +``` + +![](http://www.tecmint.com/wp-content/uploads/2016/07/View-Contents-of-File.png) +>查看文件内容 + + +如果想要计算出域名 tecmint.com 在文件中出现的次数,我们就可以通过写一个简单的脚本实现这个功能: +``` +#!/bin/bash +for file in $@; do +if [ -f $file ] ; then +#print out filename +echo "File is: $file" +#print a number incrementally for every line containing tecmint.com +awk '/^tecmint.com/ { counter=counter+1 ; printf "%s\n", counter ; }' $file +else +#print error info incase input is not a file +echo "$file is not a file, please specify a file." >&2 && exit 1 +fi +done +#terminate script with exit code 0 in case of successful execution +exit 0 +``` + +![](http://www.tecmint.com/wp-content/uploads/2016/07/Shell-Script-to-Count-a-String-in-File.png) +>计算一个字符串或文本在文件中出现次数的 shell 脚本 + + +写完脚本后保存并赋予执行权限,当我们使用文件运行脚本的时候,文件 domains.txt 作为脚本的输入,我们会得到下面的输出: + +``` +$ ./script.sh ~/domains.txt +``` + +![](http://www.tecmint.com/wp-content/uploads/2016/07/Script-To-Count-String.png) +>计算字符串或文本出现次数的脚本 + + +从脚本执行后的输出中,可以看到在文件 domains.txt 中包含域名 tecmint.com 的地方有 6 行,你可以自己计算进行验证。 + +### 3. 赋值操作符 + +我们要说的最后的 Awk 特性是赋值运算符,下面列出的只是 Awk 中的部分赋值运算符: + +- `*=` : 乘法赋值运算符 +- `+=` : 加法赋值运算符 +- `/=` : 除法赋值运算符 +- `-=` : 减法赋值运算符 +- `%=` : 取模赋值运算符 +- `^=` : 指数赋值运算符 + +下面是 Awk 中最简单的一个赋值操作的语法: +``` +$ variable_name=variable_name operator operand +``` + + +例子: + +``` +counter=0 +counter=counter+1 +num=20 +num=num-1 +``` + + +你可以使用在 Awk 中使用上面的赋值操作符使命令更简短,从先前的例子中,我们可以使用下面这种格式进行赋值操作: +``` +variable_name operator=operand +counter=0 +counter+=1 +num=20 +num-=1 +``` + + +因此,我们可以在 shell 脚本中改变 Awk 命令,使用上面提到的 += 操作符: +``` +#!/bin/bash +for file in $@; do +if [ -f $file ] ; then +#print out filename +echo "File is: $file" +#print a number incrementally for every line containing tecmint.com +awk '/^tecmint.com/ { counter+=1 ; printf "%s\n", counter ; }' $file +else +#print error info incase input is not a file +echo "$file is not a file, please specify a file." >&2 && exit 1 +fi +done +#terminate script with exit code 0 in case of successful execution +exit 0 +``` + + +![](http://www.tecmint.com/wp-content/uploads/2016/07/Alter-Shell-Script.png) +>改变了的 shell 脚本 + + +在 [Awk 系列][4] 的这一部分,我们讨论了一些有用的 Awk 特性,有变量,使用数值表达式和赋值运算符,还有一些使用他们的实例。 + +这些概念和其他的编程语言没有任何不同,但是可能在 Awk 中有一些意义上的区别。 + +在本系列的第 9 节,我们会学习更多的 Awk 特性,比如特殊格式: BEGIN 和 END。这也会与 Tecmit 有联系。 + +-------------------------------------------------------------------------------- + +via: http://www.tecmint.com/learn-awk-variables-numeric-expressions-and-assignment-operators/ + +作者:[Aaron Kili][a] +译者:[vim-kakali](https://github.com/vim-kakali) +校对:[校对ID](https://github.com/校对ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]: http://www.tecmint.com/author/aaronkili/ + + + + + + + + + + + + + + + + + + + +[1]: http://www.tecmint.com/category/awk-command/ +[2]: http://www.tecmint.com/awk-print-fields-columns-with-space-separator/ +[3]: http://www.tecmint.com/13-basic-cat-command-examples-in-linux/ +[4]: http://www.tecmint.com/category/awk-command/ From 7acdcd342428534d6482b2f32e5c9b1791ca92fa Mon Sep 17 00:00:00 2001 From: wxy Date: Mon, 1 Aug 2016 07:25:05 +0800 Subject: [PATCH 097/122] =?UTF-8?q?=E5=BD=92=E6=A1=A3=20201607?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../{ => 201607}/20151117 How bad a boss is Linus Torvalds.md | 0 ...Securi-Pi--Using the Raspberry Pi as a Secure Landing Point.md | 0 ...4 What is good stock portfolio management software on Linux.md | 0 .../20160218 How to Best Manage Encryption Keys on Linux.md | 0 .../20160218 What do Linux developers think of Git and GitHub.md | 0 ...ow to Setup Lighttpd Web server on Ubuntu 15.04 or CentOS 7.md | 0 .../20160220 Best Cloud Services For Linux To Replace Copy.md | 0 ...volving Market for Commercial Software Built On Open Source.md | 0 .../20160303 Top 5 open source command shells for Linux.md | 0 .../20160304 Microservices with Python RabbitMQ and Nameko.md | 0 ...20160425 How to Use Awk to Print Fields and Columns in File.md | 0 ...An introduction to data processing with Cassandra and Spark.md | 0 ...160519 The future of sharing integrating Pydio and ownCloud.md | 0 .../20160527 Turn Your Old Laptop into a Chromebook.md | 0 ...DB 10, PHP 7 and HTTP 2.0 Support for Nginx on Ubuntu 16.04.md | 0 .../20160531 HOW TO USE WEBP IMAGES IN UBUNTU LINUX.md | 0 .../{ => 201607}/20160531 Why Ubuntu-based Distros Are Leaders.md | 0 ...ount your Google Drive on Linux with google-drive-ocamlfuse.md | 0 ...VBoxManage On Ubuntu 16.04 And Use Its Command line Options.md | 0 .../{ => 201607}/20160606 Basic Git Commands You Must Know.md | 0 .../20160609 How to record your terminal session on Linux.md | 0 .../20160609 INSTALL MATE 1.14 IN UBUNTU MATE 16.04 VIA PPA.md | 0 published/{ => 201607}/20160610 Getting started with ReactOS.md | 0 ...sic Linux Commands That Every Linux Newbies Should Remember.md | 0 .../20160616 6 Amazing Linux Distributions For Kids.md | 0 .../{ => 201607}/20160620 Detecting cats in images with OpenCV.md | 0 published/{ => 201607}/20160620 Monitor Linux With Netdata.md | 0 ...0 PowerPC gains an Android 4.4 port with Big Endian support.md | 0 .../20160621 Container technologies in Fedora - systemd-nspawn.md | 0 .../20160624 How to permanently mount a Windows share on Linux.md | 0 ...uns on the cloud and the cloud runs on Linux. Any questions.md | 0 ...160624 Industrial SBC builds on Raspberry Pi Compute Module.md | 0 ...5 How to Hide Linux Command Line History by Going Incognito.md | 0 ... Source Discussion Platform Discourse On Ubuntu Linux 16.04.md | 0 .../{ => 201607}/20160629 USE TASK MANAGER EQUIVALENT IN LINUX.md | 0 .../{ => 201607}/20160630 What makes up the Fedora kernel.md | 0 ...up Bridge (br0) Network on Ubuntu Linux 14.04 and 16.04 LTS.md | 0 .../20160705 Create Your Own Shell in Python - Part I.md | 0 .../20160706 Create Your Own Shell in Python - Part II.md | 0 ... Using Vagrant to control your DigitalOcean cloud instances.md | 0 .../{ => 201607}/20160718 OPEN SOURCE ACCOUNTING SOFTWARE.md | 0 ...20160721 YOU CAN TRY A DEMO UBUNTU VERSION IN A WEB BROWSER.md | 0 .../{ => 201607}/20160722 7 Best Markdown Editors for Linux.md | 0 .../20160722 HOW TO CHANGE DEFAULT APPLICATIONS IN UBUNTU.md | 0 ...2 Terminix – A New GTK 3 Tiling Terminal Emulator for Linux.md | 0 ... a Real Time Photo of Earth as Your Linux Desktop Wallpaper.md | 0 46 files changed, 0 insertions(+), 0 deletions(-) rename published/{ => 201607}/20151117 How bad a boss is Linus Torvalds.md (100%) rename published/{ => 201607}/20151215 Securi-Pi--Using the Raspberry Pi as a Secure Landing Point.md (100%) rename published/{ => 201607}/20160104 What is good stock portfolio management software on Linux.md (100%) rename published/{ => 201607}/20160218 How to Best Manage Encryption Keys on Linux.md (100%) rename published/{ => 201607}/20160218 What do Linux developers think of Git and GitHub.md (100%) rename published/{ => 201607}/20160219 How to Setup Lighttpd Web server on Ubuntu 15.04 or CentOS 7.md (100%) rename published/{ => 201607}/20160220 Best Cloud Services For Linux To Replace Copy.md (100%) rename published/{ => 201607}/20160301 The Evolving Market for Commercial Software Built On Open Source.md (100%) rename published/{ => 201607}/20160303 Top 5 open source command shells for Linux.md (100%) rename published/{ => 201607}/20160304 Microservices with Python RabbitMQ and Nameko.md (100%) rename published/{ => 201607}/20160425 How to Use Awk to Print Fields and Columns in File.md (100%) rename published/{ => 201607}/20160511 An introduction to data processing with Cassandra and Spark.md (100%) rename published/{ => 201607}/20160519 The future of sharing integrating Pydio and ownCloud.md (100%) rename published/{ => 201607}/20160527 Turn Your Old Laptop into a Chromebook.md (100%) rename published/{ => 201607}/20160530 Install LEMP with MariaDB 10, PHP 7 and HTTP 2.0 Support for Nginx on Ubuntu 16.04.md (100%) rename published/{ => 201607}/20160531 HOW TO USE WEBP IMAGES IN UBUNTU LINUX.md (100%) rename published/{ => 201607}/20160531 Why Ubuntu-based Distros Are Leaders.md (100%) rename published/{ => 201607}/20160602 How to mount your Google Drive on Linux with google-drive-ocamlfuse.md (100%) rename published/{ => 201607}/20160603 How To Install And Use VBoxManage On Ubuntu 16.04 And Use Its Command line Options.md (100%) rename published/{ => 201607}/20160606 Basic Git Commands You Must Know.md (100%) rename published/{ => 201607}/20160609 How to record your terminal session on Linux.md (100%) rename published/{ => 201607}/20160609 INSTALL MATE 1.14 IN UBUNTU MATE 16.04 VIA PPA.md (100%) rename published/{ => 201607}/20160610 Getting started with ReactOS.md (100%) rename published/{ => 201607}/20160616 10 Basic Linux Commands That Every Linux Newbies Should Remember.md (100%) rename published/{ => 201607}/20160616 6 Amazing Linux Distributions For Kids.md (100%) rename published/{ => 201607}/20160620 Detecting cats in images with OpenCV.md (100%) rename published/{ => 201607}/20160620 Monitor Linux With Netdata.md (100%) rename published/{ => 201607}/20160620 PowerPC gains an Android 4.4 port with Big Endian support.md (100%) rename published/{ => 201607}/20160621 Container technologies in Fedora - systemd-nspawn.md (100%) rename published/{ => 201607}/20160624 How to permanently mount a Windows share on Linux.md (100%) rename published/{ => 201607}/20160624 IT runs on the cloud and the cloud runs on Linux. Any questions.md (100%) rename published/{ => 201607}/20160624 Industrial SBC builds on Raspberry Pi Compute Module.md (100%) rename published/{ => 201607}/20160625 How to Hide Linux Command Line History by Going Incognito.md (100%) rename published/{ => 201607}/20160628 How To Setup Open Source Discussion Platform Discourse On Ubuntu Linux 16.04.md (100%) rename published/{ => 201607}/20160629 USE TASK MANAGER EQUIVALENT IN LINUX.md (100%) rename published/{ => 201607}/20160630 What makes up the Fedora kernel.md (100%) rename published/{ => 201607}/20160701 How To Setup Bridge (br0) Network on Ubuntu Linux 14.04 and 16.04 LTS.md (100%) rename published/{ => 201607}/20160705 Create Your Own Shell in Python - Part I.md (100%) rename published/{ => 201607}/20160706 Create Your Own Shell in Python - Part II.md (100%) rename published/{ => 201607}/20160708 Using Vagrant to control your DigitalOcean cloud instances.md (100%) rename published/{ => 201607}/20160718 OPEN SOURCE ACCOUNTING SOFTWARE.md (100%) rename published/{ => 201607}/20160721 YOU CAN TRY A DEMO UBUNTU VERSION IN A WEB BROWSER.md (100%) rename published/{ => 201607}/20160722 7 Best Markdown Editors for Linux.md (100%) rename published/{ => 201607}/20160722 HOW TO CHANGE DEFAULT APPLICATIONS IN UBUNTU.md (100%) rename published/{ => 201607}/20160722 Terminix – A New GTK 3 Tiling Terminal Emulator for Linux.md (100%) rename published/{ => 201607}/20160726 Set a Real Time Photo of Earth as Your Linux Desktop Wallpaper.md (100%) diff --git a/published/20151117 How bad a boss is Linus Torvalds.md b/published/201607/20151117 How bad a boss is Linus Torvalds.md similarity index 100% rename from published/20151117 How bad a boss is Linus Torvalds.md rename to published/201607/20151117 How bad a boss is Linus Torvalds.md diff --git a/published/20151215 Securi-Pi--Using the Raspberry Pi as a Secure Landing Point.md b/published/201607/20151215 Securi-Pi--Using the Raspberry Pi as a Secure Landing Point.md similarity index 100% rename from published/20151215 Securi-Pi--Using the Raspberry Pi as a Secure Landing Point.md rename to published/201607/20151215 Securi-Pi--Using the Raspberry Pi as a Secure Landing Point.md diff --git a/published/20160104 What is good stock portfolio management software on Linux.md b/published/201607/20160104 What is good stock portfolio management software on Linux.md similarity index 100% rename from published/20160104 What is good stock portfolio management software on Linux.md rename to published/201607/20160104 What is good stock portfolio management software on Linux.md diff --git a/published/20160218 How to Best Manage Encryption Keys on Linux.md b/published/201607/20160218 How to Best Manage Encryption Keys on Linux.md similarity index 100% rename from published/20160218 How to Best Manage Encryption Keys on Linux.md rename to published/201607/20160218 How to Best Manage Encryption Keys on Linux.md diff --git a/published/20160218 What do Linux developers think of Git and GitHub.md b/published/201607/20160218 What do Linux developers think of Git and GitHub.md similarity index 100% rename from published/20160218 What do Linux developers think of Git and GitHub.md rename to published/201607/20160218 What do Linux developers think of Git and GitHub.md diff --git a/published/20160219 How to Setup Lighttpd Web server on Ubuntu 15.04 or CentOS 7.md b/published/201607/20160219 How to Setup Lighttpd Web server on Ubuntu 15.04 or CentOS 7.md similarity index 100% rename from published/20160219 How to Setup Lighttpd Web server on Ubuntu 15.04 or CentOS 7.md rename to published/201607/20160219 How to Setup Lighttpd Web server on Ubuntu 15.04 or CentOS 7.md diff --git a/published/20160220 Best Cloud Services For Linux To Replace Copy.md b/published/201607/20160220 Best Cloud Services For Linux To Replace Copy.md similarity index 100% rename from published/20160220 Best Cloud Services For Linux To Replace Copy.md rename to published/201607/20160220 Best Cloud Services For Linux To Replace Copy.md diff --git a/published/20160301 The Evolving Market for Commercial Software Built On Open Source.md b/published/201607/20160301 The Evolving Market for Commercial Software Built On Open Source.md similarity index 100% rename from published/20160301 The Evolving Market for Commercial Software Built On Open Source.md rename to published/201607/20160301 The Evolving Market for Commercial Software Built On Open Source.md diff --git a/published/20160303 Top 5 open source command shells for Linux.md b/published/201607/20160303 Top 5 open source command shells for Linux.md similarity index 100% rename from published/20160303 Top 5 open source command shells for Linux.md rename to published/201607/20160303 Top 5 open source command shells for Linux.md diff --git a/published/20160304 Microservices with Python RabbitMQ and Nameko.md b/published/201607/20160304 Microservices with Python RabbitMQ and Nameko.md similarity index 100% rename from published/20160304 Microservices with Python RabbitMQ and Nameko.md rename to published/201607/20160304 Microservices with Python RabbitMQ and Nameko.md diff --git a/published/20160425 How to Use Awk to Print Fields and Columns in File.md b/published/201607/20160425 How to Use Awk to Print Fields and Columns in File.md similarity index 100% rename from published/20160425 How to Use Awk to Print Fields and Columns in File.md rename to published/201607/20160425 How to Use Awk to Print Fields and Columns in File.md diff --git a/published/20160511 An introduction to data processing with Cassandra and Spark.md b/published/201607/20160511 An introduction to data processing with Cassandra and Spark.md similarity index 100% rename from published/20160511 An introduction to data processing with Cassandra and Spark.md rename to published/201607/20160511 An introduction to data processing with Cassandra and Spark.md diff --git a/published/20160519 The future of sharing integrating Pydio and ownCloud.md b/published/201607/20160519 The future of sharing integrating Pydio and ownCloud.md similarity index 100% rename from published/20160519 The future of sharing integrating Pydio and ownCloud.md rename to published/201607/20160519 The future of sharing integrating Pydio and ownCloud.md diff --git a/published/20160527 Turn Your Old Laptop into a Chromebook.md b/published/201607/20160527 Turn Your Old Laptop into a Chromebook.md similarity index 100% rename from published/20160527 Turn Your Old Laptop into a Chromebook.md rename to published/201607/20160527 Turn Your Old Laptop into a Chromebook.md diff --git a/published/20160530 Install LEMP with MariaDB 10, PHP 7 and HTTP 2.0 Support for Nginx on Ubuntu 16.04.md b/published/201607/20160530 Install LEMP with MariaDB 10, PHP 7 and HTTP 2.0 Support for Nginx on Ubuntu 16.04.md similarity index 100% rename from published/20160530 Install LEMP with MariaDB 10, PHP 7 and HTTP 2.0 Support for Nginx on Ubuntu 16.04.md rename to published/201607/20160530 Install LEMP with MariaDB 10, PHP 7 and HTTP 2.0 Support for Nginx on Ubuntu 16.04.md diff --git a/published/20160531 HOW TO USE WEBP IMAGES IN UBUNTU LINUX.md b/published/201607/20160531 HOW TO USE WEBP IMAGES IN UBUNTU LINUX.md similarity index 100% rename from published/20160531 HOW TO USE WEBP IMAGES IN UBUNTU LINUX.md rename to published/201607/20160531 HOW TO USE WEBP IMAGES IN UBUNTU LINUX.md diff --git a/published/20160531 Why Ubuntu-based Distros Are Leaders.md b/published/201607/20160531 Why Ubuntu-based Distros Are Leaders.md similarity index 100% rename from published/20160531 Why Ubuntu-based Distros Are Leaders.md rename to published/201607/20160531 Why Ubuntu-based Distros Are Leaders.md diff --git a/published/20160602 How to mount your Google Drive on Linux with google-drive-ocamlfuse.md b/published/201607/20160602 How to mount your Google Drive on Linux with google-drive-ocamlfuse.md similarity index 100% rename from published/20160602 How to mount your Google Drive on Linux with google-drive-ocamlfuse.md rename to published/201607/20160602 How to mount your Google Drive on Linux with google-drive-ocamlfuse.md diff --git a/published/20160603 How To Install And Use VBoxManage On Ubuntu 16.04 And Use Its Command line Options.md b/published/201607/20160603 How To Install And Use VBoxManage On Ubuntu 16.04 And Use Its Command line Options.md similarity index 100% rename from published/20160603 How To Install And Use VBoxManage On Ubuntu 16.04 And Use Its Command line Options.md rename to published/201607/20160603 How To Install And Use VBoxManage On Ubuntu 16.04 And Use Its Command line Options.md diff --git a/published/20160606 Basic Git Commands You Must Know.md b/published/201607/20160606 Basic Git Commands You Must Know.md similarity index 100% rename from published/20160606 Basic Git Commands You Must Know.md rename to published/201607/20160606 Basic Git Commands You Must Know.md diff --git a/published/20160609 How to record your terminal session on Linux.md b/published/201607/20160609 How to record your terminal session on Linux.md similarity index 100% rename from published/20160609 How to record your terminal session on Linux.md rename to published/201607/20160609 How to record your terminal session on Linux.md diff --git a/published/20160609 INSTALL MATE 1.14 IN UBUNTU MATE 16.04 VIA PPA.md b/published/201607/20160609 INSTALL MATE 1.14 IN UBUNTU MATE 16.04 VIA PPA.md similarity index 100% rename from published/20160609 INSTALL MATE 1.14 IN UBUNTU MATE 16.04 VIA PPA.md rename to published/201607/20160609 INSTALL MATE 1.14 IN UBUNTU MATE 16.04 VIA PPA.md diff --git a/published/20160610 Getting started with ReactOS.md b/published/201607/20160610 Getting started with ReactOS.md similarity index 100% rename from published/20160610 Getting started with ReactOS.md rename to published/201607/20160610 Getting started with ReactOS.md diff --git a/published/20160616 10 Basic Linux Commands That Every Linux Newbies Should Remember.md b/published/201607/20160616 10 Basic Linux Commands That Every Linux Newbies Should Remember.md similarity index 100% rename from published/20160616 10 Basic Linux Commands That Every Linux Newbies Should Remember.md rename to published/201607/20160616 10 Basic Linux Commands That Every Linux Newbies Should Remember.md diff --git a/published/20160616 6 Amazing Linux Distributions For Kids.md b/published/201607/20160616 6 Amazing Linux Distributions For Kids.md similarity index 100% rename from published/20160616 6 Amazing Linux Distributions For Kids.md rename to published/201607/20160616 6 Amazing Linux Distributions For Kids.md diff --git a/published/20160620 Detecting cats in images with OpenCV.md b/published/201607/20160620 Detecting cats in images with OpenCV.md similarity index 100% rename from published/20160620 Detecting cats in images with OpenCV.md rename to published/201607/20160620 Detecting cats in images with OpenCV.md diff --git a/published/20160620 Monitor Linux With Netdata.md b/published/201607/20160620 Monitor Linux With Netdata.md similarity index 100% rename from published/20160620 Monitor Linux With Netdata.md rename to published/201607/20160620 Monitor Linux With Netdata.md diff --git a/published/20160620 PowerPC gains an Android 4.4 port with Big Endian support.md b/published/201607/20160620 PowerPC gains an Android 4.4 port with Big Endian support.md similarity index 100% rename from published/20160620 PowerPC gains an Android 4.4 port with Big Endian support.md rename to published/201607/20160620 PowerPC gains an Android 4.4 port with Big Endian support.md diff --git a/published/20160621 Container technologies in Fedora - systemd-nspawn.md b/published/201607/20160621 Container technologies in Fedora - systemd-nspawn.md similarity index 100% rename from published/20160621 Container technologies in Fedora - systemd-nspawn.md rename to published/201607/20160621 Container technologies in Fedora - systemd-nspawn.md diff --git a/published/20160624 How to permanently mount a Windows share on Linux.md b/published/201607/20160624 How to permanently mount a Windows share on Linux.md similarity index 100% rename from published/20160624 How to permanently mount a Windows share on Linux.md rename to published/201607/20160624 How to permanently mount a Windows share on Linux.md diff --git a/published/20160624 IT runs on the cloud and the cloud runs on Linux. Any questions.md b/published/201607/20160624 IT runs on the cloud and the cloud runs on Linux. Any questions.md similarity index 100% rename from published/20160624 IT runs on the cloud and the cloud runs on Linux. Any questions.md rename to published/201607/20160624 IT runs on the cloud and the cloud runs on Linux. Any questions.md diff --git a/published/20160624 Industrial SBC builds on Raspberry Pi Compute Module.md b/published/201607/20160624 Industrial SBC builds on Raspberry Pi Compute Module.md similarity index 100% rename from published/20160624 Industrial SBC builds on Raspberry Pi Compute Module.md rename to published/201607/20160624 Industrial SBC builds on Raspberry Pi Compute Module.md diff --git a/published/20160625 How to Hide Linux Command Line History by Going Incognito.md b/published/201607/20160625 How to Hide Linux Command Line History by Going Incognito.md similarity index 100% rename from published/20160625 How to Hide Linux Command Line History by Going Incognito.md rename to published/201607/20160625 How to Hide Linux Command Line History by Going Incognito.md diff --git a/published/20160628 How To Setup Open Source Discussion Platform Discourse On Ubuntu Linux 16.04.md b/published/201607/20160628 How To Setup Open Source Discussion Platform Discourse On Ubuntu Linux 16.04.md similarity index 100% rename from published/20160628 How To Setup Open Source Discussion Platform Discourse On Ubuntu Linux 16.04.md rename to published/201607/20160628 How To Setup Open Source Discussion Platform Discourse On Ubuntu Linux 16.04.md diff --git a/published/20160629 USE TASK MANAGER EQUIVALENT IN LINUX.md b/published/201607/20160629 USE TASK MANAGER EQUIVALENT IN LINUX.md similarity index 100% rename from published/20160629 USE TASK MANAGER EQUIVALENT IN LINUX.md rename to published/201607/20160629 USE TASK MANAGER EQUIVALENT IN LINUX.md diff --git a/published/20160630 What makes up the Fedora kernel.md b/published/201607/20160630 What makes up the Fedora kernel.md similarity index 100% rename from published/20160630 What makes up the Fedora kernel.md rename to published/201607/20160630 What makes up the Fedora kernel.md diff --git a/published/20160701 How To Setup Bridge (br0) Network on Ubuntu Linux 14.04 and 16.04 LTS.md b/published/201607/20160701 How To Setup Bridge (br0) Network on Ubuntu Linux 14.04 and 16.04 LTS.md similarity index 100% rename from published/20160701 How To Setup Bridge (br0) Network on Ubuntu Linux 14.04 and 16.04 LTS.md rename to published/201607/20160701 How To Setup Bridge (br0) Network on Ubuntu Linux 14.04 and 16.04 LTS.md diff --git a/published/20160705 Create Your Own Shell in Python - Part I.md b/published/201607/20160705 Create Your Own Shell in Python - Part I.md similarity index 100% rename from published/20160705 Create Your Own Shell in Python - Part I.md rename to published/201607/20160705 Create Your Own Shell in Python - Part I.md diff --git a/published/20160706 Create Your Own Shell in Python - Part II.md b/published/201607/20160706 Create Your Own Shell in Python - Part II.md similarity index 100% rename from published/20160706 Create Your Own Shell in Python - Part II.md rename to published/201607/20160706 Create Your Own Shell in Python - Part II.md diff --git a/published/20160708 Using Vagrant to control your DigitalOcean cloud instances.md b/published/201607/20160708 Using Vagrant to control your DigitalOcean cloud instances.md similarity index 100% rename from published/20160708 Using Vagrant to control your DigitalOcean cloud instances.md rename to published/201607/20160708 Using Vagrant to control your DigitalOcean cloud instances.md diff --git a/published/20160718 OPEN SOURCE ACCOUNTING SOFTWARE.md b/published/201607/20160718 OPEN SOURCE ACCOUNTING SOFTWARE.md similarity index 100% rename from published/20160718 OPEN SOURCE ACCOUNTING SOFTWARE.md rename to published/201607/20160718 OPEN SOURCE ACCOUNTING SOFTWARE.md diff --git a/published/20160721 YOU CAN TRY A DEMO UBUNTU VERSION IN A WEB BROWSER.md b/published/201607/20160721 YOU CAN TRY A DEMO UBUNTU VERSION IN A WEB BROWSER.md similarity index 100% rename from published/20160721 YOU CAN TRY A DEMO UBUNTU VERSION IN A WEB BROWSER.md rename to published/201607/20160721 YOU CAN TRY A DEMO UBUNTU VERSION IN A WEB BROWSER.md diff --git a/published/20160722 7 Best Markdown Editors for Linux.md b/published/201607/20160722 7 Best Markdown Editors for Linux.md similarity index 100% rename from published/20160722 7 Best Markdown Editors for Linux.md rename to published/201607/20160722 7 Best Markdown Editors for Linux.md diff --git a/published/20160722 HOW TO CHANGE DEFAULT APPLICATIONS IN UBUNTU.md b/published/201607/20160722 HOW TO CHANGE DEFAULT APPLICATIONS IN UBUNTU.md similarity index 100% rename from published/20160722 HOW TO CHANGE DEFAULT APPLICATIONS IN UBUNTU.md rename to published/201607/20160722 HOW TO CHANGE DEFAULT APPLICATIONS IN UBUNTU.md diff --git a/published/20160722 Terminix – A New GTK 3 Tiling Terminal Emulator for Linux.md b/published/201607/20160722 Terminix – A New GTK 3 Tiling Terminal Emulator for Linux.md similarity index 100% rename from published/20160722 Terminix – A New GTK 3 Tiling Terminal Emulator for Linux.md rename to published/201607/20160722 Terminix – A New GTK 3 Tiling Terminal Emulator for Linux.md diff --git a/published/20160726 Set a Real Time Photo of Earth as Your Linux Desktop Wallpaper.md b/published/201607/20160726 Set a Real Time Photo of Earth as Your Linux Desktop Wallpaper.md similarity index 100% rename from published/20160726 Set a Real Time Photo of Earth as Your Linux Desktop Wallpaper.md rename to published/201607/20160726 Set a Real Time Photo of Earth as Your Linux Desktop Wallpaper.md From ac0320c3f9ec1358316d0f4a022b7c848c6bf3ce Mon Sep 17 00:00:00 2001 From: wxy Date: Mon, 1 Aug 2016 07:25:42 +0800 Subject: [PATCH 098/122] PUB:20160706 What is Git MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @cvsher 这篇翻译的很用心,很好! --- published/20160706 What is Git.md | 118 ++++++++++++++++++++++++ translated/tech/20160706 What is Git.md | 118 ------------------------ 2 files changed, 118 insertions(+), 118 deletions(-) create mode 100644 published/20160706 What is Git.md delete mode 100644 translated/tech/20160706 What is Git.md diff --git a/published/20160706 What is Git.md b/published/20160706 What is Git.md new file mode 100644 index 0000000000..f0fa7dded8 --- /dev/null +++ b/published/20160706 What is Git.md @@ -0,0 +1,118 @@ +Git 系列(一):什么是 Git +=========== + +欢迎阅读本系列关于如何使用 Git 版本控制系统的教程!通过本文的介绍,你将会了解到 Git 的用途及谁该使用 Git。 + +如果你刚步入开源的世界,你很有可能会遇到一些在 Git 上托管代码或者发布使用版本的开源软件。事实上,不管你知道与否,你都在使用基于 Git 进行版本管理的软件:Linux 内核(就算你没有在手机或者电脑上使用 Linux,你正在访问的网站也是运行在 Linux 系统上的),Firefox、Chrome 等其他很多项目都通过 Git 代码库和世界各地开发者共享他们的代码。 + +换个角度来说,你是否仅仅通过 Git 就可以和其他人共享你的代码?你是否可以在家里或者企业里私有化的使用 Git?你必须要通过一个 GitHub 账号来使用 Git 吗?为什么要使用 Git 呢?Git 的优势又是什么?Git 是我唯一的选择吗?这对 Git 所有的疑问都会把我们搞的一脑浆糊。 + +因此,忘记你以前所知的 Git,让我们重新走进 Git 世界的大门。 + +### 什么是版本控制系统? + +Git 首先是一个版本控制系统。现在市面上有很多不同的版本控制系统:CVS、SVN、Mercurial、Fossil 当然还有 Git。 + +很多像 GitHub 和 GitLab 这样的服务是以 Git 为基础的,但是你也可以只使用 Git 而无需使用其他额外的服务。这意味着你可以以私有或者公有的方式来使用 Git。 + +如果你曾经和其他人有过任何电子文件方面的合作,你就会知道传统版本管理的工作流程。开始是很简单的:你有一个原始的版本,你把这个版本发送给你的同事,他们在接收到的版本上做了些修改,现在你们有两个版本了,然后他们把他们手上修改过的版本发回来给你。你把他们的修改合并到你手上的版本中,现在两个版本又合并成一个最新的版本了。 + +然后,你修改了你手上最新的版本,同时,你的同事也修改了他们手上合并前的版本。现在你们有 3 个不同的版本了,分别是合并后最新的版本,你修改后的版本,你同事手上继续修改过的版本。至此,你们的版本管理工作开始变得越来越混乱了。 + +正如 Jason van Gumster 在他的文章中指出 [即使是艺术家也需要版本控制][1],而且已经在个别人那里发现了这种趋势变化。无论是艺术家还是科学家,开发一个某种实验版本是并不鲜见的;在你的项目中,可能有某个版本大获成功,把项目推向一个新的高度,也可能有某个版本惨遭失败。因此,最终你不可避免的会创建出一堆名为project\_justTesting.kdenlive、project\_betterVersion.kdenlive、project\_best\_FINAL.kdenlive、project\_FINAL-alternateVersion.kdenlive 等类似名称的文件。 + +不管你是修改一个 for 循环,还是一些简单的文本编辑,一个好的版本控制系统都会让我们的生活更加的轻松。 + +### Git 快照 + +Git 可以为项目创建快照,并且存储这些快照为唯一的版本。 + +如果你将项目带领到了一个错误的方向上,你可以回退到上一个正确的版本,并且开始尝试另一个可行的方向。 + +如果你是和别人合作开发,当有人向你发送他们的修改时,你可以将这些修改合并到你的工作分支中,然后你的同事就可以获取到合并后的最新版本,并在此基础上继续工作。 + +Git 并不是魔法,因此冲突还是会发生的(“你修改了某文件的最后一行,但是我把这行整行都删除了;我们怎样处理这些冲突呢?”),但是总体而言,Git 会为你保留了所有更改的历史版本,甚至允许并行版本。这为你保留了以任何方式处理冲突的能力。 + +### 分布式 Git + +在不同的机器上为同一个项目工作是一件复杂的事情。因为在你开始工作时,你想要获得项目的最新版本,然后此基础上进行修改,最后向你的同事共享这些改动。传统的方法是通过笨重的在线文件共享服务或者老旧的电邮附件,但是这两种方式都是效率低下且容易出错。 + +Git 天生是为分布式工作设计的。如果你要参与到某个项目中,你可以克隆(clone)该项目的 Git 仓库,然后就像这个项目只有你本地一个版本一样对项目进行修改。最后使用一些简单的命令你就可以拉取(pull)其他开发者的修改,或者你可以把你的修改推送(push)给别人。现在不用担心谁手上的是最新的版本,或者谁的版本又存放在哪里等这些问题了。全部人都是在本地进行开发,然后向共同的目标推送或者拉取更新。(或者不是共同的目标,这取决于项目的开发方式)。 + +### Git 界面 + +最原始的 Git 是运行在 Linux 终端上的应用软件。然而,得益于 Git 是开源的,并且拥有良好的设计,世界各地的开发者都可以为 Git 设计不同的访问界面。 + +Git 完全是免费的,并且已经打包在 Linux,BSD,Illumos 和其他类 Unix 系统中,Git 命令看起来像这样: + +``` +$ git --version +git version 2.5.3 +``` + +可能最著名的 Git 访问界面是基于网页的,像 GitHub、开源的 GitLab、Savannah、BitBucket 和 SourceForge 这些网站都是基于网页端的 Git 界面。这些站点为面向公众和面向社会的开源软件提供了最大限度的代码托管服务。在一定程度上,基于浏览器的图形界面(GUI)可以尽量的减缓 Git 的学习曲线。下面的 GitLab 界面的截图: + +![](https://opensource.com/sites/default/files/0_gitlab.png) + +再者,第三方 Git 服务提供商或者独立开发者甚至可以在 Git 的基础上开发出不是基于 HTML 的定制化前端界面。此类界面让你可以不用打开浏览器就可以方便的使用 Git 进行版本管理。其中对用户最透明的方式是直接集成到文件管理器中。KDE 文件管理器 Dolphin 可以直接在目录中显示 Git 状态,甚至支持提交,推送和拉取更新操作。 + +![](https://opensource.com/sites/default/files/0_dolphin.jpg) + +[Sparkleshare][2] 使用 Git 作为其 Dropbox 式的文件共享界面的基础。 + +![](https://opensource.com/sites/default/files/0_sparkleshare_1.jpg) + +想了解更多的内容,可以查看 [Git wiki][3],这个(长长的)页面中展示了很多 Git 的图形界面项目。 + +### 谁应该使用 Git? + +就是你!我们更应该关心的问题是什么时候使用 Git?和用 Git 来干嘛? + +### 我应该在什么时候使用 Git 呢?我要用 Git 来干嘛呢? + +想更深入的学习 Git,我们必须比平常考虑更多关于文件格式的问题。 + +Git 是为了管理源代码而设计的,在大多数编程语言中,源代码就意味者一行行的文本。当然,Git 并不知道你把这些文本当成是源代码还是下一部伟大的美式小说。因此,只要文件内容是以文本构成的,使用 Git 来跟踪和管理其版本就是一个很好的选择了。 + +但是什么是文本呢?如果你在像 Libre Office 这类办公软件中编辑一些内容,通常并不会产生纯文本内容。因为通常复杂的应用软件都会对原始的文本内容进行一层封装,就如把原始文本内容用 XML 标记语言包装起来,然后封装在 Zip 包中。这种对原始文本内容进行一层封装的做法可以保证当你把文件发送给其他人时,他们可以看到你在办公软件中编辑的内容及特定的文本效果。奇怪的是,虽然,通常你的需求可能会很复杂,就像保存 [Kdenlive][4] 项目文件,或者保存从 [Inkscape][5] 导出的SVG文件,但是,事实上使用 Git 管理像 XML 文本这样的纯文本类容是最简单的。 + +如果你在使用 Unix 系统,你可以使用 `file` 命令来查看文件内容构成: + +``` +$ file ~/path/to/my-file.blah +my-file.blah: ASCII text +$ file ~/path/to/different-file.kra: Zip data (MIME type "application/x-krita") +``` + +如果还是不确定,你可以使用 `head` 命令来查看文件内容: + +``` +$ head ~/path/to/my-file.blah +``` + +如果输出的文本你基本能看懂,这个文件就很有可能是文本文件。如果你仅仅在一堆乱码中偶尔看到几个熟悉的字符,那么这个文件就可能不是文本文件了。 + +准确的说:Git 可以管理其他格式的文件,但是它会把这些文件当成二进制大对象(blob)。两者的区别是,在文本文件中,Git 可以明确的告诉你在这两个快照(或者说提交)间有 3 行是修改过的。但是如果你在两个提交(commit)之间对一张图片进行的编辑操作,Git 会怎么指出这种修改呢?实际上,因为图片并不是以某种可以增加或删除的有意义的文本构成,因此 Git 并不能明确的描述这种变化。当然我个人是非常希望图片的编辑可以像把文本“\丑陋的蓝绿色\”修改成“\漂浮着蓬松白云的天蓝色\”一样的简单,但是事实上图片的编辑并没有这么简单。 + +经常有人在 Git 上放入 png 图标、电子表格或者流程图这类二进制大型对象(blob)。尽管,我们知道在 Git 上管理此类大型文件并不直观,但是,如果你需要使用 Git 来管理此类文件,你也并不需要过多的担心。如果你参与的项目同时生成文本文件和二进制大文件对象(如视频游戏中常见的场景,这些和源代码同样重要的图像和音频材料),那么你有两条路可以走:要么开发出你自己的解决方案,就如使用指向共享网络驱动器的引用;要么使用 Git 插件,如 Joey Hess 开发的 [git annex][6],以及 [Git-Media][7] 项目。 + +你看,Git 真的是一个任何人都可以使用的工具。它是你进行文件版本管理的一个强大而且好用工具,同时它并没有你开始认为的那么可怕。 + +-------------------------------------------------------------------------------- + +via: https://opensource.com/resources/what-is-git + +作者:[Seth Kenlon][a] +译者:[cvsher](https://github.com/cvsher) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]: https://opensource.com/users/seth +[1]: https://opensource.com/life/16/2/version-control-isnt-just-programmers +[2]: http://sparkleshare.org/ +[3]: https://git.wiki.kernel.org/index.php/InterfacesFrontendsAndTools#Graphical_Interfaces +[4]: https://opensource.com/life/11/11/introduction-kdenlive +[5]: http://inkscape.org/ +[6]: https://git-annex.branchable.com/ +[7]: https://github.com/alebedev/git-media diff --git a/translated/tech/20160706 What is Git.md b/translated/tech/20160706 What is Git.md deleted file mode 100644 index f2f01b8d39..0000000000 --- a/translated/tech/20160706 What is Git.md +++ /dev/null @@ -1,118 +0,0 @@ -什么是Git -=========== - -欢迎阅读本系列关于Git版本控制系统的教程!通过本文的介绍,你将会了解到Git的用途及谁该使用Git。 - -如果你刚步入开源的世界,你很有可能会遇到一些在Git上托管代码或者发布使用版本的开源软件。事实上,不管你知道与否,你都在使用基于Git进行版本管理的软件:linux内核(就算你没有在手机或者电脑上使用linux,你正在访问的网站也是运行在linux系统上的),Firefox,Chrome等其他很多项目都在Git上和世界各地开发者共享他们的代码。 - -换个角度来说,你是否仅仅通过Git就可以和其他人共享你的代码?你是否可以在家里或者企业里私有化的使用Git?你必须要通过一个GitHub账号来使用Git吗?为什么要使用Git呢?Git的优势又是什么?Git是我唯一的选择吗?这对Git所有的疑问都会把我们搞的一脑浆糊。 - -因此,忘记你以前所知的Git,我们从新走进Git世界的大门。 - -### 什么是版本控制系统? - -现在市面上有很多不同的版本控制系统:CVS,SVN,Mercurial,Fossil 当然还有 Git。 - -很多像 GitHub 和 GitLab 这样的服务是以Git为基础的,但是你也可以只使用Git而无需使用其他额外的服务。这意味着你可以以私有或者公有的方式来使用Git。 - -如果你曾经和其他人有过任何数字方面的合作,你就会知道传统版本管理的工作流程。开始是很简单的:你有一个原始的版本,你把这个版本发送给你的同事,他们在接收到的版本上做了些修改,现在你们有两个版本了,然后他们把他们手上修改过的版本发回来给你。你把他们的修改合并到你手上的版本中,现在两个版本又合并成一个最新的版本了。 - -然后,你修改了你手上最新的版本,同时,你的同事也修改了他们手上合并前的版本。现在你们有3个不同的版本了,分别是合并后最新的版本,你修改后的版本,你同事手上继续修改过的版本。至此,你们的版本管理工作开始变得越来越混乱了。 - -正如 Jason van Gumster 在他的文章中指出 [即使是艺术家也需要版本控制][1],而且这也有向个人设置方向发展的趋势。无论是艺术家还是科学家,在一些想法上开发出实验版本都是比较常见的;在你的项目中,可能有某个版本大获成功,把项目推向一个新的高度,也可能有某个版本惨遭失败。因此,最终你不可避免的会创建出一堆名为project_justTesting.kdenlive、project_betterVersion.kdenlive、project_best_FINAL.kdenlive、project_FINAL-alternateVersion.kdenlive等类似名称的文件。 - -不管你是修改一个for循环,还是一些简单的文本编辑,一个好的版本控制系统都会让我们的生活更加的轻松。 - -### Git快照 - -Git会为每个项目创建快照,并且为项目的每个版本都保存一个唯一的快照。 - -如果你将项目带领到了一个错误的方向上,你可以回退到上一个正确的版本,并且 开始尝试另一个可行的方向。 - -如果你是和别人合作开发,当有人向你发送他们的修改时,你可以将这些修改合并到你的工作分支中,然后你的同事就可以获取到合并后的最新版本,并在此基础上继续工作。 - -Git并不是魔法,因此冲突还是会发生的(“你修改了某文件的最后一行,但是我把这行整行都删除了;我们怎样处理这些冲突呢?”),但是总体而言,Git会为你保留了所有更改的历史版本,甚至允许并行版本。这为你保留了以任何方式处理冲突的能力。 - -### 分布式Git - -在不同的机器上为同一个项目工作是一件复杂的事情。因为在你开始工作时,你想要获得项目的最新版本,然后此基础上进行修改,最后向你的同事共享这些改动。传统的方法是通过笨重的在线文件共享服务或者老旧的电邮附件,但是这两种方式都是效率低下且容易出错。 - -Git天生是为分布式工作设计的。如果你要参与到某个项目中,你可以克隆(clone)该项目的Git仓库,然后就像这个项目只有你本地一个版本一样对项目进行修改。最后使用一些简单的命令你就可以拉取(pull)其他开发者的修改,或者你可以把你的修改推送(push)给别人。现在不用担心谁手上的是最新的版本,或者谁的版本又存放在哪里等这些问题了。全部人都是在本地进行开发,然后向共同的目标推送或者拉取更新。(或者不是共同的目标,这取决于项目的开发方式)。 - -### Git 界面 - -最原始的Git是运行在Linux终端上的应用软件。然而,得益于Git是开源的,并且拥有良好的设计,世界各地的开发者都可以为Git设计不同的接入界面。 - -Git完全是免费的,并且附带在Linux,BSD,Illumos 和其他类unix系统中,Git命令看起来像: - -``` -$ git --version -git version 2.5.3 -``` - -可能最著名的Git访问界面是基于网页的,像GitHub,开源的GitLab,Savannah,BitBucket和SourceForge这些网站都是基于网页端的Git界面。这些站点为面向公众和面向社会的开源软件提供了最大限度的代码托管服务。在一定程度上,基于浏览器的图形界面(GUI)可以尽量的减缓Git的学习曲线。下面的GitLab接口的截图: - -![](https://opensource.com/sites/default/files/0_gitlab.png) - -再者,第三方Git服务提供商或者独立开发者甚至可以在Git的基础上开发出不是基于HTML的定制化前端接口。此类接口让你可以不用打开浏览器就可以方便的使用Git进行版本管理。其中对用户最透明的方式是直接集成到文件管理器中。KDE文件管理器,Dolphin 可以直接在目录中显示Git状态,甚至支持提交,推送和拉取更新操作。 - -![](https://opensource.com/sites/default/files/0_dolphin.jpg) - -[Sparkleshare][2]使用Git作为其Dropbox类文件共享接口的基础。 - -![](https://opensource.com/sites/default/files/0_sparkleshare_1.jpg) - -想了解更多的内容,可以查看[Git wiki][3],此页面中展示了很多Git的图形界面项目。 - -### 谁应该使用Git? - -就是你!我们更应该关心的问题是什么时候使用Git?和用Git来干嘛? - -### 我应该在什么时候使用Git呢?我要用Git来干嘛呢? - -想更深入的学习Git,我们必须比平常考虑更多关于文件格式的问题。 - -Git是为了管理源代码而设计的,在大多数编程语言中,源代码就意味者一行行的文本。当然,Git并不知道你把这些文本当成是源代码还是下一部伟大的美式小说。因此,只要文件内容是以文本构成的,使用Git来跟踪和管理其版本就是一个很好的选择了。 - -但是什么是文本呢?如果你在像Libre Office这类办公软件中编辑一些内容,通常并不会产生纯文本内容。因为通常复杂的应用软件都会对原始的文本内容进行一层封装,就如把原始文本内容用XML标记语言包装起来,然后封装在Zip容器中。这种对原始文本内容进行一层封装的做法可以保证当你把文件发送给其他人时,他们可以看到你在办公软件中编辑的内容及特定的文本效果。奇怪的是,虽然,通常你的需求可能会很复杂,就像保存[Kdenlive][4]项目文件,或者保存从[Inkscape][5]导出的SVG文件,但是,事实上使用Git管理像XML文本这样的纯文本类容是最简单的。 - -如果你在使用Unix系统,你可以使用 file 命令来查看文件内容构成: - -``` -$ file ~/path/to/my-file.blah -my-file.blah: ASCII text -$ file ~/path/to/different-file.kra: Zip data (MIME type "application/x-krita") -``` - -如果还是不确定,你可以使用 head 命令来查看文件内容: - -``` -$ head ~/path/to/my-file.blah -``` - -如果输出的文本你基本能看懂,这个文件就很有可能是文本文件。如果你仅仅在一堆乱码中偶尔看到几个熟悉的字符,那么这个文件就可能不是文本文件了。 - -准确的说:Git可以管理其他格式的文件,但是它会把这些文件当成二进制大对象(blob)。两者的区别是,在文本文件中,Git可以明确的告诉你在这两个快照(或者说提交)间有3行是修改过的。但是如果你在两个提交间对一张图片进行的编辑操作,Git会怎么指出这种修改呢?实际上,因为图片并不是以某种可以增加或删除的有意义的文本构成,因此Git并不能明确的描述这种变化。当然我个人是非常希望图片的编辑可以像把本文"丑陋的蓝绿色"修改成"漂浮着蓬松白云的天蓝色"一样的简单,但是事实上图片的编辑并没有这么简单。 - -经常有人在Git上记录png图标、电子表格或者流程图这类二进制大型对象。尽管,我们知道在Git上管理此类大型文件并不直观,但是,如果你需要使用Git来管理此类文件,你也并不需要过多的担心。如果你参与的项目同时生成文本文件和二进制大文件对象(如视频游戏中常见的场景,这些和源代码同样重要的图像和音频材料),那么你有两条路可以走:要么开发出你自己的解决方案,就如使用指向共享网络驱动器的指针;要么使用Git插件,如Joey Hess开发的[git annex][6], 或者 [Git-Media][7] 项目。 - -你看,Git真的是一个任何人都可以使用的工具。它是你进行文件版本管理的一个强大而且好用工具,同时它并没有你开始认为的那么可怕。 - --------------------------------------------------------------------------------- - -via: https://opensource.com/resources/what-is-git - -作者:[Seth Kenlon ][a] -译者:[cvsher](https://github.com/cvsher) -校对:[校对者ID](https://github.com/校对者ID) - -本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 - -[a]: https://opensource.com/users/seth -[1]: https://opensource.com/life/16/2/version-control-isnt-just-programmers -[2]: http://sparkleshare.org/ -[3]: https://git.wiki.kernel.org/index.php/InterfacesFrontendsAndTools#Graphical_Interfaces -[4]: https://opensource.com/life/11/11/introduction-kdenlive -[5]: http://inkscape.org/ -[6]: https://git-annex.branchable.com/ -[7]: https://github.com/alebedev/git-media From 3b3cea5dc788eb6f20a20a927509e86c0ea76cf5 Mon Sep 17 00:00:00 2001 From: may Date: Mon, 1 Aug 2016 08:58:56 +0800 Subject: [PATCH 099/122] translating by maywanting --- sources/talk/20160620 5 SSH Hardening Tips.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sources/talk/20160620 5 SSH Hardening Tips.md b/sources/talk/20160620 5 SSH Hardening Tips.md index ad6741ab26..e1a7353807 100644 --- a/sources/talk/20160620 5 SSH Hardening Tips.md +++ b/sources/talk/20160620 5 SSH Hardening Tips.md @@ -1,3 +1,5 @@ +translating by maywanting + 5 SSH Hardening Tips ====================== From 7047bb29cf12b05c2b15c8a348b2ac5cb7a6432a Mon Sep 17 00:00:00 2001 From: wxy Date: Mon, 1 Aug 2016 07:42:23 +0800 Subject: [PATCH 100/122] PUB:20160705 How to Encrypt a Flash Drive Using VeraCrypt @GitFuture --- ...o Encrypt a Flash Drive Using VeraCrypt.md | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) rename {translated/tech => published}/20160705 How to Encrypt a Flash Drive Using VeraCrypt.md (72%) diff --git a/translated/tech/20160705 How to Encrypt a Flash Drive Using VeraCrypt.md b/published/20160705 How to Encrypt a Flash Drive Using VeraCrypt.md similarity index 72% rename from translated/tech/20160705 How to Encrypt a Flash Drive Using VeraCrypt.md rename to published/20160705 How to Encrypt a Flash Drive Using VeraCrypt.md index a049bfd73c..71a2e01a24 100644 --- a/translated/tech/20160705 How to Encrypt a Flash Drive Using VeraCrypt.md +++ b/published/20160705 How to Encrypt a Flash Drive Using VeraCrypt.md @@ -1,29 +1,29 @@ 用 VeraCrypt 加密闪存盘 ============================================ -很多安全专家偏好像 VeraCrypt 这类能够用来加密闪存盘的开源软件。因为获取它的源代码很简单。 +很多安全专家偏好像 VeraCrypt 这类能够用来加密闪存盘的开源软件,是因为可以获取到它的源代码。 -保护 USB闪存盘里的数据,加密是一个聪明的方法,正如我们在使用 Microsoft 的 BitLocker [加密闪存盘][1] 一文中提到的。 +保护 USB 闪存盘里的数据,加密是一个聪明的方法,正如我们在使用 Microsoft 的 BitLocker [加密闪存盘][1] 一文中提到的。 但是如果你不想用 BitLocker 呢? -你可能有顾虑,因为你不能够查看 Microsoft 的程序源码,那么它容易被植入用于政府或其它用途的“后门”。由于开源软件的源码是公开的,很多安全专家认为开源软件很少藏有后门。 +你可能有顾虑,因为你不能够查看 Microsoft 的程序源码,那么它容易被植入用于政府或其它用途的“后门”。而由于开源软件的源码是公开的,很多安全专家认为开源软件很少藏有后门。 还好,有几个开源加密软件能作为 BitLocker 的替代。 要是你需要在 Windows 系统,苹果的 OS X 系统或者 Linux 系统上加密以及访问文件,开源软件 [VeraCrypt][2] 提供绝佳的选择。 -VeraCrypt 源于 TrueCrypt。TrueCrypt是一个备受好评的开源加密软件,尽管它现在已经停止维护了。但是 TrueCrypt 的代码通过了审核,没有发现什么重要的安全漏洞。另外,它已经在 VeraCrypt 中进行了改善。 +VeraCrypt 源于 TrueCrypt。TrueCrypt 是一个备受好评的开源加密软件,尽管它现在已经停止维护了。但是 TrueCrypt 的代码通过了审核,没有发现什么重要的安全漏洞。另外,在 VeraCrypt 中对它进行了改善。 Windows,OS X 和 Linux 系统的版本都有。 -用 VeraCrypt 加密 USB 闪存盘不像用 BitLocker 那么简单,但是它只要几分钟就好了。 +用 VeraCrypt 加密 USB 闪存盘不像用 BitLocker 那么简单,但是它也只要几分钟就好了。 ### 用 VeraCrypt 加密闪存盘的 8 个步骤 -对应操作系统 [下载 VeraCrypt][3] 之后: +对应你的操作系统 [下载 VeraCrypt][3] 之后: -打开 VeraCrypt,点击 Create Volume,进入 VeraCrypt 的创建卷的向导程序(VeraCrypt Volume Creation Wizard)。(注:VeraCrypt Volume Creation Wizard 首字母全大写,不清楚是否需要翻译,之后有很多首字母大写的词,都以括号标出) +打开 VeraCrypt,点击 Create Volume,进入 VeraCrypt 的创建卷的向导程序(VeraCrypt Volume Creation Wizard)。 ![](http://www.esecurityplanet.com/imagesvr_ce/6246/Vera0.jpg) @@ -39,7 +39,7 @@ VeraCrypt 创建卷向导(VeraCrypt Volume Creation Wizard)允许你在闪 ![](http://www.esecurityplanet.com/imagesvr_ce/9427/Vera3.jpg) -选择创建卷标模式(Volume Creation Mode)。如果你的闪存盘是空的,或者你想要删除它里面的所有东西,选第一个。要么你想保持所有现存的文件,选第二个就好了。 +选择创建卷模式(Volume Creation Mode)。如果你的闪存盘是空的,或者你想要删除它里面的所有东西,选第一个。要么你想保持所有现存的文件,选第二个就好了。 ![](http://www.esecurityplanet.com/imagesvr_ce/7828/Vera4.jpg) @@ -47,7 +47,7 @@ VeraCrypt 创建卷向导(VeraCrypt Volume Creation Wizard)允许你在闪 ![](http://www.esecurityplanet.com/imagesvr_ce/5918/Vera5.jpg) -确定了卷标容量后,输入并确认你想要用来加密数据密码。 +确定了卷容量后,输入并确认你想要用来加密数据密码。 ![](http://www.esecurityplanet.com/imagesvr_ce/3850/Vera6.jpg) @@ -71,7 +71,7 @@ VeraCrypt 创建卷向导(VeraCrypt Volume Creation Wizard)允许你在闪 ### VeraCrypt 移动硬盘安装步骤 -如果你设置闪存盘的时候,选择的是加密过的容器而不是加密整个盘,你可以选择创建 VeraCrypt 称为移动盘(Traveler Disk)的设备。这会复制安装一个 VeraCrypt 在 USB 闪存盘。当你在别的 Windows 电脑上插入 U 盘时,就能从 U 盘自动运行 VeraCrypt;也就是说没必要在新电脑上安装 VeraCrypt。 +如果你设置闪存盘的时候,选择的是加密过的容器而不是加密整个盘,你可以选择创建 VeraCrypt 称为移动盘(Traveler Disk)的设备。这会复制安装一个 VeraCrypt 到 USB 闪存盘。当你在别的 Windows 电脑上插入 U 盘时,就能从 U 盘自动运行 VeraCrypt;也就是说没必要在新电脑上安装 VeraCrypt。 你可以设置闪存盘作为一个移动硬盘(Traveler Disk),在 VeraCrypt 的工具栏(Tools)菜单里选择 Traveler Disk SetUp 就行了。 @@ -79,15 +79,15 @@ VeraCrypt 创建卷向导(VeraCrypt Volume Creation Wizard)允许你在闪 要从移动盘(Traveler Disk)上运行 VeraCrypt,你必须要有那台电脑的管理员权限,这不足为奇。尽管这看起来是个限制,机密文件无法在不受控制的电脑上安全打开,比如在一个商务中心的电脑上。 ->Paul Rubens 从事技术行业已经超过 20 年。这期间他为英国和国际主要的出版社,包括 《The Economist》《The Times》《Financial Times》《The BBC》《Computing》和《ServerWatch》等出版社写过文章, +> 本文作者 Paul Rubens 从事技术行业已经超过 20 年。这期间他为英国和国际主要的出版社,包括 《The Economist》《The Times》《Financial Times》《The BBC》《Computing》和《ServerWatch》等出版社写过文章, -------------------------------------------------------------------------------- via: http://www.esecurityplanet.com/open-source-security/how-to-encrypt-flash-drive-using-veracrypt.html -作者:[Paul Rubens ][a] +作者:[Paul Rubens][a] 译者:[GitFuture](https://github.com/GitFuture) -校对:[校对者ID](https://github.com/校对者ID) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 From 6da38f56d75ba8092dbdd3690459cdc3839393d8 Mon Sep 17 00:00:00 2001 From: ezio Date: Mon, 1 Aug 2016 21:06:19 +0800 Subject: [PATCH 101/122] =?UTF-8?q?=E7=BB=84=E9=98=9F=E7=BF=BB=E8=AF=91=20?= =?UTF-8?q?Building=20a=20data=20science=20portfolio=20-=20Machine=20learn?= =?UTF-8?q?ing=20project?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sources/team_test/README.md | 4 + ...ce portfolio - Machine learning project.md | 79 +++++++ ...ce portfolio - Machine learning project.md | 114 ++++++++++ ...ce portfolio - Machine learning project.md | 194 ++++++++++++++++++ ...ce portfolio - Machine learning project.md | 80 ++++++++ ...ce portfolio - Machine learning project.md | 166 +++++++++++++++ ...ce portfolio - Machine learning project.md | 173 ++++++++++++++++ 7 files changed, 810 insertions(+) create mode 100644 sources/team_test/README.md create mode 100644 sources/team_test/part 1 - Building a data science portfolio - Machine learning project.md create mode 100644 sources/team_test/part 2 - Building a data science portfolio - Machine learning project.md create mode 100644 sources/team_test/part 3 - Building a data science portfolio - Machine learning project.md create mode 100644 sources/team_test/part 4 - Building a data science portfolio - Machine learning project.md create mode 100644 sources/team_test/part 5 - Building a data science portfolio - Machine learning project.md create mode 100644 sources/team_test/part 6 - Building a data science portfolio - Machine learning project.md diff --git a/sources/team_test/README.md b/sources/team_test/README.md new file mode 100644 index 0000000000..d2bdd305f8 --- /dev/null +++ b/sources/team_test/README.md @@ -0,0 +1,4 @@ +组队翻译 : 《Building a data science portfolio: Machine learning project》 +本次组织者 : @选题-oska874 +参加译者 : @译者-vim-kakali @译者-Noobfish @译者-zky001 @译者-kokialoves @译者-ideas4u @译者-cposture +分配方式 : 原文按大致长度分成 6 部分,参与者自由选择,先到先选,如有疑问联系 @选题-oska874 diff --git a/sources/team_test/part 1 - Building a data science portfolio - Machine learning project.md b/sources/team_test/part 1 - Building a data science portfolio - Machine learning project.md new file mode 100644 index 0000000000..70d9b65f92 --- /dev/null +++ b/sources/team_test/part 1 - Building a data science portfolio - Machine learning project.md @@ -0,0 +1,79 @@ +>This is the third in a series of posts on how to build a Data Science Portfolio. If you like this and want to know when the next post in the series is released, you can [subscribe at the bottom of the page][1]. + +Data science companies are increasingly looking at portfolios when making hiring decisions. One of the reasons for this is that a portfolio is the best way to judge someone’s real-world skills. The good news for you is that a portfolio is entirely within your control. If you put some work in, you can make a great portfolio that companies are impressed by. + +The first step in making a high-quality portfolio is to know what skills to demonstrate. The primary skills that companies want in data scientists, and thus the primary skills they want a portfolio to demonstrate, are: + +- Ability to communicate +- Ability to collaborate with others +- Technical competence +- Ability to reason about data +- Motivation and ability to take initiative + +Any good portfolio will be composed of multiple projects, each of which may demonstrate 1-2 of the above points. This is the third post in a series that will cover how to make a well-rounded data science portfolio. In this post, we’ll cover how to make the second project in your portfolio, and how to build an end to end machine learning project. At the end, you’ll have a project that shows your ability to reason about data, and your technical competence. [Here’s][2] the completed project if you want to take a look. + +### An end to end project + +As a data scientist, there are times when you’ll be asked to take a dataset and figure out how to [tell a story with it][3]. In times like this, it’s important to communicate very well, and walk through your process. Tools like Jupyter notebook, which we used in a previous post, are very good at helping you do this. The expectation here is that the deliverable is a presentation or document summarizing your findings. + +However, there are other times when you’ll be asked to create a project that has operational value. A project with operational value directly impacts the day-to-day operations of a company, and will be used more than once, and often by multiple people. A task like this might be “create an algorithm to forecast our churn rate”, or “create a model that can automatically tag our articles”. In cases like this, storytelling is less important than technical competence. You need to be able to take a dataset, understand it, then create a set of scripts that can process that data. It’s often important that these scripts run quickly, and use minimal system resources like memory. It’s very common that these scripts will be run several times, so the deliverable becomes the scripts themselves, not a presentation. The deliverable is often integrated into operational flows, and may even be user-facing. + +The main components of building an end to end project are: + +- Understanding the context +- Exploring the data and figuring out the nuances +- Creating a well-structured project, so its easy to integrate into operational flows +- Writing high-performance code that runs quickly and uses minimal system resources +- Documenting the installation and usage of your code well, so others can use it + +In order to effectively create a project of this kind, we’ll need to work with multiple files. Using a text editor like [Atom][4], or an IDE like [PyCharm][5] is highly recommended. These tools will allow you to jump between files, and edit files of different types, like markdown files, Python files, and csv files. Structuring your project so it’s easy to version control and upload to collaborative coding tools like [Github][6] is also useful. + +![](https://www.dataquest.io/blog/images/end_to_end/github.png) +>This project on Github. + +We’ll use our editing tools along with libraries like [Pandas][7] and [scikit-learn][8] in this post. We’ll make extensive use of Pandas [DataFrames][9], which make it easy to read in and work with tabular data in Python. + +### Finding good datasets + +A good dataset for an end to end portfolio project can be hard to find. [The dataset][10] needs to be sufficiently large that memory and performance constraints come into play. It also needs to potentially be operationally useful. For instance, this dataset, which contains data on the admission criteria, graduation rates, and graduate future earnings for US colleges would be a great dataset to use to tell a story. However, as you think about the dataset, it becomes clear that there isn’t enough nuance to build a good end to end project with it. For example, you could tell someone their potential future earnings if they went to a specific college, but that would be a quick lookup without enough nuance to demonstrate technical competence. You could also figure out if colleges with higher admissions standards tend to have graduates who earn more, but that would be more storytelling than operational. + +These memory and performance constraints tend to come into play when you have more than a gigabyte of data, and when you have some nuance to what you want to predict, which involves running algorithms over the dataset. + +A good operational dataset enables you to build a set of scripts that transform the data, and answer dynamic questions. A good example would be a dataset of stock prices. You would be able to predict the prices for the next day, and keep feeding new data to the algorithm as the markets closed. This would enable you to make trades, and potentially even profit. This wouldn’t be telling a story – it would be adding direct value. + +Some good places to find datasets like this are: + +- [/r/datasets][11] – a subreddit that has hundreds of interesting datasets. +- [Google Public Datasets][12] – public datasets available through Google BigQuery. +- [Awesome datasets][13] – a list of datasets, hosted on Github. + +As you look through these datasets, think about what questions someone might want answered with the dataset, and think if those questions are one-time (“how did housing prices correlate with the S&P 500?”), or ongoing (“can you predict the stock market?”). The key here is to find questions that are ongoing, and require the same code to be run multiple times with different inputs (different data). + +For the purposes of this post, we’ll look at [Fannie Mae Loan Data][14]. Fannie Mae is a government sponsored enterprise in the US that buys mortgage loans from other lenders. It then bundles these loans up into mortgage-backed securities and resells them. This enables lenders to make more mortgage loans, and creates more liquidity in the market. This theoretically leads to more homeownership, and better loan terms. From a borrowers perspective, things stay largely the same, though. + +Fannie Mae releases two types of data – data on loans it acquires, and data on how those loans perform over time. In the ideal case, someone borrows money from a lender, then repays the loan until the balance is zero. However, some borrowers miss multiple payments, which can cause foreclosure. Foreclosure is when the house is seized by the bank because mortgage payments cannot be made. Fannie Mae tracks which loans have missed payments on them, and which loans needed to be foreclosed on. This data is published quarterly, and lags the current date by 1 year. As of this writing, the most recent dataset that’s available is from the first quarter of 2015. + +Acquisition data, which is published when the loan is acquired by Fannie Mae, contains information on the borrower, including credit score, and information on their loan and home. Performance data, which is published every quarter after the loan is acquired, contains information on the payments being made by the borrower, and the foreclosure status, if any. A loan that is acquired may have dozens of rows in the performance data. A good way to think of this is that the acquisition data tells you that Fannie Mae now controls the loan, and the performance data contains a series of status updates on the loan. One of the status updates may tell us that the loan was foreclosed on during a certain quarter. + +![](https://www.dataquest.io/blog/images/end_to_end/foreclosure.jpg) +>A foreclosed home being sold. + +### Picking an angle + +There are a few directions we could go in with the Fannie Mae dataset. We could: + +- Try to predict the sale price of a house after it’s foreclosed on. +- Predict the payment history of a borrower. +- Figure out a score for each loan at acquisition time. + +The important thing is to stick to a single angle. Trying to focus on too many things at once will make it hard to make an effective project. It’s also important to pick an angle that has sufficient nuance. Here are examples of angles without much nuance: + +- Figuring out which banks sold loans to Fannie Mae that were foreclosed on the most. +- Figuring out trends in borrower credit scores. +- Exploring which types of homes are foreclosed on most often. +- Exploring the relationship between loan amounts and foreclosure sale prices + +All of the above angles are interesting, and would be great if we were focused on storytelling, but aren’t great fits for an operational project. + +With the Fannie Mae dataset, we’ll try to predict whether a loan will be foreclosed on in the future by only using information that was available when the loan was acquired. In effect, we’ll create a “score” for any mortgage that will tell us if Fannie Mae should buy it or not. This will give us a nice foundation to build on, and will be a great portfolio piece. + diff --git a/sources/team_test/part 2 - Building a data science portfolio - Machine learning project.md b/sources/team_test/part 2 - Building a data science portfolio - Machine learning project.md new file mode 100644 index 0000000000..2b429aaab8 --- /dev/null +++ b/sources/team_test/part 2 - Building a data science portfolio - Machine learning project.md @@ -0,0 +1,114 @@ +### Understanding the data + +Let’s take a quick look at the raw data files. Here are the first few rows of the acquisition data from quarter 1 of 2012: + +``` +100000853384|R|OTHER|4.625|280000|360|02/2012|04/2012|31|31|1|23|801|N|C|SF|1|I|CA|945||FRM| +100003735682|R|SUNTRUST MORTGAGE INC.|3.99|466000|360|01/2012|03/2012|80|80|2|30|794|N|P|SF|1|P|MD|208||FRM|788 +100006367485|C|PHH MORTGAGE CORPORATION|4|229000|360|02/2012|04/2012|67|67|2|36|802|N|R|SF|1|P|CA|959||FRM|794 +``` + +Here are the first few rows of the performance data from quarter 1 of 2012: + +``` +100000853384|03/01/2012|OTHER|4.625||0|360|359|03/2042|41860|0|N|||||||||||||||| +100000853384|04/01/2012||4.625||1|359|358|03/2042|41860|0|N|||||||||||||||| +100000853384|05/01/2012||4.625||2|358|357|03/2042|41860|0|N|||||||||||||||| +``` + +Before proceeding too far into coding, it’s useful to take some time and really understand the data. This is more critical in operational projects – because we aren’t interactively exploring the data, it can be harder to spot certain nuances unless we find them upfront. In this case, the first step is to read the materials on the Fannie Mae site: + +- [Overview][15] +- [Glossary of useful terms][16] +- [FAQs][17] +- [Columns in the Acquisition and Performance files][18] +- [Sample Acquisition data file][19] +- [Sample Performance data file][20] + +After reading through these files, we know some key facts that will help us: + +- There’s an Acquisition file and a Performance file for each quarter, starting from the year 2000 to present. There’s a 1 year lag in the data, so the most recent data is from 2015 as of this writing. +- The files are in text format, with a pipe (|) as a delimiter. +- The files don’t have headers, but we have a list of what each column is. +- All together, the files contain data on 22 million loans. +- Because the Performance files contain information on loans acquired in previous years, there will be more performance data for loans acquired in earlier years (ie loans acquired in 2014 won’t have much performance history). + +These small bits of information will save us a ton of time as we figure out how to structure our project and work with the data. + +### Structuring the project + +Before we start downloading and exploring the data, it’s important to think about how we’ll structure the project. When building an end-to-end project, our primary goals are: + +- Creating a solution that works +- Having a solution that runs quickly and uses minimal resources +- Enabling others to easily extend our work +- Making it easy for others to understand our code +- Writing as little code as possible + +In order to achieve these goals, we’ll need to structure our project well. A well structured project follows a few principles: + +- Separates data files and code files. +- Separates raw data from generated data. +- Has a README.md file that walks people through installing and using the project. +- Has a requirements.txt file that contains all the packages needed to run the project. +- Has a single settings.py file that contains any settings that are used in other files. + - For example, if you are reading the same file from multiple Python scripts, it’s useful to have them all import settings and get the file name from a centralized place. +- Has a .gitignore file that prevents large or secret files from being committed. +- Breaks each step in our task into a separate file that can be executed separately. + - For example, we may have one file for reading in the data, one for creating features, and one for making predictions. +- Stores intermediate values. For example, one script may output a file that the next script can read. + - This enables us to make changes in our data processing flow without recalculating everything. + +Our file structure will look something like this shortly: + +``` +loan-prediction +├── data +├── processed +├── .gitignore +├── README.md +├── requirements.txt +├── settings.py +``` + +### Creating the initial files + +To start with, we’ll need to create a loan-prediction folder. Inside that folder, we’ll need to make a data folder and a processed folder. The first will store our raw data, and the second will store any intermediate calculated values. + +Next, we’ll make a .gitignore file. A .gitignore file will make sure certain files are ignored by git and not pushed to Github. One good example of such a file is the .DS_Store file created by OSX in every folder. A good starting point for a .gitignore file is here. We’ll also want to ignore the data files because they are very large, and the Fannie Mae terms prevent us from redistributing them, so we should add two lines to the end of our file: + +``` +data +processed +``` + +[Here’s][21] an example .gitignore file for this project. + +Next, we’ll need to create README.md, which will help people understand the project. .md indicates that the file is in markdown format. Markdown enables you write plain text, but also add some fancy formatting if you want. [Here’s][22] a guide on markdown. If you upload a file called README.md to Github, Github will automatically process the markdown, and show it to anyone who views the project. [Here’s][23] an example. + +For now, we just need to put a simple description in README.md: + +``` +Loan Prediction +----------------------- + +Predict whether or not loans acquired by Fannie Mae will go into foreclosure. Fannie Mae acquires loans from other lenders as a way of inducing them to lend more. Fannie Mae releases data on the loans it has acquired and their performance afterwards [here](http://www.fanniemae.com/portal/funding-the-market/data/loan-performance-data.html). +``` + +Now, we can create a requirements.txt file. This will make it easy for other people to install our project. We don’t know exactly what libraries we’ll be using yet, but here’s a good starting point: + +``` +pandas +matplotlib +scikit-learn +numpy +ipython +scipy +``` + +The above libraries are the most commonly used for data analysis tasks in Python, and its fair to assume that we’ll be using most of them. [Here’s][24] an example requirements file for this project. + +After creating requirements.txt, you should install the packages. For this post, we’ll be using Python 3. If you don’t have Python installed, you should look into using [Anaconda][25], a Python installer that also installs all the packages listed above. + +Finally, we can just make a blank settings.py file, since we don’t have any settings for our project yet. + diff --git a/sources/team_test/part 3 - Building a data science portfolio - Machine learning project.md b/sources/team_test/part 3 - Building a data science portfolio - Machine learning project.md new file mode 100644 index 0000000000..31fb6f0fc9 --- /dev/null +++ b/sources/team_test/part 3 - Building a data science portfolio - Machine learning project.md @@ -0,0 +1,194 @@ +### Acquiring the data + +Once we have the skeleton of our project, we can get the raw data. + +Fannie Mae has some restrictions around acquiring the data, so you’ll need to sign up for an account. You can find the download page [here][26]. After creating an account, you’ll be able to download as few or as many loan data files as you want. The files are in zip format, and are reasonably large after decompression. + +For the purposes of this blog post, we’ll download everything from Q1 2012 to Q1 2015, inclusive. We’ll then need to unzip all of the files. After unzipping the files, remove the original .zip files. At the end, the loan-prediction folder should look something like this: + +``` +loan-prediction +├── data +│ ├── Acquisition_2012Q1.txt +│ ├── Acquisition_2012Q2.txt +│ ├── Performance_2012Q1.txt +│ ├── Performance_2012Q2.txt +│ └── ... +├── processed +├── .gitignore +├── README.md +├── requirements.txt +├── settings.py +``` + +After downloading the data, you can use the head and tail shell commands to look at the lines in the files. Do you see any columns that aren’t needed? It might be useful to consult the [pdf of column names][27] while doing this. + +### Reading in the data + +There are two issues that make our data hard to work with right now: + +- The acquisition and performance datasets are segmented across multiple files. +- Each file is missing headers. + +Before we can get started on working with the data, we’ll need to get to the point where we have one file for the acquisition data, and one file for the performance data. Each of the files will need to contain only the columns we care about, and have the proper headers. One wrinkle here is that the performance data is quite large, so we should try to trim some of the columns if we can. + +The first step is to add some variables to settings.py, which will contain the paths to our raw data and our processed data. We’ll also add a few other settings that will be useful later on: + +``` +DATA_DIR = "data" +PROCESSED_DIR = "processed" +MINIMUM_TRACKING_QUARTERS = 4 +TARGET = "foreclosure_status" +NON_PREDICTORS = [TARGET, "id"] +CV_FOLDS = 3 +``` + +Putting the paths in settings.py will put them in a centralized place and make them easy to change down the line. When referring to the same variables in multiple files, it’s easier to put them in a central place than edit them in every file when you want to change them. [Here’s][28] an example settings.py file for this project. + +The second step is to create a file called assemble.py that will assemble all the pieces into 2 files. When we run python assemble.py, we’ll get 2 data files in the processed directory. + +We’ll then start writing code in assemble.py. We’ll first need to define the headers for each file, so we’ll need to look at [pdf of column names][29] and create lists of the columns in each Acquisition and Performance file: + +``` +HEADERS = { + "Acquisition": [ + "id", + "channel", + "seller", + "interest_rate", + "balance", + "loan_term", + "origination_date", + "first_payment_date", + "ltv", + "cltv", + "borrower_count", + "dti", + "borrower_credit_score", + "first_time_homebuyer", + "loan_purpose", + "property_type", + "unit_count", + "occupancy_status", + "property_state", + "zip", + "insurance_percentage", + "product_type", + "co_borrower_credit_score" + ], + "Performance": [ + "id", + "reporting_period", + "servicer_name", + "interest_rate", + "balance", + "loan_age", + "months_to_maturity", + "maturity_date", + "msa", + "delinquency_status", + "modification_flag", + "zero_balance_code", + "zero_balance_date", + "last_paid_installment_date", + "foreclosure_date", + "disposition_date", + "foreclosure_costs", + "property_repair_costs", + "recovery_costs", + "misc_costs", + "tax_costs", + "sale_proceeds", + "credit_enhancement_proceeds", + "repurchase_proceeds", + "other_foreclosure_proceeds", + "non_interest_bearing_balance", + "principal_forgiveness_balance" + ] +} +``` + +The next step is to define the columns we want to keep. Since all we’re measuring on an ongoing basis about the loan is whether or not it was ever foreclosed on, we can discard many of the columns in the performance data. We’ll need to keep all the columns in the acquisition data, though, because we want to maximize the information we have about when the loan was acquired (after all, we’re predicting if the loan will ever be foreclosed or not at the point it’s acquired). Discarding columns will enable us to save disk space and memory, while also speeding up our code. + +``` +SELECT = { + "Acquisition": HEADERS["Acquisition"], + "Performance": [ + "id", + "foreclosure_date" + ] +} +``` + +Next, we’ll write a function to concatenate the data sets. The below code will: + +- Import a few needed libraries, including settings. +- Define a function concatenate, that: + - Gets the names of all the files in the data directory. + - Loops through each file. + - If the file isn’t the right type (doesn’t start with the prefix we want), we ignore it. + - Reads the file into a [DataFrame][30] with the right settings using the Pandas [read_csv][31] function. + - Sets the separator to | so the fields are read in correctly. + - The data has no header row, so sets header to None to indicate this. + - Sets names to the right value from the HEADERS dictionary – these will be the column names of our DataFrame. + - Picks only the columns from the DataFrame that we added in SELECT. +- Concatenates all the DataFrames together. +- Writes the concatenated DataFrame back to a file. + +``` +import os +import settings +import pandas as pd + +def concatenate(prefix="Acquisition"): + files = os.listdir(settings.DATA_DIR) + full = [] + for f in files: + if not f.startswith(prefix): + continue + + data = pd.read_csv(os.path.join(settings.DATA_DIR, f), sep="|", header=None, names=HEADERS[prefix], index_col=False) + data = data[SELECT[prefix]] + full.append(data) + + full = pd.concat(full, axis=0) + + full.to_csv(os.path.join(settings.PROCESSED_DIR, "{}.txt".format(prefix)), sep="|", header=SELECT[prefix], index=False) +``` + +We can call the above function twice with the arguments Acquisition and Performance to concatenate all the acquisition and performance files together. The below code will: + +- Only execute if the script is called from the command line with python assemble.py. +- Concatenate all the files, and result in two files: + - `processed/Acquisition.txt` + - `processed/Performance.txt` + +``` +if __name__ == "__main__": + concatenate("Acquisition") + concatenate("Performance") +``` + +We now have a nice, compartmentalized assemble.py that’s easy to execute, and easy to build off of. By decomposing the problem into pieces like this, we make it easy to build our project. Instead of one messy script that does everything, we define the data that will pass between the scripts, and make them completely separate from each other. When you’re working on larger projects, it’s a good idea to do this, because it makes it much easier to change individual pieces without having unexpected consequences on unrelated pieces of the project. + +Once we finish the assemble.py script, we can run python assemble.py. You can find the complete assemble.py file [here][32]. + +This will result in two files in the processed directory: + +``` +loan-prediction +├── data +│ ├── Acquisition_2012Q1.txt +│ ├── Acquisition_2012Q2.txt +│ ├── Performance_2012Q1.txt +│ ├── Performance_2012Q2.txt +│ └── ... +├── processed +│ ├── Acquisition.txt +│ ├── Performance.txt +├── .gitignore +├── assemble.py +├── README.md +├── requirements.txt +├── settings.py +``` diff --git a/sources/team_test/part 4 - Building a data science portfolio - Machine learning project.md b/sources/team_test/part 4 - Building a data science portfolio - Machine learning project.md new file mode 100644 index 0000000000..66db19bc54 --- /dev/null +++ b/sources/team_test/part 4 - Building a data science portfolio - Machine learning project.md @@ -0,0 +1,80 @@ +### Computing values from the performance data + +The next step we’ll take is to calculate some values from processed/Performance.txt. All we want to do is to predict whether or not a property is foreclosed on. To figure this out, we just need to check if the performance data associated with a loan ever has a foreclosure_date. If foreclosure_date is None, then the property was never foreclosed on. In order to avoid including loans with little performance history in our sample, we’ll also want to count up how many rows exist in the performance file for each loan. This will let us filter loans without much performance history from our training data. + +One way to think of the loan data and the performance data is like this: + +![](https://github.com/LCTT/wiki-images/blob/master/TranslateProject/ref_img/001.png) + +As you can see above, each row in the Acquisition data can be related to multiple rows in the Performance data. In the Performance data, foreclosure_date will appear in the quarter when the foreclosure happened, so it should be blank prior to that. Some loans are never foreclosed on, so all the rows related to them in the Performance data have foreclosure_date blank. + +We need to compute foreclosure_status, which is a Boolean that indicates whether a particular loan id was ever foreclosed on, and performance_count, which is the number of rows in the performance data for each loan id. + +There are a few different ways to compute the counts we want: + +- We could read in all the performance data, then use the Pandas groupby method on the DataFrame to figure out the number of rows associated with each loan id, and also if the foreclosure_date is ever not None for the id. + - The upside of this method is that it’s easy to implement from a syntax perspective. + - The downside is that reading in all 129236094 lines in the data will take a lot of memory, and be extremely slow. +- We could read in all the performance data, then use apply on the acquisition DataFrame to find the counts for each id. + - The upside is that it’s easy to conceptualize. + - The downside is that reading in all 129236094 lines in the data will take a lot of memory, and be extremely slow. +- We could iterate over each row in the performance dataset, and keep a separate dictionary of counts. + - The upside is that the dataset doesn’t need to be loaded into memory, so it’s extremely fast and memory-efficient. + - The downside is that it will take slightly longer to conceptualize and implement, and we need to parse the rows manually. + +Loading in all the data will take quite a bit of memory, so let’s go with the third option above. All we need to do is to iterate through all the rows in the Performance data, while keeping a dictionary of counts per loan id. In the dictionary, we’ll keep track of how many times the id appears in the performance data, as well as if foreclosure_date is ever not None. This will give us foreclosure_status and performance_count. + +We’ll create a new file called annotate.py, and add in code that will enable us to compute these values. In the below code, we’ll: + +- Import needed libraries. +- Define a function called count_performance_rows. + - Open processed/Performance.txt. This doesn’t read the file into memory, but instead opens a file handler that can be used to read in the file line by line. + - Loop through each line in the file. + - Split the line on the delimiter (|) + - Check if the loan_id is not in the counts dictionary. + - If not, add it to counts. + - Increment performance_count for the given loan_id because we’re on a row that contains it. + - If date is not None, then we know that the loan was foreclosed on, so set foreclosure_status appropriately. + +``` +import os +import settings +import pandas as pd + +def count_performance_rows(): + counts = {} + with open(os.path.join(settings.PROCESSED_DIR, "Performance.txt"), 'r') as f: + for i, line in enumerate(f): + if i == 0: + # Skip header row + continue + loan_id, date = line.split("|") + loan_id = int(loan_id) + if loan_id not in counts: + counts[loan_id] = { + "foreclosure_status": False, + "performance_count": 0 + } + counts[loan_id]["performance_count"] += 1 + if len(date.strip()) > 0: + counts[loan_id]["foreclosure_status"] = True + return counts +``` + +### Getting the values + +Once we create our counts dictionary, we can make a function that will extract values from the dictionary if a loan_id and a key are passed in: + +``` +def get_performance_summary_value(loan_id, key, counts): + value = counts.get(loan_id, { + "foreclosure_status": False, + "performance_count": 0 + }) + return value[key] +``` + +The above function will return the appropriate value from the counts dictionary, and will enable us to assign a foreclosure_status value and a performance_count value to each row in the Acquisition data. The [get][33] method on dictionaries returns a default value if a key isn’t found, so this enables us to return sensible default values if a key isn’t found in the counts dictionary. + + + diff --git a/sources/team_test/part 5 - Building a data science portfolio - Machine learning project.md b/sources/team_test/part 5 - Building a data science portfolio - Machine learning project.md new file mode 100644 index 0000000000..64be5f9492 --- /dev/null +++ b/sources/team_test/part 5 - Building a data science portfolio - Machine learning project.md @@ -0,0 +1,166 @@ +### Annotating the data + +We’ve already added a few functions to annotate.py, but now we can get into the meat of the file. We’ll need to convert the acquisition data into a training dataset that can be used in a machine learning algorithm. This involves a few things: + +- Converting all columns to numeric. +- Filling in any missing values. +- Assigning a performance_count and a foreclosure_status to each row. +- Removing any rows that don’t have a lot of performance history (where performance_count is low). + +Several of our columns are strings, which aren’t useful to a machine learning algorithm. However, they are actually categorical variables, where there are a few different category codes, like R, S, and so on. We can convert these columns to numeric by assigning a number to each category label: + +![](https://github.com/LCTT/wiki-images/blob/master/TranslateProject/ref_img/002.png) + +Converting the columns this way will allow us to use them in our machine learning algorithm. + +Some of the columns also contain dates (first_payment_date and origination_date). We can split these dates into 2 columns each: + +![](https://github.com/LCTT/wiki-images/blob/master/TranslateProject/ref_img/003.png) +In the below code, we’ll transform the Acquisition data. We’ll define a function that: + +- Creates a foreclosure_status column in acquisition by getting the values from the counts dictionary. +- Creates a performance_count column in acquisition by getting the values from the counts dictionary. +- Converts each of the following columns from a string column to an integer column: + - channel + - seller + - first_time_homebuyer + - loan_purpose + - property_type + - occupancy_status + - property_state + - product_type +- Converts first_payment_date and origination_date to 2 columns each: + - Splits the column on the forward slash. + - Assigns the first part of the split list to a month column. + - Assigns the second part of the split list to a year column. + - Deletes the column. + - At the end, we’ll have first_payment_month, first_payment_year, origination_month, and origination_year. +- Fills any missing values in acquisition with -1. + +``` +def annotate(acquisition, counts): + acquisition["foreclosure_status"] = acquisition["id"].apply(lambda x: get_performance_summary_value(x, "foreclosure_status", counts)) + acquisition["performance_count"] = acquisition["id"].apply(lambda x: get_performance_summary_value(x, "performance_count", counts)) + for column in [ + "channel", + "seller", + "first_time_homebuyer", + "loan_purpose", + "property_type", + "occupancy_status", + "property_state", + "product_type" + ]: + acquisition[column] = acquisition[column].astype('category').cat.codes + + for start in ["first_payment", "origination"]: + column = "{}_date".format(start) + acquisition["{}_year".format(start)] = pd.to_numeric(acquisition[column].str.split('/').str.get(1)) + acquisition["{}_month".format(start)] = pd.to_numeric(acquisition[column].str.split('/').str.get(0)) + del acquisition[column] + + acquisition = acquisition.fillna(-1) + acquisition = acquisition[acquisition["performance_count"] > settings.MINIMUM_TRACKING_QUARTERS] + return acquisition +``` + +### Pulling everything together + +We’re almost ready to pull everything together, we just need to add a bit more code to annotate.py. In the below code, we: + +- Define a function to read in the acquisition data. +- Define a function to write the processed data to processed/train.csv +- If this file is called from the command line, like python annotate.py: + - Read in the acquisition data. + - Compute the counts for the performance data, and assign them to counts. + - Annotate the acquisition DataFrame. + - Write the acquisition DataFrame to train.csv. + +``` +def read(): + acquisition = pd.read_csv(os.path.join(settings.PROCESSED_DIR, "Acquisition.txt"), sep="|") + return acquisition + +def write(acquisition): + acquisition.to_csv(os.path.join(settings.PROCESSED_DIR, "train.csv"), index=False) + +if __name__ == "__main__": + acquisition = read() + counts = count_performance_rows() + acquisition = annotate(acquisition, counts) + write(acquisition) +``` + +Once you’re done updating the file, make sure to run it with python annotate.py, to generate the train.csv file. You can find the complete annotate.py file [here][34]. + +The folder should now look like this: + +``` +loan-prediction +├── data +│ ├── Acquisition_2012Q1.txt +│ ├── Acquisition_2012Q2.txt +│ ├── Performance_2012Q1.txt +│ ├── Performance_2012Q2.txt +│ └── ... +├── processed +│ ├── Acquisition.txt +│ ├── Performance.txt +│ ├── train.csv +├── .gitignore +├── annotate.py +├── assemble.py +├── README.md +├── requirements.txt +├── settings.py +``` + +### Finding an error metric + +We’re done with generating our training dataset, and now we’ll just need to do the final step, generating predictions. We’ll need to figure out an error metric, as well as how we want to evaluate our data. In this case, there are many more loans that aren’t foreclosed on than are, so typical accuracy measures don’t make much sense. + +If we read in the training data, and check the counts in the foreclosure_status column, here’s what we get: + +``` +import pandas as pd +import settings + +train = pd.read_csv(os.path.join(settings.PROCESSED_DIR, "train.csv")) +train["foreclosure_status"].value_counts() +``` + +``` +False 4635982 +True 1585 +Name: foreclosure_status, dtype: int64 +``` + +Since so few of the loans were foreclosed on, just checking the percentage of labels that were correctly predicted will mean that we can make a machine learning model that predicts False for every row, and still gets a very high accuracy. Instead, we’ll want to use a metric that takes the class imbalance into account, and ensures that we predict foreclosures accurately. We don’t want too many false positives, where we make predict that a loan will be foreclosed on even though it won’t, or too many false negatives, where we predict that a loan won’t be foreclosed on, but it is. Of these two, false negatives are more costly for Fannie Mae, because they’re buying loans where they may not be able to recoup their investment. + +We’ll define false negative rate as the number of loans where the model predicts no foreclosure but the the loan was actually foreclosed on, divided by the number of total loans that were actually foreclosed on. This is the percentage of actual foreclosures that the model “Missed”. Here’s a diagram: + +![](https://github.com/LCTT/wiki-images/blob/master/TranslateProject/ref_img/004.png) + +In the diagram above, 1 loan was predicted as not being foreclosed on, but it actually was. If we divide this by the number of loans that were actually foreclosed on, 2, we get the false negative rate, 50%. We’ll use this as our error metric, so we can evaluate our model’s performance. + +### Setting up the classifier for machine learning + +We’ll use cross validation to make predictions. With cross validation, we’ll divide our data into 3 groups. Then we’ll do the following: + +- Train a model on groups 1 and 2, and use the model to make predictions for group 3. +- Train a model on groups 1 and 3, and use the model to make predictions for group 2. +- Train a model on groups 2 and 3, and use the model to make predictions for group 1. + +Splitting it up into groups this way means that we never train a model using the same data we’re making predictions for. This avoids overfitting. If we overfit, we’ll get a falsely low false negative rate, which makes it hard to improve our algorithm or use it in the real world. + +[Scikit-learn][35] has a function called [cross_val_predict][36] which will make it easy to perform cross validation. + +We’ll also need to pick an algorithm to use to make predictions. We need a classifier that can do [binary classification][37]. The target variable, foreclosure_status only has two values, True and False. + +We’ll use [logistic regression][38], because it works well for binary classification, runs extremely quickly, and uses little memory. This is due to how the algorithm works – instead of constructing dozens of trees, like a random forest, or doing expensive transformations, like a support vector machine, logistic regression has far fewer steps involving fewer matrix operations. + +We can use the [logistic regression classifier][39] algorithm that’s implemented in scikit-learn. The only thing we need to pay attention to is the weights of each class. If we weight the classes equally, the algorithm will predict False for every row, because it is trying to minimize errors. However, we care much more about foreclosures than we do about loans that aren’t foreclosed on. Thus, we’ll pass balanced to the class_weight keyword argument of the [LogisticRegression][40] class, to get the algorithm to weight the foreclosures more to account for the difference in the counts of each class. This will ensure that the algorithm doesn’t predict False for every row, and instead is penalized equally for making errors in predicting either class. + + + + diff --git a/sources/team_test/part 6 - Building a data science portfolio - Machine learning project.md b/sources/team_test/part 6 - Building a data science portfolio - Machine learning project.md new file mode 100644 index 0000000000..e99087b496 --- /dev/null +++ b/sources/team_test/part 6 - Building a data science portfolio - Machine learning project.md @@ -0,0 +1,173 @@ +### Setting up the classifier for machine learning + +We’ll use cross validation to make predictions. With cross validation, we’ll divide our data into 3 groups. Then we’ll do the following: + +- Train a model on groups 1 and 2, and use the model to make predictions for group 3. +- Train a model on groups 1 and 3, and use the model to make predictions for group 2. +- Train a model on groups 2 and 3, and use the model to make predictions for group 1. + +Splitting it up into groups this way means that we never train a model using the same data we’re making predictions for. This avoids overfitting. If we overfit, we’ll get a falsely low false negative rate, which makes it hard to improve our algorithm or use it in the real world. + +[Scikit-learn][35] has a function called [cross_val_predict][36] which will make it easy to perform cross validation. + +We’ll also need to pick an algorithm to use to make predictions. We need a classifier that can do [binary classification][37]. The target variable, foreclosure_status only has two values, True and False. + +We’ll use [logistic regression][38], because it works well for binary classification, runs extremely quickly, and uses little memory. This is due to how the algorithm works – instead of constructing dozens of trees, like a random forest, or doing expensive transformations, like a support vector machine, logistic regression has far fewer steps involving fewer matrix operations. + +We can use the [logistic regression classifier][39] algorithm that’s implemented in scikit-learn. The only thing we need to pay attention to is the weights of each class. If we weight the classes equally, the algorithm will predict False for every row, because it is trying to minimize errors. However, we care much more about foreclosures than we do about loans that aren’t foreclosed on. Thus, we’ll pass balanced to the class_weight keyword argument of the [LogisticRegression][40] class, to get the algorithm to weight the foreclosures more to account for the difference in the counts of each class. This will ensure that the algorithm doesn’t predict False for every row, and instead is penalized equally for making errors in predicting either class. + +### Making predictions + +Now that we have the preliminaries out of the way, we’re ready to make predictions. We’ll create a new file called predict.py that will use the train.csv file we created in the last step. The below code will: + +- Import needed libraries. +- Create a function called cross_validate that: + - Creates a logistic regression classifier with the right keyword arguments. + - Creates a list of columns that we want to use to train the model, removing id and foreclosure_status. + - Run cross validation across the train DataFrame. + - Return the predictions. + + +``` +import os +import settings +import pandas as pd +from sklearn import cross_validation +from sklearn.linear_model import LogisticRegression +from sklearn import metrics + +def cross_validate(train): + clf = LogisticRegression(random_state=1, class_weight="balanced") + + predictors = train.columns.tolist() + predictors = [p for p in predictors if p not in settings.NON_PREDICTORS] + + predictions = cross_validation.cross_val_predict(clf, train[predictors], train[settings.TARGET], cv=settings.CV_FOLDS) + return predictions +``` + +### Predicting error + +Now, we just need to write a few functions to compute error. The below code will: + +- Create a function called compute_error that: + - Uses scikit-learn to compute a simple accuracy score (the percentage of predictions that matched the actual foreclosure_status values). +- Create a function called compute_false_negatives that: + - Combines the target and the predictions into a DataFrame for convenience. + - Finds the false negative rate. +- Create a function called compute_false_positives that: + - Combines the target and the predictions into a DataFrame for convenience. + - Finds the false positive rate. + - Finds the number of loans that weren’t foreclosed on that the model predicted would be foreclosed on. + - Divide by the total number of loans that weren’t foreclosed on. + +``` +def compute_error(target, predictions): + return metrics.accuracy_score(target, predictions) + +def compute_false_negatives(target, predictions): + df = pd.DataFrame({"target": target, "predictions": predictions}) + return df[(df["target"] == 1) & (df["predictions"] == 0)].shape[0] / (df[(df["target"] == 1)].shape[0] + 1) + +def compute_false_positives(target, predictions): + df = pd.DataFrame({"target": target, "predictions": predictions}) + return df[(df["target"] == 0) & (df["predictions"] == 1)].shape[0] / (df[(df["target"] == 0)].shape[0] + 1) +``` + + +### Putting it all together + +Now, we just have to put the functions together in predict.py. The below code will: + +- Read in the dataset. +- Compute cross validated predictions. +- Compute the 3 error metrics above. +- Print the error metrics. + +``` +def read(): + train = pd.read_csv(os.path.join(settings.PROCESSED_DIR, "train.csv")) + return train + +if __name__ == "__main__": + train = read() + predictions = cross_validate(train) + error = compute_error(train[settings.TARGET], predictions) + fn = compute_false_negatives(train[settings.TARGET], predictions) + fp = compute_false_positives(train[settings.TARGET], predictions) + print("Accuracy Score: {}".format(error)) + print("False Negatives: {}".format(fn)) + print("False Positives: {}".format(fp)) +``` + +Once you’ve added the code, you can run python predict.py to generate predictions. Running everything shows that our false negative rate is .26, which means that of the foreclosed loans, we missed predicting 26% of them. This is a good start, but can use a lot of improvement! + +You can find the complete predict.py file [here][41]. + +Your file tree should now look like this: + +``` +loan-prediction +├── data +│ ├── Acquisition_2012Q1.txt +│ ├── Acquisition_2012Q2.txt +│ ├── Performance_2012Q1.txt +│ ├── Performance_2012Q2.txt +│ └── ... +├── processed +│ ├── Acquisition.txt +│ ├── Performance.txt +│ ├── train.csv +├── .gitignore +├── annotate.py +├── assemble.py +├── predict.py +├── README.md +├── requirements.txt +├── settings.py +``` + +### Writing up a README + +Now that we’ve finished our end to end project, we just have to write up a README.md file so that other people know what we did, and how to replicate it. A typical README.md for a project should include these sections: + +- A high level overview of the project, and what the goals are. +- Where to download any needed data or materials. +- Installation instructions. + - How to install the requirements. +- Usage instructions. + - How to run the project. + - What you should see after each step. +- How to contribute to the project. + - Good next steps for extending the project. + +[Here’s][42] a sample README.md for this project. + +### Next steps + +Congratulations, you’re done making an end to end machine learning project! You can find a complete example project [here][43]. It’s a good idea to upload your project to [Github][44] once you’ve finished it, so others can see it as part of your portfolio. + +There are still quite a few angles left to explore with this data. Broadly, we can split them up into 3 categories – extending this project and making it more accurate, finding other columns to predict, and exploring the data. Here are some ideas: + +- Generate more features in annotate.py. +- Switch algorithms in predict.py. +- Try using more data from Fannie Mae than we used in this post. +- Add in a way to make predictions on future data. The code we wrote will still work if we add more data, so we can add more past or future data. +- Try seeing if you can predict if a bank should have issued the loan originally (vs if Fannie Mae should have acquired the loan). + - Remove any columns from train that the bank wouldn’t have known at the time of issuing the loan. + - Some columns are known when Fannie Mae bought the loan, but not before. + - Make predictions. +- Explore seeing if you can predict columns other than foreclosure_status. + - Can you predict how much the property will be worth at sale time? +- Explore the nuances between performance updates. + - Can you predict how many times the borrower will be late on payments? + - Can you map out the typical loan lifecycle? +- Map out data on a state by state or zip code by zip code level. + - Do you see any interesting patterns? + +If you build anything interesting, please let us know in the comments! + +If you liked this, you might like to read the other posts in our ‘Build a Data Science Porfolio’ series: + +- [Storytelling with data][45]. +- [How to setup up a data science blog][46]. From 54212848c6ee922a9919e6e84e77bb9e5effbcb6 Mon Sep 17 00:00:00 2001 From: ezio Date: Mon, 1 Aug 2016 21:07:52 +0800 Subject: [PATCH 102/122] fix typo --- sources/team_test/README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sources/team_test/README.md b/sources/team_test/README.md index d2bdd305f8..0798a592ef 100644 --- a/sources/team_test/README.md +++ b/sources/team_test/README.md @@ -1,4 +1,7 @@ 组队翻译 : 《Building a data science portfolio: Machine learning project》 + 本次组织者 : @选题-oska874 + 参加译者 : @译者-vim-kakali @译者-Noobfish @译者-zky001 @译者-kokialoves @译者-ideas4u @译者-cposture + 分配方式 : 原文按大致长度分成 6 部分,参与者自由选择,先到先选,如有疑问联系 @选题-oska874 From 1b666b6fe8d3537162b6e353e75136e23c9ddd57 Mon Sep 17 00:00:00 2001 From: vim-kakali <1799225723@qq.com> Date: Mon, 1 Aug 2016 21:33:36 +0800 Subject: [PATCH 103/122] vim-kakali translating --- ...ing a data science portfolio - Machine learning project.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sources/team_test/part 4 - Building a data science portfolio - Machine learning project.md b/sources/team_test/part 4 - Building a data science portfolio - Machine learning project.md index 66db19bc54..a9af49b188 100644 --- a/sources/team_test/part 4 - Building a data science portfolio - Machine learning project.md +++ b/sources/team_test/part 4 - Building a data science portfolio - Machine learning project.md @@ -1,3 +1,7 @@ +vim-kakali translating + + + ### Computing values from the performance data The next step we’ll take is to calculate some values from processed/Performance.txt. All we want to do is to predict whether or not a property is foreclosed on. To figure this out, we just need to check if the performance data associated with a loan ever has a foreclosure_date. If foreclosure_date is None, then the property was never foreclosed on. In order to avoid including loans with little performance history in our sample, we’ll also want to count up how many rows exist in the performance file for each loan. This will let us filter loans without much performance history from our training data. From 1325b98f208b7a4355061b17bb319daf61efdf97 Mon Sep 17 00:00:00 2001 From: vim-kakali <1799225723@qq.com> Date: Mon, 1 Aug 2016 21:56:50 +0800 Subject: [PATCH 104/122] vim-kakali translating --- ... read and write Audio files with Octave 4.0.0 on Ubuntu.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sources/tech/20160616 Part 1 - Scientific Audio Processing How to read and write Audio files with Octave 4.0.0 on Ubuntu.md b/sources/tech/20160616 Part 1 - Scientific Audio Processing How to read and write Audio files with Octave 4.0.0 on Ubuntu.md index 80300deb6b..f35e0724a6 100644 --- a/sources/tech/20160616 Part 1 - Scientific Audio Processing How to read and write Audio files with Octave 4.0.0 on Ubuntu.md +++ b/sources/tech/20160616 Part 1 - Scientific Audio Processing How to read and write Audio files with Octave 4.0.0 on Ubuntu.md @@ -1,3 +1,7 @@ +vim-kakali translating + + + Scientific Audio Processing, Part I - How to read and write Audio files with Octave 4.0.0 on Ubuntu ================ From cb90401f21b819bb641106eedfcac48a7b408195 Mon Sep 17 00:00:00 2001 From: wxy Date: Mon, 1 Aug 2016 23:51:51 +0800 Subject: [PATCH 105/122] PUB:20160711 Getting started with Git MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @ChrisLeeGit 翻译的不错~ --- .../20160711 Getting started with Git.md | 41 ++++++++++++------- 1 file changed, 26 insertions(+), 15 deletions(-) rename {translated/tech => published}/20160711 Getting started with Git.md (77%) diff --git a/translated/tech/20160711 Getting started with Git.md b/published/20160711 Getting started with Git.md similarity index 77% rename from translated/tech/20160711 Getting started with Git.md rename to published/20160711 Getting started with Git.md index afa6b7382b..a490e59e2d 100644 --- a/translated/tech/20160711 Getting started with Git.md +++ b/published/20160711 Getting started with Git.md @@ -2,20 +2,23 @@ ========================= ![](https://opensource.com/sites/default/files/styles/image-full-size/public/images/life/get_started_lead.jpeg?itok=r22AKc6P) -> 图片来源:opensource.com -在这个系列的介绍中,我们学习到了谁应该使用 Git,以及 Git 是用来做什么的。今天,我们将学习如何克隆公共的 Git 仓库,以及如何提取出独立的文件而不用克隆整个仓库。 +*图片来源:opensource.com* + +在这个系列的[介绍篇][4]中,我们学习到了谁应该使用 Git,以及 Git 是用来做什么的。今天,我们将学习如何克隆公共 Git 仓库,以及如何提取出独立的文件而不用克隆整个仓库。 由于 Git 如此流行,因而如果你能够至少熟悉一些基础的 Git 知识也能为你的生活带来很多便捷。如果你可以掌握 Git 基础(你可以的,我发誓!),那么你将能够下载任何你需要的东西,甚至还可能做一些贡献作为回馈。毕竟,那就是开源的精髓所在:你拥有获取你使用的软件代码的权利,拥有和他人分享的自由,以及只要你愿意就可以修改它的权利。只要你熟悉了 Git,它就可以让这一切都变得很容易。 那么,让我们一起来熟悉 Git 吧。 ### 读和写 + 一般来说,有两种方法可以和 Git 仓库交互:你可以从仓库中读取,或者你也能够向仓库中写入。它就像一个文件:有时候你打开一个文档只是为了阅读它,而其它时候你打开文档是因为你需要做些改动。 本文仅讲解如何从 Git 仓库读取。我们将会在后面的一篇文章中讲解如何向 Git 仓库写回的主题。 ### Git 还是 GitHub? + 一句话澄清:Git 不同于 GitHub(或 GitLab,或 Bitbucket)。Git 是一个命令行程序,所以它就像下面这样: ``` @@ -31,29 +34,32 @@ usage: Git [--version] [--help] [-C ] 我的文章系列将首先教你纯粹的 Git 知识,因为一旦你理解了 Git 在做什么,那么你就无需关心正在使用的前端工具是什么了。然而,我的文章系列也将涵盖通过流行的 Git 服务完成每项任务的常用方法,因为那些将可能是你首先会遇到的。 ### 安装 Git + 在 Linux 系统上,你可以从所使用的发行版软件仓库中获取并安装 Git。BSD 用户应当在 Ports 树的 devel 部分查找 Git。 -对于闭源的操作系统,请前往 [项目网站][1] 并根据说明安装。一旦安装后,在 Linux、BSD 和 Mac OS X 上的命令应当没有任何差别。Windows 用户需要调整 Git 命令,从而和 Windows 文件系统相匹配,或者安装 Cygwin 以原生的方式运行 Git,而不受 Windows 文件系统转换问题的羁绊。 +对于闭源的操作系统,请前往其[项目官网][1],并根据说明安装。一旦安装后,在 Linux、BSD 和 Mac OS X 上的命令应当没有任何差别。Windows 用户需要调整 Git 命令,从而和 Windows 文件系统相匹配,或者安装 Cygwin 以原生的方式运行 Git,而不受 Windows 文件系统转换问题的羁绊。 + +### Git 下午茶 -### 下午茶和 Git 并非每个人都需要立刻将 Git 加入到我们的日常生活中。有些时候,你和 Git 最多的交互就是访问一个代码库,下载一两个文件,然后就不用它了。以这样的方式看待 Git,它更像是下午茶而非一次正式的宴会。你进行一些礼节性的交谈,获得了需要的信息,然后你就会离开,至少接下来的三个月你不再想这样说话。 当然,那是可以的。 一般来说,有两种方法访问 Git:使用命令行,或者使用一种神奇的因特网技术通过 web 浏览器快速轻松地访问。 -假设你想要在终端中安装并使用一个回收站,因为你已经被 rm 命令毁掉太多次了。你已经听说过 Trashy 了,它称自己为「理智的 rm 命令媒介」,并且你想在安装它之前阅读它的文档。幸运的是,[Trashy 公开地托管在 GitLab.com][2]。 +假设你想要给终端安装一个回收站,因为你已经被 rm 命令毁掉太多次了。你可能听说过 Trashy ,它称自己为「理智的 rm 命令中间人」,也许你想在安装它之前阅读它的文档。幸运的是,[Trashy 公开地托管在 GitLab.com][2]。 ### Landgrab + 我们工作的第一步是对这个 Git 仓库使用 landgrab 排序方法:我们会克隆这个完整的仓库,然后会根据内容排序。由于该仓库是托管在公共的 Git 服务平台上,所以有两种方式来完成工作:使用命令行,或者使用 web 界面。 -要想使用 Git 获取整个仓库,就要使用 git clone 命令和 Git 仓库的 URL 作为参数。如果你不清楚正确的 URL 是什么,仓库应该会告诉你的。GitLab 为你提供了 [Trashy][3] 仓库的拷贝-粘贴 URL。 +要想使用 Git 获取整个仓库,就要使用 git clone 命令和 Git 仓库的 URL 作为参数。如果你不清楚正确的 URL 是什么,仓库应该会告诉你的。GitLab 为你提供了 [Trashy][3] 仓库的用于拷贝粘贴的 URL。 ![](https://opensource.com/sites/default/files/1_gitlab-url.jpg) 你也许注意到了,在某些服务平台上,会同时提供 SSH 和 HTTPS 链接。只有当你拥有仓库的写权限时,你才可以使用 SSH。否则的话,你必须使用 HTTPS URL。 -一旦你获得了正确的 URL,克隆仓库是非常容易的。就是 git clone 这个 URL 即可,可选项是可以指定要克隆到的目录。默认情况下会将 git 目录克隆到你当前所在的位置;例如,'trashy.git' 表示将仓库克隆到你当前位置的 'trashy' 目录。我使用 .clone 扩展名标记那些只读的仓库,使用 .git 扩展名标记那些我可以读写的仓库,但那无论如何也不是官方要求的。 +一旦你获得了正确的 URL,克隆仓库是非常容易的。就是 git clone 该 URL 即可,以及一个可选的指定要克隆到的目录。默认情况下会将 git 目录克隆到你当前所在的目录;例如,'trashy.git' 将会克隆到你当前位置的 'trashy' 目录。我使用 .clone 扩展名标记那些只读的仓库,而使用 .git 扩展名标记那些我可以读写的仓库,不过这并不是官方要求的。 ``` $ git clone https://gitlab.com/trashy/trashy.git trashy.clone @@ -68,30 +74,34 @@ Checking connectivity... done. 一旦成功地克隆了仓库,你就可以像对待你电脑上任何其它目录那样浏览仓库中的文件。 -另外一种获得仓库拷贝的方式是使用 web 界面。GitLab 和 GitHub 都会提供一个 .zip 格式的仓库快照文件。GitHub 有一个大的绿色下载按钮,但是在 GitLab 中,可以浏览器的右侧找到并不显眼的下载按钮。 +另外一种获得仓库拷贝的方式是使用 web 界面。GitLab 和 GitHub 都会提供一个 .zip 格式的仓库快照文件。GitHub 有一个大大的绿色下载按钮,但是在 GitLab 中,可以在浏览器的右侧找到并不显眼的下载按钮。 ![](https://opensource.com/sites/default/files/1_gitlab-zip.jpg) ### 仔细挑选 -另外一种从 Git 仓库中获取文件的方法是找到你想要的文件,然后把它从仓库中拽出来。只有 web 界面才提供这种方法,本质上来说,你看到的是别人仓库的克隆;你可以把它想象成一个 HTTP 共享目录。 + +另外一种从 Git 仓库中获取文件的方法是找到你想要的文件,然后把它从仓库中拽出来。只有 web 界面才提供这种方法,本质上来说,你看到的是别人的仓库克隆;你可以把它想象成一个 HTTP 共享目录。 使用这种方法的问题是,你也许会发现某些文件并不存在于原始仓库中,因为完整形式的文件可能只有在执行 make 命令后才能构建,那只有你下载了完整的仓库,阅读了 README 或者 INSTALL 文件,然后运行相关命令之后才会产生。不过,假如你确信文件存在,而你只想进入仓库,获取那个文件,然后离开的话,你就可以那样做。 -在 GitLab 和 GitHub 中,单击文件链接,并在 Raw 模式下查看,然后使用你的 web 浏览器的保存功能,例如:在 Firefox 中,文件 > 保存页面为。在一个 GitWeb 仓库中(一些更喜欢自己托管 git 的人使用的私有 git 仓库 web 查看器),Raw 查看链接在文件列表视图中。 +在 GitLab 和 GitHub 中,单击文件链接,并在 Raw 模式下查看,然后使用你的 web 浏览器的保存功能,例如:在 Firefox 中,“文件” \> “保存页面为”。在一个 GitWeb 仓库中(这是一个某些更喜欢自己托管 git 的人使用的私有 git 仓库 web 查看器),Raw 查看链接在文件列表视图中。 ![](https://opensource.com/sites/default/files/1_webgit-file.jpg) ### 最佳实践 + 通常认为,和 Git 交互的正确方式是克隆完整的 Git 仓库。这样认为是有几个原因的。首先,可以使用 git pull 命令轻松地使克隆仓库保持更新,这样你就不必在每次文件改变时就重回 web 站点获得一份全新的拷贝。第二,你碰巧需要做些改进,只要保持仓库整洁,那么你可以非常轻松地向原来的作者提交所做的变更。 -现在,可能是时候练习查找感兴趣的 Git 仓库,然后将它们克隆到你的硬盘中了。只要你了解使用终端的基础知识,那就不会太难做到。还不知道终端使用基础吗?那再给多我 5 分钟时间吧。 +现在,可能是时候练习查找感兴趣的 Git 仓库,然后将它们克隆到你的硬盘中了。只要你了解使用终端的基础知识,那就不会太难做到。还不知道基本的终端使用方式吗?那再给多我 5 分钟时间吧。 ### 终端使用基础 + 首先要知道的是,所有的文件都有一个路径。这是有道理的;如果我让你在常规的非终端环境下为我打开一个文件,你就要导航到文件在你硬盘的位置,并且直到你找到那个文件,你要浏览一大堆窗口。例如,你也许要点击你的家目录 > 图片 > InktoberSketches > monkey.kra。 -在那样的场景下,我们可以说文件 monkeysketch.kra 的路径是:$HOME/图片/InktoberSketches/monkey.kra。 +在那样的场景下,文件 monkeysketch.kra 的路径是:$HOME/图片/InktoberSketches/monkey.kra。 在终端中,除非你正在处理一些特殊的系统管理员任务,你的文件路径通常是以 $HOME 开头的(或者,如果你很懒,就使用 ~ 字符),后面紧跟着一些列的文件夹直到文件名自身。 + 这就和你在 GUI 中点击各种图标直到找到相关的文件或文件夹类似。 如果你想把 Git 仓库克隆到你的文档目录,那么你可以打开一个终端然后运行下面的命令: @@ -100,6 +110,7 @@ Checking connectivity... done. $ git clone https://gitlab.com/foo/bar.git $HOME/文档/bar.clone ``` + 一旦克隆完成,你可以打开一个文件管理器窗口,导航到你的文档文件夹,然后你就会发现 bar.clone 目录正在等待着你访问。 如果你想要更高级点,你或许会在以后再次访问那个仓库,可以尝试使用 git pull 命令来查看项目有没有更新: @@ -111,7 +122,7 @@ bar.clone $ git pull ``` -到目前为止,你需要初步了解的所有终端命令就是那些了,那就去探索吧。你实践得越多,Git 掌握得就越好(孰能生巧),那就是游戏的名称,至少给了或取了一个元音。 +到目前为止,你需要初步了解的所有终端命令就是那些了,那就去探索吧。你实践得越多,Git 掌握得就越好(熟能生巧),这是重点,也是事情的本质。 -------------------------------------------------------------------------------- @@ -119,7 +130,7 @@ via: https://opensource.com/life/16/7/stumbling-git 作者:[Seth Kenlon][a] 译者:[ChrisLeeGit](https://github.com/chrisleegit) -校对:[校对者ID](https://github.com/校对者ID) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创翻译,[Linux中国](https://linux.cn/) 荣誉推出 @@ -127,4 +138,4 @@ via: https://opensource.com/life/16/7/stumbling-git [1]: https://git-scm.com/download [2]: https://gitlab.com/trashy/trashy [3]: https://gitlab.com/trashy/trashy.git - +[4]: https://linux.cn/article-7639-1.html From 6605d61db2546c2523362a1d801fad568cf28145 Mon Sep 17 00:00:00 2001 From: Ezio Date: Tue, 2 Aug 2016 00:01:02 +0800 Subject: [PATCH 106/122] =?UTF-8?q?=E7=BB=84=E9=98=9F=E7=BF=BB=E8=AF=91=20?= =?UTF-8?q?Building=20a=20data=20science=20portfolio=20-=20Machine=20learn?= =?UTF-8?q?ing=20project?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...ence portfolio - Machine learning project.md | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/sources/team_test/part 6 - Building a data science portfolio - Machine learning project.md b/sources/team_test/part 6 - Building a data science portfolio - Machine learning project.md index e99087b496..86ecbe127d 100644 --- a/sources/team_test/part 6 - Building a data science portfolio - Machine learning project.md +++ b/sources/team_test/part 6 - Building a data science portfolio - Machine learning project.md @@ -1,20 +1,3 @@ -### Setting up the classifier for machine learning - -We’ll use cross validation to make predictions. With cross validation, we’ll divide our data into 3 groups. Then we’ll do the following: - -- Train a model on groups 1 and 2, and use the model to make predictions for group 3. -- Train a model on groups 1 and 3, and use the model to make predictions for group 2. -- Train a model on groups 2 and 3, and use the model to make predictions for group 1. - -Splitting it up into groups this way means that we never train a model using the same data we’re making predictions for. This avoids overfitting. If we overfit, we’ll get a falsely low false negative rate, which makes it hard to improve our algorithm or use it in the real world. - -[Scikit-learn][35] has a function called [cross_val_predict][36] which will make it easy to perform cross validation. - -We’ll also need to pick an algorithm to use to make predictions. We need a classifier that can do [binary classification][37]. The target variable, foreclosure_status only has two values, True and False. - -We’ll use [logistic regression][38], because it works well for binary classification, runs extremely quickly, and uses little memory. This is due to how the algorithm works – instead of constructing dozens of trees, like a random forest, or doing expensive transformations, like a support vector machine, logistic regression has far fewer steps involving fewer matrix operations. - -We can use the [logistic regression classifier][39] algorithm that’s implemented in scikit-learn. The only thing we need to pay attention to is the weights of each class. If we weight the classes equally, the algorithm will predict False for every row, because it is trying to minimize errors. However, we care much more about foreclosures than we do about loans that aren’t foreclosed on. Thus, we’ll pass balanced to the class_weight keyword argument of the [LogisticRegression][40] class, to get the algorithm to weight the foreclosures more to account for the difference in the counts of each class. This will ensure that the algorithm doesn’t predict False for every row, and instead is penalized equally for making errors in predicting either class. ### Making predictions From 263406bc4d937c1988c6f2a02c037141731c54b2 Mon Sep 17 00:00:00 2001 From: Chang Liu Date: Tue, 2 Aug 2016 07:04:24 +0800 Subject: [PATCH 107/122] Update 20160715 bc - Command line calculator.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 准备进行翻译。 --- sources/tech/20160715 bc - Command line calculator.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sources/tech/20160715 bc - Command line calculator.md b/sources/tech/20160715 bc - Command line calculator.md index adf854e468..a85ebc4985 100644 --- a/sources/tech/20160715 bc - Command line calculator.md +++ b/sources/tech/20160715 bc - Command line calculator.md @@ -1,3 +1,5 @@ +FSSlc translating + bc: Command line calculator ============================ From 19ed340a8d11ba269efc7b18c4df21e699d80922 Mon Sep 17 00:00:00 2001 From: kokialoves <498497353@qq.com> Date: Tue, 2 Aug 2016 08:46:55 +0800 Subject: [PATCH 108/122] Update part 5 - Building a data science portfolio - Machine learning project.md --- ...ilding a data science portfolio - Machine learning project.md | 1 + 1 file changed, 1 insertion(+) diff --git a/sources/team_test/part 5 - Building a data science portfolio - Machine learning project.md b/sources/team_test/part 5 - Building a data science portfolio - Machine learning project.md index 64be5f9492..722aa8f286 100644 --- a/sources/team_test/part 5 - Building a data science portfolio - Machine learning project.md +++ b/sources/team_test/part 5 - Building a data science portfolio - Machine learning project.md @@ -1,3 +1,4 @@ +[translating by kokialoves] ### Annotating the data We’ve already added a few functions to annotate.py, but now we can get into the meat of the file. We’ll need to convert the acquisition data into a training dataset that can be used in a machine learning algorithm. This involves a few things: From 6846cec1e9cef45d8a31951fe3fc47ba2bb5cbce Mon Sep 17 00:00:00 2001 From: ChrisLeeGit Date: Tue, 2 Aug 2016 09:45:45 +0800 Subject: [PATCH 109/122] =?UTF-8?q?=E5=AE=8C=E6=88=90=E7=BF=BB=E8=AF=91?= =?UTF-8?q?=EF=BC=9ALearn=20How=20to=20Use=20Awk=20Special=20Patterns=20be?= =?UTF-8?q?gin=20and=20end?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ... Use Awk Special Patterns begin and end.md | 168 ------------------ ... Use Awk Special Patterns begin and end.md | 166 +++++++++++++++++ 2 files changed, 166 insertions(+), 168 deletions(-) delete mode 100644 sources/tech/awk/20160719 Part 9 - Learn How to Use Awk Special Patterns begin and end.md create mode 100644 translated/tech/awk/20160719 Part 9 - Learn How to Use Awk Special Patterns begin and end.md diff --git a/sources/tech/awk/20160719 Part 9 - Learn How to Use Awk Special Patterns begin and end.md b/sources/tech/awk/20160719 Part 9 - Learn How to Use Awk Special Patterns begin and end.md deleted file mode 100644 index b3f99e6d4f..0000000000 --- a/sources/tech/awk/20160719 Part 9 - Learn How to Use Awk Special Patterns begin and end.md +++ /dev/null @@ -1,168 +0,0 @@ -Being translated by ChrisLeeGit - -Learn How to Use Awk Special Patterns ‘BEGIN and END’ – Part 9 -=============================================================== - -In Part 8 of this Awk series, we introduced some powerful Awk command features, that is variables, numeric expressions and assignment operators. - -As we advance, in this segment, we shall cover more Awk features, and that is the special patterns: `BEGIN` and `END`. - -![](http://www.tecmint.com/wp-content/uploads/2016/07/Learn-Awk-Patterns-BEGIN-and-END.png) ->Learn Awk Patterns BEGIN and END - -These special features will prove helpful as we try to expand on and explore more methods of building complex Awk operations. - -To get started, let us drive our thoughts back to the introduction of the Awk series, remember when we started this series, I pointed out that the general syntax of a running an Awk command is: - -``` -# awk 'script' filenames -``` - -And in the syntax above, the Awk script has the form: - -``` -/pattern/ { actions } -``` - -When you consider the pattern in the script, it is normally a regular expression, additionally, you can also think of pattern as special patterns `BEGIN` and `END`. Therefore, we can also write an Awk command in the form below: - -``` -awk ' -BEGIN { actions } -/pattern/ { actions } -/pattern/ { actions } -………. -END { actions } -' filenames -``` - -In the event that you use the special patterns: `BEGIN` and `END` in an Awk script, this is what each of them means: - -- `BEGIN` pattern: means that Awk will execute the action(s) specified in `BEGIN` once before any input lines are read. -- `END` pattern: means that Awk will execute the action(s) specified in `END` before it actually exits. - -And the flow of execution of the an Awk command script which contains these special patterns is as follows: - -- When the `BEGIN` pattern is used in a script, all the actions for `BEGIN` are executed once before any input line is read. -- Then an input line is read and parsed into the different fields. -- Next, each of the non-special patterns specified is compared with the input line for a match, when a match is found, the action(s) for that pattern are then executed. This stage will be repeated for all the patterns you have specified. -- Next, stage 2 and 3 are repeated for all input lines. -- When all input lines have been read and dealt with, in case you specify the `END` pattern, the action(s) will be executed. - -You should always remember this sequence of execution when working with the special patterns to achieve the best results in an Awk operation. - -To understand it all, let us illustrate using the example from part 8, about the list of domains owned by Tecmint, as stored in a file named domains.txt. - -``` -news.tecmint.com -tecmint.com -linuxsay.com -windows.tecmint.com -tecmint.com -news.tecmint.com -tecmint.com -linuxsay.com -tecmint.com -news.tecmint.com -tecmint.com -linuxsay.com -windows.tecmint.com -tecmint.com -``` - -``` -$ cat ~/domains.txt -``` - -![](http://www.tecmint.com/wp-content/uploads/2016/07/View-Contents-of-File.png) ->View Contents of File - -In this example, we want to count the number of times the domain `tecmint.com` is listed in the file domains.txt. So we wrote a small shell script to help us do that using the idea of variables, numeric expressions and assignment operators which has the following content: - -``` -#!/bin/bash -for file in $@; do -if [ -f $file ] ; then -#print out filename -echo "File is: $file" -#print a number incrementally for every line containing tecmint.com -awk '/^tecmint.com/ { counter+=1 ; printf "%s\n", counter ; }' $file -else -#print error info incase input is not a file -echo "$file is not a file, please specify a file." >&2 && exit 1 -fi -done -#terminate script with exit code 0 in case of successful execution -exit 0 -``` - -Let us now employ the two special patterns: `BEGIN` and `END` in the Awk command in the script above as follows: - -We shall alter the script: - -``` -awk '/^tecmint.com/ { counter+=1 ; printf "%s\n", counter ; }' $file -``` - -To: - -``` -awk ' BEGIN { print "The number of times tecmint.com appears in the file is:" ; } -/^tecmint.com/ { counter+=1 ; } -END { printf "%s\n", counter ; } -' $file -``` - -After making the changes to the Awk command, the complete shell script now looks like this: - -``` -#!/bin/bash -for file in $@; do -if [ -f $file ] ; then -#print out filename -echo "File is: $file" -#print the total number of times tecmint.com appears in the file -awk ' BEGIN { print "The number of times tecmint.com appears in the file is:" ; } -/^tecmint.com/ { counter+=1 ; } -END { printf "%s\n", counter ; } -' $file -else -#print error info incase input is not a file -echo "$file is not a file, please specify a file." >&2 && exit 1 -fi -done -#terminate script with exit code 0 in case of successful execution -exit 0 -``` - -![](http://www.tecmint.com/wp-content/uploads/2016/07/Awk-BEGIN-and-END-Patterns.png) ->Awk BEGIN and END Patterns - -When we run the script above, it will first of all print the location of the file domains.txt, then the Awk command script is executed, where the `BEGIN` special pattern helps us print out the message “`The number of times tecmint.com appears in the file is:`” before any input lines are read from the file. - -Then our pattern, `/^tecmint.com/` is compared against every input line and the action, `{ counter+=1 ; }` is executed for each input line, which counts the number of times `tecmint.com` appears in the file. - -Finally, the `END` pattern will print the total the number of times the domain `tecmint.com` appears in the file. - -``` -$ ./script.sh ~/domains.txt -``` -![](http://www.tecmint.com/wp-content/uploads/2016/07/Script-to-Count-Number-of-Times-String-Appears.png) ->Script to Count Number of Times String Appears - -To conclude, we walked through more Awk features exploring on the concepts of special pattern: `BEGIN` and `END`. - -As I pointed out before, these Awk features will help us build more complex text filtering operations, there is more to cover under Awk features and in part 10, we shall approach the idea of Awk built-in variables, so stay connected. - - --------------------------------------------------------------------------------- - -via: http://www.tecmint.com/learn-use-awk-special-patterns-begin-and-end/ - -作者:[Aaron Kili][a] -译者:[ChrisLeeGit](https://github.com/chrisleegit) -校对:[校对ID](https://github.com/校对ID) - -本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 - -[a]: http://www.tecmint.com/author/aaronkili/ diff --git a/translated/tech/awk/20160719 Part 9 - Learn How to Use Awk Special Patterns begin and end.md b/translated/tech/awk/20160719 Part 9 - Learn How to Use Awk Special Patterns begin and end.md new file mode 100644 index 0000000000..378811776a --- /dev/null +++ b/translated/tech/awk/20160719 Part 9 - Learn How to Use Awk Special Patterns begin and end.md @@ -0,0 +1,166 @@ +awk 系列:如何使用 awk 的特殊模式 BEGIN 和 END +=============================================================== +在 awk 系列的第八节,我们介绍了一些强大的 awk 命令功能,它们是变量、数字表达式和赋值运算符。 + +本节我们将学习更多的 awk 功能,即 awk 的特殊模式:`BEGIN` 和 `END`。 + +![](http://www.tecmint.com/wp-content/uploads/2016/07/Learn-Awk-Patterns-BEGIN-and-END.png) +> 学习 awk 的模式 BEGIN 和 END + +随着我们逐渐展开,并探索出更多构建复杂 awk 操作的方法,将会证明 awk 的这些特殊功能的是多么强大。 + +开始前,先让我们回顾一下 awk 系列的介绍,记得当我们开始这个系列时,我就指出 awk 指令的通用语法是这样的: + +``` +# awk 'script' filenames +``` + +在上述语法中,awk 脚本拥有这样的形式: + +``` +/pattern/ { actions } +``` + +当你看脚本中的模式(`/pattern`)时,你会发现它通常是一个正则表达式,此外,你也可以将模式(`/pattern`)当成特殊模式 `BEGIN` 和 `END`。 +因此,我们也能按照下面的形式编写一条 awk 命令: + +``` +awk ' +BEGIN { actions } +/pattern/ { actions } +/pattern/ { actions } +………. +END { actions } +' filenames +``` + +假如你在 awk 脚本中使用了特殊模式:`BEGIN` 和 `END`,以下则是它们对应的含义: + +- `BEGIN` 模式:是指 awk 将在读取任何输入行之前立即执行 `BEGIN` 中指定的动作。 +- `END` 模式:是指 awk 将在它正式退出前执行 `END` 中指定的动作。 + +含有这些特殊模式的 awk 命令脚本的执行流程如下: + +- 当在脚本中使用了 `BEGIN` 模式,则 `BEGIN` 中所有的动作都会在读取任何输入行之前执行。 +- 然后,读入一个输入行并解析成不同的段。 +- 接下来,每一条指定的非特殊模式都会和输入行进行比较匹配,当匹配成功后,就会执行模式对应的动作。对所有你指定的模式重复此执行该步骤。 +- 再接下来,对于所有输入行重复执行步骤 2 和 步骤 3。 +- 当读取并处理完所有输入行后,假如你指定了 `END` 模式,那么将会执行相应的动作。 + +当你使用特殊模式时,想要在 awk 操作中获得最好的结果,你应当记住上面的执行顺序。 + +为了便于理解,让我们使用第八节的例子进行演示,那个例子是关于 Tecmint 拥有的域名列表,并保存在一个叫做 domains.txt 的文件中。 + +``` +news.tecmint.com +tecmint.com +linuxsay.com +windows.tecmint.com +tecmint.com +news.tecmint.com +tecmint.com +linuxsay.com +tecmint.com +news.tecmint.com +tecmint.com +linuxsay.com +windows.tecmint.com +tecmint.com +``` + +``` +$ cat ~/domains.txt +``` + +![](http://www.tecmint.com/wp-content/uploads/2016/07/View-Contents-of-File.png) +> 查看文件内容 + +在这个例子中,我们希望统计出 domains.txt 文件中域名 `tecmint.com` 出现的次数。所以,我们编写了一个简单的 shell 脚本帮助我们完成任务,它使用了变量、数学表达式和赋值运算符的思想,脚本内容如下: + +``` +#!/bin/bash +for file in $@; do +if [ -f $file ] ; then +# 输出文件名 +echo "File is: $file" +# 输出一个递增的数字记录包含 tecmint.com 的行数 +awk '/^tecmint.com/ { counter+=1 ; printf "%s\n", counter ; }' $file +else +# 若输入不是文件,则输出错误信息 +echo "$file 不是一个文件,请指定一个文件。" >&2 && exit 1 +fi +done +# 成功执行后使用退出代码 0 终止脚本 +exit 0 +``` + +现在让我们像下面这样在上述脚本的 awk 命令中应用这两个特殊模式:`BEGIN` 和 `END`: + +我们应当把脚本: + +``` +awk '/^tecmint.com/ { counter+=1 ; printf "%s\n", counter ; }' $file +``` + +改成: + +``` +awk ' BEGIN { print "文件中出现 tecmint.com 的次数是:" ; } +/^tecmint.com/ { counter+=1 ; } +END { printf "%s\n", counter ; } +' $file +``` + +在修改了 awk 命令之后,现在完整的 shell 脚本就像下面这样: + +``` +#!/bin/bash +for file in $@; do +if [ -f $file ] ; then +# 输出文件名 +echo "File is: $file" +# 输出文件中 tecmint.com 出现的总次数 +awk ' BEGIN { print "文件中出现 tecmint.com 的次数是:" ; } +/^tecmint.com/ { counter+=1 ; } +END { printf "%s\n", counter ; } +' $file +else +# 若输入不是文件,则输出错误信息 +echo "$file 不是一个文件,请指定一个文件。" >&2 && exit 1 +fi +done +# 成功执行后使用退出代码 0 终止脚本 +exit 0 +``` + +![](http://www.tecmint.com/wp-content/uploads/2016/07/Awk-BEGIN-and-END-Patterns.png) +> awk 模式 BEGIN 和 END + +当我们运行上面的脚本时,它会首先输出 domains.txt 文件的位置,然后执行 awk 命令脚本,该命令脚本中的特殊模式 `BEGIN` 将会在从文件读取任何行之前帮助我们输出这样的消息“`文件中出现 tecmint.com 的次数是:`”。 + +接下来,我们的模式 `/^tecmint.com/` 会在每个输入行中进行比较,对应的动作 `{ counter+=1 ; }` 会在每个匹配成功的行上执行,它会统计出 `tecmint.com` 在文件中出现的次数。 + +最终,`END` 模式将会输出域名 `tecmint.com` 在文件中出现的总次数。 + +``` +$ ./script.sh ~/domains.txt +``` +![](http://www.tecmint.com/wp-content/uploads/2016/07/Script-to-Count-Number-of-Times-String-Appears.png) +> 用于统计字符串出现次数的脚本 + +最后总结一下,我们在本节中演示了更多的 awk 功能,并学习了特殊模式 `BEGIN` 和 `END` 的概念。 + +正如我之前所言,这些 awk 功能将会帮助我们构建出更复杂的文本过滤操作。第十节将会给出更多的 awk 功能,我们将会学习 awk 内置变量的思想,所以,请继续保持关注。 + + +-------------------------------------------------------------------------------- + +via: http://www.tecmint.com/learn-use-awk-special-patterns-begin-and-end/ + +作者:[Aaron Kili][a] +译者:[ChrisLeeGit](https://github.com/chrisleegit) +校对:[校对ID](https://github.com/校对ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]: http://www.tecmint.com/author/aaronkili/ From 99c74fdce7d8c3b23b2659bdcbdd616f77f94a6d Mon Sep 17 00:00:00 2001 From: ChrisLeeGit Date: Tue, 2 Aug 2016 11:39:25 +0800 Subject: [PATCH 110/122] =?UTF-8?q?=E7=94=B3=E8=AF=B7=E7=BF=BB=E8=AF=91=20?= =?UTF-8?q?Part=2010=20-=20Learn=20How=20to=20Use=20Awk=20Built-in=20Varia?= =?UTF-8?q?bles?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...160725 Part 10 - Learn How to Use Awk Built-in Variables.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sources/tech/awk/20160725 Part 10 - Learn How to Use Awk Built-in Variables.md b/sources/tech/awk/20160725 Part 10 - Learn How to Use Awk Built-in Variables.md index 4cbecac8c9..9b66a0cbfe 100644 --- a/sources/tech/awk/20160725 Part 10 - Learn How to Use Awk Built-in Variables.md +++ b/sources/tech/awk/20160725 Part 10 - Learn How to Use Awk Built-in Variables.md @@ -1,3 +1,4 @@ +Being translated by ChrisLeeGit Learn How to Use Awk Built-in Variables – Part 10 ================================================= @@ -111,7 +112,7 @@ After this, we shall progress to cover how we can use shell variables in Awk com via: http://www.tecmint.com/awk-built-in-variables-examples/?utm_source=feedburner&utm_medium=feed&utm_campaign=Feed%3A+tecmint+%28Tecmint%3A+Linux+Howto%27s+Guide%29 作者:[Aaron Kili][a] -译者:[译者ID](https://github.com/译者ID) +译者:[ChrisLeeGit](https://github.com/chrisleegit) 校对:[校对ID](https://github.com/校对ID) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 From 020d5f489bd5e3ad3c0c20b1aa9c500641dc3c17 Mon Sep 17 00:00:00 2001 From: kokialoves <498497353@qq.com> Date: Tue, 2 Aug 2016 12:00:37 +0800 Subject: [PATCH 111/122] part 5 - Building a data science portfolio - Machine learning project.md (#4264) * Delete part 5 - Building a data science portfolio - Machine learning project.md * part 5 - Building a data science portfolio - Machine learning project.md --- ...ce portfolio - Machine learning project.md | 146 ++++++++---------- 1 file changed, 61 insertions(+), 85 deletions(-) diff --git a/sources/team_test/part 5 - Building a data science portfolio - Machine learning project.md b/sources/team_test/part 5 - Building a data science portfolio - Machine learning project.md index 722aa8f286..99e1046e70 100644 --- a/sources/team_test/part 5 - Building a data science portfolio - Machine learning project.md +++ b/sources/team_test/part 5 - Building a data science portfolio - Machine learning project.md @@ -1,44 +1,38 @@ -[translating by kokialoves] -### Annotating the data +注解数据 +我们已经在annotate.py中添加了一些功能, 现在我们来看一看数据文件. 我们需要将采集到的数据转换到training dataset来进行机器学习的训练. 这涉及到以下几件事情: -We’ve already added a few functions to annotate.py, but now we can get into the meat of the file. We’ll need to convert the acquisition data into a training dataset that can be used in a machine learning algorithm. This involves a few things: +转换所以列数字. +填充缺失值. +分配 performance_count 和 foreclosure_status. +移除出现次数很少的行(performance_count 计数低). +我们有几个列是strings类型的, 看起来对于机器学习算法来说并不是很有用. 然而, 他们实际上是分类变量, 其中有很多不同的类别代码, 例如R,S等等. 我们可以把这些类别标签转换为数值: -- Converting all columns to numeric. -- Filling in any missing values. -- Assigning a performance_count and a foreclosure_status to each row. -- Removing any rows that don’t have a lot of performance history (where performance_count is low). -Several of our columns are strings, which aren’t useful to a machine learning algorithm. However, they are actually categorical variables, where there are a few different category codes, like R, S, and so on. We can convert these columns to numeric by assigning a number to each category label: -![](https://github.com/LCTT/wiki-images/blob/master/TranslateProject/ref_img/002.png) +通过这种方法转换的列我们可以应用到机器学习算法中. -Converting the columns this way will allow us to use them in our machine learning algorithm. +还有一些包含日期的列 (first_payment_date 和 origination_date). 我们可以将这些日期放到两个列中: -Some of the columns also contain dates (first_payment_date and origination_date). We can split these dates into 2 columns each: + 在下面的代码中, 我们将转换采集到的数据. 我们将定义一个函数如下: -![](https://github.com/LCTT/wiki-images/blob/master/TranslateProject/ref_img/003.png) -In the below code, we’ll transform the Acquisition data. We’ll define a function that: - -- Creates a foreclosure_status column in acquisition by getting the values from the counts dictionary. -- Creates a performance_count column in acquisition by getting the values from the counts dictionary. -- Converts each of the following columns from a string column to an integer column: - - channel - - seller - - first_time_homebuyer - - loan_purpose - - property_type - - occupancy_status - - property_state - - product_type -- Converts first_payment_date and origination_date to 2 columns each: - - Splits the column on the forward slash. - - Assigns the first part of the split list to a month column. - - Assigns the second part of the split list to a year column. - - Deletes the column. - - At the end, we’ll have first_payment_month, first_payment_year, origination_month, and origination_year. -- Fills any missing values in acquisition with -1. - -``` +在采集到的数据中创建foreclosure_status列 . +在采集到的数据中创建performance_count列. +将下面的string列转换为integer列: +channel +seller +first_time_homebuyer +loan_purpose +property_type +occupancy_status +property_state +product_type +转换first_payment_date 和 origination_date 为两列: +通过斜杠分离列. +将第一部分分离成月清单. +将第二部分分离成年清单. +删除这一列. +最后, 我们得到 first_payment_month, first_payment_year, origination_month, and origination_year. +所有缺失值填充为-1. def annotate(acquisition, counts): acquisition["foreclosure_status"] = acquisition["id"].apply(lambda x: get_performance_summary_value(x, "foreclosure_status", counts)) acquisition["performance_count"] = acquisition["id"].apply(lambda x: get_performance_summary_value(x, "performance_count", counts)) @@ -63,25 +57,21 @@ def annotate(acquisition, counts): acquisition = acquisition.fillna(-1) acquisition = acquisition[acquisition["performance_count"] > settings.MINIMUM_TRACKING_QUARTERS] return acquisition -``` -### Pulling everything together +聚合到一起 +我们差不多准备就绪了, 我们只需要再在annotate.py添加一点点代码. 在下面代码中, 我们将: -We’re almost ready to pull everything together, we just need to add a bit more code to annotate.py. In the below code, we: - -- Define a function to read in the acquisition data. -- Define a function to write the processed data to processed/train.csv -- If this file is called from the command line, like python annotate.py: - - Read in the acquisition data. - - Compute the counts for the performance data, and assign them to counts. - - Annotate the acquisition DataFrame. - - Write the acquisition DataFrame to train.csv. - -``` +定义一个函数来读取采集的数据. +定义一个函数来写入数据到/train.csv +如果我们在命令行运行annotate.py来读取更新过的数据文件,它将做如下事情: +读取采集到的数据. +计算数据性能. +注解数据. +将注解数据写入到train.csv. def read(): acquisition = pd.read_csv(os.path.join(settings.PROCESSED_DIR, "Acquisition.txt"), sep="|") return acquisition - + def write(acquisition): acquisition.to_csv(os.path.join(settings.PROCESSED_DIR, "train.csv"), index=False) @@ -90,13 +80,11 @@ if __name__ == "__main__": counts = count_performance_rows() acquisition = annotate(acquisition, counts) write(acquisition) -``` -Once you’re done updating the file, make sure to run it with python annotate.py, to generate the train.csv file. You can find the complete annotate.py file [here][34]. +修改完成以后为了确保annotate.py能够生成train.csv文件. 你可以在这里找到完整的 annotate.py file [here][34]. -The folder should now look like this: +文件夹结果应该像这样: -``` loan-prediction ├── data │ ├── Acquisition_2012Q1.txt @@ -114,54 +102,42 @@ loan-prediction ├── README.md ├── requirements.txt ├── settings.py -``` -### Finding an error metric +找到标准 +我们已经完成了training dataset的生成, 现在我们需要最后一步, 生成预测. 我们需要找到错误的标准, 以及该如何评估我们的数据. 在这种情况下, 因为有很多的贷款没有收回, 所以根本不可能做到精确的计算. -We’re done with generating our training dataset, and now we’ll just need to do the final step, generating predictions. We’ll need to figure out an error metric, as well as how we want to evaluate our data. In this case, there are many more loans that aren’t foreclosed on than are, so typical accuracy measures don’t make much sense. +我们需要读取数据, 并且计算foreclosure_status列, 我们将得到如下信息: -If we read in the training data, and check the counts in the foreclosure_status column, here’s what we get: - -``` import pandas as pd import settings train = pd.read_csv(os.path.join(settings.PROCESSED_DIR, "train.csv")) train["foreclosure_status"].value_counts() -``` -``` False 4635982 True 1585 Name: foreclosure_status, dtype: int64 -``` -Since so few of the loans were foreclosed on, just checking the percentage of labels that were correctly predicted will mean that we can make a machine learning model that predicts False for every row, and still gets a very high accuracy. Instead, we’ll want to use a metric that takes the class imbalance into account, and ensures that we predict foreclosures accurately. We don’t want too many false positives, where we make predict that a loan will be foreclosed on even though it won’t, or too many false negatives, where we predict that a loan won’t be foreclosed on, but it is. Of these two, false negatives are more costly for Fannie Mae, because they’re buying loans where they may not be able to recoup their investment. +因为只有一点点贷款收回, 通过百分比标签来建立的机器学习模型会把每行都设置为Fasle, 所以我们在这里要考虑每个样本的不平衡性,确保我们做出的预测是准确的. 我们不想要这么多假的false, 我们将预计贷款收回但是它并没有收回, 我们预计贷款不会回收但是却回收了. 通过以上两点, Fannie Mae的false太多了, 因此显示他们可能无法收回投资. -We’ll define false negative rate as the number of loans where the model predicts no foreclosure but the the loan was actually foreclosed on, divided by the number of total loans that were actually foreclosed on. This is the percentage of actual foreclosures that the model “Missed”. Here’s a diagram: - -![](https://github.com/LCTT/wiki-images/blob/master/TranslateProject/ref_img/004.png) - -In the diagram above, 1 loan was predicted as not being foreclosed on, but it actually was. If we divide this by the number of loans that were actually foreclosed on, 2, we get the false negative rate, 50%. We’ll use this as our error metric, so we can evaluate our model’s performance. - -### Setting up the classifier for machine learning - -We’ll use cross validation to make predictions. With cross validation, we’ll divide our data into 3 groups. Then we’ll do the following: - -- Train a model on groups 1 and 2, and use the model to make predictions for group 3. -- Train a model on groups 1 and 3, and use the model to make predictions for group 2. -- Train a model on groups 2 and 3, and use the model to make predictions for group 1. - -Splitting it up into groups this way means that we never train a model using the same data we’re making predictions for. This avoids overfitting. If we overfit, we’ll get a falsely low false negative rate, which makes it hard to improve our algorithm or use it in the real world. - -[Scikit-learn][35] has a function called [cross_val_predict][36] which will make it easy to perform cross validation. - -We’ll also need to pick an algorithm to use to make predictions. We need a classifier that can do [binary classification][37]. The target variable, foreclosure_status only has two values, True and False. - -We’ll use [logistic regression][38], because it works well for binary classification, runs extremely quickly, and uses little memory. This is due to how the algorithm works – instead of constructing dozens of trees, like a random forest, or doing expensive transformations, like a support vector machine, logistic regression has far fewer steps involving fewer matrix operations. - -We can use the [logistic regression classifier][39] algorithm that’s implemented in scikit-learn. The only thing we need to pay attention to is the weights of each class. If we weight the classes equally, the algorithm will predict False for every row, because it is trying to minimize errors. However, we care much more about foreclosures than we do about loans that aren’t foreclosed on. Thus, we’ll pass balanced to the class_weight keyword argument of the [LogisticRegression][40] class, to get the algorithm to weight the foreclosures more to account for the difference in the counts of each class. This will ensure that the algorithm doesn’t predict False for every row, and instead is penalized equally for making errors in predicting either class. +所以我们将定义一个百分比,就是模型预测没有收回但是实际上收回了, 这个数除以总的负债回收总数. 这个负债回收百分比模型实际上是“没有的”. 下面看这个图表: +通过上面的图表, 1个负债预计不会回收, 也确实没有回收. 如果我们将这个数除以总数, 2, 我们将得到false的概率为50%. 我们将使用这个标准, 因此我们可以评估一下模型的性能. +设置机器学习分类器 +我们使用交叉验证预测. 通过交叉验证法, 我们将数据分为3组. 按照下面的方法来做: + +Train a model on groups 1 and 2, and use the model to make predictions for group 3. +Train a model on groups 1 and 3, and use the model to make predictions for group 2. +Train a model on groups 2 and 3, and use the model to make predictions for group 1. +将它们分割到不同的组 ,这意味着我们永远不会用相同的数据来为预测训练模型. 这样就避免了 overfitting. 如果我们overfit, 我们将得到很低的false概率, 这使得我们难以改进算法或者应用到现实生活中. + +[Scikit-learn][35] 有一个叫做 [cross_val_predict][36] 他可以帮助我们理解交叉算法. + +我们还需要一种算法来帮我们预测. 我们还需要一个分类器 [binary classification][37](二元分类). 目标变量foreclosure_status 只有两个值, True 和 False. + +我们用[logistic regression][38](回归算法), 因为它能很好的进行binary classification(二元分类), 并且运行很快, 占用内存很小. 我们来说一下它是如何工作的 – 取代许多树状结构, 更像随机森林, 进行转换, 更像一个向量机, 逻辑回归涉及更少的步骤和更少的矩阵. + +我们可以使用[logistic regression classifier][39](逻辑回归分类器)算法 来实现scikit-learn. 我们唯一需要注意的是每个类的标准. 如果我们使用同样标准的类, 算法将会预测每行都为false, 因为它总是试图最小化误差.不管怎样, 我们关注有多少贷款能够回收而不是有多少不能回收. 因此, 我们通过 [LogisticRegression][40](逻辑回归)来平衡标准参数, 并计算回收贷款的标准. 这将使我们的算法不会认为每一行都为false. From 725d3a6a81c30c27799bc055a116d7439da3138b Mon Sep 17 00:00:00 2001 From: FSSlc Date: Tue, 2 Aug 2016 13:33:49 +0800 Subject: [PATCH 112/122] [Translated]20160715 bc-Command line calculator.md --- .../20160715 bc - Command line calculator.md | 133 ------------------ .../20160715 bc - Command line calculator.md | 129 +++++++++++++++++ 2 files changed, 129 insertions(+), 133 deletions(-) delete mode 100644 sources/tech/20160715 bc - Command line calculator.md create mode 100644 translated/tech/20160715 bc - Command line calculator.md diff --git a/sources/tech/20160715 bc - Command line calculator.md b/sources/tech/20160715 bc - Command line calculator.md deleted file mode 100644 index a85ebc4985..0000000000 --- a/sources/tech/20160715 bc - Command line calculator.md +++ /dev/null @@ -1,133 +0,0 @@ -FSSlc translating - -bc: Command line calculator -============================ - -![](https://cdn.fedoramagazine.org/wp-content/uploads/2016/07/bc-calculator-945x400.jpg) - -If you run a graphical desktop environment, you probably point and click your way to a calculator when you need one. The Fedora Workstation, for example, includes the Calculator tool. It features several different operating modes that allow you to do, for example, complex math or financial calculations. But did you know the command line also offers a similar calculator called bc? - -The bc utility gives you everything you expect from a scientific, financial, or even simple calculator. What’s more, it can be scripted from the command line if needed. This allows you to use it in shell scripts, in case you need to do more complex math. - -Because bc is used by some other system software, like CUPS printing services, it’s probably installed on your Fedora system already. You can check with this command: - -``` -dnf list installed bc -``` - -If you don’t see it for some reason, you can install the package with this command: - -``` -sudo dnf install bc -``` - -### Doing simple math with bc - -One way to use bc is to enter the calculator’s own shell. There you can run many calculations in a row. When you enter, the first thing that appears is a notice about the program: - -``` -$ bc -bc 1.06.95 -Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006 Free Software Foundation, Inc. -This is free software with ABSOLUTELY NO WARRANTY. -For details type `warranty'. -``` - -Now you can type in calculations or commands, one per line: - -``` -1+1 -``` - -The calculator helpfully answers: - -``` -2 -``` - -You can perform other commands here. You can use addition (+), subtraction (-), multiplication (*), division (/), parentheses, exponents (^), and so forth. Note that the calculator respects all expected conventions such as order of operations. Try these examples: - -``` -(4+7)*2 -4+7*2 -``` - -To exit, send the “end of input” signal with the key combination Ctrl+D. - -Another way is to use the echo command to send calculations or commands. Here’s the calculator equivalent of “Hello, world,” using the shell’s pipe function (|) to send output from echo into bc: - -``` -echo '1+1' | bc -``` - -You can send more than one calculation using the shell pipe, with a semicolon to separate entries. The results are returned on separate lines. - -``` -echo '1+1; 2+2' | bc -``` - -### Scale - -The bc calculator uses the concept of scale, or the number of digits after a decimal point, in some calculations. The default scale is 0. Division operations always use the scale setting. So if you don’t set scale, you may get unexpected answers: - -``` -echo '3/2' | bc -echo 'scale=3; 3/2' | bc -``` - -Multiplication uses a more complex decision for scale: - -``` -echo '3*2' | bc -echo '3*2.0' | bc -``` - -Meanwhile, addition and subtraction are more as expected: - -``` -echo '7-4.15' | bc -``` - -### Other base number systems - -Another useful function is the ability to use number systems other than base-10 (decimal). For instance, you can easily do hexadecimal or binary math. Use the ibase and obase commands to set input and output base systems between base-2 and base-16. Remember that once you use ibase, any number you enter is expected to be in the new declared base. - -To do hexadecimal to decimal conversions or math, you can use a command like this. Note the hexadecimal digits above 9 must be in uppercase (A-F): - -``` -echo 'ibase=16; A42F' | bc -echo 'ibase=16; 5F72+C39B' | bc -``` - -To get results in hexadecimal, set the obase as well: - -``` -echo 'obase=16; ibase=16; 5F72+C39B' | bc -``` - -Here’s a trick, though. If you’re doing these calculations in the shell, how do you switch back to input in base-10? The answer is to use ibase, but you must set it to the equivalent of decimal number 10 in the current input base. For instance, if ibase was set to hexadecimal, enter: - -``` -ibase=A -``` - -Once you do this, all input numbers are now decimal again, so you can enter obase=10 to reset the output base system. - -### Conclusion - -This is only the beginning of what bc can do. It also allows you to define functions, variables, and loops for complex calculations and programs. You can save these programs as text files on your system to run whenever you need. You can find numerous resources on the web that offer examples and additional function libraries. Happy calculating! - - - --------------------------------------------------------------------------------- - -via: http://www.tecmint.com/mandatory-access-control-with-selinux-or-apparmor-linux/ - -作者:[Paul W. Frields][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/author/pfrields/ -[1]: http://phodd.net/gnu-bc/ diff --git a/translated/tech/20160715 bc - Command line calculator.md b/translated/tech/20160715 bc - Command line calculator.md new file mode 100644 index 0000000000..d5dc711909 --- /dev/null +++ b/translated/tech/20160715 bc - Command line calculator.md @@ -0,0 +1,129 @@ +bc : 一个命令行计算器 +============================ + +![](https://cdn.fedoramagazine.org/wp-content/uploads/2016/07/bc-calculator-945x400.jpg) + +假如你运行在一个图形桌面环境中,当你需要一个计算器时,你可能只需要一路进行点击便可以找到一个计算器。例如,Fedora 工作站中就已经包含了一个名为 `Calculator` 的工具。它有着几种不同的操作模式,例如,你可以进行复杂的数学运算或者金融运算。但是,你知道吗,命令行也提供了一个与之相似的名为 `bc` 的工具? + +`bc` 工具可以为你提供你期望一个科学计算器、金融计算器或者是简单的计算器所能提供的所有功能。另外,假如需要的话,它还可以从命令行中被脚本化。这使得当你需要做复杂的数学运算时,你可以在 shell 脚本中使用它。 + +因为 bc 被其他的系统软件所使用,例如 CUPS 打印服务,它可能已经在你的 Fedora 系统中被安装了。你可以使用下面这个命令来进行检查: + +``` +dnf list installed bc +``` + +假如因为某些原因你没有在上面命令的输出中看到它,你可以使用下面的这个命令来安装它: + +``` +sudo dnf install bc +``` + +### 用 bc 做一些简单的数学运算 + +使用 bc 的一种方式是进入它自己的 shell。在那里你可以在一行中做许多次计算。但在你键入 bc 后,首先出现的是有关这个程序的警告: + +``` +$ bc +bc 1.06.95 +Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006 Free Software Foundation, Inc. +This is free software with ABSOLUTELY NO WARRANTY. +For details type `warranty'. +``` + +现在你可以按照每行一个输入运算式或者命令了: + +``` +1+1 +``` + +bc 会回答上面计算式的答案是: + +``` +2 +``` + +在这里你还可以执行其他的命令。你可以使用 加(+)、减(-)、乘(*)、除(/)、圆括号、指数符号(^) 等等。请注意 bc 同样也遵循所有约定俗成的运算规定,例如运算的先后顺序。你可以试试下面的例子: + +``` +(4+7)*2 +4+7*2 +``` + +若要离开 bc 可以通过按键组合 `Ctrl+D` 来发送 “输入结束”信号给 bc 。 + +使用 bc 的另一种方式是使用 `echo` 命令来传递运算式或命令。下面这个示例类似于计算器中的 "Hello, world" 例子,使用 shell 的管道函数(|) 来将 `echo` 的输出传入 `bc` 中: + +``` +echo '1+1' | bc +``` + +使用 shell 的管道,你可以发送不止一个运算操作,你需要使用分号来分隔不同的运算。结果将在不同的行中返回。 + +``` +echo '1+1; 2+2' | bc +``` + +### 精度 + +在某些计算中,bc 会使用精度的概念,即小数点后面的数字位数。默认的精度是 0。除法操作总是使用精度的设定。所以,如果你没有设置精度,有可能会带来意想不到的答案: + +``` +echo '3/2' | bc +echo 'scale=3; 3/2' | bc +``` + +乘法使用一个更复杂的精度选择机制: + +``` +echo '3*2' | bc +echo '3*2.0' | bc +``` + +同时,加法和减法的相关运算则与之相似: + +``` +echo '7-4.15' | bc +``` + +### 其他进制系统 + +bc 的另一个有用的功能是可以使用除 十进制以外的其他计数系统。例如,你可以轻松地做十六进制或二进制的数学运算。可以使用 `ibase` 和 `obase` 命令来分别设定输入和输出的进制系统。需要记住的是一旦你使用了 `ibase`,之后你输入的任何数字都将被认为是在新定义的进制系统中。 + +要做十六进制数到十进制数的转换或运算,你可以使用类似下面的命令。请注意大于 9 的十六进制数必须是大写的(A-F): + +``` +echo 'ibase=16; A42F' | bc +echo 'ibase=16; 5F72+C39B' | bc +``` + +若要使得结果是十六进制数,则需要设定 `obase` : + +``` +echo 'obase=16; ibase=16; 5F72+C39B' | bc +``` + +下面是一个小技巧。假如你在 shell 中做这些运算,怎样才能使得输入重新为十进制数呢?答案是使用 `ibase` 命令,但你必须设定它为在当前进制中与十进制中的 10 等价的值。例如,假如 `ibase` 被设定为十六进制,你需要输入: + +``` +ibase=A +``` + +一旦你执行了上面的命令,所有输入的数字都将是十进制的了,接着你便可以输入 `obase=10` 来重置输出的进制系统。 + +### 结论 + +上面所提到的只是 bc 所能做到的基础。它还允许你为某些复杂的运算和程序定义函数、变量和循环结构。你可以在你的系统中将这些程序保存为文本文件以便你在需要的时候使用。你还可以在网上找到更多的资源,它们提供了更多的例子以及额外的函数库。快乐地计算吧! + +-------------------------------------------------------------------------------- + +via: http://www.tecmint.com/mandatory-access-control-with-selinux-or-apparmor-linux/ + +作者:[Paul W. Frields][a] +译者:[FSSlc](https://github.com/FSSlc) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]: https://fedoramagazine.org/author/pfrields/ +[1]: http://phodd.net/gnu-bc/ From a49a41f4118638a4b0e60ca491691aa577c8adf5 Mon Sep 17 00:00:00 2001 From: cposture Date: Tue, 2 Aug 2016 13:35:33 +0800 Subject: [PATCH 113/122] Translating by cposture --- ...lding a data science portfolio - Machine learning project.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sources/team_test/part 6 - Building a data science portfolio - Machine learning project.md b/sources/team_test/part 6 - Building a data science portfolio - Machine learning project.md index 86ecbe127d..3bec1d0a98 100644 --- a/sources/team_test/part 6 - Building a data science portfolio - Machine learning project.md +++ b/sources/team_test/part 6 - Building a data science portfolio - Machine learning project.md @@ -1,4 +1,4 @@ - +Translating by cposture 2016-08-02 ### Making predictions Now that we have the preliminaries out of the way, we’re ready to make predictions. We’ll create a new file called predict.py that will use the train.csv file we created in the last step. The below code will: From 38e37b6e10377cb56045ae51075f2f53ba1e37b0 Mon Sep 17 00:00:00 2001 From: wxy Date: Tue, 2 Aug 2016 14:05:14 +0800 Subject: [PATCH 114/122] PUB:20160721 5 tricks for getting started with Vim MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @maywanting 翻译的不错,不过有个别语句我有不同理解,你可以看看,如有不同意见,欢迎讨论改进。 --- ...1 5 tricks for getting started with Vim.md | 60 +++++++++++++++++++ ...1 5 tricks for getting started with Vim.md | 60 ------------------- 2 files changed, 60 insertions(+), 60 deletions(-) create mode 100644 published/20160721 5 tricks for getting started with Vim.md delete mode 100644 translated/tech/20160721 5 tricks for getting started with Vim.md diff --git a/published/20160721 5 tricks for getting started with Vim.md b/published/20160721 5 tricks for getting started with Vim.md new file mode 100644 index 0000000000..684a1d6295 --- /dev/null +++ b/published/20160721 5 tricks for getting started with Vim.md @@ -0,0 +1,60 @@ +Vim 起步的五个技巧 +===================================== + +![](https://opensource.com/sites/default/files/styles/image-full-size/public/images/education/BUSINESS_peloton.png?itok=nuMbW9d3) + +多年来,我一直想学 Vim。如今 Vim 是我最喜欢的 Linux 文本编辑器,也是开发者和系统管理者最喜爱的开源工具。我说的学习,指的是真正意义上的学习。想要精通确实很难,所以我只想要达到熟练的水平。我使用了这么多年的 Linux ,我会的也仅仅只是打开一个文件,使用上下左右箭头按键来移动光标,切换到插入模式,更改一些文本,保存,然后退出。 + +但那只是 Vim 的最最基本的操作。我的技能水平只能让我在终端使用 Vim 修改文本,但是它并没有任何一个我想象中强大的文本处理功能。这样我完全无法用 Vim 发挥出胜出 Pico 和 Nano 的能力。 + +所以到底为什么要学习 Vim?因为我花费了相当多的时间用于编辑文本,而且我知道还有很大的效率提升空间。为什么不选择 Emacs,或者是更为现代化的编辑器例如 Atom?因为 Vim 适合我,至少我有一丁点的使用经验。而且,很重要的一点就是,在我需要处理的系统上很少碰见没有装 Vim 或者它的弱化版(Vi)。如果你有强烈的欲望想学习对你来说更给力的 Emacs,我希望这些对于 Emacs 同类编辑器的建议能对你有所帮助。 + +花了几周的时间专注提高我的 Vim 使用技巧之后,我想分享的第一个建议就是必须使用它。虽然这看起来就是明知故问的回答,但事实上它比我所预想的计划要困难一些。我的大多数工作是在网页浏览器上进行的,而且每次我需要在浏览器之外打开并编辑一段文本时,就需要避免下意识地打开 Gedit。Gedit 已经放在了我的快速启动栏中,所以第一步就是移除这个快捷方式,然后替换成 Vim 的。 + +为了更好的学习 Vim,我尝试了很多。如果你也正想学习,以下列举了一些作为推荐。 + +### Vimtutor + +通常如何开始学习最好就是使用应用本身。我找到一个小的应用叫 Vimtutor,当你在学习编辑一个文本时它能辅导你一些基础知识,它向我展示了很多我这些年都忽视的基础命令。Vimtutor 一般在有 Vim 的地方都能找到它,如果你的系统上没有 Vimtutor,Vimtutor 可以很容易从你的包管理器上安装。 + +### GVim + +我知道并不是每个人都认同这个,但就是它让我从使用终端中的 Vim 转战到使用 GVim 来满足我基本编辑需求。反对者表示 GVim 鼓励使用鼠标,而 Vim 主要是为键盘党设计的。但是我能通过 GVim 的下拉菜单快速找到想找的指令,并且 GVim 可以提醒我正确的指令然后通过敲键盘执行它。努力学习一个新的编辑器然后陷入无法解决的困境,这种感觉并不好受。每隔几分钟读一下 man 出来的文字或者使用搜索引擎来提醒你该用的按键序列也并不是最好的学习新事物的方法。 + +### 键盘表 + +当我转战 GVim,我发现有一个键盘的“速查表”来提醒我最基础的按键很是便利。网上有很多这种可用的表,你可以下载、打印,然后贴在你身边的某一处地方。但是为了我的笔记本键盘,我选择买一沓便签纸。这些便签纸在美国不到 10 美元,当我使用键盘编辑文本,尝试新的命令的时候,可以随时提醒我。 + +### Vimium + +上文提到,我工作都在浏览器上进行。其中一条我觉得很有帮助的建议就是,使用 [Vimium][1] 来用增强使用 Vim 的体验。Vimium 是 Chrome 浏览器上的一个开源插件,能用 Vim 的指令快捷操作 Chrome。我发现我只用了几次使用快捷键切换上下文,就好像比之前更熟悉这些快捷键了。同样的扩展 Firefox 上也有,例如 [Vimerator][2]。 + +### 其它人 + +毫无疑问,最好的学习方法就是求助于在你之前探索过的人,让他给你建议、反馈和解决方法。 + +如果你住在一个大城市,那么附近可能会有一个 Vim meetup 小组,或者还有 Freenode IRC 上的 #vim 频道。#vim 频道是 Freenode 上最活跃的频道之一,那上面可以针对你个人的问题来提供帮助。听上面的人发发牢骚或者看看别人尝试解决自己没有遇到过的问题,仅仅是这样我都觉得很有趣。 + +------ + +那么,现在怎么样了?到现在为止还不错。为它所花的时间是否值得就在于之后它为你节省了多少时间。但是当我发现一个新的按键序列可以来跳过词,或者一些相似的小技巧,我经常会收获意外的惊喜与快乐。每天我至少可以看见,一点点的回报,正在逐渐配得上当初的付出。 + +学习 Vim 并不仅仅只有这些建议,还有很多。我很喜欢指引别人去 [Vim Advantures][3],它是一种使用 Vim 按键方式进行移动的在线游戏。而在另外一天我在 [Vimgifts.com][4] 发现了一个非常神奇的虚拟学习工具,那可能就是你真正想要的:用一个小小的 gif 动图来描述 Vim 操作。 + +你有花时间学习 Vim 吗?或者是任何需要大量键盘操作的程序?那些经过你努力后掌握的工具,你认为这些努力值得吗?效率的提高有没有达到你的预期?分享你们的故事在下面的评论区吧。 + +-------------------------------------------------------------------------------- + +via: https://opensource.com/life/16/7/tips-getting-started-vim + +作者:[Jason Baker][a] +译者:[maywanting](https://github.com/maywanting) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]: https://opensource.com/users/jason-baker +[1]: https://github.com/philc/vimium +[2]: http://www.vimperator.org/ +[3]: http://vim-adventures.com/ +[4]: http://vimgifs.com/ diff --git a/translated/tech/20160721 5 tricks for getting started with Vim.md b/translated/tech/20160721 5 tricks for getting started with Vim.md deleted file mode 100644 index 67d64ced2f..0000000000 --- a/translated/tech/20160721 5 tricks for getting started with Vim.md +++ /dev/null @@ -1,60 +0,0 @@ -Vim 学习的 5 个技巧 -===================================== - -![](https://opensource.com/sites/default/files/styles/image-full-size/public/images/education/BUSINESS_peloton.png?itok=nuMbW9d3) - -多年来,我一直想学 Vim。如今 Vim 是我最喜欢的 Linux 文本编辑器,也是开发者和系统管理者最喜爱的开源工具。我说的学习,指的是真正意义上的学习。想要精通确实很难,所以我只想要达到熟练的水平。根据我多年使用 Linux 的经验,我会的也仅仅只是打开一个文件,使用上下左右箭头按键来移动光标,切换到 insert 模式,更改一些文本,保存,然后退出。 - -但那只是 Vim 的最基本操作。Vim 可以让我在终端修改文本,但是它并没有任何一个我想象中强大的文本处理功能。这样我无法说明 Vim 完全优于 Pico 和 Nano。 - -所以到底为什么要学习 Vim?因为我需要花费相当多的时间用于编辑文本,而且有很大的效率提升空间。为什么不选择 Emacs,或者是更为现代化的编辑器例如 Atom?因为 Vim 适合我,至少我有一丁点的使用经验。而且,很重要的一点就是,在我需要处理的系统上很少碰见没有装 Vim 或者它的简化版(Vi)。如果你有强烈的欲望想学习 Emacs,我希望这些对于 Emacs 同类编辑器的建议能对你有所帮助。 - -花了几周的时间专注提高我的 Vim 使用技巧之后,我想分享的第一个建议就是必须使用工具。虽然这看起来就是明知故问的回答,但事实上比我所想的在代码层面上还要困难。我的大多数工作是在网页浏览器上进行的,而且我每次都得有针对性的用 Gedit 打开并修改一段浏览器之外的文本。Gedit 需要快捷键来启动,所以第一步就是移出快捷键然后替换成 Vim 的快捷键。 - -为了跟更好的学习 Vim,我尝试了很多。如果你也正想学习,以下列举了一些作为推荐。 - -### Vimtutor - -通常如何开始学习最好就是使用应用本身。我找到一个小的应用叫 Vimtutor,当你在学习编辑一个文本时它能辅导你一些基础知识,它向我展示了很多我这些年都忽视的基础命令。Vimtutor 上到处都是 Vim 影子,如果你的系统上没有 Vimtutor,Vimtutor可以很容易从你的包管理器上下载。 - -### GVim - -我知道并不是每个人都认同这个,但就是它让我从使用在终端的 Vim 转战到使用 GVim 来满足我基本编辑需求。反对者表示 GVim 鼓励使用鼠标,而 Vim 主要是为键盘党设计的。但是我能通过 GVim 的下拉菜单快速找到想找的指令,并且 GVim 可以提醒我正确的指令然后通过敲键盘执行它。努力学习一个新的编辑器然后陷入无法解决的困境,这种感觉并不好受。每隔几分钟读一下 man 出来的文字或者使用搜索引擎来提醒你指令也并不是最好的学习新事务的方法。 - -### Keyboard maps - -当我转战 GVim,我发现有一个键盘的“作弊表”来提醒我最基础的按键很是便利。网上有很多这种可用的表,你可以下载,打印,然后贴在你身边的某一处地方。但是为了我的笔记本键盘,我选择买一沓便签纸。这些便签纸在美国不到10美元,而且当我使用键盘编辑文本尝试新的命令的时候,可以随时提醒我。 - -### Vimium - -上文提到,我工作都在浏览器上进行。其中一条我觉得很有帮助的建议就是,使用 [Vimium][1] 来用增强使用 Vim 的体验。Vimium 是 Chrome 浏览器上的一个开源插件,能用 Vim 的指令快捷操作 Chrome。当我有意识的使用快捷键切换文本的次数越少时,这说明我越来越多的使用这些快捷键。同样的扩展 Firefox 上也有,例如 [Vimerator][2]。 - -### 人 - -毫无疑问,最好的学习方法就是求助于在你之前探索过的人,让他给你建议、反馈和解决方法。 - -如果你住在一个大城市,那么附近可能会有一个 Vim meetup 组,不然就是在 Freenode IRC 上的 #vim 频道。#vim 频道是 Freenode 上最活跃的频道之一,那上面可以针对你个人的问题来提供帮助。听上面的人发发牢骚或者看看别人尝试解决自己没有遇到过的问题,仅仅是这样我都觉得很有趣。 - ------- - -所以是什么成就了现在?如今便是极好。为它所花的时间是否值得就在于之后它为你节省了多少时间。但是我经常收到意外的惊喜与快乐,当我发现一个新的按键指令来复制、跳过词,或者一些相似的小技巧。每天我至少可以看见,一点点回报,正在逐渐配得上当初的付出。 - -学习 Vim 并不仅仅只有这些建议,还有很多。我很喜欢指引别人去 [Vim Advantures][3],它是一种只能使用 Vim 的快捷键的在线游戏。而且某天我发现了一个非常神奇的虚拟学习工具,在 [Vimgifts.com][4],那上面有明确的你想要的:用一个 gif 动图来描述,使用一点点 Vim 操作来达到他们想要的。 - -你有花时间学习 Vim 吗?或者有大量键盘操作交互体验的程序上投资时间吗?那些经过你努力后掌握的工具,你认为这些努力值得吗?效率的提高有达到你的预期?分享你们的故事在下面的评论区吧。 - --------------------------------------------------------------------------------- - -via: https://opensource.com/life/16/7/tips-getting-started-vim - -作者:[Jason Baker ][a] -译者:[maywanting](https://github.com/maywanting) -校对:[校对者ID](https://github.com/校对者ID) - -本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 - -[a]: https://opensource.com/users/jason-baker -[1]: https://github.com/philc/vimium -[2]: http://www.vimperator.org/ -[3]: http://vim-adventures.com/ -[4]: http://vimgifs.com/ From d4e82db38c29b847f19e2b9118e5ee8a49311780 Mon Sep 17 00:00:00 2001 From: WEIYUE XIE Date: Tue, 2 Aug 2016 19:15:14 +0800 Subject: [PATCH 115/122] =?UTF-8?q?Update=20and=20rename=20part=202=20-=20?= =?UTF-8?q?Building=20a=20data=20science=20portfolio=20-=20Machine=20learn?= =?UTF-8?q?ing=20project.md=20to=20=E7=BF=BB=E8=AF=91=E4=B8=AD=20ideas4u?= =?UTF-8?q?=20part=202=20-=20Building=20a=20data=20science=20portfolio=20-?= =?UTF-8?q?=20Machine=20learning=20project.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ideas4u 翻译中 --- ...data science portfolio - Machine learning project.md} | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) rename sources/team_test/{part 2 - Building a data science portfolio - Machine learning project.md => 翻译中 ideas4u part 2 - Building a data science portfolio - Machine learning project.md} (91%) diff --git a/sources/team_test/part 2 - Building a data science portfolio - Machine learning project.md b/sources/team_test/翻译中 ideas4u part 2 - Building a data science portfolio - Machine learning project.md similarity index 91% rename from sources/team_test/part 2 - Building a data science portfolio - Machine learning project.md rename to sources/team_test/翻译中 ideas4u part 2 - Building a data science portfolio - Machine learning project.md index 2b429aaab8..4a4fe73553 100644 --- a/sources/team_test/part 2 - Building a data science portfolio - Machine learning project.md +++ b/sources/team_test/翻译中 ideas4u part 2 - Building a data science portfolio - Machine learning project.md @@ -1,7 +1,7 @@ -### Understanding the data +### 理解数据 Let’s take a quick look at the raw data files. Here are the first few rows of the acquisition data from quarter 1 of 2012: - +让我们来简单看一下原始数据文件。下面是2012年1季度采集数据的前几行。 ``` 100000853384|R|OTHER|4.625|280000|360|02/2012|04/2012|31|31|1|23|801|N|C|SF|1|I|CA|945||FRM| 100003735682|R|SUNTRUST MORTGAGE INC.|3.99|466000|360|01/2012|03/2012|80|80|2|30|794|N|P|SF|1|P|MD|208||FRM|788 @@ -10,6 +10,7 @@ Let’s take a quick look at the raw data files. Here are the first few rows of Here are the first few rows of the performance data from quarter 1 of 2012: +下面是2012年1季度执行数据的前几行 ``` 100000853384|03/01/2012|OTHER|4.625||0|360|359|03/2042|41860|0|N|||||||||||||||| 100000853384|04/01/2012||4.625||1|359|358|03/2042|41860|0|N|||||||||||||||| @@ -17,10 +18,14 @@ Here are the first few rows of the performance data from quarter 1 of 2012: ``` Before proceeding too far into coding, it’s useful to take some time and really understand the data. This is more critical in operational projects – because we aren’t interactively exploring the data, it can be harder to spot certain nuances unless we find them upfront. In this case, the first step is to read the materials on the Fannie Mae site: - +在开始编码之前,花些时间真正理解数据是值得的。这对于操作项目优为重要,因为我们没有交互式探索数据,将很难察觉到细微的差别除非我们在前期发现他们。在这种情况下,第一个步骤是阅读房利美站点的资料: - [Overview][15] +- [概述][15] - [Glossary of useful terms][16] +- [用用的术语表][16] - [FAQs][17] +- [问答][17] +- [Columns in the Acquisition and Performance files][18] - [Columns in the Acquisition and Performance files][18] - [Sample Acquisition data file][19] - [Sample Performance data file][20] From 4110b9b4fa4f9753a42de5723cc832d0fa67d79a Mon Sep 17 00:00:00 2001 From: WEIYUE XIE Date: Tue, 2 Aug 2016 20:30:46 +0800 Subject: [PATCH 116/122] =?UTF-8?q?Update=20=E7=BF=BB=E8=AF=91=E4=B8=AD=20?= =?UTF-8?q?ideas4u=20part=202=20-=20Building=20a=20data=20science=20portfo?= =?UTF-8?q?lio=20-=20Machine=20learning=20project.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 翻译2 --- ...ience portfolio - Machine learning project.md | 47 ++++++++----------- 1 file changed, 20 insertions(+), 27 deletions(-) diff --git a/sources/team_test/翻译中 ideas4u part 2 - Building a data science portfolio - Machine learning project.md b/sources/team_test/翻译中 ideas4u part 2 - Building a data science portfolio - Machine learning project.md index 4a4fe73553..27c7604922 100644 --- a/sources/team_test/翻译中 ideas4u part 2 - Building a data science portfolio - Machine learning project.md +++ b/sources/team_test/翻译中 ideas4u part 2 - Building a data science portfolio - Machine learning project.md @@ -1,54 +1,47 @@ ### 理解数据 -Let’s take a quick look at the raw data files. Here are the first few rows of the acquisition data from quarter 1 of 2012: -让我们来简单看一下原始数据文件。下面是2012年1季度采集数据的前几行。 +我们来简单看一下原始数据文件。下面是2012年1季度前几行的采集数据。 ``` 100000853384|R|OTHER|4.625|280000|360|02/2012|04/2012|31|31|1|23|801|N|C|SF|1|I|CA|945||FRM| 100003735682|R|SUNTRUST MORTGAGE INC.|3.99|466000|360|01/2012|03/2012|80|80|2|30|794|N|P|SF|1|P|MD|208||FRM|788 100006367485|C|PHH MORTGAGE CORPORATION|4|229000|360|02/2012|04/2012|67|67|2|36|802|N|R|SF|1|P|CA|959||FRM|794 ``` -Here are the first few rows of the performance data from quarter 1 of 2012: - -下面是2012年1季度执行数据的前几行 +下面是2012年1季度的前几行执行数据 ``` 100000853384|03/01/2012|OTHER|4.625||0|360|359|03/2042|41860|0|N|||||||||||||||| 100000853384|04/01/2012||4.625||1|359|358|03/2042|41860|0|N|||||||||||||||| 100000853384|05/01/2012||4.625||2|358|357|03/2042|41860|0|N|||||||||||||||| ``` - -Before proceeding too far into coding, it’s useful to take some time and really understand the data. This is more critical in operational projects – because we aren’t interactively exploring the data, it can be harder to spot certain nuances unless we find them upfront. In this case, the first step is to read the materials on the Fannie Mae site: 在开始编码之前,花些时间真正理解数据是值得的。这对于操作项目优为重要,因为我们没有交互式探索数据,将很难察觉到细微的差别除非我们在前期发现他们。在这种情况下,第一个步骤是阅读房利美站点的资料: -- [Overview][15] - [概述][15] -- [Glossary of useful terms][16] -- [用用的术语表][16] -- [FAQs][17] +- [有用的术语表][16] - [问答][17] -- [Columns in the Acquisition and Performance files][18] -- [Columns in the Acquisition and Performance files][18] -- [Sample Acquisition data file][19] -- [Sample Performance data file][20] - -After reading through these files, we know some key facts that will help us: - -- There’s an Acquisition file and a Performance file for each quarter, starting from the year 2000 to present. There’s a 1 year lag in the data, so the most recent data is from 2015 as of this writing. -- The files are in text format, with a pipe (|) as a delimiter. -- The files don’t have headers, but we have a list of what each column is. -- All together, the files contain data on 22 million loans. -- Because the Performance files contain information on loans acquired in previous years, there will be more performance data for loans acquired in earlier years (ie loans acquired in 2014 won’t have much performance history). - -These small bits of information will save us a ton of time as we figure out how to structure our project and work with the data. +- [采集和执行文件中的列][18] +- [采集数据文件样本][19] +- [执行数据文件样本][20] +在看完这些文件后后,我们了解到一些能帮助我们的关键点: +- 从2000年到现在,每季度都有一个采集和执行文件,因数据是滞后一年的,所以到目前为止最新数据是2015年的。 +- 这些文件是文本格式的,采用管道符号“|”进行分割。 +- 这些文件是没有表头的,但我们有文件各列的名称。 +- 所有一起,文件包含2200万个贷款的数据。 +由于执行文件包含过去几年获得的贷款的信息,在早些年获得的贷款将有更多的执行数据(即在2014获得的贷款没有多少历史执行数据)。 +这些小小的信息将会为我们节省很多时间,因为我们知道如何构造我们的项目和利用这些数据。 ### Structuring the project - +### 构造项目 Before we start downloading and exploring the data, it’s important to think about how we’ll structure the project. When building an end-to-end project, our primary goals are: - +在我们开始下载和探索数据之前,先想一想将如何构造项目是很重要的。当建立端到端项目时,我们的主要目标是: - Creating a solution that works +- 创建一个可行解决方案 - Having a solution that runs quickly and uses minimal resources +- 有一个快速运行且占用最小资源的解决方案 - Enabling others to easily extend our work +- 容易可扩展 - Making it easy for others to understand our code +- 容易理解的代码 - Writing as little code as possible +- 写尽量少的代码 In order to achieve these goals, we’ll need to structure our project well. A well structured project follows a few principles: From 2f0e2db40c5bde9e80db4e50433b0bce719d2485 Mon Sep 17 00:00:00 2001 From: WEIYUE XIE Date: Tue, 2 Aug 2016 21:09:04 +0800 Subject: [PATCH 117/122] =?UTF-8?q?Update=20=E7=BF=BB=E8=AF=91=E4=B8=AD=20?= =?UTF-8?q?ideas4u=20part=202=20-=20Building=20a=20data=20science=20portfo?= =?UTF-8?q?lio=20-=20Machine=20learning=20project.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 保存进度3 --- ...ience portfolio - Machine learning project.md | 31 ++++++++----------- 1 file changed, 13 insertions(+), 18 deletions(-) diff --git a/sources/team_test/翻译中 ideas4u part 2 - Building a data science portfolio - Machine learning project.md b/sources/team_test/翻译中 ideas4u part 2 - Building a data science portfolio - Machine learning project.md index 27c7604922..370a9853e5 100644 --- a/sources/team_test/翻译中 ideas4u part 2 - Building a data science portfolio - Machine learning project.md +++ b/sources/team_test/翻译中 ideas4u part 2 - Building a data science portfolio - Machine learning project.md @@ -28,33 +28,28 @@ - 所有一起,文件包含2200万个贷款的数据。 由于执行文件包含过去几年获得的贷款的信息,在早些年获得的贷款将有更多的执行数据(即在2014获得的贷款没有多少历史执行数据)。 这些小小的信息将会为我们节省很多时间,因为我们知道如何构造我们的项目和利用这些数据。 -### Structuring the project + ### 构造项目 -Before we start downloading and exploring the data, it’s important to think about how we’ll structure the project. When building an end-to-end project, our primary goals are: 在我们开始下载和探索数据之前,先想一想将如何构造项目是很重要的。当建立端到端项目时,我们的主要目标是: -- Creating a solution that works - 创建一个可行解决方案 -- Having a solution that runs quickly and uses minimal resources - 有一个快速运行且占用最小资源的解决方案 -- Enabling others to easily extend our work - 容易可扩展 -- Making it easy for others to understand our code -- 容易理解的代码 -- Writing as little code as possible +- 写容易理解的代码 - 写尽量少的代码 -In order to achieve these goals, we’ll need to structure our project well. A well structured project follows a few principles: - -- Separates data files and code files. -- Separates raw data from generated data. -- Has a README.md file that walks people through installing and using the project. -- Has a requirements.txt file that contains all the packages needed to run the project. -- Has a single settings.py file that contains any settings that are used in other files. - - For example, if you are reading the same file from multiple Python scripts, it’s useful to have them all import settings and get the file name from a centralized place. -- Has a .gitignore file that prevents large or secret files from being committed. -- Breaks each step in our task into a separate file that can be executed separately. +为了实现这些目标,需要对我们的项目进行良好的构造。一个结构良好的项目遵循几个原则: +- 分离数据文件和代码文件 +- 从原始数据中分离生成的数据。 +- 有一个README.md文件帮助人们安装和使用该项目。 +- 有一个requirements.txt文件列明项目运行所需的所有包。 +- 有一个单独的settings.py 文件列明其它文件中使用的所有的设置 + - 例如,如果从多个Python脚本读取相同的文件,把它们全部import设置和从一个集中的地方获得文件名是有用的。 +- 有一个.gitignore文件,防止大的或秘密文件被提交。 +- 分解任务中每一步可以单独执行的步骤到单独的文件中。 - For example, we may have one file for reading in the data, one for creating features, and one for making predictions. + - 例如, - Stores intermediate values. For example, one script may output a file that the next script can read. + - This enables us to make changes in our data processing flow without recalculating everything. Our file structure will look something like this shortly: From c430acb471201c8b9e02c69ced00267861a332a4 Mon Sep 17 00:00:00 2001 From: Noobfish Date: Tue, 2 Aug 2016 21:12:45 +0800 Subject: [PATCH 118/122] Translating by noobfish since 2016.08.02 --- ...ng a data science portfolio - Machine learning project.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/sources/team_test/part 1 - Building a data science portfolio - Machine learning project.md b/sources/team_test/part 1 - Building a data science portfolio - Machine learning project.md index 70d9b65f92..439be578ce 100644 --- a/sources/team_test/part 1 - Building a data science portfolio - Machine learning project.md +++ b/sources/team_test/part 1 - Building a data science portfolio - Machine learning project.md @@ -1,3 +1,8 @@ ++@noobfish translating since Aug 2nd,2016. ++ ++ + + >This is the third in a series of posts on how to build a Data Science Portfolio. If you like this and want to know when the next post in the series is released, you can [subscribe at the bottom of the page][1]. Data science companies are increasingly looking at portfolios when making hiring decisions. One of the reasons for this is that a portfolio is the best way to judge someone’s real-world skills. The good news for you is that a portfolio is entirely within your control. If you put some work in, you can make a great portfolio that companies are impressed by. From a088e129d23496de91278e9d53b9291b06b83c01 Mon Sep 17 00:00:00 2001 From: WEIYUE XIE Date: Tue, 2 Aug 2016 21:34:22 +0800 Subject: [PATCH 119/122] =?UTF-8?q?Update=20=E7=BF=BB=E8=AF=91=E4=B8=AD=20?= =?UTF-8?q?ideas4u=20part=202=20-=20Building=20a=20data=20science=20portfo?= =?UTF-8?q?lio=20-=20Machine=20learning=20project.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...a science portfolio - Machine learning project.md | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/sources/team_test/翻译中 ideas4u part 2 - Building a data science portfolio - Machine learning project.md b/sources/team_test/翻译中 ideas4u part 2 - Building a data science portfolio - Machine learning project.md index 370a9853e5..b311cd814d 100644 --- a/sources/team_test/翻译中 ideas4u part 2 - Building a data science portfolio - Machine learning project.md +++ b/sources/team_test/翻译中 ideas4u part 2 - Building a data science portfolio - Machine learning project.md @@ -24,7 +24,7 @@ 在看完这些文件后后,我们了解到一些能帮助我们的关键点: - 从2000年到现在,每季度都有一个采集和执行文件,因数据是滞后一年的,所以到目前为止最新数据是2015年的。 - 这些文件是文本格式的,采用管道符号“|”进行分割。 -- 这些文件是没有表头的,但我们有文件各列的名称。 +- 这些文件是没有表头的,但我们有文件列明各列的名称。 - 所有一起,文件包含2200万个贷款的数据。 由于执行文件包含过去几年获得的贷款的信息,在早些年获得的贷款将有更多的执行数据(即在2014获得的贷款没有多少历史执行数据)。 这些小小的信息将会为我们节省很多时间,因为我们知道如何构造我们的项目和利用这些数据。 @@ -46,13 +46,13 @@ - 例如,如果从多个Python脚本读取相同的文件,把它们全部import设置和从一个集中的地方获得文件名是有用的。 - 有一个.gitignore文件,防止大的或秘密文件被提交。 - 分解任务中每一步可以单独执行的步骤到单独的文件中。 - - For example, we may have one file for reading in the data, one for creating features, and one for making predictions. - - 例如, -- Stores intermediate values. For example, one script may output a file that the next script can read. + - 例如,我们将有一个文件用于读取数据,一个用于创建特征,一个用于做出预测。 +- 保存中间结果,例如,一个脚本可输出下一个脚本可读取的文件。 - - This enables us to make changes in our data processing flow without recalculating everything. + - 这使我们无需重新计算就可以在数据处理流程中进行更改。 + -Our file structure will look something like this shortly: +我们的文件结构大体如下: ``` loan-prediction @@ -64,8 +64,7 @@ loan-prediction ├── settings.py ``` -### Creating the initial files - +### 创建初始文件 To start with, we’ll need to create a loan-prediction folder. Inside that folder, we’ll need to make a data folder and a processed folder. The first will store our raw data, and the second will store any intermediate calculated values. Next, we’ll make a .gitignore file. A .gitignore file will make sure certain files are ignored by git and not pushed to Github. One good example of such a file is the .DS_Store file created by OSX in every folder. A good starting point for a .gitignore file is here. We’ll also want to ignore the data files because they are very large, and the Fannie Mae terms prevent us from redistributing them, so we should add two lines to the end of our file: From 108dde60df911aef8edc5c81906557c78d4f578c Mon Sep 17 00:00:00 2001 From: WEIYUE XIE Date: Tue, 2 Aug 2016 21:40:28 +0800 Subject: [PATCH 120/122] =?UTF-8?q?Update=20and=20rename=20=E7=BF=BB?= =?UTF-8?q?=E8=AF=91=E4=B8=AD=20ideas4u=20part=202=20-=20Building=20a=20da?= =?UTF-8?q?ta=20science=20portfolio=20-=20Machine=20learning=20project.md?= =?UTF-8?q?=20to=20part=202=20-=20Building=20a=20data=20science=20portfoli?= =?UTF-8?q?o=20-=20Machine=20learning=20project.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 占坑 --- ...Building a data science portfolio - Machine learning project.md} | 1 + 1 file changed, 1 insertion(+) rename sources/team_test/{翻译中 ideas4u part 2 - Building a data science portfolio - Machine learning project.md => part 2 - Building a data science portfolio - Machine learning project.md} (99%) diff --git a/sources/team_test/翻译中 ideas4u part 2 - Building a data science portfolio - Machine learning project.md b/sources/team_test/part 2 - Building a data science portfolio - Machine learning project.md similarity index 99% rename from sources/team_test/翻译中 ideas4u part 2 - Building a data science portfolio - Machine learning project.md rename to sources/team_test/part 2 - Building a data science portfolio - Machine learning project.md index b311cd814d..19e1fed3a7 100644 --- a/sources/team_test/翻译中 ideas4u part 2 - Building a data science portfolio - Machine learning project.md +++ b/sources/team_test/part 2 - Building a data science portfolio - Machine learning project.md @@ -1,4 +1,5 @@ +翻译中 by ideas4u ### 理解数据 我们来简单看一下原始数据文件。下面是2012年1季度前几行的采集数据。 ``` From 044fb2dbd56ca01617538d61abc4f37d842d2552 Mon Sep 17 00:00:00 2001 From: WEIYUE XIE Date: Tue, 2 Aug 2016 23:19:10 +0800 Subject: [PATCH 121/122] part 2 - Building a data science portfolio - Machine learning project.md (#4270) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Update part 2 - Building a data science portfolio - Machine learning project.md save changes 5 * Update part 2 - Building a data science portfolio - Machine learning project.md 初稿完成了。 --- ...ce portfolio - Machine learning project.md | 27 +++++++------------ 1 file changed, 9 insertions(+), 18 deletions(-) diff --git a/sources/team_test/part 2 - Building a data science portfolio - Machine learning project.md b/sources/team_test/part 2 - Building a data science portfolio - Machine learning project.md index 19e1fed3a7..ff979de34f 100644 --- a/sources/team_test/part 2 - Building a data science portfolio - Machine learning project.md +++ b/sources/team_test/part 2 - Building a data science portfolio - Machine learning project.md @@ -66,21 +66,16 @@ loan-prediction ``` ### 创建初始文件 -To start with, we’ll need to create a loan-prediction folder. Inside that folder, we’ll need to make a data folder and a processed folder. The first will store our raw data, and the second will store any intermediate calculated values. - -Next, we’ll make a .gitignore file. A .gitignore file will make sure certain files are ignored by git and not pushed to Github. One good example of such a file is the .DS_Store file created by OSX in every folder. A good starting point for a .gitignore file is here. We’ll also want to ignore the data files because they are very large, and the Fannie Mae terms prevent us from redistributing them, so we should add two lines to the end of our file: - +首先,我们需要创建一个loan-prediction文件夹,在此文件夹下面,再创建一个data文件夹和一个processed文件夹。data文件夹存放原始数据,processed文件夹存放所有的中间计算结果。 +其次,创建.gitignore文件,.gitignore文件将保证某些文件被git忽略而不会被推送至github。关于这个文件的一个好的例子是由OSX在每一个文件夹都会创建的.DS_Store文件,.gitignore文件一个很好的起点就是在这了。我们还想忽略数据文件因为他们实在是太大了,同时房利美的条文禁止我们重新分发该数据文件,所以我们应该在我们的文件后面添加以下2行: ``` data processed ``` -[Here’s][21] an example .gitignore file for this project. - -Next, we’ll need to create README.md, which will help people understand the project. .md indicates that the file is in markdown format. Markdown enables you write plain text, but also add some fancy formatting if you want. [Here’s][22] a guide on markdown. If you upload a file called README.md to Github, Github will automatically process the markdown, and show it to anyone who views the project. [Here’s][23] an example. - -For now, we just need to put a simple description in README.md: - +这是该项目的一个关于.gitignore文件的例子。 +再次,我们需要创建README.md文件,它将帮助人们理解该项目。后缀.md表示这个文件采用markdown格式。Markdown使你能够写纯文本文件,同时还可以添加你想要的梦幻格式。这是关于markdown的导引。如果你上传一个叫README.md的文件至Github,Github会自动处理该markdown,同时展示给浏览该项目的人。 +至此,我们仅需在README.md文件中添加简单的描述: ``` Loan Prediction ----------------------- @@ -88,8 +83,7 @@ Loan Prediction Predict whether or not loans acquired by Fannie Mae will go into foreclosure. Fannie Mae acquires loans from other lenders as a way of inducing them to lend more. Fannie Mae releases data on the loans it has acquired and their performance afterwards [here](http://www.fanniemae.com/portal/funding-the-market/data/loan-performance-data.html). ``` -Now, we can create a requirements.txt file. This will make it easy for other people to install our project. We don’t know exactly what libraries we’ll be using yet, but here’s a good starting point: - +现在,我们可以创建requirements.txt文件了。这会唯其它人可以很方便地安装我们的项目。我们还不知道我们将会具体用到哪些库,但是以下几个库是一个很好的开始: ``` pandas matplotlib @@ -99,9 +93,6 @@ ipython scipy ``` -The above libraries are the most commonly used for data analysis tasks in Python, and its fair to assume that we’ll be using most of them. [Here’s][24] an example requirements file for this project. - -After creating requirements.txt, you should install the packages. For this post, we’ll be using Python 3. If you don’t have Python installed, you should look into using [Anaconda][25], a Python installer that also installs all the packages listed above. - -Finally, we can just make a blank settings.py file, since we don’t have any settings for our project yet. - +以上几个是在python数据分析任务中最常用到的库。可以认为我们将会用到大部分这些库。这里是【24】该项目requirements文件的一个例子。 + 创建requirements.txt文件之后,你应该安装包了。我们将会使用python3.如果你没有安装python,你应该考虑使用 [Anaconda][25],一个python安装程序,同时安装了上面列出的所有包。 +最后,我们可以建立一个空白的settings.py文件,因为我们的项目还没有任何设置。 From 307cd103c0370581b85a869913f16b1963b6b3b6 Mon Sep 17 00:00:00 2001 From: kokialoves <498497353@qq.com> Date: Wed, 3 Aug 2016 09:58:43 +0800 Subject: [PATCH 122/122] =?UTF-8?q?=E7=BF=BB=E8=AF=91=E5=AE=8C=E6=88=90=20?= =?UTF-8?q?(#4271)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Delete part 5 - Building a data science portfolio - Machine learning project.md * Create part 5 - Building a data science portfolio - Machine learning project.md --- ...ce portfolio - Machine learning project.md | 106 +++++++++++------- 1 file changed, 63 insertions(+), 43 deletions(-) diff --git a/sources/team_test/part 5 - Building a data science portfolio - Machine learning project.md b/sources/team_test/part 5 - Building a data science portfolio - Machine learning project.md index 99e1046e70..a92bb01900 100644 --- a/sources/team_test/part 5 - Building a data science portfolio - Machine learning project.md +++ b/sources/team_test/part 5 - Building a data science portfolio - Machine learning project.md @@ -1,38 +1,44 @@ -注解数据 -我们已经在annotate.py中添加了一些功能, 现在我们来看一看数据文件. 我们需要将采集到的数据转换到training dataset来进行机器学习的训练. 这涉及到以下几件事情: -转换所以列数字. -填充缺失值. -分配 performance_count 和 foreclosure_status. -移除出现次数很少的行(performance_count 计数低). -我们有几个列是strings类型的, 看起来对于机器学习算法来说并不是很有用. 然而, 他们实际上是分类变量, 其中有很多不同的类别代码, 例如R,S等等. 我们可以把这些类别标签转换为数值: +### 注解数据 +我们已经在annotate.py中添加了一些功能, 现在我们来看一看数据文件. 我们需要将采集到的数据转换到训练数据表来进行机器学习的训练. 这涉及到以下几件事情: +- 转换所以列数字. +- 填充缺失值. +- 分配 performance_count 和 foreclosure_status. +- 移除出现次数很少的行(performance_count 计数低). + +我们有几个列是文本类型的, 看起来对于机器学习算法来说并不是很有用. 然而, 他们实际上是分类变量, 其中有很多不同的类别代码, 例如R,S等等. 我们可以把这些类别标签转换为数值: + +![](https://github.com/LCTT/wiki-images/blob/master/TranslateProject/ref_img/002.png) 通过这种方法转换的列我们可以应用到机器学习算法中. 还有一些包含日期的列 (first_payment_date 和 origination_date). 我们可以将这些日期放到两个列中: - 在下面的代码中, 我们将转换采集到的数据. 我们将定义一个函数如下: +![](https://github.com/LCTT/wiki-images/blob/master/TranslateProject/ref_img/003.png) +在下面的代码中, 我们将转换采集到的数据. 我们将定义一个函数如下: -在采集到的数据中创建foreclosure_status列 . -在采集到的数据中创建performance_count列. -将下面的string列转换为integer列: -channel -seller -first_time_homebuyer -loan_purpose -property_type -occupancy_status -property_state -product_type -转换first_payment_date 和 origination_date 为两列: -通过斜杠分离列. -将第一部分分离成月清单. -将第二部分分离成年清单. -删除这一列. -最后, 我们得到 first_payment_month, first_payment_year, origination_month, and origination_year. -所有缺失值填充为-1. +- 在采集到的数据中创建foreclosure_status列 . +- 在采集到的数据中创建performance_count列. +- 将下面的string列转换为integer列: + - channel + - seller + - first_time_homebuyer + - loan_purpose + - property_type + - occupancy_status + - property_state + - product_type +- 转换first_payment_date 和 origination_date 为两列: + - 通过斜杠分离列. + - 将第一部分分离成月清单. + - 将第二部分分离成年清单. + - 删除这一列. + - 最后, 我们得到 first_payment_month, first_payment_year, origination_month, and origination_year. +- 所有缺失值填充为-1. + +``` def annotate(acquisition, counts): acquisition["foreclosure_status"] = acquisition["id"].apply(lambda x: get_performance_summary_value(x, "foreclosure_status", counts)) acquisition["performance_count"] = acquisition["id"].apply(lambda x: get_performance_summary_value(x, "performance_count", counts)) @@ -57,21 +63,25 @@ def annotate(acquisition, counts): acquisition = acquisition.fillna(-1) acquisition = acquisition[acquisition["performance_count"] > settings.MINIMUM_TRACKING_QUARTERS] return acquisition +``` + +### 聚合到一起 -聚合到一起 我们差不多准备就绪了, 我们只需要再在annotate.py添加一点点代码. 在下面代码中, 我们将: -定义一个函数来读取采集的数据. -定义一个函数来写入数据到/train.csv -如果我们在命令行运行annotate.py来读取更新过的数据文件,它将做如下事情: -读取采集到的数据. -计算数据性能. -注解数据. -将注解数据写入到train.csv. +- 定义一个函数来读取采集的数据. +- 定义一个函数来写入数据到/train.csv +- 如果我们在命令行运行annotate.py来读取更新过的数据文件,它将做如下事情: + - 读取采集到的数据. + - 计算数据性能. + - 注解数据. + - 将注解数据写入到train.csv. + +``` def read(): acquisition = pd.read_csv(os.path.join(settings.PROCESSED_DIR, "Acquisition.txt"), sep="|") return acquisition - + def write(acquisition): acquisition.to_csv(os.path.join(settings.PROCESSED_DIR, "train.csv"), index=False) @@ -80,11 +90,13 @@ if __name__ == "__main__": counts = count_performance_rows() acquisition = annotate(acquisition, counts) write(acquisition) +``` 修改完成以后为了确保annotate.py能够生成train.csv文件. 你可以在这里找到完整的 annotate.py file [here][34]. 文件夹结果应该像这样: +``` loan-prediction ├── data │ ├── Acquisition_2012Q1.txt @@ -102,37 +114,45 @@ loan-prediction ├── README.md ├── requirements.txt ├── settings.py +``` -找到标准 -我们已经完成了training dataset的生成, 现在我们需要最后一步, 生成预测. 我们需要找到错误的标准, 以及该如何评估我们的数据. 在这种情况下, 因为有很多的贷款没有收回, 所以根本不可能做到精确的计算. +### 找到标准 + +我们已经完成了训练数据表的生成, 现在我们需要最后一步, 生成预测. 我们需要找到错误的标准, 以及该如何评估我们的数据. 在这种情况下, 因为有很多的贷款没有收回, 所以根本不可能做到精确的计算. 我们需要读取数据, 并且计算foreclosure_status列, 我们将得到如下信息: +``` import pandas as pd import settings train = pd.read_csv(os.path.join(settings.PROCESSED_DIR, "train.csv")) train["foreclosure_status"].value_counts() +``` +``` False 4635982 True 1585 Name: foreclosure_status, dtype: int64 +``` 因为只有一点点贷款收回, 通过百分比标签来建立的机器学习模型会把每行都设置为Fasle, 所以我们在这里要考虑每个样本的不平衡性,确保我们做出的预测是准确的. 我们不想要这么多假的false, 我们将预计贷款收回但是它并没有收回, 我们预计贷款不会回收但是却回收了. 通过以上两点, Fannie Mae的false太多了, 因此显示他们可能无法收回投资. 所以我们将定义一个百分比,就是模型预测没有收回但是实际上收回了, 这个数除以总的负债回收总数. 这个负债回收百分比模型实际上是“没有的”. 下面看这个图表: - +![](https://github.com/LCTT/wiki-images/blob/master/TranslateProject/ref_img/004.png) 通过上面的图表, 1个负债预计不会回收, 也确实没有回收. 如果我们将这个数除以总数, 2, 我们将得到false的概率为50%. 我们将使用这个标准, 因此我们可以评估一下模型的性能. -设置机器学习分类器 +### 设置机器学习分类器 + 我们使用交叉验证预测. 通过交叉验证法, 我们将数据分为3组. 按照下面的方法来做: -Train a model on groups 1 and 2, and use the model to make predictions for group 3. -Train a model on groups 1 and 3, and use the model to make predictions for group 2. -Train a model on groups 2 and 3, and use the model to make predictions for group 1. -将它们分割到不同的组 ,这意味着我们永远不会用相同的数据来为预测训练模型. 这样就避免了 overfitting. 如果我们overfit, 我们将得到很低的false概率, 这使得我们难以改进算法或者应用到现实生活中. +- Train a model on groups 1 and 2, and use the model to make predictions for group 3. +- Train a model on groups 1 and 3, and use the model to make predictions for group 2. +- Train a model on groups 2 and 3, and use the model to make predictions for group 1. + +将它们分割到不同的组 ,这意味着我们永远不会用相同的数据来为预测训练模型. 这样就避免了overfitting(过拟合). 如果我们overfit(过拟合), 我们将得到很低的false概率, 这使得我们难以改进算法或者应用到现实生活中. [Scikit-learn][35] 有一个叫做 [cross_val_predict][36] 他可以帮助我们理解交叉算法.