**, and notice that the paragraph line is indented automatically.
+
+```
+
+
Vim plugins are awesome !
+
+```
+
+Vim Surround has many other options. Give it a try—and consult [GitHub][7] for additional information.
+
+### 4\. Vim Gitgutter
+
+The [Vim Gitgutter][8] plugin is useful for anyone using Git for version control. It shows the output of **Git diff** as symbols in the "gutter"—the sign column where Vim presents additional information, such as line numbers. For example, consider the following as the committed version in Git:
+
+```
+ 1 package main
+ 2
+ 3 import "fmt"
+ 4
+ 5 func main() {
+ 6 x := true
+ 7 items := []string{"tv", "pc", "tablet"}
+ 8
+ 9 if x {
+ 10 for _, i := range items {
+ 11 fmt.Println(i)
+ 12 }
+ 13 }
+ 14 }
+```
+
+After making some changes, Vim Gitgutter displays the following symbols in the gutter:
+
+```
+ 1 package main
+ 2
+ 3 import "fmt"
+ 4
+_ 5 func main() {
+ 6 items := []string{"tv", "pc", "tablet"}
+ 7
+~ 8 if len(items) > 0 {
+ 9 for _, i := range items {
+ 10 fmt.Println(i)
++ 11 fmt.Println("------")
+ 12 }
+ 13 }
+ 14 }
+```
+
+The **-** symbol shows that a line was deleted between lines 5 and 6. The **~** symbol shows that line 8 was modified, and the symbol **+** shows that line 11 was added.
+
+In addition, Vim Gitgutter allows you to navigate between "hunks"—individual changes made in the file—with **[c** and **]c** , or even stage individual hunks for commit by pressing **Leader+hs**.
+
+This plugin gives you immediate visual feedback of changes, and it's a great addition to your toolbox if you use Git.
+
+### 5\. VIM Fugitive
+
+[Vim Fugitive][9] is another great plugin for anyone incorporating Git into the Vim workflow. It's a Git wrapper that allows you to execute Git commands directly from Vim and integrates with Vim's interface. This plugin has many features—check its [GitHub][10] page for more information.
+
+Here's a basic Git workflow example using Vim Fugitive. Considering the changes we've made to the Go code block on section 4, you can use **git blame** by typing the command **:Gblame** :
+
+```
+e9949066 (Ricardo Gerardi 2018-12-05 18:17:19 -0500)│ 1 package main
+e9949066 (Ricardo Gerardi 2018-12-05 18:17:19 -0500)│ 2
+e9949066 (Ricardo Gerardi 2018-12-05 18:17:19 -0500)│ 3 import "fmt"
+e9949066 (Ricardo Gerardi 2018-12-05 18:17:19 -0500)│ 4
+e9949066 (Ricardo Gerardi 2018-12-05 18:17:19 -0500)│_ 5 func main() {
+e9949066 (Ricardo Gerardi 2018-12-05 18:17:19 -0500)│ 6 items := []string{"tv", "pc", "tablet"}
+e9949066 (Ricardo Gerardi 2018-12-05 18:17:19 -0500)│ 7
+00000000 (Not Committed Yet 2018-12-05 18:55:00 -0500)│~ 8 if len(items) > 0 {
+e9949066 (Ricardo Gerardi 2018-12-05 18:17:19 -0500)│ 9 for _, i := range items {
+e9949066 (Ricardo Gerardi 2018-12-05 18:17:19 -0500)│ 10 fmt.Println(i)
+00000000 (Not Committed Yet 2018-12-05 18:55:00 -0500)│+ 11 fmt.Println("------")
+e9949066 (Ricardo Gerardi 2018-12-05 18:17:19 -0500)│ 12 }
+e9949066 (Ricardo Gerardi 2018-12-05 18:17:19 -0500)│ 13 }
+e9949066 (Ricardo Gerardi 2018-12-05 18:17:19 -0500)│ 14 }
+```
+
+You can see that lines 8 and 11 have not been committed. Check the repository status by typing **:Gstatus** :
+
+```
+ 1 # On branch master
+ 2 # Your branch is up to date with 'origin/master'.
+ 3 #
+ 4 # Changes not staged for commit:
+ 5 # (use "git add
..." to update what will be committed)
+ 6 # (use "git checkout -- ..." to discard changes in working directory)
+ 7 #
+ 8 # modified: vim-5plugins/examples/test1.go
+ 9 #
+ 10 no changes added to commit (use "git add" and/or "git commit -a")
+--------------------------------------------------------------------------------------------------------
+ 1 package main
+ 2
+ 3 import "fmt"
+ 4
+_ 5 func main() {
+ 6 items := []string{"tv", "pc", "tablet"}
+ 7
+~ 8 if len(items) > 0 {
+ 9 for _, i := range items {
+ 10 fmt.Println(i)
++ 11 fmt.Println("------")
+ 12 }
+ 13 }
+ 14 }
+```
+
+Vim Fugitive opens a split window with the result of **git status**. You can stage a file for commit by pressing the **-** key on the line with the name of the file. You can reset the status by pressing **-** again. The message updates to reflect the new status:
+
+```
+ 1 # On branch master
+ 2 # Your branch is up to date with 'origin/master'.
+ 3 #
+ 4 # Changes to be committed:
+ 5 # (use "git reset HEAD ..." to unstage)
+ 6 #
+ 7 # modified: vim-5plugins/examples/test1.go
+ 8 #
+--------------------------------------------------------------------------------------------------------
+ 1 package main
+ 2
+ 3 import "fmt"
+ 4
+_ 5 func main() {
+ 6 items := []string{"tv", "pc", "tablet"}
+ 7
+~ 8 if len(items) > 0 {
+ 9 for _, i := range items {
+ 10 fmt.Println(i)
++ 11 fmt.Println("------")
+ 12 }
+ 13 }
+ 14 }
+```
+
+Now you can use the command **:Gcommit** to commit the changes. Vim Fugitive opens another split that allows you to enter a commit message:
+
+```
+ 1 vim-5plugins: Updated test1.go example file
+ 2 # Please enter the commit message for your changes. Lines starting
+ 3 # with '#' will be ignored, and an empty message aborts the commit.
+ 4 #
+ 5 # On branch master
+ 6 # Your branch is up to date with 'origin/master'.
+ 7 #
+ 8 # Changes to be committed:
+ 9 # modified: vim-5plugins/examples/test1.go
+ 10 #
+```
+
+Save the file with **:wq** to complete the commit:
+
+```
+[master c3bf80f] vim-5plugins: Updated test1.go example file
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+Press ENTER or type command to continue
+```
+
+You can use **:Gstatus** again to see the result and **:Gpush** to update the remote repository with the new commit.
+
+```
+ 1 # On branch master
+ 2 # Your branch is ahead of 'origin/master' by 1 commit.
+ 3 # (use "git push" to publish your local commits)
+ 4 #
+ 5 nothing to commit, working tree clean
+```
+
+If you like Vim Fugitive and want to learn more, the GitHub repository has links to screencasts showing additional functionality and workflows. Check it out!
+
+### What's next?
+
+These Vim plugins help developers write code in any programming language. There are two other categories of plugins to help developers: code-completion plugins and syntax-checker plugins. They are usually related to specific programming languages, so I will cover them in a follow-up article.
+
+Do you have another Vim plugin you use when writing code? Please share it in the comments below.
+
+--------------------------------------------------------------------------------
+
+via: https://opensource.com/article/19/1/vim-plugins-developers
+
+作者:[Ricardo Gerardi][a]
+选题:[lujun9972][b]
+译者:[pityonline](https://github.com/pityonline)
+校对:[校对者ID](https://github.com/校对者ID)
+
+本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
+
+[a]: https://opensource.com/users/rgerardi
+[b]: https://github.com/lujun9972
+[1]: https://www.vim.org/
+[2]: https://www.vim.org/scripts/script.php?script_id=3599
+[3]: https://github.com/jiangmiao/auto-pairs
+[4]: https://github.com/scrooloose/nerdcommenter
+[5]: http://vim.wikia.com/wiki/Filetype.vim
+[6]: https://www.vim.org/scripts/script.php?script_id=1697
+[7]: https://github.com/tpope/vim-surround
+[8]: https://github.com/airblade/vim-gitgutter
+[9]: https://www.vim.org/scripts/script.php?script_id=2975
+[10]: https://github.com/tpope/vim-fugitive
diff --git a/sources/tech/20190111 Build a retro gaming console with RetroPie.md b/sources/tech/20190111 Build a retro gaming console with RetroPie.md
new file mode 100644
index 0000000000..eedac575c9
--- /dev/null
+++ b/sources/tech/20190111 Build a retro gaming console with RetroPie.md
@@ -0,0 +1,82 @@
+[#]: collector: (lujun9972)
+[#]: translator: ( )
+[#]: reviewer: ( )
+[#]: publisher: ( )
+[#]: url: ( )
+[#]: subject: (Build a retro gaming console with RetroPie)
+[#]: via: (https://opensource.com/article/19/1/retropie)
+[#]: author: (Jay LaCroix https://opensource.com/users/jlacroix)
+
+Build a retro gaming console with RetroPie
+======
+Play your favorite classic Nintendo, Sega, and Sony console games on Linux.
+
+
+The most common question I get on [my YouTube channel][1] and in person is what my favorite Linux distribution is. If I limit the answer to what I run on my desktops and laptops, my answer will typically be some form of an Ubuntu-based Linux distro. My honest answer to this question may surprise many. My favorite Linux distribution is actually [RetroPie][2].
+
+As passionate as I am about Linux and open source software, I'm equally passionate about classic gaming, specifically video games produced in the '90s and earlier. I spend most of my surplus income on older games, and I now have a collection of close to a thousand games for over 20 gaming consoles. In my spare time, I raid flea markets, yard sales, estate sales, and eBay buying games for various consoles, including almost every iteration made by Nintendo, Sega, and Sony. There's something about classic games that I adore, a charm that seems lost in games released nowadays.
+
+Unfortunately, collecting retro games has its fair share of challenges. Cartridges with memory for save files will lose their charge over time, requiring the battery to be replaced. While it's not hard to replace save batteries (if you know how), it's still time-consuming. Games on CD-ROMs are subject to disc rot, which means that even if you take good care of them, they'll still lose data over time and become unplayable. Also, sometimes it's difficult to find replacement parts for some consoles. This wouldn't be so much of an issue if the majority of classic games were available digitally, but the vast majority are never re-released on a digital platform.
+
+### Gaming on RetroPie
+
+RetroPie is a great project and an asset to retro gaming enthusiasts like me. RetroPie is a Raspbian-based distribution designed for use on the Raspberry Pi (though it is possible to get it working on other platforms, such as a PC). RetroPie boots into a graphical interface that is completely controllable via a gamepad or joystick and allows you to easily manage digital copies (ROMs) of your favorite games. You can scrape information from the internet to organize your collection better and manage lists of favorite games, and the entire interface is very user-friendly and efficient. From the interface, you can launch directly into a game, then exit the game by pressing a combination of buttons on your gamepad. You rarely need a keyboard, unless you have to enter your WiFi password or manually edit configuration files.
+
+I use RetroPie to host a digital copy of every physical game I own in my collection. When I purchase a game from a local store or eBay, I also download the ROM. As a collector, this is very convenient. If I don't have a particular physical console within arms reach, I can boot up RetroPie and enjoy a game quickly without having to connect cables or clean cartridge contacts. There's still something to be said about playing a game on the original hardware, but if I'm pressed for time, RetroPie is very convenient. I also don't have to worry about dead save batteries, dirty cartridge contacts, disc rot, or any of the other issues collectors like me have to regularly deal with. I simply play the game.
+
+Also, RetroPie allows me to be very clever and utilize my technical know-how to achieve additional functionality that's not normally available. For example, I have three RetroPies set up, each of them synchronizing their files between each other by leveraging [Syncthing][3], a popular open source file synchronization tool. The synchronization happens automatically, and it means I can start a game on one television and continue in the same place on another unit since the save files are included in the synchronization. To take it a step further, I also back up my save and configuration files to [Backblaze B2][4], so I'm protected if an SD card becomes defective.
+
+### Setting up RetroPie
+
+Setting up RetroPie is very easy, and if you've ever set up a Raspberry Pi Linux distribution before (such as Raspbian) the process is essentially the same—you simply download the IMG file and flash it to your SD card by utilizing another tool, such as [Etcher][5], and insert it into your RetroPie. Then plug in an AC adapter and gamepad and hook it up to your television via HDMI. Optionally, you can buy a case to protect your RetroPie from outside elements and add visual appeal. Here is a listing of things you'll need to get started:
+
+ * Raspberry Pi board (Model 3B+ or higher recommended)
+ * SD card (16GB or larger recommended)
+ * A USB gamepad
+ * UL-listed micro USB power adapter, at least 2.5 amp
+
+
+
+If you choose to add the optional Raspberry Pi case, I recommend the Super NES and Super Famicom themed cases from [RetroFlag][6]. Not only do these cases look cool, but they also have fully functioning power and reset buttons. This means you can configure the reset and power buttons to directly trigger the operating system's halt process, rather than abruptly terminating power. This definitely makes for a more professional experience, but it does require the installation of a special script. The instructions are on [RetroFlag's GitHub page][7]. Be wary: there are many cases available on Amazon and eBay of varying quality. Some of them are cheap knock-offs of RetroFlag cases, and others are just a lower quality overall. In fact, even cases by RetroFlag vary in quality—I had some power-distribution issues with the NES-themed case that made for an unstable experience. If in doubt, I've found that RetroFlag's Super NES and Super Famicom themed cases work very well.
+
+### Adding games
+
+When you boot RetroPie for the first time, it will resize the filesystem to ensure you have full access to the available space on your SD card and allow you to set up your gamepad. I can't give you links for game ROMs, so I'll leave that part up to you to figure out. When you've found them, simply add them to the RetroPie SD card in the designated folder, which would be located under **/home/pi/RetroPie/roms/ **. You can use your favorite tool for transferring the ROMs to the Pi, such as [SCP][8] in a terminal, [WinSCP][9], [Samba][10], etc. Once you've added the games, you can rescan them by pressing start and choosing the option to restart EmulationStation. When it restarts, it should automatically add menu entries for the ROMs you've added. That's basically all there is to it.
+
+(The rescan updates EmulationStation’s game inventory. If you don’t do that, it won’t list any newly added games you copy over.)
+
+Regarding the games' performance, your mileage will vary depending on which consoles you're emulating. For example, I've noticed that Sega Dreamcast games barely run at all, and most Nintendo 64 games will run sluggishly with a bad framerate. Many PlayStation Portable (PSP) games also perform inconsistently. However, all of the 8-bit and 16-bit consoles emulate seemingly perfectly—I haven't run into a single 8-bit or 16-bit game that doesn't run well. Surprisingly, games designed for the original PlayStation run great for me, which is a great feat considering the lower-performance potential of the Raspberry Pi.
+
+Overall, RetroPie's performance is great, but the Raspberry Pi is not as powerful as a gaming PC, so adjust your expectations accordingly.
+
+### Conclusion
+
+RetroPie is a fantastic open source project dedicated to preserving classic games and an asset to game collectors everywhere. Having a digital copy of my physical game collection is extremely convenient. If I were to tell my childhood self that one day I could have an entire game collection on one device, I probably wouldn't believe it. But RetroPie has become a staple in my household and provides hours of fun and enjoyment.
+
+If you want to see the parts I mentioned as well as a quick installation overview, I have [a video][11] on [my YouTube channel][12] that goes over the process and shows off some gameplay at the end.
+
+--------------------------------------------------------------------------------
+
+via: https://opensource.com/article/19/1/retropie
+
+作者:[Jay LaCroix][a]
+选题:[lujun9972][b]
+译者:[译者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/jlacroix
+[b]: https://github.com/lujun9972
+[1]: https://www.youtube.com/channel/UCxQKHvKbmSzGMvUrVtJYnUA
+[2]: https://retropie.org.uk/
+[3]: https://syncthing.net/
+[4]: https://www.backblaze.com/b2/cloud-storage.html
+[5]: https://www.balena.io/etcher/
+[6]: https://www.amazon.com/shop/learnlinux.tv?listId=1N9V89LEH5S8K
+[7]: https://github.com/RetroFlag/retroflag-picase
+[8]: https://en.wikipedia.org/wiki/Secure_copy
+[9]: https://winscp.net/eng/index.php
+[10]: https://www.samba.org/
+[11]: https://www.youtube.com/watch?v=D8V-KaQzsWM
+[12]: http://www.youtube.com/c/LearnLinuxtv
diff --git a/sources/tech/20190111 Top 5 Linux Distributions for Productivity.md b/sources/tech/20190111 Top 5 Linux Distributions for Productivity.md
new file mode 100644
index 0000000000..fbd8b9d120
--- /dev/null
+++ b/sources/tech/20190111 Top 5 Linux Distributions for Productivity.md
@@ -0,0 +1,170 @@
+[#]: collector: (lujun9972)
+[#]: translator: ( )
+[#]: reviewer: ( )
+[#]: publisher: ( )
+[#]: url: ( )
+[#]: subject: (Top 5 Linux Distributions for Productivity)
+[#]: via: (https://www.linux.com/blog/learn/2019/1/top-5-linux-distributions-productivity)
+[#]: author: (Jack Wallen https://www.linux.com/users/jlwallen)
+
+Top 5 Linux Distributions for Productivity
+======
+
+
+
+I have to confess, this particular topic is a tough one to address. Why? First off, Linux is a productive operating system by design. Thanks to an incredibly reliable and stable platform, getting work done is easy. Second, to gauge effectiveness, you have to consider what type of work you need a productivity boost for. General office work? Development? School? Data mining? Human resources? You see how this question can get somewhat complicated.
+
+That doesn’t mean, however, that some distributions aren’t able to do a better job of configuring and presenting that underlying operating system into an efficient platform for getting work done. Quite the contrary. Some distributions do a much better job of “getting out of the way,” so you don’t find yourself in a work-related hole, having to dig yourself out and catch up before the end of day. These distributions help strip away the complexity that can be found in Linux, thereby making your workflow painless.
+
+Let’s take a look at the distros I consider to be your best bet for productivity. To help make sense of this, I’ve divided them into categories of productivity. That task itself was challenging, because everyone’s productivity varies. For the purposes of this list, however, I’ll look at:
+
+ * General Productivity: For those who just need to work efficiently on multiple tasks.
+
+ * Graphic Design: For those that work with the creation and manipulation of graphic images.
+
+ * Development: For those who use their Linux desktops for programming.
+
+ * Administration: For those who need a distribution to facilitate their system administration tasks.
+
+ * Education: For those who need a desktop distribution to make them more productive in an educational environment.
+
+
+
+
+Yes, there are more categories to be had, many of which can get very niche-y, but these five should fill most of your needs.
+
+### General Productivity
+
+For general productivity, you won’t get much more efficient than [Ubuntu][1]. The primary reason for choosing Ubuntu for this category is the seamless integration of apps, services, and desktop. You might be wondering why I didn’t choose Linux Mint for this category? Because Ubuntu now defaults to the GNOME desktop, it gains the added advantage of GNOME Extensions (Figure 1).
+
+![GNOME Clipboard][3]
+
+Figure 1: The GNOME Clipboard Indicator extension in action.
+
+[Used with permission][4]
+
+These extensions go a very long way to aid in boosting productivity (so Ubuntu gets the nod over Mint). But Ubuntu didn’t just accept a vanilla GNOME desktop. Instead, they tweaked it to make it slightly more efficient and user-friendly, out of the box. And because Ubuntu contains just the right mixture of default, out-of-the-box, apps (that just work), it makes for a nearly perfect platform for productivity.
+
+Whether you need to write a paper, work on a spreadsheet, code a new app, work on your company website, create marketing images, administer a server or network, or manage human resources from within your company HR tool, Ubuntu has you covered. The Ubuntu desktop distribution also doesn’t require the user to jump through many hoops to get things working … it simply works (and quite well). Finally, thanks to it’s Debian base, Ubuntu makes installing third-party apps incredibly easy.
+
+Although Ubuntu tends to be the go-to for nearly every list of “top distributions for X,” it’s very hard to argue against this particular distribution topping the list of general productivity distributions.
+
+### Graphic Design
+
+If you’re looking to up your graphic design productivity, you can’t go wrong with [Fedora Design Suite][5]. This Fedora respin was created by the team responsible for all Fedora-related art work. Although the default selection of apps isn’t a massive collection of tools, those it does include are geared specifically for the creation and manipulation of images.
+
+With apps like GIMP, Inkscape, Darktable, Krita, Entangle, Blender, Pitivi, Scribus, and more (Figure 2), you’ll find everything you need to get your image editing jobs done and done well. But Fedora Design Suite doesn’t end there. This desktop platform also includes a bevy of tutorials that cover countless subjects for many of the installed applications. For anyone trying to be as productive as possible, this is some seriously handy information to have at the ready. I will say, however, the tutorial entry in the GNOME Favorites is nothing more than a link to [this page][6].
+
+![Fedora Design Suite Favorites][8]
+
+Figure 2: The Fedora Design Suite Favorites menu includes plenty of tools for getting your graphic design on.
+
+[Used with permission][4]
+
+Those that work with a digital camera will certainly appreciate the inclusion of the Entangle app, which allows you to control your DSLR from the desktop.
+
+### Development
+
+Nearly all Linux distributions are great platforms for programmers. However, one particular distributions stands out, above the rest, as one of the most productive tools you’ll find for the task. That OS comes from [System76][9] and it’s called [Pop!_OS][10]. Pop!_OS is tailored specifically for creators, but not of the artistic type. Instead, Pop!_OS is geared toward creators who specialize in developing, programming, and making. If you need an environment that is not only perfected suited for your development work, but includes a desktop that’s sure to get out of your way, you won’t find a better option than Pop!_OS (Figure 3).
+
+What might surprise you (given how “young” this operating system is), is that Pop!_OS is also one of the single most stable GNOME-based platforms you’ll ever use. This means Pop!_OS isn’t just for creators and makers, but anyone looking for a solid operating system. One thing that many users will greatly appreciate with Pop!_OS, is that you can download an ISO specifically for your video hardware. If you have Intel hardware, [download][10] the version for Intel/AMD. If your graphics card is NVIDIA, download that specific release. Either way, you are sure go get a solid platform for which to create your masterpiece.
+
+![Pop!_OS][12]
+
+Figure 3: The Pop!_OS take on GNOME Overview.
+
+[Used with permission][4]
+
+Interestingly enough, with Pop!_OS, you won’t find much in the way of pre-installed development tools. You won’t find an included IDE, or many other dev tools. You can, however, find all the development tools you need in the Pop Shop.
+
+### Administration
+
+If you’re looking to find one of the most productive distributions for admin tasks, look no further than [Debian][13]. Why? Because Debian is not only incredibly reliable, it’s one of those distributions that gets out of your way better than most others. Debian is the perfect combination of ease of use and unlimited possibility. On top of which, because this is the distribution for which so many others are based, you can bet if there’s an admin tool you need for a task, it’s available for Debian. Of course, we’re talking about general admin tasks, which means most of the time you’ll be using a terminal window to SSH into your servers (Figure 4) or a browser to work with web-based GUI tools on your network. Why bother making use of a desktop that’s going to add layers of complexity (such as SELinux in Fedora, or YaST in openSUSE)? Instead, chose simplicity.
+
+![Debian][15]
+
+Figure 4: SSH’ing into a remote server on Debian.
+
+[Used with permission][4]
+
+And because you can select which desktop you want (from GNOME, Xfce, KDE, Cinnamon, MATE, LXDE), you can be sure to have the interface that best matches your work habits.
+
+### Education
+
+If you are a teacher or student, or otherwise involved in education, you need the right tools to be productive. Once upon a time, there existed the likes of Edubuntu. That distribution never failed to be listed in the top of education-related lists. However, that distro hasn’t been updated since it was based on Ubuntu 14.04. Fortunately, there’s a new education-based distribution ready to take that title, based on openSUSE. This spin is called [openSUSE:Education-Li-f-e][16] (Linux For Education - Figure 5), and is based on openSUSE Leap 42.1 (so it is slightly out of date).
+
+openSUSE:Education-Li-f-e includes tools like:
+
+ * Brain Workshop - A dual n-back brain exercise
+
+ * GCompris - An educational software suite for young children
+
+ * gElemental - A periodic table viewer
+
+ * iGNUit - A general purpose flash card program
+
+ * Little Wizard - Development environment for children based on Pascal
+
+ * Stellarium - An astronomical sky simulator
+
+ * TuxMath - An math tutor game
+
+ * TuxPaint - A drawing program for young children
+
+ * TuxType - An educational typing tutor for children
+
+ * wxMaxima - A cross platform GUI for the computer algebra system
+
+ * Inkscape - Vector graphics program
+
+ * GIMP - Graphic image manipulation program
+
+ * Pencil - GUI prototyping tool
+
+ * Hugin - Panorama photo stitching and HDR merging program
+
+
+![Education][18]
+
+Figure 5: The openSUSE:Education-Li-f-e distro has plenty of tools to help you be productive in or for school.
+
+[Used with permission][4]
+
+Also included with openSUSE:Education-Li-f-e is the [KIWI-LTSP Server][19]. The KIWI-LTSP Server is a flexible, cost effective solution aimed at empowering schools, businesses, and organizations all over the world to easily install and deploy desktop workstations. Although this might not directly aid the student to be more productive, it certainly enables educational institutions be more productive in deploying desktops for students to use. For more information on setting up KIWI-LTSP, check out the openSUSE [KIWI-LTSP quick start guide][20].
+
+Learn more about Linux through the free ["Introduction to Linux" ][21]course from The Linux Foundation and edX.
+
+--------------------------------------------------------------------------------
+
+via: https://www.linux.com/blog/learn/2019/1/top-5-linux-distributions-productivity
+
+作者:[Jack Wallen][a]
+选题:[lujun9972][b]
+译者:[译者ID](https://github.com/译者ID)
+校对:[校对者ID](https://github.com/校对者ID)
+
+本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
+
+[a]: https://www.linux.com/users/jlwallen
+[b]: https://github.com/lujun9972
+[1]: https://www.ubuntu.com/
+[2]: /files/images/productivity1jpg
+[3]: https://www.linux.com/sites/lcom/files/styles/rendered_file/public/productivity_1.jpg?itok=yxez3X1w (GNOME Clipboard)
+[4]: /licenses/category/used-permission
+[5]: https://labs.fedoraproject.org/en/design-suite/
+[6]: https://fedoraproject.org/wiki/Design_Suite/Tutorials
+[7]: /files/images/productivity2jpg
+[8]: https://www.linux.com/sites/lcom/files/styles/rendered_file/public/productivity_2.jpg?itok=ke0b8qyH (Fedora Design Suite Favorites)
+[9]: https://system76.com/
+[10]: https://system76.com/pop
+[11]: /files/images/productivity3jpg-0
+[12]: https://www.linux.com/sites/lcom/files/styles/rendered_file/public/productivity_3_0.jpg?itok=8UkCUfsD (Pop!_OS)
+[13]: https://www.debian.org/
+[14]: /files/images/productivity4jpg
+[15]: https://www.linux.com/sites/lcom/files/styles/rendered_file/public/productivity_4.jpg?itok=c9yD3Xw2 (Debian)
+[16]: https://en.opensuse.org/openSUSE:Education-Li-f-e
+[17]: /files/images/productivity5jpg
+[18]: https://www.linux.com/sites/lcom/files/styles/rendered_file/public/productivity_5.jpg?itok=oAFtV8nT (Education)
+[19]: https://en.opensuse.org/Portal:KIWI-LTSP
+[20]: https://en.opensuse.org/SDB:KIWI-LTSP_quick_start
+[21]: https://training.linuxfoundation.org/linux-courses/system-administration-training/introduction-to-linux
diff --git a/sources/tech/20190113 Editing Subtitles in Linux.md b/sources/tech/20190113 Editing Subtitles in Linux.md
new file mode 100644
index 0000000000..1eaa6a68fd
--- /dev/null
+++ b/sources/tech/20190113 Editing Subtitles in Linux.md
@@ -0,0 +1,168 @@
+[#]: collector: (lujun9972)
+[#]: translator: ( )
+[#]: reviewer: ( )
+[#]: publisher: ( )
+[#]: url: ( )
+[#]: subject: (Editing Subtitles in Linux)
+[#]: via: (https://itsfoss.com/editing-subtitles)
+[#]: author: (Shirish https://itsfoss.com/author/shirish/)
+
+Editing Subtitles in Linux
+======
+
+I have been a world movie and regional movies lover for decades. Subtitles are the essential tool that have enabled me to enjoy the best movies in various languages and from various countries.
+
+If you enjoy watching movies with subtitles, you might have noticed that sometimes the subtitles are not synced or not correct.
+
+Did you know that you can edit subtitles and make them better? Let me show you some basic subtitle editing in Linux.
+
+![Editing subtitles in Linux][1]
+
+### Extracting subtitles from closed captions data
+
+Around 2012, 2013 I came to know of a tool called [CCEextractor.][2] As time passed, it has become one of the vital tools for me, especially if I come across a media file which has the subtitle embedded in it.
+
+CCExtractor analyzes video files and produces independent subtitle files from the closed captions data.
+
+CCExtractor is a cross-platform, free and open source tool. The tool has matured quite a bit from its formative years and has been part of [GSOC][3] and Google Code-in now and [then.][4]
+
+The tool, to put it simply, is more or less a set of scripts which work one after another in a serialized order to give you an extracted subtitle.
+
+You can follow the installation instructions for CCExtractor on [this page][5].
+
+After installing when you want to extract subtitles from a media file, do the following:
+
+```
+ccextractor
+```
+
+The output of the command will be something like this:
+
+It basically scans the media file. In this case, it found that the media file is in malyalam and that the media container is an [.mkv][6] container. It extracted the subtitle file with the same name as the video file adding _eng to it.
+
+CCExtractor is a wonderful tool which can be used to enhance subtitles along with Subtitle Edit which I will share in the next section.
+
+```
+Interesting Read: There is an interesting synopsis of subtitles at [vicaps][7] which tells and shares why subtitles are important to us. It goes into quite a bit of detail of movie-making as well for those interested in such topics.
+```
+
+### Editing subtitles with SubtitleEditor Tool
+
+You probably are aware that most subtitles are in [.srt format][8] . The beautiful thing about this format is and was you could load it in your text editor and do little fixes in it.
+
+A srt file looks something like this when launched into a simple text-editor:
+
+The excerpt subtitle I have shared is from a pretty Old German Movie called [The Cabinet of Dr. Caligari (1920)][9]
+
+Subtitleeditor is a wonderful tool when it comes to editing subtitles. Subtitle Editor is and can be used to manipulate time duration, frame-rate of the subtitle file to be in sync with the media file, duration of breaks in-between and much more. I’ll share some of the basic subtitle editing here.
+
+![][10]
+
+First install subtitleeditor the same way you installed ccextractor, using your favorite installation method. In Debian, you can use this command:
+
+```
+sudo apt install subtitleeditor
+```
+
+When you have it installed, let’s see some of the common scenarios where you need to edit a subtitle.
+
+#### Manipulating Frame-rates to sync with Media file
+
+If you find that the subtitles are not synced with the video, one of the reasons could be the difference between the frame rates of the video file and the subtitle file.
+
+How do you know the frame rates of these files, then?
+
+To get the frame rate of a video file, you can use the mediainfo tool. You may need to install it first using your distribution’s package manager.
+
+Using mediainfo is simple:
+
+```
+$ mediainfo somefile.mkv | grep Frame
+ Format settings : CABAC / 4 Ref Frames
+ Format settings, ReFrames : 4 frames
+ Frame rate mode : Constant
+ Frame rate : 25.000 FPS
+ Bits/(Pixel*Frame) : 0.082
+ Frame rate : 46.875 FPS (1024 SPF)
+```
+
+Now you can see that framerate of the video file is 25.000 FPS. The other Frame-rate we see is for the audio. While I can share why particular fps are used in Video-encoding, Audio-encoding etc. it would be a different subject matter. There is a lot of history associated with it.
+
+Next is to find out the frame rate of the subtitle file and this is a slightly complicated.
+
+Usually, most subtitles are in a zipped format. Unzipping the .zip archive along with the subtitle file which ends in something.srt. Along with it, there is usually also a .info file with the same name which sometime may have the frame rate of the subtitle.
+
+If not, then it usually is a good idea to go some site and download the subtitle from a site which has that frame rate information. For this specific German file, I will be using [Opensubtitle.org][11]
+
+As you can see in the link, the frame rate of the subtitle is 23.976 FPS. Quite obviously, it won’t play well with my video file with frame rate 25.000 FPS.
+
+In such cases, you can change the frame rate of the subtitle file using the Subtitle Editor tool:
+
+Select all the contents from the subtitle file by doing CTRL+A. Go to Timings -> Change Framerate and change frame rates from 23.976 fps to 25.000 fps or whatever it is that is desired. Save the changed file.
+
+![synchronize frame rates of subtitles in Linux][12]
+
+#### Changing the Starting position of a subtitle file
+
+Sometimes the above method may be enough, sometimes though it will not be enough.
+
+You might find some cases when the start of the subtitle file is different from that in the movie or a media file while the frame rate is the same.
+
+In such cases, do the following:
+
+Select all the contents from the subtitle file by doing CTRL+A. Go to Timings -> Select Move Subtitle.
+
+![Move subtitles using Subtitle Editor on Linux][13]
+
+Change the new Starting position of the subtitle file. Save the changed file.
+
+![Move subtitles using Subtitle Editor in Linux][14]
+
+If you wanna be more accurate, then use [mpv][15] to see the movie or media file and click on the timing, if you click on the timing bar which shows how much the movie or the media file has elapsed, clicking on it will also reveal the microsecond.
+
+I usually like to be accurate so I try to be as precise as possible. It is very difficult in MPV as human reaction time is imprecise. If I wanna be super accurate then I use something like [Audacity][16] but then that is another ball-game altogether as you can do so much more with it. That may be something to explore in a future blog post as well.
+
+#### Manipulating Duration
+
+Sometimes even doing both is not enough and you even have to shrink or add the duration to make it sync with the media file. This is one of the more tedious works as you have to individually fix the duration of each sentence. This can happen especially if you have variable frame rates in the media file (nowadays rare but you still get such files).
+
+In such a scenario, you may have to edit the duration manually and automation is not possible. The best way is either to fix the video file (not possible without degrading the video quality) or getting video from another source at a higher quality and then [transcode][17] it with the settings you prefer. This again, while a major undertaking I could shed some light on in some future blog post.
+
+### Conclusion
+
+What I have shared in above is more or less on improving on existing subtitle files. If you were to start a scratch you need loads of time. I haven’t shared that at all because a movie or any video material of say an hour can easily take anywhere from 4-6 hours or even more depending upon skills of the subtitler, patience, context, jargon, accents, native English speaker, translator etc. all of which makes a difference to the quality of the subtitle.
+
+I hope you find this interesting and from now onward, you’ll handle your subtitles slightly better. If you have any suggestions to add, please leave a comment below.
+
+
+--------------------------------------------------------------------------------
+
+via: https://itsfoss.com/editing-subtitles
+
+作者:[Shirish][a]
+选题:[lujun9972][b]
+译者:[译者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/shirish/
+[b]: https://github.com/lujun9972
+[1]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2019/01/editing-subtitles-in-linux.jpeg?resize=800%2C450&ssl=1
+[2]: https://www.ccextractor.org/
+[3]: https://itsfoss.com/best-open-source-internships/
+[4]: https://www.ccextractor.org/public:codein:google_code-in_2018
+[5]: https://github.com/CCExtractor/ccextractor/wiki/Installation
+[6]: https://en.wikipedia.org/wiki/Matroska
+[7]: https://www.vicaps.com/blog/history-of-silent-movies-and-subtitles/
+[8]: https://en.wikipedia.org/wiki/SubRip#SubRip_text_file_format
+[9]: https://www.imdb.com/title/tt0010323/
+[10]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2018/12/subtitleeditor.jpg?ssl=1
+[11]: https://www.opensubtitles.org/en/search/sublanguageid-eng/idmovie-4105
+[12]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2019/01/subtitleeditor-frame-rate-sync.jpg?resize=800%2C450&ssl=1
+[13]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2019/01/Move-subtitles-Caligiri.jpg?resize=800%2C450&ssl=1
+[14]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2019/01/move-subtitles.jpg?ssl=1
+[15]: https://itsfoss.com/mpv-video-player/
+[16]: https://www.audacityteam.org/
+[17]: https://en.wikipedia.org/wiki/Transcoding
+[18]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2019/01/editing-subtitles-in-linux.jpeg?fit=800%2C450&ssl=1
diff --git a/sources/tech/20190113 Get started with Joplin, a note-taking app.md b/sources/tech/20190113 Get started with Joplin, a note-taking app.md
new file mode 100644
index 0000000000..2498435040
--- /dev/null
+++ b/sources/tech/20190113 Get started with Joplin, a note-taking app.md
@@ -0,0 +1,61 @@
+[#]: collector: (lujun9972)
+[#]: translator: ( )
+[#]: reviewer: ( )
+[#]: publisher: ( )
+[#]: url: ( )
+[#]: subject: (Get started with Joplin, a note-taking app)
+[#]: via: (https://opensource.com/article/19/1/productivity-tool-joplin)
+[#]: author: (Kevin Sonney https://opensource.com/users/ksonney (Kevin Sonney))
+
+Get started with Joplin, a note-taking app
+======
+Learn how open source tools can help you be more productive in 2019. First up, Joplin.
+
+
+There seems to be a mad rush at the beginning of every year to find ways to be more productive. New Year's resolutions, the itch to start the year off right, and of course, an "out with the old, in with the new" attitude all contribute to this. And the usual round of recommendations is heavily biased towards closed source and proprietary software. It doesn't have to be that way.
+
+Here's the first of my picks for 19 new (or new-to-you) open source tools to help you be more productive in 2019.
+
+### Joplin
+
+In the realm of productivity tools, note-taking apps are VERY handy. Yes, you can use the open source [NixNote][1] to access [Evernote][2] notes, but it's still linked to the Evernote servers and still relies on a third party for security. And while you CAN export your Evernote notes from NixNote, the only format options are NixNote XML or PDF files.
+
+
+
+Enter [Joplin][3]. Joplin is a NodeJS application that runs and stores notes locally, allows you to encrypt your notes and supports multiple sync methods. Joplin can run as a console or graphical application on Windows, Mac, and Linux. Joplin also has mobile apps for Android and iOS, meaning you can take your notes with you without a major hassle. Joplin even allows you to format notes with Markdown, HTML, or plain text.
+
+
+
+One really nice thing about Joplin is it supports two kinds of notes: plain notes and to-do notes. Plain notes are what you expect—documents containing text. To-do notes, on the other hand, have a checkbox in the notes list that allows you to mark them "done." And since the to-do note is still a note, you can include lists, documentation, and additional to-do items in a to-do note.
+
+When using the GUI, you can toggle editor views between plain text, WYSIWYG, and a split screen showing both the source text and the rendered view. You can also specify an external editor in the GUI, making it easy to update notes with Vim, Emacs, or any other editor capable of handling text documents.
+
+![Joplin console version][5]
+
+Joplin in the console.
+
+The console interface is absolutely fantastic. While it lacks a WYSIWYG editor, it defaults to the text editor for your login. It also has a powerful command mode that allows you to do almost everything you can do in the GUI version. And it renders Markdown correctly in the viewer.
+
+You can group notes in notebooks and tag notes for easy grouping across your notebooks. And it even has built-in search, so you can find things if you forget where you put them.
+
+Overall, Joplin is a first-class note-taking app ([and a great alternative to Evernote][6]) that will help you be organized and more productive over the next year.
+
+--------------------------------------------------------------------------------
+
+via: https://opensource.com/article/19/1/productivity-tool-joplin
+
+作者:[Kevin Sonney][a]
+选题:[lujun9972][b]
+译者:[译者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/ksonney (Kevin Sonney)
+[b]: https://github.com/lujun9972
+[1]: http://nixnote.org/NixNote-Home/
+[2]: https://evernote.com/
+[3]: https://joplin.cozic.net/
+[4]: https://opensource.com/article/19/1/file/419776
+[5]: https://opensource.com/sites/default/files/uploads/joplin-2_0.png (Joplin console version)
+[6]: https://opensource.com/article/17/12/joplin-open-source-evernote-alternative
diff --git a/sources/tech/20190114 Get started with Wekan, an open source kanban board.md b/sources/tech/20190114 Get started with Wekan, an open source kanban board.md
new file mode 100644
index 0000000000..3e2ee79ecc
--- /dev/null
+++ b/sources/tech/20190114 Get started with Wekan, an open source kanban board.md
@@ -0,0 +1,64 @@
+[#]: collector: (lujun9972)
+[#]: translator: (wwhio)
+[#]: reviewer: ( )
+[#]: publisher: ( )
+[#]: url: ( )
+[#]: subject: (Get started with Wekan, an open source kanban board)
+[#]: via: (https://opensource.com/article/19/1/productivity-tool-wekan)
+[#]: author: (Kevin Sonney https://opensource.com/users/ksonney (Kevin Sonney))
+
+Get started with Wekan, an open source kanban board
+======
+In the second article in our series on open source tools that will make you more productive in 2019, check out Wekan.
+
+
+There seems to be a mad rush at the beginning of every year to find ways to be more productive. New Year's resolutions, the itch to start the year off right, and of course, an "out with the old, in with the new" attitude all contribute to this. And the usual round of recommendations is heavily biased towards closed source and proprietary software. It doesn't have to be that way.
+
+Here's the second of my picks for 19 new (or new-to-you) open source tools to help you be more productive in 2019.
+
+### Wekan
+
+[Kanban][1] boards are a mainstay of today's agile processes. And many of us (myself included) use them to organize not just our work but also our personal lives. I know several artists who use apps like [Trello][2] to keep track of their commision lists as well as what's in progress and what's complete.
+
+
+
+But these apps are often linked to a work account or a commercial service. Enter [Wekan][3], an open source kanban board you can run locally or on the service of your choice. Wekan offers much of the same functionality as other Kanban apps, such as creating boards, lists, swimlanes, and cards, dragging and dropping between lists, assigning to users, labeling cards, and doing pretty much everything else you'd expect in a modern kanban board.
+
+
+
+The thing that distinguishes Wekan from most other kanban boards is the built-in rules. While most other boards support emailing updates, Wekan allows you to set up triggers when taking actions on cards, checklists, and labels.
+
+
+
+Wekan can then take actions like moving cards, updating labels, adding checklists, and sending emails.
+
+
+
+Setting up Wekan locally is a snap—literally. If your desktop supports [Snapcraft][4] applications, installing is as easy as:
+
+```
+sudo snap install wekan
+```
+
+It also supports Docker, which means installing on a server is reasonably straightforward on most servers and desktops.
+
+Overall, if you want a nice kanban board that you can run yourself, Wekan has you covered.
+
+
+--------------------------------------------------------------------------------
+
+via: https://opensource.com/article/19/1/productivity-tool-wekan
+
+作者:[Kevin Sonney][a]
+选题:[lujun9972][b]
+译者:[译者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/ksonney (Kevin Sonney)
+[b]: https://github.com/lujun9972
+[1]: https://en.wikipedia.org/wiki/Kanban
+[2]: https://www.trello.com
+[3]: https://wekan.github.io/
+[4]: https://snapcraft.io/
diff --git a/sources/tech/20190114 Hegemon - A Modular System And Hardware Monitoring Tool For Linux.md b/sources/tech/20190114 Hegemon - A Modular System And Hardware Monitoring Tool For Linux.md
new file mode 100644
index 0000000000..28b5d5cd27
--- /dev/null
+++ b/sources/tech/20190114 Hegemon - A Modular System And Hardware Monitoring Tool For Linux.md
@@ -0,0 +1,139 @@
+[#]: collector: (lujun9972)
+[#]: translator: ( )
+[#]: reviewer: ( )
+[#]: publisher: ( )
+[#]: url: ( )
+[#]: subject: (Hegemon – A Modular System And Hardware Monitoring Tool For Linux)
+[#]: via: (https://www.2daygeek.com/hegemon-a-modular-system-and-hardware-monitoring-tool-for-linux/)
+[#]: author: (Magesh Maruthamuthu https://www.2daygeek.com/author/magesh/)
+
+Hegemon – A Modular System And Hardware Monitoring Tool For Linux
+======
+
+I know that everybody is preferring for **[TOP Command][1]** to monitor system utilization.
+
+It’s one of the best and native command which used by vast of Linux administrators.
+
+In Linux there is an alternative for everything respective of packages.
+
+There are many utilities are available for this purpose in Linux and i prefer **[HTOP Command][2]**.
+
+If you want to know about other alternatives, i would suggest you to navigate to the each link to know more about it.
+
+Those are htop, CorFreq, glances, atop, Dstat, Gtop, Linux Dash, Netdata, Monit, etc.
+
+All these tools only allow us to monitor system utilization and not for the system hardware’s.
+
+But Hegemon is allow us to monitor both in the single dashboard.
+
+If you are looking for system hardware monitoring then i would suggest you to check **[lm_sensors][3]** and **[s-tui Stress Terminal UI][4]** utilities.
+
+### What’s Hegemon?
+
+Hegemon is a work-in-progress modular system monitor written in safe Rust.
+
+It allow users to monitor both utilization in a single dashboard. It’s system utilization and hardware temperatures.
+
+### Currently Available Features in Hegemon
+
+ * Monitor CPU and memory usage, temperatures, and fan speeds
+ * Expand any data stream to reveal a more detailed graph and additional information
+ * Adjustable update interval
+ * Clean MVC architecture with good code quality
+ * Unit tests
+
+
+
+### Planned Features include
+
+ * macOS and BSD support (only Linux is supported at the moment)
+ * Monitor disk and network I/O, GPU usage (maybe), and more
+ * Select and reorder data streams
+ * Mouse control
+
+
+
+### How to Install Hegemon in Linux?
+
+Hegemon is requires Rust 1.26 or later and the development files for libsensors. So, make sure these packages were installed before your perform Hegemon installation.
+
+libsensors library package is available in most of the distribution official repository so, use the following command to install it.
+
+For **`Debian/Ubuntu`** systems, use **[APT-GET Command][5]** or **[APT Command][6]** to install libsensors on your systems.
+
+```
+# apt install lm_sensors-devel
+```
+
+For **`Fedora`** system, use **[DNF Package Manager][7]** to install libsensors on your system.
+
+```
+# dnf install libsensors4-dev
+```
+
+Run the following command to install Rust programming language and follow the instruction. Navigate to the following URL if you want handy tutorials for **[Rust installation][8]**.
+
+```
+$ curl https://sh.rustup.rs -sSf | sh
+```
+
+If you have successfully installed Rust. Run the following command to install Hegemon.
+
+```
+$ cargo install hegemon
+```
+
+### How to Lunch Hegemon in Linux?
+
+Once you successfully install Hegemon package. Run run the below command to launch it.
+
+```
+$ hegemon
+```
+
+![][10]
+
+I was facing an issue when i was launching the “Hegemon” application due to libsensors.so.4 libraries issue.
+
+```
+$ hegemon
+error while loading shared libraries: libsensors.so.4: cannot open shared object file: No such file or directory manjaro
+```
+
+I’m using Manjaro 18.04. It has the libsensors.so & libsensors.so.5 shared libraries and not for libsensors.so.4. So, i just created the following symlink to fix the issue.
+
+```
+$ sudo ln -s /usr/lib/libsensors.so /usr/lib/libsensors.so.4
+```
+
+Here is the sample gif file which was taken from my Lenovo-Y700 laptop.
+![][11]
+
+By default it shows only overall summary and if you would like to see the detailed output then you need to expand the each section. See the expanded output with Hegemon.
+![][12]
+
+--------------------------------------------------------------------------------
+
+via: https://www.2daygeek.com/hegemon-a-modular-system-and-hardware-monitoring-tool-for-linux/
+
+作者:[Magesh Maruthamuthu][a]
+选题:[lujun9972][b]
+译者:[译者ID](https://github.com/译者ID)
+校对:[校对者ID](https://github.com/校对者ID)
+
+本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
+
+[a]: https://www.2daygeek.com/author/magesh/
+[b]: https://github.com/lujun9972
+[1]: https://www.2daygeek.com/top-command-examples-to-monitor-server-performance/
+[2]: https://www.2daygeek.com/linux-htop-command-linux-system-performance-resource-monitoring-tool/
+[3]: https://www.2daygeek.com/view-check-cpu-hard-disk-temperature-linux/
+[4]: https://www.2daygeek.com/s-tui-stress-terminal-ui-monitor-linux-cpu-temperature-frequency/
+[5]: https://www.2daygeek.com/apt-get-apt-cache-command-examples-manage-packages-debian-ubuntu-systems/
+[6]: https://www.2daygeek.com/apt-command-examples-manage-packages-debian-ubuntu-systems/
+[7]: https://www.2daygeek.com/dnf-command-examples-manage-packages-fedora-system/
+[8]: https://www.2daygeek.com/how-to-install-rust-programming-language-in-linux/
+[9]: data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7
+[10]: https://www.2daygeek.com/wp-content/uploads/2019/01/hegemon-a-modular-system-and-hardware-monitoring-tool-for-linux-1.png
+[11]: https://www.2daygeek.com/wp-content/uploads/2019/01/hegemon-a-modular-system-and-hardware-monitoring-tool-for-linux-2a.gif
+[12]: https://www.2daygeek.com/wp-content/uploads/2019/01/hegemon-a-modular-system-and-hardware-monitoring-tool-for-linux-3.png
diff --git a/sources/tech/20190114 How To Move Multiple File Types Simultaneously From Commandline.md b/sources/tech/20190114 How To Move Multiple File Types Simultaneously From Commandline.md
new file mode 100644
index 0000000000..1b342b12ef
--- /dev/null
+++ b/sources/tech/20190114 How To Move Multiple File Types Simultaneously From Commandline.md
@@ -0,0 +1,96 @@
+[#]: collector: (lujun9972)
+[#]: translator: ( )
+[#]: reviewer: ( )
+[#]: publisher: ( )
+[#]: url: ( )
+[#]: subject: (How To Move Multiple File Types Simultaneously From Commandline)
+[#]: via: (https://www.ostechnix.com/how-to-move-multiple-file-types-simultaneously-from-commandline/)
+[#]: author: (SK https://www.ostechnix.com/author/sk/)
+
+How To Move Multiple File Types Simultaneously From Commandline
+======
+
+
+
+The other day I was wondering how can I move (not copy) multiple file types from directory to another. I already knew how to [**find and copy certain type of files from one directory to another**][1]. But, I don’t know how to move multiple file types simultaneously. If you’re ever in a situation like this, I know a easy way to do it from commandline in Unix-like systems.
+
+### Move Multiple File Types Simultaneously
+
+Picture this scenario.You have multiple type of files, for example .pdf, .doc, .mp3, .mp4, .txt etc., on a directory named **‘dir1’**. Let us take a look at the dir1 contents:
+
+```
+$ ls dir1
+file.txt image.jpg mydoc.doc personal.pdf song.mp3 video.mp4
+```
+
+You want to move some of the file types (not all of them) to different location. For example, let us say you want to move doc, pdf and txt files only to another directory named **‘dir2’** in one go.
+
+To copy .doc, .pdf and .txt files from dir1 to dir2 simultaneously, the command would be:
+
+```
+$ mv dir1/*.{doc,pdf,txt} dir2/
+```
+
+It’s easy, isn’t it?
+
+Now, let us check the contents of dir2:
+
+```
+$ ls dir2/
+file.txt mydoc.doc personal.pdf
+```
+
+See? Only the file types .doc, .pdf and .txt from dir1 have been moved to dir2.
+
+![][3]
+
+You can add as many file types as you want to inside curly braces in the above command to move them across different directories. The above command just works fine for me on Bash.
+
+Another way to move multiple file types is go to the source directory i.e dir1 in our case:
+
+```
+$ cd ~/dir1
+```
+
+And, move file types of your choice to the destination (E.g dir2) as shown below.
+
+```
+$ mv *.doc *.txt *.pdf /home/sk/dir2/
+```
+
+To move all files having a particular extension, for example **.doc** only, run:
+
+```
+$ mv dir1/*.doc dir2/
+```
+
+For more details, refer man pages.
+
+```
+$ man mv
+```
+
+Moving a few number of same or different file types is easy! You could do this with couple mouse clicks in GUI mode or use a one-liner command in CLI mode. However, If you have thousands of different file types in a directory and wanted to move multiple file types to different directory in one go, it would be a cumbersome task. To me, the above method did the job easily! If you know any other one-liner commands to move multiple file types at a time, please share it in the comment section below. I will check and update the guide accordingly.
+
+And, that’s all for now. Hope this was useful. More good stuffs to come. Stay tuned!
+
+Cheers!
+
+
+
+--------------------------------------------------------------------------------
+
+via: https://www.ostechnix.com/how-to-move-multiple-file-types-simultaneously-from-commandline/
+
+作者:[SK][a]
+选题:[lujun9972][b]
+译者:[译者ID](https://github.com/译者ID)
+校对:[校对者ID](https://github.com/校对者ID)
+
+本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
+
+[a]: https://www.ostechnix.com/author/sk/
+[b]: https://github.com/lujun9972
+[1]: https://www.ostechnix.com/find-copy-certain-type-files-one-directory-another-linux/
+[2]: data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7
+[3]: http://www.ostechnix.com/wp-content/uploads/2019/01/mv-command.gif
diff --git a/sources/tech/20190114 How to Build a Netboot Server, Part 4.md b/sources/tech/20190114 How to Build a Netboot Server, Part 4.md
new file mode 100644
index 0000000000..aadd3c0b01
--- /dev/null
+++ b/sources/tech/20190114 How to Build a Netboot Server, Part 4.md
@@ -0,0 +1,632 @@
+[#]: collector: (lujun9972)
+[#]: translator: ( )
+[#]: reviewer: ( )
+[#]: publisher: ( )
+[#]: url: ( )
+[#]: subject: (How to Build a Netboot Server, Part 4)
+[#]: via: (https://fedoramagazine.org/how-to-build-a-netboot-server-part-4/)
+[#]: author: (Gregory Bartholomew https://fedoramagazine.org/author/glb/)
+
+How to Build a Netboot Server, Part 4
+======
+
+
+One significant limitation of the netboot server built in this series is the operating system image being served is read-only. Some use cases may require the end user to modify the image. For example, an instructor may want to have the students install and configure software packages like MariaDB and Node.js as part of their course walk-through.
+
+An added benefit of writable netboot images is the end user’s “personalized” operating system can follow them to different workstations they may use at later times.
+
+### Change the Bootmenu Application to use HTTPS
+
+Create a self-signed certificate for the bootmenu application:
+
+```
+$ sudo -i
+# MY_NAME=$( .*#listen => ['https://$MY_NAME:443?cert=$MY_TLSD/$MY_NAME.pem\&key=$MY_TLSD/$MY_NAME.key\&ciphers=AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA'],#" /opt/bootmenu/bootmenu.conf
+```
+
+Note the ciphers have been restricted to [those currently supported by iPXE][1].
+
+GnuTLS requires the “CAP_DAC_READ_SEARCH” capability, so add it to the bootmenu application’s systemd service:
+
+```
+# sed -i '/^AmbientCapabilities=/ s/$/ CAP_DAC_READ_SEARCH/' /etc/systemd/system/bootmenu.service
+# sed -i 's/Serves iPXE Menus over HTTP/Serves iPXE Menus over HTTPS/' /etc/systemd/system/bootmenu.service
+# systemctl daemon-reload
+```
+
+Now, add an exception for the bootmenu service to the firewall and restart the service:
+
+```
+# MY_SUBNET=192.0.2.0
+# MY_PREFIX=24
+# firewall-cmd --add-rich-rule="rule family='ipv4' source address='$MY_SUBNET/$MY_PREFIX' service name='https' accept"
+# firewall-cmd --runtime-to-permanent
+# systemctl restart bootmenu.service
+```
+
+Use wget to verify it’s working:
+
+```
+$ MY_NAME=server-01.example.edu
+$ MY_TLSD=/opt/bootmenu/tls
+$ wget -q --ca-certificate=$MY_TLSD/$MY_NAME.pem -O - https://$MY_NAME/menu
+```
+
+### Add HTTPS to iPXE
+
+Update init.ipxe to use HTTPS. Then recompile the ipxe bootloader with options to embed and trust the self-signed certificate you created for the bootmenu application:
+
+```
+$ echo '#define DOWNLOAD_PROTO_HTTPS' >> $HOME/ipxe/src/config/local/general.h
+$ sed -i 's/^chain http:/chain https:/' $HOME/ipxe/init.ipxe
+$ cp $MY_TLSD/$MY_NAME.pem $HOME/ipxe
+$ cd $HOME/ipxe/src
+$ make clean
+$ make bin-x86_64-efi/ipxe.efi EMBED=../init.ipxe CERT="../$MY_NAME.pem" TRUST="../$MY_NAME.pem"
+```
+
+You can now copy the HTTPS-enabled iPXE bootloader out to your clients and test that everything is working correctly:
+
+```
+$ cp $HOME/ipxe/src/bin-x86_64-efi/ipxe.efi $HOME/esp/efi/boot/bootx64.efi
+```
+
+### Add User Authentication to Mojolicious
+
+Create a PAM service definition for the bootmenu application:
+
+```
+# dnf install -y pam_krb5
+# echo 'auth required pam_krb5.so' > /etc/pam.d/bootmenu
+```
+
+Add a library to the bootmenu application that uses the Authen-PAM perl module to perform user authentication:
+
+```
+# dnf install -y perl-Authen-PAM;
+# MY_MOJO=/opt/bootmenu
+# mkdir $MY_MOJO/lib
+# cat << 'END' > $MY_MOJO/lib/PAM.pm
+package PAM;
+
+use Authen::PAM;
+
+sub auth {
+ my $success = 0;
+
+ my $username = shift;
+ my $password = shift;
+
+ my $callback = sub {
+ my @res;
+ while (@_) {
+ my $code = shift;
+ my $msg = shift;
+ my $ans = "";
+
+ $ans = $username if ($code == PAM_PROMPT_ECHO_ON());
+ $ans = $password if ($code == PAM_PROMPT_ECHO_OFF());
+
+ push @res, (PAM_SUCCESS(), $ans);
+ }
+ push @res, PAM_SUCCESS();
+
+ return @res;
+ };
+
+ my $pamh = new Authen::PAM('bootmenu', $username, $callback);
+
+ {
+ last unless ref $pamh;
+ last unless $pamh->pam_authenticate() == PAM_SUCCESS;
+ $success = 1;
+ }
+
+ return $success;
+}
+
+return 1;
+END
+```
+
+The above code is taken almost verbatim from the Authen::PAM::FAQ man page.
+
+Redefine the bootmenu application so it returns a netboot template only if a valid username and password are supplied:
+
+```
+# cat << 'END' > $MY_MOJO/bootmenu.pl
+#!/usr/bin/env perl
+
+use lib 'lib';
+
+use PAM;
+use Mojolicious::Lite;
+use Mojolicious::Plugins;
+use Mojo::Util ('url_unescape');
+
+plugin 'Config';
+
+get '/menu';
+get '/boot' => sub {
+ my $c = shift;
+
+ my $instance = $c->param('instance');
+ my $username = $c->param('username');
+ my $password = $c->param('password');
+
+ my $template = 'menu';
+
+ {
+ last unless $instance =~ /^fc[[:digit:]]{2}$/;
+ last unless $username =~ /^[[:alnum:]]+$/;
+ last unless PAM::auth($username, url_unescape($password));
+ $template = $instance;
+ }
+
+ return $c->render(template => $template);
+};
+
+app->start;
+END
+```
+
+The bootmenu application now looks for the lib directory relative to its WorkingDirectory. However, by default the working directory is set to the root directory of the server for systemd units. Therefore, you must update the systemd unit to set WorkingDirectory to the root of the bootmenu application instead:
+
+```
+# sed -i "/^RuntimeDirectory=/ a WorkingDirectory=$MY_MOJO" /etc/systemd/system/bootmenu.service
+# systemctl daemon-reload
+```
+
+Update the templates to work with the redefined bootmenu application:
+
+```
+# cd $MY_MOJO/templates
+# MY_BOOTMENU_SERVER=$( fc$i.html.ep; grep "^kernel\|initrd" menu.html.ep | grep "fc$i" >> fc$i.html.ep; echo "boot || chain https://$MY_BOOTMENU_SERVER/menu" >> fc$i.html.ep; sed -i "/^:f$i$/,/^boot /c :f$i\nlogin\nchain https://$MY_BOOTMENU_SERVER/boot?instance=fc$i\&username=\${username}\&password=\${password:uristring} || goto failed" menu.html.ep; done
+```
+
+The result of the last command above should be three files similar to the following:
+
+**menu.html.ep** :
+
+```
+#!ipxe
+
+set timeout 5000
+
+:menu
+menu iPXE Boot Menu
+item --key 1 lcl 1. Microsoft Windows 10
+item --key 2 f29 2. RedHat Fedora 29
+item --key 3 f28 3. RedHat Fedora 28
+choose --timeout ${timeout} --default lcl selected || goto shell
+set timeout 0
+goto ${selected}
+
+:failed
+echo boot failed, dropping to shell...
+goto shell
+
+:shell
+echo type 'exit' to get the back to the menu
+set timeout 0
+shell
+goto menu
+
+:lcl
+exit
+
+:f29
+login
+chain https://server-01.example.edu/boot?instance=fc29&username=${username}&password=${password:uristring} || goto failed
+
+:f28
+login
+chain https://server-01.example.edu/boot?instance=fc28&username=${username}&password=${password:uristring} || goto failed
+```
+
+**fc29.html.ep** :
+
+```
+#!ipxe
+kernel --name kernel.efi ${prefix}/vmlinuz-4.19.5-300.fc29.x86_64 initrd=initrd.img ro ip=dhcp rd.peerdns=0 nameserver=192.0.2.91 nameserver=192.0.2.92 root=/dev/disk/by-path/ip-192.0.2.158:3260-iscsi-iqn.edu.example.server-01:fc29-lun-1 netroot=iscsi:192.0.2.158::::iqn.edu.example.server-01:fc29 console=tty0 console=ttyS0,115200n8 audit=0 selinux=0 quiet
+initrd --name initrd.img ${prefix}/initramfs-4.19.5-300.fc29.x86_64.img
+boot || chain https://server-01.example.edu/menu
+```
+
+**fc28.html.ep** :
+
+```
+#!ipxe
+kernel --name kernel.efi ${prefix}/vmlinuz-4.19.3-200.fc28.x86_64 initrd=initrd.img ro ip=dhcp rd.peerdns=0 nameserver=192.0.2.91 nameserver=192.0.2.92 root=/dev/disk/by-path/ip-192.0.2.158:3260-iscsi-iqn.edu.example.server-01:fc28-lun-1 netroot=iscsi:192.0.2.158::::iqn.edu.example.server-01:fc28 console=tty0 console=ttyS0,115200n8 audit=0 selinux=0 quiet
+initrd --name initrd.img ${prefix}/initramfs-4.19.3-200.fc28.x86_64.img
+boot || chain https://server-01.example.edu/menu
+```
+
+Now, restart the bootmenu application and verify authentication is working:
+
+```
+# systemctl restart bootmenu.service
+```
+
+### Make the iSCSI Target Writeable
+
+Now that user authentication works through iPXE, you can create per-user, writeable overlays on top of the read-only image on demand when users connect. Using a [copy-on-write][2] overlay has three advantages over simply copying the original image file for each user:
+
+ 1. The copy can be created very quickly. This allows creation on-demand.
+ 2. The copy does not increase the disk usage on the server. Only what the user writes to their personal copy of the image is stored in addition to the original image.
+ 3. Since most sectors for each copy are the same sectors on the server’s storage, they’ll likely already be loaded in RAM when subsequent users access their copies of the operating system. This improves the server’s performance because RAM is faster than disk I/O.
+
+
+
+One potential pitfall of using copy-on-write is that once overlays are created, the images on which they are overlayed must not be changed. If they are changed, all the overlays will be corrupted. Then the overlays must be deleted and replaced with new, blank overlays. Even simply mounting the image file in read-write mode can cause sufficient filesystem updates to corrupt the overlays.
+
+Due to the potential for the overlays to be corrupted if the original image is modified, mark the original image as immutable by running:
+
+```
+# chattr +i
+```
+
+You can use lsattr to view the status of the immutable flag and use to chattr -i unset the immutable flag. While the immutable flag is set, even the root user or a system process running as root cannot modify or delete the file.
+
+Begin by stopping the tgtd.service so you can change the image files:
+
+```
+# systemctl stop tgtd.service
+```
+
+It’s normal for this command to take a minute or so to stop when there are connections still open.
+
+Now, remove the read-only iSCSI export. Then update the readonly-root configuration file in the template so the image is no longer read-only:
+
+```
+# MY_FC=fc29
+# rm -f /etc/tgt/conf.d/$MY_FC.conf
+# TEMP_MNT=$(mktemp -d)
+# mount /$MY_FC.img $TEMP_MNT
+# sed -i 's/^READONLY=yes$/READONLY=no/' $TEMP_MNT/etc/sysconfig/readonly-root
+# sed -i 's/^Storage=volatile$/#Storage=auto/' $TEMP_MNT/etc/systemd/journald.conf
+# umount $TEMP_MNT
+```
+
+Journald was changed from logging to volatile memory back to its default (log to disk if /var/log/journal exists) because a user reported his clients would freeze with an out-of-memory error due to an application generating excessive system logs. The downside to setting logging to disk is that extra write traffic is generated by the clients, and might burden your netboot server with unnecessary I/O. You should decide which option — log to memory or log to disk — is preferable depending on your environment.
+
+Since you won’t make any further changes to the template image, set the immutable flag on it and restart the tgtd.service:
+
+```
+# chattr +i /$MY_FC.img
+# systemctl start tgtd.service
+```
+
+Now, update the bootmenu application:
+
+```
+# cat << 'END' > $MY_MOJO/bootmenu.pl
+#!/usr/bin/env perl
+
+use lib 'lib';
+
+use PAM;
+use Mojolicious::Lite;
+use Mojolicious::Plugins;
+use Mojo::Util ('url_unescape');
+
+plugin 'Config';
+
+get '/menu';
+get '/boot' => sub {
+ my $c = shift;
+
+ my $instance = $c->param('instance');
+ my $username = $c->param('username');
+ my $password = $c->param('password');
+
+ my $chapscrt;
+ my $template = 'menu';
+
+ {
+ last unless $instance =~ /^fc[[:digit:]]{2}$/;
+ last unless $username =~ /^[[:alnum:]]+$/;
+ last unless PAM::auth($username, url_unescape($password));
+ last unless $chapscrt = `sudo scripts/mktgt $instance $username`;
+ $template = $instance;
+ }
+
+ return $c->render(template => $template, username => $username, chapscrt => $chapscrt);
+};
+
+app->start;
+END
+```
+
+This new version of the bootmenu application calls a custom mktgt script which, on success, returns a random [CHAP][3] password for each new iSCSI target that it creates. The CHAP password prevents one user from mounting another user’s iSCSI target by indirect means. The app only returns the correct iSCSI target password to a user who has successfully authenticated.
+
+The mktgt script is prefixed with sudo because it needs root privileges to create the target.
+
+The $username and $chapscrt variables also pass to the render command so they can be incorporated into the templates returned to the user when necessary.
+
+Next, update our boot templates so they can read the username and chapscrt variables and pass them along to the end user. Also update the templates to mount the root filesystem in rw (read-write) mode:
+
+```
+# cd $MY_MOJO/templates
+# sed -i "s/:$MY_FC/:$MY_FC-<%= \$username %>/g" $MY_FC.html.ep
+# sed -i "s/ netroot=iscsi:/ netroot=iscsi:<%= \$username %>:<%= \$chapscrt %>@/" $MY_FC.html.ep
+# sed -i "s/ ro / rw /" $MY_FC.html.ep
+```
+
+After running the above commands, you should have boot templates like the following:
+
+```
+#!ipxe
+kernel --name kernel.efi ${prefix}/vmlinuz-4.19.5-300.fc29.x86_64 initrd=initrd.img rw ip=dhcp rd.peerdns=0 nameserver=192.0.2.91 nameserver=192.0.2.92 root=/dev/disk/by-path/ip-192.0.2.158:3260-iscsi-iqn.edu.example.server-01:fc29-<%= $username %>-lun-1 netroot=iscsi:<%= $username %>:<%= $chapscrt %>@192.0.2.158::::iqn.edu.example.server-01:fc29-<%= $username %> console=tty0 console=ttyS0,115200n8 audit=0 selinux=0 quiet
+initrd --name initrd.img ${prefix}/initramfs-4.19.5-300.fc29.x86_64.img
+boot || chain https://server-01.example.edu/menu
+```
+
+NOTE: If you need to view the boot template after the variables have been [interpolated][4], you can insert the “shell” command on its own line just before the “boot” command. Then, when you netboot your client, iPXE gives you an interactive shell where you can enter “imgstat” to view the parameters being passed to the kernel. If everything looks correct, you can type “exit” to leave the shell and continue the boot process.
+
+Now allow the bootmenu user to run the mktgt script (and only that script) as root via sudo:
+
+```
+# echo "bootmenu ALL = NOPASSWD: $MY_MOJO/scripts/mktgt *" > /etc/sudoers.d/bootmenu
+```
+
+The bootmenu user should not have write access to the mktgt script or any other files under its home directory. All the files under /opt/bootmenu should be owned by root, and should not be writable by any user other than root.
+
+Sudo does not work well with systemd’s DynamicUser option, so create a normal user account and set the systemd service to run as that user:
+
+```
+# useradd -r -c 'iPXE Boot Menu Service' -d /opt/bootmenu -s /sbin/nologin bootmenu
+# sed -i 's/^DynamicUser=true$/User=bootmenu/' /etc/systemd/system/bootmenu.service
+# systemctl daemon-reload
+```
+
+Finally, create a directory for the copy-on-write overlays and create the mktgt script that manages the iSCSI targets and their overlayed backing stores:
+
+```
+# mkdir /$MY_FC.cow
+# mkdir $MY_MOJO/scripts
+# cat << 'END' > $MY_MOJO/scripts/mktgt
+#!/usr/bin/env perl
+
+# if another instance of this script is running, wait for it to finish
+"$ENV{FLOCKER}" eq 'MKTGT' or exec "env FLOCKER=MKTGT flock /tmp $0 @ARGV";
+
+# use "RETURN" to print to STDOUT; everything else goes to STDERR by default
+open(RETURN, '>&', STDOUT);
+open(STDOUT, '>&', STDERR);
+
+my $instance = shift or die "instance not provided";
+my $username = shift or die "username not provided";
+
+my $img = "/$instance.img";
+my $dir = "/$instance.cow";
+my $top = "$dir/$username";
+
+-f "$img" or die "'$img' is not a file";
+-d "$dir" or die "'$dir' is not a directory";
+
+my $base;
+die unless $base = `losetup --show --read-only --nooverlap --find $img`;
+chomp $base;
+
+my $size;
+die unless $size = `blockdev --getsz $base`;
+chomp $size;
+
+# create the per-user sparse file if it does not exist
+if (! -e "$top") {
+ die unless system("dd if=/dev/zero of=$top status=none bs=512 count=0 seek=$size") == 0;
+}
+
+# create the copy-on-write overlay if it does not exist
+my $cow="$instance-$username";
+my $dev="/dev/mapper/$cow";
+if (! -e "$dev") {
+ my $over;
+ die unless $over = `losetup --show --nooverlap --find $top`;
+ chomp $over;
+ die unless system("echo 0 $size snapshot $base $over p 8 | dmsetup create $cow") == 0;
+}
+
+my $tgtadm = '/usr/sbin/tgtadm --lld iscsi';
+
+# get textual representations of the iscsi targets
+my $text = `$tgtadm --op show --mode target`;
+my @targets = $text =~ /(?:^T.*\n)(?:^ .*\n)*/mg;
+
+# convert the textual representations into a hash table
+my $targets = {};
+foreach (@targets) {
+ my $tgt;
+ my $sid;
+
+ foreach (split /\n/) {
+ /^Target (\d+)(?{ $tgt = $targets->{$^N} = [] })/;
+ /I_T nexus: (\d+)(?{ $sid = $^N })/;
+ /Connection: (\d+)(?{ push @{$tgt}, [ $sid, $^N ] })/;
+ }
+}
+
+my $hostname;
+die unless $hostname = `hostname`;
+chomp $hostname;
+
+my $target = 'iqn.' . join('.', reverse split('\.', $hostname)) . ":$cow";
+
+# find the target id corresponding to the provided target name and
+# close any existing connections to it
+my $tid = 0;
+foreach (@targets) {
+ next unless /^Target (\d+)(?{ $tid = $^N }): $target$/m;
+ foreach (@{$targets->{$tid}}) {
+ die unless system("$tgtadm --op delete --mode conn --tid $tid --sid $_->[0] --cid $_->[1]") == 0;
+ }
+}
+
+# create a new target if an existing one was not found
+if ($tid == 0) {
+ # find an available target id
+ my @ids = (0, sort keys %{$targets});
+ $tid = 1; while ($ids[$tid]==$tid) { $tid++ }
+
+ # create the target
+ die unless -e "$dev";
+ die unless system("$tgtadm --op new --mode target --tid $tid --targetname $target") == 0;
+ die unless system("$tgtadm --op new --mode logicalunit --tid $tid --lun 1 --backing-store $dev") == 0;
+ die unless system("$tgtadm --op bind --mode target --tid $tid --initiator-address ALL") == 0;
+}
+
+# (re)set the provided target's chap password
+my $password = join('', map(chr(int(rand(26))+65), 1..8));
+my $accounts = `$tgtadm --op show --mode account`;
+if ($accounts =~ / $username$/m) {
+ die unless system("$tgtadm --op delete --mode account --user $username") == 0;
+}
+die unless system("$tgtadm --op new --mode account --user $username --password $password") == 0;
+die unless system("$tgtadm --op bind --mode account --tid $tid --user $username") == 0;
+
+# return the new password to the iscsi target on stdout
+print RETURN $password;
+END
+# chmod +x $MY_MOJO/scripts/mktgt
+```
+
+The above script does five things:
+
+ 1. It creates the /.cow/ sparse file if it does not already exist.
+ 2. It creates the /dev/mapper/- device node that serves as the copy-on-write backing store for the iSCSI target if it does not already exist.
+ 3. It creates the iqn.:- iSCSI target if it does not exist. Or, if the target does exist, it closes any existing connections to it because the image can only be opened in read-write mode from one place at a time.
+ 4. It (re)sets the chap password on the iqn.:- iSCSI target to a new random value.
+ 5. It prints the new chap password on [standard output][5] if all of the previous tasks compeleted successfully.
+
+
+
+You should be able to test the mktgt script from the command line by running it with valid test parameters. For example:
+
+```
+# echo `$MY_MOJO/scripts/mktgt fc29 jsmith`
+```
+
+When run from the command line, the mktgt script should print out either the eight-character random password for the iSCSI target if it succeeded or the line number on which something went wrong if it failed.
+
+On occasion, you may want to delete an iSCSI target without having to stop the entire service. For example, a user might inadvertently corrupt their personal image, in which case you would need to systematically undo everything that the above mktgt script does so that the next time they log in they will get a copy of the original image.
+
+Below is an rmtgt script that undoes, in reverse order, what the above mktgt script did:
+
+```
+# mkdir $HOME/bin
+# cat << 'END' > $HOME/bin/rmtgt
+#!/usr/bin/env perl
+
+@ARGV >= 2 or die "usage: $0 [+d|+f]\n";
+
+my $instance = shift;
+my $username = shift;
+
+my $rmd = ($ARGV[0] eq '+d'); #remove device node if +d flag is set
+my $rmf = ($ARGV[0] eq '+f'); #remove sparse file if +f flag is set
+my $cow = "$instance-$username";
+
+my $hostname;
+die unless $hostname = `hostname`;
+chomp $hostname;
+
+my $tgtadm = '/usr/sbin/tgtadm';
+my $target = 'iqn.' . join('.', reverse split('\.', $hostname)) . ":$cow";
+
+my $text = `$tgtadm --op show --mode target`;
+my @targets = $text =~ /(?:^T.*\n)(?:^ .*\n)*/mg;
+
+my $targets = {};
+foreach (@targets) {
+ my $tgt;
+ my $sid;
+
+ foreach (split /\n/) {
+ /^Target (\d+)(?{ $tgt = $targets->{$^N} = [] })/;
+ /I_T nexus: (\d+)(?{ $sid = $^N })/;
+ /Connection: (\d+)(?{ push @{$tgt}, [ $sid, $^N ] })/;
+ }
+}
+
+my $tid = 0;
+foreach (@targets) {
+ next unless /^Target (\d+)(?{ $tid = $^N }): $target$/m;
+ foreach (@{$targets->{$tid}}) {
+ die unless system("$tgtadm --op delete --mode conn --tid $tid --sid $_->[0] --cid $_->[1]") == 0;
+ }
+ die unless system("$tgtadm --op delete --mode target --tid $tid") == 0;
+ print "target $tid deleted\n";
+ sleep 1;
+}
+
+my $dev = "/dev/mapper/$cow";
+if ($rmd or ($rmf and -e $dev)) {
+ die unless system("dmsetup remove $cow") == 0;
+ print "device node $dev deleted\n";
+}
+
+if ($rmf) {
+ my $sf = "/$instance.cow/$username";
+ die "sparse file $sf not found" unless -e "$sf";
+ die unless system("rm -f $sf") == 0;
+ die unless not -e "$sf";
+ print "sparse file $sf deleted\n";
+}
+END
+# chmod +x $HOME/bin/rmtgt
+```
+
+For example, to use the above script to completely remove the fc29-jsmith target including its backing store device node and its sparse file, run the following:
+
+```
+# rmtgt fc29 jsmith +f
+```
+
+Once you’ve verified that the mktgt script is working properly, you can restart the bootmenu service. The next time someone netboots, they should receive a personal copy of the the netboot image they can write to:
+
+```
+# systemctl restart bootmenu.service
+```
+
+Users should now be able to modify the root filesystem as demonstrated in the below screenshot:
+
+![][6]
+
+
+--------------------------------------------------------------------------------
+
+via: https://fedoramagazine.org/how-to-build-a-netboot-server-part-4/
+
+作者:[Gregory Bartholomew][a]
+选题:[lujun9972][b]
+译者:[译者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/glb/
+[b]: https://github.com/lujun9972
+[1]: http://ipxe.org/crypto
+[2]: https://en.wikipedia.org/wiki/Copy-on-write
+[3]: https://en.wikipedia.org/wiki/Challenge-Handshake_Authentication_Protocol
+[4]: https://en.wikipedia.org/wiki/String_interpolation
+[5]: https://en.wikipedia.org/wiki/Standard_streams
+[6]: https://fedoramagazine.org/wp-content/uploads/2018/11/netboot-fix-pam_mount-1024x819.png
diff --git a/sources/tech/20190114 Turn a Raspberry Pi 3B- into a PriTunl VPN.md b/sources/tech/20190114 Turn a Raspberry Pi 3B- into a PriTunl VPN.md
new file mode 100644
index 0000000000..b7e55e0efb
--- /dev/null
+++ b/sources/tech/20190114 Turn a Raspberry Pi 3B- into a PriTunl VPN.md
@@ -0,0 +1,113 @@
+[#]: collector: (lujun9972)
+[#]: translator: ( )
+[#]: reviewer: ( )
+[#]: publisher: ( )
+[#]: url: ( )
+[#]: subject: (Turn a Raspberry Pi 3B+ into a PriTunl VPN)
+[#]: via: (https://opensource.com/article/19/1/pritunl-vpn-raspberry-pi)
+[#]: author: (Stephen Bancroft https://opensource.com/users/stevereaver)
+
+Turn a Raspberry Pi 3B+ into a PriTunl VPN
+======
+PriTunl is a VPN solution for small businesses and individuals who want private access to their network.
+
+
+
+[PriTunl][1] is a fantastic VPN terminator solution that's perfect for small businesses and individuals who want a quick and simple way to access their network privately. It's open source, and the basic free version is more than enough to get you started and cover most simple use cases. There is also a paid enterprise version with advanced features like Active Directory integration.
+
+### Special considerations on Raspberry Pi 3B+
+
+PriTunl is generally simple to install, but this project—turning a Raspberry Pi 3B+ into a PriTunl VPN appliance—adds some complexity. For one thing, PriTunl is supplied only as AMD64 and i386 binaries, but the 3B+ uses ARM architecture. This means you must compile your own binaries from source. That's nothing to be afraid of; it can be as simple as copying and pasting a few commands and watching the terminal for a short while.
+
+Another problem: PriTunl seems to require 64-bit architecture. I found this out when I got errors when I tried to compile PriTunl on my Raspberry Pi's 32-bit operating system. Fortunately, Ubuntu's beta version of 18.04 for ARM64 boots on the Raspberry Pi 3B+.
+
+Also, the Raspberry Pi 3B+ uses a different bootloader from other Raspberry Pi models. This required a complicated set of steps to install and update the necessary files to get a Raspberry Pi 3B+ to boot.
+
+### Installing PriTunl
+
+You can overcome these problems by installing a 64-bit operating system on the Raspberry Pi 3B+ before installing PriTunl. I'll assume you have basic knowledge of how to get around the Linux command line and a Raspberry Pi.
+
+Start by opening a terminal and downloading the Ubuntu 18.04 ARM64 beta release by entering:
+
+```
+$ wget http://cdimage.ubuntu.com/releases/18.04/beta/ubuntu-18.04-beta-preinstalled-server-arm64+raspi3.img.xz
+```
+
+Unpack the download:
+
+```
+$ xz -d ubuntu-18.04-beta-preinstalled-server-arm64+raspi3.xz
+```
+
+Insert the SD card you'll use with your Raspberry Pi into your desktop or laptop computer. Your computer will assign the SD card a drive letter—something like **/dev/sda** or **/dev/sdb**. Enter the **dmesg** command and examine the last lines of the output to find out the card's drive assignment.
+
+**Be VERY CAREFUL with the next step! I can't stress that enough; if you get the drive assignment wrong, you could destroy your system.**
+
+Write the image to your SD card with the following command, changing **< DRIVE>** to your SD card's drive assignment (obtained in the previous step):
+
+```
+$ dd if=ubuntu-18.04-beta-preinstalled-server-arm64+raspi3.img of= bs=8M
+```
+
+After it finishes, insert the SD card into your Pi and power it up. Make sure the Pi is connected to your network, then log in with username/password combination ubuntu/ubuntu.
+
+Enter the following commands on your Pi to install a few things to prepare to compile PriTunl:
+
+```
+$ sudo apt-get -y install build-essential git bzr python python-dev python-pip net-tools openvpn bridge-utils psmisc golang-go libffi-dev mongodb
+```
+
+There are a few changes from the standard PriTunl source [installation instructions on GitHub][2]. Make sure you are logged into your Pi and **sudo** to root:
+
+```
+$ sudo su -
+```
+
+This should leave you in root's home directory. To install PriTunl version 1.29.1914.98, enter (per GitHub):
+
+```
+export VERSION=1.29.1914.98
+tee -a ~/.bashrc << EOF
+export GOPATH=\$HOME/go
+export PATH=/usr/local/go/bin:\$PATH
+EOF
+source ~/.bashrc
+mkdir pritunl && cd pritunl
+go get -u github.com/pritunl/pritunl-dns
+go get -u github.com/pritunl/pritunl-web
+sudo ln -s ~/go/bin/pritunl-dns /usr/bin/pritunl-dns
+sudo ln -s ~/go/bin/pritunl-web /usr/bin/pritunl-web
+wget https://github.com/pritunl/pritunl/archive/$VERSION.tar.gz
+tar -xf $VERSION.tar.gz
+cd pritunl-$VERSION
+python2 setup.py build
+pip install -r requirements.txt
+python2 setup.py install --prefix=/usr/local
+```
+
+Now the MongoDB and PriTunl systemd units should be ready to start up. Assuming you're still logged in as root, enter:
+
+```
+systemctl daemon-reload
+systemctl start mongodb pritunl
+systemctl enable mongodb pritunl
+```
+
+That's it! You're ready to hit PriTunl's browser user interface and configure it by following PriTunl's [installation and configuration instructions][3] on its website.
+
+--------------------------------------------------------------------------------
+
+via: https://opensource.com/article/19/1/pritunl-vpn-raspberry-pi
+
+作者:[Stephen Bancroft][a]
+选题:[lujun9972][b]
+译者:[译者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/stevereaver
+[b]: https://github.com/lujun9972
+[1]: https://pritunl.com/
+[2]: https://github.com/pritunl/pritunl
+[3]: https://docs.pritunl.com/docs/configuration-5
diff --git a/sources/tech/20190115 Linux Tools- The Meaning of Dot.md b/sources/tech/20190115 Linux Tools- The Meaning of Dot.md
new file mode 100644
index 0000000000..5e18c7603d
--- /dev/null
+++ b/sources/tech/20190115 Linux Tools- The Meaning of Dot.md
@@ -0,0 +1,183 @@
+[#]: collector: (lujun9972)
+[#]: translator: ( )
+[#]: reviewer: ( )
+[#]: publisher: ( )
+[#]: url: ( )
+[#]: subject: (Linux Tools: The Meaning of Dot)
+[#]: via: (https://www.linux.com/blog/learn/2019/1/linux-tools-meaning-dot)
+[#]: author: (Paul Brown https://www.linux.com/users/bro66)
+
+Linux Tools: The Meaning of Dot
+======
+
+
+
+Let's face it: writing one-liners and scripts using shell commands can be confusing. Many of the names of the tools at your disposal are far from obvious in terms of what they do ( _grep_ , _tee_ and _awk_ , anyone?) and, when you combine two or more, the resulting "sentence" looks like some kind of alien gobbledygook.
+
+None of the above is helped by the fact that many of the symbols you use to build a chain of instructions can mean different things depending on their context.
+
+### Location, location, location
+
+Take the humble dot (`.`) for example. Used with instructions that are expecting the name of a directory, it means "this directory" so this:
+
+```
+find . -name "*.jpg"
+```
+
+translates to " _find in this directory (and all its subdirectories) files that have names that end in`.jpg`_ ".
+
+Both `ls .` and `cd .` act as expected, so they list and "change" to the current directory, respectively, although including the dot in these two cases is not necessary.
+
+Two dots, one after the other, in the same context (i.e., when your instruction is expecting a directory path) means " _the directory immediately above the current one_ ". If you are in _/home/your_directory_ and run
+
+```
+cd ..
+```
+
+you will be taken to _/home_. So, you may think this still kind of fits into the “dots represent nearby directories” narrative and is not complicated at all, right?
+
+How about this, then? If you use a dot at the beginning of a directory or file, it means the directory or file will be hidden:
+
+```
+$ touch somedir/file01.txt somedir/file02.txt somedir/.secretfile.txt
+$ ls -l somedir/
+total 0
+-rw-r--r-- 1 paul paul 0 Jan 13 19:57 file01.txt
+-rw-r--r-- 1 paul paul 0 Jan 13 19:57 file02.txt
+$ # Note how there is no .secretfile.txt in the listing above
+$ ls -la somedir/
+total 8
+drwxr-xr-x 2 paul paul 4096 Jan 13 19:57 .
+drwx------ 48 paul paul 4096 Jan 13 19:57 ..
+-rw-r--r-- 1 paul paul 0 Jan 13 19:57 file01.txt
+-rw-r--r-- 1 paul paul 0 Jan 13 19:57 file02.txt
+-rw-r--r-- 1 paul paul 0 Jan 13 19:57 .secretfile.txt
+$ # The -a option tells ls to show "all" files, including the hidden ones
+```
+
+And then there's when you use `.` as a command. Yep! You heard me: `.` is a full-fledged command. It is a synonym of `source` and you use that to execute a file in the current shell, as opposed to running a script some other way (which usually mean Bash will spawn a new shell in which to run it).
+
+Confused? Don't worry -- try this: Create a script called _myscript_ that contains the line
+
+```
+myvar="Hello"
+```
+
+and execute it the regular way, that is, with `sh myscript` (or by making the script executable with `chmod a+x myscript` and then running `./myscript`). Now try and see the contents of `myvar` with `echo $myvar` (spoiler: You will get nothing). This is because, when your script plunks " _Hello_ " into `myvar`, it does so in a separate bash shell instance. When the script ends, the spawned instance disappears and control returns to the original shell, where `myvar` never even existed.
+
+However, if you run _myscript_ like this:
+
+```
+. myscript
+```
+
+`echo $myvar` will print _Hello_ to the command line.
+
+You will often use the `.` (or `source`) command after making changes to your _.bashrc_ file, [like when you need to expand your `PATH` variable][1]. You use `.` to make the changes available immediately in your current shell instance.
+
+### Double Trouble
+
+Just like the seemingly insignificant single dot has more than one meaning, so has the double dot. Apart from pointing to the parent of the current directory, the double dot (`..`) is also used to build sequences.
+
+Try this:
+
+```
+echo {1..10}
+```
+
+It will print out the list of numbers from 1 to 10. In this context, `..` means " _starting with the value on my left, count up to the value on my right_ ".
+
+Now try this:
+
+```
+echo {1..10..2}
+```
+
+You'll get _1 3 5 7 9_. The `..2` part of the command tells Bash to print the sequence, but not one by one, but two by two. In other words, you'll get all the odd numbers from 1 to 10.
+
+It works backwards, too:
+
+```
+echo {10..1..2}
+```
+
+You can also pad your numbers with 0s. Doing:
+
+```
+echo {000..121..2}
+```
+
+will print out every even number from 0 to 121 like this:
+
+```
+000 002 004 006 ... 050 052 054 ... 116 118 120
+```
+
+But how is this sequence-generating construct useful? Well, suppose one of your New Year's resolutions is to be more careful with your accounts. As part of that, you want to create directories in which to classify your digital invoices of the last 10 years:
+
+```
+mkdir {2009..2019}_Invoices
+```
+
+Job done.
+
+Or maybe you have a hundreds of numbered files, say, frames extracted from a video clip, and, for whatever reason, you want to remove only every third frame between the frames 43 and 61:
+
+```
+rm frame_{043..61..3}
+```
+
+It is likely that, if you have more than 100 frames, they will be named with padded 0s and look like this:
+
+```
+frame_000 frame_001 frame_002 ...
+```
+
+That’s why you will use `043` in your command instead of just `43`.
+
+### Curly~Wurly
+
+Truth be told, the magic of sequences lies not so much in the double dot as in the sorcery of the curly braces (`{}`). Look how it works for letters, too. Doing:
+
+```
+touch file_{a..z}.txt
+```
+
+creates the files _file_a.txt_ through _file_z.txt_.
+
+You must be careful, however. Using a sequence like `{Z..a}` will run through a bunch of non-alphanumeric characters (glyphs that are neither numbers or letters) that live between the uppercase alphabet and the lowercase one. Some of these glyphs are unprintable or have a special meaning of their own. Using them to generate names of files could lead to a whole bevy of unexpected and potentially unpleasant effects.
+
+One final thing worth pointing out about sequences encased between `{...}` is that they can also contain lists of strings:
+
+```
+touch {blahg, splurg, mmmf}_file.txt
+```
+
+Creates _blahg_file.txt_ , _splurg_file.txt_ and _mmmf_file.txt_.
+
+Of course, in other contexts, the curly braces have different meanings (surprise!). But that is the stuff of another article.
+
+### Conclusion
+
+Bash and the utilities you can run within it have been shaped over decades by system administrators looking for ways to solve very particular problems. To say that sysadmins and their ways are their own breed of special would be an understatement. Consequently, as opposed to other languages, Bash was not designed to be user-friendly, easy or even logical.
+
+That doesn't mean it is not powerful -- quite the contrary. Bash's grammar and shell tools may be inconsistent and sprawling, but they also provide a dizzying range of ways to do everything you can possibly imagine. It is like having a toolbox where you can find everything from a power drill to a spoon, as well as a rubber duck, a roll of duct tape, and some nail clippers.
+
+Apart from fascinating, it is also fun to discover all you can achieve directly from within the shell, so next time we will delve ever deeper into how you can build bigger and better Bash command lines.
+
+Until then, have fun!
+
+--------------------------------------------------------------------------------
+
+via: https://www.linux.com/blog/learn/2019/1/linux-tools-meaning-dot
+
+作者:[Paul Brown][a]
+选题:[lujun9972][b]
+译者:[译者ID](https://github.com/译者ID)
+校对:[校对者ID](https://github.com/校对者ID)
+
+本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
+
+[a]: https://www.linux.com/users/bro66
+[b]: https://github.com/lujun9972
+[1]: https://www.linux.com/blog/learn/2018/12/bash-variables-environmental-and-otherwise
diff --git a/translated/talk/20170921 The Rise and Rise of JSON.md b/translated/talk/20170921 The Rise and Rise of JSON.md
deleted file mode 100644
index e5eb3b2dd6..0000000000
--- a/translated/talk/20170921 The Rise and Rise of JSON.md
+++ /dev/null
@@ -1,102 +0,0 @@
-[#]: collector: (lujun9972)
-[#]: translator: (runningwater)
-[#]: reviewer: ( )
-[#]: publisher: ( )
-[#]: subject: (The Rise and Rise of JSON)
-[#]: via: ( https://twobithistory.org/2017/09/21/the-rise-and-rise-of-json.html)
-[#]: author: (https://twobithistory.org)
-[#]: url: ( )
-
-JSON 的兴起与崛起
-======
-JSON 已经占领了全世界。当今,任何两个应用程序彼此通过网络通信时,它们很有可能在使用 JSON。它已被所有大型企业所采用:十大最受欢迎的 web API 接口(主要由 Google、Facebook 和 Twitter 提供的)列表中,仅仅只有一个 API 接口是以 XML 的格式开放数据的。Twitter 给这个 API 添加了一个说明性示例:XML 格式的支持到 2013 年结束,到时候会发布一个新版本的 API,取消 XML 格式,转而使用 JSON。JSON 也在程序编码级别和文件存储上被广泛采用:在 Stack Overflow(一个面向程序员的问答网站)上,现在更多的是关于 JSON 的问题,而不是其他的数据交换格式。
-
-![][1]
-
-XML 仍然在很多地方存在。在网页上有 SVG 和 RSS 订阅服务、Atom 提供商。Android 开发者想要获得用户权限许可时,需要在其 APP 的 `manifest` 文件中声明。此文件是 XML 格式的。XML 的替代品也不仅仅只有 JSON,现在有很多人在使用 YAML 或 Google 的 Protocol Buffers 等技术,但这些技术的受欢迎程度远不如 JSON。目前来看,JSON 是应用程序在网络之间通信的首选协议格式。
-考虑到自 2005 年来网站编程世界对 “异步 JavaScript 和 XML” 而非 “异步 JavaScript 和 JSON” 技术潜力的垂涎欲滴状态,你可以发现 JSON 在其中的主导地位是如此让人惊讶。当然了,这可能与这两种通信格式的受欢迎程度无关,仅反映出 “AJAX” 似乎比 “AJAJ” 更具吸引力。但是,即使在 2015 年时有好些人已经用 JSON 来取代 XML 了(实际上还没有很多人),我们不禁要问 XML 的噩运来的如此之快,以至于短短十年左右,“异步 JavaScript 和 XML” 这个名称就成为一个很讽刺的误称。那个十年发生了什么?JSON 怎么会在那么多应用程序中取代了 XML?现在被全世界工程师和系统所使用、依赖的这种数据格式是谁提出的?
-
-### JSON 之诞生
-
-2001 年 4 月,首个 JSON 格式的消息被发送。此消息是从旧金山湾区某车库的一台计算机发出的,这是计算机历史上重要的的时刻。Douglas Crockford 和 Chip Morningstar 是一家名为 State Software 的技术咨询公司的联合创始人,他们当时聚集在 Morningstar 的车库里测试某个想法,发出了此消息。
-
-在 “AJAX” 这个术语被创造之前, Crockford 和 Morningstar 就已经在尝试构建好用的 AJAX 应用程序了。可是浏览器对其兼容性不好。他们想要在初始页面加载后就将数据传递给应用程序,但其目标要针对所有的浏览器,这就实现不了。
-
-这在今天看来不太可信,但是要记得 2001 年的时候 Internet Explorer(IE)代表了网页浏览器的最前沿技术产品。早在 1999 年的时候,Internet Explorer 5 就支持 `XMLHttpRequest 对象原型`,开发者可以使用名为 ActiveX 的框架来访问此对象。 Crockford 和 Morningstar 可能是使用此技术来获取数据,但是在 Netscape 4 中(这是他们想要支持的另一种浏览器)就无法使用这种解决方案。为此 Crockford 和 Morningstar 只得开发不同的系统程序以兼容不同的浏览器。
-
-第一条 JSON 消息如下所示:
-
-```
-
-```
-
-消息中只有一小部分类似于今天我们所知的 JSON,本身其实是一个包含有 JavaScript 的 HTML 文档。类似于 JSON 的部分只是传递给名为`receive()` 的函数的 JavaScript 对象。
-
-Crockford 和 Morningstar 决定滥用 HTML 的 frame,以发送数据。敲入 URL 返回的 HTML 文档(如上所示)可以指向一个 frame 标签。当接收到 HTML 时,JavaScript 代码段一运行,就可以把数据对象如实地传递回应用程序。只要小心的回避浏览器保护策略,即子窗口不允许访问父窗口,这种技术就可以正常运行无误。可以看到 Crockford 和 Mornginstar 通过明确地设置文档域这种方法来达到其目的。(这种基于 frame 的技术,有时称为隐藏 frame 技术,通常在90年代后期,即广泛使用 XMLHttpRequest 技术之前使用。)
-
-关于第一个 JSON 消息的惊人之处在于它显然不是第一次就使用新的数据格式。它仅仅是 JavaScript!实际上,以此使用 JavaScript 的想法如此简单,Crockford 自己也说过他不是第一个这样做的人。他声称 Netscape 公司的某人早在 1996 年就使用 JavaScript 数组文字来交换信息。因为消息就是 JavaScript 本身,其不需要任何特殊解析工作,JavaScript 解释器就可搞定一切。
-
-最初的 JSON 信息实际上与 JavaScript 解释器发生了冲突。JavaScript 使用了大量的单词来做为保留字(ECMAScript 6 版本的就有 64 个保留字),Crockford 和 Morningstar 无意中在其 JSON 中引入了一个保留字。他们使用了 `do` 这个关键字,但 `do` 是解释器中的保留字。因为 JavaScript 使用的保留字太多了,Crockford 做了决定:既然不可避免的要使用到这些保留字,那就要求所有的 JSON 关键字都加上引号。被引起来的关键字会被 JavaScript 解释器识别成字符串,其意味着那些保留字也可以放心安全的使用。这就为什么今天 JSON 关键字都要用引号引起来的原因。
-
-Crockford 和 Morningstar 意识到这技术可以应用于各类应用系统。想给其命名为 “JSML”,即 JavaScript 标记语言,但发现这个缩写已经被叫做 Java 标记语言的所使用了。因此他们决定采用 “JavaScript Object Notation” 或 JSON 命名。他们开始向客户推销,但很快发现客户不愿意冒险使用缺乏官方规范的未知技术。所以 Crockford 决定写一个规范。
-
-2002 年,Crockford 买下了 [JSON.org][2] 域名,放上了 JSON 语法及一个解释器的实例例子。网站仍然在运行,现在已经包含有 2013 年正式批准的 JSON ECMA 标准的显著链接。在网站建立后,Crockford 并没有过多的推广,但很快发现很多人都在提交各种不同编程语言的 JSON 解析器实现。JSON 的血统明显与 JavaScript 相关联,但很明显 JSON 非常适合于不同语言之间的数据交换。
-
-
-### AJAX 导致的误会
-
-2005 年,JSON 有了一次大扩展。那一年,一位名叫 Jesse James Garrett 的网页设计师和开发人员在博客文章中创造了 “AJAX” 一词。他很谨慎地强调:AJAX 并不是新技术,而是 “好几种技术以某种强大的新方式汇集,其中的各技术各自发展。” AJAX 是 Garrett 给 Web 应用程序开发的新方法(其正获得青睐)的命名。他的博客文章接着描述了开发人员如何利用 JavaScript 和 XMLHttpRequest 对象构建新的应用程序,这些应用程序比传统的网页更具响应性和状态性。 他还举了 Gmail 和 Flickr的网站已经使用 AJAX 技术的例子。
-
-当然了,“AJAX” 中的 “X” 代表 XML。但在随后的问答帖子中,Garrett 指出,JSON 可以完全替代 XML。他写道:虽然 XML 是 AJAX 客户端进行数据输入输出的最完善的技术,但要实现同样的效果,也可以使用像 JavaScript Object Notation (JSON)或任何类似的结构数据方法等技术。
-
-开发者确实发现在构建 AJAX 应用程序时可以很容易的使用 JSON,并且很多人也开始喜欢上 XML。具有讽刺意味的是,对 AJAX 的兴趣逐渐的导致了 JSON 的普及。大约在这个时候,JSON 引起了博客圈的注意。
-
-2006 年,Dave Winer,一位高产的博主,也是许多基于 XML 技术(如 RSS 和 XML-RPC)的后端开发工程师,他抱怨到 JSON 毫无疑问的正在重新发明 XML。虽然他认为数据交换格式之间的竞争不会导致某一技术的消亡,其写到:
-
-> 让我们来比较下重构某结构数据的深度及难度,由于某些原因(我很想听听原因),XML 自身做的并不好,所以毫无疑问地,我会写一个例程来解析 JSON 格式的数据。谁想干这荒谬之事?查找一棵树然后把节点串起来。可以立马试试。
-
-很容易理解 Winer 的挫败感,事实上并没有太多人喜欢 XML。甚至 Winer 也说过他不喜欢 XML。但 XML 已被设计成一个可供任何人使用,并且几乎能想象到的事情都可以做到的系统。最终,XML 实际上是一门元语言,允许你为特定应用程序自定义特定域的语言。如 RSS、web feed 技术和 SOAP(简单对象访问协议)就是自定义的例子。Winer 认为由于通用交换格式所带来的好处,努力达成共识就很重要了。XML 的灵活性应该能满足任何人的需求,然而这里是 JSON 格式,其并不比 XML 更具优势,但其抛弃了 XML 中不好的设计,可以使 XML 更加的灵活。
-
-Crockford 阅读了 Winer 的这篇文章并留下了评论。为了回应 JSON 重新发明 XML 的指责,Crockford 写到:重造轮子的好处是可以得到一个更好的轮子。
-
-### JSON 与 XML 对比
-
-到 2014 年,JSON 已经由 ECMA 标准和 RFC 官方正式认可。它有自己的 MIME 类型。JSON 已经进入了大联盟时代。
-
-为什么 JSON 比 XML 更受欢迎?
-
-在 [JSON.org][2] 网站上,Crockford 总结了一些 JSON 的优势。他写到,JSON 的语法很小,其结构可预测,因此 JSON 更容易被人类和机器理解。其他博主不得不关注 XML 的冗长啰嗦及“尖括号负担”。XML 中每个开始标记都必须与结束标记匹配,这意味着 XML 文档包含大量的冗余信息。在未压缩时,XML 文档的体积比同信息量 JSON 文档的体积大很多,但是,更重要的,这也使 XML 文档更难以阅读。
-
-Crockford 还声称 JSON 的另一个巨大优势是其被设计为数据交换格式。从一开始,它的目的就是在应用程序间传递结构化信息的。而 XML 呢,虽然也可以使用来传递数据,但其最初被设计为文档标记语言。它从 SGML(通用标准标记语言)演变而来,后来又从称为 Scribe 的标记语言是发展,旨在发展成类似于 LaTeX 一样的文字处理系统。XML 中,一个标签可以包含有所谓的“混合内容”或包含有围绕单词、短语的内嵌标签的文本。这会让人浮现出一副用红蓝笔记录的手稿画面,这是标记语言核心思想的形象比喻。另一方面,JSON 不支持对混合内容模型清晰构建,但也意味着它的结构足够简单。一份文档最好的建模就是一棵树,但 JSON 抛弃了文档的思想,Crockford 将 JSON 抽象限制为字典和数组,这是所有程序员构建程序时都会使用的最基本也最熟悉的元素。
-
-最后,我认为人们不喜欢 XML 是因为它让人困惑。它让人迷惑的地方就是有很多不同的风格。乍一看,XML 本身及其子语言(如 RSS、ATOM、SOAP 或 SVG)之间的界限并不明显。通用 XML 文档创建的版本做为第一个基线,然后特定的子语言 XML 版本应该在这基础上变动。这就有需要变化需要考虑的了,特别是跟 JSON 做比较。JSON 的是如此简单,以至于 JSON 新版本规范甚至都不用重写。XML 的设计者试图将 XML 做为唯一的数据交换格式以支配所有格式,会掉入那个经典程序员的陷阱:过度工程化。XML 非常笼统及概念化,所以很难于简单的使用。
-
-在 2000 年的时候,推出了一场活动,以使 HTML 符合 XML 标准。发布了一份符合 XML 标准的 HTML 开发规范,这就此后很出名的 XHTML。虽然一些浏览器供应商立即开始支持这个新标准,但也很明显,大部分基于 HTML 技术的开发者不愿意改变他们的习惯。新标准要求对 XHTML 文档进行严格的验证,而不是基于 HTML 的基准。但大多的网站都是依赖于 HTML 的宽容规则的。到 2009 年的时候,试图编写第二版本的 XHTML 标准已经流产,因为未来已清晰可见, HTML 将会发展为 HTML5(一种不强制要求接受 XML 规则的标准)。
-
-如果 XHTML 的努力取得了成功,那么 XML 可能会成为其设计者希望的通用数据格式。想象一下,HTML 文档和 API 响应具有完全相同结构的世界。在这样的世界中,JSON 可能不会像现在一样普遍存在。但我读懂了, XHTML 的失败是 XML 阵营的一种道德失败。如果 XML 不是 HTML 的最佳工具,那么为了其他应用程序,也许会有更好的工具出现。在这个世界,我们的世界,很容易看到像 JSON 格式这样的足够简单、量体裁衣才能获得更大的成功。
-
-如果你喜欢这博文,每两周会更新一次! 请在 Twitter 上关注 [@TwoBitHistory] [3] 或订阅 [RSS feed] [4], 以确保得到更新的通知。
-
---------------------------------------------------------------------------------
-
-via: https://twobithistory.org/2017/09/21/the-rise-and-rise-of-json.html
-
-作者:[Two-Bit History][a]
-选题:[lujun9972][b]
-译者:[runningwater](https://github.com/runningwater)
-校对:[校对者ID](https://github.com/校对者ID)
-
-本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
-
-[a]: https://twobithistory.org
-[b]: https://github.com/lujun9972
-[1]: https://twobithistory.org/images/json.svg
-[2]: http://JSON.org
-[3]: https://twitter.com/TwoBitHistory
-[4]: https://twobithistory.org/feed.xml
diff --git a/translated/talk/20180419 5 guiding principles you should know before you design a microservice.md b/translated/talk/20180419 5 guiding principles you should know before you design a microservice.md
new file mode 100644
index 0000000000..6eee610d0b
--- /dev/null
+++ b/translated/talk/20180419 5 guiding principles you should know before you design a microservice.md
@@ -0,0 +1,155 @@
+设计微服务架构前,您应该了解的5项指导原则
+======
+
+
+对于从微服务开始的团队来说,最大的挑战之一就是坚持金发姑娘原则(The *Goldilocks principle*):不要太大, 不要太小,不能太紧密耦合。之所以是挑战的原因是会对究竟什么是设计良好的微服务感到疑惑。
+
+数十家 CTOs 通过采访分享了他们的经验, 这些对话说明了设计良好的微服务的五个特点。本文将帮助指导团队设计微服务。(有关详细信息, 请查看即将出版的书籍 [Microservices for Startups][1])。本文将简要介绍微服务的边界和主观的 ”规则“,以避免在深入了解五个特征之前就开始指导您的微服务设计。
+
+### 微服务边界
+
+ [core benefits of developing new systems with microservices][2] (开发具有微服务的新系统的核心优势)其中之一是该体系结构允许开发人员独立构建和修改单个组件, 但在最大限度地减少每个 API 之间的回调数量方面可能会出现问题。 根据 Chris McFadden 的解决方法,[SparkPost ][3] 的工程副总裁,应用适当的服务边界去解决问题。
+
+关于边界, 与 domain-driven design (DDD)—a framework for microservices (域驱动设计--微服务框架)有时难以理解和抽象的概念形成鲜明对比,本文重点介绍了与我们行业的一些顶级 CTOs 建立明确定义的微服务边界的实用原则。
+
+### 避免主观的 ”规则“
+
+如果您阅读了足够多的关于设计和创建微服务的建议,您一定会遇到下面的一些 ”规则“。 尽管将它们用作创建微服务的指南很有吸引力, 但加入这些主观规则并不是思考确定微服务的边界的原则性方式。
+
+#### ”微服务应该有 X 行代码“
+
+让我们直说:微服务中有多少行代码没有限制。微服务不会因为您写了几行额外的代码而突然变成一个巨无霸。关键是要确保服务中的代码具有很高的内聚性 (稍后将对此进行更多介绍)。
+
+#### “将每个功能转换为微服务”
+
+如果函数基于三个输入值计算某些内容并返回结果,它是否是微服务的理想候选项?它是否应该是单独可部署应用程序?这确实取决于函数是什么以及它是如何服务于整个系统。将每个函数转换为微服务在您的内容中可能根本没有意义。
+
+其他主观规则包括不考虑整个内容的规则, 例如团队的经验、 DevOps (Development和Operations的组合词)容量、服务正在执行的操作以及数据的可用性需求。
+
+### 精心设计的服务的5个特点
+
+如果您读过关于微服务的文章, 您无疑会遇到关于什么是设计良好的服务的建议。简单地说, 高内聚和低耦合。如果您不熟悉这些概念, 有许多文章需要查看 [many][4] [articles][5] 。虽然他们提供了合理的建议,但这些概念是相当抽象的。下面, 基于与经验丰富的 CTOs 的对话, 在创建设计良好的微服务时需要牢记的关键特征。
+
+#### #1: 不与其他服务共享数据库表
+
+在 SparkPost 的早期, Chris McFadden 和他的团队必须解决一个问题,,每个 SaaS 生意(Software-as-a-Service,软件即服务)都要面对的:他们需要提供基本服务,如身份验证、帐户管理和计费。
+
+为了解决这个问题,他们创建了两个微服务:用户 API 和帐户 API。用户 API 将处理用户帐户、API 密钥和身份验证,而帐户 API 将处理所有与计费相关的逻辑。一个非常符合逻辑的分离--但没过多久,他们发现了一个问题。
+
+McFadden 解释说,“我们有一个名为 ”用户 API “的服务,还有一个名为”帐户 API “的服务。问题是,他们之间实际上有几个来回的电话。因此, 您会在帐户中执行一些操作,并在用户中具有调用和终结点,反之亦然”
+
+这两个服务的耦合太紧密了。
+
+在设计微服务时, 如果您有多个服务引用同一个表, 则它是一个危险的信号,因为这可能意味着您的数据库是耦合的源头。
+
+这确实是关于服务与数据的关系, 这正是Oleksiy Kovrin,[Swiftype SRE, Elastic][6] 的领导者, 告诉我。“我们在开发新服务时使用的主要基本原则之一是, 它们不应跨越数据库边界。每个服务都应依赖于自己的一组基础数据存储。这使我们能够集中访问控制、审计日志记录、缓存逻辑等。”
+
+Kovrin 接着解释说,如果数据库表的子集 “与数据集的其余部分没有或很少连接,则这是一个强烈的信号, 表明组件可以被隔离到单独的 API 或单独的服务中”。
+
+Darby Frey , [Lead Honestly][7] 的联合创始人,与此的观点相呼应:”每个服务都应该有自己的表 [并且] 永远不应该共享数据库表。“
+
+#### #2: 数据库表数量最小化
+
+微服务的理想尺寸足够小,但不会更小。每个服务的数据库表的数量也是如此。
+
+Steven Czerwinski,[Scaylr][8] 的工程主管, 在接受采访时解释说 Scaylr 的最佳选择是 ”一个或两个服务的数据库表“。
+
+SparkPost's Chris McFadden 同意:”我们有一个(suppression)限制微服务,它处理, 跟踪, 数以百万计和数十亿的条目周围的限制,但它都非常集中只是围绕限制,所以实际上只有一个或两个表。其他服务也是如此,比如 *webhooks* 。
+
+#### #3: 考虑有状态和无状态
+
+在设计微服务时,您需要问问自己它是否需要访问数据库,或者它是否会是处理 TB 级数据 (如电子邮件或日志) 的无状态服务。
+
+Julien Lemoine, [Algolia][9] 的 CTO,解释说::“我们通过定义服务的输入和输出来定义服务的边界。有时服务是网络 API ,但它也可能是在数据库中使用文件和生成记录的进程 (这就是我们的日志处理服务)。
+
+事先要清楚状态,这将引导一个更好的服务设计。
+
+#### #4: 考虑数据可用性需求
+
+在设计微服务时,请记住哪些服务将依赖于此新服务, 以及在该数据不可用时的全系统影响。考虑到这一点,您可以正确地设计此服务的数据备份和恢复系统。
+
+Steven Czerwinski 在 Scaylr 提到,由于关键客户行空间映射数据的重要性,它将以不同的方式复制和分离。
+
+他补充说,”每个分片信息,在自己的小分区里。如果因为这部分客户群体不会有他们的可用日志而下降,那很糟糕,但它只影响5% 的客户,而不是100% 的客户。
+
+#### #5: 真理的唯一来源
+
+设计服务,使其成为系统中某些内容的唯一实际来源
+
+例如,当您从电子商务网站订购内容时, 则会生成订单 ID ,其他服务可以使用此订单 ID 来查询订单服务,以获取有关订单的完整信息。使用 [publish/subscribe pattern][10] ,在服务之间传递的数据应该是订单 ID , 而不是订单本身的属性信息。只有订单服务具有完整的信息,并且是给定订单的唯一实际来源。
+
+### 大型团队的注意事项
+
+考虑到上面列出的五个注意事项,较大的团队应了解其组织结构对微服务边界的影响。
+
+对于大型组织,整个团队可以专门拥有服务,在确定服务边界时, 有组织性的考虑因素就会发挥作用。还有两个需要考虑的因素: **独立的发布计划**和**不同的正常运行时间**的重要性。
+
+Khash Sajadi , [Cloud66.][11] 的 CEO 说:”我们所看到的微服务最成功的实现要么基于软件设计原则 (例如域驱动设计和面向服务的体系结构), 要么基于反映组织方法的设计原则“
+
+”所以 (对于) 支付团队“ Sajadi 继续说,,”他们有支付服务或信用卡验证服务, 这就是他们向外界提供的服务。所以这不一定是关于软件的。这主要是关于为外界提供更多服务的业务单位 “
+
+### 双披萨原理
+
+Amazon 是一个拥有多个团队的大型组织的完美示例。正如在一篇文章中所提到的, [API Evangelist][12] ,Jeff Bezos向所有员工发出授权,告知他们公司内的每个团队都必须通过 API 进行沟通。任何没有被解雇的人都会被解雇。
+
+这样,所有数据和功能都通过接口公开。Bezos 还设法让每个团队分离,定义他们的资源是什么, 并通过 API 使它们可用。亚马逊正在从地面上建立一个系统。这使得公司内的每一支团队都能成为彼此的合作伙伴。
+
+Travis Reeder , [Iron.io][13] 的CTO,谈论关于 Bezos 的内部提议。
+
+”Jeff Bezos 规定所有团队都必须构建 API 才能与其他团队进行沟通,“ Reeder 说。”他也是提出‘双披萨’规则的人:一支球队不应该比两个比萨饼能养活的大。
+
+“我认为这里也可以适用同样的方法:无论一个小型团队是否能够开发、管理和富有成效。如果它开始变得笨重或开始后退。可能会变得太大” Reeder 告诉我。
+
+### 最后注意事项: 您的服务是否具有正确的大小和正确定义?
+
+在微服务系统的测试和实施阶段,有一些指标需要记住。
+
+#### 指标 #1: 服务之间是否存在过度依赖?
+
+如果两个服务不断地相互回调,那么这就是耦合的强烈信号,也是它们可能更好地合并为一个服务的信号。
+
+回到 Chris McFadden 的例子, 他有两个 API 服务、帐户和用户不断地相互通信, McFadden 提出了一个合并服务的想法, 并决定将其称为 “原告 API”。事实证明, 这是一项富有成效的战略。”我们开始做的是消除这些链接 [这是] 内部 API 调用投注他们之间“ McFadden 告诉我。这有助于简化代码。
+
+#### 指标 #2: 设置服务的开销是否超过了服务独立的好处?
+
+Darby Frey 解释说,“每个应用都需要将其日志聚合到某个位置,并需要进行监视。你需要设置它的警报。你需要有标准的作业程序,并在事情发生时运行书籍。您必须管理 SSH 对该事物的访问。为了让一个应用单纯运行, 必须存在一个巨大的基础。
+
+### 主要外包
+
+设计微服务往往会让人感觉更像是一门艺术, 而不是一门科学。对工程师来说, 这可能不是很好。外面有很多一般性的建议, 但有时可能有点太抽象了。让我们回顾一下在设计下一组微服务时要注意的五个具体特征:
+
+ 1. 不与其他服务共享数据库表
+ 2. 数据库表数量最小化
+ 3. 考虑有状态和无状态
+ 4. 考虑数据可用性需求
+ 5. 真理的唯一来源
+
+
+
+下次设计一组微服务并确定服务边界时,回顾这些原则应该会使任务变得更容易。
+
+--------------------------------------------------------------------------------
+
+via: https://opensource.com/article/18/4/guide-design-microservices
+
+作者:[Jake Lumetta][a]
+选题:[lujun9972](https://github.com/lujun9972)
+译者:[lixinyuxx](https://github.com/lixinyuxx)
+校对:[校对者ID](https://github.com/校对者ID)
+
+本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
+
+[a]:https://opensource.com/users/jakelumetta
+[1]:https://buttercms.com/books/microservices-for-startups/
+[2]:https://buttercms.com/books/microservices-for-startups/should-you-always-start-with-a-monolith
+[3]:https://www.sparkpost.com/
+[4]:https://thebojan.ninja/2015/04/08/high-cohesion-loose-coupling/
+[5]:https://en.wikipedia.org/wiki/Single_responsibility_principle
+[6]:https://www.elastic.co/solutions/site-search
+[7]:https://leadhonestly.com/
+[8]:https://www.scalyr.com/
+[9]:https://www.algolia.com/
+[10]:https://en.wikipedia.org/wiki/Publish%E2%80%93subscribe_pattern
+[11]:https://www.cloud66.com/
+[12]:https://apievangelist.com/2012/01/12/the-secret-to-amazons-success-internal-apis/
+[13]:https://www.iron.io/
diff --git a/translated/tech/20120201 Computer Laboratory - Raspberry Pi- Lesson 1 OK01.md b/translated/tech/20120201 Computer Laboratory - Raspberry Pi- Lesson 1 OK01.md
new file mode 100644
index 0000000000..43c76fa0c5
--- /dev/null
+++ b/translated/tech/20120201 Computer Laboratory - Raspberry Pi- Lesson 1 OK01.md
@@ -0,0 +1,233 @@
+[#]: collector: (lujun9972)
+[#]: translator: (qhwdw)
+[#]: reviewer: (wxy)
+[#]: publisher: ( )
+[#]: url: ( )
+[#]: subject: (Computer Laboratory – Raspberry Pi: Lesson 1 OK01)
+[#]: via: (https://www.cl.cam.ac.uk/projects/raspberrypi/tutorials/os/ok01.html)
+[#]: author: (Robert Mullins http://www.cl.cam.ac.uk/~rdm34)
+
+计算机实验室之树莓派:课程 1 OK01
+======
+
+OK01 课程讲解了树莓派如何入门,以及在树莓派上如何启用靠近 RCA 和 USB 端口的 OK 或 ACT 的 LED 指示灯。这个指示灯最初是为了指示 OK 状态的,但它在第二版的树莓派上被改名为 ACT。
+
+### 1、入门
+
+我们假设你已经访问了[下载][1]页面,并且已经获得了必需的 GNU 工具链。也下载了一个称为操作系统模板的文件。请下载这个文件并在一个新目录中解开它。
+
+### 2、开始
+
+现在,你已经展开了这个模板文件,在 `source` 目录中创建一个名为 `main.s` 的文件。这个文件包含了这个操作系统的代码。具体来看,这个文件夹的结构应该像下面这样:
+
+```
+build/
+ (empty)
+source/
+ main.s
+kernel.ld
+LICENSE
+Makefile
+```
+
+用文本编辑器打开 `main.s` 文件,这样我们就可以输入汇编代码了。树莓派使用了称为 ARMv6 的汇编代码变体,这就是我们即将要写的汇编代码类型。
+
+> 扩展名为 `.s` 的文件一般是汇编代码,需要记住的是,在这里它是 ARMv6 的汇编代码。
+
+首先,我们复制下面的这些命令。
+
+```
+.section .init
+.globl _start
+_start:
+```
+
+实际上,上面这些指令并没有在树莓派上做任何事情,它们是提供给汇编器的指令。汇编器是一个转换程序,它将我们能够理解的汇编代码转换成树莓派能够理解的机器代码。在汇编代码中,每个行都是一个新的命令。上面的第一行告诉汇编器 [^1] 在哪里放我们的代码。我们提供的模板中将它放到一个名为 `.init` 的节中的原因是,它是输出的起始点。这很重要,因为我们希望确保我们能够控制哪个代码首先运行。如果不这样做,首先运行的代码将是按字母顺序排在前面的代码!`.section` 命令简单地告诉汇编器,哪个节中放置代码,从这个点开始,直到下一个 `.section` 或文件结束为止。
+
+```
+在汇编代码中,你可以跳行、在命令前或后放置空格去提升可读性。
+```
+
+接下来两行是停止一个警告消息,它们并不重要。[^2]
+
+### 3、第一行代码
+
+现在,我们正式开始写代码。计算机执行汇编代码时,是简单地一行一行按顺序执行每个指令,除非明确告诉它不这样做。每个指令都是开始于一个新行。
+
+复制下列指令。
+
+```
+ldr r0,=0x20200000
+```
+
+> `ldr reg,=val` 将数字 `val` 加载到名为 `reg` 的寄存器中。
+
+那是我们的第一个命令。它告诉处理器将数字 `0x20200000` 保存到寄存器 `r0` 中。在这里我需要去回答两个问题,寄存器是什么?`0x20200000` 是一个什么样的数字?
+
+寄存器在处理器中就是一个极小的内存块,它是处理器保存正在处理的数字的地方。处理器中有很多寄存器,很多都有专门的用途,我们在后面会一一接触到它们。最重要的有十三个(命名为 `r0`、`r1`、`r2`、…、`r9`、`r10`、`r11`、`r12`),它们被称为通用寄存器,你可以使用它们做任何计算。由于是写我们的第一行代码,我们在示例中使用了 `r0`,当然你可以使用它们中的任何一个。只要后面始终如一就没有问题。
+
+> 树莓派上的一个单独的寄存器能够保存任何介于 `0` 到 `4,294,967,295`(含)之间的任意整数,它可能看起来像一个很大的内存,实际上它仅有 32 个二进制比特。
+
+`0x20200000` 确实是一个数字。只不过它是以十六进制表示的。下面的内容详细解释了十六进制的相关信息:
+
+> 延伸阅读:十六进制解释
+
+> 十六进制是另一种表示数字的方式。你或许只知道十进制的数字表示方法,十进制共有十个数字:`0`、`1`、`2`、`3`、`4`、`5`、`6`、`7`、`8` 和 `9`。十六进制共有十六个数字:`0`、`1`、`2`、`3`、`4`、`5`、`6`、`7`、`8`、`9`、`a`、`b`、`c`、`d`、`e` 和 `f`。
+
+> 你可能还记得十进制是如何用位制来表示的。即最右侧的数字是个位,紧接着的左边一位是十位,再接着的左边一位是百位,依此类推。也就是说,它的值是 100 × 百位的数字,再加上 10 × 十位的数字,再加上 1 × 个位的数字。
+
+> ![567 is 5 hundreds, 6 tens and 7 units.][2]
+
+> 从数学的角度来看,我们可以发现规律,最右侧的数字是 100 = 1s,紧接着的左边一位是 101 = 10s,再接着是 102 = 100s,依此类推。我们设定在系统中,0 是最低位,紧接着是 1,依此类推。但如果我们使用一个不同于 10 的数字为幂底会是什么样呢?我们在系统中使用的十六进制就是这样的一个数字。
+
+> ![567 is 5x10^2+6x10^1+7x10^0][3]
+
+> ![567 = 5x10^2+6x10^1+7x10^0 = 2x16^2+3x16^1+7x16^0][4]
+
+> 上面的数学等式表明,十进制的数字 567 等于十六进制的数字 237。通常我们需要在系统中明确它们,我们使用下标 10 表示它是十进制数字,用下标 16 表示它是十六进制数字。由于在汇编代码中写上下标的小数字很困难,因此我们使用 0x 来表示它是一个十六进制的数字,因此 0x237 的意思就是 23716 。
+
+> 那么,后面的 `a`、`b`、`c`、`d`、`e` 和 `f` 又是什么呢?好问题!在十六进制中为了能够写每个数字,我们就需要额外的东西。例如 916 = 9×160 = 910 ,但是 1016 = 1×161 + 1×160 = 1610 。因此,如果我们只使用 0、1、2、3、4、5、6、7、8 和 9,我们就无法写出 1010 、1110 、1210 、1310 、1410 、1510 。因此我们引入了 6 个新的数字,这样 a16 = 1010 、b16 = 1110 、c16 = 1210 、d16 = 1310 、e16 = 1410 、f16 = 1510 。
+
+> 所以,我们就有了另一种写数字的方式。但是我们为什么要这么麻烦呢?好问题!由于计算机总是工作在二进制中,事实证明,十六进制是非常有用的,因为每个十六进制数字正好是四个二进制数字的长度。这种方法还有另外一个好处,那就是许多计算机的数字都是十六进制的整数倍,而不是十进制的整数倍。比如,我在上面的汇编代码中使用的一个数字 2020000016 。如果我们用十进制来写,它就是一个不太好记住的数字 53896806410 。
+
+> 我们可以用下面的简单方法将十进制转换成十六进制:
+
+> ![Conversion example][5]
+
+> 1. 我们以十进制数字 567 为例来说明。
+> 2. 将十进制数字 567 除以 16 并计算其余数。例如 567 ÷ 16 = 35 余数为 7。
+> 3. 在十六进制中余数就是答案中的最后一位数字,在我们的例子中它是 7。
+> 4. 重复第 2 步和第 3 步,直到除法结果的整数部分为 0。例如 35 ÷ 16 = 2 余数为 3,因此 3 就是答案中的下一位。2 ÷ 16 = 0 余数为 2,因此 2 就是答案的接下来一位。
+> 5. 一旦除法结果的整数部分为 0 就结束了。答案就是反序的余数,因此 56710 = 23716。
+
+> 转换十六进制数字为十进制,也很容易,将数字展开即可,因此 23716 = 2×162 + 3×161 +7 ×160 = 2×256 + 3×16 + 7×1 = 512 + 48 + 7 = 567。
+
+因此,我们所写的第一个汇编命令是将数字 2020000016 加载到寄存器 `r0` 中。那个命令看起来似乎没有什么用,但事实并非如此。在计算机中,有大量的内存块和设备。为了能够访问它们,我们给每个内存块和设备指定了一个地址。就像邮政地址或网站地址一样,它用于标识我们想去访问的内存块或设备的位置。计算机中的地址就是一串数字,因此上面的数字 2020000016 就是 GPIO 控制器的地址。这个地址是由制造商的设计所决定的,他们也可以使用其它地址(只要不与其它的冲突即可)。我之所以知道这个地址是 GPIO 控制器的地址是因为我看了它的手册,[^3] 地址的使用没有专门的规范(除了它们都是以十六进制表示的大数以外)。
+
+### 4、启用输出
+
+![A diagram showing key parts of the GPIO controller.][6]
+
+阅读了手册可以得知,我们需要给 GPIO 控制器发送两个消息。我们必须用它的语言告诉它,如果我们这样做了,它将非常乐意实现我们的意图,去打开 OK 的 LED 指示灯。幸运的是,它是一个非常简单的芯片,为了让它能够理解我们要做什么,只需要给它设定几个数字即可。
+
+```
+mov r1,#1
+lsl r1,#18
+str r1,[r0,#4]
+```
+
+> `mov reg,#val` 将数字 `val` 放到名为 `reg` 的寄存器中。
+
+> `lsl reg,#val` 将寄存器 `reg` 中的二进制操作数左移 `val` 位。
+
+> `str reg,[dest,#val]` 将寄存器 `reg` 中的数字保存到地址 `dest + val` 上。
+
+这些命令的作用是在 GPIO 的第 16 号插针上启用输出。首先我们在寄存器 `r1` 中获取一个必需的值,接着将这个值发送到 GPIO 控制器。因此,前两个命令是尝试取值到寄存器 `r1` 中,我们可以像前面一样使用另一个命令 `ldr` 来实现,但 `lsl` 命令对我们后面能够设置任何给定的 GPIO 针比较有用,因此从一个公式中推导出值要比直接写入来好一些。表示 OK 的 LED 灯是直接连线到 GPIO 的第 16 号针脚上的,因此我们需要发送一个命令去启用第 16 号针脚。
+
+寄存器 `r1` 中的值是启用 LED 针所需要的。第一行命令将数字 110 放到 `r1` 中。在这个操作中 `mov` 命令要比 `ldr` 命令快很多,因为它不需要与内存交互,而 `ldr` 命令是将需要的值从内存中加载到寄存器中。尽管如此,`mov` 命令仅能用于加载某些值。[^4] 在 ARM 汇编代码中,基本上每个指令都使用一个三字母代码表示。它们被称为助记词,用于表示操作的用途。`mov` 是 “move” 的简写,而 `ldr` 是 “load register” 的简写。`mov` 是将第二个参数 `#1` 移动到前面的 `r1` 寄存器中。一般情况下,`#` 肯定是表示一个数字,但我们已经看到了不符合这种情况的一个反例。
+
+第二个指令是 `lsl`(逻辑左移)。它的意思是将第一个参数的二进制操作数向左移第二个参数所表示的位数。在这个案例中,将 110 (即 12 )向左移 18 位(将它变成 10000000000000000002=26214410 )。
+
+如果你不熟悉二进制表示法,可以看下面的内容:
+
+> 延伸阅读: 二进制解释
+
+> 与十六进制一样,二进制是写数字的另一种方法。在二进制中只有两个数字,即 `0` 和 `1`。它在计算机中非常有用,因为我们可以用电路来实现它,即电流能够通过电路表示为 `1`,而电流不能通过电路表示为 `0`。这就是计算机能够完成真实工作和做数学运算的原理。尽管二进制只有两个数字,但它却能够表示任何一个数字,只是写起来有点长而已。
+
+> ![567 in decimal = 1000110111 in binary][7]
+
+> 这个图片展示了 56710 的二进制表示是 10001101112 。我们使用下标 2 来表示这个数字是用二进制写的。
+
+> 我们在汇编代码中大量使用二进制的其中一个巧合之处是,数字可以很容易地被 `2` 的幂(即 `1`、`2`、`4`、`8`、`16`)乘或除。通常乘法和除法都是非常难的,而在某些特殊情况下却变得非常容易,所以二进制非常重要。
+
+> ![13*4 = 52, 1101*100=110100][8]
+
+> 将一个二进制数字左移 `n` 位就相当于将这个数字乘以 2n。因此,如果我们想将一个数乘以 4,我们只需要将这个数字左移 2 位。如果我们想将它乘以 256,我们只需要将它左移 8 位。如果我们想将一个数乘以 12 这样的数字,我们可以有一个替代做法,就是先将这个数乘以 8,然后再将那个数乘以 4,最后将两次相乘的结果相加即可得到最终结果(N × 12 = N × (8 + 4) = N × 8 + N × 4)。
+
+> ![53/16 = 3, 110100/10000=11][9]
+
+> 右移一个二进制数 `n` 位就相当于这个数除以 2n 。在右移操作中,除法的余数位将被丢弃。不幸的是,如果对一个不能被 2 的幂次方除尽的二进制数字做除法是非常难的,这将在 [课程 9 Screen04][10] 中讲到。
+
+> ![Binary Terminology][11]
+
+> 这个图展示了二进制常用的术语。一个比特就是一个单独的二进制位。一个“半字节“ 是 4 个二进制位。一个字节是 2 个半字节,也就是 8 个比特。半字是指一个字长度的一半,这里是 2 个字节。字是指处理器上寄存器的大小,因此,树莓派的字长是 4 字节。按惯例,将一个字最高有效位标识为 31,而将最低有效位标识为 0。顶部或最高位表示最高有效位,而底部或最低位表示最低有效位。一个 kilobyte(KB)就是 1000 字节,一个 megabyte 就是 1000 KB。这样表示会导致一些困惑,到底应该是 1000 还是 1024(二进制中的整数)。鉴于这种情况,新的国际标准规定,一个 KB 等于 1000 字节,而一个 Kibibyte(KiB)是 1024 字节。一个 Kb 是 1000 比特,而一个 Kib 是 1024 比特。
+
+> 树莓派默认采用小端法,也就是说,从你刚才写的地址上加载一个字节时,是从一个字的低位字节开始加载的。
+
+再强调一次,我们只有去阅读手册才能知道我们所需要的值。手册上说,GPIO 控制器中有一个 24 字节的集合,由它来决定 GPIO 针脚的设置。第一个 4 字节与前 10 个 GPIO 针脚有关,第二个 4 字节与接下来的 10 个针脚有关,依此类推。总共有 54 个 GPIO 针脚,因此,我们需要 6 个 4 字节的一个集合,总共是 24 个字节。在每个 4 字节中,每 3 个比特与一个特定的 GPIO 针脚有关。我们想去启用的是第 16 号 GPIO 针脚,因此我们需要去设置第二组 4 字节,因为第二组的 4 字节用于处理 GPIO 针脚的第 10-19 号,而我们需要第 6 组 3 比特,它在上面的代码中的编号是 18(6×3)。
+
+最后的 `str`(“store register”)命令去保存第一个参数中的值,将寄存器 `r1` 中的值保存到后面的表达式计算出来的地址上。这个表达式可以是一个寄存器,在上面的例子中是 `r0`,我们知道 `r0` 中保存了 GPIO 控制器的地址,而另一个值是加到它上面的,在这个例子中是 `#4`。它的意思是将 GPIO 控制器地址加上 `4` 得到一个新的地址,并将寄存器 `r1` 中的值写到那个地址上。那个地址就是我们前面提到的第二组 4 字节的位置,因此,我们发送我们的第一个消息到 GPIO 控制器上,告诉它准备启用 GPIO 第 16 号针脚的输出。
+
+### 5、生命的信号
+
+现在,LED 已经做好了打开准备,我们还需要实际去打开它。意味着需要给 GPIO 控制器发送一个消息去关闭 16 号针脚。是的,你没有看错,就是要发送一个关闭的消息。芯片制造商认为,在 GPIO 针脚关闭时打开 LED 更有意义。[^5] 硬件工程师经常做这种反常理的决策,似乎是为了让操作系统开发者保持警觉。可以认为是给自己的一个警告。
+
+```
+mov r1,#1
+lsl r1,#16
+str r1,[r0,#40]
+```
+
+希望你能够认识上面全部的命令,先不要管它的值。第一个命令和前面一样,是将值 `1` 推入到寄存器 `r1` 中。第二个命令是将二进制的 `1` 左移 16 位。由于我们是希望关闭 GPIO 的 16 号针脚,我们需要在下一个消息中将第 16 比特设置为 1(想设置其它针脚只需要改变相应的比特位即可)。最后,我们写这个值到 GPIO 控制器地址加上 4010 的地址上,这将使那个针脚关闭(加上 28 将打开针脚)。
+
+### 6、永远幸福快乐
+
+似乎我们现在就可以结束了,但不幸的是,处理器并不知道我们做了什么。事实上,处理器只要通电,它就永不停止地运转。因此,我们需要给它一个任务,让它一直运转下去,否则,树莓派将进入休眠(本示例中不会,LED 灯会一直亮着)。
+
+```
+loop$:
+b loop$
+
+```
+
+> `name:` 下一行的名字。
+
+> `b label` 下一行将去标签 `label` 处运行。
+
+第一行不是一个命令,而是一个标签。它给下一行命名为 `loop$`,这意味着我们能够通过名字来指向到该行。这就称为一个标签。当代码被转换成二进制后,标签将被丢弃,但这对我们通过名字而不是数字(地址)找到行比较有用。按惯例,我们使用一个 `$` 表示这个标签只对这个代码块中的代码起作用,让其它人知道,它不对整个程序起作用。`b`(“branch”)命令将去运行指定的标签中的命令,而不是去运行它后面的下一个命令。因此,下一行将再次去运行这个 `b` 命令,这将导致永远循环下去。因此处理器将进入一个无限循环中,直到它安全关闭为止。
+
+代码块结尾的一个空行是有意这样写的。GNU 工具链要求所有的汇编代码文件都是以空行结束的,因此,这就可以你确实是要结束了,并且文件没有被截断。如果你不这样处理,在汇编器运行时,你将收到烦人的警告。
+
+### 7、树莓派上场
+
+由于我们已经写完了代码,现在,我们可以将它上传到树莓派中了。在你的计算机上打开一个终端,改变当前工作目录为 `source` 文件夹的父级目录。输入 `make` 然后回车。如果报错,请参考排错章节。如果没有报错,你将生成三个文件。 `kernel.img` 是你的编译后的操作系统镜像。`kernel.list` 是你写的汇编代码的一个清单,它实际上是生成的。这在将来检查程序是否正确时非常有用。`kernel.map` 文件包含所有标签结束位置的一个映射,这对于跟踪值非常有用。
+
+为安装你的操作系统,需要先有一个已经安装了树莓派操作系统的 SD 卡。如果你浏览 SD 卡中的文件,你应该能看到一个名为 `kernel.img` 的文件。将这个文件重命名为其它名字,比如 `kernel_linux.img`。然后,复制你编译的 `kernel.img` 文件到 SD 卡中原来的位置,这将用你的操作系统镜像文件替换现在的树莓派操作系统镜像。想切换回来时,只需要简单地删除你自己的 `kernel.img` 文件,然后将前面重命名的文件改回 `kernel.img` 即可。我发现,保留一个原始的树莓派操作系统的备份是非常有用的,万一你要用到它呢。
+
+将这个 SD 卡插入到树莓派,并打开它的电源。这个 OK 的 LED 灯将亮起来。如果不是这样,请查看故障排除页面。如果一切如愿,恭喜你,你已经写出了你的第一个操作系统。[课程 2 OK02][12] 将指导你让 LED 灯闪烁和关闭闪烁。
+
+[^1]: OK, I'm lying it tells the linker, which is another program used to link several assembled files together. It doesn't really matter.
+[^2]: Clearly they're important to you. Since the GNU toolchain is mainly used for creating programs, it expects there to be an entry point labelled `_start`. As we're making an operating system, the `_start` is always whatever comes first, which we set up with the `.section .init` command. However, if we don't say where the entry point is, the toolchain gets upset. Thus, the first line says that we are going to define a symbol called `_start` for all to see (globally), and the second line says to make the symbol `_start` the address of the next line. We will come onto addresses shortly.
+[^3]: This tutorial is designed to spare you the pain of reading it, but, if you must, it can be found here [SoC-Peripherals.pdf](https://www.cl.cam.ac.uk/projects/raspberrypi/tutorials/os/downloads/SoC-Peripherals.pdf). For added confusion, the manual uses a different addressing system. An address listed as 0x7E200000 would be 0x20200000 in our OS.
+[^4]: Only values which have a binary representation which only has 1s in the first 8 bits of the representation. In other words, 8 1s or 0s followed by only 0s.
+[^5]: A hardware engineer was kind enough to explain this to me as follows:
+
+ The reason is that modern chips are made of a technology called CMOS, which stands for Complementary Metal Oxide Semiconductor. The Complementary part means each signal is connected to two transistors, one made of material called N-type semiconductor which is used to pull it to a low voltage and another made of P-type material to pull it to a high voltage. Only one transistor of the pair turns on at any time, otherwise we'd get a short circuit. P-type isn't as conductive as N-type, which means the P-type transistor has to be about 3 times as big to provide the same current. This is why LEDs are often wired to turn on by pulling them low, because the N-type is stronger at pulling low than the P-type is in pulling high.
+
+ There's another reason. Back in the 1970s chips were made out of entirely out of N-type material ('NMOS'), with the P-type replaced by a resistor. That means that when a signal is pulled low the chip is consuming power (and getting hot) even while it isn't doing anything. Your phone getting hot and flattening the battery when it's in your pocket doing nothing wouldn't be good. So signals were designed to be 'active low' so that they're high when inactive and so don't take any power. Even though we don't use NMOS any more, it's still often quicker to pull a signal low with the N-type than to pull it high with the P-type. Often a signal that's 'active low' is marked with a bar over the top of the name, or written as SIGNAL_n or /SIGNAL. But it can still be confusing, even for hardware engineers!
+
+--------------------------------------------------------------------------------
+
+via: https://www.cl.cam.ac.uk/projects/raspberrypi/tutorials/os/ok01.html
+
+作者:[Robert Mullins][a]
+选题:[lujun9972][b]
+译者:[qhwdw](https://github.com/qhwdw)
+校对:[wxy](https://github.com/wxy)
+
+本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
+
+[a]: http://www.cl.cam.ac.uk/~rdm34
+[b]: https://github.com/lujun9972
+[1]: https://www.cl.cam.ac.uk/projects/raspberrypi/tutorials/os/downloads.html
+[2]: https://www.cl.cam.ac.uk/projects/raspberrypi/tutorials/os/images/hexadecimal1.png
+[3]: https://www.cl.cam.ac.uk/projects/raspberrypi/tutorials/os/images/hexadecimal2.png
+[4]: https://www.cl.cam.ac.uk/projects/raspberrypi/tutorials/os/images/hexadecimal3.png
+[5]: https://www.cl.cam.ac.uk/projects/raspberrypi/tutorials/os/images/hexadecimal4.png
+[6]: https://www.cl.cam.ac.uk/projects/raspberrypi/tutorials/os/images/gpioController.png
+[7]: https://www.cl.cam.ac.uk/projects/raspberrypi/tutorials/os/images/binary1.png
+[8]: https://www.cl.cam.ac.uk/projects/raspberrypi/tutorials/os/images/binary2.png
+[9]: https://www.cl.cam.ac.uk/projects/raspberrypi/tutorials/os/images/binary3.png
+[10]: https://www.cl.cam.ac.uk/projects/raspberrypi/tutorials/os/screen04.html
+[11]: https://www.cl.cam.ac.uk/projects/raspberrypi/tutorials/os/images/binary4.png
+[12]: https://www.cl.cam.ac.uk/projects/raspberrypi/tutorials/os/ok02.html
diff --git a/translated/tech/20180326 Manage your workstation with Ansible- Automating configuration.md b/translated/tech/20180326 Manage your workstation with Ansible- Automating configuration.md
deleted file mode 100644
index c464f4ea32..0000000000
--- a/translated/tech/20180326 Manage your workstation with Ansible- Automating configuration.md
+++ /dev/null
@@ -1,231 +0,0 @@
-使用Ansible来管理你的工作站:配置自动化
-======
-
-
-
-Ansible是一个令人惊讶的自动化的配置管理工具。主要应用在服务器和云部署上,但在工作站上的应用(无论是台式机还是笔记本)却得到了很少的关注,这就是本系列所要关注的。
-
-在这个系列的第一部分,我会向你展示'ansible-pull'命令的基本用法,我们创建了一个安装了少量包的palybook.它本身是没有多大的用处的,但是它为后续的自动化做了准备。
-
-在这篇文章中,所有的事件操作都是闭环的,而且在最后部分,我们将会有一个针对工作站自动配置的完整的工作解决方案。现在,我们将要设置Ansible的配置,这样未来将要做的改变将会自动的部署应用到我们的工作站上。现阶段,假设你已经完成了第一部分的工作。如果没有的话,当你完成的时候回到本文。你应该已经有一个包含第一篇文章中代码的Github库。我们将直接按照之前的方式创建。
-
-首先,因为我们要做的不仅仅是安装包文件,所以我们要做一些重新的组织工作。现在,我们已经有一个名为'local.yml'并包含以下内容的playbook:
-```
-- hosts: localhost
-
- become: true
-
- tasks:
-
- - name: Install packages
-
- apt: name={{item}}
-
- with_items:
-
- - htop
-
- - mc
-
- - tmux
-
-```
-
-如果我们仅仅想实现一个任务那么上面的配置就足够了。随着向我们的配置中不断的添加内容,这个文件将会变的相当的庞大和杂乱。最好能够根据不同类型的配置将play文件分为独立的文件。为了达到这个要求,创建一个名为taskbook的文件,它和playbook很像但内容更加的流线型。让我们在Git库中为taskbook创建一个目录。
-```
-mkdir tasks
-
-```
-
-在'local.yml'playbook中的代码使它很好过过渡到成为安装包文件的taskbook.让我们把这个文件移动到刚刚创建好并新命名的目录中。
-
-```
-mv local.yml tasks/packages.yml
-
-```
-现在,我们编辑'packages.yml'文件将它进行大幅的瘦身,事实上,我们可以精简除了独立任务本身之外的所有内容。让我们把'packages.yml'编辑成如下的形式:
-```
-- name: Install packages
-
- apt: name={{item}}
-
- with_items:
-
- - htop
-
- - mc
-
- - tmux
-
-```
-
-正如你所看到的,它使用同样的语法,但我们去掉了对这个任务无用没有必要的所有内容。现在我们有了一个专门安装包文件的taskbook.然而我们仍然需要一个名为'local.yml'的文件,因为执行'ansible-pull'命令时仍然会去发现这个文件。所以我们将在我们库的根目录下(不是在'task'目录下)创建一个包含这些内容的全新文件:
-```
-- hosts: localhost
-
- become: true
-
- pre_tasks:
-
- - name: update repositories
-
- apt: update_cache=yes
-
- changed_when: False
-
-
-
- tasks:
-
- - include: tasks/packages.yml
-
-```
-
-这个新的'local.yml'扮演的是将要导入我们的taksbooks的主页的角色。我已经在这个文件中添加了一些你在这个系列中看不到的内容。首先,在这个文件的开头处,我添加了'pre——tasks',这个任务的作用是在其他所有任务运行之前先运行某个任务。在这种情况下,我们给Ansible的命令是让它去更新我们的分布存储库主页,下面的配置将执行这个任务要求:
-
-```
-apt: update_cache=yes
-
-```
-通常'apt'模块是用来安装包文件的,但我们也能够让它来更新库索引。这样做的目的是让我们的每个play在Ansible运行的时候能够以最新的索引工作。这将确保我们在使用一个老旧的索引安装一个包的时候不会出现问题。因为'apt'模块仅仅在Debian,Ubuntu和他们的衍生环境下工作。如果你运行的一个不同的环境,你期望在你的环境中使用一个特殊的模块而不是'apt'。如果你需要使用一个不同的模块请查看Ansible的相关文档。
-
-下面这行值得以后解释:
-```
-changed_when: False
-
-```
-在独立任务中的这行阻止了Ansible去报告play改变的结果即使是它本身在系统中导致的一个改变。在这中情况下,我们不会去在意库索引是否包含新的数据;它几乎总是会的,因为库总是在改变的。我们不会去在意'apt'库的改变,因为索引的改变是正常的过程。如果我们删除这行,我们将在过程保告的后面看到所有的变动,即使仅仅库的更新而已。最好能够去忽略这类的改变。
-
-接下来是常规任务的阶段,我们将创建好的taskbook导入。我们每次添加另一个taskbook的时候,要添加下面这一行:
-```
-tasks:
-
- - include: tasks/packages.yml
-
-```
-
-如果你将要运行'ansible-pull'命令,他应该向上一篇文章中的那样做同样重要的事情。 不同的是我们已经提高了我们的组织并且能够更有效的扩展它。'ansible-pull'命令的语法,为了节省你到上一篇文章中去寻找,参考如下:
-```
-sudo ansible-pull -U https://github.com//ansible.git
-
-```
-如果你还记得话,'ansible-pull'的命令拉取一个Git库并且应用了它所包含的配置。
-
-既然我们的基础已经搭建好,我们现在可以扩展我们的Ansible并且添加功能。更特别的是,我们将添加配置来自动化的部署对工作站要做的改变。为了支撑这个要求,首先我们要创建一个特殊的账户来应用我们的Ansible配置。这个不是必要的,我们仍然能够在我们自己的用户下运行Ansible配置。但是使用一个隔离的用户能够将其隔离到不需要我们参与的在后台运行的一个系统进程中,
-
-我们可以使用常规的方式来创建这个用户,但是既然我们正在使用Ansible,我们应该尽量避开使用手动的改变。替代的是,我们将会创建一个taskbook来处理用户的创建任务。这个taskbook目前将会仅仅创建一个用户,但你可以在这个taskbook中添加额外的plays来创建更多的用户。我将这个用户命名为'ansible',你可以按照自己的想法来命名(如果你做了这个改变要确保更新所有的变动)。让我们来创建一个名为'user.yml'的taskbook并且将以下代码写进去:
-
-```
-- name: create ansible user
-
- user: name=ansible uid=900
-
-```
-下一步,我们需要编辑'local.yml'文件,将这个新的taskbook添加进去,像如下这样写:
-
-```
-- hosts: localhost
-
- become: true
-
- pre_tasks:
-
- - name: update repositories
-
- apt: update_cache=yes
-
- changed_when: False
-
-
-
- tasks:
-
- - include: tasks/users.yml
-
- - include: tasks/packages.yml
-
-```
-现在当我们运行'ansible-pull'命令的时候,一个名为'ansible'的用户将会在系统中被创建。注意我特地通过参数'UID'为这个用户声明了用户ID为900。这个不是必须的,但建议直接创建好UID。因为在1000以下的UID在登陆界面是不会显示的,这样是很棒的因为我们根本没有需要去使用'ansibe'账户来登陆我们的桌面。UID 900是固定的;它应该是在1000以下没有被使用的任何一个数值。你可以使用以下命令在系统中去验证UID 900是否已经被使用了:
-
-```
-cat /etc/passwd |grep 900
-
-```
-然而,你使用这个UID应该不会遇到什么问题,因为迄今为止在我使用的任何发行版中我还没遇到过它是被默认使用的。
-
-现在,我们已经拥有了一个名为'ansible'的账户,它将会在之后的自动化配置中使用。接下来,我们可以创建实际的定时作业来自动操作它。而不是将其放置到我们刚刚创建的'users.yml'文件中,我们应该将其分开放到它自己的文件中。在任务目录中创建一个名为'cron.yml'的taskbook并且将以下的代买写进去:
-```
-- name: install cron job (ansible-pull)
-
- cron: user="ansible" name="ansible provision" minute="*/10" job="/usr/bin/ansible-pull -o -U https://github.com//ansible.git > /dev/null"
-
-```
-定时模块的语法几乎是不需加以说明的。通过这个play,我们创建了一个通过用户'ansible'运行的定时作业。这个作业将每隔10分钟执行一次,下面是它将要执行的命令:
-
-```
-/usr/bin/ansible-pull -o -U https://github.com//ansible.git > /dev/null
-
-```
-同样,我们也可以添加想要我们的所有工作站部署的额外定时作业到这个文件中。我们只需要在新的定时作业中添加额外的palys即可。然而,仅仅是添加一个定时的taskbook是不够的,我们还需要将它添加到'local.yml'文件中以便它能够被调用。将下面的一行添加到末尾:
-```
-- include: tasks/cron.yml
-
-```
-现在当'ansible-pull'命令执行的时候,它将会以通过用户'ansible'每个十分钟设置一个新的定时作业。但是,每个十分钟运行一个Ansible作业并不是一个好的方式因为这个将消耗很多的CPU资源。每隔十分钟来运行对于Ansible来说是毫无意义的除非欧文已经在Git库中改变一些东西。
-
-然而,我们已经解决了这个问题。注意到我在定时作业中的命令'ansible-pill'添加的我们之前从未用到过的参数'-o'.这个参数告诉Ansible只有在从上次'ansible-pull'被调用以后库有了变化后才会运行。如果库没有任何变化,他将不会做任何事情。通过这个方法,你将不会无端的浪费CPU资源。当然,一些CPU资源将会在下来存储库的时候被使用,但不会像再一次应用整个配置的时候使用的那么多。当'ansible-pull'执行的时候,它将会遍历在playbooks和taskbooks中的所有任务,但至少它不会毫无目的的运行。
-
-尽管我们已经添加了所有必须的配置要素来自动化'ansible-pull',它任然还不能正常的工作。'ansible-pull'命令需要sudo的权限来运行,这将允许它执行系统级的命令。然而我们创建的用户'ansible'并没有被设置为以'sudo'的权限来执行命令,因此当定时作业触发的时候,执行将会失败。通常沃恩可以使用命令'visudo'来手动的去设置用户'ansible'的拥有这个权限。然而我们现在应该以Ansible的方式来操作,而且这将会是一个向你展示'copy'模块是如何工作的机会。'copy'模块允许你从库复制一个文件到文件系统的任何位置。在这个案列中,我们将会复制'sudo'的一个配置文件到'/etc/sudoers.d/'以便用户'ansible'能够以管理员的权限执行任务。
-
-打开'users.yml',将下面的play添加到文件末尾。
-
-```
-- name: copy sudoers_ansible
-
- copy: src=files/sudoers_ansible dest=/etc/sudoers.d/ansible owner=root group=root mode=0440
-
-```
-'copy'模块,正如我们看到的,从库复制一个文件到其他任何位置。在这个过程中,我们正在抓取一个名为'sudoers_ansible'(我们将在后续创建)的文件并将它复制到拥有者为'root'的'/etc/sudoers/ansible'中。
-
-接下来,我们需要创建我们将要复制的文件。在你的库的根目录下,创建一个名为'files'的目录:
-
-```
-mkdir files
-
-```
-然后,在我们刚刚创建的'files'目录里,创建包含以下内容的名为'sudoers_ansible'的文件:
-```
-ansible ALL=(ALL) NOPASSWD: ALL
-
-```
-在'/etc/sudoer.d'目录里创建一个文件,就像我们正在这样做的,允许我们为一个特殊的用户配置'sudo'权限。现在我们正在通过'sudo'允许用户'ansible'不需要密码拥有完全控制权限。这将允许'ansible-pull'以后台任务的形式运行而不需要手动去运行。
-
-现在,你可以通过再次运行'ansible-pull'来拉取最新的变动:
-```
-sudo ansible-pull -U https://github.com//ansible.git
-
-```
-从这个节点开始,'ansible-pull'的定时作业将会在后台每隔十分钟运行一次来检查你的库是否有变化,如果它发现有变化,将会运行你的palybook并且应用你的taskbooks.
-
-所以现在我们有了一个完整的工作方案。当你第一次设置一台新的笔记本或者台式机的时候,你要去手动的运行'ansible-pull'命令,但仅仅是在第一次的时候。从第一次之后,用户'ansible'将会在后台接手后续的运行任务。当你想对你的机器做变动的时候,你只需要简单的去拉取你的Git库来做变动,然后将这些变化回传到库中。接着,当定时作业下次在每台机器上运行的时候,它将会拉取变动的部分并应用它们。你现在只需要做一次变动,你的所有工作站将会跟着一起变动。这方法尽管有一点不方便,通常,你会有一个你的机器列表的文件和包含不同机器的规则。不管怎样,'ansible-pull'的方法,就像在文章中描述的,是管理工作站配置的非常有效的方法。
-
-我已经在我的[Github repository]中更新了这篇文章中的代码,所以你可以随时去浏览来再一次检查你的语法。同时我将前一篇文章中的代码移到了它自己的目录中。
-
-在第三部分,我们将通过介绍使用Ansible来配置GNOME桌面设置来结束这个系列。我将会告诉你如何设置你的墙纸和锁屏壁纸,应用一个桌面主题以及更多的东西。
-
-同时,到了布置一些作业的时候了,大多数人有我们使用的各种应用的配置文件。可能是Bash,Vim或者其他你使用的工具的配置文件。现在你可以尝试通过我们在使用的Ansible库来自动复制这些配置到你的机器中。在这篇文章中,我已将想你展示了如何去复制文件,所以去尝试以下看看你是都已经能应用这些知识。
-
---------------------------------------------------------------------------------
-
-via: https://opensource.com/article/18/3/manage-your-workstation-configuration-ansible-part-2
-
-作者:[Jay LaCroix][a]
-译者:[FelixYFZ](https://github.com/FelixYFZ)
-校对:[校对者ID](https://github.com/校对者ID)
-选题:[lujun9972](https://github.com/lujun9972)
-
-本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
-
-[a]:https://opensource.com/users/jlacroix
-[1]:https://opensource.com/article/18/3/manage-workstation-ansible
-[2]:https://github.com/jlacroix82/ansible_article.git
diff --git a/translated/tech/20180503 11 Methods To Find System-Server Uptime In Linux.md b/translated/tech/20180503 11 Methods To Find System-Server Uptime In Linux.md
deleted file mode 100644
index 68ca8a1371..0000000000
--- a/translated/tech/20180503 11 Methods To Find System-Server Uptime In Linux.md
+++ /dev/null
@@ -1,200 +0,0 @@
-Linux 上查看系统/服务器运行时间的 11 种方法
-======
-你是否想知道自己的 Linux 系统除宕机外正常运行了多长时间?系统什么时候启动以及现在的日期?
-
-Linux 上有多个查看服务器/系统运行时间的命令,大多数用户喜欢使用标准并且很有名的 `uptime` 命令获取这些具体的信息。
-
-服务器的运行时间对一些用户来说不那么重要,但是当服务器运行诸如在线商城门户、网上银行门户等关键任务应用时,它对于服务器管理员来说就至关重要。
-
-它必须做到 0 宕机,因为一旦停机就会影响到数百万用户。
-
-正如我所说,许多命令都可以让用户看到 Linux 服务器的运行时间。在这篇教程里我会教你如何使用下面 11 种方式来查看。
-
-正常运行时间指的是服务器自从上次关闭或重启以来经过的时间。
-
-`uptime` 命令获取 `/proc` 文件中的详细信息并输出正常运行时间,`/proc` 文件不能直接读取。
-
-以下这些命令会输出系统运行和启动的时间。也会显示一些额外的信息。
-
-### 方法 1:使用 uptime 命令
-
-`uptime` 命令会告诉你系统运行了多长时间。它会用一行显示以下信息。
-
-当前时间,系统运行时间,当前登录用户的数量,过去 1 分钟、5 分钟、15 分钟系统负载的均值。
-
-```
-# uptime
-
- 08:34:29 up 21 days, 5:46, 1 user, load average: 0.06, 0.04, 0.00
-
-```
-
-### 方法 2:使用 w 命令
-
-`w` 命令为每个登录进系统的用户,每个用户当前所做的事情,所有活动的负载对计算机的影响提供了一个快速的概要。这个单一命令结合了多个 Unix 程序:who,uptime,和 ps -a。
-```
-# w
-
- 08:35:14 up 21 days, 5:47, 1 user, load average: 0.26, 0.09, 0.02
-USER TTY FROM [email protected] IDLE JCPU PCPU WHAT
-root pts/1 103.5.134.167 08:34 0.00s 0.01s 0.00s w
-
-```
-
-### 方法 3:使用 top 命令
-
-`top` 命令是 Linux 上监视实时系统进程的基础命令之一。它显示系统信息和运行进程的信息,例如正常运行时间,平均负载,运行的任务,登录用户数量,CPU 数量 & CPU 利用率,内存 & 交换空间信息。
-
-**推荐阅读:**[TOP 命令监视服务器性能的例子][1]
-```
-# top -c
-
-top - 08:36:01 up 21 days, 5:48, 1 user, load average: 0.12, 0.08, 0.02
-Tasks: 98 total, 1 running, 97 sleeping, 0 stopped, 0 zombie
-Cpu(s): 0.0%us, 0.3%sy, 0.0%ni, 99.7%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st
-Mem: 1872888k total, 1454644k used, 418244k free, 175804k buffers
-Swap: 2097148k total, 0k used, 2097148k free, 1098140k cached
-
- PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
- 1 root 20 0 19340 1492 1172 S 0.0 0.1 0:01.04 /sbin/init
- 2 root 20 0 0 0 0 S 0.0 0.0 0:00.00 [kthreadd]
- 3 root RT 0 0 0 0 S 0.0 0.0 0:00.00 [migration/0]
- 4 root 20 0 0 0 0 S 0.0 0.0 0:34.32 [ksoftirqd/0]
- 5 root RT 0 0 0 0 S 0.0 0.0 0:00.00 [stopper/0]
-
-```
-
-### 方法 4:使用 who 命令
-
-`who` 命令列出当前登录进计算机的用户。`who` 命令与 `w` 命令类似,但后者还包含额外的数据和统计信息。
-
-```
-# who -b
-
-system boot 2018-04-12 02:48
-
-```
-
-### 方法 5:使用 last 命令
-
-`last` 命令列出最近登录过的用户。`last` 往回查找 `/var/log/wtmp` 文件并显示自从文件创建后登录进(出)的用户。
-
-```
-# last reboot -F | head -1 | awk '{print $5,$6,$7,$8,$9}'
-
-Thu Apr 12 02:48:04 2018
-
-```
-
-### 方法 6:使用 /proc/uptime 文件
-
-这个文件中包含系统上次启动后运行时间的详细信息。`/proc/uptime` 的输出相当精简。
-
-第一个数字是系统自从启动的总秒数。第二个数字是总时间中系统空闲所花费的时间,以秒为单位。
-
-```
-# cat /proc/uptime
-
-1835457.68 1809207.16
-
-```
-
-### 方法 7:使用 tuptime 命令
-
-`tuptime` 是一个汇报系统运行时间的工具,输出历史信息并作以统计,保留重启之间的数据。和 `uptime` 命令很像,但输出更有意思一些。
-
-```
-$ tuptime
-
-```
-
-### 方法 8:使用 htop 命令
-
-`htop` 是运行在 Linux 上一个由 Hisham 使用 ncurses 库开发的交互式进程查看器。`htop` 比起 `top` 有很多的特性和选项。
-
-**推荐阅读:** [使用 Htop 命令监控系统资源][2]
-
-```
-# htop
-
- CPU[| 0.5%] Tasks: 48, 5 thr; 1 running
- Mem[||||||||||||||||||||||||||||||||||||||||||||||||||| 165/1828MB] Load average: 0.10 0.05 0.01
- Swp[ 0/2047MB] Uptime: 21 days, 05:52:35
-
- PID USER PRI NI VIRT RES SHR S CPU% MEM% TIME+ Command
-29166 root 20 0 110M 2484 1240 R 0.0 0.1 0:00.03 htop
-29580 root 20 0 11464 3500 1032 S 0.0 0.2 55:15.97 /bin/sh ./OSWatcher.sh 10 1
- 1 root 20 0 19340 1492 1172 S 0.0 0.1 0:01.04 /sbin/init
- 486 root 16 -4 10780 900 348 S 0.0 0.0 0:00.07 /sbin/udevd -d
- 748 root 18 -2 10780 932 360 S 0.0 0.0 0:00.00 /sbin/udevd -d
-
-```
-
-### 方法 9:使用 glances 命令
-
-`glances` 是一个跨平台基于 curses 使用 python 写的监控工具。我们可以说它非常强大,仅用一点空间就能获得很多信息。它使用 psutil 库从系统中获取信息。
-
-`glances` 可以监控 CPU,内存,负载,进程,网络接口,磁盘 I/O,磁盘阵列,传感器,文件系统(与文件夹),容器,显示器,Alert 日志,系统信息,运行时间,快速查看(CPU,内存等)。
-
-**推荐阅读:** [Glances (集大成)– Linux 上高级的实时系统运行监控工具][3]
-```
-glances
-
-ubuntu (Ubuntu 17.10 64bit / Linux 4.13.0-37-generic) - IP 192.168.1.6/24 Uptime: 21 days, 05:55:15
-
-CPU [|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| 90.6%] CPU - 90.6% nice: 0.0% ctx_sw: 4K MEM \ 78.4% active: 942M SWAP - 5.9% LOAD 2-core
-MEM [||||||||||||||||||||||||||||||||||||||||||||||||||||||||| 78.0%] user: 55.1% irq: 0.0% inter: 1797 total: 1.95G inactive: 562M total: 12.4G 1 min: 4.35
-SWAP [|||| 5.9%] system: 32.4% iowait: 1.8% sw_int: 897 used: 1.53G buffers: 14.8M used: 749M 5 min: 4.38
- idle: 7.6% steal: 0.0% free: 431M cached: 273M free: 11.7G 15 min: 3.38
-
-NETWORK Rx/s Tx/s TASKS 211 (735 thr), 4 run, 207 slp, 0 oth sorted automatically by memory_percent, flat view
-docker0 0b 232b
-enp0s3 12Kb 4Kb Systemd 7 Services loaded: 197 active: 196 failed: 1
-lo 616b 616b
-_h478e48e 0b 232b CPU% MEM% VIRT RES PID USER NI S TIME+ R/s W/s Command
- 63.8 18.9 2.33G 377M 2536 daygeek 0 R 5:57.78 0 0 /usr/lib/firefox/firefox -contentproc -childID 1 -isForBrowser -intPrefs 6:50|7:-1|19:0|34:1000|42:20|43:5|44:10|51
-DefaultGateway 83ms 78.5 10.9 3.46G 217M 2039 daygeek 0 S 21:07.46 0 0 /usr/bin/gnome-shell
- 8.5 10.1 2.32G 201M 2464 daygeek 0 S 8:45.69 0 0 /usr/lib/firefox/firefox -new-window
-DISK I/O R/s W/s 1.1 8.5 2.19G 170M 2653 daygeek 0 S 2:56.29 0 0 /usr/lib/firefox/firefox -contentproc -childID 4 -isForBrowser -intPrefs 6:50|7:-1|19:0|34:1000|42:20|43:5|44:10|51
-dm-0 0 0 1.7 7.2 2.15G 143M 2880 daygeek 0 S 7:10.46 0 0 /usr/lib/firefox/firefox -contentproc -childID 6 -isForBrowser -intPrefs 6:50|7:-1|19:0|34:1000|42:20|43:5|44:10|51
-sda1 9.46M 12K 0.0 4.9 1.78G 97.2M 6125 daygeek 0 S 1:36.57 0 0 /usr/lib/firefox/firefox -contentproc -childID 7 -isForBrowser -intPrefs 6:50|7:-1|19:0|34:1000|42:20|43:5|44:10|51
-
-```
-
-### 方法 10:使用 stat 命令
-
-`stat` 命令显示指定文件或文件系统的详细状态。
-
-```
-# stat /var/log/dmesg | grep Modify
-
-Modify: 2018-04-12 02:48:04.027999943 -0400
-
-```
-
-### 方法 11:使用 procinfo 命令
-
-`procinfo` 从 `/proc` 文件夹下收集一些系统数据并将其很好的格式化输出在标准输出设备上。
-
-```
-# procinfo | grep Bootup
-
-Bootup: Fri Apr 20 19:40:14 2018 Load average: 0.16 0.05 0.06 1/138 16615
-
-```
-
---------------------------------------------------------------------------------
-
-via: https://www.2daygeek.com/11-methods-to-find-check-system-server-uptime-in-linux/
-
-作者:[Magesh Maruthamuthu][a]
-选题:[lujun9972](https://github.com/lujun9972)
-译者:[LuuMing](https://github.com/LuuMing)
-校对:[校对者ID](https://github.com/校对者ID)
-
-本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
-
-[a]:https://www.2daygeek.com/author/magesh/
-[1]:https://www.2daygeek.com/top-command-examples-to-monitor-server-performance/
-[2]:https://www.2daygeek.com/htop-command-examples-to-monitor-system-resources/
-[3]:https://www.2daygeek.com/install-glances-advanced-real-time-linux-system-performance-monitoring-tool-on-centos-fedora-ubuntu-debian-opensuse-arch-linux/
diff --git a/translated/tech/20181211 Winterize your Bash prompt in Linux.md b/translated/tech/20181211 Winterize your Bash prompt in Linux.md
new file mode 100644
index 0000000000..4e0a17be07
--- /dev/null
+++ b/translated/tech/20181211 Winterize your Bash prompt in Linux.md
@@ -0,0 +1,80 @@
+[#]: collector: (lujun9972)
+[#]: translator: (geekpi)
+[#]: reviewer: ( )
+[#]: publisher: ( )
+[#]: url: ( )
+[#]: subject: (Winterize your Bash prompt in Linux)
+[#]: via: (https://opensource.com/article/18/12/linux-toy-bash-prompt)
+[#]: author: (Jason Baker https://opensource.com/users/jason-baker)
+
+在 Linux 中冬季化你的 Bash 提示符
+======
+你的 Linux 终端可能支持 Unicode,那么为何不利用它在提示符中添加季节性的图标呢?
+
+
+欢迎再次来到 Linux 命令行玩具日历的另一篇。如果这是你第一次访问该系列,你甚至可能会问自己什么是命令行玩具?我们对此非常开放:它会是终端上有任何有趣的消遣,对于任何节日主题相关的还有额外的加分。
+
+也许你以前见过其中的一些,也许你没有。不管怎样,我们希望你玩得开心。
+
+今天的玩具非常简单:它是你的 Bash 提示符。你的 Bash 提示符?是的!我们还有几个星期的假期可以盯着它看,在北半球冬天还会再多几周,所以为什么不玩玩它。
+
+目前你的 Bash 提示符号可能是一个简单的美元符号( **$**),或者更有可能是一个更长的东西。如果你不确定你的 Bash 提示符是什么,你可以在环境变量 $PS1 中找到它。要查看它,请输入:
+
+```
+echo $PS1
+```
+
+对于我而言,它返回:
+
+```
+[\u@\h \W]\$
+```
+
+**\u**、 **\h** 和 **\W** 分别是用户名、主机名和工作目录的特殊字符。你还可以使用其他一些符号。为了帮助构建你的 Bash 提示符,你可以使用 [EzPrompt][1],这是一个 PS1 配置的在线生成器,它包含了许多选项,包括日期和时间、Git 状态等。
+
+你可能还有其他变量来组成 Bash 提示符。对我来说,**$PS2** 包含了我命令提示符的结束括号。有关详细信息,请参阅[这篇文章][2]。
+
+要更改提示符,只需在终端中设置环境变量,如下所示:
+
+```
+$ PS1='\u is cold: '
+jehb is cold:
+```
+
+要永久设置它,请使用你喜欢的文本编辑器将相同的代码添加到 **/etc/bashrc** 中。
+
+那么这些与冬季化有什么关系呢?好吧,你很有可能有现代机器,你的终端支持 Unicode,所以你不仅限于标准的 ASCII 字符集。你可以使用任何符合 Unicode 规范的 emoji,包括雪花 ❄、雪人 ☃ 或一对滑雪者 🎿。你有很多冬季 emoji 可供选择。
+
+```
+🎄 圣诞树
+🧥 外套
+🦌 鹿
+🧤 手套
+🤶 圣诞夫人
+🎅 圣诞老人
+🧣 围巾
+🎿 滑雪者
+🏂 滑雪板
+❄ 雪花
+☃ 雪人
+⛄ 没有雪的雪人
+🎁 包装好的礼物
+```
+选择你最喜欢的,享受冬天的欢乐。有趣的事实:现代文件系统也支持文件名中的 Unicode 字符,这意味着技术上你可以将你下个程序命名为 **“❄❄❄❄❄.py”**。只是说说,不要这么做。
+
+你有特别喜欢的命令行小玩具需要我介绍的吗?这个系列要介绍的小玩具大部分已经有了落实,但还预留了几个空位置。如果你有特别想了解的可以评论留言,我会查看的。如果还有空位置,我会考虑介绍它的。如果没有,但如果我得到了一些很好的意见,我会在最后做一些有价值的提及。
+
+查看昨天的玩具,[在 Linux 终端玩贪吃蛇][3],记得明天再来!
+
+--------------------------------------------------------------------------------
+via: https://opensource.com/article/18/12/linux-toy-bash-prompt
+作者:[Jason Baker][a]
+选题:[lujun9972][b]
+译者:[geekpi](https://github.com/geekpi)
+校对:[校对者ID](https://github.com/校对者ID)
+本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
+[a]: https://opensource.com/users/jason-baker
+[b]: https://github.com/lujun9972
+[1]: http://ezprompt.net/
+[2]: https://access.redhat.com/solutions/505983
+[3]: https://opensource.com/article/18/12/linux-toy-snake
diff --git a/sources/tech/20181220 How To Install Microsoft .NET Core SDK On Linux.md b/translated/tech/20181220 How To Install Microsoft .NET Core SDK On Linux.md
similarity index 52%
rename from sources/tech/20181220 How To Install Microsoft .NET Core SDK On Linux.md
rename to translated/tech/20181220 How To Install Microsoft .NET Core SDK On Linux.md
index 728db3b7be..08b518e442 100644
--- a/sources/tech/20181220 How To Install Microsoft .NET Core SDK On Linux.md
+++ b/translated/tech/20181220 How To Install Microsoft .NET Core SDK On Linux.md
@@ -1,5 +1,5 @@
[#]: collector: (lujun9972)
-[#]: translator: ( )
+[#]: translator: (runningwater)
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
@@ -7,20 +7,20 @@
[#]: via: (https://www.ostechnix.com/how-to-install-microsoft-net-core-sdk-on-linux/)
[#]: author: (SK https://www.ostechnix.com/author/sk/)
-How To Install Microsoft .NET Core SDK On Linux
+如何在 Linux 中安装微软的 .NET Core SDK
======

-The **.NET Core** is a free, cross platform and open source framework developed by Microsoft to build desktop applications, mobile apps, web apps, IoT apps and gaming apps etc. If you’re dotnet developer coming from Windows platform, .NET core helps you to setup your development environment easily on any Linux and Unix-like operating systems. This step by step guide explains how to install Microsoft .NET Core SDK on Linux and how to write your first app using .Net.
+**.NET Core** 是微软提供的免费、跨平台和开源的开发框架,可以构建桌面应用程序、移动端应用程序、网络应用程序、物联网应用程序和游戏应用程序等。如果你是 Windows 平台下的 dotnet 开发人员的话,使用 .NET core 可以很轻松就设置好任何 Linux 和类 Unix 操作系统下的开发环境。本分步操作指南文章解释了如何在 Linux 中安装 .NET Core SDK 以及如何使用 .NET 开发出第一个应用程序。
-### Install Microsoft .NET Core SDK On Linux
+### Linux 中安装 .NET Core SDK
-The .NET core supports GNU/Linux, Mac OS and Windows. .Net core can be installed on popular GNU/Linux operating systems including Debian, Fedora, CentOS, Oracle Linux, RHEL, SUSE/openSUSE, and Ubuntu. As of writing this guide, the latest .NET core version was **2.2**.
+.NET Core 支持 GNU/Linux、Mac OS 和 Windows 系统,可以在主流的 GNU/Linux 操作系统上安装运行,包括 Debian、Fedora、CentOS、Oracle Linux、RHEL、SUSE/openSUSE 和 Ubuntu 。在撰写这篇教程时,其最新版本为 **2.2**。
-On **Debian 9** , you can install .NET Core SDK as shown below.
+**Debian 9** 系统上安装 .NET Core SDK,请按如下步骤进行。
-First of all, you need to register Microsoft key and add .NET repository by running the following commands:
+首先,需要注册微软的密钥,接着把 .NET 源仓库地址添加进来,运行的命令如下:
```
$ wget -qO- https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > microsoft.asc.gpg
@@ -31,16 +31,16 @@ $ sudo chown root:root /etc/apt/trusted.gpg.d/microsoft.asc.gpg
$ sudo chown root:root /etc/apt/sources.list.d/microsoft-prod.list
```
-After registering the key and adding the repository, install .NET SDK using commands:
+注册好密钥及添加完仓库源后,就可以安装 .NET SDK 了,命令如下:
```
$ sudo apt-get update
$ sudo apt-get install dotnet-sdk-2.2
```
-**On Debian 8:**
+**Debian 8 系统上安装:**
-Add Microsoft key and enable .NET repository:
+增加微软密钥,添加 .NET 仓库源:
```
$ wget -qO- https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > microsoft.asc.gpg
@@ -51,16 +51,16 @@ $ sudo chown root:root /etc/apt/trusted.gpg.d/microsoft.asc.gpg
$ sudo chown root:root /etc/apt/sources.list.d/microsoft-prod.list
```
-Install .NET SDK:
+安装 .NET SDK:
```
$ sudo apt-get update
$ sudo apt-get install dotnet-sdk-2.2
```
-**On Fedora 28:**
+**Fedora 28 系统上安装:**
-Add Microsoft key and enable .NET repository:
+增加微软密钥,添加 .NET 仓库源:
```
$ sudo rpm --import https://packages.microsoft.com/keys/microsoft.asc
@@ -69,14 +69,16 @@ $ sudo mv prod.repo /etc/yum.repos.d/microsoft-prod.repo
$ sudo chown root:root /etc/yum.repos.d/microsoft-prod.repo
```
-Now, Install .NET SDK:
+现在, 可以安装 .NET SDK 了:
```
$ sudo dnf update
$ sudo dnf install dotnet-sdk-2.2
```
-On **Fedora 27** , add the key and repository using commands:
+**Fedora 27 系统下:**
+
+增加微软密钥,添加 .NET 仓库源,命令如下:
```
$ sudo rpm --import https://packages.microsoft.com/keys/microsoft.asc
@@ -85,31 +87,31 @@ $ sudo mv prod.repo /etc/yum.repos.d/microsoft-prod.repo
$ sudo chown root:root /etc/yum.repos.d/microsoft-prod.repo
```
-And install .NET SDK using commands:
+接着安装 .NET SDK ,命令如下:
```
$ sudo dnf update
$ sudo dnf install dotnet-sdk-2.2
```
-**On CentOS/Oracle Linux:**
+**CentOS/Oracle 版本的 Linux 系统上:**
-Add Microsoft key and enable .NET core repository:
+增加微软密钥,添加 .NET 仓库源,使其可用
```
$ sudo rpm -Uvh https://packages.microsoft.com/config/rhel/7/packages-microsoft-prod.rpm
```
-Update the repositories and install .NET SDK:
+更新源仓库,安装 .NET SDK:
```
$ sudo yum update
$ sudo yum install dotnet-sdk-2.2
```
-**On openSUSE Leap:**
+**openSUSE Leap 版本的系统上:**
-Add key, enable repository and install necessary dependencies using the following commands:
+添加密钥,使仓库源可用,安装必需的依赖包,其命令如下:
```
$ sudo zypper install libicu
@@ -119,29 +121,29 @@ $ sudo mv prod.repo /etc/zypp/repos.d/microsoft-prod.repo
$ sudo chown root:root /etc/zypp/repos.d/microsoft-prod.repo
```
-Update the repositories and Install .NET SDK using commands:
+更新源仓库,安装 .NET SDK,命令如下:
```
$ sudo zypper update
$ sudo zypper install dotnet-sdk-2.2
```
-**On Ubuntu 18.04 LTS:**
+**Ubuntu 18.04 LTS 版本的系统上:**
-Register the Microsoft key and .NET core repository using commands:
+注册微软的密钥和 .NET Core 仓库源,命令如下:
```
$ wget -q https://packages.microsoft.com/config/ubuntu/18.04/packages-microsoft-prod.deb
$ sudo dpkg -i packages-microsoft-prod.deb
```
-Enable ‘Universe’ repository using:
+使 ‘Universe’ 仓库可用:
```
$ sudo add-apt-repository universe
```
-Then, install .NET Core SDK using command:
+然后,安装 .NET Core SDK ,命令如下:
```
$ sudo apt-get install apt-transport-https
@@ -149,16 +151,16 @@ $sudo apt-get update
$ sudo apt-get install dotnet-sdk-2.2
```
-**On Ubuntu 16.04 LTS:**
+**Ubuntu 16.04 LTS 版本的系统上:**
-Register Microsoft key and .NET repository using commands:
+注册微软的密钥和 .NET Core 仓库源,命令如下:
```
$ wget -q https://packages.microsoft.com/config/ubuntu/16.04/packages-microsoft-prod.deb
$ sudo dpkg -i packages-microsoft-prod.deb
```
-And then, Install .NET core SDK:
+然后安装 .NET core SDK:
```
$ sudo apt-get install apt-transport-https
@@ -166,17 +168,17 @@ $ sudo apt-get update
$ sudo apt-get install dotnet-sdk-2.2
```
-### Create Your First App
+### 创建你的第一个应用程序
-We have successfully installed .Net Core SDK in our Linux box. It is time to create our first app using dotnet.
+我们已经成功的在 Linux 机器中安装了 .NET Core SDK。是时候使用 dotnet 创建第一个应用程序了。
-For the purpose of this guide, I am going to create a new app called **“ostechnixApp”**. To do so, simply run the following command:
+接下来的目的,我们会创建一个名为 **“ostechnixApp”** 的应用程序。为此,可以简单的运行如下命令:
```
$ dotnet new console -o ostechnixApp
```
-**Sample output:**
+**简单的输出:**
```
Welcome to .NET Core!
@@ -208,9 +210,9 @@ Restore completed in 894.27 ms for /home/sk/ostechnixApp/ostechnixApp.csproj.
Restore succeeded.
```
-As you can see in the above output, .Net has created a new application of type console. The parameter -o creates a directory named “ostechnixApp” where you store your app data with all necessary files.
+正如上面的输出所示的,.NET 已经为我们创建一个控制台类型的应用程序。`-o` 参数创建了一个名为 “ostechnixApp” 的目录,其包含有存储此应用程序数据所必需的文件。
-Let us switch to ostechnixApp directory and see what’s in there.
+让我们切换到 ostechnixApp 目录,看看里面有些什么。
```
$ cd ostechnixApp/
@@ -218,7 +220,7 @@ $ ls
obj ostechnixApp.csproj Program.cs
```
-As you there are three files named **ostechnixApp.csproj** and **Program.cs** and one directory named **obj**. By default, the Program.cs file will contain the code to run the ‘Hello World’ program in the console. Let us have a look at the code.
+可以看到有两个名为 **ostechnixApp.csproj** 和 **Program.cs** 的文件,以及一个名为 **ojb** 的目录。默认情况下, `Program.cs` 文件包含有可以在控制台中运行的 'Hello World' 程序代码。可以看看此代码:
```
$ cat Program.cs
@@ -236,7 +238,7 @@ namespace ostechnixApp
}
```
-To run the newly created app, simply run the following command:
+要运行此应用程序,可以简单的使用如下命令:
```
$ dotnet run
@@ -245,9 +247,9 @@ Hello World!

-Simple, isn’t it? Yes, it is! Now, you can write your code in the **Program.cs** file and run it as shown above.
+很简单,对吧?是的,就是如此简单。现在你可以在 **Program.cs** 这文件中写上自己的代码,然后像上面所示的执行。
-Alternatively, you can create a new directory, for example mycode, using commands:
+或者,你可以创建一个新的目录,如例子所示的 `mycode` 目录,命令如下:
```
$ mkdir ~/.mycode
@@ -255,13 +257,13 @@ $ mkdir ~/.mycode
$ cd mycode/
```
-…and make that as your new development environment by running the following command:
+然后运行如下命令,使其成为你的新开发环境目录:
```
$ dotnet new console
```
-Sample output:
+简单的输出:
```
The template "Console Application" was created successfully.
@@ -276,46 +278,46 @@ Restore completed in 331.87 ms for /home/sk/mycode/mycode.csproj.
Restore succeeded.
```
-The above command will create two files named **mycode.csproj** and **Program.cs** and one directory named **obj**. Open the Program.cs file in your favorite editor, delete or modify the existing ‘hello world’ code with your own code.
+上的命令会创建两个名叫 **mycode.csproj** 和 **Program.cs** 的文件及一个名为 **obj** 的目录。用你喜欢的编辑器打开 `Program.cs` 文件, 删除或修改原来的 'hello world' 代码段,然后编写自己的代码。
-Once the code is written, save and close the Program.cs file and run the app using command:
+写完代码,保存,关闭 Program.cs 文件,然后运行此应用程序,命令如下:
```
$ dotnet run
```
-To check the installed .NET core SDK version, simply run:
+想要查看安装的 .NET core SDK 的版本的话,可以简单的运行:
```
$ dotnet --version
2.2.101
```
-To get help, run:
+要获得帮助,请运行:
```
$ dotnet --help
```
-### Get Microsoft Visual Studio Code Editor
+### 使用微软的 Visual Studio Code 编辑器
-To write the code, you can use your favorite editors of your choice. Microsoft has also its own editor named “ **Microsoft Visual Studio Code** ” with support for .NET. It is an open source, lightweight and powerful source code editor. It comes with built-in support for JavaScript, TypeScript and Node.js and has a rich ecosystem of extensions for other languages (such as C++, C#, Python, PHP, Go) and runtimes (such as .NET and Unity). It is a cross-platform code editor, so you can use it in Microsoft Windows, GNU/Linux, and Mac OS X. You can use it if you’re interested.
+要编写代码,你可以任选自己喜欢的编辑器。同时微软自己也有一款支持 .NET 的编辑器,其名为 “ **Microsoft Visual Studio Code** ”。它是一款开源、轻量级、功能强大的源代码编辑器。其内置了对 JavaScript、TypeScript 和 Node.js 的支持,并为其它语言(如 C++、C#、Python、PHP、Go)和运行时态(如 .NET 和 Unity)提供了丰富的扩展,已经形成一个完整的生态系统。它是一款跨平台的代码编辑器,所以在微软的 Windows 系统、GNU/Linux 系统和 Mac OS X 系统都可以使用。如果对其感兴趣,就可以使用。
-To know how to install and use it on Linux, please refer the following guide.
+To know how to install and use it on Linux, please refer the following guide.想了解如何在 Linux 上安装和使用,请参阅以下指南。
-[Install Microsoft Visual Studio Code In Linux][3]
+[Linux 中安装 Microsoft Visual Studio Code][3]
-[**This page**][1] has some basic tutorials to learn .NET Core and .NET Core SDK tools using Visual Studio Code editor. Go and check them to learn more.
+关于 Visual Studio Code editor 中 .NET Core 和 .NET Core SDK 工具的使用,[**此网页**][1]有一些基础的教程。想了解更多就去看看吧。
### Telemetry
-By default, the .NET core SDK will collect the usage data using a feature called **‘Telemetry’**. The collected data is anonymous and shared to the development team and community under the [Creative Commons Attribution License][2]. So the .NET team will understand how the tools are used and decide how they can be improved over time. If you don’t want to share your usage information, you can simply opt-out of telemetry by setting the **DOTNET_CLI_TELEMETRY_OPTOUT** environment variable to **‘1’** or **‘true’** using your favorite shell.
+默认情况下,.NET core SDK 会采集用户使用情况数据,此功能被称为 **‘Telemetry’**。采集数据是匿名的,并根据[知识共享署名许可][2]分享给其开发团队和社区。因此 .NET 团队会知道这些工具的使用状况,然后根据统计做出决策,改进产品。如果你不想分享自己的使用信息的话,可以使用顺手的 shell 工具把名为 **DOTNET_CLI_TELEMETRY_OPTOUT** 的环境变量参数设置为 **‘1’** 或 **‘true’**,这样就简单的关闭此功能了。
-And, that’s all. You know how to install .NET Core SDK on various Linux platforms and how to create a basic app using it. TO learn more about .NET usage, refer the links given at the end of this guide.
+就这样。你已经知道如何在各 Linux 平台上安装 .NET Core SDK 以及知道如何创建基本的应用程序了。想了解更多 .NET 使用知识的话,请参阅此文章末尾给出的链接。
-More good stuffs to come. Stay tuned!
+会爆出更多干货的。敬请关注!
-Cheers!
+祝贺下!
@@ -325,7 +327,7 @@ via: https://www.ostechnix.com/how-to-install-microsoft-net-core-sdk-on-linux/
作者:[SK][a]
选题:[lujun9972][b]
-译者:[译者ID](https://github.com/译者ID)
+译者:[runningwater](https://github.com/runningwater)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出