Merge remote-tracking branch 'LCTT/master'

This commit is contained in:
Xingyu Wang 2019-05-24 19:21:27 +08:00
commit fd9774c9b5
3 changed files with 225 additions and 241 deletions

View File

@ -1,51 +1,47 @@
[#]: collector: (lujun9972)
[#]: translator: (tomjlw)
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
[#]: reviewer: (wxy)
[#]: publisher: (wxy)
[#]: url: (https://linux.cn/article-10892-1.html)
[#]: subject: (Duc A Collection Of Tools To Inspect And Visualize Disk Usage)
[#]: via: (https://www.ostechnix.com/duc-a-collection-of-tools-to-inspect-and-visualize-disk-usage/)
[#]: author: (sk https://www.ostechnix.com/author/sk/)
Duc——一个能够洞察并可视化硬盘使用情况的工具包
Duc:一个能够可视化洞察硬盘使用情况的工具包
======
![Duc——一个能够洞察并可视化硬盘使用情况的工具包][1]
![Duc一个能够洞察并可视化硬盘使用情况的工具包][1]
**Duc** 是一个在类 Unix 操作系统上可以用来索引、洞察及可视化硬盘使用情况的工具包。别把它当成一个仅能用漂亮图表展现硬盘使用情况的 CLI 工具。它被设计成在巨大的文件系统上也可以延展得很好。Duc 已在由超过五亿个文件和几 PB 的存储组成的系统上测试过,没有任何问题。
Duc 是一个在类 Unix 操作系统上可以用来索引、洞察及可视化硬盘使用情况的工具包。别把它当成一个仅能用漂亮图表展现硬盘使用情况的 CLI 工具。它对巨大的文件系统也支持的很好。Duc 已在由超过五亿个文件和几 PB 的存储组成的系统上测试过,没有任何问题。
Duc 是一个快速而且多变的工具。它将你的硬盘使用情况存在一个优化过的数据库里,这样你就可以在索引完成后迅速找到你的数据。此外,它自带不同的用户交互界面与后端以访问数据库并绘制图表。
Duc 是一个快速而且灵活的工具。它将你的硬盘使用情况存在一个优化过的数据库里,这样你就可以在索引完成后迅速找到你的数据。此外,它自带不同的用户交互界面与后端以访问数据库并绘制图表。
以下列出的是目前支持的用户界面UI
1. 命令行界面 (ls),
2. Ncurses 控制台界面 (ui),
3. X11 GUI (duc gui),
4. OpenGL GUI (duc gui)。
1. 命令行界面(`duc ls`
2. Ncurses 控制台界面(`duc ui`
3. X11 GUI`duc gui`
4. OpenGL GUI`duc gui`
支持的后端数据库:
* Tokyocabinet,
* Leveldb,
* Sqlite3.
* Tokyocabinet
* Leveldb
* Sqlite3
Duc 使用 **Tokyocabinet** 作为默认的后端数据库。
Duc 默认使用 Tokyocabinet 作为后端数据库。
### 安装 Duc
Duc 可以从 Debian 以及其衍生品例如 Ubuntu 的默认仓库中获取。因此在基于 DEB 的系统上安装 Duc 小菜一碟。
Duc 可以从 Debian 以及其衍生品例如 Ubuntu 的默认仓库中获取。因此在基于 DEB 的系统上安装 Duc 小菜一碟。
```
$ sudo apt-get install duc
```
在其它 Linux 发行版上你需要像以下所展示的那样手动从源编译安装 Duc。
在其它 Linux 发行版上你需要像以下所展示的那样手动从源代码编译安装 Duc。
从 github 上的[**发行**][2]页面下载最新的 Duc 源 .tgz 文件。在写这篇教程的时候,最新的版本是**1.4.4**
可以从 Github 上的[发行][2]页面下载最新的 Duc 源代码的 .tgz 文件。在写这篇教程的时候最新的版本是1.4.4。
```
$ wget https://github.com/zevv/duc/releases/download/1.4.4/duc-1.4.4.tar.gz
@ -63,19 +59,19 @@ $ sudo make install
### 使用 Duc
duc 的典型用法是:
`duc` 的典型用法是:
```
$ duc <subcommand> <options>
```
你可以通过运行以下命令来浏览总的选项列表以及命令:
你可以通过运行以下命令来浏览总的选项列表以及命令:
```
$ duc help
```
你也可以像下面这样了解一个特定命令的用法。
你也可以像下面这样了解一个特定命令的用法。
```
$ duc help <subcommand>
@ -87,23 +83,23 @@ $ duc help <subcommand>
$ duc help --all
```
让我们看看一些 duc 工具的特定用法。
让我们看看一些 `duc` 工具的特定用法。
### 创建索引(数据库)
首先,你需要创建一个你文件系统的索引文件(数据库)。使用“duc index”命令以创建索引文件。
首先,你需要创建一个你文件系统的索引文件(数据库)。使用 `duc index` 命令以创建索引文件。
比如说,要创建你的 **/home** 目录的索引,仅需运行:
比如说,要创建你的 `/home` 目录的索引,仅需运行:
```
$ duc index /home
```
上述命令将会创建你的 /home/ 目录的索引并将其保存在 **$HOME/.duc.db** 文件中。如果你以后需要往 /home 目录添加新的文件/目录,只要在之后重新运行一下上面的命令来重建索引。
上述命令将会创建你的 `/home` 目录的索引,并将其保存在 `$HOME/.duc.db` 文件中。如果你以后需要往 `/home` 目录添加新的文件或目录,只要在之后重新运行一下上面的命令来重建索引。
### 查询索引
Duc 有不同的命令来查询并探索索引。
Duc 有不同的命令来查询并探索索引。
要查看可访问的索引列表,运行:
@ -111,14 +107,14 @@ Duc 有不同的副命令来查询并探索索引。
$ duc info
```
**示例输出:**
示例输出:
```
日期 时间 文件 目录 大小 路径
Date Time Files Dirs Size Path
2019-04-09 15:45:55 3.5K 305 654.6M /home
```
如你在上述输出所见,我已经索引好了 /home 目录。
如你在上述输出所见,我已经索引好了 `/home` 目录。
要列出当前工作目录中所有的文件和目录,你可以这样做:
@ -126,27 +122,27 @@ $ duc info
$ duc ls
```
要列出所提供目录例如 **/home/sk/Downloads** 中的文件/目录,仅需像下面这样将路径作为参数传过去。
要列出指定的目录,例如 `/home/sk/Downloads` 中的文件/目录,仅需像下面这样将路径作为参数传过去。
```
$ duc ls /home/sk/Downloads
```
类似的,运行**“duc ui”**命令来打开基于 **ncurses** 的控制台用户界面以探索文件系统使用情况,运行**“duc gui”**以打开 **graphical (X11)** 界面来探索文件系统。
类似的,运行 `duc ui` 命令来打开基于 ncurses 的控制台用户界面以探索文件系统使用情况,运行`duc gui` 以打开图形界面X11来探索文件系统。
要了解更多命令的用法,仅需参考帮助部分。
要了解更多命令的用法,仅需参考帮助部分。
```
$ duc help ls
```
上述命令将会展现 “ls” 副命令的帮助部分。
上述命令将会展现 `ls`命令的帮助部分。
### 可视化硬盘使用状况
在之前的部分我们以及看到如何用 duc 命令列出文件和目录。在此之外,你甚至可以用一张漂亮的图表展示文件大小。
在之前的部分我们以及看到如何用 duc 命令列出文件和目录。在此之外,你甚至可以用一张漂亮的图表展示文件大小。
要展示所提供目录的图表,像以下这样使用“ls”副命令。
要展示所提供目录的图表,像以下这样使用 `ls`命令。
```
$ duc ls -Fg /home/sk
@ -156,13 +152,13 @@ $ duc ls -Fg /home/sk
![使用 “duc ls” 命令可视化硬盘使用情况][3]
如你在上述输出所见,“ls”副命令查询 duc 数据库并列出了所提供目录,在这里就是 **/home/sk/**,所包含的文件与目录的大小
如你在上述输出所见,`ls` 子命令查询 duc 数据库并列出了所提供目录包含的文件与目录的大小,在这里就是 `/home/sk/`
这里 **-F** 选项是往条目中用来添加文件类型显示(*/之一),**-g** 选项是用来绘制每个条目相对大小的图表。
这里 `-F` 选项是往条目中用来添加文件类型指示符(`/``-g` 选项是用来绘制每个条目相对大小的图表。
请注意如果未提供任何路径,当前工作目录就会被探索
请注意如果未提供任何路径,就会使用当前工作目录。
你可以使用 **-R** 选项来用[**树状结构**][4]浏览硬盘使用情况。
你可以使用 `-R` 选项来用[树状结构][4]浏览硬盘使用情况。
```
$ duc ls -R /home/sk
@ -170,7 +166,7 @@ $ duc ls -R /home/sk
![用树状结构可视化硬盘使用情况][5]
要查询 duc 数据库并打开基于 **ncurses** 的控制台以探索所提供的目录,像以下这样使用**“ui”**副命令。
要查询 duc 数据库并打开基于 ncurses 的控制台以探索所提供的目录,像以下这样使用 `ui`命令。
```
$ duc ui /home/sk
@ -178,7 +174,7 @@ $ duc ui /home/sk
![][6]
类似的,我们使用**“gui”* 副命令来查询 duc 数据库以及打开一个 **graphical (X11)** 界面来探索提供路径的硬盘使用情况。
类似的,我们使用 `gui *` 子命令来查询 duc 数据库以及打开一个图形界面X11来了解指定路径的硬盘使用情况。
```
$ duc gui /home/sk
@ -186,47 +182,38 @@ $ duc gui /home/sk
![][7]
像我之前所提到的,我们可以像下面这样了解更多关于特定命令的用法。
像我之前所提到的,我们可以像下面这样了解更多关于特定命令的用法。
```
$ duc help <命令名字>
$ duc help <命令名字>
```
我仅仅覆盖了基本用法的部分,参考 man 页面了解关于“duc”工具的更多细节。
我仅仅覆盖了基本用法的部分,参考 man 页面了解关于 `duc` 工具的更多细节。
```
$ man duc
```
* * *
相关阅读:
**相关阅读:**
* [**Filelight 在你的 Linux 系统上可视化硬盘使用情况**][8]
* [**一些好的du命令的替代品**][9]
* [**如何在 Linux 中用 Ncdu 检查硬盘使用情况**][10]
* [**Agedu——发现 Linux 中被浪费的硬盘空间**][11]
* [**如何在 Linux 中找到目录大小**][12]
* [**为初学者打造的带有示例的 df 命令教程**][13]
* * *
* [Filelight 在你的 Linux 系统上可视化硬盘使用情况][8]
* [一些好的 du 命令的替代品][9]
* [如何在 Linux 中用 Ncdu 检查硬盘使用情况][10]
* [Agedu——发现 Linux 中被浪费的硬盘空间][11]
* [如何在 Linux 中找到目录大小][12]
* [为初学者打造的带有示例的 df 命令教程][13]
### 总结
Duc 是一款简单却有用的硬盘使用查看器。如果你想要快速简便地知道哪个文件/目录占用你的硬盘空间Duc 可能是一个好的选择。你还等什么呢?获取这个工具,扫描你的文件系统,摆脱无用的文件/目录。
Duc 是一款简单却有用的硬盘用量查看器。如果你想要快速简便地知道哪个文件/目录占用你的硬盘空间Duc 可能是一个好的选择。你还等什么呢?获取这个工具,扫描你的文件系统,摆脱无用的文件/目录。
现在就到此为止了。希望这篇文章有用处。更多好东西马上就到。保持关注!
欢呼吧!
**资源:**
* [**Duc 网站**][14]
资源:
* [Duc 网站][14]
--------------------------------------------------------------------------------
@ -235,7 +222,7 @@ via: https://www.ostechnix.com/duc-a-collection-of-tools-to-inspect-and-visualiz
作者:[sk][a]
选题:[lujun9972][b]
译者:[tomjlw](https://github.com/tomjlw)
校对:[校对者ID](https://github.com/校对者ID)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出

View File

@ -1,173 +0,0 @@
Translating by MjSeven
The Easiest PDO Tutorial (Basics)
======
![](http://www.theitstuff.com/wp-content/uploads/2018/04/php-language.jpg)
Approximately 80% of the web is powered by PHP. And similarly, high number goes for SQL as well. Up until PHP version 5.5, we had the **mysql_** commands for accessing mysql databases but they were eventually deprecated due to insufficient security.
This happened with PHP 5.5 in 2013 and as I write this article, the year is 2018 and we are on PHP 7.2. The deprecation of mysql**_** brought 2 major ways of accessing the database, the **mysqli** and the **PDO** libraries.
Now though the mysqli library was the official successor, PDO gained more fame due to a simple reason that mysqli could only support mysql databases whereas PDO could support 12 different types of database drivers. Also, PDO had several more features that made it the better choice for most developers. You can see some of the feature comparisons in the table below;
| | PDO | MySQLi |
| Database support** | 12 drivers | Only MySQL |
| Paradigm | OOP | Procedural + OOP |
| Prepared Statements Client Side) | Yes | No |
| Named Parameters | Yes | No |
Now I guess it is pretty clear why PDO is the choice for most developers, so lets dig into it and hopefully we will try to cover most of the PDO you need in this article itself.
### Connection
The first step is connecting to the database and since PDO is completely Object Oriented, we will be using the instance of a PDO class.
The first thing we do is we define the host, database name, user, password and the database charset.
`$host = 'localhost';`
`$db = 'theitstuff';`
`$user = 'root';`
`$pass = 'root';`
`$charset = 'utf8mb4';`
`$dsn = "mysql:host=$host;dbname=$db;charset=$charset";`
`$conn = new PDO($dsn, $user, $pass);`
After that, as you can see in the code above we have created the **DSN** variable, the DSN variable is simply a variable that holds the information about the database. For some people running mysql on external servers, you could also adjust your port number by simply supplying a **port=$port_number**.
Finally, you can create an instance of the PDO class, I have used the **$conn** variable and I have supplied the **$dsn, $user, $pass** parameters. If you have followed this, you should now have an object named $conn that is an instance of the PDO connection class. Now its time to get into the database and run some queries.
### A simple SQL Query
Let us now run a simple SQL query.
`$tis = $conn->query('SELECT name, age FROM students');`
`while ($row = $tis->fetch())`
`{`
`echo $row['name']."\t";`
`echo $row['age'];`
`echo "<br>";`
`}`
This is the simplest form of running a query with PDO. We first created a variable called **tis( **short for TheITStuff** )** and then you can see the syntax as we used the query function from the $conn object that we had created.
We then ran a while loop and created a **$row** variable to fetch the contents from the **$tis** object and finally echoed out each row by calling out the column name.
Easy wasnt it ?. Now lets get to the prepared statement.
### Prepared Statements
Prepared statements were one of the major reasons people started using PDO as it had prepared statements that could prevent SQL injections.
There are 2 basic methods available, you could either use positional or named parameters.
#### Position parameters
Let us see an example of a query using positional parameters.
`$tis = $conn->prepare("INSERT INTO STUDENTS(name, age) values(?, ?)");`
`$tis->bindValue(1,'mike');`
`$tis->bindValue(2,22);`
`$tis->execute();`
In the above example, we have placed 2 question marks and later used the **bindValue()** function to map the values into the query. The values are bound to the position of the question mark in the statement.
I could also use variables instead of directly supplying values by using the **bindParam()** function and example for the same would be this.
`$name='Rishabh'; $age=20;`
`$tis = $conn->prepare("INSERT INTO STUDENTS(name, age) values(?, ?)");`
`$tis->bindParam(1,$name);`
`$tis->bindParam(2,$age);`
`$tis->execute();`
### Named Parameters
Named parameters are also prepared statements that map values/variables to a named position in the query. Since there is no positional binding, it is very efficient in queries that use the same variable multiple time.
`$name='Rishabh'; $age=20;`
`$tis = $conn->prepare("INSERT INTO STUDENTS(name, age) values(:name, :age)");`
`$tis->bindParam(':name', $name);`
`$tis->bindParam(':age', $age);`
`$tis->execute();`
The only change you can notice is that I used **:name** and **:age** as placeholders and then mapped variables to them. The colon is used before the parameter and it is of extreme importance to let PDO know that the position is for a variable.
You can similarly use **bindValue()** to directly map values using Named parameters as well.
### Fetching the Data
PDO is very rich when it comes to fetching data and it actually offers a number of formats in which you can get the data from your database.
You can use the **PDO::FETCH_ASSOC** to fetch associative arrays, **PDO::FETCH_NUM** to fetch numeric arrays and **PDO::FETCH_OBJ** to fetch object arrays.
`$tis = $conn->prepare("SELECT * FROM STUDENTS");`
`$tis->execute();`
`$result = $tis->fetchAll(PDO::FETCH_ASSOC);`
You can see that I have used **fetchAll** since I wanted all matching records. If only one row is expected or desired, you can simply use **fetch.**
Now that we have fetched the data it is time to loop through it and that is extremely easy.
`foreach($result as $lnu){`
`echo $lnu['name'];`
`echo $lnu['age']."<br>";`
`}`
You can see that since I had requested associative arrays, I am accessing individual members by their names.
Though there is absolutely no problem in defining how you want your data delivered, you could actually set one as default when defining the connection variable itself.
All you need to do is create an options array where you put in all your default configs and simply pass the array in the connection variable.
`$options = [`
` PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,`
`];`
`$conn = new PDO($dsn, $user, $pass, $options);`
This was a very brief and quick intro to PDO we will be making an advanced tutorial soon. If you had any difficulties understanding any part of the tutorial, do let me know in the comment section and Ill be there for you.
--------------------------------------------------------------------------------
via: http://www.theitstuff.com/easiest-pdo-tutorial-basics
作者:[Rishabh Kandari][a]
选题:[lujun9972](https://github.com/lujun9972)
译者:[译者ID](https://github.com/译者ID)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:http://www.theitstuff.com/author/reevkandari

View File

@ -0,0 +1,170 @@
最简单的 PDO 教程(基础知识)
======
![](http://www.theitstuff.com/wp-content/uploads/2018/04/php-language.jpg)
大约 80% 的 Web 应用程序由 PHP 提供支持。类似地SQL 也是如此。PHP 5.5 版本之前,我们有用于访问 mysql 数据库的 **mysql_** 命令,但由于安全性不足,它们最终被弃用。
**这发生在 2013 年的 PHP 5.5 上,我写这篇文章的时间是 2018 年PHP 版本为 7.2。mysql_** 的弃用带来了访问数据库的两种主要方法:**mysqli** 和 **PDO** 库。
虽然 mysqli 库是官方指定的,但由于 mysqli 只能支持 mysql 数据库,而 PDO 可以支持 12 种不同类型的数据库驱动程序,因此 PDO 获得了更多的赞誉。此外PDO 还有其它一些特性,使其成为大多数开发人员的更好选择。你可以在下表中看到一些特性比较:
| | PDO | MySQLi
---|---|---
| **数据库支持** | 12 种驱动 | 只有 MySQL
| **范例** | OOP | 过程 + OOP
| **预处理语句(客户端侧)** | Yes | No
| **命名参数** | Yes | No
现在我想对于大多数开发人员来说PDO 是首选的原因已经很清楚了。所以让我们深入研究它,并希望在本文中尽量涵盖关于 PDO 你需要的了解的。
### 连接
第一步是连接到数据库,由于 PDO 是完全面向对象的,所以我们将使用 PDO 类的实例。
我们要做的第一件事是定义主机、数据库名称、用户名、密码和数据库字符集。
`$host = 'localhost';`
`$db = 'theitstuff';`
`$user = 'root';`
`$pass = 'root';`
`$charset = 'utf8mb4';`
`$dsn = "mysql:host=$host;dbname=$db;charset=$charset";`
`$conn = new PDO($dsn, $user, $pass);`
之后,正如你在上面的代码中看到的,我们创建了 **DSN** 变量DSN 变量只是一个保存数据库信息的变量。对于一些在外部服务器上运行 mysql 的人,你还可以通过提供一个 **port=$port_number** 来调整端口号。
最后,你可以创建一个 PDO 类的实例,我使用了 **\$conn** 变量,并提供了 **\$dsn、\$user、\$pass** 参数。如果你遵循这些步骤,你现在应该有一个名为 $conn 的对象,它是 PDO 连接类的一个实例。现在是时候进入数据库并运行一些查询。
### 一个简单的 SQL 查询
现在让我们运行一个简单的 SQL 查询。
`$tis = $conn->query('SELECT name, age FROM students');`
`while ($row = $tis->fetch())`
`{`
`echo $row['name']."\t";`
`echo $row['age'];`
`echo "<br>";`
`}`
这是使用 PDO 运行查询的最简单形式。我们首先创建了一个名为 **tisTheITStuff 的缩写 ** 的变量,然后你可以看到我们使用了创建的 $conn 对象中的查询函数。
然后我们运行一个 while 循环并创建了一个 **$row** 变量来从 **$tis** 对象中获取内容,最后通过调用列名来显示每一行。
很简单,不是吗?现在让我们来看看预处理语句。
### 预处理语句
预处理语句是人们开始使用 PDO 的主要原因之一,因为它准备了可以阻止 SQL 注入的语句。
有两种基本方法可供使用,你可以使用位置参数或命名参数。
#### 位置参数
让我们看一个使用位置参数的查询示例。
`$tis = $conn->prepare("INSERT INTO STUDENTS(name, age) values(?, ?)");`
`$tis->bindValue(1,'mike');`
`$tis->bindValue(2,22);`
`$tis->execute();`
在上面的例子中,我们放置了两个问号,然后使用 **bindValue()** 函数将值映射到查询中。这些值绑定到语句问号中的位置。
我还可以使用变量而不是直接提供值,通过使用 **bindParam()** 函数相同例子如下:
`$name='Rishabh'; $age=20;`
`$tis = $conn->prepare("INSERT INTO STUDENTS(name, age) values(?, ?)");`
`$tis->bindParam(1,$name);`
`$tis->bindParam(2,$age);`
`$tis->execute();`
### 命名参数
命名参数也是预处理语句,它将值/变量映射到查询中的命名位置。由于没有位置绑定,因此在多次使用相同变量的查询中非常有效。
`$name='Rishabh'; $age=20;`
`$tis = $conn->prepare("INSERT INTO STUDENTS(name, age) values(:name, :age)");`
`$tis->bindParam(':name', $name);`
`$tis->bindParam(':age', $age);`
`$tis->execute();`
你可以注意到,唯一的变化是我使用 **:name** 和 **:age** 作为占位符,然后将变量映射到它们。冒号在参数之前使用,让 PDO 知道该位置是一个变量,这非常重要。
你也可以类似地使用 **bindValue()** 来使用命名参数直接映射值。
### 获取数据
PDO 在获取数据时非常丰富,它实际上提供了许多格式来从数据库中获取数据。
你可以使用 **PDO::FETCH_ASSOC** 来获取关联数组,**PDO::FETCH_NUM** 来获取数字数组,使用 **PDO::FETCH_OBJ** 来获取对象数组。
`$tis = $conn->prepare("SELECT * FROM STUDENTS");`
`$tis->execute();`
`$result = $tis->fetchAll(PDO::FETCH_ASSOC);`
你可以看到我使用了 **fetchAll**,因为我想要所有匹配的记录。如果只需要一行,你可以简单地使用 **fetch**
现在我们已经获取了数据,现在是时候循环它了,这非常简单。
`foreach($result as $lnu){`
`echo $lnu['name'];`
`echo $lnu['age']."<br>";`
`}`
你可以看到,因为我请求了关联数组,所以我正在按名称访问各个成员。
虽然在定义希望如何传输递数据方面没有要求,但在定义 conn 变量本身时,实际上可以将其设置为默认值。
你需要做的就是创建一个 options 数组,你可以在其中放入所有默认配置,只需在 conn 变量中传递数组即可。
`$options = [`
` PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,`
`];`
`$conn = new PDO($dsn, $user, $pass, $options);`
这是一个非常简短和快速的 PDO 介绍,我们很快就会制作一个高级教程。如果你在理解本教程的任何部分时遇到任何困难,请在评论部分告诉我,我会在那你为你解答。
--------------------------------------------------------------------------------
via: http://www.theitstuff.com/easiest-pdo-tutorial-basics
作者:[Rishabh Kandari][a]
选题:[lujun9972](https://github.com/lujun9972)
译者:[MjSeven](https://github.com/MjSeven)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:http://www.theitstuff.com/author/reevkandari