mirror of
https://github.com/LCTT/TranslateProject.git
synced 2025-01-22 23:00:57 +08:00
update
This commit is contained in:
commit
d38087cde7
@ -1,64 +1,43 @@
|
||||
如何从 git 错误中恢复
|
||||
如何恢复丢弃的 git stash 数据
|
||||
============================================================
|
||||
|
||||
### 不要让 git 命令中的错误抹去数天的工作
|
||||
> 不要让 git 命令中的错误抹去数天的工作
|
||||
|
||||
![How to recover from a git mistake](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/bubblehands_fromRHT_520_0612LL.png?itok=_iQ2dO3S "How to recover from a git mistake")
|
||||
Image by : opensource.com
|
||||
|
||||
今天我的同事几乎失去了他在四天工作中所做的一切。由于不正确的 **git** 命令,他把保存在 [stash][20] 中的更改删除了。在这悲伤的情节之后,我们试图寻找一种恢复他所做工作的方法,而且我们做到了!
|
||||
今天我的同事几乎失去了他在四天工作中所做的一切。由于不正确的 `git` 命令,他把保存在 [stash][20] 中的更改删除了。在这悲伤的情节之后,我们试图寻找一种恢复他所做工作的方法,而且我们做到了!
|
||||
|
||||
首先警告一下:当你在实现一个大功能时,请将它分成小块并定期提交。在不做任何改动的情况下长时间工作并不是一个好主意。
|
||||
首先警告一下:当你在实现一个大功能时,请将它分成小块并定期提交。长时间工作而不做提交并不是一个好主意。
|
||||
|
||||
现在我们已经搞定了那个错误,下面就演示一下怎样从 stash 中恢复误删的更改。
|
||||
|
||||
我用作示例的仓库中,只有一个源文件 “main.c”,如下所示:
|
||||
|
||||
### [missing_data_from_stash_01.jpeg][9]
|
||||
|
||||
![Repository with one source file](https://opensource.com/sites/default/files/u128651/missing_data_from_stash_01.jpeg "Repository with one source file")
|
||||
|
||||
José Guilherme Vanz, [CC BY][1]
|
||||
|
||||
它只有一次提交,即 “Initial commit”:
|
||||
|
||||
### [missing_data_from_stash_02.jpeg][10]
|
||||
|
||||
![One commit](https://opensource.com/sites/default/files/u128651/missing_data_from_stash_02.jpeg "One commit")
|
||||
|
||||
José Guilherme Vanz, [CC BY][2]
|
||||
|
||||
该文件的第一个版本是:
|
||||
|
||||
### [missing_data_from_stash_03.jpeg][11]
|
||||
|
||||
![First version of the file](https://opensource.com/sites/default/files/u128651/missing_data_from_stash_03.jpeg "First version of the file")
|
||||
|
||||
José Guilherme Vanz, [CC BY][3]
|
||||
|
||||
我将在文件中写一些代码。对于这个例子,我并不需要做什么大的改动,只需要有什么东西放进 stash 中即可,所以我们仅仅增加一行。“git diff” 的输出如下:
|
||||
|
||||
### [missing_data_from_stash_04.jpeg][12]
|
||||
|
||||
![git-diff output ](https://opensource.com/sites/default/files/u128651/missing_data_from_stash_04.jpeg "git-diff output ")
|
||||
|
||||
José Guilherme Vanz, [CC BY][4]
|
||||
|
||||
现在,假设我想从远程仓库中拉取一些新的更改,当时还不打算提交我自己的更改。于是,我决定先 stash 它,等拉取远程仓库中的更改后,再把我的更改恢复应用到主分支上。我执行下面的命令将我的更改移动到 stash 中:
|
||||
|
||||
```
|
||||
git stash
|
||||
```
|
||||
|
||||
使用命令 **git stash list** 查看 stash,在这里能看到我的更改:
|
||||
|
||||
### [missing_data_from_stash_06.jpeg][13]
|
||||
使用命令 `git stash list` 查看 stash,在这里能看到我的更改:
|
||||
|
||||
![Output of changes in our stash](https://opensource.com/sites/default/files/u128651/missing_data_from_stash_06.jpeg "Output of changes in our stash")
|
||||
|
||||
José Guilherme Vanz, [CC BY][5]
|
||||
|
||||
我的代码已经在一个安全的地方而且主分支目前是干净的(使用命令 **git status** 检查)。现在我只需要拉取远程仓库的更改,然后把我的更改恢复应用到主分支上,而且我也应该是这么做的。
|
||||
我的代码已经在一个安全的地方,而且主分支目前是干净的(使用命令 `git status` 检查)。现在我只需要拉取远程仓库的更改,然后把我的更改恢复应用到主分支上,而且我也应该是这么做的。
|
||||
|
||||
但是我错误地执行了命令:
|
||||
|
||||
@ -66,47 +45,38 @@ José Guilherme Vanz, [CC BY][5]
|
||||
git stash drop
|
||||
```
|
||||
|
||||
它删除了 stash,而不是像下面的命令:
|
||||
它删除了 stash,而不是执行了下面的命令:
|
||||
|
||||
```
|
||||
git stash pop
|
||||
```
|
||||
|
||||
这条命令在删除 stash 之前会从栈中恢复应用它。如果我再次执行命令 **git stash list**,就能看到在没有从栈中将更改恢复到主分支的之前,我就删除了它。OMG!接下来怎么办?
|
||||
这条命令会在从栈中删除 stash 之前应用它。如果我再次执行命令 `git stash list`,就能看到在没有从栈中将更改恢复到主分支的之前,我就删除了它。OMG!接下来怎么办?
|
||||
|
||||
好消息是:**git** 并没有删除包含了我的更改的对象,它只是移除了对它的引用。为了证明这一点,我使用命令 **git fsck**,它会验证数据库中对象的连接和有效性。这是我对该仓库执行了 **git fsck** 之后的输出:
|
||||
|
||||
### [missing_data_from_stash_07.jpeg][14]
|
||||
好消息是:`git` 并没有删除包含了我的更改的对象,它只是移除了对它的引用。为了证明这一点,我使用命令 `git fsck`,它会验证数据库中对象的连接和有效性。这是我对该仓库执行了 `git fsck` 之后的输出:
|
||||
|
||||
![Output after executing the git-fsck command on the repository](https://opensource.com/sites/default/files/u128651/missing_data_from_stash_07.jpeg "Output after executing the git-fsck command on the repository")
|
||||
|
||||
José Guilherme Vanz, [CC BY][6]
|
||||
|
||||
由于使用了参数 **--unreachable**,我让 **git-fsck** 显示出所有不可访问的对象。正如你看到的,它显示并没有不可访问的对象。而当我从 stash 中删除了我的更改之后,再次执行相同的指令,得到了一个不一样的输出:
|
||||
|
||||
### [missing_data_from_stash_08.jpeg][15]
|
||||
由于使用了参数 `--unreachable`,我让 `git-fsck` 显示出所有不可访问的对象。正如你看到的,它显示并没有不可访问的对象。而当我从 stash 中删除了我的更改之后,再次执行相同的指令,得到了一个不一样的输出:
|
||||
|
||||
![Output after dropping changes on stash](https://opensource.com/sites/default/files/u128651/missing_data_from_stash_08.jpeg "Output after dropping changes on stash")
|
||||
|
||||
José Guilherme Vanz, [CC BY][7]
|
||||
|
||||
现在有三个不可访问对象。那么哪一个才是我的更改呢?实际上,我不知道。我需要通过执行命令 **git show** 来搜索每一个对象。
|
||||
|
||||
### [missing_data_from_stash_09.jpeg][16]
|
||||
现在有三个不可访问对象。那么哪一个才是我的更改呢?实际上,我不知道。我需要通过执行命令 `git show` 来搜索每一个对象。
|
||||
|
||||
![Output after executing the git-show command ](https://opensource.com/sites/default/files/u128651/missing_data_from_stash_09.jpeg "Output after executing the git-show command ")
|
||||
|
||||
José Guilherme Vanz, [CC BY][8]
|
||||
|
||||
就是它!ID 号 **95ccbd927ad4cd413ee2a28014c81454f4ede82c** 对应了我的更改。现在我已经找到了丢失的更改,我可以恢复它。其中一种方法是将此 ID 取出来放进一个新的分支,或者直接提交它。如果你得到了你的更改对象的 ID 号,就可以决定以最好的方式,将更改再次恢复应用到主分支上。对于这个例子,我使用 **git stash** 将更改恢复到我的主分支上。
|
||||
就是它!ID 号 `95ccbd927ad4cd413ee2a28014c81454f4ede82c` 对应了我的更改。现在我已经找到了丢失的更改,我可以恢复它。其中一种方法是将此 ID 取出来放进一个新的分支,或者直接提交它。如果你得到了你的更改对象的 ID 号,就可以决定以最好的方式,将更改再次恢复应用到主分支上。对于这个例子,我使用 `git stash` 将更改恢复到我的主分支上。
|
||||
|
||||
```
|
||||
git stash apply 95ccbd927ad4cd413ee2a28014c81454f4ede82c
|
||||
```
|
||||
|
||||
另外需要重点记住的是 **git** 会周期性地执行它的垃圾回收程序。**gc** 执行之后,使用 **git fsck** 就不能再看到不可访问对象了。
|
||||
另外需要重点记住的是 `git` 会周期性地执行它的垃圾回收程序(`gc`),它执行之后,使用 `git fsck` 就不能再看到不可访问对象了。
|
||||
|
||||
_This article was [originally published][18] on the author's blog and is reprinted with permission. _
|
||||
_本文[最初发表][18]于作者的博客,并得到了转载授权。_
|
||||
|
||||
|
||||
(题图:opensource.com,附图:José Guilherme Vanz, [CC BY][1])
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
@ -114,7 +84,7 @@ via: https://opensource.com/article/17/8/recover-dropped-data-stash
|
||||
|
||||
作者:[Jose Guilherme Vanz][a]
|
||||
译者:[firmianay](https://github.com/firmianay)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
211
published/20170824 Splitting and Re-Assembling Files in Linux.md
Normal file
211
published/20170824 Splitting and Re-Assembling Files in Linux.md
Normal file
@ -0,0 +1,211 @@
|
||||
在 Linux 中分割和重组文件
|
||||
============================================================
|
||||
|
||||
![csplit](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/split-files.png?itok=kZTP_VF9 "csplit")
|
||||
|
||||
非常有用的 `csplit` 命令可以将单个文件分割成多个文件。Carla Schroder 解释说。
|
||||
|
||||
Linux 有几个用于分割文件的工具程序。那么你为什么要分割文件呢?一个用例是将大文件分割成更小的尺寸,以便它适用于比较小的存储介质,比如 U 盘。当您遇到 FAT32(最大文件大小为 4GB),且您的文件大于此时,通过 U 盘传输文件也是一个很好的技巧。另一个用例是加速网络文件传输,因为小文件的并行传输通常更快。
|
||||
|
||||
我们将学习如何使用 `csplit`,`split` 和 `cat` 来重新整理文件,然后再将文件合并在一起。这些操作在任何文件类型下都有用:文本、图片、音频文件、ISO 镜像文件等。
|
||||
|
||||
### 使用 csplit 分割文件
|
||||
|
||||
`csplit` 是这些有趣的小命令中的一个,它永远伴你左右,一旦开始用它就离不开了。`csplit` 将单个文件分割成多个文件。这个示例演示了最简单的使用方法,它将文件 foo.txt 分为三个文件,以行号 17 和 33 作为分割点:
|
||||
|
||||
```
|
||||
$ csplit foo.txt 17 33
|
||||
2591
|
||||
3889
|
||||
2359
|
||||
```
|
||||
|
||||
`csplit` 在当前目录下创建了三个新文件,并以字节为单位打印出新文件的大小。默认情况下,每个新文件名为 `xx_nn`:
|
||||
|
||||
```
|
||||
$ ls
|
||||
xx00
|
||||
xx01
|
||||
xx02
|
||||
```
|
||||
|
||||
您可以使用 `head` 命令查看每个新文件的前十行:
|
||||
|
||||
```
|
||||
$ head xx*
|
||||
|
||||
==> xx00 <==
|
||||
Foo File
|
||||
by Carla Schroder
|
||||
|
||||
Foo text
|
||||
|
||||
Foo subheading
|
||||
|
||||
More foo text
|
||||
|
||||
==> xx01 <==
|
||||
Foo text
|
||||
|
||||
Foo subheading
|
||||
|
||||
More foo text
|
||||
|
||||
==> xx02 <==
|
||||
Foo text
|
||||
|
||||
Foo subheading
|
||||
|
||||
More foo text
|
||||
```
|
||||
|
||||
如果要将文件分割成包含相同行数的多个文件怎么办?可以指定行数,然后将重复次数放在在花括号中。此示例重复分割 4 次,并将剩下的转储到最后一个文件中:
|
||||
|
||||
```
|
||||
$ csplit foo.txt 5 {4}
|
||||
57
|
||||
1488
|
||||
249
|
||||
1866
|
||||
3798
|
||||
```
|
||||
|
||||
您可以使用星号通配符来告诉 `csplit` 尽可能多地重复分割。这听起来很酷,但是如果文件不能等分,则可能会失败(LCTT 译注:低版本的 `csplit` 不支持此参数):
|
||||
|
||||
```
|
||||
$ csplit foo.txt 10 {*}
|
||||
1545
|
||||
2115
|
||||
1848
|
||||
1901
|
||||
csplit: '10': line number out of range on repetition 4
|
||||
1430
|
||||
```
|
||||
|
||||
默认的行为是删除发生错误时的输出文件。你可以用 `-k` 选项来解决这个问题,当有错误时,它就不会删除输出文件。另一个行为是每次运行 `csplit` 时,它将覆盖之前创建的文件,所以你需要使用新的文件名来分别保存它们。使用 `--prefix= _prefix_` 来设置一个不同的文件前缀:
|
||||
|
||||
```
|
||||
$ csplit -k --prefix=mine foo.txt 5 {*}
|
||||
57
|
||||
1488
|
||||
249
|
||||
1866
|
||||
993
|
||||
csplit: '5': line number out of range on repetition 9
|
||||
437
|
||||
|
||||
$ ls
|
||||
mine00
|
||||
mine01
|
||||
mine02
|
||||
mine03
|
||||
mine04
|
||||
mine05
|
||||
```
|
||||
|
||||
选项 `-n` 可用于改变对文件进行编号的数字位数(默认是 2 位):
|
||||
|
||||
```
|
||||
$ csplit -n 3 --prefix=mine foo.txt 5 {4}
|
||||
57
|
||||
1488
|
||||
249
|
||||
1866
|
||||
1381
|
||||
3798
|
||||
|
||||
$ ls
|
||||
mine000
|
||||
mine001
|
||||
mine002
|
||||
mine003
|
||||
mine004
|
||||
mine005
|
||||
```
|
||||
|
||||
`csplit` 中的 “c” 是上下文(context)的意思。这意味着你可以根据任意匹配的方式或者巧妙的正则表达式来分割文件。下面的例子将文件分为两部分。第一个文件在包含第一次出现 “fie” 的前一行处结束,第二个文件则以包含 “fie” 的行开头。
|
||||
|
||||
```
|
||||
$ csplit foo.txt /fie/
|
||||
```
|
||||
|
||||
在每次出现 “fie” 时分割文件:
|
||||
|
||||
```
|
||||
$ csplit foo.txt /fie/ {*}
|
||||
```
|
||||
|
||||
在 “fie” 前五次出现的地方分割文件:
|
||||
|
||||
```
|
||||
$ csplit foo.txt /fie/ {5}
|
||||
```
|
||||
|
||||
仅当内容以包含 “fie” 的行开始时才复制,并且省略前面的所有内容:
|
||||
|
||||
```
|
||||
$ csplit myfile %fie%
|
||||
```
|
||||
|
||||
### 将文件分割成不同大小
|
||||
|
||||
`split` 与 `csplit` 类似。它将文件分割成特定的大小,当您将大文件分割成小的多媒体文件或者使用网络传送时,这就非常棒了。默认的大小为 1000 行:
|
||||
|
||||
```
|
||||
$ split foo.mv
|
||||
$ ls -hl
|
||||
266K Aug 21 16:58 xaa
|
||||
267K Aug 21 16:58 xab
|
||||
315K Aug 21 16:58 xac
|
||||
[...]
|
||||
```
|
||||
|
||||
它们分割出来的大小相似,但你可以指定任何你想要的大小。这个例子中是 20M 字节:
|
||||
|
||||
```
|
||||
$ split -b 20M foo.mv
|
||||
```
|
||||
|
||||
尺寸单位缩写为 K,M,G,T,P,E,Z,Y(1024 的幂)或者 KB,MB,GB 等等(1000 的幂)。
|
||||
|
||||
为文件名选择你自己的前缀和后缀:
|
||||
|
||||
```
|
||||
$ split -a 3 --numeric-suffixes=9 --additional-suffix=mine foo.mv SB
|
||||
240K Aug 21 17:44 SB009mine
|
||||
214K Aug 21 17:44 SB010mine
|
||||
220K Aug 21 17:44 SB011mine
|
||||
```
|
||||
|
||||
`-a` 选项控制编号的数字位置。`--numeric-suffixes` 设置编号的开始值。默认前缀为 `x`,你也可以通过在文件名后输入它来设置一个不同的前缀。
|
||||
|
||||
### 将分割后的文件合并
|
||||
|
||||
你可能想在某个时候重组你的文件。常用的 `cat` 命令就用在这里:
|
||||
|
||||
```
|
||||
$ cat SB0* > foo2.txt
|
||||
```
|
||||
|
||||
示例中的星号通配符将匹配到所有以 SB0 开头的文件,这可能不会得到您想要的结果。您可以使用问号通配符进行更精确的匹配,每个字符使用一个问号:
|
||||
|
||||
```
|
||||
$ cat SB0?????? > foo2.txt
|
||||
```
|
||||
|
||||
和往常一样,请查阅相关的手册和信息页面以获取完整的命令选项。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.linux.com/learn/intro-to-linux/2017/8/splitting-and-re-assembling-files-linux
|
||||
|
||||
作者:[CARLA SCHRODER][a]
|
||||
译者:[firmianay](https://github.com/firmianay)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:https://www.linux.com/users/cschroder
|
||||
[1]:https://www.linux.com/licenses/category/creative-commons-attribution
|
||||
[2]:https://www.linux.com/files/images/split-filespng
|
||||
[3]:https://training.linuxfoundation.org/linux-courses/system-administration-training/introduction-to-linux
|
@ -1,96 +0,0 @@
|
||||
XYenChi is Translating
|
||||
LEDE and OpenWrt
|
||||
===================
|
||||
|
||||
The [OpenWrt][1] project is perhaps the most widely known Linux-based distribution for home WiFi routers and access points; it was spawned from the source code of the now-famous Linksys WRT54G router more than 12 years ago. In early May, the OpenWrt user community was thrown into a fair amount of confusion when a group of core OpenWrt developers [announced][2] that they were starting a spin-off (or, perhaps, a fork) of OpenWrt to be named the [Linux Embedded Development Environment][3] (LEDE). It was not entirely clear to the public why the split was taking place—and the fact that the LEDE announcement surprised a few other OpenWrt developers suggested trouble within the team.
|
||||
|
||||
The LEDE announcement was sent on May 3 by Jo-Philipp Wich to both the OpenWrt development list and the new LEDE development list. It describes LEDE as "a reboot of the OpenWrt community" and as "a spin-off of the OpenWrt project" seeking to create an embedded-Linux development community "with a strong focus on transparency, collaboration and decentralisation."
|
||||
|
||||
The rationale given for the reboot was that OpenWrt suffered from longstanding issues that could not be fixed from within—namely, regarding internal processes and policies. For instance, the announcement said, the number of developers is at an all-time low, but there is no process for on-boarding new developers (and, it seems, no process for granting commit access to new developers). The project infrastructure is unreliable (evidently, server outages over the past year have caused considerable strife within the project), the announcement said, but internal disagreements and single points of failure prevented fixing it. There is also a general lack of "communication, transparency and coordination" internally and from the project to the outside world. Finally, a few technical shortcomings were cited: inadequate testing, lack of regular builds, and poor stability and documentation.
|
||||
|
||||
The announcement goes on to describe how the LEDE reboot will address these issues. All communication channels will be made available for public consumption, decisions will be made by project-wide votes, the merge policy will be more relaxed, and so forth. A more detailed explanation of the new project's policies can be found on the [rules][4] page at the LEDE site. Among other specifics, it says that there will be only one class of committer (that is, no "core developer" group with additional privileges), that simple majority votes will settle decisions, and that any infrastructure managed by the project must have at least three operators with administrative access. On the LEDE mailing list, Hauke Mehrtens [added][5] that the project will make an effort to have patches sent upstream—a point on which OpenWrt has been criticized in the past, especially where the kernel is concerned.
|
||||
|
||||
In addition to Wich, the announcement was co-signed by OpenWrt contributors John Crispin, Daniel Golle, Felix Fietkau, Mehrtens, Matthias Schiffer, and Steven Barth. It ends with an invitation for others interested in participating to visit the LEDE site.
|
||||
|
||||
#### Reactions and questions
|
||||
|
||||
One might presume that the LEDE organizers expected their announcement to be met with some mixture of positive and negative reactions. After all, a close reading of the criticisms of the OpenWrt project in the announcement suggests that there were some OpenWrt project members that the LEDE camp found difficult to work with (the "single points of failure" or "internal disagreements" that prevented infrastructure fixes, for instance).
|
||||
|
||||
And, indeed, there were negative responses. OpenWrt co-founder Mike Baker [responded][6] with some alarm, disagreeing with all of the LEDE announcement's conclusions and saying "phrases such as a 'reboot' are both vague and misleading and the LEDE project failed to identify its true nature." Around the same time, someone disabled the @openwrt.org email aliases of those developers who signed the LEDE announcement; when Fietkau [objected][7], Baker [replied][8] that the accounts were "temporarily disabled" because "it's unclear if LEDE still represents OpenWrt." Imre Kaloz, another core OpenWrt member, [wrote][9]that "the LEDE team created most of that [broken] status quo" in OpenWrt that it was now complaining about.
|
||||
|
||||
But the majority of the responses on the OpenWrt list expressed confusion about the announcement. List members were not clear whether the LEDE team was going to [continue contributing][10] to OpenWrt or not, nor what the [exact nature][11] of the infrastructure and internal problems were that led to the split. Baker's initial response lamented the lack of public debate over the issues cited in the announcement: "We recognize the current OpenWrt project suffers from a number of issues," but "we hoped we had an opportunity to discuss and attempt to fix" them. Baker concluded:
|
||||
|
||||
We would like to stress that we do want to have an open discussion and resolve matters at hand. Our goal is to work with all parties who can and want to contribute to OpenWrt, including the LEDE team.
|
||||
|
||||
In addition to the questions over the rationale of the new project, some list subscribers expressed confusion as to whether LEDE was targeting the same uses cases as OpenWrt, given the more generic-sounding name of the new project. Furthermore, a number of people, such as Roman Yeryomin, [expressed confusion][12] as to why the issues demanded the departure of the LEDE team, particularly given that, together, the LEDE group constituted a majority of the active core OpenWrt developers. Some list subscribers, like Michael Richardson, were even unclear on [who would still be developing][13] OpenWrt.
|
||||
|
||||
#### Clarifications
|
||||
|
||||
The LEDE team made a few attempts to further clarify their position. In Fietkau's reply to Baker, he said that discussions about proposed changes within the OpenWrt project tended to quickly turn "toxic," thus resulting in no progress. Furthermore:
|
||||
|
||||
A critical part of many of these debates was the fact that people who were controlling critical pieces of the infrastructure flat out refused to allow other people to step up and help, even in the face of being unable to deal with important issues themselves in a timely manner.
|
||||
|
||||
This kind of single-point-of-failure thing has been going on for years, with no significant progress on resolving it.
|
||||
|
||||
Neither Wich nor Fietkau pointed fingers at specific individuals, although others on the list seemed to think that the infrastructure and internal decision-making problems in OpenWrt came down to a few people. Daniel Dickinson [stated][14] that:
|
||||
|
||||
My impression is that Kaloz (at least) holds infrastructure hostage to maintain control, and that the fundamental problem here is that OpenWrt is *not* democratic and ignores what people who were ones visibly working on openwrt want and overrides their wishes because he/they has/have the keys.
|
||||
|
||||
On the other hand, Luka Perkov [countered][15] that many OpenWrt developers wanted to switch from Subversion to Git, but that Fietkau was responsible for blocking that change.
|
||||
|
||||
What does seem clear is that the OpenWrt project has been operating with a governance structure that was not functioning as desired and, as a result, personality conflicts were erupting and individuals were able to disrupt or block proposed changes simply by virtue of there being no well-defined process. Clearly, that is not a model that works well in the long run.
|
||||
|
||||
On May 6, Crispin [wrote][16] to the OpenWrt list in a new thread, attempting to reframe the LEDE project announcement. It was not, he said, meant as a "hostile or disruptive" act, but to make a clean break from the dysfunctional structures of OpenWrt and start fresh. The matter "does not boil down to one single event, one single person or one single flamewar," he said. "We wanted to split with the errors we have done ourselves in the past and the wrong management decision that were made at times." Crispin also admitted that the announcement had not been handled well, saying that the LEDE team "messed up the politics of the launch."
|
||||
|
||||
Crispin's email did not seem to satisfy Kaloz, who [insisted][17] that Crispin (as release manager) and Fietkau (as lead developer) could simply have made any desirable changes within the OpenWrt project. But the discussion thread has subsequently gone silent; whatever happens next on either the LEDE or OpenWrt side remains to be seen.
|
||||
|
||||
#### Intent
|
||||
|
||||
For those still seeking further detail on what the LEDE team regarded as problematic within OpenWrt, there is one more source of information that can shed light on the issues. Prior to the public announcement, the LEDE organizers spent several weeks hashing out their plan, and IRC logs of the meetings have now been [published][18]. Of particular interest is the March 30 [meeting][19] that includes a detailed discussion of the project's goals.
|
||||
|
||||
Several specific complaints about OpenWrt's infrastructure are included, such as the shortcomings of the project's Trac issue tracker. It is swamped with incomplete bug reports and "me too" comments, Wich said, and as a result, few committers make use of it. In addition, people seem confused by the fact that bugs are also being tracked on GitHub, making it unclear where issues ought to be discussed.
|
||||
|
||||
The IRC discussion also tackles the development process itself. The LEDE team would like to implement several changes, starting with the use of staging trees that get merged into the trunk during a formal merge window, rather than the commit-directly-to-master approach employed by OpenWrt. The project would also commit to time-based releases and encourage user testing by only releasing binary modules that have successfully been tested, by the community rather than the core developers, on actual hardware.
|
||||
|
||||
Finally, the IRC discussion does make it clear that the LEDE team's intent was not to take OpenWrt by surprise with its announcement. Crispin suggested that LEDE be "semi public" at first and gradually be made more public. Wich noted that he wanted LEDE to be "neutral, professional and welcoming to OpenWrt to keep the door open for a future reintegration." The launch does not seem to have gone well on that front, which is unfortunate.
|
||||
|
||||
In an email, Fietkau added that the core OpenWrt developers had been suffering from bottlenecks on tasks like patch review and maintenance work that were preventing them from getting other work done—such as setting up download mirrors or improving the build system. In just the first few days after the LEDE announcement, he said, the team had managed to tackle the mirror and build-system tasks, which had languished for years.
|
||||
|
||||
A lot of what we did in LEDE was based on the experience with decentralizing the development of packages by moving it to GitHub and giving up a lot of control over how packages should be maintained. This ended up reducing our workload significantly and we got quite a few more active developers this way.
|
||||
|
||||
We really wanted to do something similar with the core development, but based on our experience with trying to make bigger changes we felt that we couldn't do this from within the OpenWrt project.
|
||||
|
||||
Fixing the infrastructure will reap other dividends, too, he said, such as an improved system for managing the keys used to sign releases. The team is considering a rule that imposes some conditions on non-upstream patches, such as requiring a description of the patch and an explanation of why it has not yet been sent upstream. He also noted that many of the remaining OpenWrt developers have expressed interest in joining LEDE, and that the parties involved are trying to figure out if they will re-merge the projects.
|
||||
|
||||
One would hope that LEDE's flatter governance model and commitment to better transparency will help it to find success in areas where OpenWrt has struggled. For the time being, sorting out the communication issues that plagued the initial announcement may prove to be a major hurdle. If that process goes well, though, LEDE and OpenWrt may find common ground and work together in the future. If not, then the two teams may each be forced to move forward with fewer resources than they had before, which may not be what developers or users want to see.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://lwn.net/Articles/686767/
|
||||
|
||||
作者:[Nathan Willis ][a]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:https://lwn.net/Articles/686767/
|
||||
[1]:https://openwrt.org/
|
||||
[2]:https://lwn.net/Articles/686180/
|
||||
[3]:https://www.lede-project.org/
|
||||
[4]:https://www.lede-project.org/rules.html
|
||||
[5]:http://lists.infradead.org/pipermail/lede-dev/2016-May/000080.html
|
||||
[6]:https://lwn.net/Articles/686988/
|
||||
[7]:https://lwn.net/Articles/686989/
|
||||
[8]:https://lwn.net/Articles/686990/
|
||||
[9]:https://lwn.net/Articles/686991/
|
||||
[10]:https://lwn.net/Articles/686995/
|
||||
[11]:https://lwn.net/Articles/686996/
|
||||
[12]:https://lwn.net/Articles/686992/
|
||||
[13]:https://lwn.net/Articles/686993/
|
||||
[14]:https://lwn.net/Articles/686998/
|
||||
[15]:https://lwn.net/Articles/687001/
|
||||
[16]:https://lwn.net/Articles/687003/
|
||||
[17]:https://lwn.net/Articles/687004/
|
||||
[18]:http://meetings.lede-project.org/lede-adm/2016/?C=M;O=A
|
||||
[19]:http://meetings.lede-project.org/lede-adm/2016/lede-adm.2016-03-30-11.05.log.html
|
@ -1,3 +1,5 @@
|
||||
penghuster apply for it
|
||||
|
||||
Cleaning Up Your Linux Startup Process
|
||||
============================================================
|
||||
|
||||
|
@ -1,3 +1,5 @@
|
||||
translating by firmianay
|
||||
|
||||
Here are all the Git commands I used last week, and what they do.
|
||||
============================================================
|
||||
|
||||
|
@ -1,141 +0,0 @@
|
||||
### 【翻译中@haoqixu】What is Kubernetes?
|
||||
|
||||
Kubernetes, or k8s ( _k, 8 characters, s...get it?_ ), or “kube” if you’re into brevity, is an open source platform that automates [Linux container][3] operations. It eliminates many of the manual processes involved in deploying and scaling containerized applications. In other words, you can cluster together groups of hosts running Linux containers, and Kubernetes helps you easily and efficiently manage those clusters. These clusters can span hosts across [public][4], [private][5], or hybrid clouds.
|
||||
|
||||
Kubernetes was originally developed and designed by engineers at Google. Google was one of the [early contributors to Linux container technology][6] and has talked publicly about how [everything at Google runs in containers][7]. (This is the technology behind Google’s cloud services.) Google generates more than 2 billion container deployments a week—all powered by an internal platform: [Borg][8]. Borg was the predecessor to Kubernetes and the lessons learned from developing Borg over the years became the primary influence behind much of the Kubernetes technology.
|
||||
|
||||
_Fun fact: The seven spokes in the Kubernetes logo refer to the project’s original name, “[Project Seven of Nine][1].”_
|
||||
|
||||
Red Hat was one of the first companies to work with Google on Kubernetes, even prior to launch, and has become the [2nd leading contributor][9] to Kubernetes upstream project. Google [donated][10] the Kubernetes project to the newly formed [Cloud Native Computing Foundation][11] in 2015.
|
||||
|
||||
* * *
|
||||
|
||||
### Why do you need Kubernetes?
|
||||
|
||||
Real production apps span multiple containers. Those containers must be deployed across multiple server hosts. Kubernetes gives you the orchestration and management capabilities required to deploy containers, at scale, for these workloads. Kubernetes orchestration allows you to build application services that span multiple containers, schedule those containers across a cluster, scale those containers, and manage the health of those containers over time.
|
||||
|
||||
Kubernetes also needs to integrate with networking, storage, security, telemetry and other services to provide a comprehensive container infrastructure.
|
||||
|
||||
![Kubernetes explained - diagram](https://www.redhat.com/cms/managed-files/styles/max_size/s3/kubernetes-diagram-902x416.png?itok=C_wxL4HV "Kubernetes explained - diagram")
|
||||
|
||||
Of course, this depends on how you’re using containers in your environment. A rudimentary application of Linux containers treats them as efficient, fast virtual machines. Once you scale this to a production environment and multiple applications, it's clear that you need multiple, colocated containers working together to deliver the individual services. This significantly multiplies the number of containers in your environment and as those containers accumulate, the complexity also grows.
|
||||
|
||||
Kubernetes fixes a lot of common problems with container proliferation—sorting containers together into a ”pod.” Pods add a layer of abstraction to grouped containers, which helps you schedule workloads and provide necessary services—like networking and storage—to those containers. Other parts of Kubernetes help you load balance across these pods and ensure you have the right number of containers running to support your workloads.
|
||||
|
||||
With the right implementation of Kubernetes—and with the help of other open source projects like [Atomic Registry][12], [Open vSwitch][13], [heapster][14], [OAuth][15], and [SELinux][16]— you can orchestrate all parts of your container infrastructure.
|
||||
|
||||
* * *
|
||||
|
||||
### What can you do with Kubernetes?
|
||||
|
||||
The primary advantage of using Kubernetes in your environment is that it gives you the platform to schedule and run containers on clusters of physical or virtual machines. More broadly, it helps you fully implement and rely on a container-based infrastructure in production environments. And because Kubernetes is all about automation of operational tasks, you can do many of the same things that other application platforms or management systems let you do, but for your containers.
|
||||
|
||||
With Kubernetes you can:
|
||||
|
||||
* Orchestrate containers across multiple hosts.
|
||||
|
||||
* Make better use of hardware to maximize resources needed to run your enterprise apps.
|
||||
|
||||
* Control and automate application deployments and updates.
|
||||
|
||||
* Mount and add storage to run stateful apps.
|
||||
|
||||
* Scale containerized applications and their resources on the fly.
|
||||
|
||||
* Declaratively manage services, which guarantees the deployed applications are always running how you deployed them.
|
||||
|
||||
* Health-check and self-heal your apps with autoplacement, autorestart, autoreplication, and autoscaling.
|
||||
|
||||
Kubernetes, however, relies on other projects to fully provide these orchestrated services. With the addition of other open source projects, you can fully realize the power of Kubernetes. These necessary pieces include (among others):
|
||||
|
||||
* Registry, through projects like Atomic Registry or Docker Registry.
|
||||
|
||||
* Networking, through projects like OpenvSwitch and intelligent edge routing.
|
||||
|
||||
* Telemetry, through projects such as heapster, kibana, hawkular, and elastic.
|
||||
|
||||
* Security, through projects like LDAP, SELinux, RBAC, and OAUTH with multi-tenancy layers.
|
||||
|
||||
* Automation, with the addition of Ansible playbooks for installation and cluster life-cycle management.
|
||||
|
||||
* Services, through a rich catalog of precreated content of popular app patterns.
|
||||
|
||||
[Get all of this, prebuilt and ready to deploy, with Red Hat OpenShift][17]
|
||||
|
||||
* * *
|
||||
|
||||
### Learn to speak Kubernetes
|
||||
|
||||
Like any technology, there are a lot of words specific to the technology that can be a barrier to entry. Let's break down some of the more common terms to help you understand Kubernetes.
|
||||
|
||||
**Master:** The machine that controls Kubernetes nodes. This is where all task assignments originate.
|
||||
|
||||
**Node:** These machines perform the requested, assigned tasks. The Kubernetes master controls them.
|
||||
|
||||
**Pod:** A group of one or more containers deployed to a single node. All containers in a pod share an IP address, IPC, hostname, and other resources. Pods abstract network and storage away from the underlying container. This lets you move containers around the cluster more easily.
|
||||
|
||||
**Replication controller: ** This controls how many identical copies of a pod should be running somewhere on the cluster.
|
||||
|
||||
**Service:** This decouples work definitions from the pods. Kubernetes service proxies automatically get service requests to the right pod—no matter where it moves to in the cluster or even if it’s been replaced.
|
||||
|
||||
**Kubelet:** This service runs on nodes and reads the container manifests and ensures the defined containers are started and running.
|
||||
|
||||
**kubectl:** This is the command line configuration tool for Kubernetes.
|
||||
|
||||
[Had enough? No? Check out the Kubernetes glossary.][18]
|
||||
|
||||
* * *
|
||||
|
||||
### Using Kubernetes in production
|
||||
|
||||
Kubernetes is open source. And, as such, there’s not a formalized support structure around that technology—at least not one you’d trust your business on. If you had an issue with your implementation of Kubernetes, while running in production, you’re not going to be very happy. And your customers probably won’t, either.
|
||||
|
||||
That’s where [Red Hat OpenShift][2] comes in. OpenShift is Kubernetes for the enterprise—and a lot more. OpenShift includes all of the extra pieces of technology that makes Kubernetes powerful and viable for the enterprise, including: registry, networking, telemetry, security, automation, and services. With OpenShift, your developers can make new containerized apps, host them, and deploy them in the cloud with the scalability, control, and orchestration that can turn a good idea into new business quickly and easily.
|
||||
|
||||
Best of all, OpenShift is supported and developed by the #1 leader in open source, Red Hat.
|
||||
|
||||
* * *
|
||||
|
||||
### A look at how Kubernetes fits into your infrastructure
|
||||
|
||||
![Kubernetes diagram](https://www.redhat.com/cms/managed-files/styles/max_size/s3/kubernetes-diagram-2-824x437.png?itok=KmhLmkgi "Kubernetes diagram")
|
||||
|
||||
Kubernetes runs on top of an operating system ([Red Hat Enterprise Linux Atomic Host][19], for example) and interacts with pods of containers running on the nodes. The Kubernetes master takes the commands from an administrator (or DevOps team) and relays those instructions to the subservient nodes. This handoff works with a multitude of services to automatically decide which node is best suited for the task. It then allocates resources and assigns the pods in that node to fulfill the requested work.
|
||||
|
||||
So, from an infrastructure point of view, there is little change to how you’ve been managing containers. Your control over those containers happens at a higher level, giving you better control without the need to micromanage each separate container or node. Some work is necessary, but it’s mostly a question of assigning a Kubernetes master, defining nodes, and defining pods.
|
||||
|
||||
### What about docker?
|
||||
|
||||
The [docker][20] technology still does what it's meant to do. When kubernetes schedules a pod to a node, the kubelet on that node will instruct docker to launch the specified containers. The kubelet then continuously collects the status of those containers from docker and aggregates that information in the master. Docker pulls containers onto that node and starts and stops those containers as normal. The difference is that an automated system asks docker to do those things instead of the admin doing so by hand on all nodes for all containers.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.redhat.com/en/containers/what-is-kubernetes
|
||||
|
||||
作者:[www.redhat.com ][a]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:https://www.redhat.com/
|
||||
[1]:https://cloudplatform.googleblog.com/2016/07/from-Google-to-the-world-the-Kubernetes-origin-story.html
|
||||
[2]:https://www.redhat.com/en/technologies/cloud-computing/openshift
|
||||
[3]:https://www.redhat.com/en/containers/whats-a-linux-container
|
||||
[4]:https://www.redhat.com/en/topics/cloud-computing/what-is-public-cloud
|
||||
[5]:https://www.redhat.com/en/topics/cloud-computing/what-is-private-cloud
|
||||
[6]:https://en.wikipedia.org/wiki/Cgroups
|
||||
[7]:https://speakerdeck.com/jbeda/containers-at-scale
|
||||
[8]:http://blog.kubernetes.io/2015/04/borg-predecessor-to-kubernetes.html
|
||||
[9]:http://stackalytics.com/?project_type=kubernetes-group&metric=commits
|
||||
[10]:https://techcrunch.com/2015/07/21/as-kubernetes-hits-1-0-google-donates-technology-to-newly-formed-cloud-native-computing-foundation-with-ibm-intel-twitter-and-others/
|
||||
[11]:https://www.cncf.io/
|
||||
[12]:http://www.projectatomic.io/registry/
|
||||
[13]:http://openvswitch.org/
|
||||
[14]:https://github.com/kubernetes/heapster
|
||||
[15]:https://oauth.net/
|
||||
[16]:https://selinuxproject.org/page/Main_Page
|
||||
[17]:https://www.redhat.com/en/technologies/cloud-computing/openshift
|
||||
[18]:https://kubernetes.io/docs/reference/
|
||||
[19]:https://www.redhat.com/en/technologies/linux-platforms/enterprise-linux/options
|
||||
[20]:https://www.redhat.com/en/containers/what-is-docker
|
@ -1,119 +0,0 @@
|
||||
ucasFL translating
|
||||
Know your Times Tables, but... do you know your "Hash Tables"?
|
||||
============================================================
|
||||
|
||||
Diving into the world of Hash Tables and understanding the underlying mechanics is _extremely_ interesting, and very rewarding. So lets get into it and get started from the beginning.
|
||||
|
||||
A Hash Table is a common data structure used in many modern day Software applications. It provides a dictionary-like functionality, giving you the ability to perform opertations such as inserting, removing and deleting items inside it. Let’s just say I want to find what the definition of what “Apple” is, and I know the defintion is stored in my defined Hash Table. I will query my Hash Table to give me a defintion. The _entry_ inside my Hash Table might look something like this `"Apple" => "A green fruit of fruity goodness"`. So, “Apple” is my _key_ and “A green fruit of fruity goodness” is my associated _value_ .
|
||||
|
||||
One more example just so we’re clear, take below the contents of a Hash Table:
|
||||
|
||||
|
||||
```
|
||||
1234
|
||||
```
|
||||
|
||||
```
|
||||
"bread" => "solid""water" => "liquid""soup" => "liquid""corn chips" => "solid"
|
||||
```
|
||||
|
||||
|
||||
I want to look up if _bread_ is a solid or liquid, So I will query the Hash Table to give me the associated value, and the table will return to me with “solid”. Ok so we got the generally gist of how it functions. Another important concept to note with Hash Tables is the fact that every key is unique. Let’s say tomorrow, I feel like having a bread milkshake (which is a _liquid_ ), we now need to update the Hash Table to reflect its change from solid to liquid! So we add the entry into the dictionary, the key : “bread” and the value : “liquid”. Can you spot what has changed in the table below?
|
||||
|
||||
|
||||
```
|
||||
1234
|
||||
```
|
||||
|
||||
```
|
||||
"bread" => "liquid""water" => "liquid""soup" => "liquid""corn chips" => "solid"
|
||||
```
|
||||
|
||||
|
||||
That’s right, bread has been updated to have the value “liquid”.
|
||||
|
||||
**Keys are unique**, my bread can’t be both a liquid and a solid. But what makes this data structure so special from the rest? Why not just use an [Array][1] instead? It depends on the nature of the problem. You may very well be better off using a Array for a particular problem, and that also brings me to the point, **choose the data structure that is most suited to your problem**. Example, If all you need to do is store a simple grocery list, an Array would do just fine. Consider the two problems below, each problem is very different in nature.
|
||||
|
||||
1. I need a grocery list of fruit
|
||||
|
||||
2. I need a grocery list of fruit and how much each it will cost me (per kilogram).
|
||||
|
||||
As you can see below, an Array might be a better choice for storing the fruit for the grocery list. But a Hash Table looks like a better choice for looking up the cost of each item.
|
||||
|
||||
|
||||
```
|
||||
123456789
|
||||
```
|
||||
|
||||
```
|
||||
//Example Array ["apple, "orange", "pear", "grape"] //Example Hash Table { "apple" : 3.05, "orange" : 5.5, "pear" : 8.4, "grape" : 12.4 }
|
||||
```
|
||||
|
||||
|
||||
There are literally so many oppurtunities to [use][2] Hash Tables.
|
||||
|
||||
### Time and what that means to you
|
||||
|
||||
[A brush up on time and space complexity][3].
|
||||
|
||||
On average it takes a Hash Table O(1) to search, insert and delete entries in the Hash Table. For the unaware, O(1) is spoken as “Big O 1” and represents constant time. Meaning that the running time to perform each operation is not dependent on the amount of data in the dataset. We can also _promise_ that for searching, inserting and deleting items will take constant time, “IF AND ONLY” IF the implementation of the Hash Table is done right. If it’s not, then it can be really slow _O(n)_ , especially if everything hashes to the same position/slot in the Hash Table.
|
||||
|
||||
### Building a good Hash Table
|
||||
|
||||
So far we now understand how to use a Hash Table, but what if we wanted to **build** one? Essentially what we need to do is map a string (eg. “dog”) to a **hash code** (a generated number), which maps to an index of an Array. You might ask, why not just go straight to using indexes? Why bother? Well this way it allows us to find out immediately where “dog” is located by quering directly for “dog”, `String name = Array["dog"] //name is "Lassy"`. But with using an index to look up the name, we could be in the likely situation that we do not know the index where the name is located. For example, `String name = Array[10] // name is now "Bob"` - that’s not my dog’s name! And that is the benefit of mapping the string to a hash code (which corresponds to an index of an Array). We can get the index of the Array by using the modulo operator with the size of the Hash Table, `index = hash_code % table_size`.
|
||||
|
||||
Another situation that we want to avoid is having two keys mapping to the same index, this is called a **hash collision** and they’re very likely to happen if the hash function is not properly implemented. But the truth is that every hash function _with more inputs than outputs_ there is some chance of collision. To demonstrate a simple collision take the following two function outputs below:
|
||||
|
||||
`int cat_idx = hashCode("cat") % table_size; //cat_idx is now equal to 1`
|
||||
|
||||
`int dog_idx = hashCode("dog") % table_size; //dog_idx is now also equal 1`
|
||||
|
||||
We can see that both Array indexes are now 1! And as such the values will overwrite each other because they are being written to the same index. Like if we tried to look up the value for “cat” it would then return “Lassy”. Not what we wanted after all. There are various methods of [resolving hash collisions][4], the more popular one is called **Chaining**. The idea with chaining is that there is a Linked List for each index of an Array. If a collision occurs, the value will be stored inside that Linked List. Thus in the previous example, we would get the value we requested, but it we would need to search a Linked List attached to the index 1 of the Array. Hashing with Chaining achieves O(1 + α) time where α is the load factor which can be represented as n/k, n being the number of entries in the Hash Table and k being the number of slots available in the Hash Table. But remember this only holds true if the keys that you give are particularly random (relying on [SUHA][5])).
|
||||
|
||||
This is a big assumption to make, as there is always a possibility that non-equal keys will hash to the same slot. One solution to this is to take the reliance of randomness away from what keys are given to the Hash Table, and put the randomness on how the keys will be hashed to increase the likeliness of _very few conflicts_ occuring. And this is known as…
|
||||
|
||||
### Universal Hashing
|
||||
|
||||
The concept is pretty simple, select _at random_ a hash function h from the set universal hash family to compute the hash code. So in other words, choose any random hash function to hash the key! And by following this method it provides a _very low_ probability that the hashes of two distinct keys will not be the same. I will keep this one short, but if you don’t trust me then trust [Mathematics][6] instead. Also another thing to watch out for is when implementing this method be careful of having a bad universal hash family. It can blow out the time and space complexity to O(U) where U is the size of the family. And where the challenge lies is finding a Hash family that does not take too much time to compute, and too much space to store.
|
||||
|
||||
### A Hash function of the Gods
|
||||
|
||||
The search for perfection is inevitable. What if we could construct a _Perfect hash function_ where we could just map things to a set of integers with absolutely _no collisions_ . Good news is we can do this, Well kind of.. but our data has to be static (which means no insertions/deletes/updates can assured constant time). One approach to achieve a perfect hash function is to use _2-Level Hashing_ , it is basically a combination of the last two ideas we previously discussed. It uses _Universal Hashing_ to select which hash function to use, and then combines it with _Chaining_ , but this time instead of using a Linked List data structure we use another Hash Table! Let’s see how this looks visually below:
|
||||
|
||||
[![2-Level Hashing](http://www.zeroequalsfalse.press/2017/02/20/hashtables/Diagram.png "2-Level Hashing")][8]
|
||||
|
||||
**But how does this work and how can we ensure no lookup collisions?**
|
||||
|
||||
Well it works in reverse to the [Birthday paradox][7]. It states that in a set of N randomly chosen people, some pair will have the same birthday. But if the number of days in a year far outwighs the number of people (squared) then there is a damn good possibility that no pair of people will share the same birthday. So how it relates is, for each chained Hash Table is the size of the first-level Hash Table _squared_ . That is if 2 elements happen to hash to the same slot, then the size of the chained Hash Table will be of size 4\. Most of the time the chained Tables will be very sparse/empty.
|
||||
|
||||
Repeat the following two steps to ensure no look up collisions,
|
||||
|
||||
* Select a hash from the universal hash family
|
||||
|
||||
* If we get a collision, then select another hash from the universal hash family.
|
||||
|
||||
Literally that is it, (Well.. for an O(N^2) space solution anyway). If space is a concern, then a different approach is obviously needed. But the great thing is that we will only ever have to do this process on average **twice**.
|
||||
|
||||
### Summing up
|
||||
|
||||
A Hash Table is only as good as it’s _Hash function_ . Deriving a _Perfect hash function_ is much harder to achieve without losing in particular areas such as functionality, time and space. I invite you to always consider Hash Tables when solving a problem as they offer great performance benefits and they can make a noticeable difference in the usability of your application. Hash Tables and Perfect hash functions are often used in Real-time programming applications. And have been widely implemented in algorithms around the world. Hash Tables are here to stay.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: http://www.zeroequalsfalse.press/2017/02/20/hashtables/
|
||||
|
||||
作者:[Marty Jacobs][a]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:http://www.zeroequalsfalse.press/about
|
||||
[1]:https://en.wikipedia.org/wiki/Array_data_type
|
||||
[2]:https://en.wikipedia.org/wiki/Hash_table#Uses
|
||||
[3]:https://www.hackerearth.com/practice/basic-programming/complexity-analysis/time-and-space-complexity/tutorial/
|
||||
[4]:https://en.wikipedia.org/wiki/Hash_table#Collision_resolution
|
||||
[5]:https://en.wikipedia.org/wiki/SUHA_(computer_science
|
||||
[6]:https://en.wikipedia.org/wiki/Universal_hashing#Mathematical_guarantees
|
||||
[7]:https://en.wikipedia.org/wiki/Birthday_problem
|
||||
[8]:http://www.zeroequalsfalse.press/2017/02/20/hashtables/Diagram.png
|
230
sources/tech/20170813 An Intro to Compilers.md
Normal file
230
sources/tech/20170813 An Intro to Compilers.md
Normal file
@ -0,0 +1,230 @@
|
||||
ucasFL translating
|
||||
|
||||
An Intro to Compilers
|
||||
============================================================
|
||||
|
||||
### How to Speak to Computers, Pre-Siri
|
||||
|
||||
|
||||
A compiler is just a program that translates other programs. Traditional compilers translate source code into executable machine code that your computer understands. (Some compilers translate source code into another programming language. These compilers are called source-to-source translators or transpilers.) [LLVM][7] is a widely used compiler project, consisting of many modular compiler tools.
|
||||
|
||||
Traditional compiler design comprises three parts:
|
||||
![](https://nicoleorchard.com/img/blog/compilers/compiler1.jpg)
|
||||
|
||||
* The Frontend translates source code into an intermediate representation (IR)*. [`clang`][1] is LLVM’s frontend for the C family of languages.
|
||||
|
||||
* The Optimizer analyzes the IR and translates it into a more efficient form. [`opt`][2] is the LLVM optimizer tool.
|
||||
|
||||
* The Backend generates machine code by mapping the IR to the target hardware instruction set. [`llc`][3] is the LLVM backend tool.
|
||||
|
||||
* LLVM IR is a low-level language that is similar to assembly. However, it abstracts away hardware-specific information.
|
||||
|
||||
### Hello, Compiler 👋
|
||||
|
||||
Below is a simple C program that prints “Hello, Compiler!” to stdout. The C syntax is human-readable, but my computer wouldn’t know what to do with it. I’m going to walk through the three compilation phases to make this program machine-executable.
|
||||
|
||||
```
|
||||
// compile_me.c
|
||||
// Wave to the compiler. The world can wait.
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
int main() {
|
||||
printf("Hello, Compiler!\n");
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
### The Frontend
|
||||
|
||||
As I mentioned above, `clang` is LLVM’s frontend for the C family of languages. Clang consists of a C preprocessor, lexer, parser, semantic analyzer, and IR generator.
|
||||
|
||||
* The C Preprocessor modifies the source code before beginning the translation to IR. The preprocessor handles including external files, like `#include <stdio.h>` above. It will replace that line with the entire contents of the `stdio.h` C standard library file, which will include the declaration of the `printf` function.
|
||||
|
||||
_See the output of the preprocessor step by running:_
|
||||
|
||||
```
|
||||
clang -E compile_me.c -o preprocessed.i
|
||||
|
||||
```
|
||||
|
||||
* The Lexer (or scanner or tokenizer) converts a string of characters to a string of words. Each word, or token, is assigned to one of five syntactic categories: punctuation, keyword, identifier, literal, or comment.
|
||||
|
||||
_Tokenization of compile_me.c_
|
||||
![](https://nicoleorchard.com/img/blog/compilers/lexer.jpg)
|
||||
|
||||
* The Parser determines whether or not the stream of words consists of valid sentences in the source language. After analyzing the grammar of the token stream, it outputs an abstract syntax tree (AST). Nodes in a Clang AST represent declarations, statements, and types.
|
||||
|
||||
_The AST of compile_me.c_
|
||||
|
||||
![](https://nicoleorchard.com/img/blog/compilers/tree.jpg)
|
||||
|
||||
* The Semantic Analyzer traverses the AST, determining if code sentences have valid meaning. This phase checks for type errors. If the main function in compile_me.c returned `"zero"` instead of `0`, the semantic analyzer would throw an error because `"zero"` is not of type `int`.
|
||||
|
||||
* The IR Generator translates the AST to IR.
|
||||
|
||||
_Run the clang frontend on compile_me.c to generate LLVM IR:_
|
||||
|
||||
```
|
||||
clang -S -emit-llvm -o llvm_ir.ll compile_me.c
|
||||
|
||||
```
|
||||
|
||||
_The main function in llvm_ir.ll_
|
||||
|
||||
```
|
||||
; llvm_ir.ll
|
||||
@.str = private unnamed_addr constant [18 x i8] c"Hello, Compiler!\0A\00", align 1
|
||||
|
||||
define i32 @main() {
|
||||
%1 = alloca i32, align 4 ; <- memory allocated on the stack
|
||||
store i32 0, i32* %1, align 4
|
||||
%2 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([18 x i8], [18 x i8]* @.str, i32 0, i32 0))
|
||||
ret i32 0
|
||||
}
|
||||
|
||||
declare i32 @printf(i8*, ...)
|
||||
```
|
||||
|
||||
### The Optimizer
|
||||
|
||||
The job of the optimizer is to improve code efficiency based on its understanding of the program’s runtime behavior. The optimizer takes IR as input and produces improved IR as output. LLVM’s optimizer tool, `opt`, will optimize for processor speed with the flag `-O2` (capital o, two) and for size with the flag `-Os` (capital o, s).
|
||||
|
||||
Take a look at the difference between the LLVM IR code our frontend generated above and the result of running:
|
||||
|
||||
```
|
||||
opt -O2 -S llvm_ir.ll -o optimized.ll
|
||||
|
||||
```
|
||||
|
||||
_The main function in optimized.ll_
|
||||
|
||||
```
|
||||
optimized.ll
|
||||
|
||||
@str = private unnamed_addr constant [17 x i8] c"Hello, Compiler!\00"
|
||||
|
||||
define i32 @main() {
|
||||
%puts = tail call i32 @puts(i8* getelementptr inbounds ([17 x i8], [17 x i8]* @str, i64 0, i64 0))
|
||||
ret i32 0
|
||||
}
|
||||
|
||||
declare i32 @puts(i8* nocapture readonly)
|
||||
|
||||
```
|
||||
|
||||
In the optimized version, main doesn’t allocate memory on the stack, since it doesn’t use any memory. The optimized code also calls `puts` instead of `printf`because none of `printf`’s formatting functionality was used.
|
||||
|
||||
Of course, the optimizer does more than just know when to use `puts` in lieu of `printf`. The optimizer also unrolls loops and inlines the results of simple calculations. Consider the program below, which adds two integers and prints the result.
|
||||
|
||||
```
|
||||
// add.c
|
||||
#include <stdio.h>
|
||||
|
||||
int main() {
|
||||
int a = 5, b = 10, c = a + b;
|
||||
printf("%i + %i = %i\n", a, b, c);
|
||||
}
|
||||
```
|
||||
|
||||
_Here is the unoptimized LLVM IR:_
|
||||
|
||||
```
|
||||
@.str = private unnamed_addr constant [14 x i8] c"%i + %i = %i\0A\00", align 1
|
||||
|
||||
define i32 @main() {
|
||||
%1 = alloca i32, align 4 ; <- allocate stack space for var a
|
||||
%2 = alloca i32, align 4 ; <- allocate stack space for var b
|
||||
%3 = alloca i32, align 4 ; <- allocate stack space for var c
|
||||
store i32 5, i32* %1, align 4 ; <- store 5 at memory location %1
|
||||
store i32 10, i32* %2, align 4 ; <- store 10 at memory location %2
|
||||
%4 = load i32, i32* %1, align 4 ; <- load the value at memory address %1 into register %4
|
||||
%5 = load i32, i32* %2, align 4 ; <- load the value at memory address %2 into register %5
|
||||
%6 = add nsw i32 %4, %5 ; <- add the values in registers %4 and %5\. put the result in register %6
|
||||
store i32 %6, i32* %3, align 4 ; <- put the value of register %6 into memory address %3
|
||||
%7 = load i32, i32* %1, align 4 ; <- load the value at memory address %1 into register %7
|
||||
%8 = load i32, i32* %2, align 4 ; <- load the value at memory address %2 into register %8
|
||||
%9 = load i32, i32* %3, align 4 ; <- load the value at memory address %3 into register %9
|
||||
%10 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([14 x i8], [14 x i8]* @.str, i32 0, i32 0), i32 %7, i32 %8, i32 %9)
|
||||
ret i32 0
|
||||
}
|
||||
|
||||
declare i32 @printf(i8*, ...)
|
||||
|
||||
```
|
||||
|
||||
_Here is the optimized LLVM IR:_
|
||||
|
||||
```
|
||||
@.str = private unnamed_addr constant [14 x i8] c"%i + %i = %i\0A\00", align 1
|
||||
|
||||
define i32 @main() {
|
||||
%1 = tail call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([14 x i8], [14 x i8]* @.str, i64 0, i64 0), i32 5, i32 10, i32 15)
|
||||
ret i32 0
|
||||
}
|
||||
|
||||
declare i32 @printf(i8* nocapture readonly, ...)
|
||||
|
||||
```
|
||||
|
||||
Our optimized main function is essentially lines 17 and 18 of the unoptimized version, with the variable values inlined. `opt` calculated the addition because all of the variables were constant. Pretty cool, huh?
|
||||
|
||||
### The Backend
|
||||
|
||||
LLVM’s backend tool is `llc`. It generates machine code from LLVM IR input in three phases:
|
||||
|
||||
* Instruction selection is the mapping of IR instructions to the instruction-set of the target machine. This step uses an infinite namespace of virtual registers.
|
||||
|
||||
* Register allocation is the mapping of virtual registers to actual registers on your target architecture. My CPU has an x86 architecture, which is limited to 16 registers. However, the compiler will use as few registers as possible.
|
||||
|
||||
* Instruction scheduling is the reordering of operations to reflect the target machine’s performance constraints.
|
||||
|
||||
_Running this command will produce some machine code!_
|
||||
|
||||
```
|
||||
llc -o compiled-assembly.s optimized.ll
|
||||
|
||||
```
|
||||
|
||||
```
|
||||
_main:
|
||||
pushq %rbp
|
||||
movq %rsp, %rbp
|
||||
leaq L_str(%rip), %rdi
|
||||
callq _puts
|
||||
xorl %eax, %eax
|
||||
popq %rbp
|
||||
retq
|
||||
L_str:
|
||||
.asciz "Hello, Compiler!"
|
||||
|
||||
```
|
||||
|
||||
This program is x86 assembly language, which is the human readable syntax for the language my computer speaks. Someone finally understands me 🙌
|
||||
|
||||
* * *
|
||||
|
||||
Resources
|
||||
|
||||
1. [Engineering a compiler][4]
|
||||
|
||||
2. [Getting Started with LLVM Core Libraries][5]
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://nicoleorchard.com/blog/compilers
|
||||
|
||||
作者:[Nicole Orchard ][a]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:https://nicoleorchard.com/
|
||||
[1]:http://clang.llvm.org/
|
||||
[2]:http://llvm.org/docs/CommandGuide/opt.html
|
||||
[3]:http://llvm.org/docs/CommandGuide/llc.html
|
||||
[4]:https://www.amazon.com/Engineering-Compiler-Second-Keith-Cooper/dp/012088478X
|
||||
[5]:https://www.amazon.com/Getting-Started-LLVM-Core-Libraries/dp/1782166920
|
||||
[6]:https://twitter.com/norchard/status/864246049266958336
|
||||
[7]:http://llvm.org/
|
@ -1,4 +1,4 @@
|
||||
[Kubernetes at GitHub][10]
|
||||
【翻译中 @haoqixu】[Kubernetes at GitHub][10]
|
||||
============================================================
|
||||
|
||||
Over the last year, GitHub has gradually evolved the infrastructure that runs the Ruby on Rails application responsible for `github.com` and `api.github.com`. We reached a big milestone recently: all web and API requests are served by containers running in [Kubernetes][13] clusters deployed on our [metal cloud][14]. Moving a critical application to Kubernetes was a fun challenge, and we’re excited to share some of what we’ve learned with you today.
|
||||
|
@ -1,42 +0,0 @@
|
||||
translating---geekpi
|
||||
|
||||
OpenShift on OpenStack: Delivering Applications Better Together
|
||||
============================================================
|
||||
|
||||
Have you ever asked yourself, where should I run OpenShift? The answer is anywhere—it runs great on bare metal, on virtual machines, in a private cloud or in the public cloud. But, there are some reasons why people are moving to private and public clouds related to automation around full stack exposition and consumption of resources. A traditional operating system has always been about [exposition and consumption of hardware resources][2]—hardware provides resources, applications consume them, and the operating system has always been the traffic cop. But a traditional operating system has always been confined to a single machine[1].
|
||||
|
||||
Well, in the cloud-native world, this now means expanding this concept to include multiple operating system instances. That’s where OpenStack and OpenShift come in. In a cloud-native world, virtual machines, storage volumes and network segments all become dynamically provisioned building blocks. We architect our applications from these building blocks. They are typically paid for by the hour or minute and deprovisioned when they are no longer needed. But you need to think of them as dynamically provisioned capacity for applications. OpenStack is really good at dynamically provisioning capacity (exposition), and OpenShift is really good at dynamically provisioning applications (consumption), but how do we glue them together to provide a dynamic, highly programmable, multi-node operating system?
|
||||
|
||||
To understand, let’s take a look at what would happen if we installed OpenShift in a traditional environment— imagine we want to provide developers with dynamic access to create new applications or imagine we want to provide lines of business with access to provision new copies of existing applications to meet contractual obligations. Each application would need access to persistent storage. Persistent storage is not ephemeral, and in a traditional environment, this is provisioned by filing a ticket. That’s OK, we could wire up OpenShift to file a ticket every time it needs storage. A storage admin could log into the enterprise storage array and carve off volumes as needed, then hand them back to OpenShift to satisfy applications. But this would be a horribly slow, manual process—and, you would probably have storage administrators quit.
|
||||
|
||||
![](https://blog.openshift.com/wp-content/uploads/OpenShift-on-OpenStack-Delivering-Applications-Better-Together-Traditional-Storage-1024x615.png)
|
||||
|
||||
In a cloud-native world, we should think about this as a policy-driven, automated process. The storage administrator becomes more strategic, setting policies, quota, and service levels (silver, gold, etc.), but the actual provisioning becomes dynamic.
|
||||
|
||||
![](https://blog.openshift.com/wp-content/uploads/OpenShift-on-OpenStack-Delivering-Applications-Better-Together-Cloud-Storage-1024x655.png)
|
||||
|
||||
A dynamic process scales to multiple applications – this could be lines of business or even new applications being tested by developers. From 10s of applications to 1000s of applications, dynamic provisioning provides a cloud native experience.
|
||||
|
||||
![](https://blog.openshift.com/wp-content/uploads/OpenShift-on-OpenStack-Delivering-Applications-Better-Together-Persistent-Volume-Claims-Persistent-Volumes-Demo-1024x350.png)
|
||||
|
||||
The demo video below, shows how dynamic storage provisioning works with Red Hat OpenStack Platform (Cinder volumes) and Red Hat OpenShift Container Platform – but dynamic provisioning isn’t restricted to storage alone. Imagine an environment where nodes are scaled up automatically as an instance of OpenShift needs more capacity. Imagine carving off network segments for load testing a particular instance of OpenShift before pushing a particularly sensitive application change. The reasons why you need dynamic provisioning of IT building blocks goes on and on. OpenStack is really designed to do this in a programmatic, API driven way. :
|
||||
|
||||
[YOUTUBE VIDEO](https://youtu.be/PfWmAS9Fc7I)
|
||||
|
||||
OpenShift and OpenStack deliver applications better together. OpenStack dynamically provisions resources, while OpenShift dynamically consumes them. Together, they provide a flexible cloud-native solution for all of your container and virtual machine needs.
|
||||
|
||||
[1] High availability clustering and some specialized operating systems bridged this gap to an extent, but was generally an edge case in computing.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://blog.openshift.com/openshift-on-openstack-delivering-applications-better-together/
|
||||
|
||||
作者:[SCOTT MCCARTY ][a]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:https://blog.openshift.com/author/smccartyredhat-com/
|
||||
[1]:https://blog.openshift.com/author/smccartyredhat-com/
|
||||
[2]:https://docs.google.com/presentation/d/139_dxpiYc5JR8yKAP8pl-FcZmOFQCuV8RyDxZqOOcVE/edit
|
387
sources/tech/20170823 How Machines Learn A Practical Guide.md
Normal file
387
sources/tech/20170823 How Machines Learn A Practical Guide.md
Normal file
@ -0,0 +1,387 @@
|
||||
How Machines Learn: A Practical Guide
|
||||
============================================================
|
||||
|
||||
![](https://cdn-images-1.medium.com/max/1000/1*MxSBSJIqK19z2qhfspPL-g.png)
|
||||
|
||||
You may have heard about machine learning from interesting applications like spam filtering, optical character recognition, and computer vision.
|
||||
|
||||
Getting started with machine learning is long process that involves going through several resources. There are books for newbies, academic papers, guided exercises, and standalone projects. It’s easy to lose track of what you need to learn among all these options.
|
||||
|
||||
So in today’s post, I’ll list seven steps (and 50+ resources) that can help you get started in this exciting field of Computer Science, and ramp up toward becoming a machine learning hero.
|
||||
|
||||
Note that this list of resources is not exhaustive and is meant to get you started. There are many more resources around.
|
||||
|
||||
### 1\. Get the necessary background knowledge
|
||||
|
||||
You might remember from DataCamp’s [Learn Data Science][77] infographic that mathematics and statistics are key to starting machine learning (ML). The foundations might seem quite easy because it’s just three topics. But don’t forget that these are in fact three broad topics.
|
||||
|
||||
There are two things that are very important to keep in mind here:
|
||||
|
||||
* First, you’ll definitely want some further guidance on what exactly you need to cover to get started.
|
||||
|
||||
* Second, these are the foundations of your further learning. Don’t be scared to take your time. Get the knowledge on which you’ll build everything.
|
||||
|
||||
The first point is simple: it’s a good idea to cover linear algebra and statistics. These two are the bare minimum that one should understand. But while you’re at it, you should also try to cover topics such as optimization and advanced calculus. They will come in handy when you’re getting deeper into ML.
|
||||
|
||||
Here are some pointers on where to get started if you are starting from zero:
|
||||
|
||||
* [Khan Academy][1] is a good resource for beginners. Consider taking the Linear Algebra and Calculus courses.
|
||||
|
||||
* Go to [MIT OpenCourseWare][2] and take the[ Linear Algebra][3] course.
|
||||
|
||||
* Take [this Coursera course][4] for an introduction to descriptive statistics, probability theory, and inferential statistics.
|
||||
|
||||
|
||||
![](https://cdn-images-1.medium.com/max/800/1*Uw8YXNlt5VGKTXFDbtFEig.png)
|
||||
Statistics is one of the keys to learning ML
|
||||
|
||||
If you’re more into books, consider the following:
|
||||
|
||||
* [_Linear Algebra and Its Applications_][5] _,_
|
||||
|
||||
* [_Applied Linear Algebra_][6] ,
|
||||
|
||||
* [_3,000 Solved Problems in Linear Algebra_][7] _,_
|
||||
|
||||
* [MIT Online Texbooks][8]
|
||||
|
||||
However, in most cases, you’ll start off already knowing some things about statistics and mathematics. Or maybe you have already gone through all the theory resources listed above.
|
||||
|
||||
In these cases, it’s a good idea to recap and assess your knowledge honestly. Are there any areas that you need to revise or are you good for now?
|
||||
|
||||
If you’re all set, it’s time to go ahead and apply all that knowledge with R or Python. As a general guideline, it’s a good idea to pick one and get started with that language. Later, you can still add the other programming language to your skill set.
|
||||
|
||||
Why is all this programming knowledge necessary?
|
||||
|
||||
Well, you’ll see that the courses listed above (or those you have taken in school or university) will provide you with a more theoretical (and not applied) introduction to mathematics and statistics topics. However, ML is very applied and you’ll need to be able to apply all the topics you have learned. So it’s a good idea to go over the materials again, but this time in an applied way.
|
||||
|
||||
If you want to master the basics of R and Python, consider the following courses:
|
||||
|
||||
* DataCamp’s introductory Python or R courses: [Intro to Python for Data Science][9] or [Introduction to R Programming][10].
|
||||
|
||||
* Introductory Python and R courses from Edx: [Introduction to Python for Data Science][11] and [Introduction to R for Data Science][12].
|
||||
|
||||
* There are many other free courses out there. Check out [Coursera][13] or [Codeacademy][14] for more.
|
||||
|
||||
When you have nailed down the basics, check out DataCamp’s blog on the [40+ Python Statistics For Data Science Resources][78]. This post offers 40+ resources on the statistics topics you need to know to get started with data science (and by extension also ML).
|
||||
|
||||
Also make sure you check out [this SciPy tutorial][79] on vectors and arrays and [this workshop][80] on Scientific Computing with Python.
|
||||
|
||||
To get hands-on with Python and calculus, you can check out the [SymPy package][81].
|
||||
|
||||
### 2\. Don’t be scared to invest in the “theory” of ML
|
||||
|
||||
A lot of people don’t make the effort to go through some more theoretical material because it’s “dry” or “boring.” But going through the theory and really investing your time in it is essential and invaluable in the long run. You’ll better understand new advancements in machine learning, and you’ll be able to link back to your background knowledge. This will help you stay motivated.
|
||||
|
||||
Additionally, the theory doesn’t need to be boring. As you read in the introduction, there are so many materials that will make it easier for you to get into it.
|
||||
|
||||
Books are one of the best ways to absorb the theoretical knowledge. They force you to stop and think once in a while. Of course, reading books is a very static thing to do and it might not agree with your learning style. Nonetheless, try out the following books and see if it might be something for you:
|
||||
|
||||
* [_Machine Learning textbook_][15] , by Tom Mitchell might be old but it’s gold. This book goes over the most important topics in machine learning in a well-explained and step-by-step way.
|
||||
|
||||
* _Machine Learning: The Art and Science of Algorithms that Make Sense of Data _ (you can see the slides of the book [here][16]): this book is great for beginners. There are many real-life applications discussed, which you might find lacking in Tom Mitchell’s book.
|
||||
|
||||
* [_Machine Learning Yearning_][17] : this book by Andrew Ng is not yet complete, but it’s bound to be an excellent reference for those who are learning ML.
|
||||
|
||||
* [_Algorithms and Data Structures_][18] by Jurg Nievergelt and Klaus Hinrichs
|
||||
|
||||
* Also check out the [_Data Mining for the Masses_][19] by Matthew North. You’ll find that this book guides you through some of the most difficult topics.
|
||||
|
||||
* [_Introduction to Machine Learning_][20] by Alex Smola and S.V.N. Vishwanathan.
|
||||
|
||||
|
||||
![](https://cdn-images-1.medium.com/max/800/1*TpLLAIKIRVHq6VQs3Q9IJA.png)
|
||||
Take your time to read books and to study the material covered in them
|
||||
|
||||
Videos / MOOCs are awesome for those who learn by watching and listening. There are a lot of MOOCs and videos out there, but it can also be hard to find your way through all those materials. Below is a list of the most notable ones:
|
||||
|
||||
* [This well-known Machine Learning MOOC][21], taught by Andrew Ng, introduces you to Machine Learning and the theory. Don’t worry — it’s well-explained and takes things step-by-step, so it’s excellent for beginners.
|
||||
|
||||
* The [playlist of the MIT Open Courseware 6034 course][22]: already a bit more advanced. You’ll definitely need some previous work on ML theory before you start this series, but you won’t regret it.
|
||||
|
||||
At this point, it’s important for you to go over the separate techniques and grasp the whole picture. This starts with understanding key concepts: the distinction between supervised and unsupervised learning, classification and regression, and so on. Manual (written) exercises can come in handy. They can help you understand how algorithms work and how you should go about them. You’ll most often find these written exercises in courses from universities. Check out [this ML course][82] by Portland State University.
|
||||
|
||||
### 3\. Get hands-on
|
||||
|
||||
Knowing the theory and understanding the algorithms by reading and watching is all good. But you also need to surpass this stage and get started with some exercises. You’ll learn to implement these algorithms and apply the theory that you’ve learned.
|
||||
|
||||
First, you have tutorials which introduce you to the basics of machine learning in Python and R. The best way is, of course, to go for interactive tutorials:
|
||||
|
||||
* In [Python Machine Learning: Scikit-Learn Tutorial][23], you will learn more about well-known algorithms KMeans and Support Vector Machines (SVM) to construct models with Scikit-Learn.
|
||||
|
||||
* [Machine Learning in R for beginners][24] introduces you to ML in R with the class and caret packages.
|
||||
|
||||
* [Keras Tutorial: Deep Learning in Python covers ][25]how to build Multi-Layer Perceptrons (MLPs) for classification and regression tasks, step-by-step.
|
||||
|
||||
Also check out the following tutorials, which are static and will require you to work in an IDE:
|
||||
|
||||
* [Machine Learning in Python, Step By Step][26]: step-by-step tutorial with Scikit-Learn.
|
||||
|
||||
* [Develop Your First Neural Network in Python With Keras Step-By-Step][27]: learn how to develop your first neural network with Keras thanks to this tutorial.
|
||||
|
||||
* There are many more that you can consider, but the tutorials of [Machine Learning Mastery][28] are very good.
|
||||
|
||||
Besides the tutorials, there are also courses. Taking courses will help you apply the concepts that you’ve learned in a focused way. Experienced instructors will help you. Here are some interactive courses for Python and ML:
|
||||
|
||||
* [Supervised Learning with scikit-learn][29]: you’ll learn how to build predictive models, tune their parameters, and predict how well they will perform on unseen data. All while using real world datasets. You’ll do so with Scikit-Learn.
|
||||
|
||||
* [Unsupervised Learning in Python][30]: shows you how to cluster, transform, visualize, and extract insights from unlabeled datasets. At the end of the course, you’ll build a recommender system.
|
||||
|
||||
* [Deep Learning in Python][31]: you’ll gain hands-on, practical knowledge of how to use deep learning with Keras 2.0, the latest version of a cutting-edge library for deep learning in Python.
|
||||
|
||||
* [Applied Machine Learning in Python][32]: introduces the learner to applied ML and focuses more on the techniques and methods than on the statistics behind these methods.
|
||||
|
||||
|
||||
|
||||
![](https://cdn-images-1.medium.com/max/800/1*xYFavqTjvPDUCfMVrfPr-A.png)
|
||||
After the theory, take your time to apply the knowledge you have gained.
|
||||
|
||||
For those who are learning ML with R, there are also these interactive courses:
|
||||
|
||||
* [Introduction to Machine Learning][33] gives you a broad overview of the discipline’s most common techniques and applications. You’ll gain more insight into the assessment and training of different ML models. The rest of the course focuses on an introduction to three of the most basic ML tasks: classification, regression, and clustering.
|
||||
|
||||
* [R: Unsupervised Learning][34] provides a basic introduction to clustering and dimensionality reduction in R from a ML perspective. This allows you to get from data to insights as quickly as possible.
|
||||
|
||||
* [Practical Machine Learning][35] covers the basic components of building and applying prediction functions with an emphasis on practical applications.
|
||||
|
||||
Lastly, there are also books that go over ML topics in a very applied way. If you’re looking to learn with the help of text and an IDE, check out these books:
|
||||
|
||||
* The [_Python Machine Learning Book_][36] by Sebastian Raschka
|
||||
|
||||
* The [Introduction to Artificial Neural Networks and Deep Learning: A Practical Guide with Applications in Python][37] by Sebastian Raschka
|
||||
|
||||
* [_Machine Learning with R_][38] by Brett Lantz
|
||||
|
||||
### 4\. Practice
|
||||
|
||||
Practice is even more important than getting hands-on and revising the material with Python. This step was probably the hardest one for me. Check out how other people have implemented ML algorithms when you have done some exercises. Then, get started on your own projects that illustrate your understanding of ML algorithms and theories.
|
||||
|
||||
One of the most straightforward ways is to see the exercises a tiny bit bigger. You want to do a bigger exercise which requires you to do more data cleaning and feature engineering.
|
||||
|
||||
* Start with[ Kaggle][39]. If you need additional help to conquer the so-called “data fear,” check out the [Kaggle Python Tutorial on Machine Learning][40]and[ Kaggle R Tutorial on Machine Learning][41]. These will bring you up to speed in no time.
|
||||
|
||||
* Afterwards, you can also start doing challenges by yourself. Check out these sites, where you can find lots of ML datasets: [UCI Machine Learning Repository][42], [Public datasets for machine learning][43], and [data.world][44].
|
||||
|
||||
|
||||
![](https://cdn-images-1.medium.com/max/800/1*ZbZrcoYWENMQuKLbDkdG4A.png)
|
||||
Practice makes perfect.
|
||||
|
||||
### 5\. Projects
|
||||
|
||||
Doing small exercises is good. But in the end, you’ll want to make a project in which you can demonstrate your understanding of the ML algorithms with which you’ve been working.
|
||||
|
||||
The best exercise is to implement your own ML algorithm. You can read more about why you should do this exercise and what you can learn from it in the following pages:
|
||||
|
||||
* [Why is there a need to manually implement machine learning algorithms when there are many advanced APIs like tensorflow available?][45]
|
||||
|
||||
* [Why Implement Machine Learning Algorithms From Scratch?][46]
|
||||
|
||||
* [What I Learned Implementing a Classifier from Scratch in Python][47]
|
||||
|
||||
Next, you can check out the following posts and repositories. They’ll give you some inspiration from others and will show how they have implemented ML algorithms.
|
||||
|
||||
* [How to Implement a Machine Learning Algorithm][48]
|
||||
|
||||
* [ML From Scratch][49]
|
||||
|
||||
* [Machine Learning Algorithms From Scratch][50]
|
||||
|
||||
|
||||
|
||||
![](https://cdn-images-1.medium.com/max/800/1*k0vqKBz-LwnMElA0o2FhOg.png)
|
||||
Projects can be hard at start, but they’ll increase your understanding even more.
|
||||
|
||||
### 6\. Don’t stop
|
||||
|
||||
Learning ML is something that should never stop. As many will confirm, there are always new things to learn — even when you’ve been working in this area for a decade.
|
||||
|
||||
There are, for example, ML trends such as deep learning which are very popular right now. You might also focus on other topics that aren’t central at this point but which might be in the future. Check out this [interesting question and the answers][83] if you want to know more.
|
||||
|
||||
Papers may not be the first thing that spring to mind when you’re worried about mastering the basics. But they are your way to get up to date with the latest research. Papers are not for those who are just starting out. They are definitely a good fit for those who are more advanced.
|
||||
|
||||
* [Top 20 Recent Research Papers on Machine Learning and Deep Learning][51]
|
||||
|
||||
* [Journal of Machine Learning Research][52]
|
||||
|
||||
* [Awesome Deep Learning Papers][53]
|
||||
|
||||
* [What are some of the best research papers/books for Machine learning?][54]
|
||||
|
||||
Other technologies are also something to consider. But don’t worry about them when you’re just starting out. You can, for example, focus on adding Python or R (depending on which one you already know) to your skill set. You can look through this post to find interesting resources.
|
||||
|
||||
If you also want to move towards big data, you could consider looking into Spark. Here are some interesting resources:
|
||||
|
||||
* [Introduction to Spark in R with sparklyr][55]
|
||||
|
||||
* [Data Science And Engineering With Spark][56]
|
||||
|
||||
* [Introduction to Apache Spark][57]
|
||||
|
||||
* [Distributed Machine Learning with Apache Spark][58]
|
||||
|
||||
* [Big Data Analysis with Apache Spark][59]
|
||||
|
||||
* [Apache Spark in Python: Beginner’s Guide][60]
|
||||
|
||||
* [PySpark RDD Cheat Sheet][61]
|
||||
|
||||
* [PySpark SQL Cheat Sheet][62].
|
||||
|
||||
Other programming languages, such as Java, JavaScript, C, and C++ are gaining importance in ML. In the long run, you can consider also adding one of these languages to your to-do list. You can use these blog posts to guide your choice:
|
||||
|
||||
* [Most Popular Programming Languages for Machine Learning and Data Science][63]
|
||||
|
||||
* [The Most Popular Language For Machine Learning And Data Science Is…][64]
|
||||
|
||||
|
||||
![](https://cdn-images-1.medium.com/max/800/1*6J6tjlMIi0OcNdm7tyJQ4Q.png)
|
||||
You’re never done learning.
|
||||
|
||||
### 7\. Make use of all the material that is out there
|
||||
|
||||
Machine learning is a difficult topic which can make you lose your motivation at some point. Or maybe you feel you need a change. In such cases, remember that there’s a lot of material on which you can fall back. Check out the following resources:
|
||||
|
||||
Podcasts. Great resource for continuing your journey into ML and staying up-to-date with the latest developments in the field:
|
||||
|
||||
* [Talking Machines][65]
|
||||
|
||||
* [Data Skeptic][66]
|
||||
|
||||
* [Linear Digressions][67]
|
||||
|
||||
* [This Week in Machine Learning & AI][68]
|
||||
|
||||
* [Learning Machines 101][69]
|
||||
|
||||
There are, of course, many more podcasts.
|
||||
|
||||
Documentation and package source code are two ways to get deeper into the implementation of the ML algorithms. Check out some of these repositories:
|
||||
|
||||
* [Scikit- Learn][70]: Well-known Python ML package
|
||||
|
||||
* [Keras][71]: Deep learning package for Python
|
||||
|
||||
* [caret][72]: very popular R package for Classification and Regression Training
|
||||
|
||||
Visualizations are one of the newest and trendiest ways to get into the theory of ML. They’re fantastic for beginners, but also very interesting for more advanced learners. The following visualizations will intrigue you and will help you gain more understanding into the workings of ML:
|
||||
|
||||
* [A visual introduction to machine learning][73]
|
||||
|
||||
* [Distill][74] makes ML Research clear, dynamic and vivid.
|
||||
|
||||
* [Tensorflow — Neural Network Playground][75] if you’re looking to play around with neural network architectures.
|
||||
|
||||
* More here:[ What are the best visualizations of machine learning algorithms?][76]
|
||||
|
||||
|
||||
![](https://cdn-images-1.medium.com/max/800/1*nCt9ZsXRksdOMown4vuxJA.png)
|
||||
Some variety in your learning can and will motivate you even more.
|
||||
|
||||
### You Can Get Started Now
|
||||
|
||||
Now it’s up to you. Learning ML is something that’s a continuous process, so the sooner you get started, the better. You have all of the tools in your hands now to get started. Good luck and make sure to let us know how you’re progressing.
|
||||
|
||||
_This post is based on an answer I gave to the Quora question _ [_How Does A Total Beginner Start To Learn Machine Learning_][84] _._
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
作者简介:
|
||||
|
||||
Karlijn Willems
|
||||
|
||||
Data Science Journalist
|
||||
|
||||
-----------------------
|
||||
|
||||
via: https://medium.freecodecamp.org/how-machines-learn-a-practical-guide-203aae23cafb
|
||||
|
||||
作者:[ Karlijn Willems][a]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:https://medium.freecodecamp.org/@kacawi
|
||||
[1]:http://www.khanacademy.org/
|
||||
[2]:https://ocw.mit.edu/index.htm
|
||||
[3]:https://ocw.mit.edu/courses/mathematics/18-06-linear-algebra-spring-2010/
|
||||
[4]:https://www.coursera.org/learn/basic-statistics
|
||||
[5]:https://www.amazon.com/Linear-Algebra-Its-Applications-4th/dp/0030105676
|
||||
[6]:https://www.amazon.com/Applied-Linear-Algebra-3rd-Noble/dp/0130412600
|
||||
[7]:https://www.amazon.de/Solved-Problems-Linear-Algebra-Schaums/dp/0070380236
|
||||
[8]:https://ocw.mit.edu/courses/online-textbooks/
|
||||
[9]:https://www.datacamp.com/courses/intro-to-python-for-data-science
|
||||
[10]:https://www.datacamp.com/courses/free-introduction-to-r
|
||||
[11]:https://www.edx.org/course/introduction-python-data-science-microsoft-dat208x-5
|
||||
[12]:https://www.edx.org/course/introduction-r-data-science-microsoft-dat204x-4
|
||||
[13]:http://www.coursera.org/
|
||||
[14]:https://www.codecademy.com/
|
||||
[15]:http://www.cs.cmu.edu/~tom/mlbook.html
|
||||
[16]:http://www.cs.bris.ac.uk/~flach/mlbook/materials/mlbook-beamer.pdf
|
||||
[17]:http://www.mlyearning.org/
|
||||
[18]:https://www.amazon.com/Algorithms-Data-Structures-Applications-Practitioner/dp/0134894286
|
||||
[19]:https://www.amazon.com/Data-Mining-Masses-Matthew-North/dp/0615684378
|
||||
[20]:http://alex.smola.org/drafts/thebook.pdf
|
||||
[21]:https://www.coursera.org/learn/machine-learning
|
||||
[22]:https://youtu.be/TjZBTDzGeGg?list=PLnvKubj2-I2LhIibS8TOGC42xsD3-liux
|
||||
[23]:https://www.datacamp.com/community/tutorials/machine-learning-python
|
||||
[24]:https://www.datacamp.com/community/tutorials/machine-learning-in-r
|
||||
[25]:https://www.datacamp.com/community/tutorials/deep-learning-python
|
||||
[26]:http://machinelearningmastery.com/machine-learning-in-python-step-by-step/
|
||||
[27]:http://machinelearningmastery.com/tutorial-first-neural-network-python-keras/
|
||||
[28]:http://www.machinelearningmastery.com/
|
||||
[29]:https://www.datacamp.com/courses/supervised-learning-with-scikit-learn
|
||||
[30]:https://www.datacamp.com/courses/unsupervised-learning-in-python
|
||||
[31]:https://www.datacamp.com/courses/deep-learning-in-python
|
||||
[32]:https://www.coursera.org/learn/python-machine-learning
|
||||
[33]:https://www.datacamp.com/courses/introduction-to-machine-learning-with-r
|
||||
[34]:https://www.datacamp.com/courses/unsupervised-learning-in-r
|
||||
[35]:https://www.coursera.org/learn/practical-machine-learning
|
||||
[36]:https://github.com/rasbt/python-machine-learning-book
|
||||
[37]:https://github.com/rasbt/deep-learning-book
|
||||
[38]:https://books.google.be/books/about/Machine_Learning_with_R.html?id=ZQu8AQAAQBAJ&source=kp_cover&redir_esc=y
|
||||
[39]:http://www.kaggle.com/
|
||||
[40]:https://www.datacamp.com/community/open-courses/kaggle-python-tutorial-on-machine-learning
|
||||
[41]:https://www.datacamp.com/community/open-courses/kaggle-tutorial-on-machine-learing-the-sinking-of-the-titanic
|
||||
[42]:http://archive.ics.uci.edu/ml/
|
||||
[43]:http://homepages.inf.ed.ac.uk/rbf/IAPR/researchers/MLPAGES/mldat.htm
|
||||
[44]:https://data.world/
|
||||
[45]:https://www.quora.com/Why-is-there-a-need-to-manually-implement-machine-learning-algorithms-when-there-are-many-advanced-APIs-like-tensorflow-available
|
||||
[46]:http://www.kdnuggets.com/2016/05/implement-machine-learning-algorithms-scratch.html
|
||||
[47]:http://www.jeannicholashould.com/what-i-learned-implementing-a-classifier-from-scratch.html
|
||||
[48]:http://machinelearningmastery.com/how-to-implement-a-machine-learning-algorithm/
|
||||
[49]:https://github.com/eriklindernoren/ML-From-Scratch
|
||||
[50]:https://github.com/madhug-nadig/Machine-Learning-Algorithms-from-Scratch
|
||||
[51]:http://www.kdnuggets.com/2017/04/top-20-papers-machine-learning.html
|
||||
[52]:http://www.jmlr.org/
|
||||
[53]:https://github.com/terryum/awesome-deep-learning-papers
|
||||
[54]:https://www.quora.com/What-are-some-of-the-best-research-papers-books-for-Machine-learning
|
||||
[55]:https://www.datacamp.com/courses/introduction-to-spark-in-r-using-sparklyr
|
||||
[56]:https://www.edx.org/xseries/data-science-engineering-apache-spark
|
||||
[57]:https://www.edx.org/course/introduction-apache-spark-uc-berkeleyx-cs105x
|
||||
[58]:https://www.edx.org/course/distributed-machine-learning-apache-uc-berkeleyx-cs120x
|
||||
[59]:https://www.edx.org/course/big-data-analysis-apache-spark-uc-berkeleyx-cs110x
|
||||
[60]:https://www.datacamp.com/community/tutorials/apache-spark-python
|
||||
[61]:https://www.datacamp.com/community/blog/pyspark-cheat-sheet-python
|
||||
[62]:https://www.datacamp.com/community/blog/pyspark-sql-cheat-sheet
|
||||
[63]:https://fossbytes.com/popular-top-programming-languages-machine-learning-data-science/
|
||||
[64]:http://www.kdnuggets.com/2017/01/most-popular-language-machine-learning-data-science.html
|
||||
[65]:http://www.thetalkingmachines.com/
|
||||
[66]:https://dataskeptic.com/
|
||||
[67]:http://lineardigressions.com/
|
||||
[68]:https://twimlai.com/
|
||||
[69]:http://www.learningmachines101.com/
|
||||
[70]:https://github.com/scikit-learn/scikit-learn
|
||||
[71]:http://www.github.com/fchollet/keras
|
||||
[72]:http://topepo/caret
|
||||
[73]:http://www.r2d3.us/visual-intro-to-machine-learning-part-1/
|
||||
[74]:http://distill.pub/
|
||||
[75]:http://playground.tensorflow.org/
|
||||
[76]:https://www.quora.com/What-are-the-best-visualizations-of-machine-learning-algorithms
|
||||
[77]:https://www.datacamp.com/community/tutorials/learn-data-science-infographic
|
||||
[78]:https://www.datacamp.com/community/tutorials/python-statistics-data-science
|
||||
[79]:https://www.datacamp.com/community/tutorials/python-scipy-tutorial
|
||||
[80]:http://www.math.pitt.edu/~siam/workshops/python10/python.pdf
|
||||
[81]:http://docs.sympy.org/latest/tutorial/calculus.html
|
||||
[82]:http://web.cecs.pdx.edu/~mm/MachineLearningSpring2017/
|
||||
[83]:https://www.quora.com/Should-I-quit-machine-learning
|
||||
[84]:https://www.quora.com/How-does-a-total-beginner-start-to-learn-machine-learning/answer/Karlijn-Willems-1
|
@ -1,213 +0,0 @@
|
||||
Splitting and Re-Assembling Files in Linux
|
||||
============================================================
|
||||
|
||||
![csplit](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/split-files.png?itok=kZTP_VF9 "csplit")
|
||||
The very useful csplit command divides single files into multiple files. Carla Schroder explains.[Creative Commons Attribution][1]
|
||||
|
||||
Linux has several utilities for splitting up files. So why would you want to split your files? One use case is to split a large file into smaller sizes so that it fits on smaller media, like USB sticks. This is also a good trick to transfer files via USB sticks when you're stuck with FAT32, which has a maximum file size of 4GB, and your files are bigger than that. Another use case is to speed up network file transfers, because parallel transfers of small files are usually faster.
|
||||
|
||||
We'll learn how to use `csplit, split`, and `cat` to chop up and then put files back together. These work on any file type: text, image, audio, .iso, you name it.
|
||||
|
||||
### Split Files With csplit
|
||||
|
||||
`csplit` is one of those funny little commands that has been around forever, and when you discover it you wonder how you ever made it through life without it. `csplit` divides single files into multiple files. This example demonstrates its simplest invocation, which divides the file foo.txt into three files, split at line numbers 17 and 33:
|
||||
|
||||
```
|
||||
$ csplit foo.txt 17 33
|
||||
2591
|
||||
3889
|
||||
2359
|
||||
```
|
||||
|
||||
`csplit` creates three new files in the current directory, and prints the sizes of your new files in bytes. By default, each new file is named `xx _nn_` :
|
||||
|
||||
```
|
||||
$ ls
|
||||
xx00
|
||||
xx01
|
||||
xx02
|
||||
```
|
||||
|
||||
You can view the first ten lines of each of your new files all at once with the `head` command:
|
||||
|
||||
```
|
||||
$ head xx*
|
||||
|
||||
==> xx00 <==
|
||||
Foo File
|
||||
by Carla Schroder
|
||||
|
||||
Foo text
|
||||
|
||||
Foo subheading
|
||||
|
||||
More foo text
|
||||
|
||||
==> xx01 <==
|
||||
Foo text
|
||||
|
||||
Foo subheading
|
||||
|
||||
More foo text
|
||||
|
||||
==> xx02 <==
|
||||
Foo text
|
||||
|
||||
Foo subheading
|
||||
|
||||
More foo text
|
||||
```
|
||||
|
||||
What if you want to split a file into several files all containing the same number of lines? Specify the number of lines, and then enclose the number of repetitions in curly braces. This example repeats the split 4 times, and dumps the leftover in the last file:
|
||||
|
||||
```
|
||||
$ csplit foo.txt 5 {4}
|
||||
57
|
||||
1488
|
||||
249
|
||||
1866
|
||||
3798
|
||||
```
|
||||
|
||||
You may use the asterisk wildcard to tell `csplit` to repeat your split as many times as possible. Which sounds cool, but it fails if the file does not divide evenly:
|
||||
|
||||
```
|
||||
$ csplit foo.txt 10 {*}
|
||||
1545
|
||||
2115
|
||||
1848
|
||||
1901
|
||||
csplit: '10': line number out of range on repetition 4
|
||||
1430
|
||||
```
|
||||
|
||||
The default behavior is to delete the output files on errors. You can foil this with the `-k` option, which will not remove the output files when there are errors. Another gotcha is every time you run `csplit` it overwrites the previous files it created, so give your splits new filenames to save them. Use `--prefix= _prefix_` to set a different file prefix:
|
||||
|
||||
```
|
||||
$ csplit -k --prefix=mine foo.txt 5 {*}
|
||||
57
|
||||
1488
|
||||
249
|
||||
1866
|
||||
993
|
||||
csplit: '5': line number out of range on repetition 9
|
||||
437
|
||||
|
||||
$ ls
|
||||
mine00
|
||||
mine01
|
||||
mine02
|
||||
mine03
|
||||
mine04
|
||||
mine05
|
||||
```
|
||||
|
||||
The `-n` option changes the number of digits used to number your files:
|
||||
|
||||
```
|
||||
|
||||
$ csplit -n 3 --prefix=mine foo.txt 5 {4}
|
||||
57
|
||||
1488
|
||||
249
|
||||
1866
|
||||
1381
|
||||
3798
|
||||
|
||||
$ ls
|
||||
mine000
|
||||
mine001
|
||||
mine002
|
||||
mine003
|
||||
mine004
|
||||
mine005
|
||||
```
|
||||
|
||||
The "c" in `csplit` is "context". This means you can split your files based on all manner of arbitrary matches and clever regular expressions. This example splits the file into two parts. The first file ends at the line that precedes the line containing the first occurrence of "fie", and the second file starts with the line that includes "fie".
|
||||
|
||||
```
|
||||
$ csplit foo.txt /fie/
|
||||
```
|
||||
|
||||
Split the file at every occurrence of "fie":
|
||||
|
||||
```
|
||||
$ csplit foo.txt /fie/ {*}
|
||||
```
|
||||
|
||||
Split the file at the first 5 occurrences of "fie":
|
||||
|
||||
```
|
||||
$ csplit foo.txt /fie/ {5}
|
||||
```
|
||||
|
||||
Copy only the content that starts with the line that includes "fie", and omit everything that comes before it:
|
||||
|
||||
```
|
||||
$ csplit myfile %fie%
|
||||
```
|
||||
|
||||
### Splitting Files into Sizes
|
||||
|
||||
`split` is similar to `csplit`. It splits files into specific sizes, which is fabulous when you're splitting large files to copy to small media, or for network transfers. The default size is 1000 lines:
|
||||
|
||||
```
|
||||
$ split foo.mv
|
||||
$ ls -hl
|
||||
266K Aug 21 16:58 xaa
|
||||
267K Aug 21 16:58 xab
|
||||
315K Aug 21 16:58 xac
|
||||
[...]
|
||||
```
|
||||
|
||||
They come out to a similar size, but you can specify any size you want. This example is 20 megabytes:
|
||||
|
||||
```
|
||||
$ split -b 20M foo.mv
|
||||
```
|
||||
|
||||
The size abbreviations are K, M, G, T, P, E, Z, Y (powers of 1024), or KB, MB, GB, and so on for powers of 1000.
|
||||
|
||||
Choose your own prefix and suffix for the filenames:
|
||||
|
||||
```
|
||||
$ split -a 3 --numeric-suffixes=9 --additional-suffix=mine foo.mv SB
|
||||
240K Aug 21 17:44 SB009mine
|
||||
214K Aug 21 17:44 SB010mine
|
||||
220K Aug 21 17:44 SB011mine
|
||||
```
|
||||
|
||||
The `-a` controls how many numeric digits there are. `--numeric-suffixes` sets the starting point for numbering. The default prefix is x, and you can set a different prefix by typing it after the filename.
|
||||
|
||||
### Putting Split Files Together
|
||||
|
||||
You probably want to reassemble your files at some point. Good old `cat` takes care of this:
|
||||
|
||||
```
|
||||
$ cat SB0* > foo2.txt
|
||||
```
|
||||
|
||||
The asterisk wildcard in the example will snag any file that starts with SB0, which may not give the results you want. You can make a more exact match with question mark wildcards, using one per character:
|
||||
|
||||
```
|
||||
$ cat SB0?????? > foo2.txt
|
||||
```
|
||||
|
||||
As always, consult the relevant and man and info pages for complete command options.
|
||||
|
||||
_Learn more about Linux through the free ["Introduction to Linux" ][3]course from The Linux Foundation and edX._
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.linux.com/learn/intro-to-linux/2017/8/splitting-and-re-assembling-files-linux
|
||||
|
||||
作者:[CARLA SCHRODER ][a]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:https://www.linux.com/users/cschroder
|
||||
[1]:https://www.linux.com/licenses/category/creative-commons-attribution
|
||||
[2]:https://www.linux.com/files/images/split-filespng
|
||||
[3]:https://training.linuxfoundation.org/linux-courses/system-administration-training/introduction-to-linux
|
95
translated/tech/20160511 LEDE and OpenWrt.md
Normal file
95
translated/tech/20160511 LEDE and OpenWrt.md
Normal file
@ -0,0 +1,95 @@
|
||||
LEDE 和 OpenWrt
|
||||
===================
|
||||
|
||||
[OpenWrt][1] 项目可能是最广为人知的 Linux 发行版,对于家用 WiFi 路由器和接入点; 12 年多以前,它产自现在有名的 Linksys WRT54G 路由器的源代码。五月初,OpenWrt 用户社区陷入一片巨大的混乱中,当一群 OpenWrt 代码开发者 [宣布][2] 他们将开始着手 OpenWrt 的一个副产品 (或,可能,一个分支)叫 [Linux 嵌入开发环境][3] (LEDE)时。为什么产生分裂对公众来说并不明朗,而且 LEDE 宣言惊到了一些其他 OpenWrt 开发者也暗示这团队的内部矛盾。
|
||||
|
||||
LEDE 宣言被 Jo-Philipp Wich 于五月三日发往所有 OpenWrt 开发者列表和新 LEDE 开发者列表。它描述 LEDE 为"OpenWrt 社区的一次重启" 和 "OpenWrt 项目的一个副产品" 希望产生一个 Linux 嵌入式开发社区 "注重透明性、合作和权利分散。"
|
||||
|
||||
给出的重启的原因是 OpenWrt 遭受着长期以来存在且不能从内部解决的问题——换句话说,关于内部处理方式和政策。例如,宣言称,开发者的数目在不断减少,却没有接纳新开发者的方式(而且貌似没有授权委托访问给新开发者的方法)。项目架构不可靠(例如,这么多年来服务器挂掉在这个项目中也引发了相当多的矛盾),宣言说到,但是内部不合和单点错误阻止了修复它。内部和从这个项目到外面世界也存在着"交流、透明度和合作"的普遍缺失。最后,一些技术缺陷被引用:不充分的测试、缺乏常规维护,和窘迫的稳固性与文档。
|
||||
|
||||
该宣言继续描述 LEDE 重启将解决这些问题。所有交流频道都会打开供公众使用,决策将在项目范围内投票决出,合并政策将放宽等等。更详细的说明可以在 LEDE 站点的 [rules][4] 页找到。其他特别之处中,它说将贡献者将只有一个阶级(也就是,没有“代码开发者”这样拥有额外权利的群体),简单的少数服从多数投票作出决定,并且任何被这个项目管理的架构必须有三个以上管理员账户。在 LEDE 邮件列表, Hauke Mehrtens [补充][5] 到项目将会努力修补发送上游消息——过去 OpenWrt 被批判的一点,尤其是有关内核。
|
||||
|
||||
除了 Wich,这个宣言被 OpenWrt 贡献者 John Crispin、 Daniel Golle、 Felix Fietkau、 Mehrtens、 Matthias Schiffer 和 Steven Barth 共同创作。以给其他有兴趣参与的人访问 LEDE 站点的邀请为结尾。
|
||||
|
||||
#### 回应和问题
|
||||
|
||||
有人可能会猜想 LEDE 组织者预期他们的宣言会有或积极或消极的反响。毕竟,细读宣言中批判 OpenWrt 项目暗示了有一些 OpenWrt 项目成员 LEDE 阵营发现难以共事(“单点错误” 或 “内部不和”阻止了架构修复,例如)
|
||||
|
||||
并且,确实,有很多消极回应。创立者之一 Mike Baker [回应][6] 了一些警告,反驳所有 LEDE 宣言中的结论并称“短语像‘重启’都是含糊不清且具有误导性的而且 LEDE 项目定义它的真实本质失败了。”与此同时,有人关闭了那些在 LEDE 上署名的开发者在 @openwrt.org 的邮件入口;当 Fietkau [提出反对][7], Baker [回复][8]账户“暂时停用”因为“还不确定 LEDE 代表 OpenWrt。” Imre Kaloz, 另一个 OpenWrt 核心成员,[写][9]到“ LEDE 团队生出了大多数 [破] 事儿”在 OpenWrt 里这就是现在所抱怨的。
|
||||
|
||||
但是大多数 OpenWrt 列表的回应对该宣言表示疑惑。列表成员不明确 LEDE 团队是否将为 OpenWrt [继续贡献][10],或导致了这个分支的机构的[确切本质][11]和内部问题是什么。 Baker的第一反应是后悔在宣言中引用的那些问题缺乏公开讨论:“我们意识到当前的 OpenWrt 项目遭受着许多的问题,”但“我们希望有机会去讨论并尝试着解决”它们。 Baker 作出结论:
|
||||
|
||||
我们强调我们确实希望有一个公开的讨论和解决即将到来的事情。我们的目标是与所有能够且希望对 OpenWrt 作出贡献的参与者共事,包括 LEDE 团队。
|
||||
|
||||
除了有关新项目的初心的问题之外,一些列表贡献者提出 LEDE 是否与 OpenWrt 有相同的使用场景定位,给新项目取一个听起来更一般的名字的疑惑。此外,许多人,像 Roman Yeryomin,[表示疑惑][12]为什么这些问题需要 LEDE 团队的离开(来解决),特别是,与此同时, LEDE 团队由大部分活跃核心 OpenWrt 开发者构成。一些列表贡献者,像 Michael Richardson,甚至不清楚[谁还会开发][13] OpenWrt。
|
||||
|
||||
#### 澄清
|
||||
|
||||
LEDE 团队尝试着深入阐释他们的境况。在 Fietkau 给 Baker 的回复中,他说在 OpenWrt 内部关于有目的地改变的讨论会很快变得“有毒,”因此导致没有进展。而且:
|
||||
|
||||
这些讨论的要点在于那些掌握着框架关键部分的人精力有限却拒绝他人的加入和帮助,甚至是面对无法及时解决的重要问题时。
|
||||
|
||||
这种像单点错误一样的事已经持续了很多年了,没有任何有意义的进展来解决它。
|
||||
|
||||
Wich 和 Fietkau 都没有明显指出特别的个体,虽然其他在列表的人可能会想这个基础建设和内部讨论——在 OpenWrt 找出问题针对某些人。 Daniel Dickinson [陈述][14]到:
|
||||
|
||||
我的印象是 Kaloz (至少) 以基础建设为胁来保持控制,并且基本问题是 OpenWrt 是*不*民主的,而且忽视那些真正在 openwrt 工作的人想要的是什么无视他们的愿望,因为他/他们把握着要害。
|
||||
|
||||
另一方面, Luka Perkov [指出][15] 很多 OpemWrt 开发者想从 Subversion 转移到 Git,但 Fietkau 负责块修改。
|
||||
|
||||
清晰的是 OpenWrt 的管理结构并非如预期应用,结果导致,个人冲突爆发而且能够自立门户或者块有预谋地变更,因为没有规定好的程序。明显,这不是一个能长期持续的模式。
|
||||
|
||||
五月6日, Crispin 以新思路[写给][16] OpenWrt 列表成员,尝试着重构 LEDE 项目宣言。这不是,他说,意味着“敌对或分裂”行为,只是与性能不良的 OpenWrt 结构做个清晰的划分并以新的方式开始。问题在于“不要局限于一次单独的时间,一个人或者一次口水战,”他说。“我们想与过去自己造成的错误和作出过很多次的错误管理决定分开” Crispin 也承认宣言没有把握好,说 LEDE 团队 “弄糟了开始的政纲。”
|
||||
|
||||
Crispin 的邮件似乎没能使 Kaloz 满意, 她[坚持认为][17] Crispin (作为发行经理)和 Fietkau (作为领头开发者)可以轻易地在 OpenWrt 内部作出想要的改变。 但是讨论的线索后来变得沉寂;之后 LEDE 或者 OpenWrt 哪边会发生什么还有待观察。
|
||||
|
||||
#### 目的
|
||||
|
||||
对于那些仍在寻找 LEDE 认为有问题的事情更多的细节的 OpenWrt 成员,有更多的信息来源可以为这个问题提供线索。在公众宣言之前,LEDE 组织花了几周谈论他们的计划,会议的 IRC 日志现已[推出][18]。特别有趣的是3月30日[会议][19],包含了这个项目目标的细节讨论。
|
||||
|
||||
有些关于 OpenWrt 的架构特定的抱怨包含在内,像项目的 Trac issue 追踪者的缺点。它充斥着不完整的漏洞报告和“我也是”评论, Wich 说,结果,几乎没有贡献者使用它。此外,人们对这件事感到困惑,漏洞在 Github 上也正被追踪,使得问题应该在哪里被讨论不明了。
|
||||
|
||||
IRC 讨论也定下了开发流程本身。LEDE 团队想作出些改变,以合并到主干的 staging trees 的使用为开端,与 OpenWrt 使用的 commit-directly-to-master 方式不同。项目也将提供基于时间的发行版并鼓励用户测试通过只发行已被成功测试的二进制模块,由社区而不是核心开发者,在实际的硬件上。
|
||||
|
||||
最后,IRC 讨论确定了 LEDE 团队的目的不是用它的宣言吓唬 OpenWrt 。 Crispin 提到 LEDE 首先是“半公开的”并渐渐做得更公开。 Wich 解释说他希望 LEDE 是“中立的、专业的并打开大门欢迎 OpenWrt 以便将来的合并”不幸的是,前期发起并不是做得很好。
|
||||
|
||||
在邮件中, Fietkau 补充道核心 OpenWrt 开发者确实在任务中遇到了像补丁复审和维护这些让他们完成不了其他工作——比如配置下载镜像和改良架构系统的瓶颈。在 LEDE 宣言之后短短几天内,他说,团队成功解决了镜像和建设系统任务,而这些已被搁置多年。
|
||||
|
||||
很多我们在 LEDE 所做是基于移动到 Github 分散包的开发和放开包应如何被维护的控制的经验。这样最终有效减少了我们的工作量而且我们有了很多更活跃的开发者。
|
||||
|
||||
我们真的希望为核心开发做一些类似的事,但是根据我们想作出更大改变的经验,我们觉得在 OpenWrt 项目内做不到。
|
||||
|
||||
修复架构也将收获其他好处,他说,就比如为管理用于同意发行的密码。团队正在考虑附加一些没有上游补丁的情况,像需要补丁的描述和为什么没有发送到上游的解释。他也提到很多留下的 OpenWrt 开发者表示有兴趣加入 LEDE,相关当事人正试图弄清楚他们是否会重新合并项目。
|
||||
|
||||
有人希望 LEDE 更为干脆的管理模式和更为透明的分工会在 OpenWrt 困扰的方面取得成功。解决最初的宣言中诟病的沟通方面的问题会是最大的障碍。如果那个过程处理得好,那么,未来 LEDE 和 OpenWrt 可能找到共同之处并协作。否则,之后两个团队可能一起被逼到拥有比以前更少资源,这是开发者或用户不想看到的。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://lwn.net/Articles/686767/
|
||||
|
||||
作者:[Nathan Willis ][a]
|
||||
译者:[XYenChi](https://github.com/XYenChi)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:https://lwn.net/Articles/686767/
|
||||
[1]:https://openwrt.org/
|
||||
[2]:https://lwn.net/Articles/686180/
|
||||
[3]:https://www.lede-project.org/
|
||||
[4]:https://www.lede-project.org/rules.html
|
||||
[5]:http://lists.infradead.org/pipermail/lede-dev/2016-May/000080.html
|
||||
[6]:https://lwn.net/Articles/686988/
|
||||
[7]:https://lwn.net/Articles/686989/
|
||||
[8]:https://lwn.net/Articles/686990/
|
||||
[9]:https://lwn.net/Articles/686991/
|
||||
[10]:https://lwn.net/Articles/686995/
|
||||
[11]:https://lwn.net/Articles/686996/
|
||||
[12]:https://lwn.net/Articles/686992/
|
||||
[13]:https://lwn.net/Articles/686993/
|
||||
[14]:https://lwn.net/Articles/686998/
|
||||
[15]:https://lwn.net/Articles/687001/
|
||||
[16]:https://lwn.net/Articles/687003/
|
||||
[17]:https://lwn.net/Articles/687004/
|
||||
[18]:http://meetings.lede-project.org/lede-adm/2016/?C=M;O=A
|
||||
[19]:http://meetings.lede-project.org/lede-adm/2016/lede-adm.2016-03-30-11.05.log.html
|
142
translated/tech/20170102 What is Kubernetes.md
Normal file
142
translated/tech/20170102 What is Kubernetes.md
Normal file
@ -0,0 +1,142 @@
|
||||
### Kubernetes 是什么?
|
||||
|
||||
Kubernetes,简称 k8s(k,8个字符,s)或者 “kube”,是一个开源的 [Linux 容器][3]自动化平台,消除了容器化应用程序在部署、伸缩时涉及到的许多手动操作。换句话说,你可以将多台主机组合成集群来运行 Linux 容器,Kubernetes 能帮助你简单高效地管理集群。而且构成这些集群的主机还可以跨越[公有云][4]、[私有云][5]以及混合云。
|
||||
|
||||
Kubernetes 最开始是由 Google 的工程师设计开发的。Google 作为 [Linux 容器技术的早期贡献者][6]之一,曾公开演讲介绍 [Google 如何将一切都运行于容器之中][7](这是 Google 云服务背后的技术)。Google 一周的容器部署超过 20 亿次,全部的工作都由内部平台 [Borg][8] 支撑。Borg 是 Kubernetes 的前身,几年来开发 Borg 的经验教训也成了影响 Kubernetes 中许多技术的主要因素。
|
||||
|
||||
_趣闻: Kubernetes logo 中的七个辐条来源于项目原先的名称, “[Seven of Nine 项目][1]”(译者:Borg 是「星际迷航」中的一个宇宙种族,Seven of Nine 是该种族的一名女性角色)。_
|
||||
|
||||
红帽作为最早与 Google 合作开发 Kubernetes 的公司之一(甚至早于 Kubernetes 的发行),已经是 Kubernetes 上游项目的第二大贡献者。Google 在 2015 年把 Kubernetes 项目捐献给了新成立的 [CNCF(Cloud Native Computing Foundation)基金会][11]。
|
||||
|
||||
* * *
|
||||
|
||||
### 为什么你需要 Kubernetes ?
|
||||
|
||||
真实的生产环境应用会包含多个容器,而这些容器还很可能会跨越服务器主机。Kubernetes 提供了为工作负载大规模部署容器的编排与管理能力。Kubernetes 的编排器让你能够构建多容器的应用服务,在集群上调度或伸缩这些容器,以及管理它们随时间变化的健康状态。
|
||||
|
||||
Kubernetes also needs to integrate with networking, storage, security, telemetry and other services to provide a comprehensive container infrastructure.
|
||||
Kubernetes 需要与网络、存储、安全、监控等其它服务集成才能提供综合性的容器基础设施。
|
||||
|
||||
![Kubernetes 解释-图表](https://www.redhat.com/cms/managed-files/styles/max_size/s3/kubernetes-diagram-902x416.png?itok=C_wxL4HV "Kubernetes 解释-图表")
|
||||
|
||||
当然,这取决于你如何在你的环境中使用容器。一个初步的 Linux 容器应用程序把容器作为高效快速的虚拟机。一旦把它部署到生产环境或者扩展为多个应用,你需要许多组托管在相同位置的容器合作提供某个单一的服务。随着这些容器的累积,你的运行环境中容器的数量会急剧增加,复杂度也随之增长。
|
||||
|
||||
Kubernetes 通过将容器分类组成 “pod” 来解决容器增殖带来的问题。Pod 为容器分组提供了一层抽象,以此协助你调度工作负载以及为这些容器提供类似网络与存储这类必要的服务。Kubernetes 的其它组件帮助你对 pod 进行负载均衡,以保证有合适数量的容器支撑你的工作负载。
|
||||
|
||||
正确执行的 Kubernetes,结合类似 [Atomic Registry][12]、[Open vSwitch][13]、[heapster][14]、[OAuth][15] 和 [SELinux][16] 的开源项目,让你可以管理你自己的整个容器基础设施。
|
||||
|
||||
* * *
|
||||
|
||||
### Kubernetes 能做些什么?
|
||||
|
||||
在生产环境中使用 Kubernetes 的主要优势在于它提供了在物理机或虚拟机集群上调度和运行容器的平台。更宽泛地说,它能帮你在生产环境中实现可以依赖的基于容器的基础设施。而且,由于 Kubernetes 本质上就是作业任务的自动化平台,你可以执行一些其它应用程序平台或管理系统支持的操作,只不过操作对象变成了容器。
|
||||
|
||||
有了 Kubernetes,你可以:
|
||||
|
||||
* 跨主机编排容器。
|
||||
|
||||
* 更充分地利用硬件资源来最大化地满足企业应用的需求。
|
||||
|
||||
* 控制与自动化应用的部署与升级。
|
||||
|
||||
* 为有状态的应用程序挂载和添加存储器。
|
||||
|
||||
* 线上扩展或裁剪容器化应用程序与它们的资源。
|
||||
|
||||
* 声明式的容器管理,保证应用按照我们部署的方式运作。
|
||||
|
||||
* 通过自动布局、自动重启、自动复制、自动伸缩实现应用的状态检查与自我修复。
|
||||
|
||||
然而 Kubernetes 依赖其它项目来提供完整的编排服务。结合其它开源项目作为其组件,你才能充分感受到 Kubernetes 的能力。这些必要组件包括:
|
||||
|
||||
* 仓库:Atomic Registry、Docker Registry 等。
|
||||
|
||||
* 网络:OpenvSwitch 和 智能边缘路由等。
|
||||
|
||||
* 监控:heapster、kibana、hawkular 和 elastic。
|
||||
|
||||
* 安全:LDAP、SELinux、 RBAC 与 支持多租户的 OAUTH。
|
||||
|
||||
* 自动化:通过 Ansible 的 playbook 进行集群的安装和生命周期管理。
|
||||
|
||||
* 服务:大量事先创建好的常用应用模板。
|
||||
|
||||
[红帽 OpenShift 为容器部署预先集成了上面这些组件。][17]
|
||||
|
||||
* * *
|
||||
|
||||
### Kubernetes 入门
|
||||
|
||||
和其它技术一样,大量的专有名词有可能成为入门的障碍。下面解释一些通用的术语,希望帮助你理解 Kubernetes。
|
||||
|
||||
**Master(主节点):** 控制 Kubernetes 节点的机器,也是创建作业任务的地方。
|
||||
|
||||
**Node(节点):** 这些机器在 Kubernetes 主节点的控制下执行被分配的任务。
|
||||
|
||||
**Pod:** 由一个或多个容器构成的集合,作为一个整体被部署一个单一节点。同一个 pod 中的容器共享 IP 地址、进程间通讯(IPC)、主机名以及其它资源。Pod 将底层网络和存储抽象出来,使得集群内的容器迁移更为便捷。
|
||||
|
||||
**Replication controller(复制控制器):** 控制一个 pod 在集群上运行的实例数量。
|
||||
|
||||
**Service(服务):** 将服务内容与具体的 pod 分离。Kubernetes 服务代理负责自动将服务请求分发到正确的 pod 处,用户无需考虑 pod 部署的位置甚至可以把它替换掉。
|
||||
|
||||
**Kubelet:** 这个守护进程运行在各个工作节点上,负责获取容器列表,保证被声明的容器已经启动并且正常运行。
|
||||
|
||||
**kubectl:** 这是 Kubernetes 的命令行配置工具。
|
||||
|
||||
[上面这些知识就足够了吗?不,这仅仅是一小部分,更多内容请查看 Kubernetes 术语表。][18]
|
||||
|
||||
* * *
|
||||
|
||||
### 生产环境中使用 Kubernetes
|
||||
|
||||
Kubernetes 是开源的,所以没有正式的技术支持组织为你的商业业务提供支持。如果在生存环境使用 Kubernetes 时遇到问题,你恐怕不会太愉快,当然你的客户也不会太高兴。
|
||||
|
||||
这就是[红帽 OpenShift][2] 要解决的问题。OpenShift 是为企业提供的 Kubernetes ——并且集成了更多的组件。OpenShift 包含了强化 Kubernetes 功能,使其更适用于企业场景的额外部件,包括仓库、网络、监控、安全、自动化和服务在内。OpenShift 使得开发者能够在具有伸缩性、控制和编排能力的云端开发、托管和部署容器化的应用,快速便捷地把想法转变为业务。
|
||||
|
||||
而且,OpenShift 还是由头号开源领导公司红帽支持和开发的。
|
||||
|
||||
* * *
|
||||
|
||||
### Kubernetes 如何适配你的基础设施
|
||||
|
||||
![Kubernetes 图表](https://www.redhat.com/cms/managed-files/styles/max_size/s3/kubernetes-diagram-2-824x437.png?itok=KmhLmkgi "Kubernetes 图表")
|
||||
|
||||
Kubernetes 运行在操作系统(例如 [Red Hat Enterprise Linux Atomic Host][19])之上,操作着节点上运行的容器。Kubernetes 主节点(master)从管理员(或者 DevOps 团队)处接受命令,再把指令转交给附属的节点。转交工作由 service 自动决定接受任务的节点,然后在该节点上分配资源并指派 pod 来完成任务请求。
|
||||
|
||||
所以从基础设施的角度,管理容器的方式发生了一点小小的变化。对容器的控制在更高的层次进行,这不再需要用户管理每个单独的容器或者节点,提供了更佳的控制方式。必要的工作则主要集中在如何指派 Kubernetes 主节点,定义节点和 pod 等问题上。
|
||||
|
||||
### docker 在 Kubernetes 中的角色
|
||||
|
||||
[Docker][20] 依然执行它原本的任务。当 Kubernetes 把 pod 调度到节点上,节点上的 kubelet 会指示 docker 启动特定的容器。接着,kubelet 会通过 docker 持续地收集容器的信息,然后提交到主节点上。Docker 如往常一样拉取容器镜像、启动或停止容器。不同点仅仅在于这是由自动化系统控制而非管理员在每个节点上手动操作的。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.redhat.com/en/containers/what-is-kubernetes
|
||||
|
||||
作者:[www.redhat.com ][a]
|
||||
译者:[haoqixu](https://github.com/haoqixu)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:https://www.redhat.com/
|
||||
[1]:https://cloudplatform.googleblog.com/2016/07/from-Google-to-the-world-the-Kubernetes-origin-story.html
|
||||
[2]:https://www.redhat.com/en/technologies/cloud-computing/openshift
|
||||
[3]:https://www.redhat.com/en/containers/whats-a-linux-container
|
||||
[4]:https://www.redhat.com/en/topics/cloud-computing/what-is-public-cloud
|
||||
[5]:https://www.redhat.com/en/topics/cloud-computing/what-is-private-cloud
|
||||
[6]:https://en.wikipedia.org/wiki/Cgroups
|
||||
[7]:https://speakerdeck.com/jbeda/containers-at-scale
|
||||
[8]:http://blog.kubernetes.io/2015/04/borg-predecessor-to-kubernetes.html
|
||||
[9]:http://stackalytics.com/?project_type=kubernetes-group&metric=commits
|
||||
[10]:https://techcrunch.com/2015/07/21/as-kubernetes-hits-1-0-google-donates-technology-to-newly-formed-cloud-native-computing-foundation-with-ibm-intel-twitter-and-others/
|
||||
[11]:https://www.cncf.io/
|
||||
[12]:http://www.projectatomic.io/registry/
|
||||
[13]:http://openvswitch.org/
|
||||
[14]:https://github.com/kubernetes/heapster
|
||||
[15]:https://oauth.net/
|
||||
[16]:https://selinuxproject.org/page/Main_Page
|
||||
[17]:https://www.redhat.com/en/technologies/cloud-computing/openshift
|
||||
[18]:https://kubernetes.io/docs/reference/
|
||||
[19]:https://www.redhat.com/en/technologies/linux-platforms/enterprise-linux/options
|
||||
[20]:https://www.redhat.com/en/containers/what-is-docker
|
@ -0,0 +1,115 @@
|
||||
|
||||
知道时间表,但是你是否知道“哈希表”
|
||||
============================================================
|
||||
|
||||
探索哈希表的世界并理解潜在的技术是非常有趣的,并且将会受益匪浅。所以,让我们开始探索它吧。
|
||||
|
||||
哈希表是许多现代软件、应用程序中一种常见的数据结构。它提供了类似字典的功能,从而你能够执行插入、删除和删除其中的项等操作。这么说吧,比如我想找出“苹果”的定义是什么,并且我知道该定义被存储在了我定义的哈希表中。我将查询我的哈希表来得到定义。哈希表内的记录看起来可能像:`“苹果 ”=>" “一种拥有水果之王之称的绿色水果”`。所以,“苹果”是我的关键字,而“一种拥有水果之王之称的水果”是与之关联的值。
|
||||
|
||||
还有一个例子,我们很清楚,下面的是哈希表的内容:
|
||||
|
||||
|
||||
```
|
||||
1234
|
||||
```
|
||||
|
||||
```
|
||||
"面包" => "固体""水" => "液体""汤" => "液体""玉米片" => "固体"
|
||||
```
|
||||
|
||||
我想知道*面包*是固体还是液体,所以我将查询哈希表来获取与之相关的值,该哈希表将返回“固体”给我。现在,我们大致了解了哈希表是如何工作的。使用哈希表需要注意的另一个重要概念是每一个关键字都是唯一的。如果到了明天,我拥有一个面包奶昔(它是液体),那么我们需要更新哈希表,把“固体”改为“液体”来反映哈希表的改变。所以,我们需要添加一条记录到字典中:关键字为“面包”,对应的值为“液体”。你能发现下面的表发生了什么变化吗?
|
||||
|
||||
|
||||
```
|
||||
1234
|
||||
```
|
||||
|
||||
```
|
||||
"面包" => "液体""水" => "液体""汤" => "液体""玉米片" => "固体"
|
||||
```
|
||||
|
||||
没错,“面包”对应的值被更新为了“液体”。
|
||||
|
||||
**关键字是唯一的**,我的面包不能既是液体又是固体。但是,是什么使得该数据结构与其他数据结构相比如此特殊呢?为什么不使用一个[数组][1]来代替呢?它取决于问题的本质。对于某一个特定的问题,使用数组来描述可能会更好,因此,我们需要注意的关键点就是,**我们应该选择最适合问题的数据结构**。例如,如果你需要做的只是存储一个简单的杂货列表,那么使用数组会很适合。考虑下面的两个问题,两个问题的本质完全不同。
|
||||
|
||||
1. 我需要一个水果的列表
|
||||
2. 我需要一个水果的列表以及各种水果的价格(每千克)
|
||||
|
||||
正如你在下面所看到的,用数组来存储水果的列表可能是更好的选择。但是,用哈希表来存储每一种水果的价格看起来是更好的选择。
|
||||
|
||||
|
||||
```
|
||||
123456789
|
||||
```
|
||||
|
||||
```
|
||||
//示例数组
|
||||
["apple, "orange", "pear", "grape"]
|
||||
//示例哈希表
|
||||
{ "apple" : 3.05, "orange" : 5.5, "pear" : 8.4, "grape" : 12.4 }
|
||||
```
|
||||
|
||||
实际上,有许多的机会需要[使用][2]哈希表。
|
||||
|
||||
### 时间以及它对你的意义
|
||||
|
||||
[对时间复杂度和空间复杂度的一个复习][3].
|
||||
|
||||
平均情况下,在哈希表中进行搜索、插入和删除记录的时间复杂度均为 O(1) 。实际上,O(1) 读作“大 O 1”,表示常数时间。这意味着执行每一种操作的运行时间不依赖于数据集中数据的数量。我可以保证,查找、插入和删除项目均只花费常数时间,“当且仅当”哈希表的执行正确。如果执行不正确,可能需要花费很慢的 O(n) 时间,尤其是当所有的数据都映射到了哈希表中的同一位置/点。
|
||||
|
||||
### 构建一个好的哈希表
|
||||
|
||||
到目前为止,我们已经知道如何使用哈希表了,但是如果我们想**构建**一个哈希表呢?本质上我们需要做的就是把一个字符串(比如 "dog")映射到一个哈希代码(一个生成数),即映射到一个数组的索引。你可能会问,为什么不直接使用索引呢?为什么没必要呢?通过这种方式我们可以直接查询 "dog" 立即得到 "dog" 所在的位置,`String name = Array["dog"] //name is Lassy`。但是,使用索引查询名称时,可能出现的情况是我们不知道名称所在的索引。比如,`String name = Array[10] // name is now "Bob"`- 现在不是我的狗的名字。这就是把一个字符串映射到一个哈希代码的益处(它和一个数组的索引相对应)。我们可以通过使用模运算符和哈希表的大小来计算出数组的索引:`index = hash_code % table_size`。
|
||||
|
||||
我们需要避免的另一种情况是两个关键字映射到同一个索引,这叫做**哈希碰撞**,如果选取的哈希函数不合适,这很容易发生。实际上,每一个输入比输出多的哈希函数都有可能发生碰撞。通过下面的同一个函数的两个输出来展示一个简单的碰撞:
|
||||
|
||||
`int cat_idx = hashCode("cat") % table_size; //cat_idx 现在等于 1`
|
||||
|
||||
`int dog_idx = hashCode("dog") % table_size; //dog_idx 也等于 1`
|
||||
|
||||
我们可以看到,现在两个数组的索引均是 1 。这样将会出现两个值相互覆盖,因为它们被写到了相同的索引中。如果我们查找 "cat" 的值,将会返回 "Lassy" ,但是这并不是我们想要的。有许多可以[解决哈希碰撞][4]的方法,但是更受欢迎的一种方法叫做**链接**。链接的想法就是对于数组的每一个索引位置都有一个链表,如果碰撞发生,值就被存到链表中。因此,在前面的例子中,我们将会得到我们需要的值,但是我们需要搜索数组中索引为 1 的位置上的链表。伴有链接的哈希实现需要 O(1 + α) 时间,其中 α 是装载因子,它可以表示为 n/k,其中 n 是哈希表中的记录数目,k 是哈希表中可用位置的数目。但是请记住,只有当你给出的关键字非常随机时,这一结论才正确(依赖于 [SUHA][5])。
|
||||
|
||||
这是做了一个很大的假设,因为总是有可能任何不相等的关键字都不散列到同一点。这一问题的一个解决方法是去除哈希表中关键字对随机性的依赖,转而把随机性集中于关键字是如何被散列的,从而减少矛盾发生的可能性。这被称为……
|
||||
|
||||
### 通用散列
|
||||
|
||||
这个观念很简单,从通用散列家族集合随机选择一个哈希函数来计算哈希代码。用起来话来说,就是选择任何一个随机的哈希函数来散列关键字。通过这种方法,将有很低的可能性散列两个不同的关键字结果不相同。我只是简单的提一下,如果不相信我那么请相信[数学][6]。实现这一方法时需要注意的另一件事是选择了一个不好的通用散列家族。它会把时间和空间复杂度拖到 O(U),其中 U 是散列家族的大小。而其中的挑战就是找到一个不需要太多时间来计算,也不需要太多空间来存储的哈希家族。
|
||||
|
||||
### 上帝哈希函数
|
||||
|
||||
追求完美是人的天性。我们是否能够构建一个*完美的哈希函数*,从而能够把关键字映射到整数集中,并且几乎没有碰撞。好消息是我们能够在一定程度上做到,但是我们的数据必须是静态的(这意味着在一定时间内没有插入/删除/更新)。一个实现完美哈希函数的方法就是使用 2-级哈希,它基本上是我们前面讨论过的两种方法的组合。它使用*通用散列*来选择使用哪个哈希函数,然后通过链接组合起来,但是这次不是使用链表数据结构,而是使用另一个哈希表。让我们看一看下面它是怎么实现的: [![2-Level Hashing](http://www.zeroequalsfalse.press/2017/02/20/hashtables/Diagram.png "2-Level Hashing")][8]
|
||||
|
||||
**但是这是如何工作的以及我们如何能够确保无需关心碰撞?**
|
||||
|
||||
它的工作方式与[生日悖论][7]相反。它指出,在随机选择的一堆人中,会有一些人生日相同。但是如果一年中的天数远远大于人数(平方以上),那么有极大的可能性所有人的生日都不相同。所以这二者是如何相关的?对于每一个链接哈希表,其大小均为第一级哈希表大小的平方。那就是说,如果有两个元素被散列到同一个点,那么链接哈希表的大小将为 4 。大多数时候,链接哈希表将会非常稀疏/空。
|
||||
|
||||
重复下面两个来确保无需担心碰撞:
|
||||
|
||||
* 从通用散列家族中选择一个哈希函数来计算
|
||||
* 如果发生碰撞,那么继续从通用散列家族中选择另一个哈希函数来计算
|
||||
|
||||
字面上看就是这样(这是一个 O(n^2) 空间的解)。如果需要考虑空间问题,那么显然需要另一个不同的方法。但是值得庆幸的是,该过程平均只需要进行**两次。**
|
||||
|
||||
### 总结
|
||||
|
||||
只有具有一个好的哈希函数才能算得上是一个好的哈希表。在同时保证功能实现、时间和空间的提前下构建一个完美的哈希函数是一件很困难的事。我推荐你在解决问题的时候首先考虑哈希表,因为它能够为你提供巨大的性能优势,而且它能够对应用程序的可用性产生显著差异。哈希表和完美的哈希函数常被用于实时编程应用中,并且在各种算法中都得到了广泛应用。你见或者不见,哈希表就在这儿。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: http://www.zeroequalsfalse.press/2017/02/20/hashtables/
|
||||
|
||||
作者:[Marty Jacobs][a]
|
||||
译者:[ucasFL](https://github.com/ucasFL)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:http://www.zeroequalsfalse.press/about
|
||||
[1]:https://en.wikipedia.org/wiki/Array_data_type
|
||||
[2]:https://en.wikipedia.org/wiki/Hash_table#Uses
|
||||
[3]:https://www.hackerearth.com/practice/basic-programming/complexity-analysis/time-and-space-complexity/tutorial/
|
||||
[4]:https://en.wikipedia.org/wiki/Hash_table#Collision_resolution
|
||||
[5]:https://en.wikipedia.org/wiki/SUHA_(computer_science
|
||||
[6]:https://en.wikipedia.org/wiki/Universal_hashing#Mathematical_guarantees
|
||||
[7]:https://en.wikipedia.org/wiki/Birthday_problem
|
||||
[8]:http://www.zeroequalsfalse.press/2017/02/20/hashtables/Diagram.png
|
@ -0,0 +1,40 @@
|
||||
OpenStack 上的 OpenShift:更好地交付应用程序
|
||||
============================================================
|
||||
|
||||
你有没有问过自己,我应该在哪里运行 OpenShift?答案是任何地方 - 它可以在裸机、虚拟机、私有云或公共云中很好地运行。但是,这里有一些原因为什么人们正迁移到围绕全栈和资源消耗自动化相关的私有云和公有云。传统的操作系统一直是关于[硬件资源的展示和消耗][2] - 硬件提供资源,应用程序消耗它们,操作系统一直是交通警察。但传统的操作系统一直局限于单机[1]。
|
||||
|
||||
那么,在原生云的世界里,现在意味着这个概念扩展到包括多个操作系统实例。这就是 OpenStack 和 OpenShift 所在。在原生云世界、虚拟机、存储卷和网段都成为动态配置的构建块。我们从这些构建块构建我们的应用程序。他们通常按时间或分钟付款,并在不再需要时被取消配置。但是,你需要将它们视为应用程序的动态配置能力。 OpenStack 在动态配置能力(展示)方面非常擅长,OpenShift 在动态配置应用程序(消费)方面很好,但是我们如何将它们结合在一起来提供一个动态的,高度可编程的多节点操作系统?
|
||||
|
||||
要理解这个,让我们来看看如果我们在传统的环境中安装 OpenShift 会发生什么 - 想像我们想要为开发者提供动态访问来创建新的应用程序,或者想象我们想要提供业务线,使其能够访问现有应用程序的新副本以满足合同义务。每个应用程序都需要访问持久存储。持久存储不是临时的,在传统的环境中,这通过提交一张工单实现。没关系,我们可以连到 OpenShift,每次需要存储时都会提交一张工单。存储管理员可以登录企业存储阵列并根据需要删除卷,然后将其移回 OpenShift 以满足应用程序。但这将是一个非常慢的手动过程,而且你可能会遇到存储管理员退出。
|
||||
|
||||
![](https://blog.openshift.com/wp-content/uploads/OpenShift-on-OpenStack-Delivering-Applications-Better-Together-Traditional-Storage-1024x615.png)
|
||||
|
||||
在原生云的世界里,我们应该将其视为一个策略驱动的自动化流程。存储管理员变得更加战略性、设置策略、配额和服务级别(银,黄金等),但实际配置变得动态。
|
||||
|
||||
![](https://blog.openshift.com/wp-content/uploads/OpenShift-on-OpenStack-Delivering-Applications-Better-Together-Cloud-Storage-1024x655.png)
|
||||
|
||||
动态过程可扩展到多个应用程序 - 这可能是开发者测试的业务线甚至新应用程序。从 10 多个应用程序到 1000 个应用程序,动态配置提供原生云体验。
|
||||
|
||||
![](https://blog.openshift.com/wp-content/uploads/OpenShift-on-OpenStack-Delivering-Applications-Better-Together-Persistent-Volume-Claims-Persistent-Volumes-Demo-1024x350.png)
|
||||
|
||||
下面的演示视频展示了动态存储配置如何与 Red Hat OpenStack 平台(Cinder 卷)以及 Red Hat OpenShift 容器平台配合使用,但动态配置并不限于存储。想象一下,随着 OpenShift 的一个实例需要更多的容量,节点自动扩展的环境。想象一下,推送一个敏感的程序更改前,将网段划分为负载测试 OpenShift 的特定实例。这些是你为何需要动态配置 IT 构建块的原因。OpenStack 实际上是以 API 驱动的方式实现的。
|
||||
|
||||
[YOUTUBE VIDEO](https://youtu.be/PfWmAS9Fc7I)
|
||||
|
||||
OpenShift 和 OpenStack 一起更好地交付应用程序。OpenStack 动态提供资源,而 OpenShift 会动态地消耗它们。它们一起为你所有的容器和虚拟机需求提供灵活的原生云解决方案。
|
||||
|
||||
[1]高可用性集群和一些专门的操作系统在一定程度上弥合了这一差距,但在计算中通常是一个边缘情况。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://blog.openshift.com/openshift-on-openstack-delivering-applications-better-together/
|
||||
|
||||
作者:[SCOTT MCCARTY ][a]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:https://blog.openshift.com/author/smccartyredhat-com/
|
||||
[1]:https://blog.openshift.com/author/smccartyredhat-com/
|
||||
[2]:https://docs.google.com/presentation/d/139_dxpiYc5JR8yKAP8pl-FcZmOFQCuV8RyDxZqOOcVE/edit
|
@ -1,21 +1,19 @@
|
||||
Translating by firmianay
|
||||
|
||||
Half a dozen clever Linux command line tricks
|
||||
六个聪明的 Linux 命令行技巧
|
||||
============================================================
|
||||
|
||||
### Some very useful commands for making life on the command line more rewarding
|
||||
### 一些有用的命令能让命令行上的生命更有价值
|
||||
|
||||
![command key keyboard](https://images.idgesg.net/images/article/2017/08/commands-micah_elizabeth_scott-cropped-100733439-large.jpg)
|
||||
[Micah Elizabeth Scott][32] [(CC BY 2.0)][33]RELATED
|
||||
|
||||
|
||||
Working on the Linux command can be a lot of fun, but it can be even more fun when you use commands that take less work on your part or display information in interesting and useful ways. In today’s post, we’re going to look at half a dozen commands that might make your time on the command line more profitable.
|
||||
使用 Linux 命令工作可以获得许多乐趣,但是如果您使用一些命令,它们可以减少您的工作或以有趣的方式显示信息时,您将获得更多的乐趣。在今天的文章中,我们将介绍六个命令,它们可能会使你用在命令行上的时间更加值当。
|
||||
|
||||
### watch
|
||||
|
||||
The watch command will repeatedly run whatever command you give it and show you the output. By default, it runs the command every two seconds. Each successive running of the command overwrites what it displayed on the previous run, so you're always looking at the latest data.
|
||||
watch 命令会重复运行您给出的任何命令,并显示输出。默认情况下,它每两秒运行一次命令。命令的每次运行都将覆盖上一次运行时显示的内容,因此您始终可以看到最新的数据。
|
||||
|
||||
You might use it when you’re waiting for someone to log in. In this case, you would use the command “watch who” or maybe “watch -n 15 who” to have the command run every 15 seconds instead of every two seconds. The date and time will appear in the upper right-hand corner of your terminal window.
|
||||
您可能会在等待某人登录时使用它。在这种情况下,您可以使用 “watch who” 命令或者 “watch -n 15 who” 命令使每次运行的时间变为 15 秒,而不是两秒。另外终端窗口的右上角会显示日期和时间。
|
||||
|
||||
```
|
||||
$ watch -n 5 who
|
||||
@ -25,8 +23,7 @@ shs pts/0 2017-08-23 14:45 (192.168.0.11)
|
||||
zoe pts/1 2017-08-23 08:15 (192.168.0.19)
|
||||
```
|
||||
|
||||
You might also use it to watch a log file. If nothing changes in the data you’re displaying, only the date/time display in the corner of the window will change.
|
||||
|
||||
您也可以使用它来查看日志文件。如果您显示的数据没有任何变化,则只有窗口角落里的日期和时间会发生变化。
|
||||
|
||||
|
||||
```
|
||||
@ -50,11 +47,11 @@ Aug 23 15:15:01 stinkbug CRON[7828]: (root) CMD (command -v debian-sa1 > /dev/nu
|
||||
ll && debian-sa1 1 1)
|
||||
```
|
||||
|
||||
This output is similar to what you’d see using tail -f /var/log/syslog.
|
||||
这里的输出和使用命令 “tail -f /var/log/syslog” 的输出相似。
|
||||
|
||||
### look
|
||||
|
||||
The name might suggest that look does something similar to watch, but it’s entirely different. The look command searches for words that begin with some particular string.
|
||||
这个命令的名字 look 可能会让我们以为它和 watch 做类似的事情,但其实是不同的。look 命令用于搜索以某个特定字符串开头的单词。
|
||||
|
||||
```
|
||||
$ look ecl
|
||||
@ -73,7 +70,7 @@ ecliptic
|
||||
ecliptic's
|
||||
```
|
||||
|
||||
The look command is generally helpful with spelling and used the /usr/share/dict/words file unless you specify a file name with a command like this one:
|
||||
look 命令通常有助于单词的拼写,它使用 /usr/share/dict/words 文件,除非你使用如下的命令指定了文件名:
|
||||
|
||||
```
|
||||
$ look esac .bashrc
|
||||
@ -82,12 +79,12 @@ esac
|
||||
esac
|
||||
```
|
||||
|
||||
In this case, it acts like grep following by an awk command that prints only the first word on the matching lines.
|
||||
在这种情况下,它的作用就像跟在一个 awk 命令后面的 grep ,只打印匹配行上的第一个单词。
|
||||
|
||||
|
||||
### man -k
|
||||
|
||||
The man -k command lists man pages that include the specified word. It basically works like the apropos command.
|
||||
man -k 命令列出包含指定单词的手册页。它的工作基本上和 apropos 命令一样。
|
||||
|
||||
```
|
||||
$ man -k logrotate
|
||||
@ -98,7 +95,7 @@ logrotate.conf (5) - rotates, compresses, and mails system logs
|
||||
|
||||
### help
|
||||
|
||||
While you may be tempted to use this command when you’re utterly frustrated, what the help command actually does is show you a list of shell built-ins. What’s most surprising is how many of these variables exist. You’re likely to see something like this and then start to wonder what all of these built-ins might do for you:
|
||||
当你完全绝望的时候,您可能会试图使用此命令,help 命令实际上是显示一个 shell 内置的列表。最令人惊讶的是它相当多的参数变量。你可能会看到这样的东西,然后开始想知道这些内置功能可以为你做些什么:
|
||||
|
||||
```
|
||||
$ help
|
||||
@ -152,7 +149,7 @@ A star (*) next to a name means that the command is disabled.
|
||||
|
||||
### stat -c
|
||||
|
||||
The stat command displays the vital statistics for a file — its size, owner, group, inode number, permissions, modification and access times. It’s a very useful command that displays more detail than a simple ls -l.
|
||||
stat 命令用于显示文件的大小、所有者、组、索引节点号、权限、修改和访问时间等重要的统计信息。这是一个非常有用的命令,可以显示比 ls -l 更多的细节。
|
||||
|
||||
```
|
||||
$ stat .bashrc
|
||||
@ -166,14 +163,14 @@ Change: 2017-06-21 17:37:11.899157791 -0400
|
||||
Birth: -
|
||||
```
|
||||
|
||||
With the -c option, you can specify the fields you want to see. If, for example, you want to see just the file name and access rights for a file or series of files, you might do this:
|
||||
使用 -c 选项,您可以指定要查看的字段。例如,如果您只想查看一个文件或一系列文件的文件名和访问权限,则可以这样做:
|
||||
|
||||
```
|
||||
$ stat -c '%n %a' .bashrc
|
||||
.bashrc 644
|
||||
```
|
||||
|
||||
In this command, the %n represents the name of each file, while %a represents the access rights. A %u would be the numeric UID and %U the username.
|
||||
在此命令中, %n 表示每个文件的名称,而 %a 表示访问权限。一个 %u 表示数字类型的 UID,并且 %U 表示用户名。
|
||||
|
||||
```
|
||||
$ stat -c '%n %a' bin/*
|
||||
@ -191,7 +188,7 @@ bin/show_release 700 shs
|
||||
|
||||
### TAB
|
||||
|
||||
If you’re not using the tab command for filename completion, you’re really missing out on a very useful command line trick. The tab command provides filename completion (including directories when you’re using cd). It fills in as much of a name as possible before it hits an ambiguity (more than one file starting with the same letters. If you have a file named bigplans and another named bigplans2017, you’ll hear a sound and have to decide whether to press enter or “2” and tab again to select the second file.
|
||||
如果你没有使用过 tab 命令来补全文件名,你真的错过了一个非常有用的命令行技巧。tab 命令提供文件名补全功能(包括使用 cd 时的目录)。它在出现歧义之前尽可能多的填充文件名(多个文件以相同的字母开头。如果您有一个名为 bigplans 的文件,另一个名为 bigplans2017 的文件会发生歧义,你必须决定是按下回车键还是输入 “2” 之后再按下 tab 键选择第二个文件。
|
||||
|
||||
Join the Network World communities on [Facebook][30] and [LinkedIn][31] to comment on topics that are top of mind.
|
||||
|
||||
@ -200,7 +197,7 @@ Join the Network World communities on [Facebook][30] and [LinkedIn][31] to c
|
||||
via: https://www.networkworld.com/article/3219684/linux/half-a-dozen-clever-linux-command-line-tricks.html
|
||||
|
||||
作者:[ Sandra Henry-Stocker][a]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
译者:[firmianay](https://github.com/firmianay)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
Loading…
Reference in New Issue
Block a user