+
+### 5. runit
+
+runit is also a cross-platform init system that can run on GNU/Linux, Solaris, *BSD and Mac OS X and it is an alternative for SysV init, that offers service supervision.
+
+It comes with some benefits and remarkable components not found in SysV init and possibly other init systems in Linux and these include:
+
+Service supervision, where each service is associated with a service directory
+Clean process state, it guarantees each process a clean state
+It has a reliable logging facility
+Fast system boot up and shutdown
+It is also portable
+Packaging friendly
+Small code size and many more
+Visit Homepage:
+
+As I had earlier on mentioned, the init system starts and manages all other processes on a Linux system. Additionally, SysV is the primary init scheme on Linux operating systems, but due to some performance weaknesses, system programmers have developed several replacements for it.
+
+And here, we looked at a few of those replacements, but there could be other init systems that you think are worth mentioning in this list. You can let us know of them via the comment section below.
+
+
+--------------------------------------------------------------------------------
+
+via: http://www.tecmint.com/best-linux-init-systems/?utm_source=feedburner&utm_medium=feed&utm_campaign=Feed%3A+tecmint+%28Tecmint%3A+Linux+Howto%27s+Guide%29
+
+作者:[Aaron Kili ][a]
+译者:[译者ID](https://github.com/译者ID)
+校对:[校对者ID](https://github.com/校对者ID)
+
+本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
+
+[a]: http://www.tecmint.com/author/aaronkili/
diff --git a/sources/tech/20160811 How to Mount Remote Linux Filesystem or Directory Using SSHFS Over SSH.md b/sources/tech/20160811 How to Mount Remote Linux Filesystem or Directory Using SSHFS Over SSH.md
new file mode 100644
index 0000000000..6b51e41a9c
--- /dev/null
+++ b/sources/tech/20160811 How to Mount Remote Linux Filesystem or Directory Using SSHFS Over SSH.md
@@ -0,0 +1,145 @@
+How to Mount Remote Linux Filesystem or Directory Using SSHFS Over SSH
+============================
+
+The main purpose of writing this article is to provide a step-by-step guide on how to mount remote Linux file system using SSHFS client over SSH.
+
+This article is useful for those users and system administrators who want to mount remote file system on their local systems for whatever purposes. We have practically tested by installing SSHFS client on one of our Linux system and successfully mounted remote file systems.
+
+Before we go further installation let’s understand about SSHFS and how it works.
+
+![](http://www.tecmint.com/wp-content/uploads/2012/08/Sshfs-Mount-Remote-Linux-Filesystem-Directory.png)
+>Sshfs Mount Remote Linux Filesystem or Directory
+
+### What Is SSHFS?
+
+SSHFS stands for (Secure SHell FileSystem) client that enable us to mount remote filesystem and interact with remote directories and files on a local machine using SSH File Transfer Protocol (SFTP).
+
+SFTP is a secure file transfer protocol that provides file access, file transfer and file management features over Secure Shell protocol. Because SSH uses encryption while transferring files over the network from one computer to another computer and SSHFS comes with built-in FUSE (Filesystem in Userspace) kernel module that allows any non-privileged users to create their file system without modifying kernel code.
+
+In this article, we will show you how to install and use SSHFS client on any Linux distribution to mount remote Linux filesystem or directory on a local Linux machine.
+
+#### Step 1: Install SSHFS Client in Linux Systems
+
+By default sshfs packages does not exists on all major Linux distributions, you need to enable [epel repository][1] under your Linux systems to install sshfs with the help of Yum command with their dependencies.
+
+```
+# yum install sshfs
+# dnf install sshfs [On Fedora 22+ releases]
+$ sudo apt-get install sshfs [On Debian/Ubuntu based systems]
+```
+
+#### Step 2: Creating SSHFS Mount Directory
+
+Once the sshfs package installed, you need to create a mount point directory where you will mount your remote file system. For example, we have created mount directory under /mnt/tecmint.
+
+```
+# mkdir /mnt/tecmint
+$ sudo mkdir /mnt/tecmint [On Debian/Ubuntu based systems]
+```
+
+### Step 3: Mounting Remote Filesystem with SSHFS
+
+Once you have created your mount point directory, now run the following command as a root user to mount remote file system under /mnt/tecmint. In your case the mount directory would be anything.
+
+The following command will mount remote directory called /home/tecmint under /mnt/tecmint in local system. (Don’t forget replace x.x.x.x with your IP Address and mount point).
+
+```
+# sshfs tecmint@x.x.x.x:/home/tecmint/ /mnt/tecmint
+$ sudo sshfs -o allow_other tecmint@x.x.x.x:/home/tecmint/ /mnt/tecmint [On Debian/Ubuntu based systems]
+```
+
+If your Linux server is configured with SSH key based authorization, then you will need to specify the path to your public keys as shown in the following command.
+
+```
+# sshfs -o IdentityFile=~/.ssh/id_rsa tecmint@x.x.x.x:/home/tecmint/ /mnt/tecmint
+$ sudo sshfs -o allow_other,IdentityFile=~/.ssh/id_rsa tecmint@x.x.x.x:/home/tecmint/ /mnt/tecmint [On Debian/Ubuntu based systems]
+```
+
+#### Step 4: Verifying Remote Filesystem is Mounted
+
+If you have run the above command successfully without any errors, you will see the list of remote files and directories mounted under /mnt/tecmint.
+
+```
+# cd /mnt/tecmint
+# ls
+[root@ tecmint]# ls
+12345.jpg ffmpeg-php-0.6.0.tbz2 Linux news-closeup.xsl s3.jpg
+cmslogs gmd-latest.sql.tar.bz2 Malware newsletter1.html sshdallow
+epel-release-6-5.noarch.rpm json-1.2.1 movies_list.php pollbeta.sql
+ffmpeg-php-0.6.0 json-1.2.1.tgz my_next_artical_v2.php pollbeta.tar.bz2
+```
+
+#### Step 5: Checking Mount Point with df -hT Command
+
+If you run df -hT command you will see the remote file system mount point.
+
+```
+# df -hT
+```
+
+Sample Output
+
+```
+Filesystem Type Size Used Avail Use% Mounted on
+udev devtmpfs 730M 0 730M 0% /dev
+tmpfs tmpfs 150M 4.9M 145M 4% /run
+/dev/sda1 ext4 31G 5.5G 24G 19% /
+tmpfs tmpfs 749M 216K 748M 1% /dev/shm
+tmpfs tmpfs 5.0M 4.0K 5.0M 1% /run/lock
+tmpfs tmpfs 749M 0 749M 0% /sys/fs/cgroup
+tmpfs tmpfs 150M 44K 150M 1% /run/user/1000
+tecmint@192.168.0.102:/home/tecmint fuse.sshfs 324G 55G 253G 18% /mnt/tecmint
+```
+
+#### Step 6: Mounting Remote Filesystem Permanently
+
+To mount remote filesystem permanently, you need to edit the file called /etc/fstab. To do, open the file with your favorite editor.
+
+```
+# vi /etc/fstab
+$ sudo vi /etc/fstab [On Debian/Ubuntu based systems]
+```
+
+Go to the bottom of the file and add the following line to it and save the file and exit. The below entry mount remote server file system with default settings.
+
+```
+sshfs#tecmint@x.x.x.x:/home/tecmint/ /mnt/tecmint fuse.sshfs defaults 0 0
+```
+
+Make sure you’ve [SSH Passwordless Login][2] in place between servers to auto mount filesystem during system reboots..
+
+```
+sshfs#tecmint@x.x.x.x:/home/tecmint/ /mnt/tecmint fuse.sshfs IdentityFile=~/.ssh/id_rsa defaults 0 0
+```
+
+Next, you need to update the fstab file to reflect the changes.
+
+```
+# mount -a
+$ sudo mount -a [On Debian/Ubuntu based systems]
+```
+
+#### Step 7: Unmounting Remote Filesystem
+
+To unmount remote filesystem, jun issue the following command it will unmount the remote file system.
+
+```
+# umount /mnt/tecmint
+```
+
+That’s all for now, if you’re facing any difficulties or need any help in mounting remote file system, please contact us via comments and if you feel this article is much useful then share it with your friends.
+
+
+-------------------------------------------------------------------------------
+
+via: http://www.tecmint.com/sshfs-mount-remote-linux-filesystem-directory-using-ssh/?utm_source=feedburner&utm_medium=feed&utm_campaign=Feed%3A+tecmint+%28Tecmint%3A+Linux+Howto%27s+Guide%29
+
+作者:[Ravi Saive][a]
+译者:[译者ID](https://github.com/译者ID)
+校对:[校对者ID](https://github.com/校对者ID)
+
+本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
+
+[a]: http://www.tecmint.com/author/admin/
+[1]: http://www.tecmint.com/how-to-enable-epel-repository-for-rhel-centos-6-5/
+[2]: http://www.tecmint.com/ssh-passwordless-login-using-ssh-keygen-in-5-easy-steps/
diff --git a/sources/tech/20160812 Writing a JavaScript framework - Execution timing.md b/sources/tech/20160812 Writing a JavaScript framework - Execution timing.md
new file mode 100644
index 0000000000..44f5a2653e
--- /dev/null
+++ b/sources/tech/20160812 Writing a JavaScript framework - Execution timing.md
@@ -0,0 +1,193 @@
+[translating by kokialoves]
+Writing a JavaScript framework - Execution timing, beyond setTimeout
+===================
+
+This is the second chapter of the Writing a JavaScript framework series. In this chapter, I am going to explain the different ways of executing asynchronous code in the browser. You will read about the event loop and the differences between timing techniques, like setTimeout and Promises.
+
+The series is about an open-source client-side framework, called NX. During the series, I explain the main difficulties I had to overcome while writing the framework. If you are interested in NX please visit the [home page][1].
+
+The series includes the following chapters:
+
+The series includes the following chapters:
+
+1. [Project structuring][2]
+2. Execution timing (current chapter)
+3. [Sandboxed code evaluation][3]
+4. Data binding (part 1)
+5. Data binding (part 2)
+6. Custom elements
+7. Client side routing
+
+### Async code execution
+
+Most of you are probably familiar with Promise, process.nextTick(), setTimeout() and maybe requestAnimationFrame() as ways of executing asynchronous code. They all use the event loop internally, but they behave quite differently regarding precise timing.
+
+In this chapter, I will explain the differences, then show you how to implement a timing system that a modern framework, like NX requires. Instead of reinventing the wheel we will use the native event loop to achieve our goals.
+
+### The event loop
+
+The event loop is not even mentioned in the ES6 spec. JavaScript only has jobs and job queues on its own. A more complex event loop is specified separately by NodeJS and the HTML5 spec. Since this series is about the front-end I will explain the latter one here.
+
+The event loop is called a loop for a reason. It is infinitely looping and looking for new tasks to execute. A single iteration of this loop is called a tick. The code executed during a tick is called a task.
+
+```
+while (eventLoop.waitForTask()) {
+ eventLoop.processNextTask()
+}
+```
+
+Tasks are synchronous pieces of code that may schedule other tasks in the loop. An easy programmatic way to schedule a new task is setTimeout(taskFn). However, tasks may come from several other sources like user events, networking or DOM manipulation.
+
+![](https://risingstack-blog.s3.amazonaws.com/2016/Aug/Execution_timing_event_lopp_with_tasks-1470127590983.svg)
+
+### Task queues
+
+To complicate things a bit, the event loop can have multiple task queues. The only two restrictions are that events from the same task source must belong to the same queue and tasks must be processed in insertion order in every queue. Apart from these, the user agent is free to do as it wills. For example, it may decide which task queue to process next.
+
+```
+while (eventLoop.waitForTask()) {
+ const taskQueue = eventLoop.selectTaskQueue()
+ if (taskQueue.hasNextTask()) {
+ taskQueue.processNextTask()
+ }
+}
+```
+
+With this model, we loose precise control over timing. The browser may decide to totally empty several other queues before it gets to our task scheduled with setTimeout().
+
+![](https://risingstack-blog.s3.amazonaws.com/2016/Aug/Execution_timing_event_loop_with_task_queues-1470127624172.svg)
+
+### The microtask queue
+
+Fortunately, the event loop also has a single queue called the microtask queue. The microtask queue is completely emptied in every tick after the current task finished executing.
+
+
+```
+while (eventLoop.waitForTask()) {
+ const taskQueue = eventLoop.selectTaskQueue()
+ if (taskQueue.hasNextTask()) {
+ taskQueue.processNextTask()
+ }
+
+ const microtaskQueue = eventLoop.microTaskQueue
+ while (microtaskQueue.hasNextMicrotask()) {
+ microtaskQueue.processNextMicrotask()
+ }
+}
+```
+
+The easiest way to schedule a microtask is Promise.resolve().then(microtaskFn). Microtasks are processed in insertion order, and since there is only one microtask queue, the user agent can't mess with us this time.
+
+Moreover, microtasks can schedule new microtasks that will be inserted in the same queue and processed in the same tick.
+
+![](https://risingstack-blog.s3.amazonaws.com/2016/Aug/Execution_timing_event_loop_with_microtask_queue-1470127679393.svg)
+
+### Rendering
+
+The last thing missing is the rendering schedule. Unlike event handling or parsing, rendering is not done by separate background tasks. It is an algorithm that may run at the end of every loop tick.
+
+The user agent has a lot of freedom again: It may render after every task, but it may decide to let hundreds of tasks execute without rendering.
+
+Fortunately, there is requestAnimationFrame(), that executes the passed function right before the next render. Our final event loop model looks like this.
+
+```
+while (eventLoop.waitForTask()) {
+ const taskQueue = eventLoop.selectTaskQueue()
+ if (taskQueue.hasNextTask()) {
+ taskQueue.processNextTask()
+ }
+
+ const microtaskQueue = eventLoop.microTaskQueue
+ while (microtaskQueue.hasNextMicrotask()) {
+ microtaskQueue.processNextMicrotask()
+ }
+
+ if (shouldRender()) {
+ applyScrollResizeAndCSS()
+ runAnimationFrames()
+ render()
+ }
+}
+```
+
+Now let’s use all this knowledge to build a timing system!
+
+### Using the event loop
+
+As most modern frameworks, NX deals with DOM manipulation and data binding in the background. It batches operations and executes them asynchronously for better performance. To time these things right it relies on Promises, MutationObservers and requestAnimationFrame().
+
+The desired timing is this:
+
+1. Code from the developer
+2. Data binding and DOM manipulation reactions by NX
+3. Hooks defined by the developer
+4. Rendering by the user agent
+
+#### Step 1
+
+NX registers object mutations with ES6 Proxies and DOM mutations with a MutationObserver synchronously (more about these in the next chapters). It delays the reactions as microtasks until step 2 for optimized performance. This delay is done by Promise.resolve().then(reaction) for object mutations, and handled automatically by the MutationObserver as it uses microtasks internally.
+
+#### Step 2
+
+The code (task) from the developer finished running. The microtask reactions registered by NX start executing. Since they are microtasks they run in order. Note that we are still in the same loop tick.
+
+#### Step 3
+
+NX runs the hooks passed by the developer using requestAnimationFrame(hook). This may happen in a later loop tick. The important thing is that the hooks run before the next render and after all data, DOM and CSS changes are processed.
+
+#### Step 4
+
+The browser renders the next view. This may also happen in a later loop tick, but it never happens before the previous steps in a tick.
+
+### Things to keep in mind
+
+We just implemented a simple but effective timing system on top of the native event loop. It works well in theory, but timing is a delicate thing, and slight mistakes can cause some very strange bugs.
+
+In a complex system, it is important to set up some rules about the timing and keep to them later. For NX I have the following rules.
+
+1. Never use setTimeout(fn, 0) for internal operations
+2. Register microtasks with the same method
+3. Reserve microtasks for internal operations only
+4. Do not pollute the developer hook execution time window with anything else
+
+#### Rule 1 and 2
+
+Reactions on data and DOM manipulation should execute in the order the manipulations happened. It is okay to delay them as long as their execution order is not mixed up. Mixing execution order makes things unpredictable and difficult to reason about.
+
+setTimeout(fn, 0) is totally unpredictable. Registering microtasks with different methods also leads to mixed up execution order. For example microtask2 would incorrectly execute before microtask1 in the example below.
+
+```
+Promise.resolve().then().then(microtask1)
+Promise.resolve().then(microtask2)
+```
+
+![](https://risingstack-blog.s3.amazonaws.com/2016/Aug/Execution_timing_microtask_registration_method-1470127727609.svg)
+
+#### Rule 3 and 4
+
+Separating the time window of the developer code execution and the internal operations is important. Mixing these two would start to cause seemingly unpredictable behavior, and it would eventually force developers to learn about the internal working of the framework. I think many front-end developers have experiences like this already.
+
+### Conclusion
+
+If you are interested in the NX framework, please visit the home page. Adventurous readers can find the [NX source code][5] in this Github repository.
+
+I hope you found this a good read, see you next time when I’ll discuss [sandboxed code evaluation][4]!
+
+If you have any thoughts on the topic, please share them in the comments.
+
+--------------------------------------------------------------------------------
+
+via: https://blog.risingstack.com/writing-a-javascript-framework-execution-timing-beyond-settimeout/?utm_source=javascriptweekly&utm_medium=email
+
+作者:[Bertalan Miklos][a]
+译者:[译者ID](https://github.com/译者ID)
+校对:[校对者ID](https://github.com/校对者ID)
+
+本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
+
+[a]: https://blog.risingstack.com/author/bertalan/
+[1]: http://nx-framework.com/
+[2]: https://blog.risingstack.com/writing-a-javascript-framework-project-structuring/
+[3]: https://blog.risingstack.com/writing-a-javascript-framework-sandboxed-code-evaluation/
+[4]: https://blog.risingstack.com/writing-a-javascript-framework-sandboxed-code-evaluation/
+[5]: https://github.com/RisingStack/nx-framework
diff --git a/sources/tech/20160813 Journey-to-HTTP2.md b/sources/tech/20160813 Journey-to-HTTP2.md
new file mode 100644
index 0000000000..e75737f57e
--- /dev/null
+++ b/sources/tech/20160813 Journey-to-HTTP2.md
@@ -0,0 +1,215 @@
+NearTan 认领
+
+Journey to HTTP/2
+===================
+
+It has been quite some time since I last wrote through my blog and the reason is not being able to find enough time to put into it. I finally got some time today and thought to put some of it writing about HTTP.
+
+HTTP is the protocol that every web developer should know as it powers the whole web and knowing it is definitely going to help you develop better applications.
+
+In this article, I am going to be discussing what HTTP is, how it came to be, where it is today and how did we get here.
+
+### What is HTTP?
+
+First things first, what is HTTP? HTTP is the TCP/IP based application layer communication protocol which standardizes how the client and server communicate with each other. It defines how the content is requested and transmitted across the internet. By application layer protocol, I mean it’s just an abstraction layer that standardizes how the hosts (clients and servers) communicate and itself it depends upon TCP/IP to get request and response between the client and server. By default TCP port 80 is used but other ports can be used as well. HTTPS, however, uses port 443.
+
+#### HTTP/0.9 - The One Liner (1991)
+
+The first documented version of HTTP was HTTP/0.9 which was put forward in 1991. It was the simplest protocol ever; having a single method called GET. If a client had to access some webpage on the server, it would have made the simple request like below
+
+```
+GET /index.html
+```
+
+And the response from server would have looked as follows
+
+```
+(response body)
+(connection closed)
+```
+
+That is, the server would get the request, reply with the HTML in response and as soon as the content has been transferred, the connection will be closed. There were
+
+- No headers
+- GET was the only allowed method
+- Response had to be HTML
+
+As you can see, the protocol really had nothing more than being a stepping stone for what was to come.
+
+#### HTTP/1.0 - 1996
+
+In 1996, the next version of HTTP i.e. HTTP/1.0 evolved that vastly improved over the original version.
+
+Unlike HTTP/0.9 which was only designed for HTML response, HTTP/1.0 could now deal with other response formats i.e. images, video files, plain text or any other content type as well. It added more methods (i.e. POST and HEAD), request/response formats got changed, HTTP headers got added to both the request and responses, status codes were added to identify the response, character set support was introduced, multi-part types, authorization, caching, content encoding and more was included.
+
+Here is how a sample HTTP/1.0 request and response might have looked like:
+
+```
+GET / HTTP/1.0
+Host: kamranahmed.info
+User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5)
+Accept: */*
+```
+
+As you can see, alongside the request, client has also sent it’s personal information, required response type etc. While in HTTP/0.9 client could never send such information because there were no headers.
+
+Example response to the request above may have looked like below
+
+```
+HTTP/1.0 200 OK
+Content-Type: text/plain
+Content-Length: 137582
+Expires: Thu, 05 Dec 1997 16:00:00 GMT
+Last-Modified: Wed, 5 August 1996 15:55:28 GMT
+Server: Apache 0.84
+
+(response body)
+(connection closed)
+```
+
+In the very beginning of the response there is HTTP/1.0 (HTTP followed by the version number), then there is the status code 200 followed by the reason phrase (or description of the status code, if you will).
+
+In this newer version, request and response headers were still kept as ASCII encoded, but the response body could have been of any type i.e. image, video, HTML, plain text or any other content type. So, now that server could send any content type to the client; not so long after the introduction, the term “Hyper Text” in HTTP became misnomer. HMTP or Hypermedia transfer protocol might have made more sense but, I guess, we are stuck with the name for life.
+
+One of the major drawbacks of HTTP/1.0 were you couldn’t have multiple requests per connection. That is, whenever a client will need something from the server, it will have to open a new TCP connection and after that single request has been fulfilled, connection will be closed. And for any next requirement, it will have to be on a new connection. Why is it bad? Well, let’s assume that you visit a webpage having 10 images, 5 stylesheets and 5 javascript files, totalling to 20 items that needs to fetched when request to that webpage is made. Since the server closes the connection as soon as the request has been fulfilled, there will be a series of 20 separate connections where each of the items will be served one by one on their separate connections. This large number of connections results in a serious performance hit as requiring a new TCP connection imposes a significant performance penalty because of three-way handshake followed by slow-start.
+
+### Three-way Handshake
+
+Three-way handshake in it’s simples form is that all the TCP connections begin with a three-way handshake in which the client and the server share a series of packets before starting to share the application data.
+
+- SYN - Client picks up a random number, let’s say x, and sends it to the server.
+- SYN ACK - Server acknowledges the request by sending an ACK packet back to the client which is made up of a random number, let’s say y picked up by server and the number x+1 where x is the number that was sent by the client
+- ACK - Client increments the number y received from the server and sends an ACK packet back with the number x+1
+
+Once the three-way handshake is completed, the data sharing between the client and server may begin. It should be noted that the client may start sending the application data as soon as it dispatches the last ACK packet but the server will still have to wait for the ACK packet to be recieved in order to fulfill the request.
+
+![](http://i.imgur.com/uERG2G2.png)
+
+However, some implementations of HTTP/1.0 tried to overcome this issue by introducing a new header called Connection: keep-alive which was meant to tell the server “Hey server, do not close this connection, I need it again”. But still, it wasn’t that widely supported and the problem still persisted.
+
+Apart from being connectionless, HTTP also is a stateless protocol i.e. server doesn’t maintain the information about the client and so each of the requests has to have the information necessary for the server to fulfill the request on it’s own without any association with any old requests. And so this adds fuel to the fire i.e. apart from the large number of connections that the client has to open, it also has to send some redundant data on the wire causing increased bandwidth usage.
+
+#### HTTP/1.1 - 1999
+
+After merely 3 years of HTTP/1.0, the next version i.e. HTTP/1.1 was released in 1999; which made alot of improvements over it’s predecessor. The major improvements over HTTP/1.0 included
+
+- New HTTP methods were added, which introduced PUT, PATCH, HEAD, OPTIONS, DELETE
+
+- Hostname Identification In HTTP/1.0 Host header wasn’t required but HTTP/1.1 made it required.
+
+- Persistent Connections As discussed above, in HTTP/1.0 there was only one request per connection and the connection was closed as soon as the request was fulfilled which resulted in accute performance hit and latency problems. HTTP/1.1 introduced the persistent connections i.e. connections weren’t closed by default and were kept open which allowed multiple sequential requests. To close the connections, the header Connection: close had to be available on the request. Clients usually send this header in the last request to safely close the connection.
+
+- Pipelining It also introduced the support for pipelining, where the client could send multiple requests to the server without waiting for the response from server on the same connection and server had to send the response in the same sequence in which requests were received. But how does the client know that this is the point where first response download completes and the content for next response starts, you may ask! Well, to solve this, there must be Content-Length header present which clients can use to identify where the response ends and it can start waiting for the next response.
+
+>It should be noted that in order to benefit from persistent connections or pipelining, Content-Length header must be available on the response, because this would let the client know when the transmission completes and it can send the next request (in normal sequential way of sending requests) or start waiting for the the next response (when pipelining is enabled).
+
+>But there was still an issue with this approach. And that is, what if the data is dynamic and server cannot find the content length before hand? Well in that case, you really can’t benefit from persistent connections, could you?! In order to solve this HTTP/1.1 introduced chunked encoding. In such cases server may omit content-Length in favor of chunked encoding (more to it in a moment). However, if none of them are available, then the connection must be closed at the end of request.
+
+- Chunked Transfers In case of dynamic content, when the server cannot really find out the Content-Length when the transmission starts, it may start sending the content in pieces (chunk by chunk) and add the Content-Length for each chunk when it is sent. And when all of the chunks are sent i.e. whole transmission has completed, it sends an empty chunk i.e. the one with Content-Length set to zero in order to identify the client that transmission has completed. In order to notify the client about the chunked transfer, server includes the header Transfer-Encoding: chunked
+
+- Unlike HTTP/1.0 which had Basic authentication only, HTTP/1.1 included digest and proxy authentication
+- Caching
+- Byte Ranges
+- Character sets
+- Language negotiation
+- Client cookies
+- Enhanced compression support
+- New status codes
+- ..and more
+
+I am not going to dwell about all the HTTP/1.1 features in this post as it is a topic in itself and you can already find a lot about it. The one such document that I would recommend you to read is Key differences between HTTP/1.0 and HTTP/1.1 and here is the link to original RFC for the overachievers.
+
+HTTP/1.1 was introduced in 1999 and it had been a standard for many years. Although, it improved alot over it’s predecessor; with the web changing everyday, it started to show it’s age. Loading a web page these days is more resource-intensive than it ever was. A simple webpage these days has to open more than 30 connections. Well HTTP/1.1 has persistent connections, then why so many connections? you say! The reason is, in HTTP/1.1 it can only have one outstanding connection at any moment of time. HTTP/1.1 tried to fix this by introducing pipelining but it didn’t completely address the issue because of the head-of-line blocking where a slow or heavy request may block the requests behind and once a request gets stuck in a pipeline, it will have to wait for the next requests to be fulfilled. To overcome these shortcomings of HTTP/1.1, the developers started implementing the workarounds, for example use of spritesheets, encoded images in CSS, single humungous CSS/Javascript files, domain sharding etc.
+
+#### SPDY - 2009
+
+Google went ahead and started experimenting with alternative protocols to make the web faster and improving web security while reducing the latency of web pages. In 2009, they announced SPDY.
+
+>SPDY is a trademark of Google and isn’t an acronym.
+
+It was seen that if we keep increasing the bandwidth, the network performance increases in the beginning but a point comes when there is not much of a performance gain. But if you do the same with latency i.e. if we keep dropping the latency, there is a constant performance gain. This was the core idea for performance gain behind SPDY, decrease the latency to increase the network performance.
+
+>For those who don’t know the difference, latency is the delay i.e. how long it takes for data to travel between the source and destination (measured in milliseconds) and bandwidth is the amount of data transfered per second (bits per second).
+
+The features of SPDY included, multiplexing, compression, prioritization, security etc. I am not going to get into the details of SPDY, as you will get the idea when we get into the nitty gritty of HTTP/2 in the next section as I said HTTP/2 is mostly inspired from SPDY.
+
+SPDY didn’t really try to replace HTTP; it was a translation layer over HTTP which existed at the application layer and modified the request before sending it over to the wire. It started to become a defacto standards and majority of browsers started implementing it.
+
+In 2015, at Google, they didn’t want to have two competing standards and so they decided to merge it into HTTP while giving birth to HTTP/2 and deprecating SPDY.
+
+#### HTTP/2 - 2015
+
+By now, you must be convinced that why we needed another revision of the HTTP protocol. HTTP/2 was designed for low latency transport of content. The key features or differences from the old version of HTTP/1.1 include
+
+- Binary instead of Textual
+- Multiplexing - Multiple asynchronous HTTP requests over a single connection
+- Header compression using HPACK
+- Server Push - Multiple responses for single request
+- Request Prioritization
+- Security
+
+![](http://i.imgur.com/S85j8gg.png)
+
+##### 1. Binary Protocol
+
+HTTP/2 tends to address the issue of increased latency that existed in HTTP/1.x by making it a binary protocol. Being a binary protocol, it easier to parse but unlike HTTP/1.x it is no longer readable by the human eye. The major building blocks of HTTP/2 are Frames and Streams
+
+**Frames and Streams**
+
+HTTP messages are now composed of one or more frames. There is a HEADERS frame for the meta data and DATA frame for the payload and there exist several other types of frames (HEADERS, DATA, RST_STREAM, SETTINGS, PRIORITY etc) that you can check through the HTTP/2 specs.
+
+Every HTTP/2 request and response is given a unique stream ID and it is divided into frames. Frames are nothing but binary pieces of data. A collection of frames is called a Stream. Each frame has a stream id that identifies the stream to which it belongs and each frame has a common header. Also, apart from stream ID being unique, it is worth mentioning that, any request initiated by client uses odd numbers and the response from server has even numbers stream IDs.
+
+Apart from the HEADERS and DATA, another frame type that I think worth mentioning here is RST_STREAM which is a special frame type that is used to abort some stream i.e. client may send this frame to let the server know that I don’t need this stream anymore. In HTTP/1.1 the only way to make the server stop sending the response to client was closing the connection which resulted in increased latency because a new connection had to be opened for any consecutive requests. While in HTTP/2, client can use RST_STREAM and stop receiving a specific stream while the connection will still be open and the other streams will still be in play.
+
+##### 2. Multiplexing
+
+Since HTTP/2 is now a binary protocol and as I said above that it uses frames and streams for requests and responses, once a TCP connection is opened, all the streams are sent asynchronously through the same connection without opening any additional connections. And in turn, the server responds in the same asynchronous way i.e. the response has no order and the client uses the assigned stream id to identify the stream to which a specific packet belongs. This also solves the head-of-line blocking issue that existed in HTTP/1.x i.e. the client will not have to wait for the request that is taking time and other requests will still be getting processed.
+
+##### 3. HPACK Header Compression
+
+It was part of a separate RFC which was specifically aimed at optimizing the sent headers. The essence of it is that when we are constantly accessing the server from a same client there is alot of redundant data that we are sending in the headers over and over, and sometimes there might be cookies increasing the headers size which results in bandwidth usage and increased latency. To overcome this, HTTP/2 introduced header compression.
+
+![](http://i.imgur.com/3IPWXvR.png)
+
+Unlike request and response, headers are not compressed in gzip or compress etc formats but there is a different mechanism in place for header compression which is literal values are encoded using Huffman code and a headers table is maintained by the client and server and both the client and server omit any repetitive headers (e.g. user agent etc) in the subsequent requests and reference them using the headers table maintained by both.
+
+While we are talking headers, let me add here that the headers are still the same as in HTTP/1.1, except for the addition of some pseudo headers i.e. :method, :scheme, :host and :path
+
+##### 4. Server Push
+
+Server push is another tremendous feature of HTTP/2 where the server, knowing that the client is going to ask for a certain resource, can push it to the client without even client asking for it. For example, let’s say a browser loads a web page, it parses the whole page to find out the remote content that it has to load from the server and then sends consequent requests to the server to get that content.
+
+Server push allows the server to decrease the roundtrips by pushing the data that it knows that client is going to demand. How it is done is, server sends a special frame called PUSH_PROMISE notifying the client that, “Hey, I am about to send this resource to you! Do not ask me for it.” The PUSH_PROMISE frame is associated with the stream that caused the push to happen and it contains the promised stream ID i.e. the stream on which the server will send the resource to be pushed.
+
+##### 5. Request Prioritization
+
+A client can assign a priority to a stream by including the prioritization information in the HEADERS frame by which a stream is opened. At any other time, client can send a PRIORITY frame to change the priority of a stream.
+
+Without any priority information, server processes the requests asynchronously i.e. without any order. If there is priority assigned to a stream, then based on this prioritization information, server decides how much of the resources need to be given to process which request.
+
+##### 6. Security
+
+There was extensive discussion on whether security (through TLS) should be made mandatory for HTTP/2 or not. In the end, it was decided not to make it mandatory. However, most vendors stated that they will only support HTTP/2 when it is used over TLS. So, although HTTP/2 doesn’t require encryption by specs but it has kind of become mandatory by default anyway. With that out of the way, HTTP/2 when implemented over TLS does impose some requirementsi.e. TLS version 1.2 or higher must be used, there must be a certain level of minimum keysizes, ephemeral keys are required etc.
+
+HTTP/2 is here and it has already surpassed SPDY in adaption which is gradually increasing. HTTP/2 has alot to offer in terms of performance gain and it is about time we should start using it.
+
+For anyone interested in further details here is the [link to specs][1] and a [link demonstrating the performance benefits of][2] HTTP/2. For any questions or comments, use the comments section below. Also, while reading, if you find any blatant lies; do point them out.
+
+And that about wraps it up. Until next time! stay tuned.
+
+--------------------------------------------------------------------------------
+
+via: http://kamranahmed.info/blog/2016/08/13/http-in-depth/?utm_source=webopsweekly&utm_medium=email
+
+作者:[Kamran Ahmed][a]
+译者:[译者ID](https://github.com/译者ID)
+校对:[校对者ID](https://github.com/校对者ID)
+
+本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
+
+[a]: http://github.com/kamranahmedse
+
+[1]: https://http2.github.io/http2-spec
+[2]: http://www.http2demo.io/
+
diff --git a/sources/tech/20160816 Accelerating Node.js applications with HTTP2 Server Push.md b/sources/tech/20160816 Accelerating Node.js applications with HTTP2 Server Push.md
new file mode 100644
index 0000000000..9ea8c9079a
--- /dev/null
+++ b/sources/tech/20160816 Accelerating Node.js applications with HTTP2 Server Push.md
@@ -0,0 +1,114 @@
+Accelerating Node.js applications with HTTP/2 Server Push
+=========================================================
+
+In April, we [announced support for HTTP/2 Server][3] Push via the HTTP Link header. My coworker John has demonstrated how easy it is to [add Server Push to an example PHP application][4].
+
+![](https://blog.cloudflare.com/content/images/2016/08/489477622_594bf9e3d9_z.jpg)
+
+We wanted to make it easy to improve the performance of contemporary websites built with Node.js. we developed the netjet middleware to parse the generated HTML and automatically add the Link headers. When used with an example Express application you can see the headers being added:
+
+![](https://blog.cloudflare.com/content/images/2016/08/2016-08-11_13-32-45.png)
+
+We use Ghost to power this blog, so if your browser supports HTTP/2 you have already benefited from Server Push without realizing it! More on that below.
+
+In netjet, we use the PostHTML project to parse the HTML with a custom plugin. Right now it is looking for images, scripts and external stylesheets. You can implement this same technique in other environments too.
+
+Putting an HTML parser in the response stack has a downside: it will increase the page load latency (or "time to first byte"). In most cases, the added latency will be overshadowed by other parts of your application, such as database access. However, netjet includes an adjustable LRU cache keyed by ETag headers, allowing netjet to insert Link headers quickly on pages already parsed.
+
+If you are designing a brand new application, however, you should consider storing metadata on embedded resources alongside your content, eliminating the HTML parse, and possible latency increase, entirely.
+
+Netjet is compatible with any Node.js HTML framework that supports Express-like middleware. Getting started is as simple as adding netjet to the beginning of your middleware chain.
+
+```
+var express = require('express');
+var netjet = require('netjet');
+var root = '/path/to/static/folder';
+
+express()
+ .use(netjet({
+ cache: {
+ max: 100
+ }
+ }))
+ .use(express.static(root))
+ .listen(1337);
+```
+
+With a little more work, you can even use netjet without frameworks.
+
+```
+var http = require('http');
+var netjet = require('netjet');
+
+var port = 1337;
+var hostname = 'localhost';
+var preload = netjet({
+ cache: {
+ max: 100
+ }
+});
+
+var server = http.createServer(function (req, res) {
+ preload(req, res, function () {
+ res.statusCode = 200;
+ res.setHeader('Content-Type', 'text/html');
+ res.end('Hello World
');
+ });
+});
+
+server.listen(port, hostname, function () {
+ console.log('Server running at http://' + hostname + ':' + port+ '/');
+});
+```
+
+See the [netjet documentation][1] for more information on the supported options.
+
+### Seeing what’s pushed
+
+![](https://blog.cloudflare.com/content/images/2016/08/2016-08-02_10-49-33.png)
+
+Chrome's Developer Tools makes it easy to verify that your site is using Server Push. The Network tab shows pushed assets with "Push" included as part of the initiator.
+
+Unfortunately, Firefox's Developers Tools don't yet directly expose if the resource pushed. You can, however, check for the cf-h2-pushed header in the page's response headers, which contains a list of resources that CloudFlare offered browsers over Server Push.
+
+Contributions to improve netjet or the documentation are greatly appreciated. I'm excited to hear where people are using netjet.
+
+### Ghost and Server Push
+
+Ghost is one such exciting integration. With the aid of the Ghost team, I've integrated netjet, and it has been available as an opt-in beta since version 0.8.0.
+
+If you are running a Ghost instance, you can enable Server Push by modifying the server's config.js file and add the preloadHeaders option to the production configuration block.
+
+
+```
+production: {
+ url: 'https://my-ghost-blog.com',
+ preloadHeaders: 100,
+ // ...
+}
+```
+
+Ghost has put together [a support article][2] for Ghost(Pro) customers.
+
+### Conclusion
+
+With netjet, your Node.js applications can start to use browser preloading and, when used with CloudFlare, HTTP/2 Server Push today.
+
+At CloudFlare, we're excited to make tools to help increase the performance of websites. If you find this interesting, we are hiring in Austin, Texas; Champaign, Illinois; London; San Francisco; and Singapore.
+
+
+--------------------------------------------------------------------------------
+
+via: https://blog.cloudflare.com/accelerating-node-js-applications-with-http-2-server-push/?utm_source=nodeweekly&utm_medium=email
+
+作者:[Terin Stock][a]
+译者:[译者ID](https://github.com/译者ID)
+校对:[校对者ID](https://github.com/校对者ID)
+
+本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
+
+[a]: https://blog.cloudflare.com/author/terin-stock/
+[1]: https://www.npmjs.com/package/netjet
+[2]: http://support.ghost.org/preload-headers/
+[3]: https://www.cloudflare.com/http2/server-push/
+[4]: https://blog.cloudflare.com/using-http-2-server-push-with-php/
diff --git a/sources/tech/20160816 Deploying React with Zero Configuration.md b/sources/tech/20160816 Deploying React with Zero Configuration.md
new file mode 100644
index 0000000000..e2cb16a223
--- /dev/null
+++ b/sources/tech/20160816 Deploying React with Zero Configuration.md
@@ -0,0 +1,69 @@
+Deploying React with Zero Configuration
+========================
+
+So you want to build an app with [React][1]? "[Getting started][2]" is easy… and then what?
+
+React is a library for building user interfaces, which comprise only one part of an app. Deciding on all the other parts — styles, routers, npm modules, ES6 code, bundling and more — and then figuring out how to use them is a drain on developers. This has become known as [javascript fatigue][3]. Despite this complexity, usage of React continues to grow.
+
+The community answers this challenge by sharing boilerplates. These [boilerplates][4] reveal the profusion of architectural choices developers must make. That official "Getting Started" seems so far away from the reality of an operational app.
+
+### New, Zero-configuration Experience
+
+Inspired by the cohesive developer experience provided by [Ember.js][5] and [Elm][6], the folks at Facebook wanted to provide an easy, opinionated way forward. They created a new way to develop React apps, `create-react-app`. In the three weeks since initial public release, it has received tremendous community awareness (over 8,000 GitHub stargazers) and support (dozens of pull requests).
+
+`create-react-app` is different than many past attempts with boilerplates and starter kits. It targets zero configuration [[convention-over-configuration]][7], focusing the developer on what is interesting and different about their application.
+
+A powerful side-effect of zero configuration is that the tools can now evolve in the background. Zero configuration lays the foundation for the tools ecosystem to create automation and delight developers far beyond React itself.
+
+### Zero-configuration Deploy to Heroku
+
+Thanks to the zero-config foundation of create-react-app, the idea of zero-config deployment seemed within reach. Since these new apps all share a common, implicit architecture, the build process can be automated and then served with intelligent defaults. So, [we created this community buildpack to experiment with no-configuration deployment to Heroku][8].
+
+#### Create and Deploy a React App in Two Minutes
+
+You can get started building React apps for free on Heroku.
+
+```
+npm install -g create-react-app
+create-react-app my-app
+cd my-app
+git init
+heroku create -b https://github.com/mars/create-react-app-buildpack.git
+git add .
+git commit -m "react-create-app on Heroku"
+git push heroku master
+heroku open
+```
+
+Try it yourself [using the buildpack docs][9].
+
+### Growing Up from Zero Config
+
+create-react-app is very new (currently version 0.2) and since its target is a crystal-clear developer experience, more advanced use cases are not supported (or may never be supported). For example, it does not provide server-side rendering or customized bundles.
+
+To support greater control, create-react-app includes the command npm run eject. Eject unpacks all the tooling (config files and package.json dependencies) into the app's directory, so you can customize to your heart's content. Once ejected, changes you make may necessitate switching to a custom deployment with Node.js and/or static buildpacks. Always perform such project changes through a branch / pull request, so they can be easily undone. Heroku's Review Apps are perfect for testing changes to the deployment.
+
+We'll be tracking progress on create-react-app and adapting the buildpack to support more advanced use cases as they become available. Happy deploying!
+
+
+
+--------------------------------------------------------------------------------
+
+via: https://blog.heroku.com/deploying-react-with-zero-configuration?c=7013A000000NnBFQA0&utm_campaign=Display%20-%20Endemic%20-Cooper%20-Node%20-%20Blog%20-%20Zero-Configuration&utm_medium=display&utm_source=cooperpress&utm_content=blog&utm_term=node
+
+作者:[Mars Hall][a]
+译者:[译者ID](https://github.com/译者ID)
+校对:[校对者ID](https://github.com/校对者ID)
+
+本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
+
+[a]: https://blog.heroku.com/deploying-react-with-zero-configuration?c=7013A000000NnBFQA0&utm_campaign=Display%20-%20Endemic%20-Cooper%20-Node%20-%20Blog%20-%20Zero-Configuration&utm_medium=display&utm_source=cooperpress&utm_content=blog&utm_term=node
+[1]: https://facebook.github.io/react/
+[2]: https://facebook.github.io/react/docs/getting-started.html
+[3]: https://medium.com/@ericclemmons/javascript-fatigue-48d4011b6fc4
+[4]: https://github.com/search?q=react+boilerplate
+[5]: http://emberjs.com/
+[6]: http://elm-lang.org/
+[7]: http://rubyonrails.org/doctrine/#convention-over-configuration
+[8]: https://github.com/mars/create-react-app-buildpack
+[9]: https://github.com/mars/create-react-app-buildpack#usage
diff --git a/sources/tech/20160817 Dependency Injection for the Android platform 101 - Part 1.md b/sources/tech/20160817 Dependency Injection for the Android platform 101 - Part 1.md
new file mode 100644
index 0000000000..93ddf0f20a
--- /dev/null
+++ b/sources/tech/20160817 Dependency Injection for the Android platform 101 - Part 1.md
@@ -0,0 +1,107 @@
+Dependency Injection for the Android platform 101 - Part 1
+===========================
+
+![](https://d262ilb51hltx0.cloudfront.net/max/2000/1*YWlAzAY20KLLGIyyD_mzZw.png)
+
+When we first start studying software engineering, we usually bump into something like:
+
+>Software shall be SOLID.
+
+but what does that mean, in fact? Well, let’s just say that each character of the acronym means something really important for the architecture, such as:
+
+- [Single Responsibility Principle][1]
+- [Open/closed principle][2]
+- [Liskov substitution principle][3]
+- [Interface segregation principle][4]
+- [Dependency inversion principle][5] which is the core concept on which the dependency injection is based.
+
+Simply, we need to provide a class with all the objects it needs in order to perform its duties.
+
+### Overview
+
+Dependency Injection sounds like a very complex term for something that is, in fact, really easy and could be explained with this example:
+
+As we can see, in the first case, we create the dependency in the constructor, while in the second case it gets passed as a parameter. The second case is what we call dependency injection. We do this so that our class does not depend on the specific implementation of its dependency but it just uses it.
+Moreover, based on whether the parameter is passed over to the constructor or to a method, we talk either about constructor dependency injection or method dependency injection:
+
+If you want to know more about Dependency Injection in general, be sure to check out this amazing talk from Dan Lew that actually inspired this overview.
+
+On Android, we have different choices when it comes to frameworks for solving this particular problem but the most famous is Dagger 2, first made by the awesome guys at Square and then evolved by Google itself. Specifically, Dagger 1 was made by the first and then Big G took over the project and created the second version, with major changes such being based on annotations and doing its job at compile time.
+
+### Importing the framework
+
+Setting up Dagger is no big deal, but it requires us to import the android-apt plugin by adding its dependency in the build.gradle file in the root directory of the project:
+
+```
+buildscript{
+ ...
+ dependencies{
+ ...
+ classpath ‘com.neenbedankt.gradle.plugins:android-apt:1.8’
+ }
+}
+```
+
+Then, we need to apply the android-apt plugin in the top part of the app’s build.gradle file, right below the Android application one:
+
+```
+apply plugin: ‘com.neenbedankt.android-apt’
+```
+
+At this point, we just need to add the dependencies so that we are now able to use the libraries and its annotations:
+
+```
+dependencies{
+ ...
+ compile ‘com.google.dagger:dagger:2.6’
+ apt ‘com.google.dagger:dagger-compiler:2.6’
+ provided ‘javax.annotation:jsr250-api:1.0’
+}
+```
+
+>The last dependency is needed because the @Generated annotation is not yet available on Android, but it’s pure Java.
+
+### Dagger Modules
+
+For injecting our dependencies, we first need to tell the framework what we can provide (i.e. the Context) and how that specific object is built. In order to do this, we annotate a specific class with the @Module annotation (so that Dagger is able to pick it up) scan for the @Provide annotated methods and generate the graph that will give us the object we request.
+
+Let’s see an example where we create a module that will give us the ConnectivityManager. So we need the Context that we will pass in the constructor of the module:
+
+>A very interesting feature of Dagger is providing a Singleton by simply annotating a method, dealing with all the issues inherited from Java by itself.
+
+### The Components
+
+Once we have a module, we need to tell Dagger where we want our dependencies to be injected: we do this in a Component, a specifically annotated interface in which we create different methods, where the parameters are the classes into which we want our dependencies to be injected.
+
+Let’s give an example and say that we want our MainActivity class to be able to receive the ConnectivityManager (or any other dependency in the graph). We would simply do something like this:
+
+>As we can see, the @Component annotation takes some parameters, one being an array of the modules supported, meaning the dependencies it can provide. In our case, that would be both the Context and the ConnectivityManager, as they are declared in the ApplicationModule class.
+
+### Wiring up
+
+At this point, what we need to do is create the Component as soon as possible (such as in the onCreate phase of the Application) and return it, so that the classes can use it for injecting the dependencies:
+
+>In order to have the DaggerApplicationComponent automatically generated by the framework, we need to build our projects so that Dagger can scan our codebase and generate the parts we need.
+
+In our MainActivity, though, the two things we need to do are annotate a property we want to inject with the @Inject annotation and invoke the method we declared in the ApplicationComponent interface (note that this last part varies based on what kind of injection we are performing, but for the moment we can leave it as is for the simplicity), so that our dependencies get injected and we can use them freely:
+
+### Conclusion
+
+Of course, we could do Dependency Injection manually, managing all the different objects, but Dagger takes away a lot of the “noise” involved with such boilerplate, giving us some nice additions (such as Singleton) that would otherwise be pretty awful to deal with in Java.
+
+--------------------------------------------------------------------------------
+
+via: https://medium.com/di-101/di-101-part-1-81896c2858a0#.3hg0jj14o
+
+作者:[Roberto Orgiu][a]
+译者:[译者ID](https://github.com/译者ID)
+校对:[校对者ID](https://github.com/校对者ID)
+
+本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
+
+[a]: https://medium.com/@_tiwiz
+[1]: https://en.wikipedia.org/wiki/Single_responsibility_principle
+[2]: https://en.wikipedia.org/wiki/Open/closed_principle
+[3]: http://liskov_substitution_principle/
+[4]: https://en.wikipedia.org/wiki/Interface_segregation_principle
+[5]: https://en.wikipedia.org/wiki/Dependency_inversion_principle
diff --git a/sources/tech/LFCS/Part 11 - How to Manage and Create LVM Using vgcreate, lvcreate and lvextend Commands.md b/sources/tech/LFCS/Part 11 - How to Manage and Create LVM Using vgcreate, lvcreate and lvextend Commands.md
deleted file mode 100644
index 4d2a9d7a13..0000000000
--- a/sources/tech/LFCS/Part 11 - How to Manage and Create LVM Using vgcreate, lvcreate and lvextend Commands.md
+++ /dev/null
@@ -1,206 +0,0 @@
-Part 11 - How to Manage and Create LVM Using vgcreate, lvcreate and lvextend Commands
-============================================================================================
-
-Because of the changes in the LFCS exam requirements effective Feb. 2, 2016, we are adding the necessary topics to the [LFCS series][1] published here. To prepare for this exam, your are highly encouraged to use the [LFCE series][2] as well.
-
-![](http://www.tecmint.com/wp-content/uploads/2016/03/Manage-LVM-and-Create-LVM-Partition-in-Linux.png)
->LFCS: Manage LVM and Create LVM Partition – Part 11
-
-One of the most important decisions while installing a Linux system is the amount of storage space to be allocated for system files, home directories, and others. If you make a mistake at that point, growing a partition that has run out of space can be burdensome and somewhat risky.
-
-**Logical Volumes Management** (also known as **LVM**), which have become a default for the installation of most (if not all) Linux distributions, have numerous advantages over traditional partitioning management. Perhaps the most distinguishing feature of LVM is that it allows logical divisions to be resized (reduced or increased) at will without much hassle.
-
-The structure of the LVM consists of:
-
-* One or more entire hard disks or partitions are configured as physical volumes (PVs).
-* A volume group (**VG**) is created using one or more physical volumes. You can think of a volume group as a single storage unit.
-* Multiple logical volumes can then be created in a volume group. Each logical volume is somewhat equivalent to a traditional partition – with the advantage that it can be resized at will as we mentioned earlier.
-
-In this article we will use three disks of **8 GB** each (**/dev/sdb**, **/dev/sdc**, and **/dev/sdd**) to create three physical volumes. You can either create the PVs directly on top of the device, or partition it first.
-
-Although we have chosen to go with the first method, if you decide to go with the second (as explained in [Part 4 – Create Partitions and File Systems in Linux][3] of this series) make sure to configure each partition as type `8e`.
-
-### Creating Physical Volumes, Volume Groups, and Logical Volumes
-
-To create physical volumes on top of **/dev/sdb**, **/dev/sdc**, and **/dev/sdd**, do:
-
-```
-# pvcreate /dev/sdb /dev/sdc /dev/sdd
-```
-
-You can list the newly created PVs with:
-
-```
-# pvs
-```
-
-and get detailed information about each PV with:
-
-```
-# pvdisplay /dev/sdX
-```
-
-(where **X** is b, c, or d)
-
-If you omit `/dev/sdX` as parameter, you will get information about all the PVs.
-
-To create a volume group named `vg00` using `/dev/sdb` and `/dev/sdc` (we will save `/dev/sdd` for later to illustrate the possibility of adding other devices to expand storage capacity when needed):
-
-```
-# vgcreate vg00 /dev/sdb /dev/sdc
-```
-
-As it was the case with physical volumes, you can also view information about this volume group by issuing:
-
-```
-# vgdisplay vg00
-```
-
-Since `vg00` is formed with two **8 GB** disks, it will appear as a single **16 GB** drive:
-
-![](http://www.tecmint.com/wp-content/uploads/2016/03/List-LVM-Volume-Groups.png)
->List LVM Volume Groups
-
-When it comes to creating logical volumes, the distribution of space must take into consideration both current and future needs. It is considered good practice to name each logical volume according to its intended use.
-
-For example, let’s create two LVs named `vol_projects` (**10 GB**) and `vol_backups` (remaining space), which we can use later to store project documentation and system backups, respectively.
-
-The `-n` option is used to indicate a name for the LV, whereas `-L` sets a fixed size and `-l` (lowercase L) is used to indicate a percentage of the remaining space in the container VG.
-
-```
-# lvcreate -n vol_projects -L 10G vg00
-# lvcreate -n vol_backups -l 100%FREE vg00
-```
-
-As before, you can view the list of LVs and basic information with:
-
-```
-# lvs
-```
-
-and detailed information with
-
-```
-# lvdisplay
-```
-
-To view information about a single **LV**, use **lvdisplay** with the **VG** and **LV** as parameters, as follows:
-
-```
-# lvdisplay vg00/vol_projects
-```
-
-![](http://www.tecmint.com/wp-content/uploads/2016/03/List-Logical-Volume.png)
->List Logical Volume
-
-In the image above we can see that the LVs were created as storage devices (refer to the LV Path line). Before each logical volume can be used, we need to create a filesystem on top of it.
-
-We’ll use ext4 as an example here since it allows us both to increase and reduce the size of each LV (as opposed to xfs that only allows to increase the size):
-
-```
-# mkfs.ext4 /dev/vg00/vol_projects
-# mkfs.ext4 /dev/vg00/vol_backups
-```
-
-In the next section we will explain how to resize logical volumes and add extra physical storage space when the need arises to do so.
-
-### Resizing Logical Volumes and Extending Volume Groups
-
-Now picture the following scenario. You are starting to run out of space in `vol_backups`, while you have plenty of space available in `vol_projects`. Due to the nature of LVM, we can easily reduce the size of the latter (say **2.5 GB**) and allocate it for the former, while resizing each filesystem at the same time.
-
-Fortunately, this is as easy as doing:
-
-```
-# lvreduce -L -2.5G -r /dev/vg00/vol_projects
-# lvextend -l +100%FREE -r /dev/vg00/vol_backups
-```
-
-![](http://www.tecmint.com/wp-content/uploads/2016/03/Resize-Reduce-Logical-Volume-and-Volume-Group.png)
->Resize Reduce Logical Volume and Volume Group
-
-It is important to include the minus `(-)` or plus `(+)` signs while resizing a logical volume. Otherwise, you’re setting a fixed size for the LV instead of resizing it.
-
-It can happen that you arrive at a point when resizing logical volumes cannot solve your storage needs anymore and you need to buy an extra storage device. Keeping it simple, you will need another disk. We are going to simulate this situation by adding the remaining PV from our initial setup (`/dev/sdd`).
-
-To add `/dev/sdd` to `vg00`, do
-
-```
-# vgextend vg00 /dev/sdd
-```
-
-If you run vgdisplay `vg00` before and after the previous command, you will see the increase in the size of the VG:
-
-```
-# vgdisplay vg00
-```
-
-![](http://www.tecmint.com/wp-content/uploads/2016/03/List-Volume-Group-Size.png)
->Check Volume Group Disk Size
-
-Now you can use the newly added space to resize the existing LVs according to your needs, or to create additional ones as needed.
-
-### Mounting Logical Volumes on Boot and on Demand
-
-Of course there would be no point in creating logical volumes if we are not going to actually use them! To better identify a logical volume we will need to find out what its `UUID` (a non-changing attribute that uniquely identifies a formatted storage device) is.
-
-To do that, use blkid followed by the path to each device:
-
-```
-# blkid /dev/vg00/vol_projects
-# blkid /dev/vg00/vol_backups
-```
-
-![](http://www.tecmint.com/wp-content/uploads/2016/03/Find-Logical-Volume-UUID.png)
->Find Logical Volume UUID
-
-Create mount points for each LV:
-
-```
-# mkdir /home/projects
-# mkdir /home/backups
-```
-
-and insert the corresponding entries in `/etc/fstab` (make sure to use the UUIDs obtained before):
-
-```
-UUID=b85df913-580f-461c-844f-546d8cde4646 /home/projects ext4 defaults 0 0
-UUID=e1929239-5087-44b1-9396-53e09db6eb9e /home/backups ext4 defaults 0 0
-```
-
-Then save the changes and mount the LVs:
-
-```
-# mount -a
-# mount | grep home
-```
-
-![](http://www.tecmint.com/wp-content/uploads/2016/03/Find-Logical-Volume-UUID.png)
->Find Logical Volume UUID
-
-When it comes to actually using the LVs, you will need to assign proper `ugo+rwx` permissions as explained in [Part 8 – Manage Users and Groups in Linux][4] of this series.
-
-### Summary
-
-In this article we have introduced [Logical Volume Management][5], a versatile tool to manage storage devices that provides scalability. When combined with RAID (which we explained in [Part 6 – Create and Manage RAID in Linux][6] of this series), you can enjoy not only scalability (provided by LVM) but also redundancy (offered by RAID).
-
-In this type of setup, you will typically find `LVM` on top of `RAID`, that is, configure RAID first and then configure LVM on top of it.
-
-If you have questions about this article, or suggestions to improve it, feel free to reach us using the comment form below.
-
---------------------------------------------------------------------------------
-
-via: http://www.tecmint.com/linux-basic-shell-scripting-and-linux-filesystem-troubleshooting/
-
-作者:[Gabriel Cánepa][a]
-译者:[译者ID](https://github.com/译者ID)
-校对:[校对者ID](https://github.com/校对者ID)
-
-本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创翻译,[Linux中国](https://linux.cn/) 荣誉推出
-
-[a]: http://www.tecmint.com/author/gacanepa/
-[1]: http://www.tecmint.com/sed-command-to-create-edit-and-manipulate-files-in-linux/
-[2]: http://www.tecmint.com/installing-network-services-and-configuring-services-at-system-boot/
-[3]: http://www.tecmint.com/create-partitions-and-filesystems-in-linux/
-[4]: http://www.tecmint.com/manage-users-and-groups-in-linux/
-[5]: http://www.tecmint.com/create-lvm-storage-in-linux/
-[6]: http://www.tecmint.com/creating-and-managing-raid-backups-in-linux/
diff --git a/sources/tech/LFCS/Part 12 - How to Explore Linux with Installed Help Documentations and Tools.md b/sources/tech/LFCS/Part 12 - How to Explore Linux with Installed Help Documentations and Tools.md
deleted file mode 100644
index 60903d5cce..0000000000
--- a/sources/tech/LFCS/Part 12 - How to Explore Linux with Installed Help Documentations and Tools.md
+++ /dev/null
@@ -1,181 +0,0 @@
-翻译申请 tresspassing2
-Part 12 - LFCS: How to Explore Linux with Installed Help Documentations and Tools
-==================================================================================
-
-Because of the changes in the LFCS exam requirements effective Feb. 2, 2016, we are adding the necessary topics to the [LFCS series][1] published here. To prepare for this exam, your are highly encouraged to use the [LFCE series][2] as well.
-
-![](http://www.tecmint.com/wp-content/uploads/2016/03/Explore-Linux-with-Documentation-and-Tools.png)
->LFCS: Explore Linux with Installed Documentations and Tools – Part 12
-
-Once you get used to working with the command line and feel comfortable doing so, you realize that a regular Linux installation includes all the documentation you need to use and configure the system.
-
-Another good reason to become familiar with command line help tools is that in the [LFCS][3] and [LFCE][4] exams, those are the only sources of information you can use – no internet browsing and no googling. It’s just you and the command line.
-
-For that reason, in this article we will give you some tips to effectively use the installed docs and tools in order to prepare to pass the **Linux Foundation Certification** exams.
-
-### Linux Man Pages
-
-A man page, short for manual page, is nothing less and nothing more than what the word suggests: a manual for a given tool. It contains the list of options (with explanation) that the command supports, and some man pages even include usage examples as well.
-
-To open a man page, use the **man command** followed by the name of the tool you want to learn more about. For example:
-
-```
-# man diff
-```
-
-will open the manual page for `diff`, a tool used to compare text files line by line (to exit, simply hit the q key.).
-
-Let’s say we want to compare two text files named `file1` and `file2` in Linux. These files contain the list of packages that are installed in two Linux boxes with the same distribution and version.
-
-Doing a `diff` between `file1` and `file2` will tell us if there is a difference between those lists:
-
-```
-# diff file1 file2
-```
-
-![](http://www.tecmint.com/wp-content/uploads/2016/03/Compare-Two-Text-Files-in-Linux.png)
->Compare Two Text Files in Linux
-
-where the `<` sign indicates lines missing in `file2`. If there were lines missing in `file1`, they would be indicated by the `>` sign instead.
-
-On the other hand, **7d6** means line **#7** in file should be deleted in order to match `file2` (same with **24d22** and **41d38**), and 65,67d61 tells us we need to remove lines **65** through **67** in file one. If we make these corrections, both files will then be identical.
-
-Alternatively, you can display both files side by side using the `-y` option, according to the man page. You may find this helpful to more easily identify missing lines in files:
-
-```
-# diff -y file1 file2
-```
-
-![](http://www.tecmint.com/wp-content/uploads/2016/03/Compare-and-List-Difference-of-Two-Files.png)
->Compare and List Difference of Two Files
-
-Also, you can use `diff` to compare two binary files. If they are identical, `diff` will exit silently without output. Otherwise, it will return the following message: “**Binary files X and Y differ**”.
-
-### The –help Option
-
-The `--help` option, available in many (if not all) commands, can be considered a short manual page for that specific command. Although it does not provide a comprehensive description of the tool, it is an easy way to obtain information on the usage of a program and a list of its available options at a quick glance.
-
-For example,
-
-```
-# sed --help
-```
-
-shows the usage of each option available in sed (the stream editor).
-
-One of the classic examples of using `sed` consists of replacing characters in files. Using the `-i` option (described as “**edit files in place**”), you can edit a file without opening it. If you want to make a backup of the original contents as well, use the `-i` option followed by a SUFFIX to create a separate file with the original contents.
-
-For example, to replace each occurrence of the word `Lorem` with `Tecmint` (case insensitive) in `lorem.txt` and create a new file with the original contents of the file, do:
-
-```
-# less lorem.txt | grep -i lorem
-# sed -i.orig 's/Lorem/Tecmint/gI' lorem.txt
-# less lorem.txt | grep -i lorem
-# less lorem.txt.orig | grep -i lorem
-```
-
-Please note that every occurrence of `Lorem` has been replaced with `Tecmint` in `lorem.txt`, and the original contents of `lorem.txt` has been saved to `lorem.txt.orig`.
-
-![](http://www.tecmint.com/wp-content/uploads/2016/03/Replace-A-String-in-File.png)
->Replace A String in Files
-
-### Installed Documentation in /usr/share/doc
-
-This is probably my favorite pick. If you go to `/usr/share/doc` and do a directory listing, you will see lots of directories with the names of the installed tools in your Linux system.
-
-According to the [Filesystem Hierarchy Standard][5], these directories contain useful information that might not be in the man pages, along with templates and configuration files to make configuration easier.
-
-For example, let’s consider `squid-3.3.8` (version may vary from distribution to distribution) for the popular HTTP proxy and [squid cache server][6].
-
-Let’s `cd` into that directory:
-
-```
-# cd /usr/share/doc/squid-3.3.8
-```
-
-and do a directory listing:
-
-```
-# ls
-```
-
-![](http://www.tecmint.com/wp-content/uploads/2016/03/List-Files-in-Linux.png)
->Linux Directory Listing with ls Command
-
-You may want to pay special attention to `QUICKSTART` and `squid.conf.documented`. These files contain an extensive documentation about Squid and a heavily commented configuration file, respectively. For other packages, the exact names may differ (as **QuickRef** or **00QUICKSTART**, for example), but the principle is the same.
-
-Other packages, such as the Apache web server, provide configuration file templates inside `/usr/share/doc`, that will be helpful when you have to configure a standalone server or a virtual host, to name a few cases.
-
-### GNU info Documentation
-
-You can think of info documents as man pages on steroids. As such, they not only provide help for a specific tool, but also they do so with hyperlinks (yes, hyperlinks in the command line!) that allow you to navigate from a section to another using the arrow keys and Enter to confirm.
-
-Perhaps the most illustrative example is:
-
-```
-# info coreutils
-```
-
-Since coreutils contains the [basic file, shell and text manipulation utilities][7] which are expected to exist on every operating system, you can reasonably expect a detailed description for each one of those categories in info **coreutils**.
-
-![](http://www.tecmint.com/wp-content/uploads/2016/03/Info-Coreutils.png)
->Info Coreutils
-
-As it is the case with man pages, you can exit an info document by pressing the `q` key.
-
-Additionally, GNU info can be used to display regular man pages as well when followed by the tool name. For example:
-
-```
-# info tune2fs
-```
-
-will return the man page of **tune2fs**, the ext2/3/4 filesystems management tool.
-
-And now that we’re at it, let’s review some of the uses of **tune2fs**:
-
-Display information about the filesystem on top of **/dev/mapper/vg00-vol_backups**:
-
-```
-# tune2fs -l /dev/mapper/vg00-vol_backups
-```
-
-Set a filesystem volume name (Backups in this case):
-
-```
-# tune2fs -L Backups /dev/mapper/vg00-vol_backups
-```
-
-Change the check intervals and `/` or mount counts (use the `-c` option to set a number of mount counts and `/` or the `-i` option to set a check interval, where **d=days, w=weeks, and m=months**).
-
-```
-# tune2fs -c 150 /dev/mapper/vg00-vol_backups # Check every 150 mounts
-# tune2fs -i 6w /dev/mapper/vg00-vol_backups # Check every 6 weeks
-```
-
-All of the above options can be listed with the `--help` option, or viewed in the man page.
-
-### Summary
-
-Regardless of the method that you choose to invoke help for a given tool, knowing that they exist and how to use them will certainly come in handy in the exam. Do you know of any other tools that can be used to look up documentation? Feel free to share with the Tecmint community using the form below.
-
-Questions and other comments are more than welcome as well.
-
---------------------------------------------------------------------------------
-
-via: http://www.tecmint.com/linux-basic-shell-scripting-and-linux-filesystem-troubleshooting/
-
-作者:[Gabriel Cánepa][a]
-译者:[译者ID](https://github.com/译者ID)
-校对:[校对者ID](https://github.com/校对者ID)
-
-本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创翻译,[Linux中国](https://linux.cn/) 荣誉推出
-
-[a]:http://www.tecmint.com/author/gacanepa/
-[1]: http://www.tecmint.com/sed-command-to-create-edit-and-manipulate-files-in-linux/
-[2]: http://www.tecmint.com/installing-network-services-and-configuring-services-at-system-boot/
-[3]: http://www.tecmint.com/sed-command-to-create-edit-and-manipulate-files-in-linux/
-[4]: http://www.tecmint.com/installing-network-services-and-configuring-services-at-system-boot/
-[5]: http://www.tecmint.com/linux-directory-structure-and-important-files-paths-explained/
-[6]: http://www.tecmint.com/configure-squid-server-in-linux/
-[7]: http://www.tecmint.com/sed-command-to-create-edit-and-manipulate-files-in-linux/
-[8]:
diff --git a/sources/tech/LFCS/Part 13 - How to Configure and Troubleshoot Grand Unified Bootloader (GRUB).md b/sources/tech/LFCS/Part 13 - How to Configure and Troubleshoot Grand Unified Bootloader (GRUB).md
deleted file mode 100644
index cf24c51b58..0000000000
--- a/sources/tech/LFCS/Part 13 - How to Configure and Troubleshoot Grand Unified Bootloader (GRUB).md
+++ /dev/null
@@ -1,185 +0,0 @@
-Part 13 - LFCS: How to Configure and Troubleshoot Grand Unified Bootloader (GRUB)
-=====================================================================================
-
-Because of the changes in the LFCS exam requirements effective Feb. 2, 2016, we are adding the necessary topics to the [LFCS series][1] published here. To prepare for this exam, your are highly encouraged to use the [LFCE series][2] as well.
-
-![](http://www.tecmint.com/wp-content/uploads/2016/03/Configure-Troubleshoot-Grub-Boot-Loader.png)
->LFCS: Configure and Troubleshoot Grub Boot Loader – Part 13
-
-In this article we will introduce you to GRUB and explain why a boot loader is necessary, and how it adds versatility to the system.
-
-The [Linux boot process][3] from the time you press the power button of your computer until you get a fully-functional system follows this high-level sequence:
-
-* 1. A process known as **POST** (**Power-On Self Test**) performs an overall check on the hardware components of your computer.
-* 2. When **POST** completes, it passes the control over to the boot loader, which in turn loads the Linux kernel in memory (along with **initramfs**) and executes it. The most used boot loader in Linux is the **GRand Unified Boot loader**, or **GRUB** for short.
-* 3. The kernel checks and accesses the hardware, and then runs the initial process (mostly known by its generic name “**init**”) which in turn completes the system boot by starting services.
-
-In Part 7 of this series (“[SysVinit, Upstart, and Systemd][4]”) we introduced the [service management systems and tools][5] used by modern Linux distributions. You may want to review that article before proceeding further.
-
-### Introducing GRUB Boot Loader
-
-Two major **GRUB** versions (**v1** sometimes called **GRUB Legacy** and **v2**) can be found in modern systems, although most distributions use **v2** by default in their latest versions. Only **Red Hat Enterprise Linux 6** and its derivatives still use **v1** today.
-
-Thus, we will focus primarily on the features of **v2** in this guide.
-
-Regardless of the **GRUB** version, a boot loader allows the user to:
-
-* 1). modify the way the system behaves by specifying different kernels to use,
-* 2). choose between alternate operating systems to boot, and
-* 3). add or edit configuration stanzas to change boot options, among other things.
-
-Today, **GRUB** is maintained by the **GNU** project and is well documented in their website. You are encouraged to use the [GNU official documentation][6] while going through this guide.
-
-When the system boots you are presented with the following **GRUB** screen in the main console. Initially, you are prompted to choose between alternate kernels (by default, the system will boot using the latest kernel) and are allowed to enter a **GRUB** command line (with `c`) or edit the boot options (by pressing the `e` key).
-
-![](http://www.tecmint.com/wp-content/uploads/2016/03/GRUB-Boot-Screen.png)
->GRUB Boot Screen
-
-One of the reasons why you would consider booting with an older kernel is a hardware device that used to work properly and has started “acting up” after an upgrade (refer to [this link][7] in the AskUbuntu forums for an example).
-
-The **GRUB v2** configuration is read on boot from `/boot/grub/grub.cfg` or `/boot/grub2/grub.cfg`, whereas `/boot/grub/grub.conf` or `/boot/grub/menu.lst` are used in **v1**. These files are NOT to be edited by hand, but are modified based on the contents of `/etc/default/grub` and the files found inside `/etc/grub.d`.
-
-In a **CentOS 7**, here’s the configuration file that is created when the system is first installed:
-
-```
-GRUB_TIMEOUT=5
-GRUB_DISTRIBUTOR="$(sed 's, release .*$,,g' /etc/system-release)"
-GRUB_DEFAULT=saved
-GRUB_DISABLE_SUBMENU=true
-GRUB_TERMINAL_OUTPUT="console"
-GRUB_CMDLINE_LINUX="vconsole.keymap=la-latin1 rd.lvm.lv=centos_centos7-2/swap crashkernel=auto vconsole.font=latarcyrheb-sun16 rd.lvm.lv=centos_centos7-2/root rhgb quiet"
-GRUB_DISABLE_RECOVERY="true"
-```
-
-In addition to the online documentation, you can also find the GNU GRUB manual using info as follows:
-
-```
-# info grub
-```
-
-If you’re interested specifically in the options available for /etc/default/grub, you can invoke the configuration section directly:
-
-```
-# info -f grub -n 'Simple configuration'
-```
-
-Using the command above you will find out that `GRUB_TIMEOUT` sets the time between the moment when the initial screen appears and the system automatic booting begins unless interrupted by the user. When this variable is set to `-1`, boot will not be started until the user makes a selection.
-
-When multiple operating systems or kernels are installed in the same machine, `GRUB_DEFAULT` requires an integer value that indicates which OS or kernel entry in the GRUB initial screen should be selected to boot by default. The list of entries can be viewed not only in the splash screen shown above, but also using the following command:
-
-### In CentOS and openSUSE:
-
-```
-# awk -F\' '$1=="menuentry " {print $2}' /boot/grub2/grub.cfg
-```
-
-### In Ubuntu:
-
-```
-# awk -F\' '$1=="menuentry " {print $2}' /boot/grub/grub.cfg
-```
-
-In the example shown in the below image, if we wish to boot with the kernel version **3.10.0-123.el7.x86_64** (4th entry), we need to set `GRUB_DEFAULT` to `3` (entries are internally numbered beginning with zero) as follows:
-
-```
-GRUB_DEFAULT=3
-```
-
-![](http://www.tecmint.com/wp-content/uploads/2016/03/Boot-System-with-Old-Kernel-Version.png)
->Boot System with Old Kernel Version
-
-One final GRUB configuration variable that is of special interest is `GRUB_CMDLINE_LINUX`, which is used to pass options to the kernel. The options that can be passed through GRUB to the kernel are well documented in the [Kernel Parameters file][8] and in [man 7 bootparam][9].
-
-Current options in my **CentOS 7** server are:
-
-```
-GRUB_CMDLINE_LINUX="vconsole.keymap=la-latin1 rd.lvm.lv=centos_centos7-2/swap crashkernel=auto vconsole.font=latarcyrheb-sun16 rd.lvm.lv=centos_centos7-2/root rhgb quiet"
-```
-
-Why would you want to modify the default kernel parameters or pass extra options? In simple terms, there may be times when you need to tell the kernel certain hardware parameters that it may not be able to determine on its own, or to override the values that it would detect.
-
-This happened to me not too long ago when I tried **Vector Linux**, a derivative of **Slackware**, on my 10-year old laptop. After installation it did not detect the right settings for my video card so I had to modify the kernel options passed through GRUB in order to make it work.
-
-Another example is when you need to bring the system to single-user mode to perform maintenance tasks. You can do this by appending the word single to `GRUB_CMDLINE_LINUX` and rebooting:
-
-```
-GRUB_CMDLINE_LINUX="vconsole.keymap=la-latin1 rd.lvm.lv=centos_centos7-2/swap crashkernel=auto vconsole.font=latarcyrheb-sun16 rd.lvm.lv=centos_centos7-2/root rhgb quiet single"
-```
-
-After editing `/etc/defalt/grub`, you will need to run `update-grub` (Ubuntu) or `grub2-mkconfig -o /boot/grub2/grub.cfg` (**CentOS** and **openSUSE**) afterwards to update `grub.cfg` (otherwise, changes will be lost upon boot).
-
-This command will process the boot configuration files mentioned earlier to update `grub.cfg`. This method ensures changes are permanent, while options passed through GRUB at boot time will only last during the current session.
-
-### Fixing Linux GRUB Issues
-
-If you install a second operating system or if your GRUB configuration file gets corrupted due to human error, there are ways you can get your system back on its feet and be able to boot again.
-
-In the initial screen, press `c` to get a GRUB command line (remember that you can also press `e` to edit the default boot options), and use help to bring the available commands in the GRUB prompt:
-
-![](http://www.tecmint.com/wp-content/uploads/2016/03/Fix-Grub-Issues-in-Linux.png)
->Fix Grub Configuration Issues in Linux
-
-We will focus on **ls**, which will list the installed devices and filesystems, and we will examine what it finds. In the image below we can see that there are 4 hard drives (`hd0` through `hd3`).
-
-Only `hd0` seems to have been partitioned (as evidenced by msdos1 and msdos2, where 1 and 2 are the partition numbers and msdos is the partitioning scheme).
-
-Let’s now examine the first partition on `hd0` (**msdos1**) to see if we can find GRUB there. This approach will allow us to boot Linux and there use other high level tools to repair the configuration file or reinstall GRUB altogether if it is needed:
-
-```
-# ls (hd0,msdos1)/
-```
-
-As we can see in the highlighted area, we found the `grub2` directory in this partition:
-
-![](http://www.tecmint.com/wp-content/uploads/2016/03/Find-Grub-Configuration.png)
->Find Grub Configuration
-
-Once we are sure that GRUB resides in (**hd0,msdos1**), let’s tell GRUB where to find its configuration file and then instruct it to attempt to launch its menu:
-
-```
-set prefix=(hd0,msdos1)/grub2
-set root=(hd0,msdos1)
-insmod normal
-normal
-```
-
-![](http://www.tecmint.com/wp-content/uploads/2016/03/Find-and-Launch-Grub-Menu.png)
->Find and Launch Grub Menu
-
-Then in the GRUB menu, choose an entry and press **Enter** to boot using it. Once the system has booted you can issue the `grub2-install /dev/sdX` command (change `sdX` with the device you want to install GRUB on). The boot information will then be updated and all related files be restored.
-
-```
-# grub2-install /dev/sdX
-```
-
-Other more complex scenarios are documented, along with their suggested fixes, in the [Ubuntu GRUB2 Troubleshooting guide][10]. The concepts explained there are valid for other distributions as well.
-
-### Summary
-
-In this article we have introduced you to GRUB, indicated where you can find documentation both online and offline, and explained how to approach an scenario where a system has stopped booting properly due to a bootloader-related issue.
-
-Fortunately, GRUB is one of the tools that is best documented and you can easily find help either in the installed docs or online using the resources we have shared in this article.
-
-Do you have questions or comments? Don’t hesitate to let us know using the comment form below. We look forward to hearing from you!
-
---------------------------------------------------------------------------------
-
-via: http://www.tecmint.com/linux-basic-shell-scripting-and-linux-filesystem-troubleshooting/
-
-作者:[Gabriel Cánepa][a]
-译者:[译者ID](https://github.com/译者ID)
-校对:[校对者ID](https://github.com/校对者ID)
-
-本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创翻译,[Linux中国](https://linux.cn/) 荣誉推出
-
-[a]: http://www.tecmint.com/author/gacanepa/
-[1]: http://www.tecmint.com/sed-command-to-create-edit-and-manipulate-files-in-linux/
-[2]: http://www.tecmint.com/installing-network-services-and-configuring-services-at-system-boot/
-[3]: http://www.tecmint.com/linux-boot-process/
-[4]: http://www.tecmint.com/linux-boot-process-and-manage-services/
-[5]: http://www.tecmint.com/best-linux-log-monitoring-and-management-tools/
-[6]: http://www.gnu.org/software/grub/manual/
-[7]: http://askubuntu.com/questions/82140/how-can-i-boot-with-an-older-kernel-version
-[8]: https://www.kernel.org/doc/Documentation/kernel-parameters.txt
-[9]: http://man7.org/linux/man-pages/man7/bootparam.7.html
-[10]: https://help.ubuntu.com/community/Grub2/Troubleshooting
diff --git a/sources/tech/LXD/Part 4 - LXD 2.0--Resource control.md b/sources/tech/LXD/Part 4 - LXD 2.0--Resource control.md
index 736c5b84bc..e404cccffa 100644
--- a/sources/tech/LXD/Part 4 - LXD 2.0--Resource control.md
+++ b/sources/tech/LXD/Part 4 - LXD 2.0--Resource control.md
@@ -1,6 +1,3 @@
-ezio is translating
-
-
Part 4 - LXD 2.0: Resource control
======================================
diff --git a/sources/tech/awk/Part 1 - How to Use Awk and Regular Expressions to Filter Text or String in Files.md b/sources/tech/awk/Part 1 - How to Use Awk and Regular Expressions to Filter Text or String in Files.md
deleted file mode 100644
index 6871673536..0000000000
--- a/sources/tech/awk/Part 1 - How to Use Awk and Regular Expressions to Filter Text or String in Files.md
+++ /dev/null
@@ -1,214 +0,0 @@
-translating by wwy-hust
-
-How to Use Awk and Regular Expressions to Filter Text or String in Files
-=============================================================================
-
-![](http://www.tecmint.com/wp-content/uploads/2016/04/Linux-Awk-Command-Examples.png)
-
-When we run certain commands in Unix/Linux to read or edit text from a string or file, we most times try to filter output to a given section of interest. This is where using regular expressions comes in handy.
-
-### What are Regular Expressions?
-
-A regular expression can be defined as a strings that represent several sequence of characters. One of the most important things about regular expressions is that they allow you to filter the output of a command or file, edit a section of a text or configuration file and so on.
-
-### Features of Regular Expression
-
-Regular expressions are made of:
-
-- Ordinary characters such as space, underscore(_), A-Z, a-z, 0-9.
-- Meta characters that are expanded to ordinary characters, they include:
- - `(.)` it matches any single character except a newline.
- - `(*)` it matches zero or more existences of the immediate character preceding it.
- - `[ character(s) ]` it matches any one of the characters specified in character(s), one can also use a hyphen (-) to mean a range of characters such as [a-f], [1-5], and so on.
- - `^` it matches the beginning of a line in a file.
- - `$` matches the end of line in a file.
- - `\` it is an escape character.
-
-In order to filter text, one has to use a text filtering tool such as awk. You can think of awk as a programming language of its own. But for the scope of this guide to using awk, we shall cover it as a simple command line filtering tool.
-
-The general syntax of awk is:
-
-```
-# awk 'script' filename
-```
-
-Where `'script'` is a set of commands that are understood by awk and are execute on file, filename.
-
-It works by reading a given line in the file, makes a copy of the line and then executes the script on the line. This is repeated on all the lines in the file.
-
-The `'script'` is in the form `'/pattern/ action'` where pattern is a regular expression and the action is what awk will do when it finds the given pattern in a line.
-
-### How to Use Awk Filtering Tool in Linux
-
-In the following examples, we shall focus on the meta characters that we discussed above under the features of awk.
-
-#### A simple example of using awk:
-
-The example below prints all the lines in the file /etc/hosts since no pattern is given.
-
-```
-# awk '//{print}'/etc/hosts
-```
-
-![](http://www.tecmint.com/wp-content/uploads/2016/04/Awk-Command-Example.gif)
->Awk Prints all Lines in a File
-
-#### Use Awk with Pattern:
-
-I the example below, a pattern `localhost` has been given, so awk will match line having localhost in the `/etc/hosts` file.
-
-```
-# awk '/localhost/{print}' /etc/hosts
-```
-
-![](http://www.tecmint.com/wp-content/uploads/2016/04/Use-Awk-Command-with-Pattern.gif)
->Awk Print Given Matching Line in a File
-
-#### Using Awk with (.) wild card in a Pattern
-
-The `(.)` will match strings containing loc, localhost, localnet in the example below.
-
-That is to say *** l some_single_character c ***.
-
-```
-# awk '/l.c/{print}' /etc/hosts
-```
-
-![](http://www.tecmint.com/wp-content/uploads/2016/04/Use-Awk-with-Wild-Cards.gif)
->Use Awk to Print Matching Strings in a File
-
-#### Using Awk with (*) Character in a Pattern
-
-It will match strings containing localhost, localnet, lines, capable, as in the example below:
-
-```
-# awk '/l*c/{print}' /etc/localhost
-```
-
-![](http://www.tecmint.com/wp-content/uploads/2016/04/Use-Awk-to-Match-Strings-in-File.gif)
->Use Awk to Match Strings in File
-
-You will also realize that `(*)` tries to a get you the longest match possible it can detect.
-
-Let look at a case that demonstrates this, take the regular expression `t*t` which means match strings that start with letter `t` and end with `t` in the line below:
-
-```
-this is tecmint, where you get the best good tutorials, how to's, guides, tecmint.
-```
-
-You will get the following possibilities when you use the pattern `/t*t/`:
-
-```
-this is t
-this is tecmint
-this is tecmint, where you get t
-this is tecmint, where you get the best good t
-this is tecmint, where you get the best good tutorials, how t
-this is tecmint, where you get the best good tutorials, how tos, guides, t
-this is tecmint, where you get the best good tutorials, how tos, guides, tecmint
-```
-
-And `(*)` in `/t*t/` wild card character allows awk to choose the the last option:
-
-```
-this is tecmint, where you get the best good tutorials, how to's, guides, tecmint
-```
-
-#### Using Awk with set [ character(s) ]
-
-Take for example the set [al1], here awk will match all strings containing character a or l or 1 in a line in the file /etc/hosts.
-
-```
-# awk '/[al1]/{print}' /etc/hosts
-```
-
-![](http://www.tecmint.com/wp-content/uploads/2016/04/Use-Awk-to-Print-Matching-Character.gif)
->Use-Awk to Print Matching Character in File
-
-The next example matches strings starting with either `K` or `k` followed by `T`:
-
-```
-# awk '/[Kk]T/{print}' /etc/hosts
-```
-
-![](http://www.tecmint.com/wp-content/uploads/2016/04/Use-Awk-to-Print-Matched-String-in-File.gif)
->Use Awk to Print Matched String in File
-
-#### Specifying Characters in a Range
-
-Understand characters with awk:
-
-- `[0-9]` means a single number
-- `[a-z]` means match a single lower case letter
-- `[A-Z]` means match a single upper case letter
-- `[a-zA-Z]` means match a single letter
-- `[a-zA-Z 0-9]` means match a single letter or number
-
-Lets look at an example below:
-
-```
-# awk '/[0-9]/{print}' /etc/hosts
-```
-
-![](http://www.tecmint.com/wp-content/uploads/2016/04/Use-Awk-To-Print-Matching-Numbers-in-File.gif)
->Use Awk To Print Matching Numbers in File
-
-All the line from the file /etc/hosts contain at least a single number [0-9] in the above example.
-
-#### Use Awk with (^) Meta Character
-
-It matches all the lines that start with the pattern provided as in the example below:
-
-```
-# awk '/^fe/{print}' /etc/hosts
-# awk '/^ff/{print}' /etc/hosts
-```
-
-![](http://www.tecmint.com/wp-content/uploads/2016/04/Use-Awk-to-Print-All-Matching-Lines-with-Pattern.gif)
->Use Awk to Print All Matching Lines with Pattern
-
-#### Use Awk with ($) Meta Character
-
-It matches all the lines that end with the pattern provided:
-
-```
-# awk '/ab$/{print}' /etc/hosts
-# awk '/ost$/{print}' /etc/hosts
-# awk '/rs$/{print}' /etc/hosts
-```
-
-![](http://www.tecmint.com/wp-content/uploads/2016/04/Use-Awk-to-Print-Given-Pattern-String.gif)
->Use Awk to Print Given Pattern String
-
-#### Use Awk with (\) Escape Character
-
-It allows you to take the character following it as a literal that is to say consider it just as it is.
-
-In the example below, the first command prints out all line in the file, the second command prints out nothing because I want to match a line that has $25.00, but no escape character is used.
-
-The third command is correct since a an escape character has been used to read $ as it is.
-
-```
-# awk '//{print}' deals.txt
-# awk '/$25.00/{print}' deals.txt
-# awk '/\$25.00/{print}' deals.txt
-```
-
-![](http://www.tecmint.com/wp-content/uploads/2016/04/Use-Awk-with-Escape-Character.gif)
->Use Awk with Escape Character
-
-### Summary
-
-That is not all with the awk command line filtering tool, the examples above a the basic operations of awk. In the next parts we shall be advancing on how to use complex features of awk. Thanks for reading through and for any additions or clarifications, post a comment in the comments section.
-
---------------------------------------------------------------------------------
-
-via: http://www.tecmint.com/use-linux-awk-command-to-filter-text-string-in-files/
-
-作者:[Aaron Kili][a]
-译者:[译者ID](https://github.com/译者ID)
-校对:[校对者ID](https://github.com/校对者ID)
-
-本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
-
-[a]: http://www.tecmint.com/author/aaronkili/
diff --git a/sources/tech/awk/Part 3 - How to Use Awk to Filter Text or Strings Using Pattern Specific Actions.md b/sources/tech/awk/Part 3 - How to Use Awk to Filter Text or Strings Using Pattern Specific Actions.md
deleted file mode 100644
index f6aeb69e57..0000000000
--- a/sources/tech/awk/Part 3 - How to Use Awk to Filter Text or Strings Using Pattern Specific Actions.md
+++ /dev/null
@@ -1,83 +0,0 @@
-How to Use Awk to Filter Text or Strings Using Pattern Specific Actions
-=========================================================================
-
-![](http://www.tecmint.com/wp-content/uploads/2016/04/Use-Awk-to-Filter-Text-or-Strings-Using-Pattern.png)
-
-In the third part of the Awk command series, we shall take a look at filtering text or strings based on specific patterns that a user can define.
-
-Sometimes, when filtering text, you want to indicate certain lines from an input file or lines of strings based on a given condition or using a specific pattern that can be matched. Doing this with Awk is very easy, it is one of the great features of Awk that you will find helpful.
-
-Let us take a look at an example below, say you have a shopping list for food items that you want to buy, called food_prices.list. It has the following list of food items and their prices.
-
-```
-$ cat food_prices.list
-No Item_Name Quantity Price
-1 Mangoes 10 $2.45
-2 Apples 20 $1.50
-3 Bananas 5 $0.90
-4 Pineapples 10 $3.46
-5 Oranges 10 $0.78
-6 Tomatoes 5 $0.55
-7 Onions 5 $0.45
-```
-
-And then, you want to indicate a `(*)` sign on food items whose price is greater than $2, this can be done by running the following command:
-
-```
-$ awk '/ *\$[2-9]\.[0-9][0-9] */ { print $1, $2, $3, $4, "*" ; } / *\$[0-1]\.[0-9][0-9] */ { print ; }' food_prices.list
-```
-
-![](http://www.tecmint.com/wp-content/uploads/2016/04/Filter-and-Print-Text-Using-Awk.gif)
->Print Items Whose Price is Greater Than $2
-
-From the output above, you can see that the there is a `(*)` sign at the end of the lines having food items, mangoes and pineapples. If you check their prices, they are above $2.
-
-In this example, we have used used two patterns:
-
-- the first: `/ *\$[2-9]\.[0-9][0-9] */` gets the lines that have food item price greater than $2 and
-- the second: `/*\$[0-1]\.[0-9][0-9] */` looks for lines with food item price less than $2.
-
-This is what happens, there are four fields in the file, when pattern one encounters a line with food item price greater than $2, it prints all the four fields and a `(*)` sign at the end of the line as a flag.
-
-The second pattern simply prints the other lines with food price less than $2 as they appear in the input file, food_prices.list.
-
-This way you can use pattern specific actions to filter out food items that are priced above $2, though there is a problem with the output, the lines that have the `(*)` sign are not formatted out like the rest of the lines making the output not clear enough.
-
-We saw the same problem in Part 2 of the awk series, but we can solve it in two ways:
-
-1. Using printf command which is a long and boring way using the command below:
-
-```
-$ awk '/ *\$[2-9]\.[0-9][0-9] */ { printf "%-10s %-10s %-10s %-10s\n", $1, $2, $3, $4 "*" ; } / *\$[0-1]\.[0-9][0-9] */ { printf "%-10s %-10s %-10s %-10s\n", $1, $2, $3, $4; }' food_prices.list
-```
-
-![](http://www.tecmint.com/wp-content/uploads/2016/04/Filter-and-Print-Items-Using-Awk-and-Printf.gif)
->Filter and Print Items Using Awk and Printf
-
-2. Using $0 field. Awk uses the variable 0 to store the whole input line. This is handy for solving the problem above and it is simple and fast as follows:
-
-```
-$ awk '/ *\$[2-9]\.[0-9][0-9] */ { print $0 "*" ; } / *\$[0-1]\.[0-9][0-9] */ { print ; }' food_prices.list
-```
-
-![](http://www.tecmint.com/wp-content/uploads/2016/04/Filter-and-Print-Items-Using-Awk-and-Variable.gif)
->Filter and Print Items Using Awk and Variable
-
-Conclusion
-That’s it for now and these are simple ways of filtering text using pattern specific action that can help in flagging lines of text or strings in a file using Awk command.
-
-Hope you find this article helpful and remember to read the next part of the series which will focus on using comparison operators using awk tool.
-
-
---------------------------------------------------------------------------------
-
-via: http://www.tecmint.com/awk-filter-text-or-string-using-patterns/
-
-作者:[Aaron Kili][a]
-译者:[译者ID](https://github.com/译者ID)
-校对:[校对者ID](https://github.com/校对者ID)
-
-本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
-
-[a]: http://www.tecmint.com/author/aaronkili/
-
diff --git a/sources/tech/awk/Part 4 - How to Use Comparison Operators with Awk in Linux.md b/sources/tech/awk/Part 4 - How to Use Comparison Operators with Awk in Linux.md
deleted file mode 100644
index 7f3a46360f..0000000000
--- a/sources/tech/awk/Part 4 - How to Use Comparison Operators with Awk in Linux.md
+++ /dev/null
@@ -1,95 +0,0 @@
-How to Use Comparison Operators with Awk in Linux
-===================================================
-
-![](http://www.tecmint.com/wp-content/uploads/2016/05/Use-Comparison-Operators-with-AWK.png)
-
-When dealing with numerical or string values in a line of text, filtering text or strings using comparison operators comes in handy for Awk command users.
-
-In this part of the Awk series, we shall take a look at how you can filter text or strings using comparison operators. If you are a programmer then you must already be familiar with comparison operators but those who are not, let me explain in the section below.
-
-### What are Comparison operators in Awk?
-
-Comparison operators in Awk are used to compare the value of numbers or strings and they include the following:
-
-- `>` – greater than
-- `<` – less than
-- `>=` – greater than or equal to
-- `<=` – less than or equal to
-- `==` – equal to
-- `!=` – not equal to
-- `some_value ~ / pattern/` – true if some_value matches pattern
-- `some_value !~ / pattern/` – true if some_value does not match pattern
-
-Now that we have looked at the various comparison operators in Awk, let us understand them better using an example.
-
-In this example, we have a file named food_list.txt which is a shopping list for different food items and I would like to flag food items whose quantity is less than or equal 20 by adding `(**)` at the end of each line.
-
-```
-File – food_list.txt
-No Item_Name Quantity Price
-1 Mangoes 45 $3.45
-2 Apples 25 $2.45
-3 Pineapples 5 $4.45
-4 Tomatoes 25 $3.45
-5 Onions 15 $1.45
-6 Bananas 30 $3.45
-```
-
-The general syntax for using comparison operators in Awk is:
-
-```
-# expression { actions; }
-```
-
-To achieve the above goal, I will have to run the command below:
-
-```
-# awk '$3 <= 30 { printf "%s\t%s\n", $0,"**" ; } $3 > 30 { print $0 ;}' food_list.txt
-
-No Item_Name` Quantity Price
-1 Mangoes 45 $3.45
-2 Apples 25 $2.45 **
-3 Pineapples 5 $4.45 **
-4 Tomatoes 25 $3.45 **
-5 Onions 15 $1.45 **
-6 Bananas 30 $3.45 **
-```
-
-In the above example, there are two important things that happen:
-
-- The first expression `{ action ; }` combination, `$3 <= 30 { printf “%s\t%s\n”, $0,”**” ; }` prints out lines with quantity less than or equal to 30 and adds a `(**)` at the end of each line. The value of quantity is accessed using `$3` field variable.
-- The second expression `{ action ; }` combination, `$3 > 30 { print $0 ;}` prints out lines unchanged since their quantity is greater then `30`.
-
-One more example:
-
-```
-# awk '$3 <= 20 { printf "%s\t%s\n", $0,"TRUE" ; } $3 > 20 { print $0 ;} ' food_list.txt
-
-No Item_Name Quantity Price
-1 Mangoes 45 $3.45
-2 Apples 25 $2.45
-3 Pineapples 5 $4.45 TRUE
-4 Tomatoes 25 $3.45
-5 Onions 15 $1.45 TRUE
-6 Bananas 30 $3.45
-```
-
-In this example, we want to indicate lines with quantity less or equal to 20 with the word (TRUE) at the end.
-
-### Summary
-
-This is an introductory tutorial to comparison operators in Awk, therefore you need to try out many other options and discover more.
-
-In case of any problems you face or any additions that you have in mind, then drop a comment in the comment section below. Remember to read the next part of the Awk series where I will take you through compound expressions.
-
---------------------------------------------------------------------------------
-
-via: http://www.tecmint.com/comparison-operators-in-awk/
-
-作者:[Aaron Kili][a]
-译者:[译者ID](https://github.com/译者ID)
-校对:[校对者ID](https://github.com/校对者ID)
-
-本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
-
-[a]: http://www.tecmint.com/author/aaronkili/
diff --git a/sources/tech/awk/Part 5 - How to Use Compound Expressions with Awk in Linux.md b/sources/tech/awk/Part 5 - How to Use Compound Expressions with Awk in Linux.md
deleted file mode 100644
index db9a863484..0000000000
--- a/sources/tech/awk/Part 5 - How to Use Compound Expressions with Awk in Linux.md
+++ /dev/null
@@ -1,81 +0,0 @@
-martin
-
-How to Use Compound Expressions with Awk in Linux
-====================================================
-
-![](http://www.tecmint.com/wp-content/uploads/2016/05/Use-Compound-Expressions-with-Awk.png)
-
-All along, we have been looking at simple expressions when checking whether a condition has been meet or not. What if you want to use more then one expression to check for a particular condition in?
-
-In this article, we shall take a look at the how you can combine multiple expressions referred to as compound expressions to check for a condition when filtering text or strings.
-
-In Awk, compound expressions are built using the `&&` referred to as `(and)` and the `||` referred to as `(or)` compound operators.
-
-The general syntax for compound expressions is:
-
-```
-( first_expression ) && ( second_expression )
-```
-
-Here, `first_expression` and `second_expression` must be true to make the whole expression true.
-
-```
-( first_expression ) || ( second_expression)
-```
-
-Here, one of the expressions either `first_expression` or `second_expression` must be true for the whole expression to be true.
-
-**Caution**: Remember to always include the parenthesis.
-
-The expressions can be built using the comparison operators that we looked at in Part 4 of the awk series.
-
-Let us now get a clear understanding using an example below:
-
-In this example, a have a text file named `tecmint_deals.txt`, which contains a list of some amazing random Tecmint deals, it includes the name of the deal, the price and type.
-
-```
-TecMint Deal List
-No Name Price Type
-1 Mac_OS_X_Cleanup_Suite $9.99 Software
-2 Basics_Notebook $14.99 Lifestyle
-3 Tactical_Pen $25.99 Lifestyle
-4 Scapple $19.00 Unknown
-5 Nano_Tool_Pack $11.99 Unknown
-6 Ditto_Bluetooth_Altering_Device $33.00 Tech
-7 Nano_Prowler_Mini_Drone $36.99 Tech
-```
-
-Say that we want only print and flag deals that are above $20 and of type “Tech” using the (**) sign at the end of each line.
-
-We shall need to run the command below.
-
-```
-# awk '($3 ~ /^\$[2-9][0-9]*\.[0-9][0-9]$/) && ($4=="Tech") { printf "%s\t%s\n",$0,"*"; } ' tecmint_deals.txt
-
-6 Ditto_Bluetooth_Altering_Device $33.00 Tech *
-7 Nano_Prowler_Mini_Drone $36.99 Tech *
-```
-
-In this example, we have used two expressions in a compound expression:
-
-- First expression, `($3 ~ /^\$[2-9][0-9]*\.[0-9][0-9]$/)` ; checks the for lines with deals with price above `$20`, and it is only true if the value of $3 which is the price matches the pattern `/^\$[2-9][0-9]*\.[0-9][0-9]$/`
-- And the second expression, `($4 == “Tech”)` ; checks whether the deal is of type “`Tech`” and it is only true if the value of `$4` equals to “`Tech`”.
-Remember, a line will only be flagged with the `(**)`, if first expression and second expression are true as states the principle of the `&&` operator.
-
-### Summary
-
-Some conditions always require building compound expressions for you to match exactly what you want. When you understand the use of comparison and compound expression operators then, filtering text or strings based on some difficult conditions will become easy.
-
-Hope you find this guide useful and for any questions or additions, always remember to leave a comment and your concern will be solved accordingly.
-
---------------------------------------------------------------------------------
-
-via: http://www.tecmint.com/combine-multiple-expressions-in-awk/
-
-作者:[Aaron Kili][a]
-译者:[译者ID](https://github.com/译者ID)
-校对:[校对者ID](https://github.com/校对者ID)
-
-本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
-
-[a]: http://www.tecmint.com/author/aaronkili/
diff --git a/sources/tech/awk/Part 6 - How to Use ‘next’ Command with Awk in Linux.md b/sources/tech/awk/Part 6 - How to Use ‘next’ Command with Awk in Linux.md
deleted file mode 100644
index f272dabcce..0000000000
--- a/sources/tech/awk/Part 6 - How to Use ‘next’ Command with Awk in Linux.md
+++ /dev/null
@@ -1,76 +0,0 @@
-How to Use ‘next’ Command with Awk in Linux
-=============================================
-
-![](http://www.tecmint.com/wp-content/uploads/2016/06/Use-next-Command-with-Awk-in-Linux.png)
-
-In this sixth part of Awk series, we shall look at using `next` command, which tells Awk to skip all remaining patterns and expressions that you have provided, but instead read the next input line.
-
-The `next` command helps you to prevent executing what I would refer to as time-wasting steps in a command execution.
-
-To understand how it works, let us consider a file called food_list.txt that looks like this:
-
-```
-Food List Items
-No Item_Name Price Quantity
-1 Mangoes $3.45 5
-2 Apples $2.45 25
-3 Pineapples $4.45 55
-4 Tomatoes $3.45 25
-5 Onions $1.45 15
-6 Bananas $3.45 30
-```
-
-Consider running the following command that will flag food items whose quantity is less than or equal to 20 with a `(*)` sign at the end of each line:
-
-```
-# awk '$4 <= 20 { printf "%s\t%s\n", $0,"*" ; } $4 > 20 { print $0 ;} ' food_list.txt
-
-No Item_Name Price Quantity
-1 Mangoes $3.45 5 *
-2 Apples $2.45 25
-3 Pineapples $4.45 55
-4 Tomatoes $3.45 25
-5 Onions $1.45 15 *
-6 Bananas $3.45 30
-```
-
-The command above actually works as follows:
-
-- First, it checks whether the quantity, fourth field of each input line is less than or equal to 20, if a value meets that condition, it is printed and flagged with the `(*)` sign at the end using expression one: `$4 <= 20`
-- Secondly, it checks if the fourth field of each input line is greater than 20, and if a line meets the condition it gets printed using expression two: `$4 > 20`
-
-But there is one problem here, when the first expression is executed, a line that we want to flag is printed using: `{ printf "%s\t%s\n", $0,"**" ; }` and then in the same step, the second expression is also checked which becomes a time wasting factor.
-
-So there is no need to execute the second expression, `$4 > 20` again after printing already flagged lines that have been printed using the first expression.
-
-To deal with this problem, you have to use the `next` command as follows:
-
-```
-# awk '$4 <= 20 { printf "%s\t%s\n", $0,"*" ; next; } $4 > 20 { print $0 ;} ' food_list.txt
-
-No Item_Name Price Quantity
-1 Mangoes $3.45 5 *
-2 Apples $2.45 25
-3 Pineapples $4.45 55
-4 Tomatoes $3.45 25
-5 Onions $1.45 15 *
-6 Bananas $3.45 30
-```
-
-After a single input line is printed using `$4 <= 20` `{ printf "%s\t%s\n", $0,"*" ; next ; }`, the `next` command included will help skip the second expression `$4 > 20` `{ print $0 ;}`, so execution goes to the next input line without having to waste time on checking whether the quantity is greater than 20.
-
-The next command is very important is writing efficient commands and where necessary, you can always use to speed up the execution of a script. Prepare for the next part of the series where we shall look at using standard input (STDIN) as input for Awk.
-
-Hope you find this how to guide helpful and you can as always put your thoughts in writing by leaving a comment in the comment section below.
-
---------------------------------------------------------------------------------
-
-via: http://www.tecmint.com/use-next-command-with-awk-in-linux/
-
-作者:[Aaron Kili][a]
-译者:[译者ID](https://github.com/译者ID)
-校对:[校对者ID](https://github.com/校对者ID)
-
-本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
-
-[a]: http://www.tecmint.com/author/aaronkili/
diff --git a/sources/tech/awk/Part 7 - How to Read Awk Input from STDIN in Linux.md b/sources/tech/awk/Part 7 - How to Read Awk Input from STDIN in Linux.md
deleted file mode 100644
index 157716481a..0000000000
--- a/sources/tech/awk/Part 7 - How to Read Awk Input from STDIN in Linux.md
+++ /dev/null
@@ -1,73 +0,0 @@
-vim-kakali translating
-
-
-How to Read Awk Input from STDIN in Linux
-============================================
-
-![](http://www.tecmint.com/wp-content/uploads/2016/06/Read-Awk-Input-from-STDIN.png)
-
-In the previous parts of the Awk tool series, we looked at reading input mostly from a file(s), but what if you want to read input from STDIN.
-In this Part 7 of Awk series, we shall look at few examples where you can filter the output of other commands instead of reading input from a file.
-
-We shall start with the [dir utility][1] that works similar to [ls command][2], in the first example below, we use the output of `dir -l` command as input for Awk to print owner’s username, groupname and the files he/she owns in the current directory:
-
-```
-# dir -l | awk '{print $3, $4, $9;}'
-```
-
-![](http://www.tecmint.com/wp-content/uploads/2016/06/List-Files-Owned-By-User-in-Directory.png)
->List Files Owned By User in Directory
-
-Take a look at another example where we [employ awk expressions][3], here, we want to print files owned by the root user by using an expression to filter strings as in the awk command below:
-
-```
-# dir -l | awk '$3=="root" {print $1,$3,$4, $9;} '
-```
-
-![](http://www.tecmint.com/wp-content/uploads/2016/06/List-Files-Owned-by-Root-User.png)
->List Files Owned by Root User
-
-The command above includes the `(==)` comparison operator to help us filter out files in the current directory which are owned by the root user. This is achieved using the expression `$3==”root”`.
-
-Let us look at another example of where we use a [awk comparison operator][4] to match a certain string.
-
-Here, we have used the [cat utility][5] to view the contents of a file named tecmint_deals.txt and we want to view the deals of type Tech only, so we shall run the following commands:
-
-```
-# cat tecmint_deals.txt
-# cat tecmint_deals.txt | awk '$4 ~ /tech/{print}'
-# cat tecmint_deals.txt | awk '$4 ~ /Tech/{print}'
-```
-
-![](http://www.tecmint.com/wp-content/uploads/2016/06/Use-Comparison-Operator-to-Match-String.png)
->Use Awk Comparison Operator to Match String
-
-In the example above, we have used the value `~ /pattern/` comparison operator, but there are two commands to try and bring out something very important.
-
-When you run the command with pattern tech nothing is printed out because there is no deal of that type, but with Tech, you get deals of type Tech.
-
-So always be careful when using this comparison operator, it is case sensitive as we have seen above.
-
-You can always use the output of another command instead as input for awk instead of reading input from a file, this is very simple as we have looked at in the examples above.
-
-Hope the examples were clear enough for you to understand, if you have any concerns, you can express them through the comment section below and remember to check the next part of the series where we shall look at awk features such as variables, numeric expressions and assignment operators.
-
---------------------------------------------------------------------------------
-
-via: http://www.tecmint.com/read-awk-input-from-stdin-in-linux/
-
-作者:[Aaron Kili][a]
-译者:[译者ID](https://github.com/译者ID)
-校对:[校对者ID](https://github.com/校对者ID)
-
-本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
-
-[a]: http://www.tecmint.com/author/aaronkili/
-[1]: http://www.tecmint.com/linux-dir-command-usage-with-examples/
-[2]: http://www.tecmint.com/15-basic-ls-command-examples-in-linux/
-[3]: http://www.tecmint.com/combine-multiple-expressions-in-awk
-[4]: http://www.tecmint.com/comparison-operators-in-awk
-[5]: http://www.tecmint.com/13-basic-cat-command-examples-in-linux/
-
-
-
diff --git a/translated/talk/20151023 Mark Shuttleworth--The Man Behind Ubuntu Operating System.md b/translated/talk/20151023 Mark Shuttleworth--The Man Behind Ubuntu Operating System.md
deleted file mode 100644
index 0d3547aeb9..0000000000
--- a/translated/talk/20151023 Mark Shuttleworth--The Man Behind Ubuntu Operating System.md
+++ /dev/null
@@ -1,126 +0,0 @@
-Mark Shuttleworth – Ubuntu 操作系统背后的人
-================================================================================
-![](http://1426826955.rsc.cdn77.org/wp-content/uploads/2015/10/Mark-Shuttleworth-652x445.jpg)
-
-**Mark Richard Shuttleworth** 是 Ubuntu 的创始人,他也有事被称作是 Debian 背后的那个人。他出生于1973年的 Welkom,南非。他不仅是个企业家,还是个太空游客——他是第一个前往太空旅行的独立非洲国家公民。
-
-Mark 还在1996年成立了 **Thawte**,一家互联网安全企业,那是他还只是 University of Cape Town 的一名金融/IT学生。
-
-在2000年,Mark 创立了 HBD,一家投资公司,同时他还创立了 Shuttleworth基金会,致力于给社会中有创新性的领袖提供资助——以奖金和投资等形式。
-
-
-> "移动设备对于个人电脑行业的未来而言至关重要。比如就在这个月,数据清晰地表明相对于平板电脑的发展,传统 PC 行业正在萎缩。所以如果我们想和个人电脑行业有关系,我们必须和移动设备行业有产生联系。移动互联网行业之所以有趣,还因为在这里没有盗版 Windows 操作系统。所以如果你为你的操作系统赢得了一台设备的市场份额,这台设备会持续使用你的操作系统。在传统 PC 行业,我们时不时得和 ‘免费 Windows’ 产生竞争,这一竞争困难的非常微妙。所以我们现在的目标是围绕 Ubuntu 和移动设备——手机和平板——为用户打造更深度的生态环境。"
->
-> — Mark Shuttleworth
-
-在2002年,在俄罗斯的 Star City 接收完为期一年的训练后,他作为 Soyuz 任务代号 TM-34 的一员飞往了国际空间站。再后来,在面向有志于航空航天或者其科学相关的南非学生群体中,内完成了推广科学,编程,数学的演讲后,Mark 创立了 **Canonical Ltd**。此后直至2013年,他一直在领导 Ubuntu 操作系统的开发。
-
-
-现今,Shuttleworth 有英国与南非双重国籍并和18只可爱的鸭子住在英国的 Isle of Man 小岛上一处花园,一同的还有他一样可爱的女友 Claire,2 条黑母狗以及时不时经过的羊群。
-
-
-> "电脑不再只是一台电子设备了。他现在是你思维的延续,以及通向他人的入口。"
->
-> — Mark Shuttleworth
-
-### Mark Shuttleworth 的早年生活###
-正如我们之前提到的,Mark 出生在 Welkom,南非的橙色自由州。他是一名外科医生和护士学校教师的孩子。Mark 在 Western Province Preparatory School 就读并在1986年成为了学生会主席,一个学期后就读于 Rondebosch 男子高中,再之后入学 Bishops/Diocesan 学院并在1991年再次成为那里的学生会主席。
-
-Mark 在 University of Cape Town 拿到了 Bachelor of Business Science degree in the Finance and Information Systems (译者:商业科学里的双学士学位,两个学科分别是金融和信息系统),他在学校就读是住在 Smuts Hall。他,作为学生,也在那里帮助安装了学校的第一条宿舍网络。
-
->“有无数的企业和国家佐证,引入开源政策能提高竞争力和效率。在不同层面上创造生产力对于公司和国家而言都是至关重要的。”
->
-> — Mark Shuttleworth
-
-### Mark Shuttleworth 的职业生涯 ###
-
-Mark 在1995年创立 Thawte,公司专注于数字证书和互联网安全,然后他在1999年把公司卖给了 VeriSign,赚取了大约 5.75 亿美元。
-
-2000年的时候,Mark 创立了 HBD 风险资本公司,这项事业成为了投资方和项目孵化器。2004年的时候,他创立了 Canonical Ltd. 以支持和鼓励自由软件开发项目的商业化,特别是 Ubuntu 操作系统的项目。直到2009年,Mark 才从 Canonical CEO 的位置上退下。
-
-> “在 [DDC](https://en.wikipedia.org/wiki/DCC_Alliance) (译者:一个 Debian Gnu/Linux 开发者联盟) 的早期,我更倾向于让开发者做些他们自己的(内核开发)工作看看能弄出些什么。现在我们基本上已经完成了这个开发阶段了。”
->
-> — Mark Shuttleworth
-
-### Linux、免费开源软件 与 Mark Shuttleworth ###
-
-在90年代末,Mark 作为 Debian 系统开发者的一员参与了项目。
-
-2001年,Mark 创立了 Shuttleworth 基金会,这是个扎根南非的,非赢利性,专注于赞助社会创新,免费/教育用途开源软件的基金会,赞助过的项目包括 Freedom Toaster。
-
-2004年的时候,Mark 通过出资开发 基于 Debian 的 Ubuntu 操作系统回归了免费软件界,这一切也经由他的公司,Canonical,完成。
-
-2005年,Mark 出资建立了 Ubuntu 基金会并投入了一千万美元作为启动资金。在 Ubuntu 项目内,Mark 经常被一个朗朗上口的名字称呼——“**SABDFL (Self-Appointed Benevolent Dictator for Life)**”。为了能够找到足够多的能手开发这个巨大的项目,Mark 花费了6个月的时间在 Debian 的邮件列表里找到能手,这一切都是在他乘坐在南极洲的一艘破冰船——Kapitan Khlebnikov——上完成的。2005年,Mark 买下了 Impi Linux 65% 的股份。
-
-
-> “我呼吁电信公司的掌权者们尽快开发出跨洲际的高效信息传输服务。”
->
-> — Mark Shuttleworth
-
-2006年,KDE 宣布 Shuttleworth 成为第一位 **patron** 级别赞助者——彼时 KDE 最高级别的赞助。这一赞助协议终止与2012年,取而代之的是 Kubuntu——一个运用 KDE 作为默认桌面环境的 Ubuntu 变种——的资金。
-
-![](http://1426826955.rsc.cdn77.org/wp-content/uploads/2015/10/shuttleworth-kde.jpg)
-
-2009年,Shuttleworth 宣布他会从 CEO 退位以更好的关注与合作伙伴,产品设计和顾客体验。Jane Silber ——2004年起公司的COO——晋升CEO。
-
-2010年,Mark 由于 Ubuntu 项目从 Open University 收到了荣誉学位。
-
-2012年,Mark 和 Kenneth Rogoff 一同在牛津大学与 Peter Thiel 和 Garry Kasparov 就 **创新悖论**(The Innovation Enigma)展开辩论。
-
-2013年,Mark 和 Ubuntu 一同被授予 **澳大利亚反个人隐私老大哥监控奖**(Austrian anti-privacy Big Brother Award),理由为把 Ubuntu 会把 Unity 桌面的搜索框的搜索结果发往 Canonical 服务器(译者:因此侵犯了个人隐私)。而一年前的2012年,Mark 曾经申明过这一过程极具匿名性。
-
-
-> “所有主流 PC 厂家现在都提供 Ubuntu 预安装选项。所以我们和业界的合作已经相当紧密了。但那些 PC 厂家对于给买家推广新东西这件事都很紧张。如果我们可以让买家习惯 Ubuntu 的桌面/平板/手机操作系统的体验,那他们也应该更愿意买预装 Ubuntu 的设备。因为没有哪个操作系统是通过抄袭模仿获得成功的。Android 很棒,如果我们想成功的话我们必须给市场带去更新更好的东西。整个环境都有停滞发展的危险,如果我们中没有人追寻未来的话。但如果你尝试去追寻未来了,那你必须接受不是所有人对未来的预见都和你一样这一事实。”
->
-> — Mark Shuttleworth
-
-### Mark Shuttleworth 的太空之旅 ###
-
-Mark 在2002年由于作为世界第二名自费太空游客而闻名世界,同时他也是南非第一个旅行太空的人。这趟旅行 Mark 作为俄罗斯 Soyuz TM-34 的一名航空参与者加入,并支付了约两千万美元。2天后,Soyuz 太空梭抵达了国际空间站,在那里 Mark 呆了8天并参与了 AIDS 和 GENOME 研究的相关实验。2002年的晚些时候,Mark 乘坐 Soyuz TM-33 返回了地球。为了参与这趟旅行,Mark 花了一年时间准备与训练,包括7个月居住在俄罗斯的 Start City。
-
-
-![](http://1426826955.rsc.cdn77.org/wp-content/uploads/2015/10/Mark-Shuttleworth1.jpg)
-
-在太空中,Mark 与 Nelson Mandela 和另一个南非女孩 Michelle Foster (她问 Mark 要不要娶她)通过无线电进行了交谈。Mark 回避了结婚问题,在换话题之前他说他感到很荣幸。身患绝症的 Forster 和 Nelson Mandela 通过 Dream 基金会的赞助获得了与 Mark 交谈的机会。
-
-归来后,Mark 在世界各地做了旅行,并和各地的学生就太空之旅发表了感言。
-
-
->“粗略的统计数据表明 Ubuntu 的实际用户依然在增长。而我们的合作方——Dell,HP,Lenovo 和其他硬件生产商,以及游戏厂商 EA,Valve 都在加入我们——这让我觉得我们在引导一项很有意义的事业。”
->
-> — Mark Shuttleworth
-
-### Mark Shuttleworth 的交通工具 ###
-
-Mark 有他自己的私人客机,Bombardier Global Express,经常被称为 Canonical 一号,但事实上此飞机是通过 HBD 风险投资公司注册拥有的。飞机侧面的喷绘龙图案是 HBD 风投公司的吉祥物,Norman。
-
-### 与南非储蓄银行的法律冲突 ###
-
-在从南非转移25亿南非兰特去往 Isle of Man 的过程中,南非储蓄银行征收了 2.5 亿南非兰特的税金。Mark 上诉了,经过冗长的法庭唇枪舌战,南非储蓄银行被勒令返还 2.5 亿征税,以及其利息。Mark 宣布他会把这 2.5 亿存入信托基金,以用于帮助上诉宪法法院的案子。
-
-
-> “离境征税倒也不和宪法冲突。但离境征税的主要目的不是为了提高税收,而是通过监管资金流出来保护本国经济。”
->
-> — 法官 Dikgang Moseneke
-
-2015年,南非宪法法院修正了低级法院的判决结果,并宣布了上述对于离岸征税的理解。
-
-### Mark Shuttleworth 喜欢的东西 ###
-
-Cesária Évora, mp3s,Spring, Chelsea, finally seeing something obvious for first time, coming home, Sinatra, daydreaming, sundowners, flirting, d’Urberville, string theory, Linux, particle physics, Python, reincarnation, mig-29s, snow, travel, Mozilla, lime marmalade, body shots, the African bush, leopards, Rajasthan, Russian saunas, snowboarding, weightlessness, Iain m banks, broadband, Alastair Reynolds, fancy dress, skinny-dipping, flashes of insight, post-adrenaline euphoria, the inexplicable, convertibles, Clifton, country roads, international space station, machine learning, artificial intelligence, Wikipedia, Slashdot, kitesurfing, and Manx lanes.
-
-### Shuttleworth 不喜欢的东西 ###
-
-Admin, salary negotiations, legalese, and public speaking.
-
---------------------------------------------------------------------------------
-
-via: http://www.unixmen.com/mark-shuttleworth-man-behind-ubuntu-operating-system/
-
-作者:[M.el Khamlichi][a]
-译者:[Moelf](https://github.com/Moelf)
-校对:[校对者ID](https://github.com/校对者ID)
-
-本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
-
-[a]:http://www.unixmen.com/author/pirat9/
diff --git a/translated/talk/20160509 Android vs. iPhone Pros and Cons.md b/translated/talk/20160509 Android vs. iPhone Pros and Cons.md
new file mode 100644
index 0000000000..efbef243b9
--- /dev/null
+++ b/translated/talk/20160509 Android vs. iPhone Pros and Cons.md
@@ -0,0 +1,87 @@
+Android 和 iPhone 的优缺点
+===================================
+
+
+>当我们比较 Android 与 iPhone 的时候,很显然 iPhone 和 Android 在一些关键方面都具有一定的优势,但是,究竟哪个比较好呢?
+
+ Android 与 iPhone 两者比较是个私人的问题。
+
+就好比我来说,我两个都用。我深知这两个平台的优劣势。所以,我决定分享关于这两个移动平台的观点。另外,然后谈谈我对新的 Ubuntu 移动平台的印象和它的优势。
+
+### iPhone 的优点
+
+虽然这些天我是个十足的 Android 用户,但我必须承认到 iPhone 在某些方面做的是不错。首先,苹果公司在更新他们的设备有更好的战绩。尤其是在旧设备也能运行 iOS 。反观 Android ,如果它不是谷歌福利的关系,它最好是一个更高端的运营商支持的手机。否则,你将发现找那些更新少的可怜或者不存在。
+
+其中 iPhone 做得很好的另一个领域是应用程序的可用性。扩展上: iPhone 应用程序几乎总是有一个简洁的外观。这并不是说 Android 应用程序是难看的,相反,他们可能没有和预期的流动性和一致性当建立在 iOS 上。有两个例子 [Dark Sky][1] (天气)和 [Facebook Paper][2] 很好表现了 iOS 的布局。
+
+再有就是备份过程。 Android 可以备份,默认情况下是备份到谷歌。但是对应用数据起不了太多作用。对比 iPhone ,iCloud 基本上可以让你的 iOS 设备进行完整备份。
+
+### iPhone 令我失望的地方
+
+我使用 iPhone 的最大的不容置疑的问题是它的硬件限制大于软件,换句话来说,就是存储问题。
+
+你看,对于大多数 Android 手机,我可以买一个容量较小的手机,然后在以后添加 SD 卡。这做了两件事:第一,我可以使用 SD 卡来存储大量的媒体文件。其次,我甚至可以用 SD 卡来存储我的应用程序的一些文件。苹果完全不能这么做。
+
+另一个 iPhone 让我失望的地方是它提供的选择很少。备份您的设备?希望大家喜欢 iTunes 或 iCloud 。但对一些像我一样用 Linux 的人,那就意味着,我唯一的选择便是使用 iCloud 。
+
+为了最终公平的,如果你愿意越狱,你的 iPhone 还有一些其他解决方案的。但这并不是文章所讲的。 Android 的 root 也一样。本文章针对的是两个用户的原生设置。
+
+最后,让我们不要忘记这小小的玩意儿—— [iTunes 决定删除用户的音乐][3] 因为它被视为苹果音乐内容的重复...或者类似的规定。 iPhone 并不明确?我不同意,就算音乐在有些时候很好地在结束在 iPhone 上。我也十分肯定地说在任何地方我会不会忍受这种废话!
+
+![](http://www.datamation.com/imagesvr_ce/5552/mobile-abstract-icon-200x150.jpg)
+> Android 和 iPhone 的对决取决于什么功能对你来说最重要。
+
+### Android 的优点
+
+ Android 给我最大的事情就是 iPhone 提供不了的选择。包括应用程序,设备和我的手机是如何工作的整体布局。
+
+我爱桌面小工具!对于 iPhone 用户,它们也许看上去很蠢。但我可以告诉你,他们可以让我不用打开应用程序就可以看到所需的数据,而无需额外的麻烦。另一个类似的功能,我喜欢安装自定义应用,而不是我的手机的默认!
+
+最后,我可以利用像 [Airdroid][4] 和 [Tasker][5] 工具添加全电脑式的功能到我的智能手机。AirDroid 可以让我对待我的 Android 手机就像一个文件管理和通信的计算机–这使得使用我的鼠标和键盘变得轻而易举的。Tasker 很厉害,我可以用它让我手机可联系或不可联系,当我设置参数时,我可以把我的手机处在会议模式,甚至把它自己变成省电模式。我甚至可以设置它来启动应用程序时当我到达特定的目的地时。
+
+### Android 让我失望的地方
+
+备份选项仅限于特定的用户数据,而不是手机的完整克隆。没有 root ,你将要么乘风而去或者你必须看看 Android SDK 开发解决方案。期望普通用户 root 他们的手机或运行 SDK来进行所有的Android的备份(我的意思是一切)将是一个笑话。
+
+是的,谷歌的备份服务将备份谷歌应用程序的数据,以及其他相关的自定义设置。但它是远不及我们所看到的苹果一样完整。为了完成类似于在苹果的功能,我发现你就必须要 root 你的安卓手机或利用一些随机程序将其连接到一个在 PC 机上来。
+
+为了公平的,但是,我相信 Nexus 所有者受益于一个 [完整备份服务][6] ,这是设备特定。对不起,但谷歌的默认备份是不削减它。同样的应用来备份您的电脑——他们不总是恢复预期的东西。
+
+等待,它会变得更好。现在经过了很多失败的失望和挫折,我发现有一个应用程序,看起来它“可能”提供了一个微小的希望,它被称为 Helium 。它不像我发现的其他应用程序那样拥有误导性的和令人沮丧的局限性,[Helium][7] 最初看起来像是谷歌应该一直提供的备份应用程序——强调“看起来像”。可悲的是,这是一个巨大的失望。我不仅需要将它连接到我的计算机上进行第一次运行,而且它甚至不使用他们提供的 Linux 脚本。删除他们的脚本后,我弄了一个很好的老式 adb (Android Debug Bridge) 备份到我的Linux PC 。有趣的事实:你需要在开发工具里打开一箩筐东西,再加上如果你运行 Twilight app,那是需要被关闭的。当 adb (Android Debug Bridge) 的备份选项在手机上不起作用时,它花了我一点时间把这个弄在一起。
+
+最终,Android 为非 root 用户也提供了可以轻松备份一些如联系人,短信等简单东西的选择。但是,要深度手机备份的话,以我经验还是通过有线连接和 adb (Android Debug Bridge) 。
+
+### Ubuntu 会救我们吗?
+
+在手机领域,通过两大玩家之间的好坏考核,我们将有很多的希望从 Ubuntu 看到好的一方面。但是,迄今为止,它已经相当低迷。
+
+我喜欢开发人员正在基于 OS 所做的,我当然喜欢除了 iPhone 和 Android 手机的第三个选项的想法。但是不幸的是,它在手机和平板上并不受欢迎且受到很多坏新闻,就是由于不符合标准的硬件和一个 YouTube 上的糟糕的示范。
+
+公平来说,我在以前用 iPhone 和 Android 也不是很规范。所以这不是对 Ubuntu 的挖苦。但是直到它开始表现出准备提供生态系统功能来与 iPhone 和 Android 竞争,那就另说了,这还不是我现在特别感兴趣的东西。在以后的日子里,也许,我会觉得 Ubuntu 手机可以满足我的需要了。
+
+###Android pk iPhone:为什么Android 长期胜利
+
+忽视 Android 那些痛苦的缺点,它起码对待我像一个成年人。它并没有把我困在只有两种方法来备份我的数据。是的,一些 Android 的限制是由于它的关注点在让我选择如何处理我的数据。但是,我也可以选择我自己的设备,一时兴起扩充内存。 Android 让我做了很多很酷的东西,那些手机根本就没有能力做的事情。
+
+在其核心, Android 给非 root 用户提供更大的访问手机的功能。无论是好是坏,这是人们倾向的一种自由。现在你们其中有很多用 iPhone 谩骂的人多亏了像 [libimobiledevice][8] 类似影响的项目。但要看看苹果阻止 Linux 用户所做的事情……然后问自己:作为一个 Linux 用户这是真的值得吗?评论,分享你对 iPhone 、 Android 或 Ubuntu 的看法。
+
+------------------------------------------------------------------------------
+
+via: http://www.datamation.com/mobile-wireless/android-vs.-iphone-pros-and-cons.html
+
+作者:[Matt Hartley][a]
+译者:[jovov](https://github.com/jovov)
+校对:[校对者ID](https://github.com/校对者ID)
+
+本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创翻译,[Linux中国](https://linux.cn/) 荣誉推出
+
+[a]: http://www.datamation.com/author/Matt-Hartley-3080.html
+[1]: http://darkskyapp.com/
+[2]: https://www.facebook.com/paper/
+[3]: https://blog.vellumatlanta.com/2016/05/04/apple-stole-my-music-no-seriously/
+[4]: https://www.airdroid.com/
+[5]: http://tasker.dinglisch.net/
+[6]: https://support.google.com/nexus/answer/2819582?hl=en
+[7]: https://play.google.com/store/apps/details?id=com.koushikdutta.backup&hl=en
+[8]: http://www.libimobiledevice.org/
+
diff --git a/translated/talk/20160523 Driving cars into the future with Linux.md b/translated/talk/20160523 Driving cars into the future with Linux.md
deleted file mode 100644
index 9b9d69d68c..0000000000
--- a/translated/talk/20160523 Driving cars into the future with Linux.md
+++ /dev/null
@@ -1,108 +0,0 @@
-
-驾车通往未来Linux
-===========================================
-
-![](https://opensource.com/sites/default/files/styles/image-full-size/public/images/life/open-snow-car-osdc-lead.png?itok=IgYZ6mNY)
-
-
-当我开车的时候不认为和 Linux 有多大联系,但是我肯定我是喜欢一个配备有系统的车子,让我按几个按钮语音就可以传给我的妻子母亲以及孩子。同样,这样的系统可以让我选择是否从云端流媒体收听音乐,卫星广播,以及传统的 AM/FM 收音机。我也会得到天气更新以及可以给我的车载信息娱乐 GPS 找到最快的下一个目的地[In-vehicle infotainment][1],以及 IVI 作为行业知名产业,已经普及到最新的汽车生产商。
-
-前段时间,我不得坐飞机飞跃数百英里,租一辆车。令人愉快的是,我发现我的租凭车配置了 IVI 技术。任何时候,我只要通过蓝牙连接,上传联系人到系统中,打电话回家给我的家人,让他们知道我已经安全到家了。然后“主人“会知道我再途中还是已经到他们家了。
-
-在最近的 [news roundup][2],Scott Nesbitt 引用一篇文章,说福特汽车公司是由它的开源 [Smart Device Link][3](SDL)中间设备框架,对手汽车制造商,支持那个移动手机获得大量的支持。 SDL 是 [GENIVI Alliance][4] 的项目,一个非营利性的致力于建设中间件支持开源的车载信息娱乐系统。根据文献 [[Steven Crumb][5],GENIVI 执行董事,他们 [membership][6] 很广,包括 Daimler 集团,现代,沃尔沃,日产,本田等等 170 个。
-
-为了在同行业中保持竞争力,汽车企业需要一个中间设备系统,可以支持当今消费者提供的各种人机界面技术。无论您拥有 Android,iOS 或其他设备,汽车 OEM 厂商希望自己的系统单位能够支持这些。此外,这些的 IVI 系统必须有足够适应能力以支持移动技术的不断下降,半衰期。 OEM 厂商要提供价值服务,并在他们的 IVI 堆栈支持各种为他们的客户添加选择。进入 Linux 和开源软件。
-
-除了 GENIVI 的努力下,[Linux Foundation][7] 赞助 [Automotive Grade Linux][8](AGL)工作组,一个软件基金会,致力于寻找针对汽车应用的开源解决方案。虽然 AGL 初期将侧重于 IVI 系统,他们展望不同的分歧,包括 [telematics][9],小心显示器和其他控制系统。 AGL 有超过 50 名成员在这个时候,包括捷豹,丰田,日产,并在 [recent press release][10] 宣布福特、马自达、三菱、和斯巴鲁加入。
-
-
-为了了解更多信息,我们在这一新鲜兴领域采访了两位领导人。明确地来说,我们想知道是如何被使用的 Linux 和开源软件,如果它们实际上是改变汽车行业的面貌。首先,我们谈谈 [Alison Chaiken][11],在大集团技术的软件工程师和汽车 Linux 专家,网络安全和透明度。她曾任职于 [Alison Chaiken][11] 公司,诺基亚和斯坦福直线性加速器。然后我们用 [Steven Crumb][12],GENIVI 执行董事,谁得到了在开源环境高性能计算(超级计算机和早期的云计算)开始聊天。他说,虽然他再不是一个程序员了,但是他喜欢帮助企业解决开源软件的实际业务问题。
-
-### 采访 Alison Chaiken (by [Deb Nicholson][13])
-
-#### 你是如何开始对汽车软件空间感兴趣的?
-
-我是在诺基亚手机产品时, 2009 年该项目被取消。我想,下一步是什么?一位同事正在对 [MeeGo-IVI][15],早期的汽车 Linux 发行版。 “Linux 在汽车是大了,” 我想,所以我在朝着这个方向努力。
-
-#### 你能告诉我们你这些日子工作在哪些方面?
-
-我目前正在启动为使用 Linux 系统增加大货车钻机的安全性和燃油经济性的先进巡航控制。我喜欢在这方面的工作,因为没有人会反对卡车得以提升。
-
-#### 目前关于汽车已在近年来砍死几个人故事。开源代码方案可以帮助解决这个问题吗?
-
-I presented a talk on precisely this topic, on how Linux can (and cannot) contribute to security solutions in automotive at Southern California Linux Expo 2016 ([Slides][16]). Notably, GENIVI and Automotive Grade Linux have published their code and both projects take patches via Git. Please send your fixes upstream! Many eyes make all bugs shallow.
-我提出的谈话正是这一主题,就如何 Linux 可以(或不可以)在南加州 2016 年世博会作出贡献的安全解决方案的 Linux汽车([Slides][16])。值得注意的是,GENIVI 和汽车级 Linux 已经公布了他们的代码,这两个项目的 Git 通过采取补丁。请上游发送您的修复!许多眼睛都盯着肤浅的bugs。
-
-#### 执法机构和保险公司可以找到很多有关数据用途的驱动程序。它将如何容易成为他们获取这些信息?
-
-好问题。该专用短程通信标准(IEEE-1609),以保持匿名的 Wi-Fi 安全消息驱动程序。不过,如果你从你的车张贴到 Twitter,有人能够跟踪你。
-
-#### 有什么可以开发人员和公民个人一起完成,以确保公民自由受到保护作为汽车技术发展的?
-
-电子前沿基金会(EFF)一样对汽车保持的问题上,通过什么样的数据可以存储在汽车 “黑盒子”,并在 DMCA 的规定 1201 如何应用于汽车官方渠道评论已经出色的工作了。
-
-#### 在未来几年令人兴奋的事情上,那些是你看到的驱动因素?
-
-自适应巡航控制和防撞系统有足够的预付款来挽救生命。当他们通过运输车队的推出,我真的相信死亡人数会下降。如果这还不是令人兴奋的,我不知道是什么。此外,像自动化停车辅助功能,将会使汽车更容易驾驶,减少汽车相撞事故。
-
-#### 有什么是需要人参与以及如何建造?
-
-汽车 Linux 级开发是开放源代码的,运行在廉价硬件(如树莓派 Pi 2 和中等价位的 Renesas Porter board),任何人都可以购买。 GENIVI 汽车 Linux 的中间设备联盟有很多软件通过 Git 的公开。此外,还有很酷的 [OSVehicle open hardware][17] 汽车平台。
-
-#### 这里是 Linux 软件和开放硬件,许多方面具有中等人数预算的参与。如果您有任何疑问,加入我们在 Freenode 上 IRC#automotive。
-
-### 采访 Steven Crumb (by Don Watkins)
-
-#### 关于GENIVI's 对 IVI 为什么那么大 ?
-
-GENIVI 率先通过使用自由和开源软件,包括 Linux,像车载信息娱乐(IVI)系统的非安全关键汽车软件填补了汽车行业的巨大差距。作为消费者来到期望在他们的车辆相同的功能在智能手机上的软件,以支持 IVI 功能所需的量成倍增长。软件增加量也增加了建设 IVI 系统的成本,从而延缓了上市时间。
-
-GENIVI 的使用开源软件和社区发展模式节省了汽车制造商和他们的软件提供商显著大量的资金,而显著减少了产品上市时间。我很兴奋,因为 GENIVI 我们很幸运慢慢从高度结构化和专有的方法来社区为基础的方法不断发展的组织领导排序在汽车行业的一场革命。我们还没有完成,但它一直是一个荣幸参加正在产生实实在在的好处的转换。
-
-#### 你的庞大会员怎么才可以驱动 GENIVI 方向?
-
-GENIVI 有很多会员和非会员促进我们的工作。与许多开源项目,任何公司都可以通过简单地贡献代码,修补程序和时间来检验影响的技术输出。随着中说,宝马,奔驰,现代汽车,捷豹路虎,标致雪铁龙,雷诺 / 日产和沃尔沃是所有积极采用者和贡献者 GENIVI 和其他许多 OEM 厂商已经在他们的汽车 IVI 解决方案,广泛使用 GENIVI 的软件。
-
-#### 贡献的代码使用了什么许可证?
-
-GENIVI 采用数量的许可证从(L)GPLv2 许可,以 MPLv2 到 Apache2.0。我们的一些工具使用 Eclipse 许可证。我们有一个[public licensing policy][18],详细说明我们的许可偏好。
-
-#### 一个人或一群人如何参与其中?重要的是如何对项目的持续成功的社区贡献?
-
-GENIVI 完全做它开放发展的在([projects.genivi.org][19]),因此,有兴趣的人在汽车使用开源软件,欢迎参加。这就是说,该联盟能够通过公司 [joining GENIVI][20] 作为成员不断发展的开放基金。 GENIVI 会员享受各种各样的福利,而不是其中最重要的是在已经发展了近六年来 140 家公司全球社区参与。
-
-社区是 GENIVI 非常重要的,我们不可能生产和维护我们发展了很多年没有贡献者一个活跃的社区有价值的软件。我们努力做出贡献 GENIVI 简单,只要加入一个 [邮件列表] [21] 并连接到人们在不同的软件项目。我们使用许多开源项目采用的标准做法,并提供高质量的工具和基础设施,以帮助开发人员有宾至如归的感觉,并富有成效。
-
-无论在汽车软件某人的熟悉,欢迎他们加入我们的社区。人们已经改装车多年,所以对于许多人来说,是一种天然的抽奖,任何汽车。软件是汽车的新域,GENIVI 希望成为敞开的门有兴趣的人与汽车,开源软件的工作。
-
--------------------------------
-via: https://opensource.com/business/16/5/interview-alison-chaiken-steven-crumb
-
-作者:[Don Watkins][a]
-译者:[erlinux](https://github.com/erlinux)
-校对:[校对者ID](https://github.com/校对者ID)
-
-本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创翻译,[Linux中国](https://linux.cn/) 荣誉推出
-
-[a]: https://opensource.com/users/don-watkins
-[1]: https://en.wikipedia.org/wiki/In_car_entertainment
-[2]: https://opensource.com/life/16/1/weekly-news-jan-9
-[3]: http://projects.genivi.org/smartdevicelink/home
-[4]: http://www.genivi.org/
-[5]: https://www.linkedin.com/in/stevecrumb
-[6]: http://www.genivi.org/genivi-members
-[7]: http://www.linuxfoundation.org/
-[8]: https://www.automotivelinux.org/
-[9]: https://en.wikipedia.org/wiki/Telematics
-[10]: https://www.automotivelinux.org/news/announcement/2016/01/ford-mazda-mitsubishi-motors-and-subaru-join-linux-foundation-and
-[11]: https://www.linkedin.com/in/alison-chaiken-3ba456b3
-[12]: https://www.linkedin.com/in/stevecrumb
-[13]: https://opensource.com/users/eximious
-[14]: https://en.wikipedia.org/wiki/MeeGo
-[15]: http://webinos.org/deliverable-d026-target-platform-requirements-and-ipr/automotive/
-[16]: http://she-devel.com/Chaiken_automotive_cybersecurity.pdf
-[17]: https://www.osvehicle.com/
-[18]: http://projects.genivi.org/how
-[19]: http://projects.genivi.org/
-[20]: http://genivi.org/join
-[21]: http://lists.genivi.org/mailman/listinfo/genivi-projects
diff --git a/translated/talk/20160525 What containers and unikernels can learn from Arduino and Raspberry Pi.md b/translated/talk/20160525 What containers and unikernels can learn from Arduino and Raspberry Pi.md
new file mode 100644
index 0000000000..958cf7ee67
--- /dev/null
+++ b/translated/talk/20160525 What containers and unikernels can learn from Arduino and Raspberry Pi.md
@@ -0,0 +1,51 @@
+容器和 Unikernel 能从 Raspberry Pi(树莓派)和 Arduino 学到什么
+==========================================================================
+
+![](https://opensource.com/sites/default/files/styles/image-full-size/public/images/business/bus-containers.png?itok=vM7_7vs0)
+
+
+某一天,我和我的一个机械工程师朋友聊天的时候。 他最近在做一个给半挂卡车的电子辅助刹车系统,他提到他们公司的办公室里都是 [Arduinos][1]。这主要是方便员工可以快速的对新的想法进行实验。他也提到了,Arduinos 其实比自己画电路板更加昂贵。对此,我感到非常震惊。因为我从软件行业得到的印象是 Arduinos 比定制电路板更加便宜。
+
+我常常把 [Arduinos][2] 和 [Raspberry Pi][3] 看做是可以制作非常有趣设备的小型,Cool,特别的组件。我主要是从事软件行业,并且常常想让 Linux 在 x86 和 x86-64 设备上都可以执行一致。真相就是,Arduinos 并不特殊。实际上,他们非常通用。他们相当的小,便宜,但是非常得灵活。这就是为什么他们向野火一样流行起来。他们有所有种类的输入输出设备,和扩展卡。他们能让制作者快速的构建非常 Cool 的设备。他们甚至可以让公司可以快速的开发产品。
+
+一整套 Arduino 的价格比批量生产的电路板高了很多,但是,看不见的时间成本却低了很多。当电路板大规模生产的时候,价格可以控制的很低,但是,之前的研发费用却高了很多。所以,长话短说,答案就是,使用 Arduino 划得来。
+
+### Unikernel, Rump 内核,和容器主机
+
+Unikernel, Rump 内核和迷你 Linux 发行版,这些操作系统是为了特有用途而构建的。这些特有的操作系统,某种程度上就像定制电路板。他们需要前期的研发,还需要为了工具化而设计,但是,当大规模部署的时候,他可以提供强大的性能。
+
+迷你操作系统,例如:红帽企业版或者 CoreOS 是为了运行容器而构建的。他们很小,快速,并且很容易在启动时配置,并且运行容器非常良好。缺点就是他需要额外的工程量来添加第三方插件,比如监控客户端或者虚拟化的工具。一些工具也需要为了超级权限的容器而重新设计。 如果你正在构建一个巨大的容器环境,这些额外的工作量是划算的。但是,如果只是尝试,那就没必要了。
+
+容器提供了运行标准化的工作流程 (比如使用 [glibc][4] 编译) 的能力。一个好处就是你可以在你的电脑上构建和测试这个工作单元 (Docker 镜像) 并且在完全不同的硬件上或者云端非常顺利的部署。而且保持着相同的特性。在生产环境中,容器的宿主机可以依旧被运维配置管理,但是应用被开发团队控制。这就是对两个团队来说最好的合作方式。
+
+Unikernels 和 Rump 内核依旧是为了特定目标构建的,但是却更进一步。整个的操作系统在构建的时候就被开发或者架构师配置了。这带来了好处,同时还有挑战。
+
+一个好处就是,开发人员可以控制这个工作流程的运转。理论上说,一个开发者可以为了不同的特性,尝试 [不同的 TCP 协议栈][5],并且选择最好的一个。在操作系统启动的时候,开发人也可以配置 IP 地址,而不是通过 DHCP。 开发人员也可以裁剪任何对于应用而言不需要的部分。这也是性能提升的保障,通过减少[不必要的上下文切换][6]。
+
+同时,Unikernel 也带来了挑战。目前,有很大的工具缺口。 现在,和画板子的世界类似,开发人员需要花费很多时间和精力在检查是否有完整的库文件存在,不然的话,他们必须改变他们应用的执行方式。在如何让嵌入式操作系统在运行时配置的时候,也存在挑战。最后,每次操作系统的大改动,都需要[反馈到开发人员][7]来进行修改。这并没有一个在开发和运维之间明确的界限,所以我能想象,为了接受了这个开发流程,一些组织或者公司必须要改变。
+
+### 结论
+
+这也有一些有趣的传闻在专门的容器主机,Rump 内核和 Unikernel,因为,他们会带来一个特定工作流程的潜在变革(嵌入式,云,等等)。在这个令人激动又快速发展的领域请保持你的关注,但是也不要放松警惕。
+
+目前,Unikernel 看起来和定制电路板很像。他们都需要前期的研发投资,并且都是独特的,可以为确定的工作流程带来好处。同时,容器甚至在常规的工作流中都非常有趣,而且他不需要那么多的投入。一个简单的例子,运维团队能方便的在容器上部署一个应用,但是在 Unikernel 上部署一个应用则需要重新设计和编码,而且业界并不能完全保证,这个工作流程可以被部署在 Unikernel 上。
+
+容器,Rump 内核 和 Unikernel 有一个光明的未来!
+
+--------------------------------------
+via: https://opensource.com/business/16/5/containers-unikernels-learn-arduino-raspberry-pi
+
+作者:[Scott McCarty][a]
+译者:[MikeCoder](https://github.com/MikeCoder)
+校对:[校对者ID](https://github.com/校对者ID)
+
+本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创翻译,[Linux中国](https://linux.cn/) 荣誉推出
+
+[a]: https://opensource.com/users/fatherlinux
+[1]: https://opensource.com/resources/what-arduino
+[2]: https://opensource.com/life/16/4/arduino-day-3-projects
+[3]: https://opensource.com/resources/what-raspberry-pi
+[4]: https://en.wikipedia.org/wiki/GNU_C_Library
+[5]: http://www.eetasia.com/ARTICLES/2001JUN/2001JUN18_NTEK_CT_AN5.PDF
+[6]: https://en.wikipedia.org/wiki/Context_switch
+[7]: http://developers.redhat.com/blog/2016/05/18/3-reasons-i-should-build-my-containerized-applications-on-rhel-and-openshift/
diff --git a/translated/talk/20160531 Why Ubuntu-based Distros Are Leaders.md b/translated/talk/20160531 Why Ubuntu-based Distros Are Leaders.md
deleted file mode 100644
index 9d9ce0f418..0000000000
--- a/translated/talk/20160531 Why Ubuntu-based Distros Are Leaders.md
+++ /dev/null
@@ -1,85 +0,0 @@
-为什么 Ubuntu 家族会占据 Linux 发行版的主导地位?
-=========================================
-
-在过去的数年中,我已经尝试了大量的优秀 Linux 发行版。我印象最深刻的是那些被强大的社区维护的发行版。但是这样的发行版却比他们s所属的社区更受人欢迎。流行的 Linux 发行版吸引着更多的人,通常由于这样的特点使得使用该发行版更加容易。这很明显毫无关系,但一般认为这种说法是正确的。
-
-
-我想到的一个发行版 [Ubuntu][1]。它属于健壮的 [Debian][2]分支,Ubuntu 不可思议的成为了受欢迎的 Linux 发行版,而且它也衍生出了其他的版本,比如 Linux Mint。在本文中,我会探讨我坚信 Ubuntu 会赢得 Linux 发行版战争的原因,以及它在整个 Linux 桌面领域有着怎样的影响力。
-
-
-### Ubuntu容易使用
-
-
-多年前我第一次尝试使用Ubuntu,在这之前我更喜欢使用 KED 桌面。在那个时期,我接触的大多是这种 KDE 桌面环境。主要原因还是 KDE 是大多数新手友好的 Linux 发行版中最受欢迎的。新手友好的发行版有 Knoppix,Simply Mepis, Xandros, Linspire等,另外一些发行版和这些发行版都指出他们的用户趋向于使用 KDE。
-
-
-
-现在KDE能满足我的需求,也没有什么理由去折腾其他的桌面环境了。有一天我的 Debian 安装失败了(由于我个人的操作不当),我决定尝试开发代号为「整洁的公鸭(Ubuntu Dapper Drake)」的 Ubuntu 版本【译者注:ubuntu 6.06 - Dapper Drake(整洁的公鸭),发布日期:2006年6月1日】。那个时候,我对于它的印象比一个屏幕截图还要少,但是我认为它很有趣并且毫无顾忌的使用它。
-
-
-
-Ubuntu Dapper Drake 给我的最大的印象是它的操作很简单。记住,我是来自于 KDE 世界的用户,在 KDE 上要想改变菜单的设置就有15钟方法。Ubuntu 图形界面的安装启动极具极简主义。
-
-时间来到2016年,最新的版本号是16.04:我们有多种可用的 Ubuntu 衍生版本,许多的都是基于 Ubuntu 的。所有的 Ubuntu 风格和公用发行版的核心都被设计的容易使用。并且发行版想要增大用户基数的时候,这就是最重要的原因。
-
-
-### Ubuntu LTS
-
-过去,我几乎一直坚持使用 LTS(Long Term Support)发行版作为我的主要桌面系统。10月份的发行版很适合我测试硬盘驱动器,甚至把它用在一个老旧的手提电脑上。我这样做的原因很简单——我没有兴趣在一个作为实验品的电脑上折腾短期发行版。我是个很忙的家伙,我觉得这样会浪费我的时间。
-
-
-对于我来说,我认为 Ubuntu 提供 LTS 发行版是 Ubuntu 能够变得流行的原因。这样说吧———提供一个大众的桌面 Linux 发行版,这个发行版能够得到长期的充分支持就是它的优势。事实上,Ubuntu 的优势不只这一点,其他的分支在这一点上也做的很好。长期支持版带有一个对新手的友好环境的策略,我认为这就为 Ubuntu 的普及带来了莫大的好处。
-
-
-### Ubuntu Snap 包
-
-
-以前,用户在他们的系统上使用很多 PPA(personal package archive个人软件包档案),他们总会抱怨它获得新的软件名称的能力。不好的是,这种技术也有缺点。它工作的时候带有任意的软件名称,而 PPA 却没有发现,这种情况很常见。
-
-
-现在有了[Snap 包][3] 。当然这不是一个全新的概念,过去已经进行了类似的尝试。用户不必要在最新的 Ubuntu 发行版上运行最新的软件,我认为这才是 Snap 将要长期提供给 Ubuntu 用户的东西。然而我仍然认为我们将会看到 Snap 淘汰的的那一天,我很期待看到一个在稳定的发行版上运行的优秀软件。
-
-
-
-如果你要运行很多软件,那么 Snap 包实际使用的硬盘空间很明显存在问题。不仅如此,大多数 Ubuntu 软件也是通过由官方开发的 deb 包进行管理的。当后者需要花费一些时间的时候,这个问题可以通过 Snap 使用更大的硬盘驱动器空间得到解决。
-
-
-
-### Ubuntu 社区
-
-首先,我承认大多数主要的 Linux 发行版都有强大的社区。然而,我坚信 Ubuntu 社区的成员是最多样化的,他们来自各行各业。例如,我们有一个论坛来分类不同的苹果硬件对于游戏的支持程度。这些大量的专业讨论特别广泛。
-
-
-除过论坛,Ubuntu 也提供了一个很正式的社区组织。这个组织包括一个委员会,技术板块,[各地的团队LoCo teams][4](Ubuntu Local Community Teams)和开发人员板块。还有很多,但是这些都是我知道的社区组织部分。
-
-
-我们还有一个[Ubuntu 问答][5]板块。我认为,这种特色可以代替人们从论坛寻求帮助的方式,我发现在这个网站你得到有用信息的可能行更大。不仅如此,那些提供的解决方案中被选出的最精准的答案也会被写入到官方文档中。
-
-
-### Ubuntu 的未来
-
-
-我认为 Ubuntu 的 Unity 接口【译者注:Unity 是 Canonical 公司为 Ubuntu 操作系统的 GNOME 桌面环境开发的图形化 shell】在增加桌面舒适性上少有作为。我能理解其中的缘由,现在它主要做一些诸如可以使开发团队的工作更轻松的事情。但是最终,我还是希望 Unity 可以为 Ubuntu MATE 和 Linux Mint 的普及铺平道路。
-
-
-我最好奇的一点是 Ubuntu's IRC(Internet Relay Chat) 和邮件列表的发展【译者注:可以在 Ubuntu LoCo Teams IRC Chat上提问关于地方团队和计划的事件的问题,也可以和一些不同团队的成员进行交流】。事实是,他们都不能像 Ubuntu 问答板块那样为它们自己增添一些好的文档。至于邮件列表,我一直认为这对于合作是一种很痛苦的过时方法,但这仅仅是我的个人看法——其他人可能有不同的看法,也可能会认为它很好。
-
-你说什么?你认为 Ubuntu 将来会剩下一点主要的使用者?也许你相信 Arch 和 Linux Mint 或者其他的发行版会在普及度上打败 Ubuntu 。 既然这样,那请大声说出你最喜爱的发行版。如果这个发行版是 Ubuntu 衍生版 ,说说你为什么更喜欢它而不是 Ubuntu 本身。如果不出意外,Ubuntu 会成为构建其他发行版的基础,我想很多人都是这样认为的。
-
-
---------------------------------------------------------------------------------
-
-via: http://www.datamation.com/open-source/why-ubuntu-based-distros-are-leaders.html
-
-作者:[Matt Hartley][a]
-译者:[vim-kakali](https://github.com/vim-kakali)
-校对:[校对者ID](https://github.com/校对者ID)
-
-本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
-
-[a]: http://www.datamation.com/author/Matt-Hartley-3080.html
-[1]: http://www.ubuntu.com/
-[2]: https://www.debian.org/
-[3]: http://www.datamation.com/open-source/ubuntu-snap-packages-the-good-the-bad-the-ugly.html
-[4]: http://loco.ubuntu.com/
-[5]: http://askubuntu.com/
diff --git a/translated/talk/20160620 Training vs. hiring to meet the IT needs of today and tomorrow.md b/translated/talk/20160620 Training vs. hiring to meet the IT needs of today and tomorrow.md
new file mode 100644
index 0000000000..fc7794f305
--- /dev/null
+++ b/translated/talk/20160620 Training vs. hiring to meet the IT needs of today and tomorrow.md
@@ -0,0 +1,59 @@
+Training vs. hiring to meet the IT needs of today and tomorrow
+培训还是雇人,来满足当今和未来的 IT 需求
+================================================================
+
+![](https://enterprisersproject.com/sites/default/files/styles/620x350/public/images/cio_talent_4.png?itok=QLhyS_Xf)
+
+在数字化时代,由于企业需要不断跟上工具和技术更新换代的步伐,对 IT 技能的需求也稳定增长。对于企业来说,寻找和雇佣那些拥有令人垂涎能力的创新人才,是非常不容易的。同时,培训内部员工来使他们接受新的技能和挑战,需要一定的时间。而且,这也往往满足不了需求。
+
+[Sandy Hill][1] 对多种 IT 学科涉及到的多项技术都很熟悉。她作为 [Pegasystems][2] 项目的 IT 主管,负责的 IT 团队涉及的领域从应用的部署到数据中心的运营。更重要的是,Pegasystems 开发应用来帮助销售,市场,服务以及运行团队简化操作,联系客户。这意味着她需要掌握和利用 IT 内部资源的最佳方法,面对公司客户遇到的 IT 挑战。
+
+![](https://enterprisersproject.com/sites/default/files/CIO_Q%20and%20A_0.png)
+
+**企业家项目(TEP):这些年你是如何调整培训重心的?**
+
+**Hill**:在过去的几十年中,我们经历了爆炸式的发展,所以现在我们要实现更多的全球化进程。随之而来的培训方面,将确保每个人都在同一起跑线上。
+
+我们大多的关注点已经转移到培养员工使用新的产品和工具上,这些新产品和工具的实现,能够推动创新,并提高工作效率。例如,我们实现了资产管理系统; 以前我们是没有的。因此我们需要为全部员工做培训,而不是雇佣那些已经知道该产品的人。当我们正在发展的时候,我们也试图保持紧张的预算和稳定的职员总数。所以,我们更愿意在内部培训而不是雇佣新人。
+
+**TEP:说说培训方法吧,你是怎样帮助你的员工发展他们的技能?**
+
+**Hill**:我要求每一位员工制定一个技术性的和非技术性的训练目标。这作为他们绩效评估的一部分。他们的技术性目标需要与他们的工作职能相符,非技术行目标则着重发展一项软技能,或是学一些专业领域之外的东西。我每年对职员进行一次评估,看看差距和不足之处,以使团队保持全面发展。
+
+**TEP:你的训练计划能够在多大程度上减轻招聘和保留职员的问题?**
+
+**Hill**:使我们的职员对学习新的技术保持兴奋,让他们的技能更好。让职员知道我们重视他们并且让他们在擅长的领域成长和发展,以此激励他们。
+
+**TEP:你有没有发现哪种培训是最有效的?**
+
+**HILL**:我们使用几种不同的我们发现是有效的培训方法。当有新的或特殊的项目时,我们尝试加入一套由甲方(不会翻:乙方,卖方?)领导的培训课程,作为项目的一部分。要是这个方法不能实现,我们将进行异地培训。我们也会购买一些在线的培训课程。我也鼓励职员每年参加至少一次会议,以了解行业的动向。
+
+**TEP:你有没有发现有哪些技能,雇佣新人要比培训现有员工要好?**
+
+**Hill**:这和项目有关。有一个最近的计划,试图实现 OpenStack,而我们根本没有这方面的专家。所以我们与一家从事这一领域的咨询公司合作。我们利用他们的专业知识帮助我们运行项目,并现场培训我们的内部团队成员。让内部员工学习他们需要的技能,同时还要完成他们们天的工作,这是一项艰巨的任务。
+
+顾问帮助我们确定我们需要的对某一技术熟练的的员工人数。这使我们能够对员工进行评估,看看是否存在缺口。如果存在人员上的缺口,我们还需要额外的培训或是员工招聘。我们也确实雇佣了一些承包商。另一个选择是让一些全职员工进行为期六至八周的培训,但我们的项目模式不容许这么做。
+
+**TEP:想一下你最近雇佣的员工,他们的那些技能特别能够吸引到你?**
+
+**Hill**:在最近的招聘中,我侧重于软技能。除了扎实的技术能力外,他们需要能够在团队中进行有效的沟通和工作,要有说服他人,谈判和解决冲突的能力。
+
+IT 人一向独来独往。他们一般不是社交最多的人。现在,IT 越来越整合到组织中,它为其他业务部门提供有用的更新报告和状态报告的能力是至关重要的,这也表明 IT 是积极的存在,并将取得成功。
+
+--------------------------------------------------------------------------------
+
+via: https://enterprisersproject.com/article/2016/6/training-vs-hiring-meet-it-needs-today-and-tomorrow
+
+作者:[Paul Desmond][a]
+译者:[Cathon](https://github.com/Cathon)
+校对:[校对者ID](https://github.com/校对者ID)
+
+本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
+
+[a]: https://enterprisersproject.com/user/paul-desmond
+[1]: https://enterprisersproject.com/user/sandy-hill
+[2]: https://www.pega.com/pega-can?&utm_source=google&utm_medium=cpc&utm_campaign=900.US.Evaluate&utm_term=pegasystems&gloc=9009726&utm_content=smAXuLA4U|pcrid|102822102849|pkw|pegasystems|pmt|e|pdv|c|
+
+
+
+
diff --git a/translated/talk/20160627 Linux Practicality vs Activism.md b/translated/talk/20160627 Linux Practicality vs Activism.md
new file mode 100644
index 0000000000..81135bf56f
--- /dev/null
+++ b/translated/talk/20160627 Linux Practicality vs Activism.md
@@ -0,0 +1,71 @@
+Linux 的实用性 VS 行动主义
+==================================
+
+>我们使用 Linux 是因为它比其他操作系统更实用,还是其他更高级的理由呢?
+
+其中一件关于运行 Linux 的最伟大的事情之一就是它所提供的自由。凡出现在 Linux 社区之间的划分在于我们如何珍惜这种自由。
+
+一些人认为,通过使用 Linux 所享有的自由是从供应商锁定或高软件成本的自由。大多数人会称这个是一个实际的考虑。而其他用户会告诉你,他们享受的是自由软件的自由。那就意味着拥抱支持 [开源软件运动][1] 的 Linux 发行版,完全避免专有软件和所有相关的东西。
+
+
+在这篇文章中,我将带你比较这两种自由的区别,以及他们如何影响 Linux 的使用。
+
+### 专有的问题
+
+大多数的用户有一个共同的一点是他们的喜欢避免专有软件。对于像我这样的实际的爱好者来说,这是一个我怎么样花我的钱,来控制我的软件和避免供应商锁定的问题。当然,我不是一个程序员……所以我调整我的安装软件是十分温柔的。但也有一些个别情况,一个应用程序的小调整可以意味着它的工作和不工作的区别。
+
+还有就是选择避开专有软件的Linux爱好者,因为他们觉得这是不道德的使用。通常这里主要的问题是使用专有软件会带走或者干脆阻碍你的个人自由。像这些用户更喜欢使用的Linux发行版和软件来支持 [自由软件理念][2] 。虽然它类似于开源的概念并经常直接与之混淆,[这里有些差异][3] 。
+
+因此,这里有个问题:像我这样的用户往往以其便利掩盖了其纯软件自由的理想化。不要误会我的意思,像我这样的人更喜欢使用符合自由软件背后的理想软件,但我们也更有可能做出让步,以完成特定的任务。
+
+这两种类型的 Linux 爱好者都喜欢使用非专有的解决方案。但是,自由软件倡导者根本不会去使用所有权,在那里作为实际的用户将依靠具有最佳性能的最佳工具。这意味着,在有些情况下的实际用户愿意来运行他们的非专有操作系统上的专有应用或代码实例。
+
+最终,这两种类型的用户都喜欢使用 Linux 所提供的。但是,我们这样做的原因往往会有所不同。有人认为那些不支持自由软件的人是无知的。我不同意,我认为它是实用方便性的问题。那些喜欢实用方便性的用户根本不关心他们软件的政治问题。
+
+### 实用方便性
+
+当你问起绝大多数的人为什么使用他们现在的操作系统,回答通常都集中于实用方便性。这种关于方便性的例子可能包括“它是我一直使用的东西”、“它运行的软件是我需要的”。 其他人可能进一步解释说,并没有那么多软件影响他们对操作系统的偏好和熟悉程度,最后,有“利基任务”或硬件兼容性问题也提供了很好的理由让我们用这个操作系统而不是另一个。
+
+这可能会让你们中许多人很惊讶,但我今天运行的桌面 Linux 最大的一个原因是由于熟悉。即使我为别人提供对 Windows 和 OS X 的支持,但实际上我是相当沮丧地使用这些操作系统,因为它们根本就不是我记忆中的那样习惯用法。我相信这可以让我对那些 Linux 新手表示同情,因为我太懂得踏入陌生的领域是怎样的让人倒胃口了。我的观点是这样的 —— 熟悉具有价值。而且熟悉同样使得实用方便性变得有力量。
+
+现在,如果我们把它和一个自由软件倡导者的需求来比较,你会发现那些人都愿意学习新的东西,甚至更具挑战性,去学习那些若转化成为他们所避免使用的非自由软件。这就是我经常赞美的那种用户,我认为他们愿意采取最少路径来遵循坚持他们的原则是十分值得赞赏的。
+
+### 自由的价值
+
+我不羡慕那些自由软件倡导者的一个地方,就是根据 [自由软件基金会][4] 所规定的标准需要确保他们可以一直使用 Linux 发行版和硬件,以便于尊重他们的数字自由。这意味着 Linux 内核需要摆脱专有的斑点的驱动支持和不需要任何专有代码的硬件。当然不是不可能的,但它很接近。
+
+一个自由软件倡导者可以达到的最好的情况是硬件是“自由兼容”的。有些供应商,可以满足这一需求,但他们大多是提供依赖于 Linux 兼容专有固件的硬件。伟大的实际用户对自由软件倡导者来说是个搅局者。
+
+那么这一切意味着的是,倡导者必须比实际的 Linux 爱好者,更加警惕。这本身并不一定是消极的,但如果是打算用自由软件的方法来计算的话那就值得考虑了。通过对比,实用的用户可以专心地使用与 Linux 兼容的任何软件或硬件。我不知道你是怎么想的,但在我眼中是更轻松一点的。
+
+### 定义自由软件
+
+这一部分可能会让一部分人失望,因为我不相信自由软件只有一种。从我的立场,我认为真正的自由是能够在一个给定的情况里沉浸在所有可用的数据里,然后用最适合这个人的生活方式的途径来达成协议。
+
+所以对我来说,我更喜欢使用的 Linux 桌面,满足了我所有的需求,这包括使用非专有软件和专有软件。尽管这是公平的建议,专有的软件限制了我的个人自由,但我必须反驳这一点,因为我有选择用不用它,即选择的自由。
+
+或许,这也就是为什么我发现自己更确定开源软件的理想,而不是坚持自由软件运动背后的理念的原因。我更愿意和那些不会花时间告诉我,我是怎么用错了的那些人群在一起。我的经验是,那些开源的人群仅仅是感兴趣去分享自由软件的优点,而不是因为自由软件的理想主义的激情。
+
+我觉的自由软件的概念实在是太棒了。对那些需要活跃在软件政治,并指出使用专有软件的人的缺陷的人来说,那么我认为 Linux ( [GNU/Linux][5] ) 行动是一个不错的选择。在我们的介绍里,像我一样的实际用户更倾向于从自由软件的支持者改变方向。
+
+当我介绍 Linux 的桌面时,我富有激情地分享它的实际优点。而且我成功地让他们享受这一经历,我允许用户自己去发现自由软件的观点。但我发现大多数人使用的 Linux 不是因为他们想拥抱自由软件,而是因为他们只是想要最好的用户体验。也许只有我是这样的,很难说。
+
+嘿!说你呢?你是一个自由软件倡导者吗?也许你是个使用桌面 Linux 发行专有软件/代码的粉丝?那么评论和分享您的 Linux 桌面体验吧!
+
+
+--------------------------------------------------------------------------------
+
+via: http://www.datamation.com/open-source/linux-practicality-vs-activism.html
+
+作者:[Matt Hartley][a]
+译者:[joVoV](https://github.com/joVoV)
+校对:[校对者ID](https://github.com/校对者ID)
+
+本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
+
+[a]: http://www.datamation.com/author/Matt-Hartley-3080.html
+[1]: https://en.wikipedia.org/wiki/Free_software_movement
+[2]: https://www.gnu.org/philosophy/free-sw.en.html
+[3]: https://www.gnu.org/philosophy/free-software-for-freedom.en.html
+[4]: https://en.wikipedia.org/wiki/Free_Software_Foundation
+[5]: https://en.wikipedia.org/wiki/GNU/Linux_naming_controversy
\ No newline at end of file
diff --git a/translated/talk/20160803 The revenge of Linux.md b/translated/talk/20160803 The revenge of Linux.md
new file mode 100644
index 0000000000..96eb9f362f
--- /dev/null
+++ b/translated/talk/20160803 The revenge of Linux.md
@@ -0,0 +1,38 @@
+Translated by H-mudcup
+
+Linux 的逆袭
+========================
+
+![](https://opensource.com/sites/default/files/styles/image-full-size/public/images/life/penguin%20swimming.jpg?itok=mfhEdRdM)
+
+Linux 系统在早期的时候被人们嘲笑,它什么也干不了。现在,Linux 无处不在!
+
+我当时还是个在巴西学习计算机工程的大三学生,并同时在一个全球审计和顾问公司兼职系统管理员。公司决定用 Oracle 数据库实现企业资源计划(ERP)软件。我得以在 Digital UNIX OS (DEC Alpha) 进行训练,这个训练颠覆了我的三观。
+
+那个 UNIX 系统非常的强大并且给予了我们堆积起的绝对控制权:存储系统、网络、应用和其他一切。
+
+我开始在 ksh 和 Bash 里编写大量的脚本让系统自动进行备份、文件转移、提取转换加载(ETL)操作、自动化 DBA 日常工作,还创造了很多从各种不同的项目提出的其他的服务。此外,调整数据库和操作系统的工作让我更好的理解了如何让服务器以最佳方式运行。在那时,我在自己的个人电脑上使用的是 Windows 95 系统,而我非常想要在我的个人电脑里放进一个 Digital UNIX,或者即使是 Solaris 或 HP-UX 也行,但是那些 UNIX 系统都得在特定的硬件才能上运行。我阅读了所有系统的文档,还找过额外的书籍以求获得更多的信息,也在我们的开发环境里对一些疯狂的想法进行了实验。
+
+后来在大学里,我从我的同事那听说了 Linux。我那时非常激动的从还在用拨号方式连接的因特网上下载了它。在我标准的个人电脑里装上 UNIX 这类系统的这个想法真是太酷了!
+
+由于 Linux 不同于 UNIX 系统,它能在几乎所有的个人电脑硬件上运行,在起初,让它开始工作真的是非常困难的一件事。Linux 针对的用户群只有系统管理员和极客们。我为了让它能运行,甚至用 C 语言修改了驱动软件。我之前使用 UNIX 的经历让我在编译 Linux 内核,排错这些过程中非常的顺手。由于它不同于那些只适合特定硬件配置的封闭系统,所以让 Linux 跟各种意料之外的硬件配置一起工作真的是件非常具有挑战性的事。
+
+我曾见过 Linux 在数据中心获得一席之地。一些具有冒险精神的系统管理员使用它来帮他们完成每天监视和管理基础设施的工作,随后,Linux 同 DNS 和 DHCP 服务器、打印管理和文件服务器一起攻城略地。企业曾对 Linux 有着很多顾虑(恐惧,不确定性,怀疑)和诟病:谁是它的拥有者?由谁来支持它?有适用于它的应用吗?
+
+但现在看来,Linux 在各个地方进行着逆袭!从开发者的个人电脑到大企业的服务器;我们能在智能手机、智能手表以及像树莓派这样的物联网(IoT)设备里找到它。甚至 Mac OS X 有些 DOS 命令跟我们所熟悉的命令一样。微软在制造它自己的发行版,在 Azure 上运行,然后…… Windows 10 要装备 Bash。
+
+有趣的是 IT 市场会创造并迅速的代替新技术,但是我们所掌握的 Digital UNIX、HP-UX 和 Solaris 这些旧系统的知识还依然有效并跟 Linux 息息相关,不论是为了工作还是玩。现在我们能完全的掌控我们的系统,并使它发挥最大的效用。此外,Linux 有个充满热情的社区。
+
+我真的建议想在计算机方面发展的年轻人学习 Linux。不论你处于 IT 界里的哪个分支。如过你深入了解了一个标准的家用个人电脑是如何工作的,你就可以在任何机器面前使用基本相同的语言。你可以通过 Linux 学习最基本的计算机知识,并通过它建立能在 IT 界任何地方都有用的能力。
+
+--------------------------------------------------------------------------------
+
+via: https://opensource.com/life/16/8/revenge-linux
+
+作者:[Daniel Carvalho][a]
+译者:[H-mudcup](https://github.com/H-mudcup)
+校对:[校对者ID](https://github.com/校对者ID)
+
+本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创翻译,[Linux中国](https://linux.cn/) 荣誉推出
+
+[a]: https://opensource.com/users/danielscarvalho
diff --git a/translated/talk/yearbook2015/20151208 5 great Raspberry Pi projects for the classroom.md b/translated/talk/yearbook2015/20151208 5 great Raspberry Pi projects for the classroom.md
deleted file mode 100644
index 06191d551c..0000000000
--- a/translated/talk/yearbook2015/20151208 5 great Raspberry Pi projects for the classroom.md
+++ /dev/null
@@ -1,98 +0,0 @@
-5 个适合课堂教学的树莓派项目
-================================================================================
-![](https://opensource.com/sites/default/files/styles/image-full-size/public/images/life/osdc-open-source-yearbook-lead3.png)
-
-图片来源 : opensource.com
-
-### 1. Minecraft Pi ###
-
-![](https://opensource.com/sites/default/files/lava.png)
-
-上图由树莓派基金会提供。遵循 [CC BY-SA 4.0.][1] 协议。
-
-Minecraft(我的世界)几乎是世界上每个青少年都极其喜爱的游戏 —— 在吸引年轻人注意力方面,它也是最具创意的游戏之一。伴随着每一个树莓派的游戏版本不仅仅是一个关于创造性思维的建筑游戏,它还带有一个编程接口,允许使用者通过 Python 代码来与 Minecraft 世界进行互动。
-
-对于教师来说,Minecraft: Pi 版本是一个鼓励学生们解决遇到的问题以及通过书写代码来执行特定任务的极好方式。你可以使用 Python API
- 来建造一所房子,让它跟随你到任何地方;或在你所到之处修建一座桥梁;又或者是下一场岩溶雨;或在天空中显示温度;以及其他任何你能想像到的事物。
-
-可在 "[Minecraft Pi 入门][2]" 中了解更多相关内容。
-
-### 2. 反应游戏和交通指示灯 ###
-
-![](https://opensource.com/sites/default/files/pi_traffic_installed_yellow_led_on.jpg)
-
-上图由 [Low Voltage Labs][3] 提供。遵循 [CC BY-SA 4.0][1] 协议。
-
-在树莓派上进行物理计算是非常容易的 —— 只需将 LED 灯 和按钮连接到 GPIO 针脚上,再加上少量的代码,你就可以点亮 LED 灯并通过按按钮来控制物体。一旦你知道来执行基本操作的代码,下一步就可以随你的想像那样去做了!
-
-假如你知道如何让一盏灯闪烁,你就可以让三盏灯闪烁。选出三盏交通灯颜色的 LED 灯,你就可以编程出交通灯闪烁序列。假如你知道如何使用一个按钮来触发一个事件,然后你就有一个人行横道了!同时,你还可以找到诸如 [PI-TRAFFIC][4]、[PI-STOP][5]、[Traffic HAT][6] 等预先构建好的交通灯插件。
-
-这不总是关于代码的 —— 它还可以被用来作为一个的练习,用以理解真实世界中的系统是如何被设计出来的。计算思维在生活中的各种情景中都是一个有用的技能。
-
-![](https://opensource.com/sites/default/files/reaction-game.png)
-
-上图由树莓派基金会提供。遵循 [CC BY-SA 4.0][1] 协议。
-
-下面尝试将两个按钮和一个 LED 灯连接起来,来制作一个二人制反应游戏 —— 让灯在一段随机的时间中点亮,然后看谁能够先按到按钮!
-
-想了解更多的话,请查看 [GPIO 新手指南][7]。你所需要的尽在 [CamJam EduKit 1][8]。
-
-### 3. Sense HAT 像素宠物 ###
-
-Astro Pi— 一个增强版的树莓派 —将于今年 12 月(注:应该是去年的事了。)问世,但你并没有错过让你的手玩弄硬件的机会。Sense HAT 是一个用在 Astro Pi 任务中的感应器主板插件,且任何人都可以买到。你可以用它来做数据收集、科学实验、游戏或者更多。 观看下面这个由树莓派的 Carrie Anne 带来的 Gurl Geek Diaries 录像来开始一段美妙的旅程吧 —— 通过在 Sense HAT 的显示器上展现出你自己设计的一个动物像素宠物:
-
-注:youtube 视频
-
-
-在 "[探索 Sense HAT][9]" 中可以学到更多。
-
-### 4. 红外鸟箱 ###
-
-![](https://opensource.com/sites/default/files/ir-bird-box.png)
-上图由 [Low Voltage Labs][3] 提供。遵循 [CC BY-SA 4.0][1] 协议。
-
-让全班所有同学都能够参与进来的一个好的练习是 —— 在一个鸟箱中沿着某些红外线放置一个树莓派和 NoIR 照相模块,这样你就可以在黑暗中观看,然后通过网络或在网络中你可以从树莓派那里获取到视频流。等鸟进入笼子,然后你就可以在不打扰到它们的情况下观察它们。
-
-在这期间,你可以学习到所有关于红外和光谱的知识,以及如何用软件来调整摄像头的焦距和控制它。
-
-在 "[制作一个红外鸟箱][10]" 中你可以学到更多。
-
-### 5. 机器人 ###
-
-![](https://opensource.com/sites/default/files/edukit3_1500-alex-eames-sm.jpg)
-
-上图由 Low Voltage Labs 提供。遵循 [CC BY-SA 4.0][1] 协议。
-
-拥有一个树莓派,一些感应器和一个感应器控制电路板,你就可以构建你自己的机器人。你可以制作各种类型的机器人,从用透明胶带和自制底盘组合在一起的简易四驱车,一直到由游戏控制器驱动的具有自我意识,带有传感器和摄像头的金属马儿。
-
-学习如何直接去控制单个的发动机,例如通过 RTK Motor Controller Board (£8/$12),或者尝试新的 CamJam robotics kit (£17/$25) ,它带有发动机、轮胎和一系列的感应器 — 这些都很有价值并很有学习的潜力。
-
-另外,如何你喜欢更为骨灰级别的东西,可以尝试 PiBorg 的 [4Borg][11] (£99/$150) 或 [DiddyBorg][12] (£180/$273) 或者一干到底,享受他们的 DoodleBorg 金属版 (£250/$380) — 并构建一个他们声名远扬的 [DoodleBorg tank][13](很不幸的时,这个没有卖的) 的迷你版。
-
-另外请参考 [CamJam robotics kit worksheets][14]。
-
---------------------------------------------------------------------------------
-
-via: https://opensource.com/education/15/12/5-great-raspberry-pi-projects-classroom
-
-作者:[Ben Nuttall][a]
-译者:[译者ID](https://github.com/译者ID)
-校对:[校对者ID](https://github.com/校对者ID)
-
-本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
-
-[a]:https://opensource.com/users/bennuttall
-[1]:https://creativecommons.org/licenses/by-sa/4.0/
-[2]:https://opensource.com/life/15/5/getting-started-minecraft-pi
-[3]:http://lowvoltagelabs.com/
-[4]:http://lowvoltagelabs.com/products/pi-traffic/
-[5]:http://4tronix.co.uk/store/index.php?rt=product/product&product_id=390
-[6]:https://ryanteck.uk/hats/1-traffichat-0635648607122.html
-[7]:http://pythonhosted.org/gpiozero/recipes/
-[8]:http://camjam.me/?page_id=236
-[9]:https://opensource.com/life/15/10/exploring-raspberry-pi-sense-hat
-[10]:https://www.raspberrypi.org/learning/infrared-bird-box/
-[11]:https://www.piborg.org/4borg
-[12]:https://www.piborg.org/diddyborg
-[13]:https://www.piborg.org/doodleborg
-[14]:http://camjam.me/?page_id=1035#worksheets
diff --git a/translated/talk/yearbook2015/20151208 6 creative ways to use ownCloud.md b/translated/talk/yearbook2015/20151208 6 creative ways to use ownCloud.md
deleted file mode 100644
index 5d81ed9cdf..0000000000
--- a/translated/talk/yearbook2015/20151208 6 creative ways to use ownCloud.md
+++ /dev/null
@@ -1,95 +0,0 @@
-GHLandy Translated
-
-使用 ownCloud 的六个创意方法
-================================================================================
-![Yearbook cover 2015](https://opensource.com/sites/default/files/styles/image-full-size/public/images/business/osdc-open-source-yearbook-lead1-inc0335020sw-201511-01.png)
-
-图片来源:Opensource.com
-
-[ownCloud][1] 是一个自我托管且开源的文件同步和共享服务上。就像 "big boys" Dropbox、Google Drive、Box 和其他的同类服务一样,ownCloud 可以让你访问自己的文件、日历、联系人和其他数据。你可以在自己设备之间进行任意数据(包括它自身的一部分)同步以及给其他人分享文件。然而,ownCloud 并非只能运行在它自己的开发商之中,试试[将 ownCloud 运行在其他服务器上][2]
-
-现在,一起来看看在 ownCloud 上的六件创意事件。其中一些是由于 ownCloud 的开源才得以完成,而另外的则是 ownCloud 自身特有的功能。
-
-### 1. 可扩展的 ownCloud 派集群 ###
-
-由于 ownCloud 是开源的,你可以选择将它运行在自己的服务器中,或者从你信任的服务器提供商那里获取空间——没必要将你的文件存储在大公司的服务器中,谁知他们将你的文件存储到哪里去。[点击此处查看部分 ownCloud 服务商][3],或者下载该服务软件到你的虚拟主机中[搭建自己的服务器][4].
-
-![](https://opensource.com/sites/default/files/images/life-uploads/banana-pi-owncloud-cluster.jpg)
-
-拍摄: Jörn Friedrich Dreyer. [CC BY-SA 4.0.][5]
-
-我们见过最具创意的事情就是组建 [香蕉派集群][6] 和 [树莓派集群][7]。ownCloud 的扩展性通常是成千上万的用户来完成的,这些人则将它往不同方向发展,通过大量的小型系统集群在一起,就可以创建出运行速度非常快的 ownCloud。酷毙了!
-
-### 2. 密码同步 ###
-
-为了让 ownCloud 更容易扩展,我们需要将它模块化,并拥有 [ownCloud app store][8]。然后你就可以在里边搜索音乐、视频播放器、日历、联系人、生产应用、游戏、应用框架等。
-
-仅从 200 多个可用应用中挑选一个是一件非常困难的事,但密码管理则是一个很好的特性。ownCloud app store 里边至少有三款这种应用:[Passwords][9]、[Secure Container][10] 和 [Passman][11]。
-
-![](https://opensource.com/sites/default/files/images/life-uploads/password.png)
-
-### 3. 随心所欲地存储文件 ###
-
-外部存储允许你通过接口将现有数据联系到 ownCloud,让你轻松访问存储在FTP、WebDAV、Amazon S3,甚至 Dropbox 和Google Drive。
-
-注:youtube 视频
-
-
-DropBox 喜欢创建自己的 “围墙式花园”,只有注册用户之间才可以进行协作;假如你通过Google Drive 来分享文件,你的同伴也必须要有一个 Google 账号才可以访问的分享。通过 ownCloud 的外部存储功能,你可以轻松打破这些规则障碍。
-
-最有创意的就是把 Google Drive 和 Dropbox 添加为外部存储。这样你就可以无缝的使用它们,并使用不需要账户地链接把文件分享给和你协作的人。
-
-### 4. 下载以上传的文件 ###
-
-由于 ownCloud 的开源,人们可以不受公司需求限制地向它共享代码,增加新特性。共献者关注的往往是安全和隐私,所以 ownCloud 引入的特性常常比别人的要早,比如通过密码保护的公共链接和[设置失效期限][12]。
-
-现在,ownCloud 可以配置分享链接的读写权限了,这就是说链接的访问者可以无缝的编辑你分享给他们的文件(不管是否有密码保护),或者在不提供他们的私人数据来登录其他服务的情况下将文件上传到服务器。
-
-注:youtube 视频
-
-
-对于有人想给你分享大体积的文件时,这个特性就非常有用了。相比于上传到第三方站点、然后给你发送一个连接、你再去下载文件(通常需要登录),ownCloud 仅需要上传文件到你提供的分享文件夹、你就可以买上获取到文件了。
-
-### 5. 免费却又安全的存储空间 ###
-
-之前就强调过,我们的代码贡献者最关注的就是安全和隐私,这就是 ownCloud 中有用于加密和解密存储数据的应用的原因。
-
-通过使用 ownCloud 将你的文件存储到 Dropbox 或者 Google Drive,则会违背控制数据以及保持数据隐私的原则。但是加密应用则刚好可以满足安全及隐私问题。在发送数据给这些提供商前进行数据加密,并在取回数据的时候进行解密,你的数据就会变得很安全。
-
-### 6. 在你的可控范围内分享文件 ###
-
-作为开源项目,ownCloud 没有必要自建 “围墙式花园”。进入联邦云共享:[developed and published by ownCloud][13] 协议使不同的文件同步和共享服务器可以彼此之间进行通信,并能够安全地传输文件。联邦云共享本身有一个有趣的故事:[22 所德国大学][14] 想要为自身的 500,000 学生建立一个庞大的云服务,但是每个大学都想控制自己学生数据。于是乎,我们需要一个可行性解决方案:也就是联邦云服务。该解决方案让让学生保持连接,使得他们可以无缝的协同工作。同时,每个大学的系统管理员保持着对自己学生创建的文件的控制权,如限制存储或者限制什么人、什么文件以及如何共享。
-
-注:youtube 视频
-
-
-并且,这项令人崇敬的技术并没有限制于德国的大学之间,而是每个 ownCloud 用户都能在自己的用户设置中找到自己的 [联邦云 ID][15],并将之分享给同伴。
-
-现在你明白了吧。仅六个方法,ownCloud 就能让人们完成特殊和特别的事。而是这一切成为可能的,就是 ownCloud 的开源 —— 设计用来释放你数据。
-
---------------------------------------------------------------------------------
-
-via: https://opensource.com/life/15/12/6-creative-ways-use-owncloud
-
-作者:[Jos Poortvliet][a]
-译者:[GHLandy](https://github.com/GHLandy)
-校对:[校对者ID](https://github.com/校对者ID)
-
-本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
-
-[a]:https://opensource.com/users/jospoortvliet
-[1]:https://owncloud.com/
-[2]:https://blogs.fsfe.org/mk/new-stickers-and-leaflets-no-cloud-and-e-mail-self-defense/
-[3]:https://owncloud.org/providers
-[4]:https://owncloud.org/install/#instructions-server
-[5]:https://creativecommons.org/licenses/by-sa/4.0/
-[6]:http://www.owncluster.de/
-[7]:https://christopherjcoleman.wordpress.com/2013/01/05/host-your-owncloud-on-a-raspberry-pi-cluster/
-[8]:https://apps.owncloud.com/
-[9]:https://apps.owncloud.com/content/show.php/Passwords?content=170480
-[10]:https://apps.owncloud.com/content/show.php/Secure+Container?content=167268
-[11]:https://apps.owncloud.com/content/show.php/Passman?content=166285
-[12]:https://owncloud.com/owncloud45-community/
-[13]:http://karlitschek.de/2015/08/announcing-the-draft-federated-cloud-sharing-api/
-[14]:https://owncloud.com/customer/sciebo/
-[15]:https://owncloud.org/federation/
diff --git a/translated/talk/yearbook2015/20160306 5 Favorite Open Source Django Packages.md b/translated/talk/yearbook2015/20160306 5 Favorite Open Source Django Packages.md
deleted file mode 100644
index 81e999fd80..0000000000
--- a/translated/talk/yearbook2015/20160306 5 Favorite Open Source Django Packages.md
+++ /dev/null
@@ -1,164 +0,0 @@
-5个最受喜爱的开源Django包
-================================================================================
-![Yearbook cover 2015](https://opensource.com/sites/default/files/styles/image-full-size/public/u23316/osdc-open-source-yearbook-lead8.png?itok=0_5-hdFE)
-
-图片来源:Opensource.com
-
-_Jacob Kaplan-Moss和Frank Wiles也参与了本文的写作。_
-
-Django围绕“[可重用应用][1]”观点建立:自我包含了提供可重复使用特性的包。你可以将这些可重用应用组装起来,在加上适用于你的网站的特定代码,来搭建你自己的网站。Django具有一个丰富多样的、由可供你使用的可重用应用组建起来的生态系统——PyPI列出了[超过8000个 Django 应用][2]——可你该如何知道哪些是最好的呢?
-
-为了节省你的时间,我们总结了五个最受喜爱的 Django 应用。它们是:
-- [Cookiecutter][3]: 建立 Django 网站的最佳方式。
-- [Whitenoise][4]: 最棒的静态资源服务器。
-- [Django Rest Framework][5]: 使用 Django 开发 REST API 的最佳方式。
-- [Wagtail][6]: 基于 Django 的最佳内容管理系统。
-- [django-allauth][7]: 提供社交账户登录的最佳应用(如 Twitter, Facebook, GitHub 等)。
-
-我们同样推荐你查看 [Django Packages][8],一个可重用 Django 应用的目录。Django Packages 将 Django 应用组织成“表格”,你可以在功能相似的不同应用之间进行比较并做出选择。你可以查看每个包中提供的特性,和使用统计情况。(比如:这是[ REST 工具的表格][9],也许可以帮助你理解我们为何推荐 Django REST Framework.
-
-## 为什么你应该相信我们?
-
-我们使用 Django 的时间比几乎其他人都长。在 Django 发布之前,我们当中的两个人(Frank 和 Jacob)在 [Lawrence Journal-World][10] (Django 的发源地)工作(事实上他们两人推动了 Django 开源发布的进程)。我们在过去的八年当中运行着一个咨询公司,来建议公司使用 Django 去将事情做到最好。
-
-所以,我们见证了Django项目和社群的完整历史,我们见证了流行软件包的兴起和没落。在我们三个中,我们可能私下试用了8000个应用中的一半以上,或者我们知道谁试用过这些。我们对如何使应用变得坚实可靠有着深刻的理解,并且我们对给予这些应用持久力量的来源也有不错的理解。
-
-## 建立Django网站的最佳方式:[Cookiecutter][3]
-
-建立一个新项目或应用总是有些痛苦。你可以用Django内建的 `startproject`。不过,如果你像我们一样,你可能会对你的办事方式很挑剔。Cookiecutter 为你提供了一个快捷简单的方式来构建易于使用的项目或应用模板,从而解决了这个问题。一个简单的例子:键入 `pip install cookiecutter`,然后在命令行中运行以下命令:
-
-```bash
-$ cookiecutter https://github.com/marcofucci/cookiecutter-simple-django
-```
-
-接下来你需要回答几个简单的问题,比如你的项目名称、目录、作者名字、E-Mail和其他几个关于配置的小问题。这些能够帮你补充项目相关的细节。我们使用最最原始的 "_foo_" 作为我们的目录名称。所以 cokkiecutter 在子目录 "_foo_" 下建立了一个简单的 Django 项目。
-
-如果你在"_foo_"项目中闲逛,你会看见你刚刚选择的其它设置已通过模板,连同子目录一同嵌入到文件当中。这个“模板”在我们刚刚在执行 `cookiecutter` 命令时输入的 Github 仓库 URL 中定义。这个样例工程使用了一个 Github 远程仓库作为模板;不过你也可以使用本地的模板,这在建立非重用项目时非常有用。
-
-我们认为 cookiecutter 是一个极棒的 Django 包,但是,事实上其实它在面对纯 Python 甚至非 Python 相关需求时也极为有用。你能够将所有文件依你所愿精确摆放在任何位置上,使得 cookiecutter 成为了一个简化工作流程的极佳工具。
-
-## 最棒的静态资源服务器:[Whitenoise][4]
-
-多年来,托管网站的静态资源——图片、Javascript、CSS——都是一件很痛苦的事情。Django 内建的 [django.views.static.serve][11] 视图,就像Django文章所述的那样,“在生产环境中不可靠,所以只应为开发环境的提供辅助功能。”但使用一个“真正的” Web 服务器,如 NGINX 或者借助 CDN 来托管媒体资源,配置起来会相当困难。
-
-Whitenoice 很简洁地解决了这个问题。它可以像在开发环境那样轻易地在生产环境中设置静态服务器,并且针对生产环境进行了加固和优化。它的设置方法极为简单:
-
-1. 确保你在使用 Django 的 [contrib.staticfiles][12] 应用,并确认你在配置文件中正确设置了 `STATIC_ROOT` 变量。
-
-2. 在 `wsgi.py` 文件中启用 Whitenoise:
-
- ```python
- from django.core.wsgi import get_wsgi_application
- from whitenoise.django import DjangoWhiteNoise
-
- application = get_wsgi_application()
- application = DjangoWhiteNoise(application)
- ```
-
-配置它真的就这么简单!对于大型应用,你可能想要使用一个专用的媒体服务器和/或一个 CDN,但对于大多数小型或中型 Django 网站,Whitenoise 已经足够强大。
-
-如需查看更多关于 Whitenoise 的信息,[请查看文档][13]。
-
-## 开发REST API的最佳工具:[Django REST Framework][5]
-
-REST API 正在迅速成为现代 Web 应用的标准功能。与一个 API 进行简短的会话,你只需使用 JSON 而不是 HTML,当然你可以只用 Django 做到这些。你可以制作自己的视图,设置合适的 `Content-Type`, 然后返回 JSON 而不是渲染后的 HTML 响应。这是在像 [Django Rest Framework][14](下称DRF)这样的API框架发布之前,大多数人所做的。
-
-如果你对 Django 的视图类很熟悉,你会觉得使用DRF构建REST API与使用它们很相似,不过 DRF 只针对特定 API 使用场景而设计。在一般 API 设计中,你会用到它的不少代码,所以我们强调了一些 DRF 的特性来使你更快地接受它,而不是去看一份让你兴奋的示例代码:
-
-* 可自动预览的 API 可以使你的开发和人工测试轻而易举。你可以查看 DRF 的[示例代码][15]。你可以查看 API 响应,并且它支持 POST/PUT/DELETE 类型的操作,不需要你做任何事。
-
-
-* 认证方式易于迁移,如OAuth, Basic Auth, 或API Tokens.
-* 内建请求速度限制。
-* 当与 [django-rest-swagger][16] 结合时,API文档几乎可以自动生成。
-* 第三方库拥有广泛的生态。
-
-当然你可以不依赖 DRF 来构建 API,但我们无法推测你不开始使用 DRF 的原因。就算你不使用 DRF 的全部特性,使用一个成熟的视图库来构建你自己的 API 也会使你的 API 更加一致、完全,更能提高你的开发速度。如果你还没有开始使用 DRF, 你应该找点时间去体验一下。
-
-## 以 Django 为基础的最佳 CMS:[Wagtail][6]
-
-Wagtail是当下Django CMS(内容管理系统)世界中最受人青睐的应用,并且它的热门有足够的理由。就想大多数的 CMS 一样,它具有极佳的灵活性,可以通过简单的 Django 模型来定义不同类型的页面及其内容。使用它,你可以从零开始,在几个小时而不是几天之内来和建造一个基本可以运行的内容管理系统。举一个小例子,为你公司的员工定义一个页面类型可以像下面一样简单:
-
-```python
-from wagtail.wagtailcore.models import Page
-from wagtail.wagtailcore.fields import RichTextField
-from wagtail.wagtailadmin.edit_handlers import FieldPanel, MultiFieldPanel
-from wagtail.wagtailimages.edit_handlers import ImageChooserPanel
-
-class StaffPage(Page):
- name = models.CharField(max_length=100)
- hire_date = models.DateField()
- bio = models.RichTextField()
- email = models.EmailField()
- headshot = models.ForeignKey('wagtailimages.Image', null=True, blank=True)
- content_panels = Page.content_panels + [
- FieldPanel('name'),
- FieldPanel('hire_date'),
- FieldPanel('email'),
- FieldPanel('bio',classname="full"),
- ImageChoosePanel('headshot'),
- ]
-```
-
-然而,Wagtail 真正出彩的地方在于它的灵活性及其易于使用的现代化管理页面。你可以控制不同类型的页面在哪网站的哪些区域可以访问,为页面添加复杂的附加逻辑,还可以极为方便地取得标准的适应/审批工作流。在大多数 CMS 系统中,你会在开发时在某些点上遇到困难。而使用 Wagtail 时,我们经过不懈努力找到了一个突破口,使得让我们轻易地开发出一套简洁稳定的系统,使得程序完全依照我们的想法运行。如果你对此感兴趣,我们写了一篇[深入理解 Wagtail][17].
-
-## 提供社交账户登录的最佳工具:[django-allauth][7]
-
-django-allauth 是一个能够解决你的注册和认证需求的、可重用的Django应用。无论你需要构建本地注册系统还是社交账户注册系统,django-allauth 都能够帮你做到。
-
-这个应用支持多种认证体系,比如用户名或电子邮件。一旦用户注册成功,它可以提供从零到电子邮件认证的多种账户验证的策略。同时,它也支持多种社交账户和电子邮件账户关联。它还支持可插拔的注册表单,可让用户在注册时回答一些附加问题。
-
-django-allauth 支持多于 20 种认证提供者,包括 Facebook, Github, Google 和 Twitter。如果你发现了一个它不支持的社交网站,那很有可能有一款第三方插件提供该网站的接入支持。这个项目还支持自定义后台开发,可以支持自定义的认证方式。
-
-django-allauth 易于配置,且有[完善的文档][18]。该项目通过了很多测试,所以你可以相信它的所有部件都会正常运作。
-
-你有最喜爱的 Django 包吗?请在评论中告诉我们。
-
-## 关于作者
-
-![Photo](https://opensource.com/sites/default/files/styles/profile_pictures/public/pictures/main-one-i-use-everywhere.png?itok=66GC-D1q)
-
-Jeff Triplett
-
-劳伦斯,堪萨斯州
-
-
-我在 2007 年搬到了堪萨斯州的劳伦斯,在 Django 的发源地—— Lawrence Journal-World 工作。我现在在劳伦斯市的 [Revolution Systems (Revsys)][19] 工作,做一位开发者兼顾问。
-
-我是[北美 Django 运动基金会(DEFNA)][20]的联合创始人,2015 和 2016 年 [DjangoCon US][21] 的会议主席,而且我在 Django 的发源地劳伦斯参与组织了 [Django Birthday][22] 来庆祝 Django 的 10 岁生日。
-
-我是当地越野跑小组的成员,我喜欢篮球,我还喜欢梦见自己随着一道气流游遍美国。
-
---------------------------------------------------------------------------------
-
-via: https://opensource.com/business/15/12/5-favorite-open-source-django-packages
-
-作者:[Jeff Triplett][a]
-译者:[StdioA](https://github.com/StdioA)
-校对:[校对者ID](https://github.com/校对者ID)
-
-本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
-
-[a]:https://opensource.com/users/jefftriplett
-[1]:https://docs.djangoproject.com/en/1.8/intro/reusable-apps/
-[2]:https://pypi.python.org/pypi?:action=browse&c=523
-[3]:https://github.com/audreyr/cookiecutter
-[4]:http://whitenoise.evans.io/en/latest/base.html
-[5]:http://www.django-rest-framework.org/
-[6]:https://wagtail.io/
-[7]:http://www.intenct.nl/projects/django-allauth/
-[8]:https://www.djangopackages.com/
-[9]:https://www.djangopackages.com/grids/g/rest/
-[10]:http://www2.ljworld.com/news/2015/jul/09/happy-birthday-django/
-[11]:https://docs.djangoproject.com/en/1.8/ref/views/#django.views.static.serve
-[12]:https://docs.djangoproject.com/en/1.8/ref/contrib/staticfiles/
-[13]:http://whitenoise.evans.io/en/latest/index.html
-[14]:http://www.django-rest-framework.org/
-[15]:http://restframework.herokuapp.com/
-[16]:http://django-rest-swagger.readthedocs.org/en/latest/index.html
-[17]:https://opensource.com/business/15/5/wagtail-cms
-[18]:http://django-allauth.readthedocs.org/en/latest/
-[19]:http://www.revsys.com/
-[20]:http://defna.org/
-[21]:https://2015.djangocon.us/
-[22]:https://djangobirthday.com/
diff --git a/translated/tech/20151220 GCC-Inline-Assembly-HOWTO.md b/translated/tech/20151220 GCC-Inline-Assembly-HOWTO.md
deleted file mode 100644
index e0e1fc6d50..0000000000
--- a/translated/tech/20151220 GCC-Inline-Assembly-HOWTO.md
+++ /dev/null
@@ -1,632 +0,0 @@
-* * *
-
-# GCC 内联汇编 HOWTO
-
-v0.1, 01 March 2003.
-* * *
-
-_本 HOWTO 文档将讲解 GCC 提供的内联汇编特性的用途和用法。对于阅读这篇文章,这里只有两个前提要求,很明显,就是 x86 汇编语言和 C 语言的基本认识。_
-
-* * *
-
-## 1. 简介
-
-## 1.1 版权许可
-
-Copyright (C)2003 Sandeep S.
-
-本文档自由共享;你可以重新发布它,并且/或者在遵循自由软件基金会发布的 GNU 通用公共许可证下修改它;或者该许可证的版本 2 ,或者(按照你的需求)更晚的版本。
-
-发布这篇文档是希望它能够帮助别人,但是没有任何保证;甚至不包括可售性和适用于任何特定目的的保证。关于更详细的信息,可以查看 GNU 通用许可证。
-
-## 1.2 反馈校正
-
-请将反馈和批评一起提交给 [Sandeep.S](mailto:busybox@sancharnet.in) 。我将感谢任何一个指出本文档中错误和不准确之处的人;一被告知,我会马上改正它们。
-
-## 1.3 致谢
-
-我对提供如此棒的特性的 GNU 人们表示真诚的感谢。感谢 Mr.Pramode C E 所做的所有帮助。感谢在 Govt Engineering College 和 Trichur 的朋友们的精神支持和合作,尤其是 Nisha Kurur 和 Sakeeb S 。 感谢在 Gvot Engineering College 和 Trichur 的老师们的合作。
-
-另外,感谢 Phillip , Brennan Underwood 和 colin@nyx.net ;这里的许多东西都厚颜地直接取自他们的工作成果。
-
-* * *
-
-## 2. 概览
-
-在这里,我们将学习 GCC 内联汇编。这内联表示的是什么呢?
-
-我们可以要求编译器将一个函数的代码插入到调用者代码中函数被实际调用的地方。这样的函数就是内联函数。这听起来和宏差不多?这两者确实有相似之处。
-
-内联函数的优点是什么呢?
-
-这种内联方法可以减少函数调用开销。同时如果所有实参的值为常量,它们的已知值可以在编译期允许简化,因此并非所有的内联函数代码都需要被包含。代码大小的影响是不可预测的,这取决于特定的情况。为了声明一个内联函数,我们必须在函数声明中使用 `inline` 关键字。
-
-现在我们正处于一个猜测内联汇编到底是什么的点上。它只不过是一些写为内联函数的汇编程序。在系统编程上,它们方便、快速并且极其有用。我们主要集中学习(GCC)内联汇编函数的基本格式和用法。为了声明内联汇编函数,我们使用 `asm` 关键词。
-
-内联汇编之所以重要,主要是因为它可以操作并且使其输出通过 C 变量显示出来。正是因为此能力, "asm" 可以用作汇编指令和包含它的 C 程序之间的接口。
-
-* * *
-
-## 3. GCC 汇编语法
-
-GCC , Linux上的 GNU C 编译器,使用 **AT&T** / **UNIX** 汇编语法。在这里,我们将使用 AT&T 语法 进行汇编编码。如果你对 AT&T 语法不熟悉的话,请不要紧张,我会教你的。AT&T 语法和 Intel 语法的差别很大。我会给出主要的区别。
-
-1. 源操作数和目的操作数顺序
-
- AT&T 语法的操作数方向和 Intel 语法的刚好相反。在Intel 语法中,第一操作数为目的操作数,第二操作数为源操作数,然而在 AT&T 语法中,第一操作数为源操作数,第二操作数为目的操作数。也就是说,
-
- Intel 语法中的 "Op-code dst src" 变为
-
- AT&T 语法中的 "Op-code src dst"。
-
-2. 寄存器命名
-
- 寄存器名称有 % 前缀,即如果必须使用 eax,它应该用作 %eax。
-
-3. 立即数
-
- AT&T 立即数以 ’$’ 为前缀。静态 "C" 变量 也使用 ’$’ 前缀。在 Intel 语法中,十六进制常量以 ’h’ 为后缀,然而AT&T不使用这种语法,这里我们给常量添加前缀 ’0x’。所以,对于十六进制,我们首先看到一个 ’$’,然后是 ’0x’,最后才是常量。
-
-4. 操作数大小
-
- 在 AT&T 语法中,存储器操作数的大小取决于操作码名字的最后一个字符。操作码后缀 ’b’ 、’w’、’l’分别指明了字节(byte)(8位)、字(word)(16位)、长型(long)(32位)存储器引用。Intel 语法通过给存储器操作数添加’byte ptr’、 ’word ptr’ 和 ’dword ptr’前缀来实现这一功能。
-
- 因此,Intel的 "mov al, byte ptr foo" 在 AT&T 语法中为 "movb foo, %al"。
-
-5. 存储器操作数
-
- 在 Intel 语法中,基址寄存器包含在 ’[’ 和 ’]’ 中,然而在 AT&T 中,它们变为 ’(’ 和 ’)’。另外,在 Intel 语法中, 间接内存引用为
-
- section:[base + index*scale + disp], 在 AT&T中变为
-
- section:disp(base, index, scale)。
-
- 需要牢记的一点是,当一个常量用于 disp 或 scale,不能添加’$’前缀。
-
-现在我们看到了 Intel 语法和 AT&T 语法之间的一些主要差别。我仅仅写了它们差别的一部分而已。关于更完整的信息,请参考 GNU 汇编文档。现在为了更好地理解,我们可以看一些示例。
-
-> `
->
-> +------------------------------+------------------------------------+
-> | Intel Code | AT&T Code |
-> +------------------------------+------------------------------------+
-> | mov eax,1 | movl $1,%eax |
-> | mov ebx,0ffh | movl $0xff,%ebx |
-> | int 80h | int $0x80 |
-> | mov ebx, eax | movl %eax, %ebx |
-> | mov eax,[ecx] | movl (%ecx),%eax |
-> | mov eax,[ebx+3] | movl 3(%ebx),%eax |
-> | mov eax,[ebx+20h] | movl 0x20(%ebx),%eax |
-> | add eax,[ebx+ecx*2h] | addl (%ebx,%ecx,0x2),%eax |
-> | lea eax,[ebx+ecx] | leal (%ebx,%ecx),%eax |
-> | sub eax,[ebx+ecx*4h-20h] | subl -0x20(%ebx,%ecx,0x4),%eax |
-> +------------------------------+------------------------------------+
->
->
-> `
-
-* * *
-
-## 4. 基本内联
-
-基本内联汇编的格式非常直接了当。它的基本格式为
-
-`asm("汇编代码");`
-
-示例
-
-> `
->
-> * * *
->
-> asm("movl %ecx %eax"); /* 将 ecx 寄存器的内容移至 eax */
-> __asm__("movb %bh (%eax)"); /* 将 bh 的一个字节数据 移至 eax 寄存器指向的内存 */
->
->
-> * * *
->
-> `
-
-你可能注意到了这里我使用了 `asm ` 和 `__asm__`。这两者都是有效的。如果关键词 `asm` 和我们程序的一些标识符冲突了,我们可以使用 `__asm__`。如果我们的指令多余一条,我们可以写成一行,并用括号括起,也可以为每条指令添加 ’\n’ 和 ’\t’ 后缀。这是因为gcc将每一条当作字符串发送给 **as**(GAS)( GAS 即 GNU 汇编器 ——译者注),并且通过使用换行符/制表符发送正确地格式化行给汇编器。
-
-示例
-
-> `
->
-> * * *
->
-> __asm__ ("movl %eax, %ebx\n\t"
-> "movl $56, %esi\n\t"
-> "movl %ecx, $label(%edx,%ebx,$4)\n\t"
-> "movb %ah, (%ebx)");
->
->
-> * * *
->
-> `
-
-如果在代码中,我们涉及到一些寄存器(即改变其内容),但在没有固定这些变化的情况下从汇编中返回,这将会导致一些不好的事情。这是因为 GCC 并不知道寄存器内容的变化,这会导致问题,特别是当编译器做了某些优化。在没有告知 GCC 的情况下,它将会假设一些寄存器存储了我们可能已经改变的变量的值,它会像什么事都没发生一样继续运行(什么事都没发生一样是指GCC不会假设寄存器装入的值是有效的,当退出改变了寄存器值的内联汇编后,寄存器的值不会保存到相应的变量或内存空间 ——译者注)。我们所可以做的是使用这些没有副作用的指令,或者当我们退出时固定这些寄存器,或者等待程序崩溃。这是为什么我们需要一些扩展功能。扩展汇编正好给我们提供了那样的功能。
-
-* * *
-
-## 5. 扩展汇编
-
-在基本内联汇编中,我们只有指令。然而在扩展汇编中,我们可以同时指定操作数。它允许我们指定输入寄存器、输出寄存器以及修饰寄存器列表。GCC 不强制用户必须指定使用的寄存器。我们可以把头疼的事留给 GCC ,这可能可以更好地适应 GCC 的优化。不管怎樣,基本格式为:
-
-> `
->
-> * * *
->
-> asm ( 汇编程序模板
-> : 输出操作数 /* 可选的 */
-> : 输入操作数 /* 可选的 */
-> : 修饰寄存器列表 /* 可选的 */
-> );
->
->
-> * * *
->
-> `
-
-汇编程序模板由汇编指令组成.每一个操作数由一个操作数约束字符串所描述,其后紧接一个括弧括起的 C 表达式。冒号用于将汇编程序模板和第一个输出操作数分开,另一个(冒号)用于将最后一个输出操作数和第一个输入操作数分开,如果存在的话。逗号用于分离每一个组内的操作数。总操作数的数目限制在10个,或者机器描述中的任何指令格式中的最大操作数数目,以较大者为准。
-
-如果没有输出操作数但存在输入操作数,你必须将两个连续的冒号放置于输出操作数原本会放置的地方周围。
-
-示例:
-
-> `
->
-> * * *
->
-> asm ("cld\n\t"
-> "rep\n\t"
-> "stosl"
-> : /* 无输出寄存器 */
-> : "c" (count), "a" (fill_value), "D" (dest)
-> : "%ecx", "%edi"
-> );
->
->
-> * * *
->
-> `
-
-现在,这段代码是干什么的?以上的内联汇编是将 `fill_value` 值 连续 `count` 次 拷贝到 寄存器 `edi` 所指位置(每执行stosl一次,寄存器 edi 的值会递增或递减,这取决于是否设置了 direction 标志,因此以上代码实则初始化一个内存块 ——译者注)。 它也告诉 gcc 寄存器 `ecx` 和 `edi` 一直无效(原文为 eax ,但代码修饰寄存器列表中为 ecx,因此这可能为作者的纰漏 ——译者注)。为了使扩展汇编更加清晰,让我们再看一个示例。
-
-> `
->
-> * * *
->
->
-> int a=10, b;
-> asm ("movl %1, %%eax;
-> movl %%eax, %0;"
-> :"=r"(b) /* 输出 */
-> :"r"(a) /* 输入 */
-> :"%eax" /* 修饰寄存器 */
-> );
->
->
-> * * *
->
-> `
-
-这里我们所做的是使用汇编指令使 ’b’ 变量的值等于 ’a’ 变量的值。一些有意思的地方是:
-
-* "b" 为输出操作数,用 %0 引用,并且 "a" 为输入操作数,用 %1 引用。
-* "r" 为操作数约束。之后我们会更详细地了解约束(字符串)。目前,"r" 告诉 GCC 可以使用任一寄存器存储操作数。输出操作数约束应该有一个约束修饰符 "=" 。这修饰符表明它是一个只读的输出操作数。
-* 寄存器名字以两个%为前缀。这有利于 GCC 区分操作数和寄存器。操作数以一个 % 为前缀。
-* 第三个冒号之后的修饰寄存器 %eax 告诉 GCC %eax的值将会在 "asm" 内部被修改,所以 GCC 将不会使用此寄存器存储任何其他值。
-
-当 "asm" 执行完毕, "b" 变量会映射到更新的值,因为它被指定为输出操作数。换句话说, "asm" 内 "b" 变量的修改 应该会被映射到 "asm" 外部。
-
-现在,我们可以更详细地看看每一个域。
-
-## 5.1 汇编程序模板
-
-汇编程序模板包含了被插入到 C 程序的汇编指令集。其格式为:每条指令用双引号圈起,或者整个指令组用双引号圈起。同时每条指令应以分界符结尾。有效的分界符有换行符(\n)和逗号(;)。’\n’ 可以紧随一个制表符(\t)。我们应该都明白使用换行符或制表符的原因了吧?和 C 表达式对应的操作数使用 %0、%1 ... 等等表示。
-
-## 5.2 操作数
-
-C 表达式用作 "asm" 内的汇编指令操作数。作为第一双引号内的操作数约束,写下每一操作数。对于输出操作数,在引号内还有一个约束修饰符,其后紧随一个用于表示操作数的 C 表达式。即,
-
-"约束字符串"(C 表达式),它是一个通用格式。对于输出操作数,还有一个额外的修饰符。约束字符串主要用于决定操作数的寻找方式,同时也用于指定使用的寄存器。
-
-如果我们使用的操作数多于一个,那么每一个操作数用逗号隔开。
-
-在汇编程序模板,每个操作数用数字引用。编号方式如下。如果总共有 n 个操作数(包括输入和输出操作数),那么第一个输出操作数编号为 0 ,逐项递增,并且最后一个输入操作数编号为 n - 1 。操作数的最大数目为前一节我们所看到的那样。
-
-输出操作数表达式必须为左值。输入操作数的要求不像这样严格。它们可以为表达式。扩展汇编特性常常用于编译器自己不知道其存在的机器指令 ;-)。如果输出表达式无法直接寻址(例如,它是一个位域),我们的约束字符串必须给定一个寄存器。在这种情况下,GCC 将会使用该寄存器作为汇编的输出,然后存储该寄存器的内容到输出。
-
-正如前面所陈述的一样,普通的输出操作数必须为只写的; GCC 将会假设指令前的操作数值是死的,并且不需要被(提前)生成。扩展汇编也支持输入-输出或者读-写操作数。
-
-所以现在我们来关注一些示例。我们想要求一个数的5次方结果。为了计算该值,我们使用 `lea` 指令。
-
-> `
->
-> * * *
->
-> asm ("leal (%1,%1,4), %0"
-> : "=r" (five_times_x)
-> : "r" (x)
-> );
->
->
-> * * *
->
-> `
-
-这里我们的输入为x。我们不指定使用的寄存器。 GCC 将会选择一些输入寄存器,一个输出寄存器,并且做我们期望的事。如果我们想要输入和输出存在于同一个寄存器里,我们可以要求 GCC 这样做。这里我们使用那些读-写操作数类型。这里我们通过指定合适的约束来实现它。
-
-> `
->
-> * * *
->
-> asm ("leal (%0,%0,4), %0"
-> : "=r" (five_times_x)
-> : "0" (x)
-> );
->
->
-> * * *
->
-> `
-
-现在输出和输出操作数位于同一个寄存器。但是我们无法得知是哪一个寄存器。现在假如我们也想要指定操作数所在的寄存器,这里有一种方法。
-
-> `
->
-> * * *
->
-> asm ("leal (%%ecx,%%ecx,4), %%ecx"
-> : "=c" (x)
-> : "c" (x)
-> );
->
->
-> * * *
->
-> `
-
-在以上三个示例中,我们并没有添加任何寄存器到修饰寄存器里,为什么?在头两个示例, GCC 决定了寄存器并且它知道发生了什么改变。在最后一个示例,我们不必将 'ecx' 添加到修饰寄存器列表(原文修饰寄存器列表拼写有错,这里已修正 ——译者注), gcc 知道它表示x。因此,因为它可以知道 `ecx` 的值,它就不被当作修饰的(寄存器)了。
-
-## 5.3 修饰寄存器列表
-
-一些指令会破坏一些硬件寄存器。我们不得不在修饰寄存器中列出这些寄存器,即汇编函数内第三个 ’**:**’ 之后的域。这可以通知 gcc 我们将会自己使用和修改这些寄存器。所以 gcc 将不会假设存入这些寄存器的值是有效的。我们不用在这个列表里列出输入输出寄存器。因为 gcc 知道 "asm" 使用了它们(因为它们被显式地指定为约束了)。如果指令隐式或显式地使用了任何其他寄存器,(并且寄存器不能出现在输出或者输出约束列表里),那么不得不在修饰寄存器列表中指定这些寄存器。
-
-如果我们的指令可以修改状态寄存器,我们必须将 "cc" 添加进修饰寄存器列表。
-
-如果我们的指令以不可预测的方式修改了内存,那么需要将 "memory" 添加进修饰寄存器列表。这可以使 GCC 不会在汇编指令间保持缓存于寄存器的内存值。如果被影响的内存不在汇编的输入或输出列表中,我们也必须添加 **volatile** 关键词。
-
-我们可以按我们的需求多次读写修饰寄存器。考虑一个模板内的多指令示例;它假设子例程 _foo 接受寄存器 `eax` 和 `ecx` 里的参数。
-
-> `
->
-> * * *
->
-> asm ("movl %0,%%eax;
-> movl %1,%%ecx;
-> call _foo"
-> : /* no outputs */
-> : "g" (from), "g" (to)
-> : "eax", "ecx"
-> );
->
->
-> * * *
->
-> `
-
-## 5.4 Volatile ...?
-
-如果你熟悉内核源码或者其他像内核源码一样漂亮的代码,你一定见过许多声明为 `volatile` 或者 `__volatile__`的函数,其跟着一个 `asm` 或者 `__asm__`。我之前提过关键词 `asm` 和 `__asm__`。那么什么是 `volatile`呢?
-
-如果我们的汇编语句必须在我们放置它的地方执行(即,不能作为一种优化被移出循环语句),将关键词 `volatile` 放置在 asm 后面,()的前面。因为为了防止它被移动、删除或者其他操作,我们将其声明为
-
-`asm volatile ( ... : ... : ... : ...);`
-
-当我们必须非常谨慎时,请使用 `__volatile__`。
-
-如果我们的汇编只是用于一些计算并且没有任何副作用,不使用 `volatile` 关键词会更好。不使用 `volatile` 可以帮助 gcc 优化代码并使代码更漂亮。
-
-
-在 `Some Useful Recipes` 一节中,我提供了多个内联汇编函数的例子。这儿我们详细查看修饰寄存器列表。
-
-* * *
-
-## 6. 更多关于约束
-
-到这个时候,你可能已经了解到约束和内联汇编有很大的关联。但我们很少说到约束。约束用于表明一个操作数是否可以位于寄存器和位于哪个寄存器;是否操作数可以为一个内存引用和哪种地址;是否操作数可以为一个立即数和为哪一个可能的值(即值的范围)。它可以有...等等。
-
-## 6.1 常用约束
-
-在许多约束中,只有小部分是常用的。我们将看看这些约束。
-
-1. **寄存器操作数约束(r)**
-
- 当使用这种约束指定操作数时,它们存储在通用寄存器(GPR)中。请看下面示例:
-
- `asm ("movl %%eax, %0\n" :"=r"(myval));`
-
- 这里,变量 myval 保存在寄存器中,寄存器 eax 的值被复制到该寄存器中,并且myval的值从寄存器更新到了内存。当指定 "r" 约束时, gcc 可以将变量保存在任何可用的 GPR 中。为了指定寄存器,你必须使用特定寄存器约束直接地指定寄存器的名字。它们为:
-
- > `
- >
- > +---+--------------------+
- > | r | Register(s) |
- > +---+--------------------+
- > | a | %eax, %ax, %al |
- > | b | %ebx, %bx, %bl |
- > | c | %ecx, %cx, %cl |
- > | d | %edx, %dx, %dl |
- > | S | %esi, %si |
- > | D | %edi, %di |
- > +---+--------------------+
- >
- >
- > `
-
-2. **内存操作数约束(m)**
-
- 当操作数位于内存时,任何对它们的操作将直接发生在内存位置,这与寄存器约束相反,后者首先将值存储在要修改的寄存器中,然后将它写回到内存位置。但寄存器约束通常用于一个指令必须使用它们或者它们可以大大提高进程速度的地方。当需要在 "asm" 内更新一个 C 变量,而又不想使用寄存器去保存它的只,使用内存最为有效。例如, idtr 的值存储于内存位置:
-
- `asm("sidt %0\n" : :"m"(loc));`
-
-3. **匹配(数字)约束**
-
- 在某些情况下,一个变量可能既充当输入操作数,也充当输出操作数。可以通过使用匹配约束在 "asm" 中指定这种情况。
-
- `asm ("incl %0" :"=a"(var):"0"(var));`
-
- 在操作数子节中,我们也看到了一些类似的示例。在这个匹配约束的示例中,寄存器 "%eax" 既用作输入变量,也用作输出变量。 var 输入被读进 %eax ,并且更新的 %eax 再次被存储进 var。这里的 "0" 用于指定与第0个输出变量相同的约束。也就是,它指定 var 输出实例应只被存储在 "%eax" 中。该约束可用于:
-
- * 在输入从变量读取或变量修改后,修改被写回同一变量的情况
- * 在不需要将输入操作数实例和输出操作数实例分开的情况
-
- 使用匹配约束最重要的意义在于它们可以导致有效地使用可用寄存器。
-
-其他一些约束:
-
-1. "m" : 允许一个内存操作数使用机器普遍支持的任一种地址。
-2. "o" : 允许一个内存操作数,但只有当地址是可偏移的。即,该地址加上一个小的偏移量可以得到一个地址。
-3. "V" : A memory operand that is not offsettable. In other words, anything that would fit the `m’ constraint but not the `o’constraint.
-4. "i" : 允许一个(带有常量)的立即整形操作数。这包括其值仅在汇编时期知道的符号常量。
-5. "n" : 允许一个带有已知数字的立即整形操作数。许多系统不支持汇编时期的常量,因为操作数少于一个字宽。对于此种操作数,约束应该使用 'n' 而不是'i'。
-6. "g" : 允许任一寄存器、内存或者立即整形操作数,不包括通用寄存器之外的寄存器。
-
-
-以下约束为x86特有。
-
-1. "r" : 寄存器操作数约束,查看上面给定的表格。
-2. "q" : 寄存器 a、b、c 或者 d。
-3. "I" : 范围从 0 到 31 的常量(对于 32 位移位)。
-4. "J" : 范围从 0 到 63 的常量(对于 64 位移位)。
-5. "K" : 0xff。
-6. "L" : 0xffff。
-7. "M" : 0, 1, 2, or 3 (lea 指令的移位)。
-8. "N" : 范围从 0 到 255 的常量(对于 out 指令)。
-9. "f" : 浮点寄存器
-10. "t" : 第一个(栈顶)浮点寄存器
-11. "u" : 第二个浮点寄存器
-12. "A" : 指定 `a` 或 `d` 寄存器。这主要用于想要返回 64 位整形数,使用 `d` 寄存器保存最高有效位和 `a` 寄存器保存最低有效位。
-
-## 6.2 约束修饰符
-
-当使用约束时,对于更精确的控制超越了约束作用的需求,GCC 给我们提供了约束修饰符。最常用的约束修饰符为:
-
-1. "=" : 意味着对于这条指令,操作数为只写的;旧值会被忽略并被输出数据所替换。
-2. "&" : 意味着这个操作数为一个早期的改动操作数,其在该指令完成前通过使用输入操作数被修改了。因此,这个操作数不可以位于一个被用作输出操作数或任何内存地址部分的寄存器。如果在旧值被写入之前它仅用作输入而已,一个输入操作数可以为一个早期改动操作数。
-
- 约束的列表和解释是决不完整的。示例可以给我们一个关于内联汇编的用途和用法的更好的理解。在下一节,我们会看到一些示例,在那里我们会发现更多关于修饰寄存器列表的东西。
-
-* * *
-
-## 7. 一些实用的诀窍
-
-现在我们已经介绍了关于 GCC 内联汇编的基础理论,现在我们将专注于一些简单的例子。将内联汇编函数写成宏的形式总是非常方便的。我们可以在内核代码里看到许多汇编函数。(usr/src/linux/include/asm/*.h)。
-
-1. 首先我们从一个简单的例子入手。我们将写一个两个数相加的程序。
-
- > `
- >
- > * * *
- >
- > int main(void)
- > {
- > int foo = 10, bar = 15;
- > __asm__ __volatile__("addl %%ebx,%%eax"
- > :"=a"(foo)
- > :"a"(foo), "b"(bar)
- > );
- > printf("foo+bar=%d\n", foo);
- > return 0;
- > }
- >
- >
- > * * *
- >
- > `
-
- 这里我们要求 GCC 将 foo 存放于 %eax,将 bar 存放于 %ebx,同时我们也想要在 %eax 中存放结果。'=' 符号表示它是一个输出寄存器。现在我们可以以其他方式将一个整数加到一个变量。
-
- > `
- >
- > * * *
- >
- > __asm__ __volatile__(
- > " lock ;\n"
- > " addl %1,%0 ;\n"
- > : "=m" (my_var)
- > : "ir" (my_int), "m" (my_var)
- > : /* 无修饰寄存器列表 */
- > );
- >
- >
- > * * *
- >
- > `
-
- 这是一个原子加法。为了移除原子性,我们可以移除指令 'lock'。在输出域中,"=m" 表明 my_var 是一个输出且位于内存。类似地,"ir" 表明 my_int 是一个整型,并应该存在于其他寄存器(回想我们上面看到的表格)。没有寄存器位于修饰寄存器列表中。
-
-2. 现在我们将在一些寄存器/变量上展示一些操作,并比较值。
-
- > `
- >
- > * * *
- >
- > __asm__ __volatile__( "decl %0; sete %1"
- > : "=m" (my_var), "=q" (cond)
- > : "m" (my_var)
- > : "memory"
- > );
- >
- >
- > * * *
- >
- > `
-
- 这里,my_var 的值减 1 ,并且如果结果的值为 0,则变量 cond 置 1。我们可以通过添加指令 "lock;\n\t" 作为汇编模板的第一条指令来添加原子性。
-
- 以类似的方式,为了增加 my_var,我们可以使用 "incl %0" 而不是 "decl %0"。
-
- 这里需要注意的点为(i)my_var 是一个存储于内存的变量。(ii)cond 位于任何一个寄存器 eax、ebx、ecx、edx。约束 "=q" 保证这一点。(iii)同时我们可以看到 memory 位于修饰寄存器列表中。也就是说,代码将改变内存中的内容。
-
-3. 如何置1或清0寄存器中的一个比特位。作为下一个诀窍,我们将会看到它。
-
- > `
- >
- > * * *
- >
- > __asm__ __volatile__( "btsl %1,%0"
- > : "=m" (ADDR)
- > : "Ir" (pos)
- > : "cc"
- > );
- >
- >
- > * * *
- >
- > `
-
- 这里,ADDR 变量(一个内存变量)的 'pos' 位置上的比特被设置为 1。我们可以使用 'btrl' 来清楚由 'btsl' 设置的比特位。pos 的约束 "Ir" 表明 pos 位于寄存器并且它的值为 0-31(x86 相关约束)。也就是说,我们可以设置/清除 ADDR 变量上第 0 到 31 位的任一比特位。因为条件码会被改变,所以我们将 "cc" 添加进修饰寄存器列表。
-
-4. 现在我们看看一些更为复杂而有用的函数。字符串拷贝。
-
- > `
- >
- > * * *
- >
- > static inline char * strcpy(char * dest,const char *src)
- > {
- > int d0, d1, d2;
- > __asm__ __volatile__( "1:\tlodsb\n\t"
- > "stosb\n\t"
- > "testb %%al,%%al\n\t"
- > "jne 1b"
- > : "=&S" (d0), "=&D" (d1), "=&a" (d2)
- > : "0" (src),"1" (dest)
- > : "memory");
- > return dest;
- > }
- >
- >
- > * * *
- >
- > `
-
- 源地址存放于 esi,目标地址存放于 edi,同时开始拷贝,当我们到达 **0** 时,拷贝完成。约束 "&S"、"&D"、"&a" 表明寄存器 esi、edi和 eax 早期的修饰寄存器,也就是说,它们的内容在函数完成前会被改变。这里很明显可以知道为什么 "memory" 会放在修饰寄存器列表。
-
- 我们可以看到一个类似的函数,它能移动双字块数据。注意函数被声明为一个宏。
-
- > `
- >
- > * * *
- >
- > #define mov_blk(src, dest, numwords) \
- > __asm__ __volatile__ ( \
- > "cld\n\t" \
- > "rep\n\t" \
- > "movsl" \
- > : \
- > : "S" (src), "D" (dest), "c" (numwords) \
- > : "%ecx", "%esi", "%edi" \
- > )
- >
- >
- > * * *
- >
- > `
-
- 这里我们没有输出,所以寄存器 ecx、esi和 edi 的内容发生改变,这是块移动的副作用。因此我们必须将它们添加进修饰寄存器列表。
-
-5. 在 Linux 中,系统调用使用 GCC 内联汇编实现。让我们看看如何实现一个系统调用。所有的系统调用被写成宏(linux/unistd.h)。例如,带有三个参数的系统调用被定义为如下所示的宏。
-
- > `
- >
- > * * *
- >
- > type name(type1 arg1,type2 arg2,type3 arg3) \
- > { \
- > long __res; \
- > __asm__ volatile ( "int $0x80" \
- > : "=a" (__res) \
- > : "0" (__NR_##name),"b" ((long)(arg1)),"c" ((long)(arg2)), \
- > "d" ((long)(arg3))); \
- > __syscall_return(type,__res); \
- > }
- >
- >
- > * * *
- >
- > `
-
- 无论何时调用带有三个参数的系统调用,以上展示的宏用于执行调用。系统调用号位于 eax 中,每个参数位于 ebx、ecx、edx 中。最后 "int 0x80" 是一条用于执行系统调用的指令。返回值被存储于 eax 中。
-
- 每个系统调用都以类似的方式实现。Exit 是一个单一参数的系统调用,让我们看看它的代码看起来会是怎样。它如下所示。
-
- > `
- >
- > * * *
- >
- > {
- > asm("movl $1,%%eax; /* SYS_exit is 1 */
- > xorl %%ebx,%%ebx; /* Argument is in ebx, it is 0 */
- > int $0x80" /* Enter kernel mode */
- > );
- > }
- >
- >
- > * * *
- >
- > `
-
- Exit 的系统调用号是 1 同时它的参数是 0。因此我们分配 eax 包含 1,ebx 包含 0,同时通过 `int $0x80` 执行 `exit(0)`。这就是 exit 的工作原理。
-
-* * *
-
-## 8. 结束语
-
-这篇文档已经将 GCC 内联汇编过了一遍。一旦你理解了基本概念,你便不难采取自己的行动。我们看了许多例子,它们有助于理解 GCC 内联汇编的常用特性。
-
-GCC 内联是一个极大的主题,这篇文章是不完整的。更多关于我们讨论过的语法细节可以在 GNU 汇编器的官方文档上获取。类似地,对于一个完整的约束列表,可以参考 GCC 的官方文档。
-
-当然,Linux 内核 大规模地使用 GCC 内联。因此我们可以在内核源码中发现许多各种各样的例子。它们可以帮助我们很多。
-
-如果你发现任何的错别字,或者本文中的信息已经过时,请告诉我们。
-
-* * *
-
-## 9. 参考
-
-1. [Brennan’s Guide to Inline Assembly](http://www.delorie.com/djgpp/doc/brennan/brennan_att_inline_djgpp.html)
-2. [Using Assembly Language in Linux](http://linuxassembly.org/articles/linasm.html)
-3. [Using as, The GNU Assembler](http://www.gnu.org/manual/gas-2.9.1/html_mono/as.html)
-4. [Using and Porting the GNU Compiler Collection (GCC)](http://gcc.gnu.org/onlinedocs/gcc_toc.html)
-5. [Linux Kernel Source](http://ftp.kernel.org/)
-
-* * *
-via: http://www.ibiblio.org/gferg/ldp/GCC-Inline-Assembly-HOWTO.html
-
- 作者:[Sandeep.S](mailto:busybox@sancharnet.in) 译者:[cposture](https://github.com/cposture) 校对:[]()
-
-本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创翻译,[Linux中国](http://linux.cn/) 荣誉推出
diff --git a/translated/tech/20160218 How to Best Manage Encryption Keys on Linux.md b/translated/tech/20160218 How to Best Manage Encryption Keys on Linux.md
deleted file mode 100644
index b833d94658..0000000000
--- a/translated/tech/20160218 How to Best Manage Encryption Keys on Linux.md
+++ /dev/null
@@ -1,110 +0,0 @@
-Linux 如何最好地管理加密密钥
-=============================================
-
-![](http://www.linux.com/images/stories/41373/key-management-diagram.png)
-
-存储 SSH 的加密秘钥以及记住密码一直是一个让人头疼的问题。但是不幸的是,在当前充满了恶意黑客和攻击的世界中,基本的安全预警是必不可少的。对于大量的普通用户,它相当于简单地记住密码,也可能寻找一个好程序去存储密码,正如我们提醒这些用户不要在每个网站都有相同的密码。但是对于在各个 IT 领域的我们,我们需要将这个提高一个层次。我们不得不处理加密秘钥,比如 SSH 密钥,而不只是密码。
-
-设想一个场景:我有一个运行在云上的服务器,用于我的主 git 库。我有很多台工作电脑。所有电脑都需要登陆中央服务器去 push 与 pull。我设置 git 使用 SSH。当 git 使用 SSH, git 实际上以相同的方式登陆服务器,就好像你通过 SSH 命令打开一个服务器的命令行。为了配置所有内容,我在我的 .ssh 目录下创建一个配置文件,其中包含一个有服务器名字,主机名,登陆用户,密钥文件的路径的主机项。之后我可以通过输入命令来测试这个配置。
-
->ssh gitserver
-
-很快我得到了服务器的 bash shell。现在我可以配置 git 使用相同项与存储的密钥来登陆服务器。很简单,除了一个问题,对于每一个我用于登陆服务器的电脑,我需要有一个密钥文件。那意味着需要不止一个密钥文件。当前这台电脑和我的其他电脑都存储有这些密钥文件。同样的,用户每天有特大量的密码,对于我们 IT人员,很容易结束这特大量的密钥文件。怎么办呢?
-
-## 清理
-
-在开始使用程序去帮助你管理你的密钥之前,你不得不在你的密码应该怎么处理和我们问的问题是否有意义这两个方面打下一些基础。同时,这需要第一,也是最重要的,你明白你的公钥和私钥的使用位置。我将设想你知道:
-
-1. 公钥和私钥之间的差异;
-
-2. 为什么你不可以从公钥生成私钥,但是你可以逆向生成?
-
-3. `authorized_keys` 文件的目的以及它的内容;
-
-4. 你如何使用私钥去登陆服务器,其中服务器上的 `authorized_keys` 文件中存有相应的公钥;
-
-这里有一个例子。当你在亚马逊的网络服务上创建一个云服务器,你必须提供一个 SSH 密码,用于连接你的服务器。每一个密钥有一个公开的部分,和私密的部分。因为你想保持你的服务器安全,乍看之下你可能要将你的私钥放到服务器上,同时你自己带着公钥。毕竟,你不想你的服务器被公开访问,对吗?但是实际上这是逆向的。
-
-你把自己的公钥放到 AWS 服务器,同时你持有你自己的私钥用于登陆服务器。你保护私钥,同时保持私钥在自己一方,而不是在一些远程服务器上,正如上图中所示。
-
-原因如下:如果公钥公之于众,他们不可以登陆服务器,因为他们没有私钥。进一步说,如果有人成功攻入你的服务器,他们所能找到的只是公钥。你不可以从公钥生成私钥。同时如果你在其他的服务器上使用相同的密钥,他们不可以使用它去登陆别的电脑。
-
-这就是为什么你把你自己的公钥放到你的服务器上以便通过 SSH 登陆这些服务器。你持有这些私钥,不要让这些私钥脱离你的控制。
-
-但是还有麻烦。试想一下我 git 服务器的例子。我要做一些决定。有时我登陆架设在别的地方的开发服务器。在开发服务器上,我需要连接我的 git 服务器。如何使我的开发服务器连接 git 服务器?通过使用私钥。同时这里面还有麻烦。这个场景需要我把私钥放置到一个架设在别的地方的服务器上。这相当危险。
-
-一个进一步的场景:如果我要使用一个密钥去登陆许多的服务器,怎么办?如果一个入侵者得到这个私钥,他或她将拥有私钥,并且得到服务器的全部虚拟网络的权限,同时准备做一些严重的破坏。这一点也不好。
-
-同时那当然会带来一个别的问题,我真的应该在这些其他服务器上使用相同的密钥?因为我刚才描述的,那会非常危险的。
-
-最后,这听起来有些混乱,但是有一些简单的解决方案。让我们有条理地组织一下:
-
-(注意你有很多地方需要密钥登陆服务器,但是我提出这个作为一个场景去向你展示当你处理密钥的时候你面对的问题)
-
-## 关于口令句
-
-当你创建你的密钥时,你可以选择是否包含一个口令字,这个口令字会在使用私钥的时候是必不可少的。有了这个口令字,私钥文件本身会被口令字加密。例如,如果你有一个公钥存储在服务器上,同时你使用私钥去登陆服务器的时候,你会被提示,输入口令字。没有口令字,这个密钥是无法使用的。或者,你可以配置你的密钥不需要口令字。然后所有你需要的只是用于登陆服务器的密钥文件。
-
-普遍上,不使用口令字对于用户来说是更容易的,但是我强烈建议在很多情况下使用口令字,原因是,如果私钥文件被偷了,偷密钥的人仍然不可以使用它,除非他或者她可以找到口令字。在理论上,这个将节省你很多时间,因为你可以在攻击者发现口令字之前,从服务器上删除公钥文件,从而保护你的系统。还有一些别的原因去使用口令字,但是这个原因对我来说在很多场合更有价值。(举一个例子,我的 Android 平板上有 VNC 软件。平板上有我的密钥。如果我的平板被偷了之后,我会马上从服务器上删除公钥,使得它的私钥没有作用,无论有没有口令字。)但是在一些情况下我不使用口令字,是因为我正在登陆的服务器上没有什么有价值的数据。它取决于情境。
-
-## 服务器基础设施
-
-你如何设置自己服务器的基础设置将会影响到你如何管理你的密钥。例如,如果你有很多用户登陆,你将需要决定每个用户是否需要一个单独的密钥。(普遍来说,他们应该;你不会想要用户之间共享私钥。那样当一个用户离开组织或者失去信任时,你可以删除那个用户的公钥,而不需要必须给其他人生成新的密钥。相似地,通过共享密钥,他们能以其他人的身份登录,这就更坏了。)但是另外一个问题,你如何配置你的服务器。你是否使用工具,比如 Puppet,配置大量的服务器?同时你是否基于你自己的镜像创建大量的服务器?当你复制你的服务器,你是否需要为每个人设置相同的密钥?不同的云服务器软件允许你配置这个;你可以让这些服务器使用相同的密钥,或者给每一个生成一个新的密钥。
-
-如果你在处理复制的服务器,它可能导致混淆如果用户需要使用不同的密钥登陆两个不同的系统。但是另一方面,服务器共享相同的密钥会有安全风险。或者,第三,如果你的密钥有除了登陆之外的需要(比如挂载加密的驱动),之后你会在很多地方需要相同的密钥。正如你所看到的,你是否需要在不同的服务器上使用相同的密钥不是我为你做的决定;这其中有权衡,而且你需要去决定什么是最好的。
-
-最终,你可能会有:
-
-- 需要登录的多个服务器
-
-- 多个用户登陆不同的服务器,每个都有自己的密钥
-
-- 每个用户多个密钥当他们登陆不同的服务器的时候
-
-(如果你正在别的情况下使用密钥,相同的普遍概念会应用于如何使用密钥,需要多少密钥,他们是否共享,你如何处理密钥的私密部分和公开部分。)
-
-## 安全方法
-
-知道你的基础设施和独一无二的情况,你需要组合一个密钥管理方案,它会引导你去分发和存储你的密钥。比如,正如我之前提到的,如果我的平板被偷了,我会从我服务器上删除公钥,期望在平板在用于访问服务器。同样的,我会在我的整体计划中考虑以下内容:
-
-1. 移动设备上的私钥没有问题,但是必须包含口令字;
-
-2. 必须有一个方法可以快速地从服务器上删除公钥。
-
-在你的情况中,你可能决定,你不想在自己经常登录的系统上使用口令字;比如,这个系统可能是一个开发者一天登录多次的测试机器。这没有问题,但是你需要调整你的规则。你可能添加一条规则,不可以通过移动设备登录机器。换句话说,你需要根据自己的状况构建你的协议,不要假设某个方案放之四海而皆准。
-
-## 软件
-
-至于软件,毫不意外,现实世界中并没有很多好的,可用的软件解决方案去存储和管理你的私钥。但是应该有吗?考虑到这个,如果你有一个程序存储你所有服务器的全部密钥,并且这个程序被一个核心密钥锁住,那么你的密钥就真的安全了吗?或者,同样的,如果你的密钥被放置在你的硬盘上,用于 SSH 程序快速访问,那样一个密钥管理软件是否真正提供了任何保护吗?
-
-但是对于整体基础设施和创建,管理公钥,有许多的解决方案。我已经提到了 Puppet。在 Puppet 的世界中,你创建模块来以不同的方式管理你的服务器。这个想法是服务器是动态的,而且不必要准确地复制其他机器。[这里有一个聪明的途径](http://manuel.kiessling.net/2014/03/26/building-manageable-server-infrastructures-with-puppet-part-4/),它在不同的服务器上使用相同的密钥,但是对于每一个用户使用不同的 Puppet 模块。这个方案可能适合你,也可能不适合你。
-
-或者,另一个选项就是完全换挡。在 Docker 的世界中,你可以采取一个不同的方式,正如[关于 SSH 和 Docker 博客](http://blog.docker.com/2014/06/why-you-dont-need-to-run-sshd-in-docker/)所描述的。
-
-但是怎么样管理私钥?如果你搜索,你无法找到很多的软件选择,原因我之前提到过;密钥存放在你的硬盘上,一个管理软件可能无法提到很多额外的安全。但是我确实使用这种方法来管理我的密钥:
-
-首先,我的 `.ssh/config` 文件中有很多的主机项。我有一个我登陆的主机项,但是有时我对于一个单独的主机有不止一项。如果我有很多登陆,那种情况就会发生。对于架设我的 git 库的服务器,我有两个不同的登陆项;一个限制于 git,另一个为普遍目的的 bash 访问。这个为 git 设置的登陆选项在机器上有极大的限制。还记得我之前说的关于我存在于远程开发机器上的 git 密钥吗?好了。虽然这些密钥可以登陆到我其中一个服务器,但是使用的账号是被严格限制的。
-
-其次,大部分的私钥都包含口令字。(对于处理不得不多次输入口令字的情况,考虑使用 [ssh-agent](http://blog.docker.com/2014/06/why-you-dont-need-to-run-sshd-in-docker/)。)
-
-再次,我确实有许多服务器,我想要更加小心地防御,并且在我 host 文件中并没有这样的项。这更加接近于社交工程方面,因为密钥文件还存在于那里,但是可能需要攻击者花费更长的时间去定位这个密钥文件,分析出来他们攻击的机器。在这些例子中,我只是手动打出来长的 SSH 命令。(这真不怎么坏。)
-
-同时你可以看出来我没有使用任何特别的软件去管理这些私钥。
-
-## 无放之四海而皆准的方案
-
-我们偶然间收到 linux.com 的问题,关于管理密钥的好软件的建议。但是让我们后退一步。这个问题事实上需要重新定制,因为没有一个普适的解决方案。你问的问题基于你自己的状况。你是否简单地尝试找到一个位置去存储你的密钥文件?你是否寻找一个方法去管理多用户问题,其中每个人都需要将他们自己的公钥插入到 `authorized_keys` 文件中?
-
-通过这篇文章,我已经囊括了基础知识,希望到此你明白如何管理你的密钥,并且,只有当你问了正确的问题,无论你寻找任何软件(甚至你需要另外的软件),它都会出现。
-
-------------------------------------------------------------------------------
-
-via: http://www.linux.com/learn/tutorials/838235-how-to-best-manage-encryption-keys-on-linux
-
-作者:[Jeff Cogswell][a]
-译者:[mudongliang](https://github.com/mudongliang)
-校对:[校对者ID](https://github.com/校对者ID)
-
-本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创翻译,[Linux中国](https://linux.cn/) 荣誉推出
-
-[a]:http://www.linux.com/community/forums/person/62256
diff --git a/translated/tech/20160219 How to Setup Lighttpd Web server on Ubuntu 15.04 or CentOS 7.md b/translated/tech/20160219 How to Setup Lighttpd Web server on Ubuntu 15.04 or CentOS 7.md
deleted file mode 100644
index 8840e8b973..0000000000
--- a/translated/tech/20160219 How to Setup Lighttpd Web server on Ubuntu 15.04 or CentOS 7.md
+++ /dev/null
@@ -1,210 +0,0 @@
-[Translated] Haohong Wang
-如何在Ubuntu 15.04/CentOS 7中安装Lighttpd Web server
-=================================================================================
-Lighttpd 是一款开源Web服务器软件。Lighttpd 安全快速,符合行业标准,适配性强并且针对高配置环境进行了优化。Lighttpd因其CPU、内存占用小,针对小型CPU加载的快速适配以及出色的效率和速度而从众多Web服务器中脱颖而出。 而Lighttpd诸如FastCGI,CGI,Auth,Out-Compression,URL-Rewriting等高级功能更是那些低配置的服务器的福音。
-
-以下便是在我们运行Ubuntu 15.04 或CentOS 7 Linux发行版的机器上安装Lighttpd Web服务器的简要流程。
-
-### 安装Lighttpd
-
-#### 使用包管理器安装
-
-这里我们通过使用包管理器这种最简单的方法来安装Lighttpd。只需以sudo模式在终端或控制台中输入下面的指令即可。
-
-**CentOS 7**
-
-由于CentOS 7.0官方repo中并没有提供Lighttpd,所以我们需要在系统中安装额外的软件源epel repo。使用下面的yum指令来安装epel。
-
- # yum install epel-release
-
-然后,我们需要更新系统及进程为Lighttpd的安装做准备。
-
- # yum update
- # yum install lighttpd
-
-![Install Lighttpd Centos](http://blog.linoxide.com/wp-content/uploads/2016/02/install-lighttpd-centos.png)
-
-**Ubuntu 15.04**
-
-Ubuntu 15.04官方repo中包含了Lighttpd,所以只需更新本地repo并使用apt-get指令即可安装Lighttpd。
-
- # apt-get update
- # apt-get install lighttpd
-
-![Install lighttpd ubuntu](http://blog.linoxide.com/wp-content/uploads/2016/02/install-lighttpd-ubuntu.png)
-
-#### 从源代码安装Lighttpd
-
-如果想从Lighttpd源码安装最新版本(例如1.4.39),我们需要在本地编译源码并进行安装。首先我们要安装编译源码所需的依赖包。
-
- # cd /tmp/
- # wget http://download.lighttpd.net/lighttpd/releases-1.4.x/lighttpd-1.4.39.tar.gz
-
-下载完成后,执行下面的指令解压缩。
-
- # tar -zxvf lighttpd-1.4.39.tar.gz
-
-然后使用下面的指令进行编译。
-
- # cd lighttpd-1.4.39
- # ./configure
- # make
-
-**注:**在这份教程中,我们安装的是默认配置的Lighttpd。其他诸如高级功能或拓展功能,如对SSL的支持,mod_rewrite,mod_redirect等,需自行配置。
-
-当编译完成后,我们就可以把它安装到系统中了。
-
- # make install
-
-### 设置Lighttpd
-
-如果有更高的需求,我们可以通过修改默认设置文件,如`/etc/lighttpd/lighttpd.conf`,来对Lighttpd进行进一步设置。 而在这份教程中我们将使用默认设置,不对设置文件进行修改。如果你曾做过修改并想检查设置文件是否出错,可以执行下面的指令。
-
- # lighttpd -t -f /etc/lighttpd/lighttpd.conf
-
-#### 使用 CentOS 7
-
-在CentOS 7中,我们需在Lighttpd默认设置中创设一个例如`/src/www/htdocs`的webroot文件夹。
-
- # mkdir -p /srv/www/htdocs/
-
-而后将默认欢迎页面从`/var/www/lighttpd`复制至刚刚新建的目录中:
-
- # cp -r /var/www/lighttpd/* /srv/www/htdocs/
-
-### 开启服务
-
-现在,通过执行systemctl指令来重启数据库服务。
-
- # systemctl start lighttpd
-
-然后我们将它设置为伴随系统启动自动运行。
-
- # systemctl enable lighttpd
-
-### 设置防火墙
-
-如要让我们运行在Lighttpd上的网页和网站能在Internet或相似的网络上被访问,我们需要在防火墙程序中设置打开80端口。由于CentOS 7和Ubuntu15.04都附带Systemd作为默认初始化系统,所以我们安装firewalld作为解决方案。如果要打开80端口或http服务,我们只需执行下面的命令:
-
- # firewall-cmd --permanent --add-service=http
- success
- # firewall-cmd --reload
- success
-
-### 连接至Web Server
-在将80端口设置为默认端口后,我们就可以默认直接访问Lighttpd的欢迎页了。我们需要根据运行Lighttpd的设备来设置浏览器的IP地址和域名。在本教程中,我们令浏览器指向 [http://lighttpd.linoxide.com/](http://lighttpd.linoxide.com/) 同时将子域名指向它的IP地址。如此一来,我们就可以在浏览器中看到如下的欢迎页面了。
-
-![Lighttpd Welcome Page](http://blog.linoxide.com/wp-content/uploads/2016/02/lighttpd-welcome-page.png)
-
-此外,我们可以将网站的文件添加到webroot目录下,并删除lighttpd的默认索引文件,使我们的静态网站链接至互联网上。
-
-如果想在Lighttpd Web Server中运行PHP应用,请参考下面的步骤:
-
-### 安装PHP5模块
-在Lighttpd成功安装后,我们需要安装PHP及相关模块以在Lighttpd中运行PHP5脚本。
-
-#### 使用 Ubuntu 15.04
-
- # apt-get install php5 php5-cgi php5-fpm php5-mysql php5-curl php5-gd php5-intl php5-imagick php5-mcrypt php5-memcache php-pear
-
-#### 使用 CentOS 7
-
- # yum install php php-cgi php-fpm php-mysql php-curl php-gd php-intl php-pecl-imagick php-mcrypt php-memcache php-pear lighttpd-fastcgi
-
-### 设置Lighttpd的PHP服务
-
-如要让PHP与Lighttpd协同工作,我们只要根据所使用的发行版执行如下对应的指令即可。
-
-#### 使用 CentOS 7
-
-首先要做的便是使用文件编辑器编辑php设置文件(例如`/etc/php.ini`)并取消掉对**cgi.fix_pathinfo=1**的注释。
-
- # nano /etc/php.ini
-
-完成上面的步骤之后,我们需要把PHP-FPM进程的所有权从Apache转移至Lighttpd。要完成这些,首先用文件编辑器打开`/etc/php-fpm.d/www.conf`文件。
-
- # nano /etc/php-fpm.d/www.conf
-
-然后在文件中增加下面的语句:
-
- user = lighttpd
- group = lighttpd
-
-做完这些,我们保存并退出文本编辑器。然后从`/etc/lighttpd/modules.conf`设置文件中添加FastCGI模块。
-
- # nano /etc/lighttpd/modules.conf
-
-然后,去掉下面语句前面的`#`来取消对它的注释。
-
- include "conf.d/fastcgi.conf"
-
-最后我们还需在文本编辑器设置FastCGI的设置文件。
-
- # nano /etc/lighttpd/conf.d/fastcgi.conf
-
-在文件尾部添加以下代码:
-
- fastcgi.server += ( ".php" =>
- ((
- "host" => "127.0.0.1",
- "port" => "9000",
- "broken-scriptfilename" => "enable"
- ))
- )
-
-在编辑完成后保存并退出文本编辑器即可。
-
-#### 使用 Ubuntu 15.04
-
-如需启用Lighttpd的FastCGI,只需执行下列代码:
-
- # lighttpd-enable-mod fastcgi
-
- Enabling fastcgi: ok
- Run /etc/init.d/lighttpd force-reload to enable changes
-
- # lighttpd-enable-mod fastcgi-php
-
- Enabling fastcgi-php: ok
- Run `/etc/init.d/lighttpd` force-reload to enable changes
-
-然后,执行下列命令来重启Lighttpd。
-
- # systemctl force-reload lighttpd
-
-### 检测PHP工作状态
-
-如需检测PHP是否按预期工作,我们需在Lighttpd的webroot目录下新建一个php文件。本教程中,在Ubuntu下/var/www/html 目录,CentOS下/src/www/htdocs目录下使用文本编辑器创建并打开info.php。
-
-**使用 CentOS 7**
-
- # nano /var/www/info.php
-
-**使用 Ubuntu 15.04**
-
- # nano /srv/www/htdocs/info.php
-
-然后只需将下面的语句添加到文件里即可。
-
-
-
-在编辑完成后保存并推出文本编辑器即可。
-
-现在,我们需根据路径 [http://lighttpd.linoxide.com/info.php](http://lighttpd.linoxide.com/info.php) 下的info.php文件的IP地址或域名,来让我们的网页浏览器指向系统上运行的Lighttpd。如果一切都按照以上说明进行,我们将看到如下图所示的PHP页面信息。
-
-![phpinfo lighttpd](http://blog.linoxide.com/wp-content/uploads/2016/02/phpinfo-lighttpd.png)
-
-### 总结
-
-至此,我们已经在CentOS 7和Ubuntu 15.04 Linux 发行版上成功安装了轻巧快捷并且安全的Lighttpd Web服务器。现在,我们已经可以利用Lighttpd Web服务器来实现上传网站文件到网站根目录,配置虚拟主机,启用SSL,连接数据库,运行Web应用等功能了。 如果你有任何疑问,建议或反馈请在下面的评论区中写下来以让我们更好的改良Lighttpd。谢谢!(译注:评论网址 http://linoxide.com/linux-how-to/setup-lighttpd-web-server-ubuntu-15-04-centos-7/ )
---------------------------------------------------------------------------------
-
-via: http://linoxide.com/linux-how-to/setup-lighttpd-web-server-ubuntu-15-04-centos-7/
-
-作者:[Arun Pyasi][a]
-译者:[HaohongWANG](https://github.com/HaohongWANG)
-校对:[校对者ID](https://github.com/校对者ID)
-
-本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
-
-[a]:http://linoxide.com/author/arunp/
diff --git a/translated/tech/20160301 The Evolving Market for Commercial Software Built On Open Source.md b/translated/tech/20160301 The Evolving Market for Commercial Software Built On Open Source.md
deleted file mode 100644
index c45b3eb760..0000000000
--- a/translated/tech/20160301 The Evolving Market for Commercial Software Built On Open Source.md
+++ /dev/null
@@ -1,36 +0,0 @@
-构建在开源之上的商业软件市场持续成长
-=====================================================================
-
-![](https://www.linux.com/images/stories/41373/Structure-event-photo.jpg)
-> 与会者在 Structure 上听取演讲,Structure Data 2016 也将在 UCSF Mission Bay 会议中心举办。图片来源:Structure Events。
-
-如今真的很难低估开源项目对于企业软件市场的影响;开源集成如此快速地形成了规范,我们没能捕捉到转折点也情有可原。
-
-举个例子,Hadoop,改变的不止是数据分析的世界。它引领了新一代数据公司,它们围绕开源项目创造自己的软件,按需调整和支持那些代码,更像红帽在 90 年代和 21 世纪早期拥抱 Linux 那样。软件越来越多地通过公有云交付,而不是购买者自己的服务器,拥有了令人惊奇的操作灵活性,但同时也带来了一些关于授权,支持以及价格之类的新问题。
-
-我们多年来持续追踪这个趋势,它们组成了我们的 Structure Data 会议,而 Structure Data 2016 也不例外。三家围绕 Hadoop 最重要的大数据公司——Hortonworks,Cloudera 和 MapR——的 CEO 将会共同讨论它们是如何销售他们围绕开源项目的企业软件和服务,获利的同时回报那个社区项目。
-
-以前在企业软件上获利是很容易的事情。一个客户购买了之后,企业供应商的一系列大型软件就变成了它自己的收银机,从维护合同和阶段性升级中获得近乎终生的收入,软件也越来越难以被替代,因为它已经成为了客户的业务核心。客户抱怨这种绑定,但如果它们想提高工作队伍的生产力也确实没有多少选择。
-
-而现在的情况不再是这样了。尽管无数的公司还陷于在他们的基础设施上运行至关重要的巨大软件包,新的项目被使用开源技术部署到云服务器上。这让升级功能不再需要去掉大量软件包再重新安装别的,同时也让公司按需付费,而不是为一堆永远用不到的特性买单。
-
-有很多客户想要利用开源项目的优势,而又不想建立和支持一支工程师队伍来调整开源项目以满足自己的需求。这些客户愿意为开源项目和在这之上的专有特性之间的差异付费。
-
-这对于基础设施相关的软件来说格外正确。当然,你的客户们可以安装他们自己对项目的调整,比如 Hadoop,Spark 或 Node.js,但付费可以帮助他们自定义包部署如今重要的开源技术而不用自己干这些活儿。只需看看 Structure Data 2016 的发言者就明白了,比如 Confluent(Kafka),Databricks(Spark),以及 Cloudera-Hortonworks-MapR(Hadoop)三人组。
-
-当然还有一个值得提到的是在出错的时候有个供应商给你指责。如果你的工程师弄糟了开源项目的实现,那你只能怪你自己了。但是如果你和一个愿意保证在服务级别的特定性能和正常运行时间指标的公司签订了合同,你就是愿意为支持,指导,以及在突然出现不可避免的问题时朝你公司外的人发火的机会买单。
-
-构建在开源之上的商业软件市场的持续成长是我们在 Structure Data 上追踪多年的内容,如果这个话题正合你意,我们鼓励你加入我们,在旧金山,3 月 9 日和 10 日。
-
-
---------------------------------------------------------------------------------
-
-via: https://www.linux.com/news/enterprise/cloud-computing/889564-the-evolving-market-for-commercial-software-built-on-open-source-
-
-作者:[Tom Krazit ][a]
-译者:[alim0x](https://github.com/alim0x)
-校对:[校对者ID](https://github.com/校对者ID)
-
-本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
-
-[a]: https://www.linux.com/community/forums/person/70513
diff --git a/translated/tech/20160303 Top 5 open source command shells for Linux.md b/translated/tech/20160303 Top 5 open source command shells for Linux.md
deleted file mode 100644
index d40eb58b54..0000000000
--- a/translated/tech/20160303 Top 5 open source command shells for Linux.md
+++ /dev/null
@@ -1,86 +0,0 @@
-最牛的五个Linux开源command shell
-===============================================
-
-关键字: shell , Linux , bash , zsh , fish , ksh , tcsh , license
-
-![](https://opensource.com/sites/default/files/styles/image-full-size/public/images/business/terminal_blue_smoke_command_line_0.jpg?itok=u2mRRqOa)
-
-这个世界上有两种Linux用户:敢于冒险的和态度谨慎的。
-
-其中一类用户总是本能的去尝试任何能够戳中其痛点的新选择。他们尝试过不计其数的窗口管理器、系统发行版和几乎所有能找到的桌面插件。
-
-另一类用户找到他们喜欢的东西后,会一直使用下去。他们往往喜欢所使用的系统发行版的默认选项。最先熟练掌握的文本编辑器会成为他们最钟爱的那一个。
-
-作为一个使用桌面版和服务器版十五年之久的Linux用户,比起第一类来,我无疑属于第二类用户。我更倾向于使用现成的东西,如此一来,很多时候我就可以通过文档和示例方便地找到我所需要的使用案例。如果我决定选择使用非费标准的东西,这个切换过程一定会基于细致的研究,并且前提是来自挚友的大力推荐。
-
-但这并不意味着我不喜欢尝试新事物并且查漏补失。所以最近一段时间,在我不假思索的使用了bash shell多年之后,决定尝试一下另外四个shell工具:ksh, tcsh, zsh, 和 fish. 这四个shell都可以通过我所以用的Fedora系统的默认库轻松安装,并且他们可能已经内置在你所使用的系统发行版当中了。
-
-这里对每个选择都稍作介绍,并且阐述下它适合做为你的下一个Linux命令行解释器的原因所在。
-
-### bash
-
-首先,我们回顾一下最为熟悉的一个。 [GNU Bash][1],又名 Bourne Again Shell,它是我这些年使用过的众多Linux发行版的默认选择。它最初发布于1989年,并且轻松成长为Linux世界中使用最广泛的shell,甚至常见于其他一些类Unix系统当中。
-
-Bash是一个广受赞誉的shell,当你通过互联网寻找各种事情解决方法所需的文档时,总能够无一例外的发现这些文档都默认你使用的是bash shell。但Bash也有一些缺点存在,如果你写过Bash脚本就会发现我们写的代码总是得比真正所需要的多那么几行。这并不是说有什么事情是它做不到的,而是说它读写起来并不总是那么直观,至少是不够优雅。
-
-如上所述,基于其巨大的安装量,并且考虑到各类专业和非专业系统管理员已经适应了它的使用方式和独特之处,至少在将来一段时间内,bash或许会一直存在。
-
-### ksh
-
-[KornShell][4],或许你对这个名字并不熟悉,但是你一定知道它的调用命令 ksh。这个替代性的shell于80年代起源于贝尔实验室,由David Korn所写。虽然最初是一个专有软件,但是后期版本是在[Eclipse Public 许可][5]下发布的。
-
-ksh的拥趸们列出了他们觉得其优越的诸多理由,包括更好的循环语法,清晰的管道退出代码,更简单的方式来处理重复命令和关联数组。它能够模拟vi和emacs的许多行为,所以如果你是一个重度文本编辑器患者,它值得你一试。最后,我发现它虽然在高级脚本方面拥有不同的体验,但在基本输入方面与bash如出一辙。
-
-### tcsh
-
-[Tcsh][6]衍生于csh(Berkely Unix C shell),并且可以追溯到早期的Unix和计算本身。
-
-Tcsh最大的卖点在于它的脚本语言,对于熟悉C语言编程的人来说,看起来会非常亲切。Tcsh的脚本编写有人喜欢,有人憎恶。但是它也有其他的技术特色,包括可以为aliases添加参数,各种可能迎合你偏好的默认行为,包括tab自动完成和将tab完成的工作记录下来以备后查。
-
-你可以在[BSD 许可][7]下找到tcsh。
-
-### zsh
-
-[Zsh][8]是另外一个与bash和ksh有着相似之处的shell。产生于90年代初,zsh支持众多有用的新技术,包括拼写纠正,主题化,可命名的目录快捷键,在多个终端中分享命令历史信息和各种相对于original Bourne shell的轻微调整。
-
-虽然部分需要遵照GPL许可,但zsh的代码和二进制文件可以在MIT-like许可下进行分发; 你可以在 [actual license][9] 中查看细节。
-
-### fish
-
-之前我访问了[fish][10]的主页,当看到 “好了,这是一个为90年代而生的命令行shell” 这条略带调侃的介绍时(fish完成于2005年),我就意识到我会爱上这个交互友好的shell的。
-
-Fish的作者提供了若干切换过来的理由,shell中所有的不太实用的调用都有点小幽默并且能戳中笑点。这些特性包括自动建议("Watch out, Netscape Navigator 4.0"),支持“惊人”的256色VGA调色,不过也有真正有用的特性,包括根据机器的man页面自动补全命令,清除脚本和基于web的配置。
-
-Fish的许可主要基于第二版GPL,但有些部分是在其他许可下的。你可以查看资源库来了解[完整信息][11]
-
-***
-
-如果你想要寻找关于每个选择确切不同之处的详尽纲要,[这个网站][12]应该可以帮到你。
-
-我的立场到底是怎样的呢?好吧,最终我应该还是会重新投入bash的怀抱,因为对于大多数时间都在使用命令行交互的人来说,切换过程对于高级脚本能带来的好处微乎其微,并且我已经习惯于使用bash了。
-
-但是我很庆幸做出了敞开大门并且尝试新选择的决定。我知道门外还有许许多多其他的东西。你尝试过哪些shell,更中意哪一个?请在评论里告诉我们。
-
-本文来源: https://opensource.com/business/16/3/top-linux-shells
-
-作者:[Jason Baker][a]
-译者:[mr-ping](https://github.com/mr-ping)
-校对:[校对者ID](https://github.com/校对者ID)
-
-本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
-
-[a]:https://opensource.com/users/jason-baker
-
-[1]: https://www.gnu.org/software/bash/
-[2]: http://mywiki.wooledge.org/BashPitfalls
-[3]: http://www.gnu.org/licenses/gpl.html
-[4]: http://www.kornshell.org/
-[5]: https://www.eclipse.org/legal/epl-v10.html
-[6]: http://www.tcsh.org/Welcome
-[7]: https://en.wikipedia.org/wiki/BSD_licenses
-[8]: http://www.zsh.org/
-[9]: https://sourceforge.net/p/zsh/code/ci/master/tree/LICENCE
-[10]: https://fishshell.com/
-[11]: https://github.com/fish-shell/fish-shell/blob/master/COPYING
-[12]: http://hyperpolyglot.org/unix-shells
-
diff --git a/translated/tech/20160425 How to Use Awk to Print Fields and Columns in File.md b/translated/tech/20160425 How to Use Awk to Print Fields and Columns in File.md
deleted file mode 100644
index 127cc061c1..0000000000
--- a/translated/tech/20160425 How to Use Awk to Print Fields and Columns in File.md
+++ /dev/null
@@ -1,109 +0,0 @@
-ictlyh Translating
-How to Use Awk to Print Fields and Columns in File
-===================================================
-
-In this part of our [Linux Awk command series][1], we shall have a look at one of the most important features of Awk, which is field editing.
-
-It is good to know that Awk automatically divides input lines provided to it into fields, and a field can be defined as a set of characters that are separated from other fields by an internal field separator.
-
-![](http://www.tecmint.com/wp-content/uploads/2016/04/Awk-Print-Fields-and-Columns.png)
->Awk Print Fields and Columns
-
-If you are familiar with the Unix/Linux or do [bash shell programming][2], then you should know what internal field separator (IFS) variable is. The default IFS in Awk are tab and space.
-
-This is how the idea of field separation works in Awk: when it encounters an input line, according to the IFS defined, the first set of characters is field one, which is accessed using $1, the second set of characters is field two, which is accessed using $2, the third set of characters is field three, which is accessed using $3 and so forth till the last set of character(s).
-
-To understand this Awk field editing better, let us take a look at the examples below:
-
-**Example 1**: I have created a text file called tecmintinfo.txt.
-
-```
-# vi tecmintinfo.txt
-# cat tecmintinfo.txt
-```
-
-![](http://www.tecmint.com/wp-content/uploads/2016/04/Create-File-in-Linux.png)
->Create File in Linux
-
-Then from the command line, I try to print the first, second and third fields from the file tecmintinfo.txt using the command below:
-
-```
-$ awk '//{print $1 $2 $3 }' tecmintinfo.txt
-TecMint.comisthe
-```
-
-From the output above, you can see that the characters from the first three fields are printed based on the IFS defined which is space:
-
-- Field one which is “TecMint.com” is accessed using $1.
-- Field two which is “is” is accessed using $2.
-- Field three which is “the” is accessed using $3.
-
-If you have noticed in the printed output, the field values are not separated and this is how print behaves by default.
-
-To view the output clearly with space between the field values, you need to add (,) operator as follows:
-
-```
-$ awk '//{print $1, $2, $3; }' tecmintinfo.txt
-
-TecMint.com is the
-```
-
-One important thing to note and always remember is that the use of ($) in Awk is different from its use in shell scripting.
-
-Under shell scripting ($) is used to access the value of variables while in Awk ($) it is used only when accessing the contents of a field but not for accessing the value of variables.
-
-**Example 2**: Let us take a look at one other example using a file which contains multiple lines called my_shoping.list.
-
-```
-No Item_Name Unit_Price Quantity Price
-1 Mouse #20,000 1 #20,000
-2 Monitor #500,000 1 #500,000
-3 RAM_Chips #150,000 2 #300,000
-4 Ethernet_Cables #30,000 4 #120,000
-```
-
-Say you wanted to only print Unit_Price of each item on the shopping list, you will need to run the command below:
-
-```
-$ awk '//{print $2, $3 }' my_shopping.txt
-
-Item_Name Unit_Price
-Mouse #20,000
-Monitor #500,000
-RAM_Chips #150,000
-Ethernet_Cables #30,000
-```
-
-Awk also has a printf command that helps you to format your output is a nice way as you can see the above output is not clear enough.
-
-Using printf to format output of the Item_Name and Unit_Price:
-
-```
-$ awk '//{printf "%-10s %s\n",$2, $3 }' my_shopping.txt
-
-Item_Name Unit_Price
-Mouse #20,000
-Monitor #500,000
-RAM_Chips #150,000
-Ethernet_Cables #30,000
-```
-
-### Summary
-
-Field editing is very important when using Awk to filter text or strings, it helps you get particular data in columns in a list. And always remember that the use of ($) operator in Awk is different from that in shell scripting.
-
-I hope the article was helpful to you and for any additional information required or questions, you can post a comment in the comment section.
-
---------------------------------------------------------------------------------
-
-via: http://www.tecmint.com/awk-print-fields-columns-with-space-separator/?utm_source=feedburner&utm_medium=feed&utm_campaign=Feed%3A+tecmint+%28Tecmint%3A+Linux+Howto%27s+Guide%29
-
-作者:[Aaron Kili][a]
-译者:[译者ID](https://github.com/译者ID)
-校对:[校对者ID](https://github.com/校对者ID)
-
-本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
-
-[a]: http://www.tecmint.com/author/aaronkili/
-[1]: http://www.tecmint.com/tag/awk-command/
-[2]: http://www.tecmint.com/category/bash-shell/
diff --git a/translated/tech/20160502 The intersection of Drupal, IoT, and open hardware.md b/translated/tech/20160502 The intersection of Drupal, IoT, and open hardware.md
deleted file mode 100644
index 7cfffd953f..0000000000
--- a/translated/tech/20160502 The intersection of Drupal, IoT, and open hardware.md
+++ /dev/null
@@ -1,62 +0,0 @@
-Drupal, IoT 和开源硬件的交叉点
-=======================================================
-
-![](https://opensource.com/sites/default/files/styles/image-full-size/public/images/business/drupal_blue_gray_lead.jpeg?itok=t7W_KD-D)
-
-
-认识一下 [Amber Matz][1],来自由 Lullabot Education 提供的 [Drupalize.Me][3] 的生产经理以及培训师。当她没有倒腾 Arduino,Raspberry Pi 以及电子穿戴设备时,通常会在波特兰 Drupal 用户组里和主持人争论。
-
-在即将举行的 [DrupalCon NOLA][3] 大会上,Amber 将主持一个关于 Drupal 和 IoT 的主题。如果你会去参加,也想了解下开源硬件,IoT 和 Drupal 之间的交叉点,那这个将很合适。如果你去不了新奥尔良的现场也没关系,Amber 还分享了许多很酷的事情。在这次采访中,她讲述了自己参与 Drupal 的原因,一些她自己喜欢的开源硬件项目,以及 IoT 和 Drupal 的未来。
-
-![](https://opensource.com/sites/default/files/images/life/Interview%20banner%20Q%26A.png)
-
-**你是怎么加入 Drupal 社区的?**
-
-在这之前,我在一家大型非盈利性机构市场部的“站长办公室”工作,大量产出没人喜欢的定制 PHP/MySQL 表格。终于我觉得这样很烦并开始在网上寻找更好的方式。然后我找到了 Drupal 6 并开始自己沉迷进去。多年以后,在准备职业转换的时候,发现了波特兰 Drupal 用户组,然后在里面找了一份全职的 Drupal 开发者工作。我一直经常参加在波特兰的聚会,我觉得它是一种很好的社区,交友,以及专业开发的资源。一个偶然的机会,我在 Lullabot 找了一份培训师的工作为 Drupalize.Me 提供内容。现在,我管理着 Drupalize.Me 的内容管道,创建 Drupal 8 的内容,还很大程度地参与到波特兰 Drupal 社区中。我是今年的协调员,寻找并规划演讲者。
-
-**我们得明白:什么是 Arduino 原型,你是怎么找到它的,以及你用 Arduino 做过的最酷的事是什么?**
-
-Arduino,Raspberry Pi,以及可穿戴电子设备,这些年到处都能听到这些术语。我在几年前通过 Becky Stern YouTube 秀(最近由 Becky 继续主持,每周三播出)发现了 [Adafruit 的可穿戴电子设备][4]。我被那些可穿戴设备迷住了,还订了一套 LED 缝制工具,不过没做出任何东西。我就是没搞懂。我没有任何电子相关的背景,而且在我被那些项目吸引的时候,我根本不知道怎么做出那样的东西。看上去太遥远了。
-
-后来,我找到一个 Coursera 的“物联网”专题。(很时髦,对吧?)但我很快就喜欢上了。我最终找到了 Arduino 是什么的解释,以及所有这些其他的重要术语和概念。我订了一套推荐的 Arduino 初学者套件,还附带了一本如何上手的小册子。当我第一次让 LED 闪烁的时候,开心极了。我在圣诞节以及之后有两个星期的假期,然后我什么都没干,就一直根据初学者小册子给 Arduino 电路编程。很奇怪我觉得很放松!我太喜欢了。
-
-一月份的时候,我开始构思我自己的原型设备。在知道我要主持公司培训的开场白时,我用五个 LED 灯和 Arduino 搭建了一个开场白视觉计时器。
-
-![](https://opensource.com/sites/default/files/resize/amber-arduino-lightning-talk-timer-400x400.jpg)
-
-这是一次巨大的成功。我还做了我的第一个可穿戴项目,一件会发光的连帽衫,使用了和 Arduino IDE 兼容的 Gemma 微控制器,一个小的圆形可缝制部件,然后用可导电的线缝起来,将一个滑动可变电阻和衣服帽口的收缩绳连在一起,用来控制缝到帽子里的五个 NeoPixel 灯的颜色。这就是我对原型设计的看法:开展一些很好玩也可能会有点实际用途的疯狂项目。
-
-**Drupal 和 IoT 带来的最大机遇是什么??**
-
-IoT 和网站服务以及 Drupal 分层趋势实际并没有太大差别。就是将数据从一个物体传送到另一个物体,然后将数据转换成一些有用的东西。但数据是如何送达?能用来做点什么?你觉得现在就有一大堆现成的解决方案,应用,中间层,以及 API?采用 IoT,这只会继续成指数增长。我觉得,给我任何一个设备或“物体”,需要只用一种方式来将它连接到因特网的无线可能上。然后有现成的各种代码库来帮助制作者将他们的数据从一个物体送到另一个物体。
-
-那么 Drupal 在这里处于什么位置?首先,网站服务将是第一个明显的地方。但作为一个制作者,我不希望将时间花在编写 Drupal 的订制模块上。我想要的是即插即用!所以我很高兴出现这样的模块能连接 IoT 云端 API 和服务,比如 ThingSpeak,Adafruit.io,IFTTT,以及其他的。我觉得也有一个很好的商业机会,在 Drupal 里构建一套 IoT 云服务,允许用户发送和存储他们的传感器数据,并可以制成表格和图像,还可以写一些插件可以响应特定数据或阙值。每一个 IoT 云 API 服务都是一个细分的机会,所以能留下很大空间给其他人。
-
-**这次 DrupalCon 你有哪些期待?**
-
-我喜欢重新联系 Drupal 上的朋友,认识一些新的人,还能见到 Lullabot 和 Drupalize.Me 的同事(我们是分布式的公司)!Drupal 8 有太多东西可以去探索了,不可抗拒地要帮我们的客户收集培训资料。所以,我很期待参与一些 Drupal 8 相关的主题,以及跟上最新的开发活动。最后,我对新奥尔良也很感兴趣!我曾经在 2004 年去过,很期待将这次将看到哪些改变。
-
-**谈一谈你这次 DrupalCon 上的演讲,超越闪烁:将 Drupal 加到你的 IoT 游乐场中。别人为什么要参与?他们最重要的收获会是什么?**
-
-我的主题的标题是,超越闪烁:将 Drupal 加到你的 IoT 游乐场中,本身有很多假设,我将让所有人都放在同一速度和层次。你不需要了解任何关于 Arduino,物联网,甚至是 Drupal,都能跟上。我将从用 Arduino 让 LED 灯闪烁开始,然后我会谈一下我自己在这里面的最大收获:玩,学,教,和做。我会列出一些曾经激发过我的例子,它们也很有希望能激发和鼓励其他听众去尝试一下。然后,就是展示时间!
-
-首先,第一个东西。它是一个构建提醒信号灯。在这个展示里,我会说明如何将信号灯连到互联网上,以及如何响应从云 API 服务收到的数据。然后,第二个东西。它是一个蒸汽朋克风格 iPhone 外壳形式的“天气手表”。有一个小型 LED 矩阵用来显示我的天气的图标,一个气压和温度传感器,一个 GPS 模块,以及一个 Bluetooth LE 模块,都连接到一个 Adafruit Flora 微控制器上。第二个东西能通过蓝牙连接到我的 iPhone 上的一个应用,并将天气和位置数据通过 MQTT 协议发到 Adafruit.io 的服务器!然后,在 Drupal 这边,我会从云端下载这些数据,根据天气更新一个功能块,然后更新地图。所以大家也能体验一下通过网站服务,地图和 Drupal 8 的功能块所能做的事情。
-
-学习和制作这些展示原型是一次烧脑的探险,我也希望有人能参与这个主题并感染一点我对这个技术交叉的传染性热情!我很兴奋能分享一些我的发现。
-
-
-------------------------------------------------------------------------------
-
-via: https://opensource.com/business/16/5/drupalcon-interview-amber-matz
-
-作者:[Jason Hibbets][a]
-译者:[zpl1025](https://github.com/zpl1025)
-校对:[校对者ID](https://github.com/校对者ID)
-
-本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创翻译,[Linux中国](https://linux.cn/) 荣誉推出
-
-[a]: https://opensource.com/users/jhibbets
-[1]: https://www.drupal.org/u/amber-himes-matz
-[2]: https://drupalize.me/
-[3]: https://events.drupal.org/neworleans2016/
-[4]: https://www.adafruit.com/beckystern
diff --git a/translated/tech/20160511 An introduction to data processing with Cassandra and Spark.md b/translated/tech/20160511 An introduction to data processing with Cassandra and Spark.md
deleted file mode 100644
index 0786996e39..0000000000
--- a/translated/tech/20160511 An introduction to data processing with Cassandra and Spark.md
+++ /dev/null
@@ -1,49 +0,0 @@
-Cassandra 和 Spark 数据处理入门
-==============================================================
-
-![](https://opensource.com/sites/default/files/styles/image-full-size/public/images/life/osdc_520x292_opendata_0613mm.png?itok=mzC0Tb28)
-
-Apache Cassandra 数据库近来引起了很多的兴趣,这主要源于现代云端软件对于可用性及性能方面的要求。
-
-那么,Apache Cassandra 是什么?它是一种为高可用性及线性可扩展性优化的分布式的联机交易处理 (OLTP) 数据库。当人们想知道 Cassandra 的用途时,可以想想你想要的离客户近的系统。这j最终是我们的用户进行交互的系统。需要保证实时可用的程序:产品目录,IoT,医疗系统,以及移动应用。对这些程序而言,下线时间意味着利润降低甚至导致其他更坏的结果。Netfilix 是这个于2008年开源的项目的早期使用者,他们对此项目的贡献以及带来的成功让这个项目名声大噪。
-
-Cassandra 于2010年成为了 Apache 软件基金会的顶级项目,在这之后就开始变得流行。现在,只要你有 Cassadra 的相关知识,找工作时就能轻松不少。光是想想一个 NoSQL 语言和开源技术能达到如此企业级 SQL 的高度就觉得这是十分疯狂而又不可思议的。这引出了一个问题。是什么让它如此的流行?
-
-因为采用了首先在[亚马逊发表的 Dynamo 论文][1]提出的设计,Cassandra 有能力在大规模的硬件及网络故障时保持实时在线。由于采用了点对点模式,在没有单点故障的情况下,我们能幸免于机架故障甚至完全网络分区。我们能在不影响用户体验的前提下处理数据中心故障。一个能考虑到故障的分布式系统才是一个没有后顾之忧的分布式系统,因为老实说,故障是迟早会发生的。有了 Cassandra, 我们可疑直面残酷的生活并将之融入数据库的结构和功能中。
-
-
-
-我们能猜到你现在在想什么,“但我只有关系数据库相关背景,难道这样的转变不会很困难吗?"这问题的答案介于是和不是之间。使用 Cassandra 建立数据模型对有关系数据库背景的开发者而言是轻车熟路。我们使用表格来建立数据模型,并使用 CQL 或者 Cassandra 查询语言来查询数据库。然而,与 SQL 不同的是,Cassandra 支持更加复杂的数据结构,例如多重和用户自定义类型。举个例子,当要储存对一个小猫照片的点赞数目时,我们可以将整个数据储存在一个包含照片本身的集合之中从而获得更快的顺序查找而不是建立一个独立的表。这样的表述在 CQL 中十分的自然。在我们照片表中,我们需要记录名字,URL以及给此照片点赞过的人。
-
-![](https://opensource.com/sites/default/files/resize/screen_shot_2016-05-06_at_7.17.33_am-350x198.png)
-
-在一个高性能系统中,毫秒对用户体验和客户保留都能产生影响。昂贵的 JOIN 制约了我们通过增加不可预见的网络调用而扩容的能力。当我们将数据反规范化使其能在尽可能少的请求中被获取到时,我们即可从磁盘空间花费的降低中获益并获得可预测的,高性能应用。我们将反规范化同 Cassandra 一同介绍是因为它提供了很有吸引力的的折衷方案。
-
-很明显,我们不会局限于对于小猫照片的点赞数量。Canssandra 是一款个为并发高写入优化的方案。这使其成为需要时常吞吐数据的大数据应用的理想解决方案。市场上的时序和 IoT 的使用场景正在以稳定的速度在需求和亮相方面增加,我们也在不断探寻优化我们所收集到的数据以求提升我们的技术应用(注:这句翻的非常别扭,求校队)
-
-
-这就引出了我们的下一步,我们已经提到了如何以一种现代的,性价比高的方式储存数据,但我们应该如何获得更多的马力呢?具体而言,当我们收集到了所需的数据,我们应该怎样处理呢?如何才能有效的分析几百 TB 的数据呢?如何才能在实时的对我们所收集到的信息进行反馈并在几秒而不是几小时的时间利作出决策呢?Apache Spark 将给我们答案。
-
-
-Spark 是大数据变革中的下一步。 Hadoop 和 MapReduce 都是革命性的产品,他们让大数据界获得了分析所有我们所取得的数据的机会。Spark 对性能的大幅提升及对代码复杂度的大幅降低则将大数据分析提升到了另一个高度。通过 Spark,我们能大批量的处理计算,对流处理进行快速反映,通过机器学习作出决策并理解通过对图的遍历理解复杂的递归关系。这并非只是为你的客户提供与快捷可靠的应用程序连接(Cassandra 已经提供了这样的功能),这更是能一探 Canssandra 所储存的数据并作出更加合理的商业决策同时更好地满足客户需求。
-
-你可以看看 [Spark-Cassandra Connector][2] (open source) 并动手试试。若想了解更多关于这两种技术的信息,我们强烈推荐名为 [DataStax Academy][3] 的自学课程
-
---------------------------------------------------------------------------------
-
-via: https://opensource.com/life/16/5/basics-cassandra-and-spark-data-processing
-
-作者:[Jon Haddad][a],[Dani Traphagen][b]
-译者:[KevinSJ](https://github.com/KevinSJ)
-校对:[校对者ID](https://github.com/校对者ID)
-
-本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
-
-[a]: https://twitter.com/rustyrazorblade
-[b]: https://opensource.com/users/dtrapezoid
-[1]: http://www.allthingsdistributed.com/files/amazon-dynamo-sosp2007.pdf
-[2]: https://github.com/datastax/spark-cassandra-connector
-[3]: https://academy.datastax.com/
-[4]: http://conferences.oreilly.com/oscon/open-source-us/public/schedule/detail/49162
-[5]: https://twitter.com/dtrapezoid
-[6]: https://twitter.com/rustyrazorblade
diff --git a/translated/tech/20160519 The future of sharing integrating Pydio and ownCloud.md b/translated/tech/20160519 The future of sharing integrating Pydio and ownCloud.md
deleted file mode 100644
index bf5a25c77e..0000000000
--- a/translated/tech/20160519 The future of sharing integrating Pydio and ownCloud.md
+++ /dev/null
@@ -1,65 +0,0 @@
-分享的未来:整合 Pydio 与 ownCloud
-=========================================================
-
-![](https://opensource.com/sites/default/files/styles/image-full-size/public/images/business/BIZ_darwincloud_520x292_0311LL.png?itok=5yWIaEDe)
->图片来源 :
-opensource.com
-
-开源共享生态圈内容纳了许多各异的项目,他们每一个都能提供出自己的解决方案,且每一个都不按套路来。有很多原因导致你选择开源的解决方案,而非 Dropbox、Google Drive、iCloud 或 OneDrive 这些商业的解决方案。这些商业的解决方案虽然能让你不必为如何管理数据担心,但也理所应当的带着种种限制,其中就包含对于原有基础结构的控制和整合不足。
-
-对于用户而言仍有相当一部分文件分享和同步的替代品可供选择,其中就包括了 Pydio 和 ownCloud。
-
-### Pydio
-
-Pydio (Put your data in orbit 把你的数据放上轨道) 项目由一位作曲家 Charles du Jeu 发起,起初他也只是需要一种与乐队成员分享大型音频文件的方法。[Pydio][1] 是一种文件分享与同步的解决方案,综合了多存储后端,设计时还同时考虑了开发者和系统管理员两方面。在世界各地有逾百万的下载量,已被翻译成 27 种语言。
-
-项目在很开始的时候便开源了,先是在 [SourceForge][2] 上茁壮的成长,现在已在 [GitHub][3] 上安了家.。
-
-用户界面基于 Google 的 [Material 设计][4]。用户可以使用现有的传统的文件基础结构或是本地部署 Pydio,并通过 web、桌面和移动端应用随时随地地管理自己的东西。对于管理员来说,细粒度的访问权限绝对是配置访问时的利器。
-
-在 [Pydio 社区][5],你可以找到许多让你增速的资源。Pydio 网站 [对于如何为 Pydio GitHub 仓库贡献][6] 给出了明确的指导方案。[论坛][7]中也包含了开发者板块和社区。
-
-### ownCloud
-
-[ownCloud][8] 在世界各地拥有逾 8 百万的用户,并且开源,支持自托管文件同步,且共享技术。同步客户端支持所有主流平台并支持 WebDAV 通过 web 界面实现。ownCloud 拥有简单的使用界面,强大的管理工具,和大规模的共享及协作功能——以满足用户管理数据时的需求。
-
-ownCloud 的开放式架构是通过 API 和为应用提供平台来实现可扩展性的。迄今已有逾 300 款应用,功能包括处理像日历、联系人、邮件、音乐、密码、笔记等诸多数据类型。ownCloud 由一个数百位贡献者的国际化的社区开发,安全,并且能做到为小到一个树莓派大到好几百万用户的 PB 级存储集群量身定制。
-
-### 联合共享 (Federated sharing)
-
-文件共享开始转向团队合作时代,而标准化为合作提供了坚实的土壤。
-
-联合共享——一个由 [OpenCloudMesh][9] 项目提供的新开放标准,就是在这个方向迈出的一步。先不说别的,在支持该标准的服务端上,可以像 Pydio 和 ownCloud 那样分享文件和文件夹。
-
-ownCloud 7 率先引入,这种服务端到服务端的分享方式可以让你挂载远程服务端上共享的文件,实际上就是创建你所有云的云。你可以直接创建共享链接,让用户在其他支持联合云共享的服务端上使用。
-
-实现这个新的 API 允许存储解决方案之间更深层次的集成,同时保留了原有平台的安全,控制和属性。
-
-“交换和共享文件是当下和未来不可或缺的东西。”ownCloud 的创始人 Frank Karlitschek 说道:“正因如此,采用联合和分布的方式而非集中的数据孤岛就显得至关重要。[联合共享]的设计初衷便是在保证安全和用户隐私的同时追求分享的无缝、至简之道。”
-
-### 下一步是什么呢?
-
-正如 OpenCloudMesh 做的那样,将会通过像 Pydio 和 ownCloud 这样的机构和公司,合作推广这一文件共享的新开放标准。ownCloud 9 已经引入联合服务端间交换用户列表的功能,让你的用户在你的服务器上享有和你同样的无缝体验。将来,一个中央地址簿服务(联合!)集合,用以检索其他联合云 ID 的想法可能会把云间合作推向一个新的高度。
-
-这一举措无疑有助于日益开放的技术社区中的那些成员方便地讨论,开发,并推动“OCM 分享 API”作为一个厂商中立协议。所有领导 OCM 项目的合作伙伴都全心致力于开放 API 的设计原理,并欢迎其他开源的文件分享和同步社区参与并加入其中。
-
---------------------------------------------------------------------------------
-
-via: https://opensource.com/business/16/5/sharing-files-pydio-owncloud
-
-作者:[ben van 't ende][a]
-译者:[martin2011qi](https://github.com/martin2011qi)
-校对:[校对者ID](https://github.com/校对者ID)
-
-本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
-
-[a]: https://opensource.com/users/benvantende
-[1]: https://pydio.com/
-[2]: https://sourceforge.net/projects/ajaxplorer/
-[3]: https://github.com/pydio/
-[4]: https://www.google.com/design/spec/material-design/introduction.html
-[5]: https://pydio.com/en/community
-[6]: https://pydio.com/en/community/contribute
-[7]: https://pydio.com/forum/f
-[8]: https://owncloud.org/
-[9]: https://wiki.geant.org/display/OCM/Open+Cloud+Mesh
diff --git a/translated/tech/20160524 Writing online multiplayer game with python and asyncio - part 1.md b/translated/tech/20160524 Writing online multiplayer game with python and asyncio - part 1.md
new file mode 100644
index 0000000000..26ddea6b1e
--- /dev/null
+++ b/translated/tech/20160524 Writing online multiplayer game with python and asyncio - part 1.md
@@ -0,0 +1,71 @@
+使用python 和asyncio编写在线多人游戏 - 第1部分
+===================================================================
+
+你曾经把async和python关联起来过吗?在这里我将告诉你怎样做,而且在[working example][1]这个例子里面展示-一个流行的贪吃蛇游戏,这是为多人游戏而设计的。
+[Play game][2]
+
+###1.简介
+
+在技术和文化领域,大量的多人在线游戏毋庸置疑是我们这个世界的主流之一。同时,为一个MMO游戏写一个服务器一般和大量的预算与低水平的编程技术相关,在最近这几年,事情发生了很大的变化。基于动态语言的现代框架允许在稳健的硬件上面处理大量并发的用户连接。同时,HTML5 和 WebSockets 标准允许基于实时的图形游戏直接在web浏览器上创建客户端,而不需要任何的扩展。
+
+对于创建可扩展非堵塞的服务器,Python可能不是最受欢迎的工具,尤其是和在这个领域最受欢迎的node.js相比。但是最近版本的python打算改变这种现状。[asyncio][3]的介绍和一个特别的[async/await][4] 语法使得异步代码看起来像常规的阻塞代码,这使得python成为一个值得信赖的异步编程语言。所以我将尝试利用这些新特点来创建一个多人在线游戏。
+
+###2.异步
+一个游戏服务器应该处理最大数量的用户的并发连接和实时处理这些连接。一个典型的解决方案----创建线程,然而在这种情况下并不能解决这个问题。运行上千的线程需要CPU在它们之间不停的切换(这叫做上下文切换),这将开销非常大,效率很低下。更糟糕的是,因为,此外,它们会占用大量的内存。在python中,还有一个问题,python的解释器(CPython)并不是针对多线程设计的,它主要针对于单线程实现最大数量的行为。这就是为什么它使用GIL(global interpreter lock),一个不允许同时运行多线程python代码的架构,来防止共享物体的不可控用法。正常情况下当当前线程正在等待的时候,解释器转换到另一个线程,通常是一个I/O的响应(像一个服务器的响应一样)。这允许在你的应用中有非阻塞I/O,因为每一个操作仅仅堵塞一个线程而不是堵塞整个服务器。然而,这也使得通常的多线程变得无用,因为它不允许你并发执行python代码,即使是在多核心的cpu上。同时在单线程中拥有非阻塞IO是完全有可能的,因而消除了经常切换上下文的需要。
+
+实际上,你可以用纯python代码来实现一个单线程的非阻塞IO。你所需要的只是标准的[select][5]模块,这个模块可以让你写一个事件循环来等待未阻塞的socket的io。然而,这个方法需要你在一个地方定义所有app的逻辑,不久之后,你的app就会变成非常复杂的状态机。有一些框架可以简化这个任务,比较流行的是[tornade][6] 和 [twisted][7]。他们被用来使用回调方法实现复杂的协议(这和node.js比较相似)。这个框架运行在他自己的事件循环中,这个事件在定义的事件上调用你的回调。并且,这或许是一些情况的解决方案,但是它仍然需要使用回调的方式编程,这使你的代码碎片化。和写同步代码并且并发执行多个副本相比,就像我们会在普通的线程上做一样。这为什么在单个线程上是不可能的呢?
+
+这就是为什么microthread出现的原因。这个想法是为了在一个线程上并发执行任务。当你在一个任务中调用阻塞的方法时,有一个叫做"manager" (或者“scheduler”)的东西在执行事件循环。当有一些事件准备处理的时候,一个manager会让等这个事件的“任务”单元去执行,直到自己停了下来。然后执行完之后就返回那个管理器(manager)。
+
+>Microthreads are also called lightweight threads or green threads (a term which came from Java world). Tasks which are running concurrently in pseudo-threads are called tasklets, greenlets or coroutines.(Microthreads 也会被称为lightweight threads 或者 green threads(java中的一个术语)。在伪线程中并发执行的任务叫做tasklets,greenlets或者coroutines).
+
+microthreads的其中一种实现在python中叫做[Stackless Python][8]。这个被用在了一个叫[EVE online][9]的非常有名的在线游戏中,所以它变得非常有名。这个MMO游戏自称说在一个持久的宇宙中,有上千个玩家在做不同的活动,这些都是实时发生的。Stackless 是一个单独的python解释器,它代替了标准的栈调用并且直接控制流来减少上下文切换的开销。尽管这非常有效,这个解决方案不如使用标准解释器的“soft”库有名。像[eventlet][10]和[gevent][11] 的方式配备了标准的I / O库的补丁的I / O功能在内部事件循环执行。这使得将正常的阻塞代码转变成非阻塞的代码变得简单。这种方法的一个缺点是从代码看这并不明显,这被称为非阻塞。Python的新的版本介绍了本地协同程序作为生成器的高级形式。在Python 的3.4版本中,引入了asyncio库,这个库依赖于本地协同程序来提供单线程并发。但是在Python 3.5 协同程序变成了Python语言的一部分,使用新的关键字 async 和 await 来描述。这是一个简单的例子,这表明了使用asyncio来运行 并发任务。
+
+```
+import asyncio
+
+async def my_task(seconds):
+ print("start sleeping for {} seconds".format(seconds))
+ await asyncio.sleep(seconds)
+ print("end sleeping for {} seconds".format(seconds))
+
+all_tasks = asyncio.gather(my_task(1), my_task(2))
+loop = asyncio.get_event_loop()
+loop.run_until_complete(all_tasks)
+loop.close()
+```
+
+我们启动了两个任务,一个睡眠1秒钟,另一个睡眠2秒钟,输出如下:
+
+```
+start sleeping for 1 seconds
+start sleeping for 2 seconds
+end sleeping for 1 seconds
+end sleeping for 2 seconds
+```
+
+正如你所看到的,协同程序不会阻塞彼此-----第二个任务在第一个结束之前启动。这发生的原因是asyncio.sleep是协同程序,它会返回一个调度器的执行直到时间过去。在下一节中,
+我们将会使用coroutine-based的任务来创建一个游戏循环。
+
+--------------------------------------------------------------------------------
+
+via: https://7webpages.com/blog/writing-online-multiplayer-game-with-python-asyncio-getting-asynchronous/
+
+作者:[Kyrylo Subbotin][a]
+译者:[xinglianfly](https://github.com/xinglianfly)
+校对:[校对者ID](https://github.com/校对者ID)
+
+本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
+
+[a]: https://7webpages.com/blog/writing-online-multiplayer-game-with-python-asyncio-getting-asynchronous/
+[1]: http://snakepit-game.com/
+[2]: http://snakepit-game.com/
+[3]: https://docs.python.org/3/library/asyncio.html
+[4]: https://docs.python.org/3/whatsnew/3.5.html#whatsnew-pep-492
+[5]: https://docs.python.org/2/library/select.html
+[6]: http://www.tornadoweb.org/
+[7]: http://twistedmatrix.com/
+[8]: http://www.stackless.com/
+[9]: http://www.eveonline.com/
+[10]: http://eventlet.net/
+[11]: http://www.gevent.org/
diff --git a/translated/tech/20160602 How to mount your Google Drive on Linux with google-drive-ocamlfuse.md b/translated/tech/20160602 How to mount your Google Drive on Linux with google-drive-ocamlfuse.md
deleted file mode 100644
index b64fa51ab0..0000000000
--- a/translated/tech/20160602 How to mount your Google Drive on Linux with google-drive-ocamlfuse.md
+++ /dev/null
@@ -1,68 +0,0 @@
-教你用 google-drive-ocamlfuse 在 Linux 上挂载 Google Drive
-=====================
-
->如果你在找一个方便的方式在 Linux 机器上挂载你的 Google Drive 文件夹, Jack Wallen 将教你怎么使用 google-drive-ocamlfuse 来挂载 Google Drive。
-
-![](http://tr4.cbsistatic.com/hub/i/2016/05/18/ee5d7b81-e5be-4b24-843d-d3ca99230a63/651be96ac8714698f8100afa6883e64d/linuxcloudhero.jpg)
->图片来源: Jack Wallen
-
-Google 还没有发行 Linux 版本的 Google Drive 应用,尽管现在有很多方法从 Linux 中访问你的 Drive 文件。
-(注:不清楚 app 需不需要翻译成应用,这里翻译了)
-
-如果你喜欢界面化的工具,你可以选择 Insync。如果你喜欢用命令行,这有很多工具,像 Grive2 和用 Ocaml 语言编写的、非常容易使用的、基于 FUSE 的系统(注:there are tools such as Grive2 and the incredibly easy to use FUSE-based system written in Ocaml. 这一句感觉翻译不出来)。我将会用后面这种方式演示如何在 Linux 桌面上挂载你的 Google Drive。尽管这是通过命令行完成的,但是它的用法会简单到让你吃惊。它太简单了以至于谁都能做到。
-
-系统特点:
-
-- 对普通文件/文件夹有完全的读写权限
-- 对于 Google Docs,sheets,slides 这三个应用只读
-- 能够访问 Drive 回收站(.trash)
-- 处理重复文件功能
-- 支持多个帐号
-
-接下来完成 google-drive-ocamlfuse 在 Ubuntu 16.04 桌面的安装,然后你就能够访问云盘上的文件了。
-
-### 安装
-
-1. 打开终端。
-2. 用`sudo add-apt-repository ppa:alessandro-strada/ppa`命令添加必要的 PPA
-3. 出现提示的时候,输入密码并按下回车。
-4. 用`sudo apt-get update`命令更新应用。
-5. 输入`sudo apt-get install google-drive-ocamlfuse`命令安装软件。
-(注:这里,我把所有的命令加上着重标记了)
-
-### 授权
-
-接下来就是授权 google-drive-ocamlfuse,让它有权限访问你的 Google 账户。先回到终端窗口敲下命令 google-drive-ocamlfuse,这个命令将会打开一个浏览器窗口,它会提示你登陆你的 Google 帐号或者如果你已经登陆了 Google 帐号,它会询问是否允许 google-drive-ocamlfuse 访问 Google 账户。如果你还没有登陆,先登陆然后点击允许。接下来的窗口(在 Ubuntu 16.04 桌面上会出现,但不会出现在基本系统 Freya 桌面上)将会询问你是否授给 gdfuse 和 OAuth2 Endpoint访问你的 Google 账户的权限,再次点击允许。然后出现的窗口就会告诉你等待授权令牌下载完成,这个时候就能最小化浏览器了。当你的终端提示像图 A 一样的内容,你就能知道令牌下载完了,并且你已经可以挂载 Google Drive 了。
-
-**图 A**
-
-![](http://tr4.cbsistatic.com/hub/i/r/2016/05/18/a493122b-445f-4aca-8974-5ec41192eede/resize/620x/6ae5907ad2c08dc7620b7afaaa9e389c/googledriveocamlfuse3.png)
->图片来源: Jack Wallen
-
-**应用已经得到授权,你可以进行后面的工作。**
-
-### 挂载 Google Drive
-
-在挂载 Google Drive 之前,你得先创建一个文件夹,作为挂载点。在终端里,敲下`mkdir ~/google-drive`命令在你的家目录下创建一个新的文件夹。最后敲下命令`google-drive-ocamlfuse ~/google-drive`将你的 Google Drive 挂载到 google-drive 文件夹中。
-
-这时你可以查看本地 google-drive 文件夹中包含的 Google Drive 文件/文件夹。你能够把 Google Drive 当作本地文件系统来进行工作。
-
-当你想 卸载 google-drive 文件夹,输入命令 `fusermount -u ~/google-drive`。
-
-### 没有 GUI,但它特别好用
-
-我发现这个特别的系统非常容易使用,在同步 Google Drive 时它出奇的快,并且这可以作为一种巧妙的方式备份你的 Google Drive 账户。
-
-试试 google-drive-ocamlfuse,看看你能用它做出什么有趣的事。
-
---------------------------------------------------------------------------------
-
-via: http://www.techrepublic.com/article/how-to-mount-your-google-drive-on-linux-with-google-drive-ocamlfuse/
-
-作者:[Jack Wallen ][a]
-译者:[GitFuture](https://github.com/GitFuture)
-校对:[校对者ID](https://github.com/校对者ID)
-
-本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
-
-[a]: http://www.techrepublic.com/search/?a=jack+wallen
diff --git a/translated/tech/20160602 Web Service Efficiency at Instagram with Python.md b/translated/tech/20160602 Web Service Efficiency at Instagram with Python.md
new file mode 100644
index 0000000000..b35fad81eb
--- /dev/null
+++ b/translated/tech/20160602 Web Service Efficiency at Instagram with Python.md
@@ -0,0 +1,78 @@
+Instagram Web 服务效率与 Python
+===============================================
+
+Instagram 目前是世界上最大规模部署 Django web 框架(该框架完全使用 Python 编写)的主角。我们最初选用 Python 是因为它久负盛名的简洁性与实用性,这非常符合我们的哲学思想——“先做简单的事情”。但简洁性也会带来效率方面的折衷。Instagram 的规模在过去两年中已经翻番,并且最近已突破 5 亿用户,所以急需最大程度地提升 web 服务效率以便我们的平台能够继续顺利地扩大。在过去的一年,我们已经将效率计划(efficiency program)提上日程,并在过去的六个月,我们已经能够做到无需向我们的 Django 层(Django tiers)添加新的容量来维护我们的用户增长。我们将在本文分享一些由我们构建的工具以及如何使用它们来优化我们的日常部署流程。
+
+### 为何需要提升效率?
+
+Instagram,正如所有的软件,受限于像服务器和数据中心能源这样的样物理限制。鉴于这些限制,在我们的效率计划中有两个我们希望实现的主要目标:
+
+1. Instagram 应当能够利用持续代码发布提供正常地通信服务,防止因为自然灾害、区域性网络问题等造成某一个数据中心区丢失。
+2. Instagram 应当能够自由地滚动发布新产品和新功能,不必因容量而受阻。
+
+想要实现这些目标,我们意识到我们需要持续不断地监控我们的系统并在战斗中回归(battle regression)。
+
+
+### 定义效率
+
+Web 服务器的瓶颈通常在于每台服务器上可用的 CPU 时间。在这种环境下,效率就意味着利用相同的 CPU 资源完成更多的任务,也就是说,每秒处理更多的用户请求(requests per second, RPS)。当我们寻找优化方法时,我们面临的第一个最大的挑战就是尝试量化我们当前的效率。到目前为止,我们一直在使用“每次请求的平均 CPU 时间”来评估效率,但使用这种指标也有其固有限制:
+
+1. 设备多样性。使用 CPU 时间来测量 CPU 资源并非理想方案,因为它同时受到 CPU 模型与 CPU 负载影响。
+1. 请求影响数据。测量每次请求的 CPU 资源并非理想方案,因为在使用每次请求测量(per-request measurement)方案时,添加或移除轻量级或重量级的请求也会影响到效率指标。
+
+相对于 CPU 时间来说,CPU 指令是一种更好的指标,因为对于相同的请求,它会报告相同的数字,不管 CPU 模型和 CPU 负载情况如何。我们选择使用了一种叫做”每个活动用户(per active user)“的指标,而不是将我们所有的数据链接到每个用户请求上。我们最终采用”每个活动用户在高峰期间的 CPU 指令(CPU instruction per active user during peak minute)“来测量效率。我们建立好新的度量标准后,下一步就是通过对 Django 的分析来学习更多关于我们的回归(our regressions)。
+
+### Django 服务分析
+
+通过分析我们的 Django web 服务,我们希望回答两个主要问题:
+
+1. 一次 CPU 回归会发生吗?
+2. 是什么导致了 CPU 回归问题发生以及我们该怎样修复它?
+
+想要回答第一个问题,我们需要追踪”每个活动用户的 CPU 指令(CPU-instruction-per-active-user)“指标。如果该指标增加,我们就知道一次 CPU 回归已经发生了。
+
+我们为此构建的工具叫做 Dynostats。Dynostats 利用 Django 中间件以一定的速率采样用户请求,记录键效率以及性能指标,例如 CPU 总指令数、端到端请求时延、花费在访问内存缓存(memcache)和数据库服务的时间等。另一方面,每个请求都有很多可用于聚合的元数据(metadata),例如端点名称、HTTP 请求返回码、服务该请求的服务器名称以及请求中最新提交的哈希值(hash)。对于单个请求记录来说,有两个方面非常强大,因为我们可以在不同的维度上进行切割,那将帮助我们减少任何导致 CPU 回归的原因。例如,我们可以根据他们的端点名称聚合所有请求,正如下面的时间序列图所示,从图中可以清晰地看出在特定端点上是否发生了回归。
+
+![](https://d262ilb51hltx0.cloudfront.net/max/800/1*3iouYiAchYBwzF-v0bALMw.png)
+
+CPU 指令对测量效率很重要——当然,它们也很难获得。Python 并没有支持直接访问 CPU 硬件计数器(CPU 硬件计数器是指可编程 CPU 寄存器,用于测量性能指标,例如 CPU 指令)的公共库。另一方面,Linux 内核提供了 `perf_event_open` 系统调用。通过 Python ctypes 桥接技术能够让我们调用标准 C 库编写的系统调用函数,它也为我们提供了兼容 C 的数据类型,从而可以编程硬件计数器并从它们读取数据。
+
+使用 Dynostats,我们已经可以找出 CPU 回归,并探究 CPU 回归发生的原因,例如哪个端点受到的影响最多,谁提交了真正会导致 CPU 回归的变更等。然而,当开发者收到他们的变更已经导致一次 CPU 回归发生的通知时,他们通常难以找出问题所在。如果问题很明显,那么回归可能就不会一开始就被提交!
+
+这就是为何我们需要一个 Python 分析器,从而使开发者能够使用它找出回归(一旦 Dynostats 发现了它)发生的根本原因。不同于白手起家,我们决定对一个现成的 Python 分析器 cProfile 做适当的修改。cProfile 模块通常会提供一个统计集合来描述程序不同的部分执行时间和执行频率。我们将 cProfile 的定时器(timer)替换成了一个从硬件计数器读取的 CPU 指令计数器,以此取代对时间的测量。我们在采样请求后产生数据并把数据发送到数据流水线。我们也会发送一些我们在 Dynostats 所拥有的类似元数据,例如服务器名称、集群、区域、端点名称等。
+在数据流水线的另一边,我们创建了一个消费数据的尾随者(tailer)。尾随者的主要功能是解析 cProfile 的统计数据并创建能够表示 Python 函数级别的 CPU 指令的实体。如此,我们能够通过 Python 函数来聚集 CPU 指令,从而更加方便地找出是什么函数导致了 CPU 回归。
+
+### 监控与警报机制
+
+在 Instagram,我们 [每天部署 30-50 次后端服务][1]。这些部署中的任何一个都能发生 CPU 回归的问题。因为每次发生通常都包含至少一个区别(diff),所以找出任何回归是很容易的。我们的效率监控机制包含在每次发布前后都会在 Dynostats 中哦了过扫描 CPU 指令,并且当变更超出某个阈值时发出警告。对于长期会发生 CPU 回归的情况,我们也有一个探测器为负载最繁重的端点提供日常和每周的变更扫描。
+
+部署新的变更并非触发一次 CPU 回归的唯一情况。在许多情况下,新的功能和新的代码路径都由全局环境变量(global environment variables, GEV)控制。 在一个计划好的时间表上,给一个用户子集发布新功能有一些非常一般的实践。我们在 Dynostats 和 cProfile 统计数据中为每个请求添加了这个信息作为额外的元数据字段。来自这些字段的组请求通过转变全局环境变量(GEV),从而暴露出可能的 CPU 回归问题。这让我们能够在它们对性能造成影响前就捕获到 CPU 回归。
+
+
+### 接下来是什么?
+
+Dynostats 和我们定制的 cProfile,以及我们建立去支持它们的监控和警报机制能够有效地找出大多数导致 CPU 回归的元凶。这些进展已经帮助我们恢复了超过 50% 的不必要的 CPU 回归,否则我们就根本不会知道。
+
+我们仍然还有一些可以提升的方面并可以更加便捷将它们地加入到 Instagram 的日常部署流程中:
+
+1. CPU 指令指标应该要比其它指标如 CPU 时间更加稳定,但我们仍然观察了让我们头疼的差异。保持信号“信噪比(noise ratio)”合理地低是非常重要的,这样开发者们就可以集中于真实的回归上。这可以通过引入置信区间(confidence intervals)的概念来提升,并在信噪比过高时发出警报。针对不同的端点,变化的阈值也可以设置为不同值。
+2. 通过更改 GEV 来探测 CPU 回归的一个限制就是我们要在 Dynostats 中手动启用这些比较的日志输出。当 GEV 逐渐增加,越来越多的功能被开发出来,这就不便于扩展了。
+作为替代,我们能够利用一个自动化框架来调度这些比较的日志输出,并对所有的 GEV 进行遍历,然后当检查到回归时就发出警告。
+3. cProfile 需要一些增强以便更好地处理装饰器函数以及它们的子函数。
+
+鉴于我们在为 Instagram 的 web 服务构建效率框架中所投入的工作,所以我们对于将来使用 Python 继续扩展我们的服务很有信心。
+我们也开始向 Python 语言自身投入更多,并且开始探索从 Python 2 转移 Python 3 之道。我们将会继续探索并做更多的实验以继续提升基础设施与开发者效率,我们期待着很快能够分享更多的经验。
+
+
+--------------------------------------------------------------------------------
+
+via: https://engineering.instagram.com/web-service-efficiency-at-instagram-with-python-4976d078e366#.tiakuoi4p
+
+作者:[Min Ni][a]
+译者:[ChrisLeeGit](https://github.com/chrisleegit)
+校对:[校对者ID](https://github.com/校对者ID)
+
+本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
+
+[a]: https://engineering.instagram.com/@InstagramEng?source=post_header_lockup
+[1]: https://engineering.instagram.com/continuous-deployment-at-instagram-1e18548f01d1#.p5adp7kcz
diff --git a/translated/tech/20160608 Implementing Mandatory Access Control with SELinux or AppArmor in Linux.md b/translated/tech/20160608 Implementing Mandatory Access Control with SELinux or AppArmor in Linux.md
new file mode 100644
index 0000000000..82dd1a3484
--- /dev/null
+++ b/translated/tech/20160608 Implementing Mandatory Access Control with SELinux or AppArmor in Linux.md
@@ -0,0 +1,247 @@
+在 Linux 上用 SELinux 或 AppArmor 实现强制访问控制
+===========================================================================
+
+为了克服标准 用户-组-其他/读-写-执行 权限以及[访问控制列表][1]的限制以及加强安全机制,美国国家安全局(NSA)设计出一个灵活的强制访问控制(MAC)方法 SELinux(Security Enhanced Linux 的缩写),来限制其他事物,在仍然允许对这个模型后续修改的情况下,让进程尽可能以最小权限访问或在系统对象(如文件,文件夹,网络端口等)上执行其他操作。
+
+![](http://www.tecmint.com/wp-content/uploads/2016/06/SELinux-AppArmor-Security-Hardening-Linux.png)
+>SELinux 和 AppArmor 加固 Linux 安全
+
+另一个流行并且广泛使用的 MAC 是 AppArmor,相比于 SELinux 它提供额外的特性,包括一个学习模型,让系统“学习”一个特定应用的行为,通过配置文件设置限制实现安全的应用使用。
+
+在 CentOS 7 中,SELinux 合并进了内核并且默认启用强制(Enforcing)模式(下一节会介绍这方面更多的内容),与使用 AppArmor 的 openSUSE 和 Ubuntu 完全不同。
+
+在这篇文章中我们会解释 SELinux 和 AppArmor 的本质以及如何在你选择的发行版上使用这两个工具之一并从中获益。
+
+### SELinux 介绍以及如何在 CentOS 7 中使用
+
+Security Enhanced Linux 可以以两种不同模式运行:
+
+- 强制(Enforcing):SELinux 基于 SELinux 策略规则拒绝访问,一个指导准则集合控制安全引擎。
+- 宽容(Permissive):SELinux 不拒绝访问,但如果在强制模式下会被拒绝的操作会被记录下来。
+
+SELinux 也能被禁用。尽管这不是它的一个操作模式,不过也是一个选项。但学习如何使用这个工具强过只是忽略它。时刻牢记这一点!
+
+使用 getenforce 命令来显示 SELinux 的当前模式。如果你想要更改模式,使用 setenforce 0(设置为宽容模式)或 setenforce 1(强制模式)。
+
+因为这些设置重启后就失效了,你需要编辑 /etc/selinux/ 的配置文件并设置 SELINUX 变量为 enforcing,permissive 或 disabled 来保存设置让其重启后也有效:
+
+![](http://www.tecmint.com/wp-content/uploads/2016/06/Enable-Disable-SELinux-Mode.png)
+>如何启用和禁用 SELinux 模式
+
+还有一点要注意,如果 getenforce 返回 Disabled,你得编辑 /etc/selinux/ 配置为你想要的操作模式并重启。否则你无法利用 setenforce 设置(或切换)操作模式。
+
+setenforce 的典型用法之一包括在 SELinux 模式之间切换(从强制到宽容或相反)来定位一个应用是否行为不端或没有像预期一样工作。如果它在你将 SELinux 设置为宽容模式正常工作,你就可以确定你遇到的是 SELinux 权限问题。
+
+两种我们使用 SELinux 可能需要解决的典型案例:
+
+- 改变一个守护进程监听的默认端口。
+- 给一个虚拟主机设置 /var/www/html 以外的文档根路径值。
+
+让我们用以下例子来看看这两种情况。
+
+#### 例 1:更改 sshd 守护进程的默认端口
+
+大部分系统管理员为了加强服务器安全首先要做的事情之一就是更改 SSH 守护进程监听的端口,主要是为了组织端口扫描和外部攻击。要达到这个目的,我们要更改 `/etc/ssh/sshd_config` 中的 Port 值为以下值(我们在这里使用端口 9999 为例):
+
+```
+Port 9999
+```
+
+在尝试重启服务并检查它的状态之后,我们会看到它启动失败:
+
+```
+# systemctl restart sshd
+# systemctl status sshd
+```
+
+![](http://www.tecmint.com/wp-content/uploads/2016/06/Check-sshd-Service-Status.png)
+>检查 SSH 服务状态
+
+如果我们看看 /var/log/audit/audit.log,就会看到 sshd 被 SELinux 组织在端口 9999 上启动,因为他是 JBoss 管理服务的保留端口(SELinux 日志信息包含了词语“AVC”,所以应该很容易把它同其他信息区分开来):
+
+```
+# cat /var/log/audit/audit.log | grep AVC | tail -1
+```
+
+![](http://www.tecmint.com/wp-content/uploads/2016/06/Check-Linux-Audit-Logs.png)
+>检查 Linux 审计日志
+
+在这种情况下大部分人可能会禁用 SELinux,但我们不这么做。我们会看到有个让 Selinux 和监听其他端口的 sshd 和谐共处的方法。首先确保你有 policycoreutils-python 这个包,执行:
+
+```
+# yum install policycoreutils-python
+```
+
+查看 SELinux 允许 sshd 监听的端口列表。在接下来的图片中我们还能看到端口 9999 是为其他服务保留的,所以我们暂时无法用它来运行其他服务:
+
+```
+# semanage port -l | grep ssh
+```
+
+当然我们可以给 SSH 选择其他端口,但如果我们确定我们不会使用这台机器跑任何 JBoss 相关的服务,我们就可以修改 SELinux 已存在的规则,转而给 SSH 分配那个端口:
+
+```
+# semanage port -m -t ssh_port_t -p tcp 9999
+```
+
+在那之后,我们可以用第一个 semanage 命令检查端口是否正确分配了,或用 -lC 参数(list custom 的简称):
+
+```
+# semanage port -lC
+# semanage port -l | grep ssh
+```
+
+![](http://www.tecmint.com/wp-content/uploads/2016/06/Assign-Port-to-SSH.png)
+>给 SSH 分配端口
+
+我们现在可以重启 SSH 服务并通过端口 9999 连接了。注意这个更改重启之后依然有效。
+
+#### 例 2:给一个虚拟主机设置 /var/www/html 以外的文档根路径值
+
+如果你需要用除 /var/www/html 以外目录作为文档根目录[设置一个 Apache 虚拟主机][2](也就是说,比如 `/websrv/sites/gabriel/public_html`):
+
+```
+DocumentRoot “/websrv/sites/gabriel/public_html”
+```
+
+Apache 会拒绝提供内容,因为 index.html 已经被标记为了 default_t SELinux 类型,Apache 无法访问它:
+
+```
+# wget http://localhost/index.html
+# ls -lZ /websrv/sites/gabriel/public_html/index.html
+```
+
+![](http://www.tecmint.com/wp-content/uploads/2016/06/Labeled-default_t-SELinux-Type.png)
+>被标记为 default_t SELinux 类型
+
+和之前的例子一样,你可以用以下命令验证这是不是 SELinux 相关的问题:
+
+```
+# cat /var/log/audit/audit.log | grep AVC | tail -1
+```
+
+![](http://www.tecmint.com/wp-content/uploads/2016/06/Check-Logs-for-SELinux-Issues.png)
+>检查日志确定是不是 SELinux 的问题
+
+要将 /websrv/sites/gabriel/public_html 整个目录内容标记为 httpd_sys_content_t,执行:
+
+```
+# semanage fcontext -a -t httpd_sys_content_t "/websrv/sites/gabriel/public_html(/.*)?"
+```
+
+上面这个命令会赋予 Apache 对那个目录以及其内容的读取权限。
+
+最后,要应用这条策略(并让更改的标记立即生效),执行:
+
+```
+# restorecon -R -v /websrv/sites/gabriel/public_html
+```
+
+现在你应该可以访问这个目录了:
+
+```
+# wget http://localhost/index.html
+```
+
+![](http://www.tecmint.com/wp-content/uploads/2016/06/Access-Apache-Directory.png)
+>访问 Apache 目录
+
+要获取关于 SELinux 的更多信息,参阅 Fedora 22 [SELinux 以及 管理员指南][3]。
+
+
+### AppArmor 介绍以及如何在 OpenSUSE 和 Ubuntu 上使用它
+
+AppArmor 的操作是基于纯文本文件的规则定义,该文件中含有允许权限和访问控制规则。安全配置文件用来限制应用程序如何与系统中的进程和文件进行交互。
+
+系统初始就提供了一系列的配置文件,但其他的也可以由应用程序安装的时候设置或由系统管理员手动设置。
+
+像 SELinux 一样,AppArmor 以两种模式运行。在 enforce 模式下,应用被赋予它们运行所需要的最小权限,但在 complain 模式下 AppArmor 允许一个应用执行有限的操作并将操作造成的“抱怨”记录到日志里(/var/log/kern.log,/var/log/audit/audit.log,和其它在 /var/log/apparmor 中的日志)。
+
+日志中会显示配置文件在强制模式下运行时会产生错误的记录,它们中带有审计这个词。因此,你可以在 AppArmor 的 enforce 模式下运行之前,先在 complain 模式下尝试运行一个应用并调整它的行为。
+
+可以用这个命令显示 AppArmor 的当前状态:
+
+```
+$ sudo apparmor_status
+```
+
+![](http://www.tecmint.com/wp-content/uploads/2016/06/Check-AppArmor-Status.png)
+>查看 AppArmor 的状态
+
+上面的图片指明配置 /sbin/dhclient,/usr/sbin/,和 /usr/sbin/tcpdump 在 enforce 模式下(在 Ubuntu 下默认就是这样的)。
+
+因为不是所有的应用都包含相关的 AppArmor 配置,apparmor-profiles 包提供了其它配置给没有提供限制的包。默认它们配置在 complain 模式下运行以便系统管理员能够测试并选择一个所需要的配置。
+
+我们将会利用 apparmor-profiles,因为写一份我们自己的配置已经超出了 LFCS [认证][4]的范围了。但是,由于配置都是纯文本文件,你可以查看并学习它们,为以后创建自己的配置做准备。
+
+AppArmor 配置保存在 /etc/apparmor.d 中。让我们来看看这个文件夹在安装 apparmor-profiles 之前和之后有什么不同:
+
+```
+$ ls /etc/apparmor.d
+```
+
+![](http://www.tecmint.com/wp-content/uploads/2016/06/View-AppArmor-Directory-Content.png)
+>查看 AppArmor 文件夹内容
+
+如果你再次执行 sudo apparmor_status,你会在 complain 模式看到更长的配置文件列表。你现在可以执行下列操作:
+
+将当前在 enforce 模式下的配置文件切换到 complain 模式:
+
+```
+$ sudo aa-complain /path/to/file
+```
+
+以及相反的操作(complain –> enforce):
+
+```
+$ sudo aa-enforce /path/to/file
+```
+
+上面这些例子是允许使用通配符的。举个例子:
+
+```
+$ sudo aa-complain /etc/apparmor.d/*
+```
+
+会将 /etc/apparmor.d 中的所有配置文件设置为 complain 模式,反之
+
+```
+$ sudo aa-enforce /etc/apparmor.d/*
+```
+
+会将所有配置文件设置为 enforce 模式。
+
+要完全禁用一个配置,在 /etc/apparmor.d/disabled 目录中创建一个符号链接:
+
+```
+$ sudo ln -s /etc/apparmor.d/profile.name /etc/apparmor.d/disable/
+```
+
+要获取关于 AppArmor 的更多信息,参阅[官方 AppArmor wiki][5] 以及 [Ubuntu 提供的][6]文档。
+
+### 总结
+
+在这篇文章中我们学习了一些 SELinux 和 AppArmor 这两个著名强制访问控制系统的基本知识。什么时候使用两者中的一个或是另一个?为了避免提高难度,你可能需要考虑专注于你选择的发行版自带的那一个。不管怎样,它们会帮助你限制进程和系统资源的访问,以提高你服务器的安全性。
+
+关于本文你有任何的问题,评论,或建议,欢迎在下方发表。不要犹豫,让我们知道你是否有疑问或评论。
+
+
+--------------------------------------------------------------------------------
+
+via: http://www.tecmint.com/mandatory-access-control-with-selinux-or-apparmor-linux/
+
+作者:[Gabriel Cánepa][a]
+译者:[alim0x](https://github.com/alim0x)
+校对:[校对者ID](https://github.com/校对者ID)
+
+本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
+
+[a]: http://www.tecmint.com/author/gacanepa/
+[1]: http://www.tecmint.com/secure-files-using-acls-in-linux/
+[2]: http://www.tecmint.com/apache-virtual-hosting-in-centos/
+[3]: https://docs.fedoraproject.org/en-US/Fedora/22/html/SELinux_Users_and_Administrators_Guide/index.html
+[4]: http://www.tecmint.com/sed-command-to-create-edit-and-manipulate-files-in-linux/
+[5]: http://wiki.apparmor.net/index.php/Main_Page
+[6]: https://help.ubuntu.com/community/AppArmor
+
+
diff --git a/translated/tech/20160611 vlock – A Smart Way to Lock User Virtual Console or Terminal in Linux.md b/translated/tech/20160611 vlock – A Smart Way to Lock User Virtual Console or Terminal in Linux.md
deleted file mode 100644
index 26c74b019e..0000000000
--- a/translated/tech/20160611 vlock – A Smart Way to Lock User Virtual Console or Terminal in Linux.md
+++ /dev/null
@@ -1,99 +0,0 @@
-vlock – 一个锁定 Linux 用户虚拟控制台或终端的好方法
-=======================================================================
-
-虚拟控制台是 Linux 非常重要的功能,他们为使用系统的用户提供了 shell 提示符,以保证用户在登录和远程登录一个未安装图形界面的系统时仍能使用。
-
-一个用户可以同时操作多个虚拟控制台会话,只需在虚拟控制台间来回切换即可。
-
-![](http://www.tecmint.com/wp-content/uploads/2016/05/vlock-Lock-User-Terminal-in-Linux.png)
->用 vlock 锁定 Linux 用户控制台或终端
-
-这篇使用指导,旨在教会大家如何使用 vlock 来锁定用户虚拟控制台和终端。
-
-### vlock 是什么?
-
-vlock 是一个用于锁定一个或多个用户虚拟控制台用户会话的工具。在多用户系统中 vlock 是扮演着重要的角色,他让用户可以在锁住自己会话的同时不影响其他用户通过其他虚拟控制台操作同一个系统。必要时,还可以锁定所有的控制台,同时禁止在虚拟控制台间切换。
-
-vlock 的主要功能面向控制台会话方面,同时也支持非控制台会话的锁定,但该功能的测试还不完全。
-
-### 在 Linux 上安装 vlock
-
-根据你的 Linux 系统选择 vlock 安装指令:
-
-```
-# yum install vlock [On RHEL / CentOS / Fedora]
-$ sudo apt-get install vlock [On Ubuntu / Debian / Mint]
-```
-
-### 在 Linux 上使用 vlock
-
-vlock 操作选项的常规语法:
-
-```
-# vlock option
-# vlock option plugin
-# vlock option -t plugin
-```
-
-#### vlock 常用选项及用法:
-
-1. 锁定用户的当前虚拟控制台或终端会话,如下:
-
- ```
- # vlock --current
- ```
-
- ![](http://www.tecmint.com/wp-content/uploads/2016/05/Lock-User-Terminal-Session-in-Linux.png)
- >锁定 Linux 用户终端会话
-
- 选项 -c 或 --current,锁定当前的会话,该参数为运行 vlock 时的默认行为。
-
-2. 锁定所有你的虚拟控制台会话,并禁用虚拟控制台间切换,命令如下:
-
- ```
- # vlock --all
- ```
-
- ![](http://www.tecmint.com/wp-content/uploads/2016/05/Lock-All-Linux-Terminal-Sessions.png)
- >锁定所有 Linux 终端会话
-
- 选项 -a 或 --all,锁定所有用户的控制台会话,并禁用虚拟控制台间切换。
-
- 其他的选项只有在编译 vlock 时编入了相关插件支持及其引用后,才能发挥作用:
-
-3. 选项 -n 或 --new,调用时后,会在锁定用户的控制台会话前切换到一个新的虚拟控制台。
-
- ```
- # vlock --new
- ```
-
-4. 选项 -s 或 --disable-sysrq,在禁用虚拟控制台的同时禁用 SysRq 功能,只有在与 -a 或 --all 同时使用时才起作用。
-
- ```
- # vlock -sa
- ```
-
-5. 选项 -t 或 --timeout ,用以设定屏幕保护插件的 timeout 值。
-
- ```
- # vlock --timeout 5
- ```
-
-你可以使用 `-h` 或 `--help` 和 `-v` 或 `--version` 分别查看帮助消息和版本信息。
-
-我们的介绍就到这了,提示一点,你可以将 vlock 的 `~/.vlockrc` 文件包含到系统启动中并参考入门手册[添加环境变量][1],特别是 Debian 系的用户。
-
-想要找到更多或是补充一些这里没有提及的信息,可以直接在写在下方评论区。
-
---------------------------------------------------------------------------------
-
-via: http://www.tecmint.com/vlock-lock-user-virtual-console-terminal-linux/?utm_source=feedburner&utm_medium=feed&utm_campaign=Feed%3A+tecmint+%28Tecmint%3A+Linux+Howto%27s+Guide%29
-
-作者:[Aaron Kili][a]
-译者:[martin2011qi](https://github.com/martin2011qi)
-校对:[校对者ID](https://github.com/校对者ID)
-
-本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
-
-[a]: http://www.tecmint.com/author/aaronkili/
-[1]: http://www.tecmint.com/set-path-variable-linux-permanently/
diff --git a/translated/tech/20160616 10 Basic Linux Commands That Every Linux Newbies Should Remember.md b/translated/tech/20160616 10 Basic Linux Commands That Every Linux Newbies Should Remember.md
deleted file mode 100644
index c69b7a6e54..0000000000
--- a/translated/tech/20160616 10 Basic Linux Commands That Every Linux Newbies Should Remember.md
+++ /dev/null
@@ -1,141 +0,0 @@
-Linux新手必知必会的10条Linux基本命令
-=====================================================================
-
-![](http://www.linuxandubuntu.com/uploads/2/1/1/5/21152474/4225072_orig.png)
-
-
-[Linux][1]对我们的生活产生了巨大的冲击。至少你的安卓手机使用的就是Linux核心。尽管如此,在第一次开始使用Linux时你还是会感到难以下手。因为在Linux中,通常需要使用终端命令来取代Windows系统中的点击启动图标操作。但是不必担心,这里我们会介绍10个Linux基本命令来帮助你开启Linux神秘之旅。
-
-
-### 帮助新手走出第一步的10个Linux基本命令
-
-当我们谈论Linux命令时,实质上是在谈论Linux系统本身。这短短的10个Linux基本命令不会让你变成天才或者Linux专家,但是能帮助你轻松开始Linux之旅。使用这些基本命令会帮助新手们完成Linux的日常任务,由于它们的使用频率如此至高,所以我更乐意称他们为Linux命令之王!
-
-让我们开始学习这10条Linux基本命令吧。
-
-
-#### 1. sudo
-
-这条命令的意思是“以超级用户的身份执行”,是 SuperUserDo 的简写,它是新手将要用到的最重要的一条Linux命令。当一条单行命令需要root权限的时候,`sudo`命令就派上用场了。你可以在每一条需要root权限的命令前都加上`sudo`。
-
-```
-$ sudo su
-```
-
-
-#### 2. ls (list)
-
-
-跟其他人一样,你肯定也经常想看看目录下都有些什么东西。使用列表命令,终端会把当前工作目录下所有的文件以及文件夹展示给你。比如说,我当前处在 /home 文件夹中,我想看看 /home文件夹中都有哪些文件和目录。
-
-```
-/home$ ls
-```
-
-
-在/home中执行`ls`命令将会返回以下内容
-
-```
-imad lost+found
-```
-
-
-#### 3. cd
-
-变更目录命令(cd)是终端中总会被用到的主要命令。他是最常用到的Linux基本命令之一。此命令使用非常简单,当你打算从当前目录跳转至某个文件夹时,只需要将文件夹键入此命令之后即可。如果你想跳转至上层目录,只需要在此命令之后键入两个点(..)就可以了。
-
-举个例子,我现在处在/home目录中,我想移动到/home目录中的usr文件夹下,可以通过以下命令来完成操作。
-
-```
-/home $ cd usr
-
-/home/usr $
-```
-
-
-#### 4. mkdir
-
-只是可以切换目录还是不够完美。有时候你会想要新建一个文件夹或子文件夹。此时可以使用mkdir命令来完成操作。使用方法很简单,只需要把新的文件夹名跟在mkdir命令之后就好了。
-
-```
-~$ mkdir folderName
-```
-
-
-#### 5. cp
-
-拷贝-粘贴(copy-and-paste)是我们组织文件需要用到的重要命令。使用 `cp` 命令可以帮助你在终端当中完成拷贝-粘贴操作。首先确定你想要拷贝的文件,然后键入打算粘贴此文件的目标位置。
-
-```
-$ cp src des
-```
-
-注意:如果目标目录对新建文件需要root权限时,你可以使用`sudo`命令来完成文件拷贝操作。
-
-
-#### 6. rm
-
-rm命令可以帮助你移除文件甚至目录。如果文件需要root权限才能移除,可以用`-f`参数来强制执行。也可以使用`-r`参数来递归的移除文件夹。
-
-```
-$ rm myfile.txt
-```
-
-
-#### 7. apt-get
-
-这个命令会依据发行版的不同而有所区别。在基于Debian的发行版中,我们拥有Advanced Packaging Tool(APT)包管理工具来安装、移除和升级包。apt-get命令会帮助你安装需要在Linux系统中运行的软件。它是一个功能强大的命令行,可以用来帮助你对软件执行安装、升级和移除操作。
-
-在其他发行版中,例如Fedora、Centos,都各自不同的包管理工具。Fedora之前使用的是yum,不过现在dnf成了它默认的包管理工具。
-
-```
-$ sudo apt-get update
-
-$ sudo dnf update
-```
-
-
-#### 8. grep
-
-当你需要查找一个文件,但是又忘记了它具体的位置和路径时,`grep`命令会帮助你解决这个难题。你可以提供文件的关键字,使用`grep`命令来查找到它。
-
-```
-$ grep user /etc/passwd
-```
-
-
-#### 9. cat
-
-作为一个用户,你应该会经常需要浏览脚本内的文本或者代码。`cat`命令是Linux系统的基本命令之一,它的用途就是将文件的内容展示给你。
-
-```
-$ cat CMakeLists.txt
-```
-
-
-#### 10. poweroff
-
-最后一个命令是 `poweroff`。有时你需要直接在终端中执行关机操作。此命令可以完成这个任务。由于关机操作需要root权限,所以别忘了在此命令之前添加`sudo`。
-
-```
-$ sudo poweroff
-```
-
-
-### 总结
-
-如我在文章开始所言,这10条命令并不会让你立即成为一个Linux大拿。它们会让你在初期快速上手Linux。以这些命令为基础,给自己设置一个目标,每天学习一到三条命令,这就是此文的目的所在。在下方评论区分享有趣并且有用的命令。别忘了跟你的朋友分享此文。
-
-
---------------------------------------------------------------------------------
-
-via: http://www.linuxandubuntu.com/home/10-basic-linux-commands-that-every-linux-newbies-should-remember
-
-作者:[Commenti][a]
-译者:[mr-ping](https://github.com/mr-ping)
-校对:[校对者ID](https://github.com/校对者ID)
-
-本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
-
-[a]: http://www.linuxandubuntu.com/home/10-basic-linux-commands-that-every-linux-newbies-should-remember#comments
-[1]: http://linuxandubuntu.com/home/category/linux
diff --git a/translated/tech/20160620 PowerPC gains an Android 4.4 port with Big Endian support.md b/translated/tech/20160620 PowerPC gains an Android 4.4 port with Big Endian support.md
deleted file mode 100644
index 3b450cb603..0000000000
--- a/translated/tech/20160620 PowerPC gains an Android 4.4 port with Big Endian support.md
+++ /dev/null
@@ -1,103 +0,0 @@
-PowerPC 获得大端 Android 4.4 系统的移植
-===========================================================
-
-eInfochips(一家软件厂商) 已将将 Android 4.4 系统移植到 PowerPC 架构,它将作为一家航空电子客户的人机界面(HMI:Human Machine Interface)用来监视引擎的建康状况。
-
-eInfochips 已经开发了第一个面向 PowerPC 架构的 CPU 的 Android 移植版本,它使用较新的大端 Android 系统。此移植基于 Android 开源项目[Android Open Source Project (AOSP)] 中 Android 4.4 (KitKat) 的代码,其功能内核的版本号为 3.12.19。
-
-Android 开始兴起的时候,PowerPC正在快速失去和 ARM 架构共通角逐的市场。高端的网络客户和以市场为导向的嵌入式工具大多运行在诸如飞思卡尔(Freescale)的 PowerQUICC 和 QorIQ 上,而不取决于 Linux 系统。一些 Android 的移植计划最终失败,然而在 2009 年,飞思卡尔和 Embedded Alley(一家软件厂商,当前是 Mentor Graphics 的 Linux 团队的一部分)[宣布了针对 PowerQUICC 和 QorIQ 芯片的移植版本][15],当前由 NXP 公司构建。另一个名为[Android-PowerPC][16] 的项目也作出了相似的工作。
-
-这些努力来的都并不容易,然而,当航空公司找到 eInfochips,希望能够为他们那些基于 PowerPC 的引擎监控系统添加 Android 应用程序以改善人机界面。此公司找出了这些早期的移植版本,然而,他们都很难达到标准。所以,他们不得不从头开始新的移植。
-
-最主要的问题是这些移植的 Android 版本实在是太老了,且 very different。Embedded Alley 移植的版本为 Android 1.5 (Cupcake),它于 2009 年发布,Linux 内核版本为 2.6.28。最后一版的移植为 Android-PowerPC 项目的 Android 2.2 (Froyo)它于 2010 年发布,内核版本为 2.6.32。此外,航空公司还有一些额外的技术诉求,例如对大端的支持. 现有的存储器接入方案仍旧应用于网络通信和电信行业。然而那些早期的移植版本仅能够支持小端的存储器访问。
-
-### 来自 eInfochips 的全新 PowerPC 架构移植
-
-eInfochips, 它最为出名的应该是那些基于 ARM/骁龙处理器的模块计算机板卡,例如 [Eragon 600][17]。 它已经完成了基于 QorIQ 的 Android 4.4 系统移植,且发布了白皮书描述了此项目。采用该项目的航空电子设备客户仍旧不愿透露姓名,目前仍旧不清楚什么时候会公开此该移植版本。
-
-
-![](http://hackerboards.com/files/einfochips_porting_android_on_powerpc-sm.jpg)
->图片来自 eInfochips 的博客日志
-
-- 全新的 PowerPC Android 项目包括:
-- 基于 PowerPC [e5500][1] 深度定制(bionic 定制不知道什么鬼,校对的时候也可以想想怎么处理)
-- 基于 Android KitKat 的大端序支持
-- 开发工具链为 Gcc 5.2
-- Android 4.4 框架的 PowerPC 支持
-- PowerPC e5500 的 Android 内核版本为 3.12.19
-
-根据 eInfochips 的销售经理 Sooryanarayanan Balasubramanian 描述,航空电子客户想要使用 Android 主要是因为熟悉的界面能够缩减培训的时间,并且让程序更新和提供新的程序变得更加容易。他继续解释说:“这次成功的移植了 Android,使得今后的工作仅仅需要在应用层作出修修改改,而不再向以前一样需要在所有层之间作相互的校验。”“这是第一次在航空航天工业作出这些尝试,这需要在设计时作出尽职的调查。”
-
-通过白皮书,可以知道将 Android 移植到 PowerPC 上需要对框架,核心库,开发工具链,运行时链接器,对象链接器和开源编译工具作出大量的修改。在字节码生成阶段,移植团队决定使用便携模式而不是快速的解释模式。这是因为,还没有 PowerPC 可用的快速解释模式,而使用 [libffi][18] 的便携模式能够支持 PowerPC。
-
-同时,团队还面临在 Android 运行时 (ART) 环境和 Dalvik 虚拟机 (DVM) 环境之间的选择。他们发现,ART 环境下的便携模式还未经测试且缺乏良好的文档支持,所以最终选择了 DVM 环境下的便携模式。
-
-白皮书中还提及了其它的一些在移植过程中遇到的困难,包括重新开发工具链,重写脚本以解决 AOSP “非标准”的使用编译器标志的问题。最终,移植提供了 37 个服务,and features a headless Android deployment along with an emulated UI in user space.
-
-
-### 目标硬件
-
-感谢来自 [eInfochips 博客日志][2] 的图片(如下图所示),我们能够确认此 PowerPC 的 Android 移植项目的硬件平台。这个板卡为 [X-ES Xpedite 6101][3],它是固实的 XMC/PrPMC 夹层模组。
-
-![](http://hackerboards.com/files/xes_xpedite6101-sm.jpg)
->X-ES Xpedite 6101 照片和框图
-
-X-ES Xpedite 6101 板卡拥有可选择的 NXP 公司基于 QorIQ T系列通信处理器 T2081, T1042, 和 T1022,他们分别拥有 8 个,4 个和 2 个 e6500 核心,稍有不同的是,T2081 的处理器主频为 1.8GHz,T1042/22 的处理器主频为 1.4GHz。所有的核心都集成了 AltiVec SIMD 引擎,这也就意味着它能够提供 DSP 级别的浮点运算性能。所有以上 3 款 X-ES 板卡都能够支持最高 8GB 的 DDR3-1600 ECC SDRAM 内存。外加 512MB NOR 和 32GB 的 NAND 闪存。
-
-![](http://hackerboards.com/files/nxp_qoriq_t2081_block-sm.jpg)
->NXP T2081 框图
-
-板卡的 I/O 包括一个 x4 PCI Express Gen2 通到,along with dual helpings of Gigabit Ethernet, RS232/422/485 串口和 SATA 3.0 接口。此外,它可选 3 款 QorIQ 处理器,Xpedite 6101 提供了三种[X-ES 加固等级][19],分别是额定工作温度 0 ~ 55°C, -40 ~ 70°C, 或者是 -40 ~ 85°C,且包含 3 类冲击和抗振类别。
-
-此外,我们已经介绍过的基于 X-ES QorIQ 的 XMC/PrPMC 板卡包括[XPedite6401 和 XPedite6370][20],它们支持已有的板卡级 Linux Linux,Wind River VxWorks(一种实时操作系统) 和 Green Hills Integrity(也是一种操作系统)。
-
-
-### 更多信息
-
-eInfochips Android PowerPC 移植白皮书可以[在此[4]下载(需要先免费注册)。
-
-### Related posts:
-
-- [Commercial embedded Linux distro boosts virtualization][5]
-- [Freescale unveils first ARM-based QorIQ SoCs][6]
-- [High-end boards run Linux on 64-bit ARM QorIQ SoCs][7]
-- [Free, Open Enea Linux taps Yocto Project and Linaro code][8]
-- [LynuxWorks reverts to its LynxOS roots, changes name][9]
-- [First quad- and octa-core QorIQ SoCs unveiled][10]
-- [Free white paper shows how Linux won embedded][11]
-- [Quad-core Snapdragon COM offers three dev kit options][12]
-- [Tiny COM runs Linux on quad-core 64-bit Snapdragon 410][13]
-- [PowerPC based IoT gateway COM ships with Linux BSP][14]
-
-
---------------------------------------------------------------------------------
-
-via: http://hackerboards.com/powerpc-gains-android-4-4-port-with-big-endian-support/
-
-作者:[Eric Brown][a]
-译者:[dongfengweixiao](https://github.com/dongfengweixiao)
-校对:[校对者ID](https://github.com/校对者ID)
-
-本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
-
-[a]: http://hackerboards.com/powerpc-gains-android-4-4-port-with-big-endian-support/
-[1]: http://linuxdevices.linuxgizmos.com/low-cost-powerquicc-chips-offer-flexible-interconnect-options/
-[2]: https://www.einfochips.com/blog/k2-categories/aerospace/presenting-a-case-for-porting-android-on-powerpc-architecture.html
-[3]: http://www.xes-inc.com/products/processor-mezzanines/xpedite6101/
-[4]: http://biz.einfochips.com/portingandroidonpowerpc
-[5]: http://hackerboards.com/commercial-embedded-linux-distro-boosts-virtualization/
-[6]: http://hackerboards.com/freescale-unveils-first-arm-based-qoriq-socs/
-[7]: http://hackerboards.com/high-end-boards-run-linux-on-64-bit-arm-qoriq-socs/
-[8]: http://hackerboards.com/free-open-enea-linux-taps-yocto-and-linaro-code/
-[9]: http://hackerboards.com/lynuxworks-reverts-to-its-lynxos-roots-changes-name/
-[10]: http://hackerboards.com/first-quad-and-octa-core-qoriq-socs-unveiled/
-[11]: http://hackerboards.com/free-white-paper-shows-how-linux-won-embedded/
-[12]: http://hackerboards.com/quad-core-snapdragon-com-offers-three-dev-kit-options/
-[13]: http://hackerboards.com/tiny-com-runs-linux-and-android-on-quad-core-64-bit-snapdragon-410/
-[14]: http://hackerboards.com/powerpc-based-iot-gateway-com-ships-with-linux-bsp/
-[15]: http://linuxdevices.linuxgizmos.com/android-ported-to-powerpc/
-[16]: http://www.androidppc.com/
-[17]: http://hackerboards.com/quad-core-snapdragon-com-offers-three-dev-kit-options/
-[18]: https://sourceware.org/libffi/
-[19]: http://www.xes-inc.com/capabilities/ruggedization/
-[20]: http://hackerboards.com/high-end-boards-run-linux-on-64-bit-arm-qoriq-socs/
diff --git a/translated/tech/20160820 Protocol Buffer Basics C++.md b/translated/tech/20160820 Protocol Buffer Basics C++.md
new file mode 100644
index 0000000000..ed86014010
--- /dev/null
+++ b/translated/tech/20160820 Protocol Buffer Basics C++.md
@@ -0,0 +1,411 @@
+Protocol Buffer Basics: C++
+============================
+
+这篇教程提供了一个面向 C++ 程序员、关于 `protocol buffers` 的基础介绍。通过创建一个简单的示例应用程序,它将向我们展示:
+
+* 在 `.proto` 文件中定义消息格式
+* 使用 `protocol buffer` 编译器
+* 使用 `C++ protocol buffer API` 读写消息
+
+这不是一个关于使用 C++ protocol buffers 的全面指南。要获取更详细的信息,请参考 [Protocol Buffer Language Guide][1] 和 [Encoding Reference][2]。
+
+### 为什么使用 Protocol Buffers
+
+我们接下来要使用的例子是一个非常简单的"地址簿"应用程序,它能从文件中读取联系人详细信息。地址簿中的每一个人都有一个名字,ID,邮件地址和联系电话。
+
+如何序列化和获取结构化的数据?这里有几种解决方案:
+
+* 以二进制形式发送/接收原生的内存数据结构。通常,这是一种脆弱的方法,因为接收/读取代码的编译必须基于完全相同的内存布局、大小端等等。同时,当文件增加时,原始格式数据会随着与该格式相连的软件拷贝而迅速扩散,这将很难扩展文件格式。
+
+* 你可以创造一种 `ad-hoc` 方法,将数据项编码为一个字符串——比如将 4 个整数编码为 "12:3:-23:67"。虽然它需要编写一次性的编码和解码代码且解码需要耗费小的运行时成本,但这是一种简单灵活的方法。这最适合编码非常简单的数据。
+
+* 序列化数据为 `XML`。这种方法是非常吸引人的,因为 `XML` 是一种适合人阅读的格式,并且有为许多语言开发的库。如果你想与其他程序和项目共享数据,这可能是一种不错的选择。然而,众所周知,`XML` 是空间密集型的,且在编码和解码时,它对程序会造成巨大的性能损失。同时,使用 XML DOM 树被认为比操作一个类的简单字段更加复杂。
+
+`Protocol buffers` 是针对这个问题的一种灵活、高效、自动化的解决方案。使用 `Protocol buffers`,你需要写一个 `.proto` 说明,用于描述你所希望存储的数据结构。利用 `.proto` 文件,protocol buffer 编译器可以创建一个类,用于实现自动化编码和解码高效的二进制格式的 protocol buffer 数据。产生的类提供了构造 `protocol buffer` 的字段的 getters 和 setters,并且作为一个单元,关注读写 `protocol buffer` 的细节。重要的是,`protocol buffer` 格式支持扩展格式,代码仍然可以读取以旧格式编码的数据。
+
+### 在哪可以找到示例代码
+
+示例代码被包含于源代码包,位于 "examples" 文件夹。在[这][4]下载代码。
+
+### 定义你的协议格式
+
+为了创建自己的地址簿应用程序,你需要从 `.proto` 开始。`.proto` 文件中的定义很简单:为你所需要序列化的数据结构添加一个消息(message),然后为消息中的每一个字段指定一个名字和类型。这里是定义你消息的 `.proto` 文件,`addressbook.proto`。
+
+```
+package tutorial;
+
+message Person {
+ required string name = 1;
+ required int32 id = 2;
+ optional string email = 3;
+
+ enum PhoneType {
+ MOBILE = 0;
+ HOME = 1;
+ WORK = 2;
+ }
+
+ message PhoneNumber {
+ required string number = 1;
+ optional PhoneType type = 2 [default = HOME];
+ }
+
+ repeated PhoneNumber phone = 4;
+}
+
+message AddressBook {
+ repeated Person person = 1;
+}
+```
+
+如你所见,其语法类似于 C++ 或 Java。我们开始看看文件的每一部分内容做了什么。
+
+`.proto` 文件以一个 package 声明开始,这可以避免不同项目的命名冲突。在 C++,你生成的类会被置于与 package 名字一样的命名空间。
+
+下一步,你需要定义消息(message)。消息只是一个包含一系列类型字段的集合。大多标准简单数据类型是可以作为字段类型的,包括 `bool`、`int32`、`float`、`double` 和 `string`。你也可以通过使用其他消息类型作为字段类型,将更多的数据结构添加到你的消息中——在以上的示例,`Person` 消息包含了 `PhoneNumber` 消息,同时 `AddressBook` 消息包含 `Person` 消息。你甚至可以定义嵌套在其他消息内的消息类型——如你所见,`PhoneNumber` 类型定义于 `Person` 内部。如果你想要其中某一个字段拥有预定义值列表中的某个值,你也可以定义 `enum` 类型——这儿你想指定一个电话号码可以是 `MOBILE`、`HOME` 或 `WORK` 中的某一个。
+
+每一个元素上的 “=1”、"=2" 标记确定了用于二进制编码的唯一"标签"(tag)。标签数字 1-15 的编码比更大的数字少需要一个字节,因此作为一种优化,你可以将这些标签用于经常使用或 repeated 元素,剩下 16 以及更高的标签用于非经常使用或 optional 元素。每一个 repeated 字段的元素需要重新编码标签数字,因此 repeated 字段对于这优化是一个特别好的候选者。
+
+每一个字段必须使用下面的修饰符加以标注:
+
+* required:必须提供字段的值,否则消息会被认为是 "未初始化的"(uninitialized)。如果 `libprotobuf` 以 debug 模式编译,序列化未初始化的消息将引起一个断言失败。以优化形式构建,将会跳过检查,并且无论如何都会写入消息。然而,解析未初始化的消息总是会失败(通过 parse 方法返回 `false`)。除此之外,一个 required 字段的表现与 optional 字段完全一样。
+
+* optional:字段可能会被设置,也可能不会。如果一个 optional 字段没被设置,它将使用默认值。对于简单类型,你可以指定你自己的默认值,正如例子中我们对电话号码的 `type` 一样,否则使用系统默认值:数字类型为 0、字符串为空字符串、布尔值为 false。对于嵌套消息,默认值总为消息的"默认实例"或"原型",它的所有字段都没被设置。调用 accessor 来获取一个没有显式设置的 optional(或 required) 字段的值总是返回字段的默认值。
+
+* repeated:字段可以重复任意次数(包括 0)。repeated 值的顺序会被保存于 protocol buffer。可以将 repeated 字段想象为动态大小的数组。
+
+你可以查找关于编写 `.proto` 文件的完整指导——包括所有可能的字段类型——在 [Protocol Buffer Language Guide][6]。不要在这里面查找与类继承相似的特性,因为 protocol buffers 不会做这些。
+
+> required 是永久性的,在把一个字段标识为 required 的时候,你应该特别小心。如果在某些情况下你不想写入或者发送一个 required 的字段,那么将该字段更改为 optional 可能会遇到问题——旧版本的读者(译者注:即读取、解析旧版本 Protocol Buffer 消息的一方)会认为不含该字段的消息是不完整的,从而有可能会拒绝解析。在这种情况下,你应该考虑编写特别针对于应用程序的、自定义的消息校验函数。Google 的一些工程师得出了一个结论:使用 required 弊多于利;他们更愿意使用 optional 和 repeated 而不是 required。当然,这个观点并不具有普遍性。
+
+### 编译你的 Protocol Buffers
+
+既然你有了一个 `.proto`,那你需要做的下一件事就是生成一个将用于读写 `AddressBook` 消息的类(从而包括 `Person` 和 `PhoneNumber`)。为了做到这样,你需要在你的 `.proto` 上运行 protocol buffer 编译器 `protoc`:
+
+1. 如果你没有安装编译器,请[下载这个包][4],并按照 README 中的指令进行安装。
+2. 现在运行编译器,知道源目录(你的应用程序源代码位于哪里——如果你没有提供任何值,将使用当前目录),目标目录(你想要生成的代码放在哪里;常与 `$SRC_DIR` 相同),并且你的 `.proto` 路径。在此示例,你...:
+
+```
+protoc -I=$SRC_DIR --cpp_out=$DST_DIR $SRC_DIR/addressbook.proto
+```
+
+因为你想要 C++ 的类,所以你使用了 `--cpp_out` 选项——也为其他支持的语言提供了类似选项。
+
+在你指定的目标文件夹,将生成以下的文件:
+
+* `addressbook.pb.h`,声明你生成类的头文件。
+* `addressbook.pb.cc`,包含你的类的实现。
+
+### Protocol Buffer API
+
+让我们看看生成的一些代码,了解一下编译器为你创建了什么类和函数。如果你查看 `tutorial.pb.h`,你可以看到有一个在 `tutorial.proto` 中指定所有消息的类。关注 `Person` 类,可以看到编译器为每个字段生成了读写函数(accessors)。例如,对于 `name`、`id`、`email` 和 `phone` 字段,有下面这些方法:
+
+```c++
+// name
+inline bool has_name() const;
+inline void clear_name();
+inline const ::std::string& name() const;
+inline void set_name(const ::std::string& value);
+inline void set_name(const char* value);
+inline ::std::string* mutable_name();
+
+// id
+inline bool has_id() const;
+inline void clear_id();
+inline int32_t id() const;
+inline void set_id(int32_t value);
+
+// email
+inline bool has_email() const;
+inline void clear_email();
+inline const ::std::string& email() const;
+inline void set_email(const ::std::string& value);
+inline void set_email(const char* value);
+inline ::std::string* mutable_email();
+
+// phone
+inline int phone_size() const;
+inline void clear_phone();
+inline const ::google::protobuf::RepeatedPtrField< ::tutorial::Person_PhoneNumber >& phone() const;
+inline ::google::protobuf::RepeatedPtrField< ::tutorial::Person_PhoneNumber >* mutable_phone();
+inline const ::tutorial::Person_PhoneNumber& phone(int index) const;
+inline ::tutorial::Person_PhoneNumber* mutable_phone(int index);
+inline ::tutorial::Person_PhoneNumber* add_phone();
+```
+
+正如你所见到,getters 的名字与字段的小写名字完全一样,并且 setter 方法以 set_ 开头。同时每个单一(singular)(required 或 optional)字段都有 `has_` 方法,该方法在字段被设置了值的情况下返回 true。最后,所有字段都有一个 `clear_` 方法,用以清除字段到空(empty)状态。
+
+数字 `id` 字段仅有上述的基本读写函数集合(accessors),而 `name` 和 `email` 字段有两个额外的方法,因为它们是字符串——一个是可以获得字符串直接指针的`mutable_` getter ,另一个为额外的 setter。注意,尽管 `email` 还没被设置(set),你也可以调用 `mutable_email`;因为 `email` 会被自动地初始化为空字符串。在本例中,如果你有一个单一的(required 或 optional)消息字段,它会有一个 `mutable_` 方法,而没有 `set_` 方法。
+
+repeated 字段也有一些特殊的方法——如果你看看 repeated `phone` 字段的方法,你可以看到:
+
+* 检查 repeated 字段的 `_size`(也就是说,与 `Person` 相关的电话号码的个数)
+* 使用下标取得特定的电话号码
+* 更新特定下标的电话号码
+* 添加新的电话号码到消息中,之后你便可以编辑。(repeated 标量类型有一个 `add_` 方法,用于传入新的值)
+
+为了获取 protocol 编译器为所有字段定义生成的方法的信息,可以查看 [C++ generated code reference][5]。
+
+#### 枚举和嵌套类(Enums and Nested Classes)
+
+与 `.proto` 的枚举相对应,生成的代码包含了一个 `PhoneType` 枚举。你可以通过 `Person::PhoneType` 引用这个类型,通过 `Person::MOBILE`、`Person::HOME` 和 `Person::WORK` 引用它的值。(实现细节有点复杂,但是你无须了解它们而可以直接使用)
+
+编译器也生成了一个 `Person::PhoneNumber` 的嵌套类。如果你查看代码,你可以发现真正的类型为 `Person_PhoneNumber`,但它通过在 `Person` 内部使用 typedef 定义,使你可以把 `Person_PhoneNumber` 当成嵌套类。唯一产生影响的一个例子是,如果你想要在其他文件前置声明该类——在 C++ 中你不能前置声明嵌套类,但是你可以前置声明 `Person_PhoneNumber`。
+
+#### 标准的消息方法
+
+所有的消息方法都包含了许多别的方法,用于检查和操作整个消息,包括:
+
+* `bool IsInitialized() const;` :检查是否所有 `required` 字段已经被设置。
+* `string DebugString() const;`:返回人类可读的消息表示,对 debug 特别有用。
+* `void CopyFrom(const Person& from);`:使用给定的值重写消息。
+* `void Clear();`:清除所有元素为空(empty)的状态。
+
+上面这些方法以及下一节要讲的 I/O 方法实现了被所有 C++ protocol buffer 类共享的消息(Message)接口。为了获取更多信息,请查看 [complete API documentation for Message][7]。
+
+#### 解析和序列化(Parsing and Serialization)
+
+最后,所有 protocol buffer 类都有读写你选定类型消息的方法,这些方法使用了特定的 protocol buffer [二进制格式][8]。这些方法包括:
+
+* `bool SerializeToString(string* output) const;`:序列化消息以及将消息字节数据存储在给定的字符串。注意,字节数据是二进制格式的,而不是文本格式;我们只使用 `string` 类作为合适的容器。
+* `bool ParseFromString(const string& data);`:从给定的字符创解析消息。
+* `bool SerializeToOstream(ostream* output) const;`:将消息写到给定的 C++ `ostream`。
+* `bool ParseFromIstream(istream* input);`:从给定的 C++ `istream` 解析消息。
+
+这些只是两个用于解析和序列化的选择。再次说明,可以查看 `Message API reference` 完整的列表。
+
+> Protocol Buffers 和 面向对象设计的 Protocol buffer 类通常只是纯粹的数据存储器(像 C++ 中的结构体);它们在对象模型中并不是一等公民。如果你想向生成的 protocol buffer 类中添加更丰富的行为,最好的方法就是在应用程序中对它进行封装。如果你无权控制 .proto 文件的设计的话,封装 protocol buffers 也是一个好主意(例如,你从另一个项目中重用一个 .proto 文件)。在那种情况下,你可以用封装类来设计接口,以更好地适应你的应用程序的特定环境:隐藏一些数据和方法,暴露一些便于使用的函数,等等。但是你绝对不要通过继承生成的类来添加行为。这样做的话,会破坏其内部机制,并且不是一个好的面向对象的实践。
+
+### 写消息(Writing A Message)
+
+现在我们尝试使用 protocol buffer 类。你的地址簿程序想要做的第一件事是将个人详细信息写入到地址簿文件。为了做到这一点,你需要创建、填充 protocol buffer 类实例,并且将它们写入到一个输出流(output stream)。
+
+这里的程序可以从文件读取 `AddressBook`,根据用户输入,将新 `Person` 添加到 `AddressBook`,并且再次将新的 `AddressBook` 写回文件。这部分直接调用或引用 protocol buffer 类的代码会高亮显示。
+
+```c++
+#include
+#include
+#include
+#include "addressbook.pb.h"
+using namespace std;
+
+// This function fills in a Person message based on user input.
+void PromptForAddress(tutorial::Person* person) {
+ cout << "Enter person ID number: ";
+ int id;
+ cin >> id;
+ person->set_id(id);
+ cin.ignore(256, '\n');
+
+ cout << "Enter name: ";
+ getline(cin, *person->mutable_name());
+
+ cout << "Enter email address (blank for none): ";
+ string email;
+ getline(cin, email);
+ if (!email.empty()) {
+ person->set_email(email);
+ }
+
+ while (true) {
+ cout << "Enter a phone number (or leave blank to finish): ";
+ string number;
+ getline(cin, number);
+ if (number.empty()) {
+ break;
+ }
+
+ tutorial::Person::PhoneNumber* phone_number = person->add_phone();
+ phone_number->set_number(number);
+
+ cout << "Is this a mobile, home, or work phone? ";
+ string type;
+ getline(cin, type);
+ if (type == "mobile") {
+ phone_number->set_type(tutorial::Person::MOBILE);
+ } else if (type == "home") {
+ phone_number->set_type(tutorial::Person::HOME);
+ } else if (type == "work") {
+ phone_number->set_type(tutorial::Person::WORK);
+ } else {
+ cout << "Unknown phone type. Using default." << endl;
+ }
+ }
+}
+
+// Main function: Reads the entire address book from a file,
+// adds one person based on user input, then writes it back out to the same
+// file.
+int main(int argc, char* argv[]) {
+ // Verify that the version of the library that we linked against is
+ // compatible with the version of the headers we compiled against.
+ GOOGLE_PROTOBUF_VERIFY_VERSION;
+
+ if (argc != 2) {
+ cerr << "Usage: " << argv[0] << " ADDRESS_BOOK_FILE" << endl;
+ return -1;
+ }
+
+ tutorial::AddressBook address_book;
+
+ {
+ // Read the existing address book.
+ fstream input(argv[1], ios::in | ios::binary);
+ if (!input) {
+ cout << argv[1] << ": File not found. Creating a new file." << endl;
+ } else if (!address_book.ParseFromIstream(&input)) {
+ cerr << "Failed to parse address book." << endl;
+ return -1;
+ }
+ }
+
+ // Add an address.
+ PromptForAddress(address_book.add_person());
+
+ {
+ // Write the new address book back to disk.
+ fstream output(argv[1], ios::out | ios::trunc | ios::binary);
+ if (!address_book.SerializeToOstream(&output)) {
+ cerr << "Failed to write address book." << endl;
+ return -1;
+ }
+ }
+
+ // Optional: Delete all global objects allocated by libprotobuf.
+ google::protobuf::ShutdownProtobufLibrary();
+
+ return 0;
+}
+```
+
+注意 `GOOGLE_PROTOBUF_VERIFY_VERSION` 宏。它是一种好的实践——虽然不是严格必须的——在使用 C++ Protocol Buffer 库之前执行该宏。它可以保证避免不小心链接到一个与编译的头文件版本不兼容的库版本。如果被检查出来版本不匹配,程序将会终止。注意,每个 `.pb.cc` 文件在初始化时会自动调用这个宏。
+
+同时注意在程序最后调用 `ShutdownProtobufLibrary()`。它用于释放 Protocol Buffer 库申请的所有全局对象。对大部分程序,这不是必须的,因为虽然程序只是简单退出,但是 OS 会处理释放程序的所有内存。然而,如果你使用了内存泄漏检测工具,工具要求全部对象都要释放,或者你正在写一个库,该库可能会被一个进程多次加载和卸载,那么你可能需要强制 Protocol Buffer 清除所有东西。
+
+### 读取消息
+
+当然,如果你无法从它获取任何信息,那么这个地址簿没多大用处!这个示例读取上面例子创建的文件,并打印文件里的所有内容。
+
+```c++
+#include
+#include
+#include
+#include "addressbook.pb.h"
+using namespace std;
+
+// Iterates though all people in the AddressBook and prints info about them.
+void ListPeople(const tutorial::AddressBook& address_book) {
+ for (int i = 0; i < address_book.person_size(); i++) {
+ const tutorial::Person& person = address_book.person(i);
+
+ cout << "Person ID: " << person.id() << endl;
+ cout << " Name: " << person.name() << endl;
+ if (person.has_email()) {
+ cout << " E-mail address: " << person.email() << endl;
+ }
+
+ for (int j = 0; j < person.phone_size(); j++) {
+ const tutorial::Person::PhoneNumber& phone_number = person.phone(j);
+
+ switch (phone_number.type()) {
+ case tutorial::Person::MOBILE:
+ cout << " Mobile phone #: ";
+ break;
+ case tutorial::Person::HOME:
+ cout << " Home phone #: ";
+ break;
+ case tutorial::Person::WORK:
+ cout << " Work phone #: ";
+ break;
+ }
+ cout << phone_number.number() << endl;
+ }
+ }
+}
+
+// Main function: Reads the entire address book from a file and prints all
+// the information inside.
+int main(int argc, char* argv[]) {
+ // Verify that the version of the library that we linked against is
+ // compatible with the version of the headers we compiled against.
+ GOOGLE_PROTOBUF_VERIFY_VERSION;
+
+ if (argc != 2) {
+ cerr << "Usage: " << argv[0] << " ADDRESS_BOOK_FILE" << endl;
+ return -1;
+ }
+
+ tutorial::AddressBook address_book;
+
+ {
+ // Read the existing address book.
+ fstream input(argv[1], ios::in | ios::binary);
+ if (!address_book.ParseFromIstream(&input)) {
+ cerr << "Failed to parse address book." << endl;
+ return -1;
+ }
+ }
+
+ ListPeople(address_book);
+
+ // Optional: Delete all global objects allocated by libprotobuf.
+ google::protobuf::ShutdownProtobufLibrary();
+
+ return 0;
+}
+```
+
+### 扩展 Protocol Buffer
+
+早晚在你发布了使用 protocol buffer 的代码之后,毫无疑问,你会想要 "改善"
+ protocol buffer 的定义。如果你想要新的 buffers 向后兼容,并且老的 buffers 向前兼容——几乎可以肯定你很渴望这个——这里有一些规则,你需要遵守。在新的 protocol buffer 版本:
+
+ * 你绝不可以修改任何已存在字段的标签数字
+ * 你绝不可以添加或删除任何 required 字段
+ * 你可以删除 optional 或 repeated 字段
+ * 你可以添加新的 optional 或 repeated 字段,但是你必须使用新的标签数字(也就是说,标签数字在 protocol buffer 中从未使用过,甚至不能是已删除字段的标签数字)。
+
+ (这是对于上面规则的一些[异常情况][9],但它们很少用到。)
+
+ 如果你能遵守这些规则,旧代码则可以欢快地读取新的消息,并且简单地忽略所有新的字段。对于旧代码来说,被删除的 optional 字段将会简单地赋予默认值,被删除的 `repeated` 字段会为空。新代码显然可以读取旧消息。然而,请记住新的 optional 字段不会呈现在旧消息中,因此你需要显式地使用 `has_` 检查它们是否被设置或者在 `.proto` 文件在标签数字后使用 `[default = value]` 提供一个合理的默认值。如果一个 optional 元素没有指定默认值,它将会使用类型特定的默认值:对于字符串,默认值为空字符串;对于布尔值,默认值为 false;对于数字类型,默认类型为 0。注意,如果你添加一个新的 repeated 字段,新代码将无法辨别它被留空(left empty)(被新代码)或者从没被设置(被旧代码),因为 repeated 字段没有 `has_` 标志。
+
+### 优化技巧
+
+C++ Protocol Buffer 库已极度优化过了。但是,恰当的用法能够更多地提高性能。这里是一些技巧,可以帮你从库中挤压出最后一点速度:
+
+* 尽可能复用消息对象。即使它们被清除掉,消息也会尽量保存所有被分配来重用的内存。因此,如果我们正在处理许多相同类型或一系列相似结构的消息,一个好的办法是重用相同的消息对象,从而减少内存分配的负担。但是,随着时间的流逝,对象可能会膨胀变大,尤其是当你的消息尺寸(译者注:各消息内容不同,有些消息内容多一些,有些消息内容少一些)不同的时候,或者你偶尔创建了一个比平常大很多的消息的时候。你应该自己通过调用 [SpaceUsed][10] 方法监测消息对象的大小,并在它太大的时候删除它。
+
+* 对于在多线程中分配大量小对象的情况,你的操作系统内存分配器可能优化得不够好。你可以尝试使用 google 的 [tcmalloc][11]。
+
+### 高级用法
+
+Protocol Buffers 绝不仅用于简单的数据存取以及序列化。请阅读 [C++ API reference][12] 来看看你还能用它来做什么。
+
+protocol 消息类所提供的一个关键特性就是反射。你不需要编写针对一个特殊的消息类型的代码,就可以遍历一个消息的字段并操作它们的值。一个使用反射的有用方法是 protocol 消息与其他编码互相转换,比如 XML 或 JSON。反射的一个更高级的用法可能就是可以找出两个相同类型的消息之间的区别,或者开发某种 "协议消息的正则表达式",利用正则表达式,你可以对某种消息内容进行匹配。只要你发挥你的想像力,就有可能将 Protocol Buffers 应用到一个更广泛的、你可能一开始就期望解决的问题范围上。
+
+反射是由 [Message::Reflection interface][13] 提供的。
+
+--------------------------------------------------------------------------------
+
+via: https://developers.google.com/protocol-buffers/docs/cpptutorial
+
+作者:[Google][a]
+译者:[cposture](https://github.com/cposture)
+校对:[校对者ID](https://github.com/校对者ID)
+
+本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
+
+[a]: https://developers.google.com/protocol-buffers/docs/cpptutorial
+[1]: https://developers.google.com/protocol-buffers/docs/proto
+[2]: https://developers.google.com/protocol-buffers/docs/encoding
+[3]: https://developers.google.com/protocol-buffers/docs/downloads
+[4]: https://developers.google.com/protocol-buffers/docs/downloads.html
+[5]: https://developers.google.com/protocol-buffers/docs/reference/cpp-generated
+[6]: https://developers.google.com/protocol-buffers/docs/proto
+[7]: https://developers.google.com/protocol-buffers/docs/reference/cpp/google.protobuf.message.html#Message
+[8]: https://developers.google.com/protocol-buffers/docs/encoding
+[9]: https://developers.google.com/protocol-buffers/docs/proto#updating
+[10]: https://developers.google.com/protocol-buffers/docs/reference/cpp/google.protobuf.message.html#Message.SpaceUsed.details
+[11]: http://code.google.com/p/google-perftools/
+[12]: https://developers.google.com/protocol-buffers/docs/reference/cpp/index.html
+[13]: https://developers.google.com/protocol-buffers/docs/reference/cpp/google.protobuf.message.html#Message.Reflection
diff --git a/translated/tech/LFCS/Part 13 - How to Configure and Troubleshoot Grand Unified Bootloader (GRUB).md b/translated/tech/LFCS/Part 13 - How to Configure and Troubleshoot Grand Unified Bootloader (GRUB).md
new file mode 100644
index 0000000000..d8b7b294e2
--- /dev/null
+++ b/translated/tech/LFCS/Part 13 - How to Configure and Troubleshoot Grand Unified Bootloader (GRUB).md
@@ -0,0 +1,184 @@
+LFCS 系列第十三讲:如何配置并排除 GNU 引导加载程序(GRUB)故障
+=====================================================================================
+
+由于 LFCS 考试需求的变动已于 2016 年 2 月 2 日生效,因此我们向 [LFCS 系列][1] 添加了一些必要的话题。为了准备认证考试,我们也强烈推荐你去看 [LFCE 系列][2]。
+
+![](http://www.tecmint.com/wp-content/uploads/2016/03/Configure-Troubleshoot-Grub-Boot-Loader.png)
+>LFCS 系列第十三讲:配置并排除 Grub 引导加载程序故障。
+
+本文将会向你介绍 GRUB 的知识,并会说明你为什么需要一个引导加载程序,以及它是如何增强系统通用性的。
+
+[Linux 引导过程][3] 是从你按下你的电脑电源键开始,直到你拥有一个全功能的系统为止,整个过程遵循着这样的高层次顺序:
+
+* 1. 一个叫做 **POST**(**上电自检**)的过程会对你的电脑硬件组件做全面的检查。
+* 2. 当 **POST** 完成后,它会把控制权转交给引导加载程序,接下来引导加载程序会将 Linux 内核(以及 **initramfs**)加载到内存中并执行。
+* 3. 内核首先检查并访问硬件,然后运行初始进程(主要以它的通用名 **init** 而为人熟知),接下来初始进程会启动一些服务,最后完成系统启动过程。
+
+在该系列的第七讲(“[SysVinit, Upstart, 和 Systemd][4]”)中,我们介绍了现代 Linux 发行版使用的一些服务管理系统和工具。在继续学习之前,你可能想要回顾一下那一讲的知识。
+
+### GRUB 引导装载程序介绍
+
+在现代系统中,你会发现有两种主要的 **GRUB** 版本(一种是偶尔被成为 **GRUB Legacy** 的 **v1** 版本,另一种则是 **v2** 版本),虽说多数最新版本的发行版系统都默认使用了 **v2** 版本。如今,只有 **红帽企业版 Linux 6** 及其衍生系统仍在使用 **v1** 版本。
+
+因此,在本指南中,我们将着重关注 **v2** 版本的功能。
+
+不管 **GRUB** 的版本是什么,一个引导加载程序都允许用户:
+
+* 1). 通过指定使用不同的内核来修改系统的表现方式;
+* 2). 从多个操作系统中选择一个启动;
+* 3). 添加或编辑配置节点来改变启动选项等。
+
+如今,**GNU** 项目负责维护 **GRUB**,并在它们的网站上提供了丰富的文档。当你在阅读这篇指南时,我们强烈建议你看下 [GNU 官方文档][6]。
+
+当系统引导时,你会在主控制台看到如下的 **GRUB** 画面。最开始,你可以根据提示在多个内核版本中选择一个内核(默认情况下,系统将会使用最新的内核启动),并且可以进入 **GRUB** 命令行模式(使用 `c` 键),或者编辑启动项(按下 `e` 键)。
+
+![](http://www.tecmint.com/wp-content/uploads/2016/03/GRUB-Boot-Screen.png)
+> GRUB 启动画面
+
+你会考虑使用一个旧版内核启动的原因之一是之前工作正常的某个硬件设备在一次升级后出现了“怪毛病(acting up)”(例如,你可以参考 AskUbuntu 论坛中的 [这条链接][7])。
+
+**GRUB v2** 的配置文件会在启动时从 `/boot/grub/grub.cfg` 或 `/boot/grub2/grub.cfg` 文件中读取,而 **GRUB v1** 使用的配置文件则来自 `/boot/grub/grub.conf` 或 `/boot/grub/menu.lst`。这些文件不能直接手动编辑,而是根据 `/etc/default/grub` 的内容和 `/etc/grub.d` 目录中的文件来修改的。
+
+在 **CentOS 7** 上,当系统最初完成安装后,会生成如下的配置文件:
+
+```
+GRUB_TIMEOUT=5
+GRUB_DISTRIBUTOR="$(sed 's, release .*$,,g' /etc/system-release)"
+GRUB_DEFAULT=saved
+GRUB_DISABLE_SUBMENU=true
+GRUB_TERMINAL_OUTPUT="console"
+GRUB_CMDLINE_LINUX="vconsole.keymap=la-latin1 rd.lvm.lv=centos_centos7-2/swap crashkernel=auto vconsole.font=latarcyrheb-sun16 rd.lvm.lv=centos_centos7-2/root rhgb quiet"
+GRUB_DISABLE_RECOVERY="true"
+```
+
+除了在线文档外,你也可以使用下面的命令查阅 GNU GRUB 手册:
+
+```
+# info grub
+```
+
+如果你对 `/etc/default/grub` 文件中的可用选项特别感兴趣的话,你可以直接查阅配置一节的帮助文档:
+
+```
+# info -f grub -n 'Simple configuration'
+```
+
+使用上述命令,你会发现 `GRUB_TIMEOUT` 用于设置启动画面出现和系统自动开始启动(除非被用户中断)之间的时间。当该变量值为 `-1` 时,除非用户主动做出选择,否则不会开始启动。
+
+当同一台机器上安装了多个操作系统或内核后,`GRUB_DEFAULT` 就需要用一个整数来指定 GRUB 启动画面默认选择启动的操作系统或内核条目。我们既可以通过上述启动画查看启动条目列表,也可以使用下面的命令:
+
+### 在 CentOS 和 openSUSE 系统上
+
+```
+# awk -F\' '$1=="menuentry " {print $2}' /boot/grub2/grub.cfg
+```
+
+### 在 Ubuntu 系统上
+
+```
+# awk -F\' '$1=="menuentry " {print $2}' /boot/grub/grub.cfg
+```
+
+如下图所示的例子中,如果我们想要使用版本为 `3.10.0-123.el7.x86_64` 的内核(第四个条目),我们需要将 `GRUB_DEFAULT` 设置为 `3`(条目从零开始编号),如下所示:
+
+```
+GRUB_DEFAULT=3
+```
+
+![](http://www.tecmint.com/wp-content/uploads/2016/03/Boot-System-with-Old-Kernel-Version.png)
+> 使用旧版内核启动系统
+
+最后一个需要特别关注的 GRUB 配置变量是 `GRUB_CMDLINE_LINUX`,它是用来给内核传递选项的。我们可以在 [内核变量文件][8] 和 [man 7 bootparam][9] 中找到能够通过 GRUB 传递给内核的选项的详细文档。
+
+我的 **CentOS 7** 服务器上当前的选项是:
+
+```
+GRUB_CMDLINE_LINUX="vconsole.keymap=la-latin1 rd.lvm.lv=centos_centos7-2/swap crashkernel=auto vconsole.font=latarcyrheb-sun16 rd.lvm.lv=centos_centos7-2/root rhgb quiet"
+```
+为什么你希望修改默认的内核参数或者传递额外的选项呢?简单来说,在很多情况下,你需要告诉内核某些由内核自身无法判断的硬件参数,或者是覆盖一些内核会检测的值。
+
+不久之前,就在我身上发生过这样的事情,当时我在自己已用了 10 年的老笔记本上尝试衍生自 **Slackware** 的 **Vector Linux**。完成安装后,内核并没有检测出我的显卡的正确配置,所以我不得不通过 GRUB 传递修改过的内核选项来让它工作。
+
+另外一个例子是当你需要将系统切换到单用户模式以执行维护工作时。为此,你可以直接在 `GRUB_CMDLINE_LINUX` 变量中直接追加 `single` 并重启即可:
+
+```
+GRUB_CMDLINE_LINUX="vconsole.keymap=la-latin1 rd.lvm.lv=centos_centos7-2/swap crashkernel=auto vconsole.font=latarcyrheb-sun16 rd.lvm.lv=centos_centos7-2/root rhgb quiet single"
+```
+
+编辑完 `/etc/default/grub` 之后,你需要运行 `update-grub` (在 Ubuntu 上)或者 `grub2-mkconfig -o /boot/grub2/grub.cfg` (在 **CentOS** 和 **openSUSE** 上)命令来更新 `grub.cfg` 文件(否则,改动会在系统启动时丢失)。
+
+这条命令会处理早先提到的一些启动配置文件来更新 `grub.cfg` 文件。这种方法可以确保改动持久化,而在启动时刻通过 GRUB 传递的选项仅在当前会话期间有效。
+
+### 修复 Linux GRUB 问题
+
+如果你安装了第二个操作系统,或者由于人为失误而导致你的 GRUB 配置文件损坏了,依然有一些方法可以让你恢复并能够再次启动系统。
+
+在启动画面中按下 `c` 键进入 GRUB 命令行模式(记住,你也可以按下 `e` 键编辑默认启动选项),并可以在 GRUB 提示中输入 `help` 命令获得可用命令:
+
+![](http://www.tecmint.com/wp-content/uploads/2016/03/Fix-Grub-Issues-in-Linux.png)
+> 修复 Linux 的 Grub 配置问题
+
+我们将会着重关注 **ls** 命令,它会列出已安装的设备和文件系统,并且我们将会看看它可以查找什么。在下面的图片中,我们可以看到有 4 块硬盘(`hd0` 到 `hd3`)。
+
+貌似只有 `hd0` 已经分区了(msdos1 和 msdos2 可以证明,这里的 1 和 2 是分区号,msdos 则是分区方案)。
+
+现在我们来看看能否在第一个分区 `hd0`(**msdos1**)上找到 GRUB。这种方法允许我们启动 Linux,并且使用高级工具修复配置文件或者如果有必要的话,干脆重新安装 GRUB:
+
+```
+# ls (hd0,msdos1)/
+```
+
+从高亮区域可以发现,`grub2` 目录就在这个分区:
+
+![](http://www.tecmint.com/wp-content/uploads/2016/03/Find-Grub-Configuration.png)
+> 查找 Grub 配置
+
+一旦我们确信了 GRUB 位于 (**hd0, msdos1**),那就让我们告诉 GRUB 该去哪儿查找它的配置文件并指示它去尝试启动它的菜单:
+
+```
+set prefix=(hd0,msdos1)/grub2
+set root=(hd0,msdos1)
+insmod normal
+normal
+```
+
+![](http://www.tecmint.com/wp-content/uploads/2016/03/Find-and-Launch-Grub-Menu.png)
+> 查找并启动 Grub 菜单
+
+然后,在 GRUB 菜单中,选择一个条目并按下 **Enter** 键以使用它启动。一旦系统成功启动后,你就可以运行 `grub2-install /dev/sdX` 命令修复问题了(将 `sdX` 改成你想要安装 GRUB 的设备)。然后启动信息将会更新,并且所有相关文件都会得到恢复。
+
+```
+# grub2-install /dev/sdX
+```
+
+其它更加复杂的情景及其修复建议都记录在 [Ubuntu GRUB2 故障排除指南][10] 中。该指南中阐述的概念对于其它发行版也是有效的。
+
+### 总结
+
+本文向你介绍了 GRUB,并指导你可以在何处找到线上和线下的文档,同时说明了如何面对由于引导加载相关的问题而导致系统无法正常启动的情况。
+
+幸运的是,GRUB 是文档支持非常丰富的工具之一,你可以使用我们在文中分享的资源非常轻松地获取已安装的文档或在线文档。
+
+你有什么问题或建议吗?请不要犹豫,使用下面的评论框告诉我们吧。我们期待着来自你的回复!
+
+--------------------------------------------------------------------------------
+
+via: http://www.tecmint.com/configure-and-troubleshoot-grub-boot-loader-linux/
+
+作者:[Gabriel Cánepa][a]
+译者:[ChrisLeeGit](https://github.com/chrisleegit)
+校对:[校对者ID](https://github.com/校对者ID)
+
+本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创翻译,[Linux中国](https://linux.cn/) 荣誉推出
+
+[a]: http://www.tecmint.com/author/gacanepa/
+[1]: http://www.tecmint.com/sed-command-to-create-edit-and-manipulate-files-in-linux/
+[2]: http://www.tecmint.com/installing-network-services-and-configuring-services-at-system-boot/
+[3]: http://www.tecmint.com/linux-boot-process/
+[4]: http://www.tecmint.com/linux-boot-process-and-manage-services/
+[5]: http://www.tecmint.com/best-linux-log-monitoring-and-management-tools/
+[6]: http://www.gnu.org/software/grub/manual/
+[7]: http://askubuntu.com/questions/82140/how-can-i-boot-with-an-older-kernel-version
+[8]: https://www.kernel.org/doc/Documentation/kernel-parameters.txt
+[9]: http://man7.org/linux/man-pages/man7/bootparam.7.html
+[10]: https://help.ubuntu.com/community/Grub2/Troubleshooting
diff --git a/translated/tech/LXD/Part 3 - LXD 2.0--Your first LXD container.md b/translated/tech/LXD/Part 3 - LXD 2.0--Your first LXD container.md
deleted file mode 100644
index 4b6dcfd8aa..0000000000
--- a/translated/tech/LXD/Part 3 - LXD 2.0--Your first LXD container.md
+++ /dev/null
@@ -1,438 +0,0 @@
-kylepeng93 is translating
-你的地一个LXD容器
-==========================================
-
-这是第三篇发布的博客[LXD2.0系列]
-由于在管理LXD容器时涉及到大量的命令,所以这篇文章的篇幅是比较长的,如果你更喜欢使用同样的命令来快速的一步步实现整个过程,你可以[尝试我们的在线示例]!
-![](https://linuxcontainers.org/static/img/containers.png)
-
-### 创建并启动一个新的容器
-正如我在先前的文章中提到的一样,LXD命令行客户端使用了少量的图片来做了一个预配置。Ubuntu的所有发行版和架构平台都拥有最好的官方图片,但是对于其他的发行版仍然有大量的非官方图片,那些图片都是由社区制作并且被LXC上层贡献者所维护。
-### Ubuntu
-如果你想要支持最为完善的ubuntu版本,你可以按照下面的去做:
-```
-lxc launch ubuntu:
-```
-注意,这里所做的解释会随着ubuntu LTS的发布而变化。因此对于你使用的脚本应该取决于下面提到的具体你想要安装的版本:
-###Ubuntu14.04 LTS
-得到最新的,已经测试过的,稳定的ubuntu14.04 LTS镜像,你可以简单的执行:
-```
-lxc launch ubuntu:14.04
-```
-这该模式下,一个任意的容器名将会被指定给它。
-如果你更喜欢指定一个你自己的命令,你可以这样做:
-```
-lxc launch ubuntu:14.04 c1
-```
-
-如果你想要指定一个特定的体系架构(非主要的),比如32位Intel镜像,你可以这样做:
-```
-lxc launch ubuntu:14.04/i386 c2
-```
-
-### 当前的Ubuntu开发版本
-上面使用的“ubuntu:”远程方式只会给你提供官方的并经过测试的ubuntu镜像。但是如果你想要未经测试过的日常构建版本,开发版可能对你来说是合适的,你将要使用“ubuntu-daily”来远程获取。
-```
-lxc launch ubuntu-daily:devel c3
-```
-
-在这个例子中,最新的ubuntu开发版本将会被选自动选中。
-你也可以更加精确,比如你可以使用代号名:
-```
-lxc launch ubuntu-daily:xenial c4
-```
-
-### 最新的Alpine Linux
-Alpine镜像在“Images:”远程中可用,可以通过如下命令执行:
-```
-lxc launch images:alpine/3.3/amd64 c5
-```
-
-### And many more
-### 其他
-所有ubuntu镜像列表可以这样获得:
-```
-lxc image list ubuntu:
-lxc image list ubuntu-daily:
-```
-
-所有的非官方镜像:
-```
-lxc image list images:
-```
-
-所有给定的可用远程别名清单可以这样获得(针对“ubuntu:”远程):
-```
-lxc image alias list ubuntu:
-```
-
-
-### 创建但不启动一个容器
-如果你想创建一个容器或者一批容器,但是你不想马上启动他们,你可以使用“lxc init”替换掉“lxc launch”。所有的选项都是相同的,唯一的不同就是它并不会在你创建完成之后启动容器。
-```
-lxc init ubuntu:
-```
-
-### 关于你的容器的信息
-### 列出所有的容器
-为了列出你的所有容器,你可以这样这做:
-```
-lxc list
-```
-
-有大量的选项供你选择来改变被显示出来的列。在一个拥有大量容器的系统上,默认显示的列可能会有点慢(因为必须获取容器中的网络信息),你可以这样做来避免这种情况:
-```
-lxc list --fast
-```
-
-上面的命令显示了一个不同的列的集合,这个集合在服务器端需要处理的信息更少。
-你也可以基于名字或者属性来过滤掉一些东西:
-```
-stgraber@dakara:~$ lxc list security.privileged=true
-+------+---------+---------------------+-----------------------------------------------+------------+-----------+
-| NAME | STATE | IPV4 | IPV6 | TYPE | SNAPSHOTS |
-+------+---------+---------------------+-----------------------------------------------+------------+-----------+
-| suse | RUNNING | 172.17.0.105 (eth0) | 2607:f2c0:f00f:2700:216:3eff:fef2:aff4 (eth0) | PERSISTENT | 0 |
-+------+---------+---------------------+-----------------------------------------------+------------+-----------+
-```
-
-在这个例子中,只有那些有特权(用户命名空间不可用)的容器才会被列出来。
-```
-stgraber@dakara:~$ lxc list --fast alpine
-+-------------+---------+--------------+----------------------+----------+------------+
-| NAME | STATE | ARCHITECTURE | CREATED AT | PROFILES | TYPE |
-+-------------+---------+--------------+----------------------+----------+------------+
-| alpine | RUNNING | x86_64 | 2016/03/20 02:11 UTC | default | PERSISTENT |
-+-------------+---------+--------------+----------------------+----------+------------+
-| alpine-edge | RUNNING | x86_64 | 2016/03/20 02:19 UTC | default | PERSISTENT |
-+-------------+---------+--------------+----------------------+----------+------------+
-```
-
-在这个例子中,只有在名字中带有“alpine”的容器才会被列出来(支持复杂的正则表达式)。
-### 获取容器的详细信息
-由于list命令显然不能以一种友好的可读方式显示容器的所有信息,因此你可以使用如下方式来查询单个容器的信息:
-```
-lxc info
-```
-
-例如:
-```
-stgraber@dakara:~$ lxc info zerotier
-Name: zerotier
-Architecture: x86_64
-Created: 2016/02/20 20:01 UTC
-Status: Running
-Type: persistent
-Profiles: default
-Pid: 31715
-Processes: 32
-Ips:
- eth0: inet 172.17.0.101
- eth0: inet6 2607:f2c0:f00f:2700:216:3eff:feec:65a8
- eth0: inet6 fe80::216:3eff:feec:65a8
- lo: inet 127.0.0.1
- lo: inet6 ::1
- lxcbr0: inet 10.0.3.1
- lxcbr0: inet6 fe80::c0a4:ceff:fe52:4d51
- zt0: inet 29.17.181.59
- zt0: inet6 fd80:56c2:e21c:0:199:9379:e711:b3e1
- zt0: inet6 fe80::79:e7ff:fe0d:5123
-Snapshots:
- zerotier/blah (taken at 2016/03/08 23:55 UTC) (stateless)
- ```
-
-### 生命周期管理命令
-这些命令对于任何容器或者虚拟机管理器或许都是最普通的命令,但是它们仍然需要被涉及到。
-所有的这些命令在批量操作时都能接受多个容器名。
-### 启动
-启动一个容器就向下面一样简单:
-```
-lxc start
-```
-
-### 停止
-停止一个容器可以这样来完成:
-```
-lxc stop
-```
-
-如果容器不合作(即没有对发出的信号产生回应),这时候,你可以使用下面的方式强制执行:
-```
-lxc stop --force
-```
-
-### 重启
-通过下面的命令来重启一个容器:
-```
-lxc restart
-```
-
-如果容器不合作(即没有对发出的信号产生回应),你可以使用下面的方式强制执行:
-```
-lxc restart --force
-```
-
-### 暂停
-你也可以“暂停”一个容器,在这种模式下,所有的容器任务将会被发送相同的信号,这也意味着他们将仍然是可见的,并且仍然会占用内存,但是他们不会从调度程序中得到任何的CPU时间片。
-如果你有一个CPU的饥饿容器,而这个容器需要一点时间来启动,但是你却并 不会经常用到它。这时候,你可以先启动它,然后将它暂停,并在你需要它的时候再启动它。
-```
-lxc pause
-```
-
-### 删除
-最后,如果你不需要这个容器了,你可以用下面的命令删除它:
-```
-lxc delete
-```
-
-注意,如果容器还处于运行状态时你将必须使用“-forece”。
-### 容器的配置
-LXD拥有大量的容器配置设定,包括资源限制,容器启动控制以及对各种设备是否允许访问的配置选项。完整的清单因为太长所以并没有在本文中列出,但是,你可以从[here]获取它。
-就设备而言,LXD当前支持下面列出的这些设备:
-- 磁盘
-既可以是一块物理磁盘,也可以只是一个被挂挂载到容器上的分区,还可以是一个来自主机的绑定挂载路径。
-- 网络接口卡
-一块网卡。它可以是一块桥接的虚拟网卡,或者是一块点对点设备,还可以是一块以太局域网设备或者一块已经被连接到容器的真实物理接口。
-- unix块
-一个UNIX块设备,比如/dev/sda
-- unix字符
-一块UNIX字符设备,比如/dev/kvm
-- none
-这种特殊类型被用来隐藏那种可以通过profiles文件被继承的设备。
-
-### 配置profiles文件
-所有可用的profiles的文件列表可以这样获取:
-```
-lxc profile list
-```
-
-为了看到给定profile文件的内容,最简单的方式是这样做:
-```
-lxc profile show
-```
-
-你可能想要改变文件里面的内容,可以这样做:
-```
-lxc profile edit
-```
-
-你可以使用如下命令来改变profiles的列表并将这种变化应用到给定的容器中:
-```
-lxc profile apply ,,,...
-```
-
-### 本地配置
-For things that are unique to a container and so don’t make sense to put into a profile, you can just set them directly against the container:
-
-```
-lxc config edit
-```
-
-上面的命令将会完成和“profile edit”命令一样的功能。
-
-即使不在文本编辑器中打开整个文件的内容,你也可以像这样修改单独的键:
-```
-lxc config set
-```
-或者添加设备,例如
-```
-lxc config device add my-container kvm unix-char path=/dev/kvm
-```
-
-上面的命令将会为名为“my-container”的容器打开一个/dev/kvm入口。
-对一个profile文件使用“lxc profile set”和“lxc profile device add”命令也能实现上面的功能。
-#### 读取配置
-你可以使用如下命令来阅读容器的本地配置:
-```
-lxc config show
-```
-
-或者得到已经被展开了的配置(包含了所有的键值):
-```
-lxc config show --expanded
-```
-
-例如:
-```
-stgraber@dakara:~$ lxc config show --expanded zerotier
-name: zerotier
-profiles:
-- default
-config:
- security.nesting: "true"
- user.a: b
- volatile.base_image: a49d26ce5808075f5175bf31f5cb90561f5023dcd408da8ac5e834096d46b2d8
- volatile.eth0.hwaddr: 00:16:3e:ec:65:a8
- volatile.last_state.idmap: '[{"Isuid":true,"Isgid":false,"Hostid":100000,"Nsid":0,"Maprange":65536},{"Isuid":false,"Isgid":true,"Hostid":100000,"Nsid":0,"Maprange":65536}]'
-devices:
- eth0:
- name: eth0
- nictype: macvlan
- parent: eth0
- type: nic
- limits.ingress: 10Mbit
- limits.egress: 10Mbit
- root:
- path: /
- size: 30GB
- type: disk
- tun:
- path: /dev/net/tun
- type: unix-char
-ephemeral: false
-```
-
-这样做可以很方便的检查有哪些配置属性被应用到了给定的容器。
-### 实时配置更新
-注意,除非在文档中已经被明确指出,否则所有的键值和设备入口都会被应用到受影响的实时容器。这意味着你可以添加和移除某些设备或者在不重启容器的情况下修改正在运行的容器的安全profile配置文件。
-### 获得一个shell
-LXD允许你对容器中的任务进行直接的操作。最常用的做法是在容器中得到一个shell或者执行一些管理员任务。
-和SSH相比,这样做的好处是你可以接触到独立与容器之外的网络或者任何一个软件又或者任何一个能够在容器内可见的文件配置。
-执行环境
-对比LXD在容器内执行命令的方式,有一点是不同的,那就是它自身并不是在容器中运行。这也意味着它不知道该使用什么样的shell,以及设置什么样的环境变量和哪里是它的家目录。
-通过LXD来执行命令必须总是在最小路径环境变量集并且HONE环境变量必须为/root的情况下以容器的超级用户身份来执行(即uid为0,gid为0)。
-其他的环境变量可以通过命令行来设置,或者在“environment.”配置文件中设置成永久环境变量。
-### 执行命令
-在容器中获得一个shell可以简单的执行下列命令得到:
-```
-lxc exec bash
-```
-
-当然,这样做的前提是容器内已经安装了bash。
-
-更多复杂的命令要求有对参数分隔符的合理使用。
-```
-lxc exec -- ls -lh /
-```
-
-如果想要设置或者重写变量,你可以使用“-env”参数,例如:
-```
-stgraber@dakara:~$ lxc exec zerotier --env mykey=myvalue env | grep mykey
-mykey=myvalue
-```
-
-### 管理文件
-因为LXD可以直接访问容器的文件系统,因此,它可以直接往容器中读取和写入任意文件。当我们需要提取日志文件或者与容器发生交互时,这个特性是很有用的。
-#### 从容器中取回一个文件
-想要从容器中获得一个文件,简单的执行下列命令:
-```
-lxc file pull /
-```
-
-例如:
-```
-stgraber@dakara:~$ lxc file pull zerotier/etc/hosts hosts
-```
-
-或者将它读取到标准输出:
-```
-stgraber@dakara:~$ lxc file pull zerotier/etc/hosts -
-127.0.0.1 localhost
-
-# 下面的所有行对于支持IPv6的主机是有用的
-::1 ip6-localhost ip6-loopback
-fe00::0 ip6-localnet
-ff00::0 ip6-mcastprefix
-ff02::1 ip6-allnodes
-ff02::2 ip6-allrouters
-ff02::3 ip6-allhosts
-```
-
-#### 向容器发送一个文件
-
-发送会简单的以另一种方式完成:
-```
-lxc file push