2
0
mirror of https://github.com/LCTT/TranslateProject.git synced 2025-03-03 01:10:13 +08:00

Merge remote-tracking branch 'LCTT/master'

This commit is contained in:
Xingyu.Wang 2018-09-10 16:55:38 +08:00
commit 5df858c92e
17 changed files with 1292 additions and 1213 deletions

75
lctt2018.md Normal file
View File

@ -0,0 +1,75 @@
LCTT 2018五周年纪念日
======
我是老王,可能大家有不少人知道我,由于历史原因,我有好几个生日(;o但是这些年来我又多了一个生日或者说纪念日——每过两年我就要严肃认真地写一篇 [LCTT](https://linux.cn/lctt) 生日纪念文章。
这一篇就是今年的了LCTT 如今已经五岁了!
或许如同小孩子过生日总是比较快乐,而随着年岁渐长,过生日往往有不少负担——比如说,每次写这篇纪念文章时,我就需要回忆、反思这两年的做了些什么,往往颇为汗颜。
不过不管怎么说,总要总结一下这两年我们做了什么,有什么不足,也发一些展望吧。
### 江山代有英豪出
LCTT如同一般的开源贡献组织总是有不断的新老传承。我们的翻译组也有不少成员由于工作学习的原因慢慢淡出但同时也不断有新的成员加入并接过前辈手中的旗帜就是没人接我的
> **加入方式**
> 请首先加入翻译组的 QQ 群,群号是:**198889102**,加群时请说明是“**志愿者**”。加入后记得修改您的群名片为您的 GitHub 的 ID。
> 加入的成员,请先阅读 [WIKI 如何开始](https://github.com/LCTT/TranslateProject/wiki/01-%E5%A6%82%E4%BD%95%E5%BC%80%E5%A7%8B)。
比如说我们这两年来oska874 承担了主要的选题工作,然后 lujun9972 适时的出现接过了不少选题工作再比如说qhwdw 出现后承担了大量繁难文章的翻译pityonline 则专注于校对,甚至其校对的严谨程度让我都甘拜下风。还有 MjSeven 也同 qhwdw 一样,以极高的翻译频率从一星译者迅速登顶五星译者。当然,还有 Bestony、Locez、VizV 等人为 LCTT 提供了不少技术支持和开发工作。
### 硕果累累
我们并没有特别的招新渠道,但是总是时不时会有新的成员慕名而来,到目前为止,我们已经有 [331](https://linux.cn/lctt-list) 位做过贡献的成员,已经翻译发布了 3885 篇译文,合计字节达 33MB 之多!
这两年,我们不但翻译了很多技术、新闻和评论类文章,也新增了新的翻译类型:[漫画](https://linux.cn/talk/comic/),其中一些漫画得到了很多好评。
我们发布的文章有一些达到了 100000+ 的访问量,这对于我们这种技术垂直内容可不容易。
而同时,[Linux 中国](https://linux.cn/)也发布了近万篇文章,而这一篇,应该就是第 [9999](https://linux.cn/article-9999-1.html) 篇文章,我们将在明天,进入新的篇章。
### 贡献者主页和贡献者证书
为了彰显诸位贡献者的贡献,我们为每位贡献者创立的自己的专页,并据此建立了[排行榜](https://linux.cn/lctt-list)。
同时,我们还特意请 Bestony 和“一一”设计开发和”贡献者证书”,大家可以在 [LCTT 贡献平台](https://lctt.linux.cn/)中领取。
### 规则进化
LCTT 最初创立时,甚至都没有采用 PR 模式。但是随着贡献者的增多,我们也逐渐在改善我们的流程、方法。
之前采用了很粗糙的 PR 模式,对 PR 中的文件、提交乃至于信息都没有进行硬性约束。后来在 VizV 的帮助下,建立了对 PR 的合规性检查;又在 pityonline 的督促下,采用了更为严格的 PR 审查机制。
LCTT 创立几年来,我们的一些流程和规范,已经成为其它一些翻译组的参考范本,我们也希望我们的这些经验,可以进一步帮助到其它的开源社区。
### 仓库重建和版权问题
今年还发生一次严重的事故,由于对选题来源把控不严和对版权问题没有引起足够的重视,我们引用的一篇文章违背了原文的版权规定,结果被原文作者投诉到 GitHub。而我并没有及时看到 GitHub 给我发的 DMCA 处理邮件,因此错过了处理窗口期,从而被 GitHub 将整个库予以删除。
出现这样的重大失误之后,经过大家的帮助,我们历经周折才将仓库基本恢复。这要特别感谢 VizV 的辛苦工作。
在此之后,我们对译文选文的规则进行了梳理,并全面清查了文章版权。这个教训对我们来说弥足沉重。
### 通证时代
在 Linux 中国及 LCTT 发展过程中,我一直小心翼翼注意商业化的问题。严格来说,没有经济支持的开源组织如同无根之木,无源之水,是长久不了的。而商业化的技术社区又难免为了三斗米而折腰。所以往往很多技术社区要么渐渐凋零,要么就变成了商业机构。
从中国电信辞职后,我专职运营 Linux 中国这个开源社区已经近三年了,其间也有一些商业性收入,但是仅能勉强承担基本的运营费用。
这种尴尬的局面,使我,以及其它的开源社区同仁们纷纷寻求更好的发展之路。
去年参加中国开源年会时,在闭门会上,大家的讨论启发了我和诸位同仁,我们认为,开源社区结合通证经济,似乎是一条可行的开源社区发展之路。
今年 8 月 1 日,我们经过了半年的论证和实验,[发布了社区通证 LCCN](https://linux.cn/article-9886-1.html),并已经初步发放到了各位译者手中。我们还在继续建设通证生态各种工具,如合约、交易商城等。
我们希望能够通过通证为开源社区转入新的活力,也愿意将在探索道路上遇到的问题和解决的思路、工具链分享给更多的社区。
### 总结
从上一次总结以来,这又是七百多天,时光荏苒,而 LCTT 的创立也近两千天了。我希望,我们的翻译组以及更多的贡献者可以在通证经济的推动下,找到自洽、自治的发展道路;也希望能有更多的贡献者涌现出来接过我们的大旗,将开源发扬光大。
wxy
2018/9/9 夜

View File

@ -1,212 +0,0 @@
ucasFL translating
How To Compress And Decompress Files In Linux
======
![](https://www.ostechnix.com/wp-content/uploads/2018/03/compress-720x340.jpg)
Compressing is quite useful when backing up important files and also sending large files over Internet. Please note that compressing an already compressed file adds extra overhead, hence you will get a slightly bigger file. So, stop compressing a compressed file. There are many programs to compress and decompress files in GNU/Linux. In this tutorial, were going to learn about two applications only.
### Compress and decompress files
The most common programs used to compress files in Unix-like systems are:
1. gzip
2. bzip2
##### 1\. Compress and decompress files using Gzip program
The gzip is an utility to compress and decompress files using Lempel-Ziv coding (LZ77) algorithm.
**1.1 Compress files**
To compress a file named **ostechnix.txt** , replacing it with a gzipped compressed version, run:
```
$ gzip ostechnix.txt
```
Gzip will replace the original file **ostechnix.txt** with a gzipped compressed version named **ostechnix.txt.gz**.
The gzip command can also be used in other ways too. One fine example is we can create a compressed version of a specific commands output. Look at the following command.
```
$ ls -l Downloads/ | gzip > ostechnix.txt.gz
```
The above command creates compressed version of the directory listing of Downloads folder.
**1.2 Compress files and write the output to different files (Dont replace the original file)
**
By default, gzip program will compress the given file, replacing it with a gzipped compressed version. You can, however, keep the original file and write the output to standard output. For example, the following command, compresses **ostechnix.txt** and writes the output to **output.txt.gz**.
```
$ gzip -c ostechnix.txt > output.txt.gz
```
Similarly, to decompress a gzipped file specifying the output filename:
```
$ gzip -c -d output.txt.gz > ostechnix1.txt
```
The above command decompresses the **output.txt.gz** file and writes the output to **ostechnix1.txt** file. In both cases, it wont delete the original file.
**1.3 Decompress files**
To decompress the file **ostechnix.txt.gz** , replacing it with the original uncompressed version, we do:
```
$ gzip -d ostechnix.txt.gz
```
We can also use gunzip to decompress the files.
```
$ gunzip ostechnix.txt.gz
```
**1.4 View contents of compressed files without decompressing them**
To view the contents of the compressed file using gzip without decompressing it, use **-c** flag as shown below:
```
$ gunzip -c ostechnix1.txt.gz
```
Alternatively, use **zcat** utility like below.
```
$ zcat ostechnix.txt.gz
```
You can also pipe the output to “less” command to view the output page by page like below.
```
$ gunzip -c ostechnix1.txt.gz | less
$ zcat ostechnix.txt.gz | less
```
Alternatively, there is a **zless** program which performs the same function as the pipeline above.
```
$ zless ostechnix1.txt.gz
```
**1.5 Compress file with gzip by specifying compression level**
Another notable advantage of gzip is it supports compression level. It supports 3 compression levels as given below.
* **1** Fastest (Worst)
* **9** Slowest (Best)
* **6** Default level
To compress a file named **ostechnix.txt** , replacing it with a gzipped compressed version with **best** compression level, we use:
```
$ gzip -9 ostechnix.txt
```
**1.6 Concatenate multiple compressed files**
It is also possible to concatenate multiple compressed files into one. How? Have a look at the following example.
```
$ gzip -c ostechnix1.txt > output.txt.gz
$ gzip -c ostechnix2.txt >> output.txt.gz
```
The above two commands will compress ostechnix1.txt and ostechnix2.txt and saves them in one file named **output.txt.gz**.
You can view the contents of both files (ostechnix1.txt and ostechnix2.txt) without extracting them using any one of the following commands:
```
$ gunzip -c output.txt.gz
$ gunzip -c output.txt
$ zcat output.txt.gz
$ zcat output.txt
```
For more details, refer the man pages.
```
$ man gzip
```
##### 2\. Compress and decompress files using bzip2 program
The **bzip2** is very similar to gzip program, but uses different compression algorithm named the Burrows-Wheeler block sorting text compression algorithm, and Huffman coding. The files compressed using bzip2 will end with **.bz2** extension.
Like I said, the usage of bzip2 is almost same as gzip. Just replace **gzip** in the above examples with **bzip2** , **gunzip** with **bunzip2** , **zcat** with **bzcat** and so on.
To compress a file using bzip2, replacing it with compressed version, run:
```
$ bzip2 ostechnix.txt
```
If you dont want to replace the original file, use **-c** flag and write the output to a new file.
```
$ bzip2 -c ostechnix.txt > output.txt.bz2
```
To decompress a compressed file:
```
$ bzip2 -d ostechnix.txt.bz2
```
Or,
```
$ bunzip2 ostechnix.txt.bz2
```
To view the contents of a compressed file without decompressing it:
```
$ bunzip2 -c ostechnix.txt.bz2
```
Or,
```
$ bzcat ostechnix.txt.bz2
```
For more details, refer man pages.
```
$ man bzip2
```
##### Summary
In this tutorial, we learned what is gzip and bzip2 programs and how to use them to compress and decompress files with some examples in GNU/Linux. In this next, guide we are going to learn how to archive files and directories in Linux.
Cheers!
--------------------------------------------------------------------------------
via: https://www.ostechnix.com/how-to-compress-and-decompress-files-in-linux/
作者:[SK][a]
译者:[译者ID](https://github.com/译者ID)
校对:[校对者ID](https://github.com/校对者ID)
选题:[lujun9972](https://github.com/lujun9972)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://www.ostechnix.com/author/sk/

View File

@ -1,182 +0,0 @@
pinewall is translating
[Anatomy of a Linux DNS Lookup Part IV][2]
============================================
In [Anatomy of a Linux DNS Lookup Part I][3], [Part II][4], and [Part III][5] I covered:
* `nsswitch`
* `/etc/hosts`
* `/etc/resolv.conf`
* `ping` vs `host` style lookups
* `systemd` and its `networking` service
* `ifup` and `ifdown`
* `dhclient`
* `resolvconf`
* `NetworkManager`
* `dnsmasq`
In Part IV Ill cover how containers do DNS. Yes, thats not simple either…
* * *
1) Docker and DNS
============================================================
In [part III][6] we looked at DNSMasq, and learned that it works by directing DNS queries to the localhost address `127.0.0.1`, and a process listening on port 53 there will accept the request.
So when you run up a Docker container, on a host set up like this, what do you expect to see in its `/etc/resolv.conf`?
Have a think, and try and guess what it will be.
Heres the default output if you run a default Docker setup:
```
$ docker run  ubuntu cat /etc/resolv.conf
# Dynamic resolv.conf(5) file for glibc resolver(3) generated by resolvconf(8)
#     DO NOT EDIT THIS FILE BY HAND -- YOUR CHANGES WILL BE OVERWRITTEN
# 127.0.0.53 is the systemd-resolved stub resolver.
# run "systemd-resolve --status" to see details about the actual nameservers.
search home
nameserver 8.8.8.8
nameserver 8.8.4.4
```
Hmmm.
#### Where did the addresses `8.8.8.8` and `8.8.4.4` come from?
When I pondered this question, my first thought was that the container would inherit the `/etc/resolv.conf` settings from the host. But a little thought shows that that wont always work.
If you have DNSmasq set up on the host, the `/etc/resolv.conf` file will be pointed at the `127.0.0.1` loopback address. If this were passed through to the container, the container would look up DNS addresses from within its own networking context, and theres no DNS server available within the container context, so the DNS lookups would fail.
A-ha! you might think: we can always use the hosts DNS server by using the  _hosts_  IP address, available from within the container as the default route:
```
root@79a95170e679:/# ip route                                                               
default via 172.17.0.1 dev eth0                                               
172.17.0.0/16 dev eth0 proto kernel scope link src 172.17.0.2     
```
#### Use the host?
From that we can work out that the host is on the ip address: `172.17.0.1`, so we could try manually pointing DNS at that using dig (you could also update the `/etc/resolv.conf` and then run `ping`, this just seems like a good time to introduce `dig` and its `@` flag, which points the request at the ip address you specify):
```
root@79a95170e679:/# dig @172.17.0.1 google.com | grep -A1 ANSWER.SECTION
;; ANSWER SECTION:
google.com.             112     IN      A       172.217.23.14
```
However: that might work if you use DNSMasq, but if you dont it wont, as theres no DNS server on the host to look up.
So Dockers solution to this quandary is to bypass all that complexity and point your DNS lookups to Googles DNS servers at `8.8.8.8` and `8.8.4.4`, ignoring whatever the host context is.
_Anecdote: This was the source of my first problem with Docker back in 2013\. Our corporate network blocked access to those IP addresses, so my containers couldnt resolve URLs._
So thats Docker containers, but container  _orchestrators_  such as Kubernetes can do different things again…
# 2) Kubernetes and DNS
The unit of container deployment in Kubernetes is a Pod. A pod is a set of co-located containers that (among other things) share the same IP address.
An extra challenge with Kubernetes is to forward requests for Kubernetes services to the right resolver (eg `myservice.kubernetes.io`) to the private network allocated to those service addresses. These addresses are said to be on the cluster domain. This cluster domain is configurable by the administrator, so it might be `cluster.local` or `myorg.badger` depending on the configuration you set up.
In Kubernetes you have four options for configuring how DNS lookup works within your pod.
* Default
This (misleadingly-named) option takes the same DNS resolution path as the host the pod runs on, as in the naive DNS lookup described earlier. Its misleadingly named because its not the default! ClusterFirst is.
If you want to override the `/etc/resolv.conf` entries, you can in your config for the kubelet.
* ClusterFirst
ClusterFirst does selective forwarding on the DNS request. This is achieved in one of two ways based on the configuration.
In the first, older and simpler setup, a rule was followed where if the cluster domain was not found in the request, then it was forwarded to the host.
In the second, newer approach, you can configure selective forwarding on an internal DNS
Heres what the config looks like and a diagram lifted from the [Kubernetes docs][7] which shows the flow:
```
apiVersion: v1
kind: ConfigMap
metadata:
name: kube-dns
namespace: kube-system
data:
stubDomains: |
{"acme.local": ["1.2.3.4"]}
upstreamNameservers: |
["8.8.8.8", "8.8.4.4"]
```
The `stubDomains` entry defines specific DNS servers to use for specific domains. The upstream servers are the servers we defer to when nothing else has picked up the DNS request.
This is achieved with our old friend DNSMasq running in a pod.
![kubedns](https://zwischenzugs.files.wordpress.com/2018/08/kubedns.png?w=525)
The other two options are more niche:
* ClusterFirstWithHostNet
This applies if you use host network for your pods, ie you bypass the Docker networking setup to use the same network as you would directly on the host the pod is running on.
* None
None does nothing to DNS but forces you to specify the DNS settings in the `dnsConfig` field in the pod specification.
### CoreDNS Coming
And if that wasnt enough, this is set to change again as CoreDNS comes to Kubernetes, replacing kube-dns. CoreDNS will offer a few benefits over kube-dns, being more configurabe and more efficient.
Find out more [here][8].
If youre interested in OpenShift networking, I wrote a post on that [here][9]. But that was for 3.6 so is likely out of date now.
### End of Part IV
Thats part IV done. In it we covered.
* Docker DNS lookups
* Kubernetes DNS lookups
* Selective forwarding (stub domains)
* kube-dns
--------------------------------------------------------------------------------
via: https://zwischenzugs.com/2018/08/06/anatomy-of-a-linux-dns-lookup-part-iv/
作者:[zwischenzugs][a]
译者:[译者ID](https://github.com/译者ID)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://zwischenzugs.com/
[1]:https://zwischenzugs.com/2018/08/06/anatomy-of-a-linux-dns-lookup-part-iv/
[2]:https://zwischenzugs.com/2018/08/06/anatomy-of-a-linux-dns-lookup-part-iv/
[3]:https://zwischenzugs.com/2018/06/08/anatomy-of-a-linux-dns-lookup-part-i/
[4]:https://zwischenzugs.com/2018/06/18/anatomy-of-a-linux-dns-lookup-part-ii/
[5]:https://zwischenzugs.com/2018/07/06/anatomy-of-a-linux-dns-lookup-part-iii/
[6]:https://zwischenzugs.com/2018/07/06/anatomy-of-a-linux-dns-lookup-part-iii/
[7]:https://kubernetes.io/docs/tasks/administer-cluster/dns-custom-nameservers/#impacts-on-pods
[8]:https://coredns.io/
[9]:https://zwischenzugs.com/2017/10/21/openshift-3-6-dns-in-pictures/

View File

@ -1,323 +0,0 @@
Zafiry translating...
What is a Makefile and how does it work?
======
![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/osdc_liberate%20docs_1109ay.png?itok=xQOLreya)
If you want to run or update a task when certain files are updated, the `make` utility can come in handy. The `make` utility requires a file, `Makefile` (or `makefile`), which defines set of tasks to be executed. You may have used `make` to compile a program from source code. Most open source projects use `make` to compile a final executable binary, which can then be installed using `make install`.
In this article, we'll explore `make` and `Makefile` using basic and advanced examples. Before you start, ensure that `make` is installed in your system.
### Basic examples
Let's start by printing the classic "Hello World" on the terminal. Create a empty directory `myproject` containing a file `Makefile` with this content:
```
say_hello:
        echo "Hello World"
```
Now run the file by typing `make` inside the directory `myproject`. The output will be:
```
$ make
echo "Hello World"
Hello World
```
In the example above, `say_hello` behaves like a function name, as in any programming language. This is called the target. The prerequisites or dependencies follow the target. For the sake of simplicity, we have not defined any prerequisites in this example. The command `echo "Hello World"` is called the recipe. The recipe uses prerequisites to make a target. The target, prerequisites, and recipes together make a rule.
To summarize, below is the syntax of a typical rule:
```
target: prerequisites
<TAB> recipe
```
As an example, a target might be a binary file that depends on prerequisites (source files). On the other hand, a prerequisite can also be a target that depends on other dependencies:
```
final_target: sub_target final_target.c
        Recipe_to_create_final_target
sub_target: sub_target.c
        Recipe_to_create_sub_target
```
It is not necessary for the target to be a file; it could be just a name for the recipe, as in our example. We call these "phony targets."
Going back to the example above, when `make` was executed, the entire command `echo "Hello World"` was displayed, followed by actual command output. We often don't want that. To suppress echoing the actual command, we need to start `echo` with `@`:
```
say_hello:
        @echo "Hello World"
```
Now try to run `make` again. The output should display only this:
```
$ make
Hello World
```
Let's add a few more phony targets: `generate` and `clean` to the `Makefile`:
```
say_hello:
        @echo "Hello World"
generate:
        @echo "Creating empty text files..."
        touch file-{1..10}.txt
clean:
        @echo "Cleaning up..."
        rm *.txt
```
If we try to run `make` after the changes, only the target `say_hello` will be executed. That's because only the first target in the makefile is the default target. Often called the default goal, this is the reason you will see `all` as the first target in most projects. It is the responsibility of `all` to call other targets. We can override this behavior using a special phony target called `.DEFAULT_GOAL`.
Let's include that at the beginning of our makefile:
```
.DEFAULT_GOAL := generate
```
This will run the target `generate` as the default:
```
$ make
Creating empty text files...
touch file-{1..10}.txt
```
As the name suggests, the phony target `.DEFAULT_GOAL` can run only one target at a time. This is why most makefiles include `all` as a target that can call as many targets as needed.
Let's include the phony target `all` and remove `.DEFAULT_GOAL`:
```
all: say_hello generate
say_hello:
        @echo "Hello World"
generate:
        @echo "Creating empty text files..."
        touch file-{1..10}.txt
clean:
        @echo "Cleaning up..."
        rm *.txt
```
Before running `make`, let's include another special phony target, `.PHONY`, where we define all the targets that are not files. `make` will run its recipe regardless of whether a file with that name exists or what its last modification time is. Here is the complete makefile:
```
.PHONY: all say_hello generate clean
all: say_hello generate
say_hello:
        @echo "Hello World"
generate:
        @echo "Creating empty text files..."
        touch file-{1..10}.txt
clean:
        @echo "Cleaning up..."
        rm *.txt
```
The `make` should call `say_hello` and `generate`:
```
$ make
Hello World
Creating empty text files...
touch file-{1..10}.txt
```
It is a good practice not to call `clean` in `all` or put it as the first target. `clean` should be called manually when cleaning is needed as a first argument to `make`:
```
$ make clean
Cleaning up...
rm *.txt
```
Now that you have an idea of how a basic makefile works and how to write a simple makefile, let's look at some more advanced examples.
### Advanced examples
#### Variables
In the above example, most target and prerequisite values are hard-coded, but in real projects, these are replaced with variables and patterns.
The simplest way to define a variable in a makefile is to use the `=` operator. For example, to assign the command `gcc` to a variable `CC`:
```
CC = gcc
```
This is also called a recursive expanded variable, and it is used in a rule as shown below:
```
hello: hello.c
    ${CC} hello.c -o hello
```
As you may have guessed, the recipe expands as below when it is passed to the terminal:
```
gcc hello.c -o hello
```
Both `${CC}` and `$(CC)` are valid references to call `gcc`. But if one tries to reassign a variable to itself, it will cause an infinite loop. Let's verify this:
```
CC = gcc
CC = ${CC}
all:
    @echo ${CC}
```
Running `make` will result in:
```
$ make
Makefile:8: *** Recursive variable 'CC' references itself (eventually).  Stop.
```
To avoid this scenario, we can use the `:=` operator (this is also called the simply expanded variable). We should have no problem running the makefile below:
```
CC := gcc
CC := ${CC}
all:
    @echo ${CC}
```
#### Patterns and functions
The following makefile can compile all C programs by using variables, patterns, and functions. Let's explore it line by line:
```
# Usage:
# make        # compile all binary
# make clean  # remove ALL binaries and objects
.PHONY = all clean
CC = gcc                        # compiler to use
LINKERFLAG = -lm
SRCS := $(wildcard *.c)
BINS := $(SRCS:%.c=%)
all: ${BINS}
%: %.o
        @echo "Checking.."
        ${CC} ${LINKERFLAG} $< -o $@
%.o: %.c
        @echo "Creating object.."
        ${CC} -c $<
clean:
        @echo "Cleaning up..."
        rm -rvf *.o ${BINS}
```
* Lines starting with `#` are comments.
* Line `.PHONY = all clean` defines phony targets `all` and `clean`.
* Variable `LINKERFLAG` defines flags to be used with `gcc` in a recipe.
* `SRCS := $(wildcard *.c)`: `$(wildcard pattern)` is one of the functions for filenames. In this case, all files with the `.c` extension will be stored in a variable `SRCS`.
* `BINS := $(SRCS:%.c=%)`: This is called as substitution reference. In this case, if `SRCS` has values `'foo.c bar.c'`, `BINS` will have `'foo bar'`.
* Line `all: ${BINS}`: The phony target `all` calls values in`${BINS}` as individual targets.
* Rule:
```
%: %.o
  @echo "Checking.."
  ${CC} ${LINKERFLAG} $&lt; -o $@
```
Let's look at an example to understand this rule. Suppose `foo` is one of the values in `${BINS}`. Then `%` will match `foo`(`%` can match any target name). Below is the rule in its expanded form:
```
foo: foo.o
  @echo "Checking.."
  gcc -lm foo.o -o foo
```
As shown, `%` is replaced by `foo`. `$<` is replaced by `foo.o`. `$<` is patterned to match prerequisites and `$@` matches the target. This rule will be called for every value in `${BINS}`
* Rule:
```
%.o: %.c
  @echo "Creating object.."
  ${CC} -c $&lt;
```
Every prerequisite in the previous rule is considered a target for this rule. Below is the rule in its expanded form:
```
foo.o: foo.c
  @echo "Creating object.."
  gcc -c foo.c
```
* Finally, we remove all binaries and object files in target `clean`.
Below is the rewrite of the above makefile, assuming it is placed in the directory having a single file `foo.c:`
```
# Usage:
# make        # compile all binary
# make clean  # remove ALL binaries and objects
.PHONY = all clean
CC = gcc                        # compiler to use
LINKERFLAG = -lm
SRCS := foo.c
BINS := foo
all: foo
foo: foo.o
        @echo "Checking.."
        gcc -lm foo.o -o foo
foo.o: foo.c
        @echo "Creating object.."
        gcc -c foo.c
clean:
        @echo "Cleaning up..."
        rm -rvf foo.o foo
```
For more on makefiles, refer to the [GNU Make manual][1], which offers a complete reference and examples.
--------------------------------------------------------------------------------
via: https://opensource.com/article/18/8/what-how-makefile
作者:[Sachin Patil][a]
选题:[lujun9972](https://github.com/lujun9972)
译者:[译者ID](https://github.com/译者ID)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://opensource.com/users/psachin
[1]:https://www.gnu.org/software/make/manual/make.pdf

View File

@ -1,114 +0,0 @@
Translating by DavidChenLiang
An introduction to diffs and patches
======
![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/find-file-linux-code_magnifying_glass_zero.png?itok=E2HoPDg0)
If youve ever worked on a large codebase with a distributed development model, youve probably heard people say things like “Sue just sent a patch,” or “Rajiv is checking out the diff.” Maybe those terms were new to you and you wondered what they meant. Open source has had an impact here, as the main development model of large projects from Apache web server to the Linux kernel have been “patch-based” development projects throughout their lifetime. In fact, did you know that Apaches name originated from the set of patches that were collected and collated against the original [NCSA HTTPd server source code][1]?
You might think this is folklore, but an early [capture of the Apache website][2] claims that the name was derived from this original “patch” collection; hence **APA** t **CH** y server, which was then simplified to Apache.
But enough history trivia. What exactly are these patches and diffs that developers talk about?
First, for the sake of this article, lets assume that these two terms reference one and the same thing. “Diff” is simply short for “difference;” a Unix utility by the same name reveals the difference between one or more files. We will look at a diff utility example below.
A “patch” refers to a specific collection of differences between files that can be applied to a source code tree using the Unix diff utility. So we can create diffs (or patches) using the diff tool and apply them to an unpatched version of that same source code using the patch tool. As an aside (and breaking my rule of no more history trivia), the word “patch” comes from the physical covering of punchcard holes to make software changes in the early computing days, when punchcards represented the program executed by the computers processor. The image below, found on this [Wikipedia page][3] describing software patches, shows this original “patching” concept:
![](https://opensource.com/sites/default/files/uploads/360px-harvard_mark_i_program_tape.agr_.jpg)
Now that you have a basic understanding of patches and diffs, lets explore how software developers use these tools. If you havent used a source code control system like [Git][4] or [Subversion][5], I will set the stage for how most non-trivial software projects are developed. If you think of the life of a software project as a set of actions along a timeline, you might visualize changes to the software—such as adding a feature or a function to a source code file or fixing a bug—appearing at different points on the timeline, with each discrete point representing the state of all the source code files at that time. We will call these points of change “commits,” using the same nomenclature that todays most popular source code control tool, Git, uses. When you want to see the difference between the source code before and after a certain commit, or between many commits, you can use a tool to show us diffs, or differences.
If you are developing software using this same source code control tool, Git, you may have changes in your local system that you want to provide for others to potentially add as commits to their own tree. One way to provide local changes to others is to create a diff of your local tree's changes and send this “patch” to others who are working on the same source code. This lets others patch their tree and see the source code tree with your changes applied.
### Linux, Git, and GitHub
This model of sharing patch files is how the Linux kernel community operates regarding proposed changes today. If you look at the archives for any of the popular Linux kernel mailing lists—[LKML][6] is the primary one, but others include [linux-containers][7], [fs-devel][8], [Netdev][9], to name a few—youll find many developers posting patches that they wish to have others review, test, and possibly bring into the official Linux kernel Git tree at some point. It is outside of the scope of this article to discuss Git, the source code control system written by Linus Torvalds, in more detail, but it's worth noting that Git enables this distributed development model, allowing patches to live separately from a main repository, pushing and pulling into different trees and following their specific development flow.
Before moving on, we cant ignore the most popular service in which patches and diffs are relevant: [GitHub][10]. Given its name, you can probably guess that GitHub is based on Git, but it offers a web- and API-based workflow around the Git tool for distributed open source project development. One of the main ways that patches are shared in GitHub is not via email, like the Linux kernel, but by creating a **pull request**. When you commit changes on your own copy of a source code tree, you can share those changes by creating a pull request against a commonly shared repository for that software project. GitHub is used by many active and popular open source projects today, such as [Kubernetes][11], [Docker][12], [the Container Network Interface (CNI)][13], [Istio][14], and many others. In the GitHub world, users tend to use the web-based interface to review the diffs or patches that comprise a pull request, but you can still access the raw patch files and use them at the command line with the patch utility.
### Getting down to business
Now that weve covered patches and diffs and how they are used in popular open source communities or tools, let's look at a few examples.
The first example includes two copies of a source tree, and one has changes that we want to visualize using the diff utility. In our examples, we will look at “unified” diffs because that is the expected view for patches in most of the modern software development world. Check the diff manual page for more information on options and ways to produce differences. The original source code is located in sources-orig and our second, modified codebase is located in a directory named sources-fixed. To show the differences in a unified diff format in your terminal, use the following command:
```
$ diff -Naur sources-orig/ sources-fixed/
```
...which then shows the following diff command output:
```
diff -Naur sources-orig/officespace/interest.go sources-fixed/officespace/interest.go
--- sources-orig/officespace/interest.go        2018-08-10 16:39:11.000000000 -0400
+++ sources-fixed/officespace/interest.go       2018-08-10 16:39:40.000000000 -0400
@@ -11,15 +11,13 @@
   InterestRate float64
 }
+// compute the rounded interest for a transaction
 func computeInterest(acct *Account, t Transaction) float64 {
   interest := t.Amount 选题模板.txt 中文排版指北.md comic core.md Dict.md lctt2014.md lctt2016.md LCTT翻译规范.md LICENSE Makefile published README.md sign.md sources translated t.InterestRate
   roundedInterest := math.Floor(interest*100) / 100.0
   remainingInterest := interest - roundedInterest
-  // a little extra..
-  remainingInterest *= 1000
-
   // Save the remaining interest into an account we control:
   acct.Balance = acct.Balance + remainingInterest
```
The first few lines of the diff command output could use some explanation: The three `---` signs show the original filename; any lines that exist in the original file but not in the compared new file will be prefixed with a single `-` to note that this line was “subtracted” from the sources. The `+++` signs show the opposite: The compared new file and additions found in this file are marked with a single `+` symbol to show they were added in the new version of the file. Each “hunk” (thats what sections prefixed by `@@` are called) of the difference patch file has contextual line numbers that help the patch tool (or other processors) know where to apply this change. You can see from the "Office Space" movie reference function that weve corrected (by removing three lines) the greed of one of our software developers, who added a bit to the rounded-out interest calculation along with a comment to our function.
If you want someone else to test the changes from this tree, you could save this output from diff into a patch file:
```
$ diff -Naur sources-orig/ sources-fixed/ >myfixes.patch
```
Now you have a patch file, myfixes.patch, which can be shared with another developer to apply and test this set of changes. A fellow developer can apply the changes using the patch tool, given that their current working directory is in the base of the source code tree:
```
$ patch -p1 < ../myfixes.patch
patching file officespace/interest.go
```
Now your fellow developers source tree is patched and ready to build and test the changes that were applied via the patch. What if this developer had made changes to interest.go separately? As long as the changes do not conflict directly—for example, change the same exact lines—the patch tool should be able to solve where to merge the changes in. As an example, an interest.go file with several other changes is used in the following example run of patch:
```
$ patch -p1 < ../myfixes.patch
patching file officespace/interest.go
Hunk #1 succeeded at 26 (offset 15 lines).
```
In this case, patch warns that the changes did not apply at the original location in the file, but were offset by 15 lines. If you have heavily changed files, patch may give up trying to find where the changes fit, but it does provide options (with requisite warnings in the documentation) for turning up the matching “fuzziness” (which are beyond the scope of this article).
If you are using Git and/or GitHub, you will probably not use the diff or patch tools as standalone tools. Git offers much of this functionality so you can use the built-in capabilities of working on a shared source tree with merging and pulling other developers changes. One similar capability is to use git diff to provide the unified diff output in your local tree or between any two references (a commit identifier, the name of a tag or branch, and so on). You can even create a patch file that someone not using Git might find useful by simply piping the git diff output to a file, given that it uses the exact format of the diffcommand that patch can consume. Of course, GitHub takes these capabilities into a web-based user interface so you can view file changes on a pull request. In this view, you will note that it is effectively a unified diff view in your web browser, and GitHub allows you to download these changes as a raw patch file.
### Summary
Youve learned what a diff and a patch are, as well as the common Unix/Linux command line tools that interact with them. Unless you are a developer on a project still using a patch file-based development method—like the Linux kernel—you will consume these capabilities primarily through a source code control system like Git. But its helpful to know the background and underpinnings of features many developers use daily through higher-level tools like GitHub. And who knows—they may come in handy someday when you need to work with patches from a mailing list in the Linux world.
--------------------------------------------------------------------------------
via: https://opensource.com/article/18/8/diffs-patches
作者:[Phil Estes][a]
选题:[lujun9972](https://github.com/lujun9972)
译者:[译者ID](https://github.com/译者ID)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://opensource.com/users/estesp
[1]:https://github.com/TooDumbForAName/ncsa-httpd
[2]:https://web.archive.org/web/19970615081902/http:/www.apache.org/info.html
[3]:https://en.wikipedia.org/wiki/Patch_(computing)
[4]:https://git-scm.com/
[5]:https://subversion.apache.org/
[6]:https://lkml.org/
[7]:https://lists.linuxfoundation.org/pipermail/containers/
[8]:https://patchwork.kernel.org/project/linux-fsdevel/list/
[9]:https://www.spinics.net/lists/netdev/
[10]:https://github.com/
[11]:https://kubernetes.io/
[12]:https://www.docker.com/
[13]:https://github.com/containernetworking/cni
[14]:https://istio.io/

View File

@ -1,99 +0,0 @@
translating---geekpi
How to Update Firmware on Ubuntu 18.04
======
Usually, the default software center in Ubuntu and other Linux handle the update of the firmware of your system. But if you encounter errors with it, you can use fwupd command line tool for updating the firmware of your system.
I use [Dell XPS 13 Ubuntu edition][1] as my main operating system. I have done a fresh [installation of Ubuntu 18.04][2] on it and I cannot be happier with the hardware compatibility. Bluetooth, external USB headsets and speakers, multi-monitor, everything works out of the box.
The one thing that troubled me was one of the [firmware][3] updates that appeared in the Software Center.
![Updating firmware in Ubuntu][4]
Clicking on the Update button resulted in an error a few seconds later.
![Updating firmware in Ubuntu][5]
The error message was:
**Unable to update “Thunderbolt NVM for Xps Notebook 9360”: could not detect device after update: timed out while waiting for device**
In this quick tip, Ill show you how to update the firmware of your system in [Ubuntu][6].
### Updating firmware in Ubuntu 18.04
![How to update firmware in Ubuntu][7]
One thing you should know that GNOME Software i.e. the software center in Ubuntu 18.04 is also capable of updating the firmware. But in situations when it fails for some reason, you can use the command line tool fwupd.
[fwupd][8] is an open source daemon that handles firmware upgrades in Linux based systems. It is created by GNOME developer [Richard Hughes][9]. Developers from Dell also contributed to the development of this open source tool.
Basically, it utilizes the LVFS, Linux Vendor Firmware Service. Hardware vendors upload redistributable firmware to the LVFS site and thanks to fwupd, you can upgrade those firmware from inside the operating system itself. fwupd is supported by major Linux distributions like Ubuntu and Fedora.
Open a terminal and update your system first:
```
sudo apt update && sudo apt upgrade -y
```
After that you can use the following commands one by one to start the daemon, refresh the list of available firmware updates and install the firmware updates.
```
sudo service fwupd start
```
Once the daemon is running, check if there are any firmware updates available.
```
sudo fwupdmgr refresh
```
The output should look like this:
Fetching metadata <https://cdn.fwupd.org/downloads/firmware.xml.gz>
Downloading… [****************************]
Fetching signature <https://cdn.fwupd.org/downloads/firmware.xml.gz.asc>
After this, run the firmware update:
```
sudo fwupdmgr update
```
The output of the firmware update could be similar to this:
```
No upgrades for XPS 13 9360 TPM 2.0, current is 1.3.1.0: 1.3.1.0=same
No upgrades for XPS 13 9360 System Firmware, current is 0.2.8.1: 0.2.8.1=same, 0.2.7.1=older, 0.2.6.2=older, 0.2.5.1=older, 0.2.4.2=older, 0.2.3.1=older, 0.2.2.1=older, 0.2.1.0=older, 0.1.3.7=older, 0.1.3.5=older, 0.1.3.2=older, 0.1.2.3=older
Downloading 21.00 for XPS13 9360 Thunderbolt Controller…
Updating 21.00 on XPS13 9360 Thunderbolt Controller…
Decompressing… [***********]
Authenticating… [***********]
Restarting device… [***********]
```
This should handle the firmware update in Ubuntu 18.04. I hope this quick tip helped you with firmware updates in Linux.
If you have questions or suggestions, please feel free to use the comment section below.
--------------------------------------------------------------------------------
via: https://itsfoss.com/update-firmware-ubuntu/
作者:[Abhishek Prakash][a]
选题:[lujun9972](https://github.com/lujun9972)
译者:[译者ID](https://github.com/译者ID)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://itsfoss.com/author/abhishek/
[1]: https://itsfoss.com/dell-xps-13-ubuntu-review/
[2]: https://itsfoss.com/install-ubuntu-dual-boot-mode-windows/
[3]: https://en.wikipedia.org/wiki/Firmware
[4]: https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2018/08/ubuntu-firmware-update-error-1.png
[5]: https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2018/08/ubuntu-firmware-update-error-2.jpg
[6]: https://www.ubuntu.com/
[7]: https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2018/08/update-firmware-ubuntu.png
[8]: https://fwupd.org/
[9]: https://github.com/hughsie/fwupd

View File

@ -1,110 +0,0 @@
heguangzhi Translating
6 open source tools for making your own VPN
======
![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/vpn_scrabble_networking.jpg?itok=pdsUHw5N)
If you want to try your hand at building your own VPN but arent sure where to start, youve come to the right place. Ill compare six of the best free and open source tools to set up and use a VPN on your own server. These VPNs work whether you want to set up a site-to-site VPN for your business or just create a remote access proxy to unblock websites and hide your internet traffic from ISPs.
Which is best depends on your needs and limitations, so take into consideration your own technical expertise, environment, and what you want to achieve with your VPN. In particular, consider the following factors:
* VPN protocol
* Number of clients and types of devices
* Server distro compatibility
* Technical expertise required
### Algo
[Algo][1] was designed from the bottom up to create VPNs for corporate travelers who need a secure proxy to the internet. It “includes only the minimal software you need,” meaning you sacrifice extensibility for simplicity. Algo is based on StrongSwan but cuts out all the things that you dont need, which has the added benefit of removing security holes that a novice might otherwise not notice.
As an added bonus, it even blocks ads!
Algo supports only the IKEv2 protocol and Wireguard. Because IKEv2 support is built into most devices these days, it doesnt require a client app like OpenVPN. Algo can be deployed using Ansible on Ubuntu (the preferred option), Windows, RedHat, CentOS, and FreeBSD. Setup is automated using Ansible, which configures the server based on your answers to a short set of questions. Its also very easy to tear down and re-deploy on demand.
Algo is probably the easiest and fastest VPN to set up and deploy on this list. Its extremely tidy and well thought out. If you dont need any of the more advanced features offered by other tools and just need a secure proxy, its a great option. Note that Algo explicitly states its not meant for geo-unblocking or evading censorship, and was primarily designed for confidentiality.
### Streisand
[Streisand][2] can be installed on any Ubuntu 16.04 server using a single command; the process takes about 10 minutes. It supports L2TP, OpenConnect, OpenSSH, OpenVPN, Shadowsocks, Stunnel, Tor bridge, and WireGuard. Depending on which protocol you choose, you may need to install a client app.
In many ways, Streisand is similar to Algo, but it offers more protocols and customization. This takes a bit more effort to manage and secure but is also more flexible. Note Streisand does not support IKEv2. I would say Streisand is more effective for bypassing censorship in places like China and Turkey due to its versatility, but Algo is easier and faster to set up.
The setup is automated using Ansible, so theres not much technical expertise required. You can easily add more users by sending them custom-generated connection instructions, which include an embedded copy of the servers SSL certificate.
Tearing down Streisand is a quick and painless process, and you can re-deploy on demand.
### OpenVPN
[OpenVPN][3] requires both client and server applications to set up VPN connections using the protocol of the same name. OpenVPN can be tweaked and customized to fit your needs, but it also requires the most technical expertise of the tools covered here. Both remote access and site-to-site configurations are supported; the former is what youll need if you plan on using your VPN as a proxy to the internet. Because client apps are required to use OpenVPN on most devices, the end user must keep them updated.
Server-side, you can opt to deploy in the cloud or on your Linux server. Compatible distros include CentOS, Ubuntu, Debian, and openSUSE. Client apps are available for Windows, MacOS, iOS, and Android, and there are unofficial apps for other devices. Enterprises can opt to set up an OpenVPN Access Server, but thats probably overkill for individuals, who will want the Community Edition.
OpenVPN is relatively easy to configure with static key encryption, but it isnt all that secure. Instead, I recommend setting it up with [easy-rsa][4], a key management package you can use to set up a public key infrastructure. This allows you to connect multiple devices at a time and protect them with perfect forward secrecy, among other benefits. OpenVPN uses SSL/TLS for encryption, and you can specify DNS servers in your configuration.
OpenVPN can traverse firewalls and NAT firewalls, which means you can use it to bypass gateways and firewalls that might otherwise block the connection. It supports both TCP and UDP transports.
### StrongSwan
You might have come across a few different VPN tools with “Swan” in the name. FreeS/WAN, OpenSwan, LibreSwan, and [strongSwan][5] are all forks of the same project, and the lattermost is my personal favorite. Server-side, strongSwan runs on Linux 2.6, 3.x, and 4x kernels, Android, FreeBSD, macOS, iOS, and Windows.
StrongSwan uses the IKEv2 protocol and IPSec. Compared to OpenVPN, IKEv2 connects much faster while offering comparable speed and security. This is useful if you prefer a protocol that doesnt require installing an additional app on the client, as most newer devices manufactured today natively support IKEv2, including Windows, MacOS, iOS, and Android.
StrongSwan is not particularly easy to use, and despite decent documentation, it uses a different vocabulary than most other tools, which can be confusing. Its modular design makes it great for enterprises, but that also means its not the most streamlined. Its certainly not as straightforward as Algo or Streisand.
Access control can be based on group memberships using X.509 attribute certificates, a feature unique to strongSwan. It supports EAP authentication methods for integration into other environments like Windows Active Directory. StrongSwan can traverse NAT firewalls.
### SoftEther
[SoftEther][6] started out as a project by a graduate student at the University of Tsukuba in Japan. SoftEther VPN Server and VPN Bridge run on Windows, Linux, OSX, FreeBSD, and Solaris, while the client app works on Windows, Linux, and MacOS. VPN Bridge is mainly for enterprises that need to set up site-to-site VPNs, so individual users will just need the server and client programs to set up remote access.
SoftEther supports the OpenVPN, L2TP, SSTP, and EtherIP protocols, but its own SoftEther protocol claims to be able to be immunized against deep packet inspection thanks to “Ethernet over HTTPS” camouflage. SoftEther also makes a few tweaks to reduce latency and increase throughput. Additionally, SoftEther includes a clone function that allows you to easily transition from OpenVPN to SoftEther.
SoftEther can traverse NAT firewalls and bypass firewalls. On restricted networks that permit only ICMP and DNS packets, you can utilize SoftEthers VPN over ICMP or VPN over DNS options to penetrate the firewall. SoftEther works with both IPv4 and IPv6.
SoftEther is easier to set up than OpenVPN and strongSwan but is a bit more complicated than Streisand and Algo.
### WireGuard
[WireGuard][7] is the newest tool on this list; it's so new that its not even finished yet. That being said, it offers a fast and easy way to deploy a VPN. It aims to improve on IPSec by making it simpler and leaner like SSH.
Like OpenVPN, WireGuard is both a protocol and a software tool used to deploy a VPN that uses said protocol. A key feature is “crypto key routing,” which associates public keys with a list of IP addresses allowed inside the tunnel.
WireGuard is available for Ubuntu, Debian, Fedora, CentOS, MacOS, Windows, and Android. WireGuard works on both IPv4 and IPv6.
WireGuard is much lighter than most other VPN protocols, and it transmits packets only when data needs to be sent.
The developers say WireGuard should not yet be trusted because it hasnt been fully audited yet, but youre welcome to give it a spin. It could be the next big thing!
### Homemade VPN vs. commercial VPN
Making your own VPN adds a layer of privacy and security to your internet connection, but if youre the only one using it, then it would be relatively easy for a well-equipped third party, such as a government agency, to trace activity back to you.
Furthermore, if you plan to use your VPN to unblock geo-locked content, a homemade VPN may not be the best option. Since youll only be connecting from a single IP address, your VPN server is fairly easy to block.
Good commercial VPNs dont have these issues. With a provider like [ExpressVPN][8], you share the servers IP address with dozens or even hundreds of other users, making it nigh-impossible to track a single users activity. You also get a huge range of hundreds or thousands of servers to choose from, so if one has been blacklisted, you can just switch to another.
The tradeoff of a commercial VPN, however, is that you must trust the provider not to snoop on your internet traffic. Be sure to choose a reputable provider with a clear no-logs policy.
--------------------------------------------------------------------------------
via: https://opensource.com/article/18/8/open-source-tools-vpn
作者:[Paul Bischoff][a]
选题:[lujun9972](https://github.com/lujun9972)
译者:[译者ID](https://github.com/译者ID)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:
[1]: https://blog.trailofbits.com/2016/12/12/meet-algo-the-vpn-that-works/
[2]: https://github.com/StreisandEffect/streisand
[3]: https://openvpn.net/
[4]: https://github.com/OpenVPN/easy-rsa
[5]: https://www.strongswan.org/
[6]: https://www.softether.org/
[7]: https://www.wireguard.com/
[8]: https://www.comparitech.com/vpn/reviews/expressvpn/

View File

@ -1,68 +0,0 @@
ucasFL translating
8 great Python libraries for side projects
======
![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/python-programming-code-keyboard.png?itok=fxiSpmnd)
We have a saying in the Python/Django world: We came for the language and stayed for the community. That is true for most of us, but something else that has kept us in the Python world is how easy it is to have an idea and quickly work through it over lunch or in a few hours at night.
This month we're diving into Python libraries we love to use to quickly scratch those side-project or lunchtime itches.
### To save data in a database on the fly: Dataset
[Dataset][1] is our go-to library when we quickly want to collect data and save it into a database before we know what our final database tables will look like. Dataset has a simple, yet powerful API that makes it easy to put data in and sort it out later.
Dataset is built on top of SQLAlchemy, so extending it will feel familiar. The underlying database models are a breeze to import into Django using Django's built-in [inspectdb][2] management command. This makes working with existing databases pretty painless.
### To scrape data from web pages: Beautiful Soup
[Beautiful Soup][3] (BS4 as of this writing) makes extracting information out of HTML pages easy. It's our go-to anytime we need to turn unstructured or loosely structured HTML into structured data. It's also great for working with XML data that might otherwise not be readable.
### To work with HTTP content: Requests
[Requests][4] is arguably one of the gold standard libraries for working with HTTP content. Anytime we need to consume an HTML page or even an API, Requests has us covered. It's also very well documented.
### To write command-line utilities: Click
When we need to write a native Python script, [Click][5] is our favorite library for writing command-line utilities. The API is straightforward, well thought out, and there are only a few patterns to remember. The docs are great, which makes looking up advanced features easy.
### To name things: Python Slugify
As we all know, naming things is hard. [Python Slugify][6] is a useful library for turning a title or description into a unique(ish) identifier. If you are working on a web project and you want to use SEO-friendly URLs, Python Slugify makes this easier.
### To work with plugins: Pluggy
[Pluggy][7] is relatively new, but it's also one of the best and easiest ways to add a plugin system to your existing application. If you have ever worked with pytest, you have used pluggy without knowing it.
### To convert CSV files into APIs: Datasette
[Datasette][8], not to be confused with Dataset, is an amazing tool for easily turning CSV files into full-featured read-only REST JSON APIs. Datasette has tons of features, including charting and geo (for creating interactive maps), and it's easy to deploy via a container or third-party web host.
### To handle environment variables and more: Envparse
If you need to parse environment variables because you don't want to save API keys, database credentials, or other sensitive information in your source code, then [envparse][9] is one of your best bets. Envparse handles environment variables, ENV files, variable types, and even pre- and post-processors (in case you want to ensure that a variable is always upper or lower case, for instance).
Do you have a favorite Python library for side projects that's not on this list? Please share it in the comments.
--------------------------------------------------------------------------------
via: https://opensource.com/article/18/9/python-libraries-side-projects
作者:[Jeff Triplett][a]
选题:[lujun9972](https://github.com/lujun9972)
译者:[译者ID](https://github.com/译者ID)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://opensource.com/users/laceynwilliams
[1]: https://dataset.readthedocs.io/en/latest/
[2]: https://docs.djangoproject.com/en/2.1/ref/django-admin/#django-admin-inspectdb
[3]: https://www.crummy.com/software/BeautifulSoup/
[4]: http://docs.python-requests.org/
[5]: http://click.pocoo.org/5/
[6]: https://github.com/un33k/python-slugify
[7]: https://pluggy.readthedocs.io/en/latest/
[8]: https://github.com/simonw/datasette
[9]: https://github.com/rconradharris/envparse

View File

@ -1,3 +1,5 @@
translating---geekpi
Two open source alternatives to Flash Player
======

View File

@ -1,43 +1,46 @@
理解 Linux 文件系统ext4 以及更多文件系统
==========================================
理解 Linux 文件系统ext4 等文件系统
=======
> 了解 ext4 的历史,包括其与 ext3 和之前的其它文件系统之间的区别。
![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/rh_003499_01_linux11x_cc.png?itok=XMDOouJR)
目前的大部分 Linux 文件系统都默认采用 ext4 文件系统, 正如以前的 Linux 发行版默认使用 ext3、ext2 以及更久前的 ext。对于不熟悉 Linux 或文件系统的朋友而言,你可能不清楚 ext4 相对于上一版本 ext3 带来了什么变化。你可能还想知道在一连串关于可替代文件系统例如 btrfs、xfs 和 zfs 不断被发布的情况下ext4 是否仍然能得到进一步的发展 。
在一篇文章中,我们不可能讲述文件系统的所有方面,但我们尝试让您尽快了解 Linux 默认文件系统的发展历史,包括它的产生以及未来发展。我仔细研究了维基百科里的各种关于 ext 文件系统文章、kernel.orgs wiki 中关于 ext4 的条目以及结合自己的经验写下这篇文章。
目前的大部分 Linux 文件系统都默认采用 ext4 文件系统, 正如以前的 Linux 发行版默认使用 ext3、ext2 以及更久前的 ext。
对于不熟悉 Linux 或文件系统的朋友而言,你可能不清楚 ext4 相对于上一版本 ext3 带来了什么变化。你可能还想知道在一连串关于替代的文件系统例如 btrfs、xfs 和 zfs 不断被发布的情况下ext4 是否仍然能得到进一步的发展。
在一篇文章中,我们不可能讲述文件系统的所有方面,但我们尝试让您尽快了解 Linux 默认文件系统的发展历史,包括它的产生以及未来发展。我仔细研究了维基百科里的各种关于 ext 文件系统文章、kernel.org 的 wiki 中关于 ext4 的条目以及结合自己的经验写下这篇文章。
### ext 简史
#### MINIX 文件系统
在有 ext 之前, 使用的是 MINIX 文件系统。如果你不熟悉 Linux 历史, 那么可以理解为 MINIX 相对于 IBM PC/AT 微型计算机来说是一个非常小的类 Unix 系统。Andrew Tannenbaum 为了教学的目的而开发了它并于 1987 年发布了源代码(印刷版!)。
在有 ext 之前, 使用的是 MINIX 文件系统。如果你不熟悉 Linux 历史, 那么可以理解为 MINIX 是用于 IBM PC/AT 微型计算机的一个非常小的类 Unix 系统。Andrew Tannenbaum 为了教学的目的而开发了它,并于 1987 年发布了源代码(以印刷版的格式!)。
![](https://opensource.com/sites/default/files/styles/panopoly_image_original/public/u128651/ibm_pc_at.jpg?itok=Tfk3hQYB)
*IBM 1980 中期的 PC/AT[MBlairMartin](https://commons.wikimedia.org/wiki/File:IBM_PC_AT.jpg)[CC BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/deed.en)*
虽然你可以读阅 MINIX 的源代码但实际上它并不是免费的开源软件FOSS。出版 Tannebaum 著作的出版商要求你花 69 美元的许可费来获得 MINIX 的操作权,而这笔费用包含在书籍的费用中。尽管如此,在那时来说非常便宜,并且 MINIX 的使用得到迅速发展,很快超过了 Tannebaum 当初使用它来教授操作系统编码的意图。在整个 20 世纪 90 年代,你可以发现 MINIX 的安装在世界各个大学里面非常流行。
而此时,年轻的 Lius Torvalds 使用 MINIX 来开发原始 Linux 内核,并于 1991 年首次公布。而后在 1992 年 12 月在 GPL 开源协议下发布。
虽然你可以细读 MINIX 的源代码但实际上它并不是自由开源软件FOSS。出版 Tannebaum 著作的出版商要求你花 69 美元的许可费来运行 MINIX而这笔费用包含在书籍的费用中。尽管如此在那时来说非常便宜并且 MINIX 的使用得到迅速发展,很快超过了 Tannebaum 当初使用它来教授操作系统编码的意图。在整个 20 世纪 90 年代,你可以发现 MINIX 的安装在世界各个大学里面非常流行。而此时,年轻的 Lius Torvalds 使用 MINIX 来开发原始 Linux 内核,并于 1991 年首次公布。而后在 1992 年 12 月在 GPL 开源协议下发布。
但是等等,这是一篇以*文件系统*为主题的文章不是吗是的MINIX 有自己的文件系统,早期的 Linux 版本依赖于它。跟 MINIX 一样Linux 的文件系统也如同玩具那般小 —— MINX 文件系统最多能处理 14 个字符的文件名,并且只能处理 64MB 的存储空间。到了 1991 年,一般的硬盘尺寸已经达到了 40-140MB。很显然Linux 需要一个更好的文件系统。
但是等等,这是一篇以*文件系统*为主题的文章不是吗是的MINIX 有自己的文件系统,早期的 Linux 版本依赖于它。跟 MINIX 一样Linux 的文件系统也如同玩具那般小 —— MINIX 文件系统最多能处理 14 个字符的文件名,并且只能处理 64MB 的存储空间。到了 1991 年,一般的硬盘尺寸已经达到了 40-140MB。很显然Linux 需要一个更好的文件系统。
#### ext
当 Linus 开发出刚起步的 Linux 内核时Rémy Card 从事第一代的 ext 文件系统的开发工作。 ext 文件系统在 1992 首次实现并发布 —— 仅在 Linux 首次发布后的一年! —— ext 解决了 MINIX 文件系统中最糟糕的问题。
1992年的 ext 使用在 Linux 内核中的新虚拟文件系统VFS抽象层。与之前的 MINIX 文件系统不同的是ext 可以处理高达 2GB 存储空间并处理 255 个字符的文件名。
1992 年的 ext 使用在 Linux 内核中的新虚拟文件系统VFS抽象层。与之前的 MINIX 文件系统不同的是ext 可以处理高达 2GB 存储空间并处理 255 个字符的文件名。
但 ext 并没有长时间占统治地位,主要是由于它原始时间戳(每个文件仅有一个时间戳,而不是今天我们所熟悉的有 inode 、最近文件访问时间和最新文件修改时间的时间戳。仅仅一年后ext2 就替代了它。
但 ext 并没有长时间占统治地位,主要是由于它原始时间戳(每个文件仅有一个时间戳,而不是今天我们所熟悉的有 inode 、最近文件访问时间和最新文件修改时间的时间戳。仅仅一年后ext2 就替代了它。
#### ext2
Rémy 很快就意识到 ext 的局限性,所以一年后他设计出 ext2 替代它。当 ext 仍然根植于 "玩具” 操作系统时ext2 从一开始就被设计为一个商业级文件系统,沿用 BSD 的 Berkeley 文件系统的设计原理。
Rémy 很快就意识到 ext 的局限性,所以一年后他设计出 ext2 替代它。当 ext 仍然根植于 玩具” 操作系统时ext2 从一开始就被设计为一个商业级文件系统,沿用 BSD 的 Berkeley 文件系统的设计原理。
Ext2 提供了 GB 级别的最大文件大小和 TB 级别的文件系统大小,使其在 20 世纪 90 年代的地位牢牢巩固在文件系统大联盟中。很快它被广泛地使用,无论是在 Linux 内核中还是最终在 MINIX 中,且利用第三方模块可以使其应用于 MacOs 和 Windows。
Ext2 提供了 GB 级别的最大文件大小和 TB 级别的文件系统大小,使其在 20 世纪 90 年代的地位牢牢巩固在文件系统大联盟中。很快它被广泛地使用,无论是在 Linux 内核中还是最终在 MINIX 中,且利用第三方模块可以使其应用于 MacOS 和 Windows。
但这里仍然有一些问题需要解决ext2 文件系统与 20 世纪 90 年代的大多数文件系统一样,如果在将数据写入到磁盘的时候,系统发生溃或断电,则容易发生灾难性的数据损坏。随着时间的推移,由于碎片(单个文件存储在多个位置,物理上其分散在旋转的磁盘上),它们也遭受了严重的性能损失。
但这里仍然有一些问题需要解决ext2 文件系统与 20 世纪 90 年代的大多数文件系统一样,如果在将数据写入到磁盘的时候,系统发生溃或断电,则容易发生灾难性的数据损坏。随着时间的推移,由于碎片(单个文件存储在多个位置,物理上其分散在旋转的磁盘上),它们也遭受了严重的性能损失。
尽管存在这些问题,但今天 ext2 还是用在某些特殊的情况下 —— 最常见的是,作为便携式 USB 拇指驱动器的文件系统格式。
@ -45,21 +48,19 @@ Ext2 提供了 GB 级别的最大文件大小和 TB 级别的文件系统大小
1998 年, 在 ext2 被采用后的 6 年后Stephen Tweedie 宣布他正在致力于改进 ext2。这成了 ext3并于 2001 年 11 月在 2.4.15 内核版本中被采用到 Linux 内核主线中。
![Packard Bell 计算机][2]
20世纪90年代中期的 Packard Bell 计算机, [Spacekid][3], [CC0][4]
*20 世纪 90 年代中期的 Packard Bell 计算机,[Spacekid][3][CC0][4]*
在大部分情况下Ext2 在 Linux 发行版中得很好,但像 FAT、FAT32、HFS 和当时的其他文件系统一样 —— 在断电时容易发生灾难性的破坏。如果在将数据写入文件系统时候发生断电,则可能会将其留在所谓 *不一致* 的状态 —— 事情只完成一半而另一半未完成。这可能导致大量文件丢失或损坏,这些文件与正在保存的文件无关甚至导致整个文件系统无法卸载。
在大部分情况下Ext2 在 Linux 发行版中工作得很好,但像 FAT、FAT32、HFS 和当时的其他文件系统一样 —— 在断电时容易发生灾难性的破坏。如果在将数据写入文件系统时候发生断电,则可能会将其留在所谓*不一致*的状态 —— 事情只完成一半而另一半未完成。这可能导致大量文件丢失或损坏,这些文件与正在保存的文件无关甚至导致整个文件系统无法卸载。
Ext3 和 20 世纪 90 年代后期的其他文件系统,如微软的 NTFS ,使用*日志*来解决这个问题。 日志是磁盘上的一种特殊分配,其写入存储在事务中;如果事务完成写入磁盘,则日志中的数据将提交给文件系统它本身。如果文件在它提交操作前崩溃,则重新启动的系统识别其为未完成的事务而将其进行回滚,就像从未发生过一样。这意味着正在处理的文件可能依然会丢失,但文件系统本身保持一致,且其他所有数据都是安全的。
Ext3 和 20 世纪 90 年代后期的其他文件系统,如微软的 NTFS ,使用*日志*来解决这个问题。日志是磁盘上的一种特殊的分配区域,其写入被存储在事务中;如果该事务完成磁盘写入,则日志中的数据将提交给文件系统自身。如果系统在该操作提交前崩溃,则重新启动的系统识别其为未完成的事务而将其进行回滚,就像从未发生过一样。这意味着正在处理的文件可能依然会丢失,但文件系统*本身*保持一致,且其他所有数据都是安全的。
在使用 ext3 文件系统的 Linux 内核中实现了三个级别的日志记录方式:**日记journal** , **顺序ordered** , 和 **回写writeback**
* **日记Journal** 是最低风险模式,在将数据和元数据提交给文件系统之前将其写入日志。这可以保证正在写入的文件与整个文件系统的一致性,但其显著降低了性能。
* **顺序Ordered** 是大多数 Linux 发行版默认模式ordered 模式将元数据写入日志且直接将数据提交到文件系统。顾名思义,这里的操作顺序是固定的:首先,元数据提交到日志;其次,数据写入文件系统,然后才将日志中关联的元数据更新到文件系统。这确保了在发生奔溃时,与未完整写入相关联的元数据仍在日志中,且文件系统可以在回滚日志时清理那些不完整的写入事务。在 ordered 模式下,系统崩溃可能导致在崩溃期间文件被主动写入或损坏,但文件系统它本身 —— 以及未被主动写入的文件 —— 确保是安全的。
* **回写Writeback** 是第三种模式 —— 也是最不安全的日志模式。在 writeback 模式下,像 ordered 模式一样,元数据会被记录,但数据不会。与 ordered 模式不同,元数据和数据都可以以任何有利于获得最佳性能的顺序写入。这可以显著提高性能,但安全性低很多。尽管 wireteback 模式仍然保证文件系统本身的安全性,但在奔溃或之前写入的文件很容易丢失或损坏。
在使用 ext3 文件系统的 Linux 内核中实现了三个级别的日志记录方式:<ruby>日记<rt>journal</rt></ruby><ruby>顺序<rt>ordered</rt></ruby><ruby>回写<rt>writeback</rt></ruby>
* **日记** 是最低风险模式,在将数据和元数据提交给文件系统之前将其写入日志。这可以保证正在写入的文件与整个文件系统的一致性,但其显著降低了性能。
* **顺序** 是大多数 Linux 发行版默认模式;顺序模式将元数据写入日志而直接将数据提交到文件系统。顾名思义,这里的操作顺序是固定的:首先,元数据提交到日志;其次,数据写入文件系统,然后才将日志中关联的元数据更新到文件系统。这确保了在发生崩溃时,那些与未完整写入相关联的元数据仍在日志中,且文件系统可以在回滚日志时清理那些不完整的写入事务。在顺序模式下,系统崩溃可能导致在崩溃期间文件的错误被主动写入,但文件系统它本身 —— 以及未被主动写入的文件 —— 确保是安全的。
* **回写** 是第三种模式 —— 也是最不安全的日志模式。在回写模式下,像顺序模式一样,元数据会被记录到日志,但数据不会。与顺序模式不同,元数据和数据都可以以任何有利于获得最佳性能的顺序写入。这可以显著提高性能,但安全性低很多。尽管回写模式仍然保证文件系统本身的安全性,但在崩溃或崩溃之前写入的文件很容易丢失或损坏。
跟之前的 ext2 类似ext3 使用 16 位内部寻址。这意味着对于有着 4K 块大小的 ext3 在最大规格为 16TiB 的文件系统中可以处理的最大文件大小为 2TiB。
@ -67,182 +68,167 @@ Ext3 和 20 世纪 90 年代后期的其他文件系统,如微软的 NTFS
Theodore Ts'o (是当时 ext3 主要开发人员) 在 2006 年发表的 ext4 ,于两年后在 2.6.28 内核版本中被加入到了 Linux 主线。
Tso 将 ext4 描述为一个显著扩展 ext3 的临时技术,仍然依赖于旧技术。他预计 ext4 终将会被真正的下一代文件系统所取代。
Tso 将 ext4 描述为一个显著扩展 ext3 但仍然依赖于旧技术的临时技术。他预计 ext4 终将会被真正的下一代文件系统所取代。
![](https://opensource.com/sites/default/files/styles/panopoly_image_original/public/u128651/dell_precision_380_workstation.jpeg?itok=3EjYXY2i)
Ext4 在功能上与 Ext3 在功能上非常相似,但大大支持文件系统、提高了对碎片的抵抗力,有更高的性能以及更好的时间戳。
*Dell Precision 380 工作站,[Lance Fisher](https://commons.wikimedia.org/wiki/File:Dell_Precision_380_Workstation.jpeg)[CC BY-SA 2.0](https://creativecommons.org/licenses/by-sa/2.0/deed.en)*
### Ext4 vs ext3
Ext4 在功能上与 Ext3 在功能上非常相似,但支持大文件系统、提高了对碎片的抵抗力,有更高的性能以及更好的时间戳。
Ext3 和 Ext4 有一些非常明确的差别,在这里集中讨论下。
### ext4 vs ext3
ext3 和 ext4 有一些非常明确的差别,在这里集中讨论下。
#### 向后兼容性
Ext4 特地设计为尽可能地向后兼容 ext3。这不仅允许 ext3 文件系统升级到 ext4也允许 ext4 驱动程序在 ext3 模式下自动挂载 ext3 文件系统,因此使它无需单独维护两个代码库。
ext4 特地设计为尽可能地向后兼容 ext3。这不仅允许 ext3 文件系统原地升级到 ext4也允许 ext4 驱动程序以 ext3 模式自动挂载 ext3 文件系统,因此使它无需单独维护两个代码库。
#### 大文件系统
Ext3 文进系统使用 32 为寻址,这限制它仅支持 2TiB 文件大小和 16TiB 文件系统系统大小(这是假设在块大小为 4KiB 的情况下,一些 ext3 文件系统使用更小的块大小,因此对其进一步做了限制)。
ext3 文件系统使用 32 位寻址,这限制它仅支持 2TiB 文件大小和 16TiB 文件系统系统大小(这是假设在块大小为 4KiB 的情况下,一些 ext3 文件系统使用更小的块大小,因此对其进一步限制)。
Ext4 使用 48 位的内部寻址,理论上可以在文件系统上分配高达 16TiB 大小的文件,其中文件系统大小最高可达 1000 000 TiB1EiB。在早期 ext4 的实现中 有些用户空间的程序仍然将其限制为最大大小为 16TiB 的文件系统,但截至 2011 年e2fsprogs 已经直接支持大于 16TiB 大小的 ext4 文件系统。例如,红帽企业 Linux 合同上仅支持最高 50TiB 的 ext4 文件系统,并建议 ext4 卷不超过 100TiB。
ext4 使用 48 位的内部寻址,理论上可以在文件系统上分配高达 16TiB 大小的文件,其中文件系统大小最高可达 1000000 TiB1EiB。在早期 ext4 的实现中有些用户空间的程序仍然将其限制为最大大小为 16TiB 的文件系统,但截至 2011 年e2fsprogs 已经直接支持大于 16TiB 大小的 ext4 文件系统。例如,红帽企业 Linux 在其合同上仅支持最高 50TiB 的 ext4 文件系统,并建议 ext4 卷不超过 100TiB。
#### 分配改进
#### 分配方式改进
Ext4 在将存储块写入磁盘之前对存储块的分配方式进行了大量改进,这可以显著提高读写性能。
ext4 在将存储块写入磁盘之前对存储块的分配方式进行了大量改进,这可以显著提高读写性能。
##### 区段extent
##### 区段
extent 是一系列连续的物理块大小 (最多达 128 MiB假设块大小为 4KiB可以一次性保留和寻址。使用区段可以减少给定未见所需的 inode 数量,并显著减少碎片并提高写入大文件时的性能。
<ruby>区段<rt>extent</rt></ruby>是一系列连续的物理块 (最多达 128 MiB假设块大小为 4KiB可以一次性保留和寻址。使用区段可以减少给定文件所需的 inode 数量,并显著减少碎片并提高写入大文件时的性能。
##### 多块分配
Ext3 为每一个新分配的块调用一次块分配器。当多个块调用同时打开分配器时很容易导致严重的碎片。然而ext4 使用延迟分配,这允许它合并写入并更好地决定如何为尚未提交的写入分配块。
ext3 为每一个新分配的块调用一次块分配器。当多个写入同时打开分配器时很容易导致严重的碎片。然而ext4 使用延迟分配,这允许它合并写入并更好地决定如何为尚未提交的写入分配块。
##### 持的预分配
##### 持的预分配
在为文件预分配磁盘空间时大部分文件系统必须在创建时将零写入该文件的块中。Ext4 允许使用 `fallocate()`,它保证了空间的可用性(并试图为它找到连续的空间),而不需要县写入它。
这显著提高了写入和将来读取流和数据库应用程序的写入数据的性能。
在为文件预分配磁盘空间时大部分文件系统必须在创建时将零写入该文件的块中。ext4 允许替代使用 `fallocate()`,它保证了空间的可用性(并试图为它找到连续的空间),而不需要先写入它。这显著提高了写入和将来读取流和数据库应用程序的写入数据的性能。
##### 延迟分配
这是一个耐人味而有争议性的功能。延迟分配允许 ext4 等待分配将写入数据的实际块直到它准备好将数据提交到磁盘。相比之下即使数据仍然在写入缓存ext3 也会立即分配块。)
这是一个耐人味而有争议性的功能。延迟分配允许 ext4 等待分配将写入数据的实际块,直到它准备好将数据提交到磁盘。(相比之下,即使数据仍然在写入缓存中写入ext3 也会立即分配块。)
当缓存中的数据累积时,延迟分配块允许文件系统做出更好的选择。然而不幸的是,当程序员想确保数据完全刷新到磁盘时,它增加了在还没有专门编写调用 fsync方法的程序中的数据丢失的可能性。
当缓存中的数据累积时,延迟分配块允许文件系统对如何分配块做出更好的选择,降低碎片(写入,以及稍后的读)并显著提升性能。然而不幸的是,它*增加*了还没有专门调用 `fsync()` 方法(当程序员想确保数据完全刷新到磁盘时)的程序的数据丢失的可能性。
假设一个程序完全重写了一个文件:
`fd=open("file" ,O_TRUNC); write(fd, data); close(fd);`
```
fd=open("file" ,O_TRUNC); write(fd, data); close(fd);
```
使用旧的文件系统, `close(fd);` 足以保证 `file` 中的内存刷新到磁盘。即使严格来说,写不是事务性的,但如果文件关闭后发生崩溃,则丢失数据的风险很小。如果写入不成功(由于程序上的错误、磁盘上的错误、断电等),文件的原始版本和较新版本都可能丢失数据或损坏。如果其他进程在写入文件时访问文件,则会看到损坏的版本。
如果其他进程打开文件并且不希望其内容发生更改 —— 例如,映射到多个正在运行的程序的共享库。这些进程可能会崩溃。
使用旧的文件系统, `close(fd);` 足以保证 `file` 中的内容刷新到磁盘。即使严格来说,写不是事务性的,但如果文件关闭后发生崩溃,则丢失数据的风险很小。
如果写入不成功(由于程序上的错误、磁盘上的错误、断电等),文件的原始版本和较新版本都可能丢失数据或损坏。如果其他进程在写入文件时访问文件,则会看到损坏的版本。如果其他进程打开文件并且不希望其内容发生更改 —— 例如,映射到多个正在运行的程序的共享库。这些进程可能会崩溃。
为了避免这些问题,一些程序员完全避免使用 `O_TRUNC`。相反,他们可能会写入一个新文件,关闭它,然后将其重命名为旧文件名:
`fd=open("newfile"); write(fd, data); close(fd); rename("newfile", "file");`
```
fd=open("newfile"); write(fd, data); close(fd); rename("newfile", "file");
```
在没有延迟分配的文件系统下,这足以避免上面列出的潜在的损坏和崩溃问题:因为`rename()` 是原子操作,所以它不会被崩溃中断;并且运行的程序将引用旧的。现在 `file` 的未链接版本主要有一个打开的文件文件句柄即可。
但是因为 ext4 的延迟分配会导致写入被延迟和重新排序,`rename("newfile","file")` 可以在 `newfile` 的内容实际写入磁盘内容之前执行,这打开了并行进行再次获得 `file` 坏版本的问题。
在*没有*延迟分配的文件系统下,这足以避免上面列出的潜在的损坏和崩溃问题:因为`rename()` 是原子操作,所以它不会被崩溃中断;并且运行的程序将继续引用旧的文件。现在 `file` 的未链接版本只要有一个打开的文件文件句柄即可。但是因为 ext4 的延迟分配会导致写入被延迟和重新排序,`rename("newfile","file")` 可以在 `newfile` 的内容实际写入磁盘内容之前执行,这出现了并行进行再次获得 `file` 坏版本的问题。
为了缓解这种情况Linux 内核(自版本 2.6.30 )尝试检测这些常见代码情况并强制立即分配。这减少但不能防止数据丢失的可能性 —— 并且它对新文件没有任何帮助。如果你是一位开发人员,请注意:
保证数据立即写入磁盘的方法是正确调用 `fsync()`
为了缓解这种情况Linux 内核(自版本 2.6.30 )尝试检测这些常见代码情况并强制立即分配。这会减少但不能防止数据丢失的可能性 —— 并且它对新文件没有任何帮助。如果你是一位开发人员,请注意:保证数据立即写入磁盘的唯一方法是正确调用 `fsync()`
#### 无限制的子目录
Ext3 仅限于 32000 个子目录ext4 允许无限数量的子目录。从 2.6.23 内核版本开始ext4 使用 HTree 索引来减少大量子目录的性能损失。
ext3 仅限于 32000 个子目录ext4 允许无限数量的子目录。从 2.6.23 内核版本开始ext4 使用 HTree 索引来减少大量子目录的性能损失。
#### 日志校验
Ext3 没有对日志进行校验,这给内核直接控制之外的磁盘或控制器设备带来了自己的缓存问题。如果控制器或具有子集对缓存的磁盘确实无序写入,则可能会破坏 ext3 的日记事务顺序,
从而可能破坏在崩溃期间(或之前一段时间)写入的文件。
ext3 没有对日志进行校验,这给处于内核直接控制之外的磁盘或带有自己的缓存的控制器设备带来了问题。如果控制器或具有自己的缓存的磁盘脱离了写入顺序,则可能会破坏 ext3 的日记事务顺序,从而可能破坏在崩溃期间(或之前一段时间)写入的文件。
理论上,这个问题可以使用 write barriers —— 在安装文件系统时,你在挂载选项设置 `barrier=1` ,然后将设备 `fsync` 一直向下调用直到 metal。通过实践可以发现存储设备和控制器经常不遵守 write barriers —— 提高性能(和 benchmarks跟竞争对手比较),但增加了本应该防止数据损坏的可能性。
理论上,这个问题可以使用写入<ruby>障碍<rt>barrier</rt></ruby> —— 在安装文件系统时,你在挂载选项设置 `barrier=1` ,然后设备就会忠实地执行 `fsync` 一直向下到底层硬件。通过实践,可以发现存储设备和控制器经常不遵守写入障碍 —— 提高性能(和跟竞争对手比较的性能基准),但增加了本应该防止数据损坏的可能性。
对日志进行校验和允许文件系统奔溃后意识到其某些条目在第一次安装时无效或无序。因此,这避免了即使部分存储设备不存在 barriers ,也会回滚部分或无序日志条目和进一步损坏的文件系统的错误
对日志进行校验和允许文件系统崩溃后第一次挂载时意识到其某些条目是无效或无序的。因此,这避免了回滚部分条目或无序日志条目的错误,并进一步损坏的文件系统——即使部分存储设备假做或不遵守写入障碍
#### 快速文件系统检查
在 ext3 下,整个文件系统 —— 包括已删除或空文件 —— 在 `fsck` 被调用时需要检查。相比之下ext4 标记了未分配块和 inode 表的小部分,从而允许 `fsck` 完全跳过它们。
这大大减少了在大多数文件系统上运行 `fsck` 的时间,并从内核 2.6.24 开始实现。
在 ext3 下,在 `fsck` 被调用时会检查整个文件系统 —— 包括已删除或空文件。相比之下ext4 标记了 inode 表未分配的块和扇区,从而允许 `fsck` 完全跳过它们。这大大减少了在大多数文件系统上运行 `fsck` 的时间,它实现于内核 2.6.24。
#### 改进的时间戳
Ext3 提供粒度为一秒的时间戳。虽然足以满足大多数用途,但任务关键型应用程序经常需要更严格的时间控制。Ext4 通过提供纳秒级的时间戳,使其可用于那些企业,科学以及任务关键型的应用程序。
ext3 提供粒度为一秒的时间戳。虽然足以满足大多数用途,但任务关键型应用程序经常需要更严格的时间控制。ext4 通过提供纳秒级的时间戳,使其可用于那些企业、科学以及任务关键型的应用程序。
Ext3文件系统也没有提供足够的位来存储 2038 年 1 月 18 日以后的日期。Ext4 在这里增加了两位,将 [the Unix epoch][5] 扩展了 408 年。如果你在公元 2446 年读到这篇文章,
你很有可能已经转移到一个更好的文件系统 —— 如果你还在测量 UTC 00:001970 年 1 月 1 日以来的时间,这会让我非常非常高兴。
ext3 文件系统也没有提供足够的位来存储 2038 年 1 月 18 日以后的日期。ext4 在这里增加了两个位,将 [Unix 纪元][5] 扩展了 408 年。如果你在公元 2446 年读到这篇文章,你很有可能已经转移到一个更好的文件系统 —— 如果你还在测量自 1970 年 1 月 1 日 00:00UTC以来的时间这会让我死后得以安眠。
#### 在线碎片整理
ext2 和 ext3 都不直接支持在线碎片整理 —— 即在挂载时会对文件系统进行碎片整理。Ext2 有一个包含的实用程序,**e2defrag**,它的名字暗示 —— 它需要在文件系统未挂载时脱机运行。(显然,这对于根文件系统来说非常有问题。)在 ext3 中的情况甚至更糟糕 —— 虽然 ext3 比 ext2 更不容易受到严重碎片的影响,但 ext3 文件系统运行 **e2defrag** 可能会导致灾难性损坏和数据丢失。
ext2 和 ext3 都不直接支持在线碎片整理 —— 即在挂载时会对文件系统进行碎片整理。ext2 有一个包含的实用程序,`e2defrag`,它的名字暗示 —— 它需要在文件系统未挂载时脱机运行。(显然,这对于根文件系统来说非常有问题。)在 ext3 中的情况甚至更糟糕 —— 虽然 ext3 比 ext2 更不容易受到严重碎片的影响,但 ext3 文件系统运行 `e2defrag` 可能会导致灾难性损坏和数据丢失。
尽管 ext3 最初被认为“不受碎片影响”,但对同一文件(例如 BitTorrent采用大规模并行写入过程的过程清楚地表明情况并非完全如此。一些用户空间攻击和解决方法例如 [Shake][6]
以这种或那种方式解决了这个问题 —— 但它们比真正的、文件系统感知的、内核级碎片整理过程更慢并且在各方面都不太令人满意。
尽管 ext3 最初被认为“不受碎片影响”,但对同一文件(例如 BitTorrent采用大规模并行写入过程的过程清楚地表明情况并非完全如此。一些用户空间的手段和解决方法例如 [Shake][6],以这样或那样方式解决了这个问题 —— 但它们比真正的、文件系统感知的、内核级碎片整理过程更慢并且在各方面都不太令人满意。
Ext4通过 **e4defrag** 解决了这个问题,且是一个在线、内核模式、文件系统感知、块和范围级别的碎片整理实用程序。
ext4通过 `e4defrag` 解决了这个问题,且是一个在线、内核模式、文件系统感知、块和区段级别的碎片整理实用程序。
### 正在进行的ext4开发
### 正在进行的 ext4 开发
Ext4正如 Monty Python 中瘟疫感染者曾经说过的那样,“我还没死呢!” 虽然它的[主要开发人员][7]认为它只是一个真正的[下一代文件系统][8]的权宜之计,但是在一段时间内,没有任何可能的候选人准备好(由于技术或许可问题)部署为根文件系统。
ext4正如 Monty Python 中瘟疫感染者曾经说过的那样,“我还没死呢!” 虽然它的[主要开发人员][7]认为它只是一个真正的[下一代文件系统][8]的权宜之计,但是在一段时间内,没有任何可能的候选人准备好(由于技术或许可问题)部署为根文件系统。
在未来的 ext4 版本中仍然有一些关键功能,包括元数据校验和、一流的配额支持和大分配块。
在未来的 ext4 版本中仍然有一些关键功能要开发,包括元数据校验和、一流的配额支持和大分配块。
#### 元数据校验和
由于 ext4 具有冗余超级块,因此为文件系统校验其中的元数据提供了一种方法,可以自行确定主超级块是否已损坏并需要使用备用块。可以在没有校验和的情况下,从损坏的超级块恢复 —— 但是用户首先需要意识到它已损坏,然后尝试使用备用方法手动挂载文件系统。由于在某些情况下,使用损坏的主超级块安装文件系统读写可能会造成进一步的损坏,即使是经验丰富的用户也无法避免,这也不是一个完美的解决方案!
与 btrfs 或 zfs 等下一代文件系统提供的极其强大的每块校验和相比ext4 的元数据校验和功能非常弱。但它总比没有好。虽然校验和所有的事情都听起来很简单!—— 事实上,将校验和连接到文件系统有一些重大的挑战; 请参阅[设计文档][9]了解详细信息。
与 btrfs 或 zfs 等下一代文件系统提供的极其强大的每块校验和相比ext4 的元数据校验和功能非常弱。但它总比没有好。虽然校验**所有的事情**都听起来很简单!—— 事实上,将校验和与文件系统连接到一起有一些重大的挑战;请参阅[设计文档][9]了解详细信息。
#### 一流的配额支持
等等,配额?!从 ext2 出现的那条开始我们就有了这些!是的,但他们一直都是事后的想法,而且他们总是有点傻逼。这里可能不值得详细介绍,
但[设计文档][10]列出了配额将从用户空间移动到内核中的方式,并且能够更加正确和高效地执行。
等等,配额?!从 ext2 出现的那天开始我们就有了这些!是的,但它们一直都是事后的添加的东西,而且它们总是犯傻。这里可能不值得详细介绍,但[设计文档][10]列出了配额将从用户空间移动到内核中的方式,并且能够更加正确和高效地执行。
#### 大分配块
随着时间的推移,那些讨厌的存储系统不断变得越来越大。由于一些固态硬盘已经使用 8K 硬件模块,因此 ext4 对 4K 模块的当前限制越来越受到限制。
较大的存储块可以显着减少碎片并提高性能,代价是增加“松弛”空间(当您只需要块的一部分来存储文件或文件的最后一块时留下的空间)。
随着时间的推移,那些讨厌的存储系统不断变得越来越大。由于一些固态硬盘已经使用 8K 硬件块大小,因此 ext4 对 4K 模块的当前限制越来越受到限制。较大的存储块可以显著减少碎片并提高性能,代价是增加“松弛”空间(当您只需要块的一部分来存储文件或文件的最后一块时留下的空间)。
您可以在[设计文档][11]中查看详细说明。
### ext4的实际限制
### ext4 的实际限制
Ext4 是一个健壮,稳定的文件系统。它是大多数人应该都在 2018 年用它作为根文件系统,但它无法处理所有需求。让我们简单地谈谈你不应该期待的一些事情 —— 现在或可能在未来
ext4 是一个健壮、稳定的文件系统。如今大多数人都应该在用它作为根文件系统,但它无法处理所有需求。让我们简单地谈谈你不应该期待的一些事情 —— 现在或可能在未来
虽然 ext4 可以处理高达 1 EiB 大小相当于 1,000,000 TiB 大小的数据,但你真的、真的不应该尝试这样做。除了仅仅能够记住更多块的地址之外,还存在规模上的问题
并且现在 ext4 不会处理(并且可能永远不会)超过 50 —— 100TiB 的数据。
虽然 ext4 可以处理高达 1 EiB 大小(相当于 1,000,000 TiB大小的数据但你真的、*真的*不应该尝试这样做。除了能够记住更多块的地址之外,还存在规模上的问题。并且现在 ext4 不会处理(并且可能永远不会)超过 50 —— 100TiB 的数据。
Ext4 也不足以保证数据的完整性。随着日志记录的重大进展又回到了前 3 天,它并未涵盖数据损坏的许多常见原因。如果数据已经在磁盘上被[破坏][12]——由于故障硬件,
宇宙射线的影响(是的,真的),或者数据随时间的简单降级 —— ext4无法检测或修复这种损坏。
ext4 也不足以保证数据的完整性。随着日志记录的重大进展又回到了 ext3 的那个时候,它并未涵盖数据损坏的许多常见原因。如果数据已经在磁盘上被[破坏][12]——由于故障硬件,宇宙射线的影响(是的,真的),或者只是数据随时间衰减 —— ext4 无法检测或修复这种损坏。
最后两点是ext4 只是一个纯文件系统,而不是存储卷管理器。这意味着,即使你有多个磁盘 ——也就是奇偶校验或冗余,理论上你可以从 ext4 中恢复损坏的数据,但无法知道使用它是否对你有利。虽然理论上可以在离散层中分离文件系统和存储卷管理系统而不会丢失自动损坏检测和修复功能,但这不是当前存储系统的设计方式,并且它将给新设计带来重大挑战。
基于上面两点ext4 只是一个纯*文件系统*,而不是存储卷管理器。这意味着,即使你有多个磁盘——也就是奇偶校验或冗余,理论上你可以从 ext4 中恢复损坏的数据,但无法知道使用它是否对你有利。虽然理论上可以在不同的层中分离文件系统和存储卷管理系统而不会丢失自动损坏检测和修复功能,但这不是当前存储系统的设计方式,并且它将给新设计带来重大挑战。
### 备用文件系统
在我们开始之前,提醒一句:要非常小心这是没有内置任何备用的文件系统,并直接支持为您分配的主线内核的一部分!
即使文件系统是安全的,如果在内核升级期间出现问题,使用它作为根文件系统也是非常可怕的。如果你没有充分的想法通过一个 chroot 去使用介质引导,耐心地操作内核模块和 grub 配置,
和 DKMS...不要在一个很重要的系统中去掉对根文件的备份。
在我们开始之前,提醒一句:要非常小心,没有任何备用的文件系统作为主线内核的一部分而内置和直接支持!
可能有充分的理由使用您的发行版不直接支持的文件系统 —— 但如果您这样做,我强烈建议您在系统启动并可用后再安装它。
(例如,您可能有一个 ext4 根文件系统,但是将大部分数据存储在 zfs 或 btrfs 池中。)
即使一个文件系统是*安全的*,如果在内核升级期间出现问题,使用它作为根文件系统也是非常可怕的。如果你没有充分的理由通过一个 chroot 去使用替代介质引导,耐心地操作内核模块、 grub 配置和 DKMS...不要在一个很重要的系统中去掉预留的根文件。
可能有充分的理由使用您的发行版不直接支持的文件系统 —— 但如果您这样做,我强烈建议您在系统启动并可用后再安装它。(例如,您可能有一个 ext4 根文件系统,但是将大部分数据存储在 zfs 或 btrfs 池中。)
#### XFS
XFS 与 非 ext 文件系统在Linux下的主线一样。它是一个 64 位的日志文件系统,自 2001 年以来内置于 Linux 内核中,为大型文件系统和高度并发性提供了高性能
(即,大量的进程都会立即写入文件系统)。
XFS 与非 ext 文件系统在 Linux 中的主线中的地位一样。它是一个 64 位的日志文件系统,自 2001 年以来内置于 Linux 内核中,为大型文件系统和高度并发性提供了高性能(即,大量的进程都会立即写入文件系统)。
从 RHEL 7开始XFS 成为 Red Hat Enterprise Linux 的默认文件系统。对于家庭或小型企业用户来说,它仍然有一些缺点 —— 最值得注意的是,重新调整现有 XFS 文件系统
是一件非常痛苦的事情,不如创建另一个并复制数据更有意义。
从 RHEL 7 开始XFS 成为 Red Hat Enterprise Linux 的默认文件系统。对于家庭或小型企业用户来说,它仍然有一些缺点 —— 最值得注意的是,重新调整现有 XFS 文件系统是一件非常痛苦的事情,不如创建另一个并复制数据更有意义。
虽然 XFS 是稳定且是高性能的,但它和 ext4 之间没有足够的具体的最终用途差异来推荐它在非默认值的任何地方使用例如RHEL7,除非它解决了对 ext4 的特定问题,例如> 50 TiB容量的文件系统。
虽然 XFS 是稳定且是高性能的,但它和 ext4 之间没有足够具体的最终用途差异以值得推荐在非默认例如RHEL7的任何地方使用它,除非它解决了对 ext4 的特定问题,例如 > 50 TiB 容量的文件系统。
XFS 在任何方面都不是 ZFSbtrfs 甚至 WAFL专有 SAN 文件系统)的“下一代”文件系统。就像 ext4 一样,它应该被视为一种更好的方式的权宜之计。
XFS 在任何方面都不是 ZFS、btrfs 甚至 WAFL一个专有的 SAN 文件系统)的“下一代”文件系统。就像 ext4 一样,它应该被视为一种更好的方式的权宜之计。
#### ZFS
ZFS 由 Sun Microsystems 开发,以 zettabyte 命名 —— 相当于 1 万亿 GB —— 因为它理论上可以解决大型存储系统。
作为真正的下一代文件系统ZFS 提供卷管理(能够在单个文件系统中处理多个单独的存储设备),块级加密校验和(允许以极高的准确率检测数据损坏),
[自动损坏修复][12](其中冗余或奇偶校验存储可用),[快速异步增量复制][13],内联压缩等,[还有更多][14]。
作为真正的下一代文件系统ZFS 提供卷管理(能够在单个文件系统中处理多个单独的存储设备),块级加密校验和(允许以极高的准确率检测数据损坏),[自动损坏修复][12](其中冗余或奇偶校验存储可用),[快速异步增量复制][13],内联压缩等,[以及更多][14]。
从 Linux 用户的角度来看ZFS 的最大问题是许可证问题。ZFS 许可证是 CDDL 许可证,这是一种与 GPL 冲突的半许可许可证。关于在 Linux 内核中使用 ZFS 的意义存在很多争议,
其争议范围从“它是 GPL 违规”到“它是 CDDL 违规”到“它完全没问题,它还没有在法庭上进行过测试。 “ 最值得注意的是自2016 年以来Canonical 已将 ZFS 代码内联
在其默认内核中,而且目前尚无法律挑战。
从 Linux 用户的角度来看ZFS 的最大问题是许可证问题。ZFS 许可证是 CDDL 许可证,这是一种与 GPL 冲突的半许可许可证。关于在 Linux 内核中使用 ZFS 的意义存在很多争议,其争议范围从“它是 GPL 违规”到“它是 CDDL 违规”到“它完全没问题,它还没有在法庭上进行过测试。 ” 最值得注意的是,自 2016 年以来 Canonical 已将 ZFS 代码内联在其默认内核中,而且目前尚无法律挑战。
此时,即使我作为一个非常狂热于 ZFS 的用户,我也不建议将 ZFS 作为 Linux的 root 文件系统。如果你想在 Linux 上利用 ZFS 的优势,在 ext4 上设置一个小的根文件系统,
然后将 ZFS 放在你剩余的存储上,把数据,应用程序以及你喜欢的东西放在它上面 —— 但在 ext4 上保持 root直到你的发行版明显支持 zfs 根目录。
此时,即使我作为一个非常狂热于 ZFS 的用户,我也不建议将 ZFS 作为 Linux 的 root 文件系统。如果你想在 Linux 上利用 ZFS 的优势,用 ext4 设置一个小的根文件系统,然后将 ZFS 用在你剩余的存储上,把数据、应用程序以及你喜欢的东西放在它上面 —— 但把 root 保留在 ext4 上,直到你的发行版明显支持 zfs 根目录。
#### BTRFS
Btrfs 是 B-Tree Filesystem 的简称,通常发音为 “butter” —— 由 Chris Mason 于 2007 年在 Oracle 任职期间宣布。BTRFS 旨在跟 ZFS 有大部分相同的目标,
提供多种设备管理,每块校验、异步复制、直列压缩等,[还有更多][8]。
Btrfs 是 B-Tree Filesystem 的简称,通常发音为 “butter” —— 由 Chris Mason 于 2007 年在 Oracle 任职期间发布。BTRFS 旨在跟 ZFS 有大部分相同的目标,提供多种设备管理、每块校验、异步复制、直列压缩等,[还有更多][8]。
截至 2018 年btrfs 相当稳定,可用作标准的单磁盘文件系统,但可能不应该依赖于卷管理器。与许多常见用例中的 ext4XFS 或 ZFS 相比,它存在严重的性能问题,
其下一代功能 —— 复制replication多磁盘拓扑和快照管理 —— 可能非常多,其结果可能是从灾难性地性能降低到实际数据的丢失。
截至 2018 年btrfs 相当稳定,可用作标准的单磁盘文件系统,但可能不应该依赖于卷管理器。与许多常见用例中的 ext4、XFS 或 ZFS 相比,它存在严重的性能问题,其下一代功能 —— 复制、多磁盘拓扑和快照管理 —— 可能非常多,其结果可能是从灾难性地性能降低到实际数据的丢失。
btrfs 的持续状态是有争议的; SUSE Enterprise Linux 在 2015 年采用它作为默认文件系统,而 Red Hat 宣布它将不再支持从 2017 年开始使用 RHEL 7.4 的 btrfs。
可能值得注意的是,生产,支持的 btrfs 部署将其用作单磁盘文件系统,而不是作为一个多磁盘卷管理器 —— a la ZFS —— 甚至 Synology 在它的存储设备使用 BTRFS
btrfs 的维持状态是有争议的SUSE Enterprise Linux 在 2015 年采用它作为默认文件系统,而 Red Hat 于 2017 年宣布它从 RHEL 7.4 开始不再支持 btrfs。可能值得注意的是该产品支持 btrfs 部署用作单磁盘文件系统,而不是像 ZFS 中的多磁盘卷管理器,甚至 Synology 在它的存储设备使用 BTRFS
但是它在传统 Linux 内核 RAIDmdraid之上分层来管理磁盘。
--------------------------------------------------------------------------------
@ -251,7 +237,7 @@ via: https://opensource.com/article/18/4/ext4-filesystem
作者:[Jim Salter][a]
译者:[HardworkFish](https://github.com/HardworkFish)
校对:[校对者ID](https://github.com/校对者ID)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出

View File

@ -0,0 +1,211 @@
如何在 Linux 中压缩和解压缩文件
======
![](https://www.ostechnix.com/wp-content/uploads/2018/03/compress-720x340.jpg)
当在备份重要文件和通过网络发送大文件的时候,对文件进行压缩非常有用。请注意,压缩一个已经压缩过的文件会增加额外开销,因此你将会得到一个更大一些的文件。所以,请不要压缩已经压缩过的文件。在 GNU/Linux 中,有许多程序可以用来压缩和解压缩文件。在这篇教程中,我们仅学习其中两个应用程序。
### 压缩和解压缩文件
在类 Unix 系统中,最常见的用来压缩文件的程序是:
1. gzip
2. bzip2
##### 1\. 使用 Gzip 程序来压缩和解压缩文件
Gzip 是一个使用 Lempel-Ziv 编码LZ77算法来压缩和解压缩文件的实用工具。
**1.1 压缩文件**
如果要压缩一个名为 ostechnix.txt 的文件,使之成为 gzip 格式的压缩文件,那么只需运行如下命令:
```
$ gzip ostechnix.txt
```
上面的命令运行结束之后,将会出现一个名为 ostechnix.txt.gz 的 gzip 格式压缩文件,代替原始的 ostechnix.txt 文件。
gzip 命令还可以有其他用法。一个有趣的例子是,我们可以将一个特定命令的输出通过管道传递,然后作为 gzip 程序的输入来创建一个压缩文件。看下面的命令:
```
$ ls -l Downloads/ | gzip > ostechnix.txt.gz
```
上面的命令将会创建一个 gzip 格式的压缩文件,文件的内容为 “Downloads” 目录的目录项。
**1.2 压缩文件并将输出写到新文件中(不覆盖原始文件)
**
默认情况下gzip 程序会压缩给定文件,并以压缩文件替代原始文件。但是,你也可以保留原始文件,并将输出写到标准输出。比如,下面这个命令将会压缩 ostechnix.txt 文件,并将输出写入文件 output.txt.gz 。
```
$ gzip -c ostechnix.txt > output.txt.gz
```
类似地,要解压缩一个 gzip 格式的压缩文件并指定输出文件的文件名,只需运行:
```
$ gzip -c -d output.txt.gz > ostechnix1.txt
```
上面的命令将会解压缩 output.txt.gz 文件,并将输出写入到文件 ostechnix1.txt 中。在上面两个例子中,原始文件均不会被删除。
**1.3 解压缩文件**
如果要解压缩 ostechnix.txt.gz 文件,并以原始未压缩版本的文件来代替它,那么只需运行:
```
$ gzip -d ostechnix.txt.gz
```
我们也可以使用 gunzip 程序来解压缩文件:
```
$ gunzip ostechnix.txt.gz
```
**1.4 在不解压缩的情况下查看压缩文件的内容**
如果你想在不解压缩的情况下,使用 gzip 程序查看压缩文件的内容,那么可以像下面这样使用 -c 选项:
```
$ gunzip -c ostechnix1.txt.gz
```
或者,你也可以像下面这样使用 zcat 程序:
```
$ zcat ostechnix.txt.gz
```
你也可以通过管道将输出传递给 less 命令,从而一页一页的来查看输出,就像下面这样:
```
$ gunzip -c ostechnix1.txt.gz | less
$ zcat ostechnix.txt.gz | less
```
另外zless 程序也能够实现和上面的管道同样的功能。
```
$ zless ostechnix1.txt.gz
```
**1.5 使用 gzip 压缩文件并指定压缩级别**
Gzip 的另外一个显著优点是支持压缩级别。它支持下面给出的 3 个压缩级别:
* **1** 最快 (最差)
* **9** 最慢 (最好)
* **6** 默认级别
要压缩名为 ostechnix.txt 的文件,使之成为“最好”压缩级别的 gzip 压缩文件,可以运行:
```
$ gzip -9 ostechnix.txt
```
**1.6 连接多个压缩文件**
我们也可以把多个需要压缩的文件压缩到同一个文件中。如何实现呢?看下面这个例子。
```
$ gzip -c ostechnix1.txt > output.txt.gz
$ gzip -c ostechnix2.txt >> output.txt.gz
```
上面的两个命令将会压缩文件 ostechnix1.txt 和 ostechnix2.txt并将输出保存到一个文件 output.txt.gz 中。
你可以通过下面其中任何一个命令,在不解压缩的情况下,查看两个文件 ostechnix1.txt 和 ostechnix2.txt 的内容:
```
$ gunzip -c output.txt.gz
$ gunzip -c output.txt
$ zcat output.txt.gz
$ zcat output.txt
```
如果你想了解关于 gzip 的更多细节,请参阅它的 man 手册。
```
$ man gzip
```
##### 2\. 使用 bzip2 程序来压缩和解压缩文件
bzip2 和 gzip 非常类似,但是 bzip2 使用的是 Burrows-Wheeler 块排序压缩算法,并使用<ruby>哈夫曼<rt>Huffman</rt></ruby>编码。使用 bzip2 压缩的文件以 “.bz2” 扩展结尾。
正如我上面所说的, bzip2 的用法和 gzip 几乎完全相同。只需在上面的例子中将 gzip 换成 bzip2将 gunzip 换成 bunzip2将 zcat 换成 bzcat 即可。
要使用 bzip2 压缩一个文件,并以压缩后的文件取而代之,只需运行:
```
$ bzip2 ostechnix.txt
```
如果你不想替换原始文件,那么可以使用 -c 选项,并把输出写入到新文件中。
```
$ bzip2 -c ostechnix.txt > output.txt.bz2
```
如果要解压缩文件,则运行:
```
$ bzip2 -d ostechnix.txt.bz2
```
或者,
```
$ bunzip2 ostechnix.txt.bz2
```
如果要在不解压缩的情况下查看一个压缩文件的内容,则运行:
```
$ bunzip2 -c ostechnix.txt.bz2
```
或者,
```
$ bzcat ostechnix.txt.bz2
```
如果你想了解关于 bzip2 的更多细节,请参阅它的 man 手册。
```
$ man bzip2
```
##### 总结
在这篇教程中,我们学习了 gzip 和 bzip2 程序是什么,并通过 GNU/Linux 下的一些例子学习了如何使用它们来压缩和解压缩文件。接下来,我们将要学习如何在 Linux 中将文件和目录归档。
干杯!
--------------------------------------------------------------------------------
via: https://www.ostechnix.com/how-to-compress-and-decompress-files-in-linux/
作者:[SK][a]
译者:[ucasFL](https://github.com/ucasFL)
校对:[校对者ID](https://github.com/校对者ID)
选题:[lujun9972](https://github.com/lujun9972)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://www.ostechnix.com/author/sk/

View File

@ -0,0 +1,165 @@
Linux DNS 查询剖析(第四部分)
============================================
在 [Linux DNS 查询剖析(第一部分)][1][Linux DNS 查询剖析(第二部分)][2] 和 [Linux DNS 查询剖析(第三部分)][3] 中,我们已经介绍了以下内容:
* `nsswitch`
* `/etc/hosts`
* `/etc/resolv.conf`
* `ping` 与 `host` 查询方式的对比
* `systemd` 和对应的 `networking` 服务
* `ifup` 和 `ifdown`
* `dhclient`
* `resolvconf`
* `NetworkManager`
* `dnsmasq`
在第四部分中,我将介绍容器如何完成 DNS 查询。你想的没错,也不是那么简单。
* * *
### 1) Docker 和 DNS
============================================================
在 [Linux DNS 查询剖析(第三部分)][3] 中,我们介绍了 `dnsmasq`,其工作方式如下:将 DNS 查询指向到 localhost 地址 `127.0.0.1`,同时启动一个进程监听 `53` 端口并处理查询请求。
在按上述方式配置 DNS 的主机上,如果运行了一个 Docker 容器,容器内的 `/etc/resolv.conf` 文件会是怎样的呢?
我们来动手试验一下吧。
按照默认 Docker 创建流程,可以看到如下的默认输出:
```
$ docker run  ubuntu cat /etc/resolv.conf
# Dynamic resolv.conf(5) file for glibc resolver(3) generated by resolvconf(8)
#     DO NOT EDIT THIS FILE BY HAND -- YOUR CHANGES WILL BE OVERWRITTEN
# 127.0.0.53 is the systemd-resolved stub resolver.
# run "systemd-resolve --status" to see details about the actual nameservers.
search home
nameserver 8.8.8.8
nameserver 8.8.4.4
```
奇怪!
#### 地址 `8.8.8.8` 和 `8.8.4.4` 从何而来呢?
当我思考容器内的 `/etc/resolv.conf` 配置时,我的第一反应是继承主机的 `/etc/resolv.conf`。但只要稍微进一步分析,就会发现这样并不总是有效的。
如果在主机上配置了 `dnsmasq`,那么 `/etc/resolv.conf` 文件总会指向 `127.0.0.1` 这个<ruby>回环地址<rt>loopback address</rt></ruby>。如果这个地址被容器继承,容器会在其本身的<ruby>网络上下文<rt>networking context</rt></ruby>中使用;由于容器内并没有运行(在 `127.0.0.1` 地址的DNS 服务器,因此 DNS 查询都会失败。
“有了!”你可能有了新主意:将 _主机的_ 的 IP 地址用作 DNS 服务器地址,其中这个 IP 地址可以从容器的<ruby>默认路由<rt>default route</rt></ruby>中获取:
```
root@79a95170e679:/# ip route
default via 172.17.0.1 dev eth0
172.17.0.0/16 dev eth0 proto kernel scope link src 172.17.0.2
```
#### 使用主机 IP 地址真的可行吗?
从默认路由中,我们可以找到主机的 IP 地址 `172.17.0.1`,进而可以通过手动指定 DNS 服务器的方式进行测试(你也可以更新 `/etc/resolv.conf` 文件并使用 `ping` 进行测试;但我觉得这里很适合介绍新的 `dig` 工具及其 `@` 参数,后者用于指定需要查询的 DNS 服务器地址):
```
root@79a95170e679:/# dig @172.17.0.1 google.com | grep -A1 ANSWER.SECTION
;; ANSWER SECTION:
google.com.             112     IN      A       172.217.23.14
```
但是还有一个问题,这种方式仅适用于主机配置了 `dnsmasq` 的情况;如果主机没有配置 `dnsmasq`,主机上并不存在用于查询的 DNS 服务器。
在这个问题上Docker 的解决方案是忽略所有可能的复杂情况,即无论主机中使用什么 DNS 服务器,容器内都使用 Google 的 DNS 服务器 `8.8.8.8` 和 `8.8.4.4` 完成 DNS 查询。
_我的经历在 2013 年,我遇到了使用 Docker 以来的第一个问题,与 Docker 的这种 DNS 解决方案密切相关。我们公司的网络屏蔽了 `8.8.8.8` 和 `8.8.4.4`导致容器无法解析域名。_
这就是 Docker 容器的情况,但对于包括 Kubernetes 在内的容器 _<ruby>编排引擎<rt>orchestrators</rt></ruby>_,情况又有些不同。
### 2) Kubernetes 和 DNS
在 Kubernetes 中,最小部署单元是 `pod``pod` 是一组相互协作的容器,共享 IP 地址(和其它资源)。
Kubernetes 面临的一个额外的挑战是,将 Kubernetes 服务请求(例如,`myservice.kubernetes.io`)通过对应的<ruby>解析器<rt>resolver</rt></ruby>,转发到具体服务地址对应的<ruby>内网地址<rt>private network</rt></ruby>。这里提到的服务地址被称为归属于“<ruby>集群域<rt>cluster domain</rt></ruby>”。集群域可由管理员配置,根据配置可以是 `cluster.local``myorg.badger` 等。
在 Kubernetes 中,你可以为 `pod` 指定如下四种 `pod` 内 DNS 查询的方式。
* Default
在这种(名称容易让人误解)的方式中,`pod` 与其所在的主机采用相同的 DNS 查询路径,与前面介绍的主机 DNS 查询一致。我们说这种方式的名称容易让人误解,因为该方式并不是默认选项!`ClusterFirst` 才是默认选项。
如果你希望覆盖 `/etc/resolv.conf` 中的条目,你可以添加到 `kubelet` 的配置中。
* ClusterFirst
`ClusterFirst` 方式中,遇到 DNS 查询请求会做有选择的转发。根据配置的不同,有以下两种方式:
第一种方式配置相对古老但更简明,即采用一个规则:如果请求的域名不是集群域的子域,那么将其转发到 `pod` 所在的主机。
第二种方式相对新一些,你可以在内部 DNS 中配置选择性转发。
下面给出示例配置并从 [Kubernetes 文档][4]中选取一张图说明流程:
```
apiVersion: v1
kind: ConfigMap
metadata:
name: kube-dns
namespace: kube-system
data:
stubDomains: |
{"acme.local": ["1.2.3.4"]}
upstreamNameservers: |
["8.8.8.8", "8.8.4.4"]
```
`stubDomains` 条目中,可以为特定域名指定特定的 DNS 服务器;而 `upstreamNameservers` 条目则给出,待查询域名不是集群域子域情况下用到的 DNS 服务器。
这是通过在一个 `pod` 中运行我们熟知的 `dnsmasq` 实现的。
![kubedns](https://zwischenzugs.files.wordpress.com/2018/08/kubedns.png?w=525)
剩下两种选项都比较小众:
* ClusterFirstWithHostNet
适用于 `pod` 使用主机网络的情况,例如绕开 Docker 网络配置,直接使用与 `pod` 对应主机相同的网络。
* None
`None` 意味着不改变 DNS但强制要求你在 `pod` <ruby>规范文件<rt>specification</rt></ruby>`dnsConfig` 条目中指定 DNS 配置。
### CoreDNS 即将到来
除了上面提到的那些,一旦 `CoreDNS` 取代Kubernetes 中的 `kube-dns`,情况还会发生变化。`CoreDNS` 相比 `kube-dns` 具有可配置性更高、效率更高等优势。
如果想了解更多,参考[这里][5]。
如果你对 OpenShift 的网络感兴趣,我曾写过一篇[文章][6]可供你参考。但文章中 OpenShift 的版本是 `3.6`,可能有些过时。
### 第四部分总结
第四部分到此结束,其中我们介绍了:
* Docker DNS 查询
* Kubernetes DNS 查询
* 选择性转发(子域不转发)
* kube-dns
--------------------------------------------------------------------------------
via: https://zwischenzugs.com/2018/08/06/anatomy-of-a-linux-dns-lookup-part-iv/
作者:[zwischenzugs][a]
译者:[pinewall](https://github.com/pinewall)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://zwischenzugs.com/
[1]:https://zwischenzugs.com/2018/06/08/anatomy-of-a-linux-dns-lookup-part-i/
[2]:https://zwischenzugs.com/2018/06/18/anatomy-of-a-linux-dns-lookup-part-ii/
[3]:https://zwischenzugs.com/2018/07/06/anatomy-of-a-linux-dns-lookup-part-iii/
[4]:https://kubernetes.io/docs/tasks/administer-cluster/dns-custom-nameservers/#impacts-on-pods
[5]:https://coredns.io/
[6]:https://zwischenzugs.com/2017/10/21/openshift-3-6-dns-in-pictures/

View File

@ -0,0 +1,322 @@
Makefile及其工作原理
======
![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/osdc_liberate%20docs_1109ay.png?itok=xQOLreya)
当你在一些源文件改变后需要运行或更新一个任务时make工具通常会被用到。make工具需要读取Makefile(或makefile)文件在该文件中定义了一系列需要执行的任务。make可以用来将源代码编译为可执行程序。大部分开源项目会使用make来实现二进制文件的编译然后使用make istall命令来执行安装。
本文将通过一些基础和进阶的示例来展示make和Makefile的使用方法。在开始前请确保你的系统中安装了make。
### 基础示例
依然从打印“Hello World”开始。首先创建一个名字为myproject的目录目录下新建Makefile文件文件内容为
```
say_hello:
        echo "Hello World"
```
在myproject目录下执行make会有如下输出
```
$ make
echo "Hello World"
Hello World
```
在上面的例子中“say_hello”类似于其他编程语言中的函数名。在此可以成为target。在target之后的是预置条件和依赖。为了简单期间我们在示例中没有定义预置条件。“echo Hello World'"命令被称为recipe。recipe基于预置条件来实现target。target、预置条件和recipe共同构成一个规则。
总结一下,一个典型的规则的语法为:
```
target: 预置条件
<TAB> recipe
```
在示例中target是一个基于源代码这个预置条件的二进制文件。另外在另一规则中这个预置条件也可以是依赖其他预置条件的target。
```
final_target: sub_target final_target.c
        Recipe_to_create_final_target
sub_target: sub_target.c
        Recipe_to_create_sub_target
```
target不要求是一个文件也可以只是方便recipe使用的名字。我们称之为伪target。
再回到上面的示例中当make被执行时整条指令echo "Hello World"都被打印出来之后才是真正的执行结果。如果不希望指令本身被打印处理需要在echo前添加@。
```
say_hello:
        @echo "Hello World"
```
重新运行make将会只有如下输出
```
$ make
Hello World
```
接下来在Makefile中添加如下伪targetgenerate和clean
```
say_hello:
        @echo "Hello World"
generate:
        @echo "Creating empty text files..."
        touch file-{1..10}.txt
clean:
        @echo "Cleaning up..."
        rm *.txt
```
随后当我们运行make时只有say_hello这个target被执行。这是因为makefile中的默认target为第一个target。通常情况下只有默认的target会被调用大多数项目会将“all”作为默认target。“all”负责来调用其他的target。我们可以通过.DEFAULT_GOAL这个特殊的伪target来覆盖掉默认的行为。
在makefile文件开头增加.DEFAULT_GOAL
```
.DEFAULT_GOAL := generate
```
make会将generate作为默认target
```
$ make
Creating empty text files...
touch file-{1..10}.txt
```
顾名思义,.DEFAULT_GOAL伪target仅能定义一个target。这就是为什么很多项目仍然会有all这个target。这样可以保证多个target的实现。
下面删除掉.DEFAULT_GOAL增加all target
```
all: say_hello generate
say_hello:
        @echo "Hello World"
generate:
        @echo "Creating empty text files..."
        touch file-{1..10}.txt
clean:
        @echo "Cleaning up..."
        rm *.txt
```
运行之前我们再增加一些特殊的伪target。.PHONY用来定义这些不是file的target。make会默认调用这写伪target下的recipe而不去检查文件是否存在或最后修改日期。完整的makefile如下
```
.PHONY: all say_hello generate clean
all: say_hello generate
say_hello:
        @echo "Hello World"
generate:
        @echo "Creating empty text files..."
        touch file-{1..10}.txt
clean:
        @echo "Cleaning up..."
        rm *.txt
```
make命令会调用say_hello和generate
```
$ make
Hello World
Creating empty text files...
touch file-{1..10}.txt
```
clean不应该被放入all中或者被放入第一个target。clean应当在需要清理时手动调用调用方法为make clean。
```
$ make clean
Cleaning up...
rm *.txt
```
现在你应该已经对makefile有了基础的了解接下来我们看一些进阶的示例。
### 进阶示例
#### 变量
在之前的实例中大部分target和预置条件是已经固定了的但在实际项目中它们通常用变量和模式来代替。
定义变量最简单的方式是使用‘=操作符。例如将命令gcc赋值给变量CC
```
CC = gcc
```
这被称为递归扩展变量,用于如下所示的规则中:
```
hello: hello.c
    ${CC} hello.c -o hello
```
你可能已经想到了recipe将会在传递给终端时展开为
```
gcc hello.c -o hello
```
${CC}和$(CC)都能对gcc进行引用。但如果一个变量尝试将它本身赋值给自己将会造成死循环。让我们验证一下
```
CC = gcc
CC = ${CC}
all:
    @echo ${CC}
```
此时运行make会导致
```
$ make
Makefile:8: *** Recursive variable 'CC' references itself (eventually).  Stop.
```
为了避免这种情况发生,可以使用“:=”操作符(这被称为简单扩展变量)。以下代码不会造成上述问题:
```
CC := gcc
CC := ${CC}
all:
    @echo ${CC}
```
#### 模式和函数
下面的makefile使用了变量、模式和函数来实现所有C代码的编译。我们来逐行分析下
```
# Usage:
# make        # compile all binary
# make clean  # remove ALL binaries and objects
.PHONY = all clean
CC = gcc                        # compiler to use
LINKERFLAG = -lm
SRCS := $(wildcard *.c)
BINS := $(SRCS:%.c=%)
all: ${BINS}
%: %.o
        @echo "Checking.."
        ${CC} ${LINKERFLAG} $< -o $@
%.o: %.c
        @echo "Creating object.."
        ${CC} -c $<
clean:
        @echo "Cleaning up..."
        rm -rvf *.o ${BINS}
```
* 以“#”开头的行是评论。
* `.PHONY = all clean` 定义了“all”和“clean”两个伪代码。
* 变量`LINKERFLAG` recipe中gcc命令需要用到的参数。
* `SRCS := $(wildcard *.c)`: `$(wildcard pattern)` 是与文件名相关的一个函数。在本示例中,所有“.c"后缀的文件会被存入“SRCS”变量。
* `BINS := $(SRCS:%.c=%)`: 这被称为替代引用。本例中如果“SRCS”的值为“'foo.c bar.c'”则“BINS”的值为“'foo bar'”。
* Line `all: ${BINS}`: 伪target “all”调用“${BINS}”变量中的所有值作为子target。
* 规则:
```
%: %.o
  @echo "Checking.."
  ${CC} ${LINKERFLAG} $&lt; -o $@
```
下面通过一个示例来理解这条规则。假定“foo”是变量“${BINS}”中的一个值。“%”会匹配到“foo”“%”匹配任意一个target。下面是规则展开后的内容
```
foo: foo.o
  @echo "Checking.."
  gcc -lm foo.o -o foo
```
如上所示,“%”被“foo”替换掉了。“$<”被“foo.o”替换掉。“$<”用于匹配预置条件,`$@`匹配target。对“${BINS}”中的每个值,这条规则都会被调用一遍。
* 规则:
```
%.o: %.c
  @echo "Creating object.."
  ${CC} -c $&lt;
```
之前规则中的每个预置条件在这条规则中都会都被作为一个target。下面是展开后的内容
```
foo.o: foo.c
  @echo "Creating object.."
  gcc -c foo.c
```
* 最后在target “clean”中所有的而简直文件和编译文件将被删除。
下面是重写后的makefile该文件应该被放置在一个有foo.c文件的目录下
```
# Usage:
# make        # compile all binary
# make clean  # remove ALL binaries and objects
.PHONY = all clean
CC = gcc                        # compiler to use
LINKERFLAG = -lm
SRCS := foo.c
BINS := foo
all: foo
foo: foo.o
        @echo "Checking.."
        gcc -lm foo.o -o foo
foo.o: foo.c
        @echo "Creating object.."
        gcc -c foo.c
clean:
        @echo "Cleaning up..."
        rm -rvf foo.o foo
```
关于makefiles的更多信息[GNU Make manual][1]提供了更完整的说明和实例。
--------------------------------------------------------------------------------
via: https://opensource.com/article/18/8/what-how-makefile
作者:[Sachin Patil][a]
选题:[lujun9972](https://github.com/lujun9972)
译者:[Zafiry](https://github.com/zafiry)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://opensource.com/users/psachin
[1]:https://www.gnu.org/software/make/manual/make.pdf

View File

@ -0,0 +1,124 @@
差异文件diffs和补丁文件patches简介
======
![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/find-file-linux-code_magnifying_glass_zero.png?itok=E2HoPDg0)
如果你曾有机会在一个使用分布式开发模型的大型代码库上工作过,你就应该听说过类似下面的话,"Sue刚发过来一个补丁","Rajiv 正在签出差异文件", 可能这些词(补丁,差异文件)对你而言很陌生,而你确定很想搞懂他们到底指什么。开源软件对上述提到的名词有很大的贡献,作为从开发 Apache web 服务器到开发Linux 内核的开发模型,"基于补丁文件的开发" 这一模式贯穿了上述项目的始终。实际上,你可能不知道 Apache 的名字就来自一系列的代码补丁,他们被一一收集起来并针对原来的[NCSA HTTPd server source code][1]进行了校对
你可能认为前面说的只不过是些逸闻,但是一份早期的[capture of the Apache website][2]声称Apache 的名字就是来自于最早的“补丁文件”集合;(译注Apache 英文音和补丁相似),是“打了补丁的”服务器的英文名字简化。
好了,言归正传,程序员嘴里说的"差异"和"补丁" 到底是什么?
首先,在这篇文章里,我们可以认为这两个术语都指向同一个概念。“差异” 就是”补丁“。Unix 下的同名工具程序diff("差异")和patch("补丁")剖析了一个或多个文件之间的”差异”。下面我们看看diff 的例子:
一个"补丁"指的是文件之间一系列差异,这些差异能被 Unix 的 diff程序应用在源代码树上使之转变为程序员想要的文件状态。我们能使用diff 工具来创建“差异”( 或“补丁”),然后将他们“打” 在一个没有这个补丁的源代码版本上,此外,(我又要开始跑题了...,“补丁” 这个词真的指在计算机的早期使用打卡机的时候,用来覆盖在纸带上的用于修复代码错误的覆盖纸,那个时代纸带(上面有孔)就是在计算机处理器上运行的程序。下面的这张图,来自[Wikipedia Page][3] 真切的描绘了最初的“ 打补丁”这个词的出处:
![](https://opensource.com/sites/default/files/uploads/360px-harvard_mark_i_program_tape.agr_.jpg)
现在你对补丁和差异就了一个基本的概念,让我们来看看软件开发者是怎么使用这些工具的。如果你还没有使用过类似于[Git][4]这样的源代码版本控制工具的话,我将会一步步展示最流行的软件项目是怎么使用它们的。如果你将一个软件的生命周期看成是一条时间线的话,你就能看见这个软件的点滴变化,比如在何时源代码树加上了一个功能,在何时源代码树修复了一个功能缺陷。我们称这些改变的点为“进行了一次提交”,”提交“这个词被当今最流行的源代码版本管理工具Git使用, 当你想检查在一个提交前后的代码变化的话,(或者在许多个提交之间的代码变化),你都可以使用工具来观察文件差异。
如果你在使用 Git 开发软件的话,你开发环境本地有可能就有你想交给别的开发者的提交,为了给别的开发者你的提交,一个方法就是创建一个你本地文件的差异文件,然后将这个“补丁”发送给和你工作在同一个源代码树的别的开发者。别的开发者在“打”了你的补丁之后,就能看到在你的代码变树上的变化。
### Linux, Git, 和 GitHub
这种共享补丁的开发模型正是现今 Linux 内核社区如何处理内核修改提议而采用的模型。如果你有机会浏览任何一个主流的 Linux 内核邮件列表-主要是[LKML][6],包括[linux-containers][7][fs-devel][8][Netdev][9]等等你能看到很多开发者会贴出他们想让其他内核开发者审核测试或者合入Linux官方Git代码树某个提交的补丁。当然讨论 Git 不在这篇文章范围之内Git 是由 Linus Torvalds 开发的源代码控制系统,它支持分布式开发模型以及允许独立于主要代码仓库的补丁包,这些补丁包能被推送或拉取到不同的源代码树上并遵守这些代码树各自的开发流程。)
在继续我们的话题之前,我们当然不能忽略和补丁和差异这个概念最相关的的服务:[GitHub][10]。从它的名字就能猜想出 GitHub 是基于 Git 的,而且它还围绕着 Git对分布式开源代码开发模型提供了基于Web 和 API 的工作流管理。译注即Pull Request -- 拉取请求)。在 GitHub 上,分享补丁的方式不是像 Linux 内核社区那样通过邮件列表,而是通过创建一个 **拉取请求** 。当你提交你自己源代码的改动时你能通过创建一个针对软件项目的主仓库的“拉取请求”来分享你的代码改动译注即核心开发者维护一个主仓库开发者去“fork”这个仓库待各自的提交后再创建针对这个主仓库的拉取请求所有的拉取请求由主仓库的核心开发者批准后才能合入主代码库。GitHub 被当今很多活跃的开源社区所采用,如[Kubernetes][11],[Docker][12],[the Container Network Interface (CNI)][13],[Istio][14]等等。在 GitHub 的世界里,用户会倾向于使用基于 Web 页面的方式来审核一个拉取请求里的补丁或差异,你也可以直接访问原始的补丁并在命令行上直接使用它们。
### 该说点干货了
我们前面已经讲了在流行的开源社区了是怎么应用补丁和 diff的现在看看一些例子。
第一个例子包括一个源代码树的两个不同拷贝,其中一个有代码改动,我们想用 diff来看看这些改动是什么。这个例子里我们想看的是“合并格式”的补丁这是现在软件开发世界里最通用的格式。如果想知道更详细参数的用法以及如何生成diff请参考diff手册。原始的代码在sources-orig目录 而改动后的代码在sources-fixed目录. 如果要在你的命令行上用“合并格式”来展示补丁,请运行如下命令。(译注: 参数 N 代表如果比较的文件不存在,则认为是个空文件, a代表将所有文件都作为文本文件对待u 代表使用合并格式并输出上下文r 代表递归比较目录)
```
$ diff -Naur sources-orig/ sources-fixed/
```
...下面是 diff命令的输出:
```
diff -Naur sources-orig/officespace/interest.go sources-fixed/officespace/interest.go
--- sources-orig/officespace/interest.go        2018-08-10 16:39:11.000000000 -0400
+++ sources-fixed/officespace/interest.go       2018-08-10 16:39:40.000000000 -0400
@@ -11,15 +11,13 @@
   InterestRate float64
 }
+// compute the rounded interest for a transaction
 func computeInterest(acct *Account, t Transaction) float64 {
   interest := t.Amount * t.InterestRate
   roundedInterest := math.Floor(interest*100) / 100.0
   remainingInterest := interest - roundedInterest
-  // a little extra..
-  remainingInterest *= 1000
-
   // Save the remaining interest into an account we control:
   acct.Balance = acct.Balance + remainingInterest
```
最开始几行 diff的输出可以这样解释三个---’显示了原来文件的名字;任何在原文件(译注:不是源文件)里存在而在新文件里不存在的行将会用前缀‘-’,用来表示这些行被从源代码里‘减去’了。而‘+++’表示的则相反:在新文件里被加上的行会被放上前缀‘+’,表示这是在新文件里被'加上'的行。每一个补丁”块“(用@@作为前缀的的部分)都有上下文的行号,这能帮助补丁工具(或其他处理器)知道在代码的哪里应用这个补丁块。你能看到我们已经修改了”办公室“这部电影里提到的那个函数(移除了三行并加上了一行代码注释),电影里那个有点贪心的工程师可是偷偷的在计算利息的函数里加了点”料“哦。( LCTT译注剧情详情请见电影 https://movie.douban.com/subject/1296424/
如果你想找人来测试你的代码改动,你可以将差异保存到一个补丁里:
```
$ diff -Naur sources-orig/ sources-fixed/ >myfixes.patch
```
现在你有补丁 myfixes.patch了你能把它分享给别的开发者他们可以将这个补丁打在他们自己的源代码树上从而得到和你一样的代码并测试他们。如果一个开发者的当前工作目录就是他的源代码树的根的话他可以用下面的命令来打补丁
```
$ patch -p1 < ../myfixes.patch
patching file officespace/interest.go
```
现在这个开发者的源代码树已经打好补丁并准备好构建和测试文件的修改了。那么如果这个开发者在打补丁之前已经改动过了怎么办只要这些改动没有直接冲突译注比如改在同一行上补丁工具就能自动的合并代码的改动。例如下面的interest.go 文件他有其他几处改动然后它想打上myfixes.patch 这个补丁:
```
$ patch -p1 < ../myfixes.patch
patching file officespace/interest.go
Hunk #1 succeeded at 26 (offset 15 lines).
```
在这个例子中补丁警告说代码改动并不在文件原来的地方而是偏移了15行。如果你文件改动的很厉害补丁可能干脆说找不到要应用的地方还好补丁程序提供了提供了打开”模糊“匹配的选项这个选项在文档里有预置的警告信息对其讲解已经超出了本文的范围
如果你使用 Git 或者 GitHub 的话你可能不会直接使用diff或patch。Git 已经内置了这些功能你能使用这些功能和共享一个源代码树的其他开发者交互拉取或合并代码。Git一个比较相近的功能是可以使用 git diff 来对你的本地代码树生成全局差异,又或者对你的任意两次”引用“(可能是一个代表提交的数字,或一个标记或分支的名字,等等)做全局补丁。你甚至能简单的用管道将 git diff的输出到一个文件里这个文件必须严格符合将要被使用它的程序的输入要求然后将这个文件交给一个并不使用 Git 的开发者应用到他的代码上。当然GitHub 把这些功能放到了 Web 上,你能直接在 Web 页面上查看一个拉取请求的文件变动。在Web 上你能看到所展示的合并差异GitHub 还允许你将这些代码改动下载为原始的补丁文件。
### 总结
好了,你已经学到了”差异“和”补丁“是什么,以及在 Unix/Linux 上怎么使用命令行工具和他们交互。除非你还在像 Linux 内核开发这样的项目中工作而使用完全基于补丁的开发方式你应该会主要通过你的源代码控制系统如Git来使用补丁。但熟悉像 GitHub 这样的高级别工具的技术背景和技术底层对你的工作也是大有裨益的。谁知道会不会有一天你需要和一个来自 Linux 世界邮件列表的补丁包打交道呢?
--------------------------------------------------------------------------------
via: https://opensource.com/article/18/8/diffs-patches
作者:[Phil Estes][a]
选题:[lujun9972](https://github.com/lujun9972)
译者:[David Chen](https://github.com/DavidChenLiang)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://opensource.com/users/estesp
[1]:https://github.com/TooDumbForAName/ncsa-httpd
[2]:https://web.archive.org/web/19970615081902/http:/www.apache.org/info.html
[3]:https://en.wikipedia.org/wiki/Patch_(computing)
[4]:https://git-scm.com/
[5]:https://subversion.apache.org/
[6]:https://lkml.org/
[7]:https://lists.linuxfoundation.org/pipermail/containers/
[8]:https://patchwork.kernel.org/project/linux-fsdevel/list/
[9]:https://www.spinics.net/lists/netdev/
[10]:https://github.com/
[11]:https://kubernetes.io/
[12]:https://www.docker.com/
[13]:https://github.com/containernetworking/cni
[14]:https://istio.io/

View File

@ -0,0 +1,99 @@
如何在 Ubuntu 18.04 上更新固件
======
通常Ubuntu 和其他 Linux 中的默认软件中心会处理系统固件的更新。但是如果你遇到了错误,你可以使用 fwupd 命令行工具更新系统的固件。
我使用 [Dell XPS 13 Ubuntu 版本][1]作为我的主要操作系统。我全新[安装了 Ubuntu 18.04][2],我对硬件兼容性感到满意。蓝牙、外置 USB 耳机和扬声器、多显示器,一切都开箱即用。
困扰我的一件事是软件中心出现的一个[固件][3]更新。
![Updating firmware in Ubuntu][4]
单击“更新”按钮会在几秒钟后出现错误。
![Updating firmware in Ubuntu][5]
错误消息是:
**Unable to update “Thunderbolt NVM for Xps Notebook 9360”: could not detect device after update: timed out while waiting for device**
在这篇文章中,我将向你展示如何在 [Ubuntu][6] 中更新系统固件。
### 在 Ubuntu 18.04 中更新固件
![How to update firmware in Ubuntu][7]
有一件事你应该知道 GNOME Softwar 即 Ubuntu 18.04 中的软件中心也能够更新固件。但是在由于某种原因失败的情况下,你可以使用命令行工具 fwupd。
[fwupd][8] 是一个开源守护进程,可以处理基于 Linux 的系统中的固件升级。它由 GNOME 开发人员 [Richard Hughes][9] 创建。戴尔的开发人员也为这一开源工具的开发做出了贡献。
基本上,它使用 LVFSLinux 供应商固件服务 Linux Vendor Firmware Service。硬件供应商将可再发行固件上传到 LVFS 站点,并且多亏 fwupd你可以从操作系统内部升级这些固件。fwupd 受到 Ubuntu 和 Fedora 等主要 Linux 发行版的支持。
首先打开终端并更新系统:
```
sudo apt update && sudo apt upgrade -y
```
之后,你可以逐个使用以下命令来启动守护程序,刷新可用固件更新列表并安装固件更新。
```
sudo service fwupd start
```
守护进程运行后,检查是否有可用的固件更新。
```
sudo fwupdmgr refresh
```
输出应如下所示:
```
Fetching metadata <https://cdn.fwupd.org/downloads/firmware.xml.gz>
Downloading… [****************************]
Fetching signature <https://cdn.fwupd.org/downloads/firmware.xml.gz.asc>
```
在此之后,运行固件更新:
```
sudo fwupdmgr update
```
固件更新的输出可能与此类似:
```
No upgrades for XPS 13 9360 TPM 2.0, current is 1.3.1.0: 1.3.1.0=same
No upgrades for XPS 13 9360 System Firmware, current is 0.2.8.1: 0.2.8.1=same, 0.2.7.1=older, 0.2.6.2=older, 0.2.5.1=older, 0.2.4.2=older, 0.2.3.1=older, 0.2.2.1=older, 0.2.1.0=older, 0.1.3.7=older, 0.1.3.5=older, 0.1.3.2=older, 0.1.2.3=older
Downloading 21.00 for XPS13 9360 Thunderbolt Controller…
Updating 21.00 on XPS13 9360 Thunderbolt Controller…
Decompressing… [***********]
Authenticating… [***********]
Restarting device… [***********]
```
这应该处理了在 Ubuntu 18.04 中的固件更新。我希望这篇文章可以帮助你在 Linux 中进行固件更新。
如果你有任何问题或建议,请在下面的评论栏留言。
--------------------------------------------------------------------------------
via: https://itsfoss.com/update-firmware-ubuntu/
作者:[Abhishek Prakash][a]
选题:[lujun9972](https://github.com/lujun9972)
译者:[geekpi](https://github.com/geekpi)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://itsfoss.com/author/abhishek/
[1]: https://itsfoss.com/dell-xps-13-ubuntu-review/
[2]: https://itsfoss.com/install-ubuntu-dual-boot-mode-windows/
[3]: https://en.wikipedia.org/wiki/Firmware
[4]: https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2018/08/ubuntu-firmware-update-error-1.png
[5]: https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2018/08/ubuntu-firmware-update-error-2.jpg
[6]: https://www.ubuntu.com/
[7]: https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2018/08/update-firmware-ubuntu.png
[8]: https://fwupd.org/
[9]: https://github.com/hughsie/fwupd

View File

@ -0,0 +1,137 @@
heguangzhi Translating
6个开源工具制作自己的VPN
======
![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/vpn_scrabble_networking.jpg?itok=pdsUHw5N)
如果您想尝试建立您自己的 VPN但是不确定从哪里开始那么您来对地方了。我将挑选6个最好的免费和开源工具在您自己的服务器上搭建和使用 VPN。这些 VPN 软件不管您是想为您的企业建立站点到站点的还是仅创建远程代理访问以解除访问限制并隐藏来自ISP的互联网流量都可以得到解决。
根据您的需求和条件,并参考您自己的技术特长,环境以及您想要通过 VPN 实现的目标。需要考虑以下因素:
* VPN 协议
* 客户端的数量和设备类型
* 服务端的兼容性
* 技术专业的能力
### Algo
[Algo][1] 是从下往上的设计的,为需要互联网安全代理的企业创建 VPN 专用网。它“只包括您需要的最小化的软件”这意味着您为了简单而牺牲了可扩展性。Algo 是基于 StrongSwan 的,但是删除了所有您不需要的东西,这有另外一个好处,那就是删除了新手可能不会注意到的安全漏洞。
作为额外的奖励,它甚至屏蔽了广告!
Algo supports only the IKEv2 protocol and Wireguard. Because IKEv2 support is built into most devices these days, it doesnt require a client app like OpenVPN. Algo can be deployed using Ansible on Ubuntu (the preferred option), Windows, RedHat, CentOS, and FreeBSD. Setup is automated using Ansible, which configures the server based on your answers to a short set of questions. Its also very easy to tear down and re-deploy on demand.
Algo 只支持 IKEv2 协议和 Wireguard 。因为 IKEv2 支持现在已经内置在大多数设备中,所以它不需要像 OpenVPN 这样的客户端应用程序。Algo 可以使用 Ansible 在 Ubuntu (首选选项)、Windows、RedHat、CentOS 和 FreeBSD 上部署。自动化的安装 Ansible它根据您对一组简短问题的回答来配置服务。终止和重新部署也非常容易。
Algo 可能是在本篇文章中安装和部署的最简单和最快的VPN。它非常简洁考虑周全。如果您不需要其他工具提供的任何更高级的功能只需要一个安全的代理这是一个很好的选择。请注意Algo 明确表示,它不是为了解除地理封锁或逃避审查,主要是为了加密。
### Streisand
[Streisand][2] 可以使用一个命令安装在任何 Ubuntu 16.04 服务器上这个过程大约需要10分钟。它支持 L2TP、OpenConnect、OpenSSH、OpenVPN、Shadowsocks、Stunnel、Tor bridge 和 WireGuard。根据您选择的协议您可能需要安装客户端应用程序。
在很多方面Streisand 与 Algo 相似,但是它提供了更多的协议和定制。这需要更多的工作来管理和维护,但也更加灵活。注意 Streisand 不支持 IKEv2 。我认为 Streisand 在中国和土耳其这样的地方绕过审查制度更有效,因为它的多功能性,但是 Algo 更容易和更快地安装。
使用 Ansible 可以自动化安装,所以不需要太多的专业技术知识。通过向用户发送自定义生成的连接指令,包括服务器 SSL 证书的嵌入副本,可以轻松添加更多用户。
卸载 Streisand 是一个快速无痛的过程,您可以按需重新部署。
### OpenVPN
[OpenVPN][3] 要求客户端和服务器应用程序使用同名协议建立 VPN 连接。OpenVPN 可以根据您的需求进行调整和定制,但它也需要更多专业技术知识。支持远程访问和站点到站点配置;如果您计划使 VPN 作为互联网的代理,前者是您需要的。因为客户端应用程序需要在大多数设备上使用 OpenVPN ,最终用户必须保持更新。
在服务器端,您可以选择部署在云中或 Linux 服务器上。兼容的发行版包括 CentOS 、Ubuntu 、Debian 和 openSUSE。Windows 、MacOS 、iOS 和 Android 都有客户端应用程序,其他设备也有非官方应用程序。企业可以选择设置一个 OpenVPN 接入服务器,但是对于想要社区版的个人来说,这可能太过分了。
OpenVPN 相对容易配置静态密钥加密,但并不完全安全。相反,我建议使用 [easy-rsa][4] 来设置它这是一个密钥管理包可以用来设置公钥基础设施。这允许您一次连接多个设备并以完美的前向保密和其他好处来保护它们。OpenVPN 使用 SSL/TLS 进行加密,您可以在配置中指定 DNS 服务器。
OpenVPN 可以穿越防火墙和 NAT 防火墙,这意味着您可以使用它绕过网关和防火墙,否则它们可能会阻止连接。它同时支持 TCP 和 UDP 传输。
### StrongSwan
您可能会遇到一些不同的 VPN 工具名称中有“Swan”。FreeS/WAN, 、OpenSwan、LibreSwan和[strongSwan][5] 都是同一个项目的分叉后者是我个人最喜欢的。服务器端strongSwan 运行在 Linux 2.6、3.x和4x内核、Android、FreeBSD、macOS、iOS 和 Windows上。
StrongSwan 使用 IKEv2 协议和 IPSec 。与 OpenVPN 相比IKEv2 连接速度更快,同时提供了很好的速度和安全性。如果您更喜欢不需要在客户端安装额外应用程序的协议,这将非常有用,因为现在生产的大多数新设备都支持 IKEv2,,包括 Windows、MacOS、iOS和Android。
StrongSwan 并不特别容易使用,尽管文档不错,但它使用的词汇与大多数其他工具不同,这可能会让人比较困惑。它的模块化设计让它对企业来说很棒,但这也意味着它不是最精简。这当然不像 Algo 或Streisand 那么简单。
访问控制可以基于使用X.509 属性证书的组成员身份,这是 strongSwan 独有的功能。它支持用于集成到其他环境(如Windows Active Directory )中的EAP身份验证方法。strongSwan可以穿越NAT 网络防火墙。
### SoftEther
[SoftEther][6] 是由日本筑波大学的一名研究生发起的一个项目。SoftEther VPN 服务器和 VPN网桥在 Windows、Linux、OSX、FreeBSD 和 Solaris 上运行而客户端应用程序在Windows、Linux和 MacOS 上运行。VPN 网桥主要用于需要设置站点到站点VPN的企业因此单个用户只需要服务器和客户端程序来设置远程访问。
SoftEther 支持 OpenVPN、L2TP、SSTP 和 EtherIP 协议由于“基于HTTPS的以太网”伪装它自己的 SoftEther 协议声称能够免疫深度数据包检测。SoftEther 还做了一些调整以减少延迟并增加吞吐量。此外SoftEther 还包括一个克隆功能,允许您轻松地从 OpenVPN 过渡到SoftEther。
SoftEther 可以穿透 NAT 防火墙并绕过防火墙。在只允许 ICMP 和 DNS 数据包的受限网络上,您可以通过 ICMP 利用SoftEther的VPN 或者通过 DNS 利用 VPN 选项来穿透防火墙。SoftEther 可与IPv4 和IPv6 一起工作。
SoftEther 比 OpenVPN 和strongSwan更容易设置但比 Streisand 和 Algo 更复杂。
### WireGuard
[WireGuard][7] 是这个名单上最新的工具它太新了甚至还没有完成。也就是说它为部署VPN提供了一种快速简便的方法。它旨在通过使 IPSec 更简单、更精简来改进它就像SSH一样。
与OpenVPN一样WireGuard 既是一种协议也是一种软件工具用于部署使用所述协议的VPN。一个关键特性是“加密密钥路由”它将公钥与隧道内允许的 IP 地址列表相关联。
WireGuard可用于 Ubuntu、Debian、Fedora、CentOS、MacOS、Windows 和安卓系统。WireGuard可在 IPv4和 IPv6 上工作。
WireGuard比大多数其他VPN协议轻得多它只在需要发送数据时才发送数据包。
开发人员说WireGuard还不应该被信任因为它还没有被完全审计过但是欢迎你给它一个机会。这可能是下一件大事
### 自制 VPN vs. 商业 VPN
制作您自己的 VPN 为您的互联网连接增加了一层隐私和安全,但是如果您是唯一一个使用它的人,那么装备精良的第三方,比如政府机构,将很容易追踪到你的活动。
此外,如果您计划使用您的 VPN 来解锁地理锁定的内容自制的VPN可能不是最好的选择。因为您只能从一个IP地址连接所以你的 VPN 服务器很容易被阻止。
好的商业 VPN 不存在这些问题。有了像[ExpressVPN][8]这样的提供商您可以与数十甚至数百个其他用户共享服务器的IP地址这使得跟踪一个用户的活动几乎变得不可能。您也可以从成百上千的服务器中选择所以如果其中一台被列入黑名单你可以切换到另一台。
然而商业VPN的权衡是您必须相信提供商不会窥探您的互联网流量。一定要选择一个有明确的无日志政策的信誉良好的供应商。
--------------------------------------------------------------------------------
via: https://opensource.com/article/18/8/open-source-tools-vpn
作者:[Paul Bischoff][a]
选题:[lujun9972](https://github.com/lujun9972)
译者:[译者ID](https://github.com/译者ID)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:
[1]: https://blog.trailofbits.com/2016/12/12/meet-algo-the-vpn-that-works/
[2]: https://github.com/StreisandEffect/streisand
[3]: https://openvpn.net/
[4]: https://github.com/OpenVPN/easy-rsa
[5]: https://www.strongswan.org/
[6]: https://www.softether.org/
[7]: https://www.wireguard.com/
[8]: https://www.comparitech.com/vpn/reviews/expressvpn/

View File

@ -0,0 +1,66 @@
8 个用于<ruby>业余项目<rt>side projects</rt></ruby>的优秀 Python 库
======
![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/python-programming-code-keyboard.png?itok=fxiSpmnd)
在 Python/Django 的世界里有这样一个谚语:为语言而来,为社区而留。对绝大多数人来说的确是这样的,但是,还有一件事情使得我们一直停留在 Python 的世界里,不愿离开,那就是我们可以很容易地利用一顿午餐或晚上几个小时的时间,把一个想法快速地实现出来。
这个月,我们来探讨一些我们喜欢用来快速完成<ruby>业余项目<rt>side projects</rt></ruby>或打发午餐时间的 Python 库。
### 在数据库中即时保存数据Dataset
当我们想要在不知道最终数据库表长什么样的情况下,快速收集数据并保存到数据库中的时候,[Dataset][1] 库将是我们的最佳选择。Dataset 库有一个简单但功能强大的 API因此我们可以很容易的把数据保存下来之后再进行排序。
Dataset 建立在 SQLAlchemy 之上,所以如果需要对它进行扩展,你会感到非常熟悉。使用 Django 内建的 [inspectdb][2] 管理命令可以很容易地把底层数据库模型导入 Django 中,这使得和现有数据库一同工作不会出现任何障碍。
### 从网页抓取数据Beautiful Soup
[Beautiful Soup][3](一般写作 BS4库使得从 HTML 网页中提取信息变得非常简单。当我们需要把非结构化或弱结构化的 HTML 转换为结构化数据的时候,就需要使用 Beautiful Soup 。用它来处理 XML 数据也是一个很好的选择,否则 XML 的可读性或许会很差。
### 和 HTTP 内容打交道Requests
当需要和 HTTP 内容打交道的时候,[Requests][4] 毫无疑问是最好的标准库。当我们想要抓取 HTML 网页或连接 API 的时候,都离不开 Requests 库。同时,它也有很好的文档。
### 编写命令行工具Click
当需要写一个简单的 Python 脚本作为命令行工具的时候,[Click][5] 是我最喜欢用的库。它的 API 非常直观,并且在实现时经过了深思熟虑,我们只需要记住很少的几个模式。它的文档也很优秀,这使得学习其高级特性更加容易。
### 对事物命名Python Slugify
众所周知,命名是一件困难的事情。[Python Slugify][6] 是一个非常有用的库,它可以把一个标题或描述转成一个带有特性的唯一标识符。如果你正在做一个 Web 项目,并且你想要使用对<ruby>搜索引擎优化友好<rt>SEO-friendly</rt></ruby>的链接,那么,使用 Python Slugify 可以让这件事变得很容易。
### 和插件打交道Pluggy
[Pluggy][7] 库相对较新,但是如果你想添加一个插件系统到现有应用中,那么使用 Pluggy 是最好也是最简单的方式。如果你使用过 pytest那么实际上相当于已经使用过 Pluggy 了,虽然你还不知道它。
### 把 CSV 文件转换到 API 中DataSette
[DataSette][8] 是一个神奇的工具,它可以很容易地把 CSV 文件转换进全特性只读 REST JSON API同时不要把它和 Dataset 库混淆。Datasette 有许多特性,包括创建图表和 geo用于创建交互式图表并且很容易通过容器或第三方网络主机进行部署。
### 处理环境变量等Envparse
如果你不想在源代码中保存 API 密钥、数据库凭证或其他敏感信息,那么你便需要解析环境变量,这时候 [envparse][9] 是最好的选择。Envparse 能够处理环境变量、ENV 文件、变量类型,甚至还可以进行预处理和后处理(例如,你想要确保变量名总是大写或小写的)
有什么你最喜欢的用于<ruby>业余项目<rt>side projects</rt></ruby>的 Python 库不在这个列表中吗?请在评论中和我们分享。
--------------------------------------------------------------------------------
via: https://opensource.com/article/18/9/python-libraries-side-projects
作者:[Jeff Triplett][a]
选题:[lujun9972](https://github.com/lujun9972)
译者:[ucasFL](https://github.com/ucasFL)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://opensource.com/users/laceynwilliams
[1]: https://dataset.readthedocs.io/en/latest/
[2]: https://docs.djangoproject.com/en/2.1/ref/django-admin/#django-admin-inspectdb
[3]: https://www.crummy.com/software/BeautifulSoup/
[4]: http://docs.python-requests.org/
[5]: http://click.pocoo.org/5/
[6]: https://github.com/un33k/python-slugify
[7]: https://pluggy.readthedocs.io/en/latest/
[8]: https://github.com/simonw/datasette
[9]: https://github.com/rconradharris/envparse