Merge remote-tracking branch 'lctt/master'

This commit is contained in:
belitex
2018-10-15 17:14:27 +08:00
82 changed files with 6290 additions and 2892 deletions

View File

@@ -1,11 +1,10 @@
五种加速 Go 的特性
============================================================
========
_Anthony Starks 使用他出色的 Deck 演示工具重构了我原来的基于 Google Slides 的幻灯片。你可以在他的博客上查看他重构后的幻灯片, [mindchunk.blogspot.com.au/2014/06/remixing-with-deck][5]._
_Anthony Starks 使用他出色的 Deck 演示工具重构了我原来的基于 Google Slides 的幻灯片。你可以在他的博客上查看他重构后的幻灯片,
[mindchunk.blogspot.com.au/2014/06/remixing-with-deck][5]。_
* * *
我最近被邀请在 Gocon 发表演讲,这是一个每半年在日本东京举行的精彩 Go 的大会。[Gocon 2014][6] 是一个完全由社区驱动的为期一天的活动,由培训和一整个下午的围绕着 <q style="border: 0px; vertical-align: baseline; quotes: none;">生产环境中的 Go</q> 这个主题的演讲组成.
我最近被邀请在 Gocon 发表演讲,这是一个每半年在日本东京举行的 Go 的精彩大会。[Gocon 2014][6] 是一个完全由社区驱动的为期一天的活动,由培训和一整个下午的围绕着生产环境中的 Go</q> 这个主题的演讲组成.LCTT 译注:本文发表于 2014 年)
以下是我的讲义。原文的结构能让我缓慢而清晰的演讲,因此我已经编辑了它使其更可读。
@@ -19,14 +18,16 @@
我很高兴今天能来到 Gocon。我想参加这个会议已经两年了我很感谢主办方能提供给我向你们演讲的机会。
[![Gocon 2014](https://dave.cheney.net/wp-content/uploads/2014/06/Gocon-2014-1.jpg)][9]
[![Gocon 2014](https://dave.cheney.net/wp-content/uploads/2014/06/Gocon-2014-1.jpg)][9]
我想以一个问题开始我的演讲。
为什么选择 Go
当大家讨论学习或在生产环境中使用 Go 的原因时,答案不一而足,但因为以下三个原因的最多。
[![Gocon 2014 ](https://dave.cheney.net/wp-content/uploads/2014/06/Gocon-2014-2.jpg)][10]
[![Gocon 2014 ](https://dave.cheney.net/wp-content/uploads/2014/06/Gocon-2014-2.jpg)][10]
这就是 TOP3 的原因。
第一,并发。
@@ -37,29 +38,29 @@ Go 的 <ruby>并发原语<rt>Concurrency Primitives</rt></ruby> 对于来自 Nod
我们今天从经验丰富的 Gophers 那里听说过,他们非常欣赏部署 Go 应用的简单性。
[![Gocon 2014](https://dave.cheney.net/wp-content/uploads/2014/06/Gocon-2014-3.jpg)][11]
[![Gocon 2014](https://dave.cheney.net/wp-content/uploads/2014/06/Gocon-2014-3.jpg)][11]
然后是性能。
我相信人们选择 Go 的一个重要原因是它 __
[![Gocon 2014 (4)](https://dave.cheney.net/wp-content/uploads/2014/06/Gocon-2014-4.jpg)][12]
[![Gocon 2014 (4)](https://dave.cheney.net/wp-content/uploads/2014/06/Gocon-2014-4.jpg)][12]
在今天的演讲中,我想讨论五个有助于提高 Go 性能的特性。
我还将与大家分享 Go 如何实现这些特性的细节。
[![Gocon 2014 (5)](https://dave.cheney.net/wp-content/uploads/2014/06/Gocon-2014-5.jpg)][13]
[![Gocon 2014 (5)](https://dave.cheney.net/wp-content/uploads/2014/06/Gocon-2014-5.jpg)][13]
我要谈的第一个特性是 Go 对于值的高效处理和存储。
[![Gocon 2014 (6)](https://dave.cheney.net/wp-content/uploads/2014/06/Gocon-2014-6.jpg)][14]
[![Gocon 2014 (6)](https://dave.cheney.net/wp-content/uploads/2014/06/Gocon-2014-6.jpg)][14]
这是 Go 中一个值的例子。编译时,`gocon` 正好消耗四个字节的内存。
让我们将 Go 与其他一些语言进行比较
[![Gocon 2014 (7)](https://dave.cheney.net/wp-content/uploads/2014/06/Gocon-2014-7.jpg)][15]
[![Gocon 2014 (7)](https://dave.cheney.net/wp-content/uploads/2014/06/Gocon-2014-7.jpg)][15]
由于 Python 表示变量的方式的开销,使用 Python 存储相同的值会消耗六倍的内存。
@@ -67,19 +68,19 @@ Python 使用额外的内存来跟踪类型信息,进行 <ruby>引用计数<rt
让我们看另一个例子:
[![Gocon 2014 (8)](https://dave.cheney.net/wp-content/uploads/2014/06/Gocon-2014-8.jpg)][16]
[![Gocon 2014 (8)](https://dave.cheney.net/wp-content/uploads/2014/06/Gocon-2014-8.jpg)][16]
与 Go 类似Java 消耗 4 个字节的内存来存储 `int` 型。
但是,要在像 `List``Map` 这样的集合中使用此值,编译器必须将其转换为 `Integer` 对象。
[![Gocon 2014 (9)](https://dave.cheney.net/wp-content/uploads/2014/06/Gocon-2014-9.jpg)][17]
[![Gocon 2014 (9)](https://dave.cheney.net/wp-content/uploads/2014/06/Gocon-2014-9.jpg)][17]
因此Java 中的整数通常消耗 16 到 24 个字节的内存。
为什么这很重要? 内存便宜且充足,为什么这个开销很重要?
[![Gocon 2014 (10)](https://dave.cheney.net/wp-content/uploads/2014/06/Gocon-2014-10.jpg)][18]
[![Gocon 2014 (10)](https://dave.cheney.net/wp-content/uploads/2014/06/Gocon-2014-10.jpg)][18]
这是一张显示 CPU 时钟速度与内存总线速度的图表。
@@ -87,13 +88,13 @@ Python 使用额外的内存来跟踪类型信息,进行 <ruby>引用计数<rt
两者之间的差异实际上是 CPU 花费多少时间等待内存。
[![Gocon 2014 (11)](https://dave.cheney.net/wp-content/uploads/2014/06/Gocon-2014-11.jpg)][19]
[![Gocon 2014 (11)](https://dave.cheney.net/wp-content/uploads/2014/06/Gocon-2014-11.jpg)][19]
自 1960 年代后期以来CPU 设计师已经意识到了这个问题。
他们的解决方案是一个缓存,一个更小更快的内存区域,介入 CPU 和主存之间。
他们的解决方案是一个缓存,一个更小更快的内存区域,介入 CPU 和主存之间。
[![Gocon 2014 (12)](https://dave.cheney.net/wp-content/uploads/2014/06/Gocon-2014-12.jpg)][20]
[![Gocon 2014 (12)](https://dave.cheney.net/wp-content/uploads/2014/06/Gocon-2014-12.jpg)][20]
这是一个 `Location` 类型,它保存物体在三维空间中的位置。它是用 Go 编写的,因此每个 `Location` 只消耗 24 个字节的存储空间。
@@ -103,7 +104,7 @@ Python 使用额外的内存来跟踪类型信息,进行 <ruby>引用计数<rt
这很重要,因为现在所有 1000 个 `Location` 结构体都按顺序放在缓存中,紧密排列在一起。
[![Gocon 2014 (13)](https://dave.cheney.net/wp-content/uploads/2014/06/Gocon-2014-13.jpg)][21]
[![Gocon 2014 (13)](https://dave.cheney.net/wp-content/uploads/2014/06/Gocon-2014-13.jpg)][21]
Go 允许您创建紧凑的数据结构,避免不必要的填充字节。
@@ -111,11 +112,11 @@ Go 允许您创建紧凑的数据结构,避免不必要的填充字节。
更好的缓存利用率可带来更好的性能。
[![Gocon 2014 (14)](https://dave.cheney.net/wp-content/uploads/2014/06/Gocon-2014-14.jpg)][22]
[![Gocon 2014 (14)](https://dave.cheney.net/wp-content/uploads/2014/06/Gocon-2014-14.jpg)][22]
函数调用不是无开销的。
[![Gocon 2014 (15)](https://dave.cheney.net/wp-content/uploads/2014/06/Gocon-2014-15.jpg)][23]
[![Gocon 2014 (15)](https://dave.cheney.net/wp-content/uploads/2014/06/Gocon-2014-15.jpg)][23]
调用函数时会发生三件事。
@@ -125,7 +126,7 @@ Go 允许您创建紧凑的数据结构,避免不必要的填充字节。
处理器计算函数的地址并执行到该新地址的分支。
[![Gocon 2014 (16)](https://dave.cheney.net/wp-content/uploads/2014/06/Gocon-2014-16.jpg)][24]
[![Gocon 2014 (16)](https://dave.cheney.net/wp-content/uploads/2014/06/Gocon-2014-16.jpg)][24]
由于函数调用是非常常见的操作,因此 CPU 设计师一直在努力优化此过程,但他们无法消除开销。
@@ -133,7 +134,7 @@ Go 允许您创建紧凑的数据结构,避免不必要的填充字节。
减少函数调用开销的解决方案是 <ruby>内联<rt>Inlining</rt></ruby>。
[![Gocon 2014 (17)](https://dave.cheney.net/wp-content/uploads/2014/06/Gocon-2014-17.jpg)][25]
[![Gocon 2014 (17)](https://dave.cheney.net/wp-content/uploads/2014/06/Gocon-2014-17.jpg)][25]
Go 编译器通过将函数体视为调用者的一部分来内联函数。
@@ -143,13 +144,13 @@ Go 编译器通过将函数体视为调用者的一部分来内联函数。
复杂的函数通常不受调用它们的开销所支配,因此不会内联。
[![Gocon 2014 (18)](https://dave.cheney.net/wp-content/uploads/2014/06/Gocon-2014-18.jpg)][26]
[![Gocon 2014 (18)](https://dave.cheney.net/wp-content/uploads/2014/06/Gocon-2014-18.jpg)][26]
这个例子显示函数 `Double` 调用 `util.Max`
为了减少调用 `util.Max` 的开销,编译器可以将 `util.Max` 内联到 `Double` 中,就象这样
[![Gocon 2014 (19)](https://dave.cheney.net/wp-content/uploads/2014/06/Gocon-2014-19.jpg)][27]
[![Gocon 2014 (19)](https://dave.cheney.net/wp-content/uploads/2014/06/Gocon-2014-19.jpg)][27]
内联后不再调用 `util.Max`,但是 `Double` 的行为没有改变。
@@ -159,7 +160,7 @@ Go 实现非常简单。编译包时,会标记任何适合内联的小函数
然后函数的源代码和编译后版本都会被存储。
[![Gocon 2014 (20)](https://dave.cheney.net/wp-content/uploads/2014/06/Gocon-2014-20.jpg)][28]
[![Gocon 2014 (20)](https://dave.cheney.net/wp-content/uploads/2014/06/Gocon-2014-20.jpg)][28]
此幻灯片显示了 `util.a` 的内容。源代码已经过一些转换,以便编译器更容易快速处理。
@@ -169,13 +170,13 @@ Go 实现非常简单。编译包时,会标记任何适合内联的小函数
拥有该函数的源代码可以实现其他优化。
[![Gocon 2014 (21)](https://dave.cheney.net/wp-content/uploads/2014/06/Gocon-2014-21.jpg)][29]
[![Gocon 2014 (21)](https://dave.cheney.net/wp-content/uploads/2014/06/Gocon-2014-21.jpg)][29]
在这个例子中,尽管函数 `Test` 总是返回 `false`,但 `Expensive` 在不执行它的情况下无法知道结果。
`Test` 被内联时,我们得到这样的东西
`Test` 被内联时,我们得到这样的东西
[![Gocon 2014 (22)](https://dave.cheney.net/wp-content/uploads/2014/06/Gocon-2014-22.jpg)][30]
[![Gocon 2014 (22)](https://dave.cheney.net/wp-content/uploads/2014/06/Gocon-2014-22.jpg)][30]
编译器现在知道 `Expensive` 的代码无法访问。
@@ -183,7 +184,7 @@ Go 实现非常简单。编译包时,会标记任何适合内联的小函数
Go 编译器可以跨文件甚至跨包自动内联函数。还包括从标准库调用的可内联函数的代码。
[![Gocon 2014 (23)](https://dave.cheney.net/wp-content/uploads/2014/06/Gocon-2014-23.jpg)][31]
[![Gocon 2014 (23)](https://dave.cheney.net/wp-content/uploads/2014/06/Gocon-2014-23.jpg)][31]
<ruby>强制垃圾回收<rt>Mandatory Garbage Collection</rt></ruby> 使 Go 成为一种更简单,更安全的语言。
@@ -191,13 +192,13 @@ Go 编译器可以跨文件甚至跨包自动内联函数。还包括从标准
这意味着在堆上分配的内存是有代价的。每次 GC 运行时都会花费 CPU 时间,直到释放内存为止。
[![Gocon 2014 (24)](https://dave.cheney.net/wp-content/uploads/2014/06/Gocon-2014-24.jpg)][32]
[![Gocon 2014 (24)](https://dave.cheney.net/wp-content/uploads/2014/06/Gocon-2014-24.jpg)][32]
然而,有另一个地方分配内存,那就是栈。
与 C 不同,它强制您选择是否将值通过 `malloc` 将其存储在堆上还是通过在函数范围内声明将其储存在栈上Go 实现了一个名为 <ruby>逃逸分析<rt>Escape Analysis</rt></ruby> 的优化。
[![Gocon 2014 (25)](https://dave.cheney.net/wp-content/uploads/2014/06/Gocon-2014-25.jpg)][33]
[![Gocon 2014 (25)](https://dave.cheney.net/wp-content/uploads/2014/06/Gocon-2014-25.jpg)][33]
逃逸分析决定了对一个值的任何引用是否会从被声明的函数中逃逸。
@@ -207,7 +208,7 @@ Go 编译器可以跨文件甚至跨包自动内联函数。还包括从标准
让我们看一些例子
[![Gocon 2014 (26)](https://dave.cheney.net/wp-content/uploads/2014/06/Gocon-2014-26.jpg)][34]
[![Gocon 2014 (26)](https://dave.cheney.net/wp-content/uploads/2014/06/Gocon-2014-26.jpg)][34]
`Sum` 返回 1 到 100 的整数的和。这是一种相当不寻常的做法,但它说明了逃逸分析的工作原理。
@@ -215,7 +216,7 @@ Go 编译器可以跨文件甚至跨包自动内联函数。还包括从标准
没有必要回收 `numbers`,它会在 `Sum` 返回时自动释放。
[![Gocon 2014 (27)](https://dave.cheney.net/wp-content/uploads/2014/06/Gocon-2014-27.jpg)][35]
[![Gocon 2014 (27)](https://dave.cheney.net/wp-content/uploads/2014/06/Gocon-2014-27.jpg)][35]
第二个例子也有点尬。在 `CenterCursor` 中,我们创建一个新的 `Cursor` 对象并在 `c` 中存储指向它的指针。
@@ -225,7 +226,7 @@ Go 编译器可以跨文件甚至跨包自动内联函数。还包括从标准
即使 `c``new` 函数分配了空间,它也不会存储在堆上,因为没有引用 `c` 的变量逃逸 `CenterCursor` 函数。
[![Gocon 2014 (28)](https://dave.cheney.net/wp-content/uploads/2014/06/Gocon-2014-28.jpg)][36]
[![Gocon 2014 (28)](https://dave.cheney.net/wp-content/uploads/2014/06/Gocon-2014-28.jpg)][36]
默认情况下Go 的优化始终处于启用状态。可以使用 `-gcflags = -m` 开关查看编译器的逃逸分析和内联决策。
@@ -233,11 +234,11 @@ Go 编译器可以跨文件甚至跨包自动内联函数。还包括从标准
我将在本演讲的其余部分详细讨论栈。
[![Gocon 2014 (30)](https://dave.cheney.net/wp-content/uploads/2014/06/Gocon-2014-30.jpg)][37]
[![Gocon 2014 (30)](https://dave.cheney.net/wp-content/uploads/2014/06/Gocon-2014-30.jpg)][37]
Go 有 goroutines。 这是 Go 并发的基石。
Go 有 goroutine。 这是 Go 并发的基石。
我想退一步,探索 goroutines 的历史。
我想退一步,探索 goroutine 的历史。
最初,计算机一次运行一个进程。在 60 年代,多进程或 <ruby>分时<rt>Time Sharing</rt></ruby> 的想法变得流行起来。
@@ -245,7 +246,7 @@ Go 有 goroutines。 这是 Go 并发的基石。
这称为 _进程切换_
[![Gocon 2014 (29)](https://dave.cheney.net/wp-content/uploads/2014/06/Gocon-2014-29.jpg)][38]
[![Gocon 2014 (29)](https://dave.cheney.net/wp-content/uploads/2014/06/Gocon-2014-29.jpg)][38]
进程切换有三个主要开销。
@@ -255,44 +256,41 @@ Go 有 goroutines。 这是 Go 并发的基石。
最后是操作系统 <ruby>上下文切换<rt>Context Switch</rt></ruby> 的成本,以及 <ruby>调度函数<rt>Scheduler Function</rt></ruby> 选择占用 CPU 的下一个进程的开销。
[![Gocon 2014 (31)](https://dave.cheney.net/wp-content/uploads/2014/06/Gocon-2014-31.jpg)][39]
[![Gocon 2014 (31)](https://dave.cheney.net/wp-content/uploads/2014/06/Gocon-2014-31.jpg)][39]
现代处理器中有数量惊人的寄存器。我很难在一张幻灯片上排开它们,这可以让你知道保护和恢复它们需要多少时间。
由于进程切换可以在进程执行的任何时刻发生,因此操作系统需要存储所有寄存器的内容,因为它不知道当前正在使用哪些寄存器。
[![Gocon 2014 (32)](https://dave.cheney.net/wp-content/uploads/2014/06/Gocon-2014-32.jpg)][40]
[![Gocon 2014 (32)](https://dave.cheney.net/wp-content/uploads/2014/06/Gocon-2014-32.jpg)][40]
这导致了线程的出生,这些线程在概念上与进程相同,但共享相同的内存空间。
由于线程共享地址空间,因此它们比进程更轻,因此创建速度更快,切换速度更快。
[![Gocon 2014 (33)](https://dave.cheney.net/wp-content/uploads/2014/06/Gocon-2014-33.jpg)][41]
[![Gocon 2014 (33)](https://dave.cheney.net/wp-content/uploads/2014/06/Gocon-2014-33.jpg)][41]
Goroutines 升华了线程的思想。
Goroutine 升华了线程的思想。
Goroutines 是 <ruby>协作式调度<rt>Cooperative Scheduled
Goroutine 是 <ruby>协作式调度<rt>Cooperative Scheduled
</rt></ruby>的,而不是依靠内核来调度。
当对 Go <ruby>运行时调度器<rt>Runtime Scheduler</rt></ruby> 进行显式调用时goroutine 之间的切换仅发生在明确定义的点上。
编译器知道正在使用的寄存器并自动保存它们。
[![Gocon 2014 (34)](https://dave.cheney.net/wp-content/uploads/2014/06/Gocon-2014-34.jpg)][42]
[![Gocon 2014 (34)](https://dave.cheney.net/wp-content/uploads/2014/06/Gocon-2014-34.jpg)][42]
虽然 goroutine 是协作式调度的,但运行时会为你处理。
Goroutines 可能会给禅让给其他协程时刻是:
Goroutine 可能会给禅让给其他协程时刻是:
* 阻塞式通道发送和接收。
* Go 声明,虽然不能保证会立即调度新的 goroutine。
* 文件和网络操作式的阻塞式系统调用。
* 在被垃圾回收循环停止后。
[![Gocon 2014 (35)](https://dave.cheney.net/wp-content/uploads/2014/06/Gocon-2014-35.jpg)][43]
[![Gocon 2014 (35)](https://dave.cheney.net/wp-content/uploads/2014/06/Gocon-2014-35.jpg)][43]
这个例子说明了上一张幻灯片中描述的一些调度点。
@@ -304,7 +302,7 @@ Goroutines 可能会给禅让给其他协程时刻是:
最后,当 `Read` 操作完成并且数据可用时,线程切换回左侧。
[![Gocon 2014 (36)](https://dave.cheney.net/wp-content/uploads/2014/06/Gocon-2014-36.jpg)][44]
[![Gocon 2014 (36)](https://dave.cheney.net/wp-content/uploads/2014/06/Gocon-2014-36.jpg)][44]
这张幻灯片显示了低级语言描述的 `runtime.Syscall` 函数,它是 `os` 包中所有函数的基础。
@@ -316,13 +314,13 @@ Goroutines 可能会给禅让给其他协程时刻是:
这导致每 Go 进程的操作系统线程相对较少Go 运行时负责将可运行的 Goroutine 分配给空闲的操作系统线程。
[![Gocon 2014 (37)](https://dave.cheney.net/wp-content/uploads/2014/06/Gocon-2014-37.jpg)][45]
[![Gocon 2014 (37)](https://dave.cheney.net/wp-content/uploads/2014/06/Gocon-2014-37.jpg)][45]
在上一节中,我讨论了 goroutine 如何减少管理许多(有时是数十万个并发执行线程)的开销。
Goroutine故事还有另一面那就是栈管理它引导我进入我的最后一个话题。
[![Gocon 2014 (39)](https://dave.cheney.net/wp-content/uploads/2014/06/Gocon-2014-39.jpg)][46]
[![Gocon 2014 (39)](https://dave.cheney.net/wp-content/uploads/2014/06/Gocon-2014-39.jpg)][46]
这是一个进程的内存布局图。我们感兴趣的关键是堆和栈的位置。
@@ -330,13 +328,13 @@ Goroutine故事还有另一面那就是栈管理它引导我进入我的
栈位于虚拟地址空间的顶部,并向下增长。
[![Gocon 2014 (40)](https://dave.cheney.net/wp-content/uploads/2014/06/Gocon-2014-40.jpg)][47]
[![Gocon 2014 (40)](https://dave.cheney.net/wp-content/uploads/2014/06/Gocon-2014-40.jpg)][47]
因为堆和栈相互覆盖的结果会是灾难性的,操作系统通常会安排在栈和堆之间放置一个不可写内存区域,以确保如果它们发生碰撞,程序将中止。
这称为保护页,有效地限制了进程的栈大小,通常大约为几兆字节。
[![Gocon 2014 (41)](https://dave.cheney.net/wp-content/uploads/2014/06/Gocon-2014-41.jpg)][48]
[![Gocon 2014 (41)](https://dave.cheney.net/wp-content/uploads/2014/06/Gocon-2014-41.jpg)][48]
我们已经讨论过线程共享相同的地址空间,因此对于每个线程,它必须有自己的栈。
@@ -346,7 +344,7 @@ Goroutine故事还有另一面那就是栈管理它引导我进入我的
缺点是随着程序中线程数的增加,可用地址空间的数量会减少。
[![Gocon 2014 (42)](https://dave.cheney.net/wp-content/uploads/2014/06/Gocon-2014-42.jpg)][49]
[![Gocon 2014 (42)](https://dave.cheney.net/wp-content/uploads/2014/06/Gocon-2014-42.jpg)][49]
我们已经看到 Go 运行时将大量的 goroutine 调度到少量线程上,但那些 goroutines 的栈需求呢?
@@ -354,13 +352,13 @@ Go 编译器不使用保护页,而是在每个函数调用时插入一个检
由于这种检查goroutines 初始栈可以做得更小,这反过来允许 Go 程序员将 goroutines 视为廉价资源。
[![Gocon 2014 (43)](https://dave.cheney.net/wp-content/uploads/2014/06/Gocon-2014-43.jpg)][50]
[![Gocon 2014 (43)](https://dave.cheney.net/wp-content/uploads/2014/06/Gocon-2014-43.jpg)][50]
这是一张显示了 Go 1.2 如何管理栈的幻灯片。
`G` 调用 `H` 时,没有足够的空间让 `H` 运行,所以运行时从堆中分配一个新的栈帧,然后在新的栈段上运行 `H`。当 `H` 返回时,栈区域返回到堆,然后返回到 `G`
[![Gocon 2014 (44)](https://dave.cheney.net/wp-content/uploads/2014/06/Gocon-2014-44.jpg)][51]
[![Gocon 2014 (44)](https://dave.cheney.net/wp-content/uploads/2014/06/Gocon-2014-44.jpg)][51]
这种管理栈的方法通常很好用,但对于某些类型的代码,通常是递归代码,它可能导致程序的内部循环跨越这些栈边界之一。
@@ -368,7 +366,7 @@ Go 编译器不使用保护页,而是在每个函数调用时插入一个检
每次都会导致栈拆分。 这被称为 <ruby>热分裂<rt>Hot Split</rt></ruby> 问题。
[![Gocon 2014 (45)](https://dave.cheney.net/wp-content/uploads/2014/06/Gocon-2014-45.jpg)][52]
[![Gocon 2014 (45)](https://dave.cheney.net/wp-content/uploads/2014/06/Gocon-2014-45.jpg)][52]
为了解决热分裂问题Go 1.3 采用了一种新的栈管理方法。
@@ -380,7 +378,7 @@ Go 编译器不使用保护页,而是在每个函数调用时插入一个检
这解决了热分裂问题。
[![Gocon 2014 (46)](https://dave.cheney.net/wp-content/uploads/2014/06/Gocon-2014-46.jpg)][53]
[![Gocon 2014 (46)](https://dave.cheney.net/wp-content/uploads/2014/06/Gocon-2014-46.jpg)][53]
内联逃逸分析Goroutines 和分段/复制栈。
@@ -398,7 +396,7 @@ Go 编译器不使用保护页,而是在每个函数调用时插入一个检
如果没有可增长的栈,逃逸分析可能会对栈施加太大的压力。
[![Gocon 2014 (47)](https://dave.cheney.net/wp-content/uploads/2014/06/Gocon-2014-47.jpg)][54]
[![Gocon 2014 (47)](https://dave.cheney.net/wp-content/uploads/2014/06/Gocon-2014-47.jpg)][54]
* 感谢 Gocon 主办方允许我今天发言
* twitter / web / email details
@@ -407,11 +405,8 @@ Go 编译器不使用保护页,而是在每个函数调用时插入一个检
### 相关文章:
1. [听我在 OSCON 上关于 Go 性能的演讲][1]
2. [为什么 Goroutine 的栈是无限大的?][2]
3. [Go 的运行时环境变量的旋风之旅][3]
4. [没有事件循环的性能][4]
--------------------------------------------------------------------------------
@@ -431,9 +426,9 @@ David 是来自澳大利亚悉尼的程序员和作者。
via: https://dave.cheney.net/2014/06/07/five-things-that-make-go-fast
作者:[Dave Cheney ][a]
作者:[Dave Cheney][a]
译者:[houbaron](https://github.com/houbaron)
校对:[校对者ID](https://github.com/校对者ID)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出

View File

@@ -1,14 +1,15 @@
三周内构建 JavaScript 全栈 web 应用
============================================================
===========
![](https://cdn-images-1.medium.com/max/2000/1*PgKBpQHRUgqpXcxtyehPZg.png)
应用 Align 中,用户主页的控制面板
*应用 Align 中,用户主页的控制面板*
### 从构思到部署应用程序的简单分步指南
我在 Grace Hopper Program 为期三个月的编码训练营即将结束,实际上这篇文章的标题有些纰漏 —— 现在我已经构建了 _三个_ 全栈应用:[从零开始的电子商店an e-commerce store from scratch][3]、我个人的 [私人黑客马拉松项目personal hackathon project][4],还有这个“三周的结业项目”。这个项目是迄今为止强度最大的 —— 我和另外两名队友共同花费三周的时光 —— 而它也是我在训练营中最引以为豪的成就。这是我目前所构建和涉及的第一款稳定且复杂的应用。
我在 Grace Hopper Program 为期三个月的编码训练营即将结束,实际上这篇文章的标题有些纰漏 —— 现在我已经构建了 _三个_ 全栈应用:[从零开始的电子商店][3]、我个人的 [私人黑客马拉松项目][4],还有这个“三周的结业项目”。这个项目是迄今为止强度最大的 —— 我和另外两名队友共同花费三周的时光 —— 而它也是我在训练营中最引以为豪的成就。这是我目前所构建和涉及的第一款稳定且复杂的应用。
如大多数开发者所知即使你“知道怎么编写代码”但真正要制作第一款全栈的应用却是非常困难的。JavaScript 生态系统出奇的大:有包管理器模块构建工具转译器数据库库文件,还要对上述所有东西进行选择,难怪如此多的编程新手除了 Codecademy 的教程外,做不了任何东西。这就是为什么我想让你体验这个决策的分布教程,跟着我们队伍的脚印,构建可用的应用。
如大多数开发者所知即使你“知道怎么编写代码”但真正要制作第一款全栈的应用却是非常困难的。JavaScript 生态系统出奇的大:有包管理器模块构建工具转译器数据库库文件,还要对上述所有东西进行选择,难怪如此多的编程新手除了 Codecademy 的教程外,做不了任何东西。这就是为什么我想让你体验这个决策的分布教程,跟着我们队伍的脚印,构建可用的应用。
* * *
@@ -38,12 +39,8 @@
![](https://cdn-images-1.medium.com/max/400/1*r5FBoa8JsYOoJihDgrpzhg.jpeg)
![](https://cdn-images-1.medium.com/max/400/1*0O8ZWiyUgWm0b8wEiHhuPw.jpeg)
![](https://cdn-images-1.medium.com/max/400/1*y9Q5v-sF0PWmkhthcW338g.jpeg)
这些骨架确保我们意见统一,提供了可预见的蓝图,让我们向着计划的方向努力。
@@ -53,35 +50,32 @@
到了设计数据结构的时候。基于我们的示意图和用户故事,我们在 Google doc 中制作了一个清单,它包含我们将会需要的模型和每个模型应该包含的属性。我们知道需要 “目标goal” 模型、“用户user”模型、“里程碑milestone”模型、“记录checkin”模型还有最后的“资源resource”模型和“上传upload”模型
![](https://cdn-images-1.medium.com/max/800/1*oA3mzyixVzsvnN_egw1xwg.png)
最初的数据模型结构
*最初的数据模型结构*
在正式确定好这些模型后,我们需要选择某种 _类型_ 的数据库“关系型的”还是“非关系型的”也就是“SQL”还是“NoSQL”。由于基于表的 SQL 数据库需要预定义的格式,而基于文档的 NoSQL 数据库却可以用动态格式描述非结构化数据。
对于我们这个情况,用 SQL 型还是 No-SQL 型的数据库没多大影响,由于下列原因,我们最终选择了 Google 的 NoSQL 云数据库 Firebase
1. 它能够把用户上传的图片保存在云端并存储起来
2. 它包含 WebSocket 功能,能够实时更新
3. 它能够处理用户验证,并且提供简单的 OAuth 功能。
我们确定了数据库后,就要理解数据模型之间的关系了。由于 Firebase 是 NoSQL 类型,我们无法创建联合表或者设置像 _"记录 Checkins属于目标Goals"_ 的从属关系。因此我们需要弄清楚 JSON 树是什么样的,对象是怎样嵌套的(或者不是嵌套的关系)。最终,我们构建了像这样的模型:
我们确定了数据库后,就要理解数据模型之间的关系了。由于 Firebase 是 NoSQL 类型,我们无法创建联合表或者设置像 _记录 Checkins属于目标Goals_ 的从属关系。因此我们需要弄清楚 JSON 树是什么样的,对象是怎样嵌套的(或者不是嵌套的关系)。最终,我们构建了像这样的模型:
![](https://cdn-images-1.medium.com/max/800/1*py0hQy-XHZWmwff3PM6F1g.png)
我们最终为目标Goal对象确定的 Firebase 数据格式。注意里程碑Milestones和记录Checkins对象嵌套在 Goals 中。
_(注意: 出于性能考虑Firebase 更倾向于简单、常规的数据结构, 但对于我们这种情况需要在数据中进行嵌套因为我们不会从数据库中获取目标Goal却不获取相应的子对象里程碑Milestones和记录Checkins。)_
*我们最终为目标Goal对象确定的 Firebase 数据格式。注意里程碑Milestones和记录Checkins对象嵌套在 Goals 中。*
_注意: 出于性能考虑Firebase 更倾向于简单、常规的数据结构, 但对于我们这种情况需要在数据中进行嵌套因为我们不会从数据库中获取目标Goal却不获取相应的子对象里程碑Milestones和记录Checkins_
### 第 4 步:设置好 Github 和敏捷开发工作流
我们知道,从一开始就保持井然有序、执行敏捷开发对我们有极大好处。我们设置好 Github 上的仓库我们无法直接将代码合并到主master分支这迫使我们互相审阅代码。
![](https://cdn-images-1.medium.com/max/800/1*5kDNcvJpr2GyZ0YqLauCoQ.png)
我们还在 [Waffle.io][5] 网站上创建了敏捷开发的面板,它是免费的,很容易集成到 Github。我们在 Waffle 面板上罗列出所有用户故事以及需要我们去修复的 bugs。之后当我们开始编码时,我们每个人会为自己正在研究的每一个用户故事创建一个 git 分支,在完成工作后合并这一条条的分支。
我们还在 [Waffle.io][5] 网站上创建了敏捷开发的面板,它是免费的,很容易集成到 Github。我们在 Waffle 面板上罗列出所有用户故事以及需要我们去修复的 bug。之后当我们开始编码时我们每个人会为自己正在研究的每一个用户故事创建一个 git 分支,在完成工作后合并这一条条的分支。
![](https://cdn-images-1.medium.com/max/800/1*gnWqGwQsdGtpt3WOwe0s_A.gif)
@@ -103,9 +97,9 @@ _(注意: 出于性能考虑Firebase 更倾向于简单、常规的数据结
接下来是为应用创建 “概念证明”,也可以说是实现起来最复杂的基本功能的原型,证明我们的应用 _可以_ 实现。对我们而言,这意味着要找个前端库来实现时间线的渲染,成功连接到 Firebase显示数据库中的一些种子数据。
![](https://cdn-images-1.medium.com/max/800/1*d5Wu3fOlX8Xdqix1RPZWSA.png)
Victory.JS 绘制的简单时间线
*Victory.JS 绘制的简单时间线*
我们找到了基于 D3 构建的响应式库 Victory.JS花了一天时间阅读文档_VictoryLine__VictoryScatter_ 组件实现了非常基础的示例,能够可视化地显示数据库中的数据。实际上,这很有用!我们可以开始构建了。
@@ -113,26 +107,16 @@ Victory.JS 绘制的简单时间线
最后,是时候构建出应用中那些令人期待的功能了。取决于你要构建的应用,这一重要步骤会有些明显差异。我们根据所用的框架,编码出不同的用户故事并保存在 Waffle 上。常常需要同时接触前端和后端代码(比如,创建一个前端表格同时要连接到数据库)。我们实现了包含以下这些大大小小的功能:
* 能够创建新目标goals、里程碑milestones和记录checkins
* 能够创建新目标、里程碑和记录
* 能够删除目标,里程碑和记录
* 能够更改时间线的名称,颜色和详细内容
* 能够缩放时间线
* 能够为资源添加链接
* 能够上传视频
* 在达到相关目标的里程碑和记录时弹出资源和视频
* 集成富文本编辑器
* 用户注册、验证、OAuth 验证
* 弹出查看时间线选项
* 加载画面
有各种原因,这一步花了我们很多时间 —— 这一阶段是产生最多优质代码的阶段,每当我们实现了一个功能,就会有更多的事情要完善。
@@ -142,7 +126,8 @@ Victory.JS 绘制的简单时间线
当我们使用 MVP 架构实现了想要的功能,就可以开始清理,对它进行美化了。像表单,菜单和登陆栏等组件,我的团队用的是 Material-UI不需要很多深层次的设计知识它也能确保每个组件看上去都很圆润光滑。
![](https://cdn-images-1.medium.com/max/800/1*PCRFAbsPBNPYhz6cBgWRCw.gif)
这是我制作的最喜爱功能之一了。它美得令人心旷神怡。
*这是我制作的最喜爱功能之一了。它美得令人心旷神怡。*
我们花了一点时间来选择颜色方案和编写 CSS ,这让我们在编程中休息了一段美妙的时间。期间我们还设计了 logo 图标,还上传了网站图标。
@@ -169,15 +154,16 @@ Victory.JS 绘制的简单时间线
但是,现在我们感到非常开心,不仅是因为成品,还因为我们从这个过程中获得了难以估量的知识和理解。点击 [这里][7] 查看 Align 应用!
![](https://cdn-images-1.medium.com/max/800/1*KbqmSW-PMjgfWYWS_vGIqg.jpeg)
Align 团队Sara Kladky (左), Melanie Mohn (中), 还有我自己.
*Align 团队Sara KladkyMelanie Mohn还有我自己。*
--------------------------------------------------------------------------------
via: https://medium.com/ladies-storm-hackathons/how-we-built-our-first-full-stack-javascript-web-app-in-three-weeks-8a4668dbd67c?imm_mid=0f581a&cmp=em-web-na-na-newsltr_20170816
作者:[Sophia Ciocca ][a]
作者:[Sophia Ciocca][a]
译者:[BriFuture](https://github.com/BriFuture)
校对:[校对者ID](https://github.com/校对者ID)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出

View File

@@ -1,14 +1,15 @@
管理 Linux 系统中的用户
管理 Linux 系统中的用户
======
![](https://images.idgesg.net/images/article/2017/09/charging-bull-100735753-large.jpg)
也许你的 Lniux 用户并不是愤怒的公牛,但是当涉及管理他们的账户的时候,能让他们一直开心也是一种挑战。监控他们当前正在访问的东西,追踪他们他们遇到问题时的解决方案,并且保证能把他们在使用系统时出现的重要变动记录下来。这里有一些方法和工具可以使这份工作轻松一点。
也许你的 Linux 用户并不是愤怒的公牛,但是当涉及管理他们的账户的时候,能让他们一直满意也是一种挑战。你需要监控他们的访问权限,跟进他们遇到问题时的解决方案,并且把他们在使用系统时出现的重要变动记录下来。这里有一些方法和工具可以让这个工作轻松一点。
### 配置账户
### 配置账户
添加和除账户是管理用户中简单的一项,但是这里面仍然有很多需要考虑的选项。无论你是用桌面工具或是命令行选项,这都是一个非常自动化的过程。你可以使用命令添加一个新用户,像是 `adduser jdoe`,这同时会触发一系列的事情。使用下一个可用的 UID 可以创建 John 的账户,或许还会被许多用以配置账户的文件所填充。当你运行 `adduser` 命令加一个新的用户名的时候,它会提示一些额外的信息,同时解释这是在干什么。
添加和除账户是管理用户中比较简单的一项,但是这里面仍然有很多需要考虑的方面。无论你是用桌面工具或是命令行选项,这都是一个非常自动化的过程。你可以使用 `adduser jdoe` 命令添加一个新用户,同时会触发一系列的反应。在创建 John 这个账户时会自动使用下一个可用的 UID并有很多自动生成的文件来完成这个工作。当你运行 `adduser` 后跟一个参数时(要创建的用户名,它会提示一些额外的信息,同时解释这是在干什么。
```
```
$ sudo adduser jdoe
Adding user 'jdoe' ...
Adding new group `jdoe' (1001) ...
@@ -20,21 +21,21 @@ Retype new UNIX password:
passwd: password updated successfully
Changing the user information for jdoe
Enter the new value, or press ENTER for the default
Full Name []: John Doe
Room Number []:
Work Phone []:
Home Phone []:
Other []:
Full Name []: John Doe
Room Number []:
Work Phone []:
Home Phone []:
Other []:
Is the information correct? [Y/n] Y
```
```
像你看到的那样,`adduser` 将添加用户的信息(到 `/etc/passwd` 和 `/etc/shadow` 文件中),创建新的家目录,并用 `/etc/skel` 里设置的文件填充家目录,提示你分配初始密码和认信息,然后确认这些信息都是正确的,如果你在最后的提示 “Is the information correct” 处的答是 “n”回溯你之前所有的回答,允许修改任何你想要修改的地方。
如你所见,`adduser`添加用户的信息(到 `/etc/passwd``/etc/shadow` 文件中),创建新的<ruby>家目录<rt>home directory</rt></ruby>,并用 `/etc/skel` 里设置的文件填充家目录,提示你分配初始密码和认信息,然后确认这些信息都是正确的,如果你在最后的提示 “Is the information correct?” 处的答是 “n”回溯你之前所有的回答,允许修改任何你想要修改的地方。
创建好一个用户后,你可能会想要确认一下它是否是你期望的样子,更好的方法是确保在添加第一个帐户**之前**,“自动”选择与想要查看的内容匹配。默认有默认的好处,它对于你想知道他们定义在哪里有所用处,以你想出一些变动 —— 例如,你不想家目录在 `/home` 里,你不想用户 UID 从 1000 开始,或是你不想家目录下的文件被系统的**每个人**都可读。
创建好一个用户后,你可能会想要确认一下它是否是你期望的样子,更好的方法是确保在添加第一个帐户**之前**,“自动”选择与想要查看的内容是否匹配。默认有默认的好处,它对于你想知道他们定义在哪里很有用,以便你想出一些变动 —— 例如,你不想让用户的家目录在 `/home` 里,你不想用户 UID 从 1000 开始,或是你不想家目录下的文件被系统的**每个人**都可读。
`adduser` 如何工作的一些细节设置在 `/etc/adduser.conf` 文件里。这个文件包含的一些设置决定了一个新的账户如何配置,以及它之后的样子。注意,注释和空白行将会在输出中被忽略,因此我们可以更加集中注意在设置上面。
`adduser` 的一些配置细节设置在 `/etc/adduser.conf` 文件里。这个文件包含的一些配置项决定了一个新的账户如何配置,以及它之后的样子。注意,注释和空白行将会在输出中被忽略,因此我们更关注配置项。
```
```
$ cat /etc/adduser.conf | grep -v "^#" | grep -v "^$"
DSHELL=/bin/bash
DHOME=/home
@@ -55,45 +56,45 @@ DIR_MODE=0755
SETGID_HOME=no
QUOTAUSER=""
SKEL_IGNORE_REGEX="dpkg-(old|new|dist|save)"
```
```
可以看到,我们有了一个默认的 shell`DSHELL`UID`FIRST_UID`)的开始数值,家目录(`DHOME`)的位置,以及启动文件(`SKEL`)的来源位置。这个文件也会指定分配给家目录(`DIR_HOME`)的权限。
可以看到,我们有了一个默认的 shell`DSHELL`UID`FIRST_UID`)的起始值,家目录(`DHOME`)的位置,以及启动文件(`SKEL`)的来源位置。这个文件也会指定分配给家目录(`DIR_HOME`)的权限。
其中 `DIR_HOME` 是最重要的设置,它决定了每个家目录被使用的权限。这个设置分配给用户创建的目录权限是 `755`,家目录的权限将会设置为 `rwxr-xr-x`。用户可以读其他用户的文件,但是不能修改和移除们。如果你想要更多的限制,你可以更改这个设置为 `750`(用户组外的任何人都不可访问)甚至是 `700`(除用户自己外的人都不可访问)。
其中 `DIR_HOME` 是最重要的设置,它决定了每个家目录被使用的权限。这个设置分配给用户创建的目录权限是 755家目录的权限将会设置为 `rwxr-xr-x`。用户可以读其他用户的文件,但是不能修改和移除们。如果你想要更多的限制,你可以更改这个设置为 750用户组外的任何人都不可访问甚至是 700除用户自己外的人都不可访问
任何用户账号在创建之前都可以进行手动修改。例如,你可以编辑 `/etc/passwd` 或者修改家目录的权限,开始在新服务器上添加用户之前配置 `/etc/adduser.conf` 可以确保一定的一致性,从长远来看可以节省时间和避免一些麻烦。
任何用户账号在创建之前都可以进行手动修改。例如,你可以编辑 `/etc/passwd` 或者修改家目录的权限,开始在新服务器上添加用户之前配置 `/etc/adduser.conf` 可以确保一定的一致性,从长远来看可以节省时间和避免一些麻烦。
`/etc/adduser.conf` 的修改将会在之后创建的用户上生效。如果你想以不同的方式设置某个特定账户,除了用户名之外,你还可以选择使用 `adduser` 命令提供账户配置选项。或许你想为某些账户分配不同的 shell请求特殊的 UID完全禁用登录。`adduser` 的帮助页将会为你显示一些配置个人账户的选择。
`/etc/adduser.conf` 的修改将会在之后创建的用户上生效。如果你想以不同的方式设置某个特定账户,除了用户名之外,你还可以选择使用 `adduser` 命令提供账户配置选项。或许你想为某些账户分配不同的 shell分配特殊的 UID完全禁用该账户登录。`adduser` 的帮助页将会为你显示一些配置个人账户的选择。
```
adduser [options] [--home DIR] [--shell SHELL] [--no-create-home]
[--uid ID] [--firstuid ID] [--lastuid ID] [--ingroup GROUP | --gid ID]
[--disabled-password] [--disabled-login] [--gecos GECOS]
[--add_extra_groups] [--encrypt-home] user
```
```
每个 Linux 系统现在都会默认把每个用户放入对应的组中。作为一个管理员,你可能会选择以不同的方式去做事。你也许会发现把用户放在一个共享组中可以让你的站点工作的更好,这时,选择使用 `adduser` 的 `--gid` 选项去选择一个特定的组。当然,用户总是许多组的成员,因此也有一些选项管理主要和次要的组。
每个 Linux 系统现在都会默认把每个用户放入对应的组中。作为一个管理员,你可能会选择以不同的方式。你也许会发现把用户放在一个共享组中更适合你的站点,你就可以选择使用 `adduser``--gid` 选项指定一个特定的组。当然,用户总是许多组的成员,因此也有一些选项管理主要和次要的组。
### 处理用户密码
### 处理用户密码
一直以来,知道其他人的密码都是一个不好的念头,在设置账户时,管理员通常使用一个临时密码,然后在用户第一次登录时运行一条命令强制他修改密码。这里是一个例子:
一直以来,知道其他人的密码都是一件好事,在设置账户时,管理员通常使用一个临时密码,然后在用户第一次登录时运行一条命令强制他修改密码。这里是一个例子:
```
$ sudo chage -d 0 jdoe
```
当用户第一次登录的时候,会看到像这样的事情:
当用户第一次登录,会看到类似下面的提示:
```
WARNING: Your password has expired.
You must change your password now and login again!
Changing password for jdoe.
(current) UNIX password:
```
```
### 添加用户到副组
### 添加用户到副组
添加用户到副组中,你可能会用如下所示的 `usermod` 命令 —— 添加用户到组中并确认已经做出变动。
添加用户到副组中,你可能会用如下所示的 `usermod` 命令添加用户到组中并确认已经做出变动。
```
$ sudo usermod -a -G sudo jdoe
@@ -101,54 +102,54 @@ $ sudo grep sudo /etc/group
sudo:x:27:shs,jdoe
```
记住在一些组,像是 `sudo` 或者 `wheel` 组中,意味着包含特权,一定要特别注意这一点。
记住在一些组意味着特别的权限,如 sudo 或者 wheel,一定要特别注意这一点。
### 移除用户,添加组等
### 移除用户,添加组等
Linux 系统也提供了移除账户,添加新的组,移除组等一些命令。例如,`deluser` 命令,将会从 `/etc/passwd``/etc/shadow` 中移除用户记录,但是会完整保留其家目录,除非你添加了 `--remove-home` 或者 `--remove-all-files` 选项。`addgroup` 命令会添加一个组,默认按目前组的次序分配下一个 id在用户组范围内除非你使用 `--gid` 选项指定 id。
Linux 系统也提供了命令去移除账户、添加新的组、移除组等。例如,`deluser` 命令,将会从 `/etc/passwd` 和 `/etc/shadow` 中移除用户登录入口,但是会完整保留他的家目录,除非你添加了 `--remove-home` 或者 `--remove-all-files` 选项。`addgroup` 命令会添加一个组,按目前组的次序给他下一个 ID在用户组范围内除非你使用 `--gid` 选项指定 ID。
```
$ sudo addgroup testgroup --gid=131
Adding group `testgroup' (GID 131) ...
Done.
```
```
### 管理特权账户
### 管理特权账户
一些 Linux 系统中有一个 wheel 组,它给组中成员赋予了像 root 一样运行命令的能力。在这种情况下,`/etc/sudoers` 将会引用该组。在 Debian 系统中,这个组被叫做 `sudo`,但是以相同的方式工作,你在 `/etc/sudoers` 中可以看到像这样的引用:
一些 Linux 系统中有一个 wheel 组,它给组中成员赋予了像 root 一样运行命令的权限。在这种情况下,`/etc/sudoers` 将会引用该组。在 Debian 系统中,这个组被叫做 sudo但是原理是相同的,你在 `/etc/sudoers` 中可以看到像这样的信息:
```
%sudo ALL=(ALL:ALL) ALL
```
%sudo ALL=(ALL:ALL) ALL
```
这个基础的设定意味着任何在 wheel 或者 sudo 组中的成员只要在他们运行的命令之前添加 `sudo`,就可以以 root 的权限去运行命令。
这行基本的配置意味着任何在 wheel 或者 sudo 组中的成员只要在他们运行的命令之前添加 `sudo`,就可以以 root 的权限去运行命令。
你可以向 `sudoers` 文件中添加更多有限的权 —— 也许给特定用户运行一两个 root 的命令。如果这样做,您还应定期查看 `/etc/sudoers` 文件以评估用户拥有的权限,以及仍然需要提供的权限。
你可以向 sudoers 文件中添加更多有限的权 —— 也许给特定用户几个能以 root 运行的命令。如果你是这样做的,你应该定期查看 `/etc/sudoers` 文件以评估用户拥有的权限,以及仍然需要提供的权限。
在下面显示的命令中,我们看到在 `/etc/sudoers` 中匹配到的行。在这个文件中最有趣的行是,包含能使用 `sudo` 运行命令的路径设置,以及两个允许通过 `sudo` 运行命令的组。像刚才提到的那样,单个用户可以通过包含在 `sudoers` 文件中来获得权限,但是更有实际意义的方法是通过组成员来定义各自的权限。
在下面显示的命令中,我们过滤了 `/etc/sudoers` 中有效的配置行。其中最有意思的是,包含能使用 `sudo` 运行命令的路径设置,以及两个允许通过 `sudo` 运行命令的组。像刚才提到的那样,单个用户可以通过包含在 sudoers 文件中来获得权限,但是更有实际意义的方法是通过组成员来定义各自的权限。
```
# cat /etc/sudoers | grep -v "^#" | grep -v "^$"
Defaults env_reset
Defaults mail_badpass
Defaults secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin"
root ALL=(ALL:ALL) ALL
%admin ALL=(ALL) ALL <== admin group
%sudo ALL=(ALL:ALL) ALL <== sudo group
```
root ALL=(ALL:ALL) ALL
%admin ALL=(ALL) ALL <== admin group
%sudo ALL=(ALL:ALL) ALL <== sudo group
```
### 登录检查
### 登录检查
你可以通过以下命令查看用户的上一次登录:
你可以通过以下命令查看用户的上一次登录:
```
# last jdoe
jdoe pts/18 192.168.0.11 Thu Sep 14 08:44 - 11:48 (00:04)
jdoe pts/18 192.168.0.11 Thu Sep 14 13:43 - 18:44 (00:00)
jdoe pts/18 192.168.0.11 Thu Sep 14 19:42 - 19:43 (00:00)
```
```
如果你想查看每一个用户上一次的登录情况,你可以通过一个像这样的循环来运行 `last` 命令:
如果你想查看每一个用户上一次的登录情况,你可以通过一个像这样的循环来运行 `last` 命令:
```
$ for user in `ls /home`; do last $user | head -1; done
@@ -157,21 +158,21 @@ jdoe pts/18 192.168.0.11 Thu Sep 14 19:42 - 19:43 (00:03)
rocket pts/18 192.168.0.11 Thu Sep 14 13:02 - 13:02 (00:00)
shs pts/17 192.168.0.11 Thu Sep 14 12:45 still logged in
```
此命令仅显示自当前 `wtmp` 文件变为活跃状态以来已登录的用户。空白行表示用户自那以后从未登录过,但没有将其调出。一个更好的命令是过滤掉在这期间从未登录过的用户的显示:
```
$ for user in `ls /home`; do echo -n "$user ";last $user | head -1 | awk '{print substr($0,40)}'; done
此命令仅显示自当前 wtmp 文件登录过的用户。空白行表示用户自那以后从未登录过,但没有将他们显示出来。一个更好的命令可以明确地显示这期间从未登录过的用户:
```
$ for user in `ls /home`; do echo -n "$user"; last $user | head -1 | awk '{print substr($0,40)}'; done
dhayes
jdoe pts/18 192.168.0.11 Thu Sep 14 19:42 - 19:43
peanut pts/19 192.168.0.29 Mon Sep 11 09:15 - 17:11
rocket pts/18 192.168.0.11 Thu Sep 14 13:02 - 13:02
shs pts/17 192.168.0.11 Thu Sep 14 12:45 still logged
tsmith
```
```
这个命令会打印很多,但是可以通过一个脚本使它更加清晰易用。
这个命令要打很多,但是可以通过一个脚本使它更加清晰易用。
```
#!/bin/bash
@@ -180,13 +181,13 @@ for user in `ls /home`
do
echo -n "$user ";last $user | head -1 | awk '{print substr($0,40)}'
done
```
```
有时,此类信息可以提醒用户角色的变动,表明他们可能不再需要相关帐户
有时这些信息可以提醒用户角色的变动,表明他们可能不再需要相关帐户了。
### 与用户沟通
### 与用户沟通
Linux 提供了许多方法和用户沟通。你可以向 `/etc/motd` 文件中添加信息,当用户从终端登录到服务器时,将会显示这些信息。你也可以通过例如 `write`(通知单个用户)或者 `wall``write` 给所有已登录的用户)命令发送通知。
Linux 提供了许多和用户沟通的方法。你可以向 `/etc/motd` 文件中添加信息,当用户从终端登录到服务器时,将会显示这些信息。你也可以通过例如 `write`(通知单个用户)或者 `wall`write 给所有已登录的用户)命令发送通知。
```
$ wall System will go down in one hour
@@ -194,30 +195,30 @@ $ wall System will go down in one hour
Broadcast message from shs@stinkbug (pts/17) (Thu Sep 14 14:04:16 2017):
System will go down in one hour
```
```
重要的通知应该通过多个道传因为很难预测用户实际会注意到什么。mesage-of-the-daymotd`wall` 和 email 通知可以吸引用户大部分的注意力。
重要的通知应该通过多个道传因为很难预测用户实际会注意到什么。mesage-of-the-daymotd`wall` 和 email 通知可以吸引用户大部分的注意力。
### 注意日志文件
### 注意日志文件
更多地注意日志文件也可以帮你理解用户活动。事实上,`/var/log/auth.log` 文件将会为你显示用户的登录和注销活动,组的创建等。`/var/log/message` 或者 `/var/log/syslog` 文件将会告诉你更多有关系统活动的事情。
注意日志文件也可以帮你理解用户活动情况。尤其 `/var/log/auth.log` 文件将会显示用户的登录和注销活动,组的创建记录等。`/var/log/message` 或者 `/var/log/syslog` 文件将会告诉你更多有关系统活动的日志。
### 追踪问题和请求
### 追踪问题和需求
无论你是否在 Linux 系统上安装了票务系统,跟踪用户遇到的问题以及他们提出的求都非常重要。如果求的一部分久久不见回应,用户必然不会高兴。即使是纸质日志也可能是有用的,或者更好的是,有一个电子表格,可以让你注意到哪些问题仍然悬而未决,以及问题的根本原因是什么。确保解决问题和求非常重要,日志还可以帮助记住你必须采取的措施来解决几个月甚至几年后重新出现的问题。
无论你是否在 Linux 系统上安装了事件跟踪系统,跟踪用户遇到的问题以及他们提出的求都非常重要。如果求的一部分久久不见回应,用户必然不会高兴。即使是记录在纸上也是有用的,或者最好有个电子表格,可以让你注意到哪些问题仍然悬而未决,以及问题的根本原因是什么。确问题和求非常重要,记录还可以帮助记住你必须采取的措施来解决几个月甚至几年后重新出现的问题。
### 总结
### 总结
在繁忙的服务器上管理用户帐部分取决于配置良好的默认值开始,部分取决于监控用户活动和遇到的问题。如果用户觉得你对他们的顾虑有所回应并且知道在需要系统升级时会发生什么,他们可能会很高兴。
在繁忙的服务器上管理用户帐号,部分取决于配置良好的默认值,部分取决于监控用户活动和遇到的问题。如果用户觉得你对他们的顾虑有所回应并且知道在需要系统升级时会发生什么,他们可能会很高兴。
-----------
--------------------------------------------------------------------------------
via: https://www.networkworld.com/article/3225109/linux/managing-users-on-linux-systems.html
作者:[Sandra Henry-Stocker][a]
译者:[dianbanjiu](https://github.com/dianbanjiu)
校对:[wxy](https://github.com/wxy)
校对:[wxy](https://github.com/wxy)、[pityonline](https://github.com/pityonline)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://www.networkworld.com/author/Sandra-Henry_Stocker/
[a]: https://www.networkworld.com/author/Sandra-Henry_Stocker/

View File

@@ -1,9 +1,9 @@
NPM 的桌面 GUI 程序
ndmNPM 的桌面 GUI 程序
======
![](https://www.ostechnix.com/wp-content/uploads/2018/04/ndm-3-720x340.png)
NPM 是 **N** ode **P** ackage **M** anager node 包管理器)的缩写,它是用于安装 NodeJS 软件包或模块的命令行软件包管理器。我们发布过一个指南描述了如何[**使用 NPM 管理 NodeJS 包**][1]。你可能已经注意到,使用 Npm 管理 NodeJS 包或模块并不是什么大问题。但是,如果你不习惯用 CLI 的方式,这有一个名为 **NDM** 的桌面 GUI 程序,它可用于管理 NodeJS 程序/模块。 NDM代表 **N** PM **D** esktop **M** anager npm 桌面管理器),是 NPM 的免费开源图形前端,它允许我们通过简单图形桌面安装、更新、删除 NodeJS 包。
NPM 是 **N**ode **P**ackage **M**anager node 包管理器)的缩写,它是用于安装 NodeJS 软件包或模块的命令行软件包管理器。我们发布过一个指南描述了如何[使用 NPM 管理 NodeJS 包][1]。你可能已经注意到,使用 Npm 管理 NodeJS 包或模块并不是什么大问题。但是,如果你不习惯用 CLI 的方式,这有一个名为 **NDM** 的桌面 GUI 程序,它可用于管理 NodeJS 程序/模块。 NDM代表 **N**PM **D**esktop **M**anager npm 桌面管理器),是 NPM 的自由开源图形前端,它允许我们通过简单图形桌面安装、更新、删除 NodeJS 包。
在这个简短的教程中,我们将了解 Linux 中的 Ndm。
@@ -11,59 +11,58 @@ NPM 是 **N** ode **P** ackage **M** anager node 包管理器)的缩写,
NDM 在 AUR 中可用,因此你可以在 Arch Linux 及其衍生版(如 Antergos 和 Manjaro Linux上使用任何 AUR 助手程序安装。
使用 [**Pacaur**][2]
使用 [Pacaur][2]
```
$ pacaur -S ndm
```
使用 [**Packer**][3]
使用 [Packer][3]
```
$ packer -S ndm
```
使用 [**Trizen**][4]
使用 [Trizen][4]
```
$ trizen -S ndm
```
使用 [**Yay**][5]
使用 [Yay][5]
```
$ yay -S ndm
```
使用 [**Yaourt**][6]
使用 [Yaourt][6]
```
$ yaourt -S ndm
```
在基于 RHEL 的系统(如 CentOS运行以下命令以安装 NDM。
```
$ echo "[fury] name=ndm repository baseurl=https://repo.fury.io/720kb/ enabled=1 gpgcheck=0" | sudo tee /etc/yum.repos.d/ndm.repo && sudo yum update &&
```
在 Debian、Ubuntu、Linux Mint
```
$ echo "deb [trusted=yes] https://apt.fury.io/720kb/ /" | sudo tee /etc/apt/sources.list.d/ndm.list && sudo apt-get update && sudo apt-get install ndm
```
也可以使用 **Linuxbrew** 安装 NDM。首先按照以下链接中的说明安装 Linuxbrew。
安装 Linuxbrew 后,可以使用以下命令安装 NDM
```
$ brew update
$ brew install ndm
```
在其他 Linux 发行版上,进入[**NDM 发布页面**][7],下载最新版本,自行编译和安装。
在其他 Linux 发行版上,进入 [NDM 发布页面][7],下载最新版本,自行编译和安装。
### NDM 使用
@@ -73,15 +72,15 @@ $ brew install ndm
在这里你可以本地或全局安装 NodeJS 包/模块。
**本地安装 NodeJS 包**
#### 本地安装 NodeJS 包
要在本地安装软件包,首先通过单击主屏幕上的 **“Add projects”** 按钮选择项目目录,然后选择要保留项目文件的目录。例如,我选择了一个名为 **“demo”** 的目录作为我的项目目录。
要在本地安装软件包,首先通过单击主屏幕上的 “Add projects” 按钮选择项目目录,然后选择要保留项目文件的目录。例如,我选择了一个名为 “demo” 的目录作为我的项目目录。
单击项目目录(即 **demo**),然后单击 **Add packages** 按钮。
单击项目目录(即 demo然后单击 Add packages 按钮。
![][10]
输入要安装的软件包名称,然后单击 **Install** 按钮。
输入要安装的软件包名称,然后单击 Install 按钮。
![][11]
@@ -91,41 +90,37 @@ $ brew install ndm
同样,你可以创建单独的项目目录并在其中安装 NodeJS 模块。要查看项目中已安装模块的列表,请单击项目目录,右侧将显示软件包。
**全局安装 NodeJS 包**
#### 全局安装 NodeJS 包
要全局安装 NodeJS 包,请单击主界面左侧的 **Globals** 按钮。然后,单击 “Add packages” 按钮,输入包的名称并单击 “Install” 按钮。
要全局安装 NodeJS 包,请单击主界面左侧的 Globals 按钮。然后,单击 “Add packages” 按钮,输入包的名称并单击 “Install” 按钮。
**管理包**
#### 管理包
单击任何已安装的包,不将在顶部看到各种选项,例如:
1. 版本(查看已安装的版本),
  2. 最新(安装最新版本),
  3. 更新(更新当前选定的包),
  4. 卸载(删除所选包)等。
1. 版本(查看已安装的版本),
2. 最新(安装最新版本),
3. 更新(更新当前选定的包),
4. 卸载(删除所选包)等。
![][13]
NDM 还有两个选项,即 **“Update npm”** 用于将 node 包管理器更新成最新可用版本, **Doctor** 运行一组检查以确保你的 npm 安装有所需的功能管理你的包/模块。
NDM 还有两个选项,即 “Update npm” 用于将 node 包管理器更新成最新可用版本, 而 “Doctor” 会运行一组检查以确保你的 npm 安装有所需的功能管理你的包/模块。
### 结
###
NDM 使安装、更新、删除 NodeJS 包的过程更加容易你无需记住执行这些任务的命令。NDM 让我们在简单的图形界面中点击几下鼠标即可完成所有操作。对于那些懒得输入命令的人来说NDM 是管理 NodeJS 包的完美伴侣。
干杯!
--------------------------------------------------------------------------------
via: https://www.ostechnix.com/ndm-a-desktop-gui-application-for-npm/
作者:[SK][a]
译者:[geekpi](https://github.com/geekpi)
校对:[校对者ID](https://github.com/校对者ID)
选题:[lujun9972](https://github.com/lujun9972)
译者:[geekpi](https://github.com/geekpi)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出

View File

@@ -3,92 +3,90 @@
![](https://www.ostechnix.com/wp-content/uploads/2016/07/Install-Oracle-VirtualBox-On-Ubuntu-18.04-720x340.png)
本教程将指导你在 Ubuntu 18.04 LTS 无头服务器上,一步一步地安装 **Oracle VirtualBox**。同时,本教程也将介绍如何使用 **phpVirtualBox** 去管理安装在无头服务器上的 **VirtualBox** 实例。**phpVirtualBox** 是 VirtualBox 的一个基于 Web 的端工具。这个教程也可以工作在 Debian 和其它 Ubuntu 衍生版本上,如 Linux Mint。现在我们开始。
本教程将指导你在 Ubuntu 18.04 LTS 无头服务器上,一步一步地安装 **Oracle VirtualBox**。同时,本教程也将介绍如何使用 **phpVirtualBox** 去管理安装在无头服务器上的 **VirtualBox** 实例。**phpVirtualBox** 是 VirtualBox 的一个基于 Web 的端工具。这个教程也可以工作在 Debian 和其它 Ubuntu 衍生版本上,如 Linux Mint。现在我们开始。
### 前提条件
在安装 Oracle VirtualBox 之前,我们的 Ubuntu 18.04 LTS 服务器上需要满足如下的前提条件。
首先,逐个运行如下的命令来更新 Ubuntu 服务器。
```
$ sudo apt update
$ sudo apt upgrade
$ sudo apt dist-upgrade
```
接下来,安装如下的必需的包:
```
$ sudo apt install build-essential dkms unzip wget
```
安装完成所有的更新和必需的包之后,重启动 Ubuntu 服务器。
```
$ sudo reboot
```
### 在 Ubuntu 18.04 LTS 服务器上安装 VirtualBox
添加 Oracle VirtualBox 官方仓库。为此你需要去编辑 **/etc/apt/sources.list** 文件:
添加 Oracle VirtualBox 官方仓库。为此你需要去编辑 `/etc/apt/sources.list` 文件:
```
$ sudo nano /etc/apt/sources.list
```
添加下列的行。
在这里,我将使用 Ubuntu 18.04 LTS因此我添加下列的仓库。
```
deb http://download.virtualbox.org/virtualbox/debian bionic contrib
```
![][2]
用你的 Ubuntu 发行版的代码名字替换关键字 **bionic**,比如,**xenialvividutopictrustyraringquantalpreciselucidjessiewheezy、或 squeeze**
用你的 Ubuntu 发行版的代码名字替换关键字 bionic比如xenialvividutopictrustyraringquantalpreciselucidjessiewheezy、或 squeeze
然后,运行下列的命令去添加 Oracle 公钥:
```
$ wget -q https://www.virtualbox.org/download/oracle_vbox_2016.asc -O- | sudo apt-key add -
```
对于 VirtualBox 的老版本,添加如下的公钥:
```
$ wget -q https://www.virtualbox.org/download/oracle_vbox.asc -O- | sudo apt-key add -
```
接下来,使用如下的命令去更新软件源:
```
$ sudo apt update
```
最后,使用如下的命令去安装最新版本的 Oracle VirtualBox
```
$ sudo apt install virtualbox-5.2
```
### 添加用户到 VirtualBox 组
我们需要去创建并添加我们的系统用户到 **vboxusers** 组中。你也可以单独创建用户,然后将它分配到 **vboxusers** 组中,也可以使用已有的用户。我不想去创建新用户,因此,我添加已存在的用户到这个组中。请注意,如果你为 virtualbox 使用一个单独的用户,那么你必须注销当前用户,并使用那个特定的用户去登入,来完成剩余的步骤。
我们需要去创建并添加我们的系统用户到 `vboxusers` 组中。你也可以单独创建用户,然后将它分配到 `vboxusers` 组中,也可以使用已有的用户。我不想去创建新用户,因此,我添加已存在的用户到这个组中。请注意,如果你为 virtualbox 使用一个单独的用户,那么你必须注销当前用户,并使用那个特定的用户去登入,来完成剩余的步骤。
我使用的是我的用户名 `sk`,因此,我运行如下的命令将它添加到 `vboxusers` 组中。
我使用的是我的用户名 **sk**,因此,我运行如下的命令将它添加到 **vboxusers** 组中。
```
$ sudo usermod -aG vboxusers sk
```
现在,运行如下的命令去检查 virtualbox 内核模块是否已加载。
```
$ sudo systemctl status vboxdrv
```
![][3]
@@ -96,15 +94,15 @@ $ sudo systemctl status vboxdrv
正如你在上面的截屏中所看到的vboxdrv 模块已加载,并且是已运行的状态!
对于老的 Ubuntu 版本,运行:
```
$ sudo /etc/init.d/vboxdrv status
```
如果 virtualbox 模块没有启动,运行如下的命令去启动它。
```
$ sudo /etc/init.d/vboxdrv setup
```
很好!我们已经成功安装了 VirtualBox 并启动了 virtualbox 模块。现在,我们继续来安装 Oracle VirtualBox 的扩展包。
@@ -119,21 +117,19 @@ VirtualBox 扩展包为 VirtualBox 访客系统提供了如下的功能。
* Intel PXE 引导 ROM
* 对 Linux 宿主机上的 PCI 直通提供支持
从[这里][4]为 VirtualBox 5.2.x 下载最新版的扩展包。
从[**这里**][4]为 VirtualBox 5.2.x 下载最新版的扩展包。
```
$ wget https://download.virtualbox.org/virtualbox/5.2.14/Oracle_VM_VirtualBox_Extension_Pack-5.2.14.vbox-extpack
```
使用如下的命令去安装扩展包:
```
$ sudo VBoxManage extpack install Oracle_VM_VirtualBox_Extension_Pack-5.2.14.vbox-extpack
```
恭喜!我们已经成功地在 Ubuntu 18.04 LTS 服务器上安装了 Oracle VirtualBox 的扩展包。现在已经可以去部署虚拟机了。参考 [**virtualbox 官方指南**][5],在命令行中开始创建和管理虚拟机。
恭喜!我们已经成功地在 Ubuntu 18.04 LTS 服务器上安装了 Oracle VirtualBox 的扩展包。现在已经可以去部署虚拟机了。参考 [virtualbox 官方指南][5],在命令行中开始创建和管理虚拟机。
然而,并不是每个人都擅长使用命令行。有些人可能希望在图形界面中去创建和使用虚拟机。不用担心!下面我们为你带来非常好用的 **phpVirtualBox** 工具!
@@ -146,84 +142,82 @@ $ sudo VBoxManage extpack install Oracle_VM_VirtualBox_Extension_Pack-5.2.14.vbo
由于它是基于 web 的工具,我们需要安装 Apache web 服务器、PHP 和一些 php 模块。
为此,运行如下命令:
```
$ sudo apt install apache2 php php-mysql libapache2-mod-php php-soap php-xml
```
然后,从 [**下载页面**][6] 上下载 phpVirtualBox 5.2.x 版。请注意,由于我们已经安装了 VirtualBox 5.2 版,因此,同样的我们必须去安装 phpVirtualBox 的 5.2 版本。
然后,从 [下载页面][6] 上下载 phpVirtualBox 5.2.x 版。请注意,由于我们已经安装了 VirtualBox 5.2 版,因此,同样的我们必须去安装 phpVirtualBox 的 5.2 版本。
运行如下的命令去下载它:
```
$ wget https://github.com/phpvirtualbox/phpvirtualbox/archive/5.2-0.zip
```
使用如下命令解压下载的安装包:
```
$ unzip 5.2-0.zip
```
这个命令将解压 5.2.0.zip 文件的内容到一个名为 phpvirtualbox-5.2-0 的文件夹中。现在,复制或移动这个文件夹的内容到你的 apache web 服务器的根文件夹中。
这个命令将解压 5.2.0.zip 文件的内容到一个名为 `phpvirtualbox-5.2-0` 的文件夹中。现在,复制或移动这个文件夹的内容到你的 apache web 服务器的根文件夹中。
```
$ sudo mv phpvirtualbox-5.2-0/ /var/www/html/phpvirtualbox
```
给 phpvirtualbox 文件夹分配适当的权限。
```
$ sudo chmod 777 /var/www/html/phpvirtualbox/
```
接下来,我们开始配置 phpVirtualBox。
像下面这样复制示例配置文件。
```
$ sudo cp /var/www/html/phpvirtualbox/config.php-example /var/www/html/phpvirtualbox/config.php
```
编辑 phpVirtualBox 的 **config.php** 文件:
编辑 phpVirtualBox 的 `config.php` 文件:
```
$ sudo nano /var/www/html/phpvirtualbox/config.php
```
找到下列行,并且用你的系统用户名和密码去替换它(就是前面的“添加用户到 VirtualBox 组中”节中使用的用户名)。
在我的案例中,我的 Ubuntu 系统用户名是 **sk** ,它的密码是 **ubuntu**
在我的案例中,我的 Ubuntu 系统用户名是 `sk` ,它的密码是 `ubuntu`
```
var $username = 'sk';
var $password = 'ubuntu';
```
![][7]
保存并关闭这个文件。
接下来,创建一个名为 **/etc/default/virtualbox** 的新文件:
接下来,创建一个名为 `/etc/default/virtualbox` 的新文件:
```
$ sudo nano /etc/default/virtualbox
```
添加下列行。用你自己的系统用户替换 sk
添加下列行。用你自己的系统用户替换 `sk`
```
VBOXWEB_USER=sk
```
最后,重引导你的系统或重启下列服务去完成整个配置工作。
```
$ sudo systemctl restart vboxweb-service
$ sudo systemctl restart vboxdrv
$ sudo systemctl restart apache2
```
### 调整防火墙允许连接 Apache web 服务器
@@ -231,6 +225,7 @@ $ sudo systemctl restart apache2
如果你在 Ubuntu 18.04 LTS 上启用了 UFW那么在默认情况下apache web 服务器是不能被任何远程系统访问的。你必须通过下列的步骤让 http 和 https 流量允许通过 UFW。
首先,我们使用如下的命令来查看在策略中已经安装了哪些应用:
```
$ sudo ufw app list
Available applications:
@@ -238,12 +233,12 @@ Apache
Apache Full
Apache Secure
OpenSSH
```
正如你所见Apache 和 OpenSSH 应该已经在 UFW 的策略文件中安装了。
如果你在策略中看到的是 **Apache Full”**,说明它允许流量到达 **80****443** 端口:
如果你在策略中看到的是 `Apache Full`,说明它允许流量到达 80 和 443 端口:
```
$ sudo ufw app info "Apache Full"
Profile: Apache Full
@@ -253,34 +248,33 @@ server.
Ports:
80,443/tcp
```
现在,运行如下的命令去启用这个策略中的 HTTP 和 HTTPS 的入站流量:
```
$ sudo ufw allow in "Apache Full"
Rules updated
Rules updated (v6)
```
如果你希望允许 https 流量,但是仅是 http (80) 的流量,运行如下的命令:
```
$ sudo ufw app info "Apache"
```
### 访问 phpVirtualBox 的 Web 控制台
现在,用任意一台远程系统的 web 浏览器来访问。
在地址栏中,输入:**<http://IP-address-of-virtualbox-headless-server/phpvirtualbox>**
在地址栏中,输入:`http://IP-address-of-virtualbox-headless-server/phpvirtualbox`
在我的案例中,我导航到这个链接 **<http://192.168.225.22/phpvirtualbox>**
在我的案例中,我导航到这个链接 `http://192.168.225.22/phpvirtualbox`
你将看到如下的屏幕输出。输入 phpVirtualBox 管理员用户凭据。
phpVirtualBox 的默认管理员用户名和密码是 **admin** / **admin**
phpVirtualBox 的默认管理员用户名和密码是 `admin` / `admin`
![][8]
@@ -303,7 +297,7 @@ via: https://www.ostechnix.com/install-oracle-virtualbox-ubuntu-16-04-headless-s
作者:[SK][a]
选题:[lujun9972](https://github.com/lujun9972)
译者:[qhwdw](https://github.com/qhwdw)
校对:[校对者ID](https://github.com/校对者ID)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出

View File

@@ -1,11 +1,12 @@
树莓派自建 NAS 云盘之-树莓派搭建网络存储盘
树莓派自建 NAS 云盘之——树莓派搭建网络存储盘
======
> 跟随这些逐步指导构建你自己的基于树莓派的 NAS 系统。
![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/bus-storage.png?itok=95-zvHYl)
我将在接下来的三篇文章中讲述如何搭建一个简便、实用的 NAS 云盘系统。我在这个中心化的存储系统中存储数据,并且让它每晚都会自动的备份增量数据。本系列文章将利用 NFS 文件系统将磁盘挂载到同一网络下的不同设备上,使用 [Nextcloud][1] 来离线访问数据、分享数据。
我将在接下来的三篇文章中讲述如何搭建一个简便、实用的 NAS 云盘系统。我在这个中心化的存储系统中存储数据,并且让它每晚都会自动的备份增量数据。本系列文章将利用 NFS 文件系统将磁盘挂载到同一网络下的不同设备上,使用 [Nextcloud][1] 来离线访问数据、分享数据。
本文主要讲述将数据盘挂载到远程设备上的软硬件步骤。本系列第二篇文章将讨论数据备份策略、如何添加定时备份数据任务。最后一篇文章中我们将会安装 Nextcloud 软件用户通过Nextcloud 提供的 web 接口可以方便的离线或在线访问数据。本系列教程最终搭建的 NAS 云盘支持多用户操作、文件共享等功能,所以你可以通过它方便的分享数据,比如说你可以发送一个加密链接,跟朋友分享你的照片等等。
本文主要讲述将数据盘挂载到远程设备上的软硬件步骤。本系列第二篇文章将讨论数据备份策略、如何添加定时备份数据任务。最后一篇文章中我们将会安装 Nextcloud 软件,用户通过 Nextcloud 提供的 web 界面可以方便的离线或在线访问数据。本系列教程最终搭建的 NAS 云盘支持多用户操作、文件共享等功能,所以你可以通过它方便的分享数据,比如说你可以发送一个加密链接,跟朋友分享你的照片等等。
最终的系统架构如下图所示:
@@ -16,11 +17,11 @@
首先需要准备硬件。本文所列方案只是其中一种示例,你也可以按不同的硬件方案进行采购。
最主要的就是[树莓派3][2],它带有四核 CPU1G RAM以及有些)快速的网络接口。数据将存储在两个 USB 磁盘驱动器上(这里使用 1TB 磁盘);其中一个磁盘用于每天数据存储,另一个用于数据备份。请务必使用有源 USB 磁盘驱动器或者带附加电源的 USB 集线器,因为树莓派无法为两个 USB 磁盘驱动器供电。
最主要的就是[树莓派 3][2],它带有四核 CPU1G RAM以及比较)快速的网络接口。数据将存储在两个 USB 磁盘驱动器上(这里使用 1TB 磁盘);其中一个磁盘用于每天数据存储,另一个用于数据备份。请务必使用有源 USB 磁盘驱动器或者带附加电源的 USB 集线器,因为树莓派无法为两个 USB 磁盘驱动器供电。
### 软件
社区中最活跃的操作系统当属 [Raspbian][3],便于定制个性化项目。已经有很多 [操作指南][4] 讲述如何在树莓派中安装 Raspbian 系统,所以这里不再赘述。在撰写本文时,最新的官方支持版本是 [Raspbian Stretch][5],它对我来说很好使用。
在该社区中最活跃的操作系统当属 [Raspbian][3],便于定制个性化项目。已经有很多 [操作指南][4] 讲述如何在树莓派中安装 Raspbian 系统,所以这里不再赘述。在撰写本文时,最新的官方支持版本是 [Raspbian Stretch][5],它对我来说很好使用。
到此,我将假设你已经配置好了基本的 Raspbian 系统并且可以通过 `ssh` 访问到你的树莓派。
@@ -31,51 +32,28 @@
```
pi@raspberrypi:~ $ sudo fdisk -l
<...>
Disk /dev/sda: 931.5 GiB, 1000204886016 bytes, 1953525168 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0xe8900690
Device     Boot Start        End    Sectors   Size Id Type
/dev/sda1        2048 1953525167 1953523120 931.5G 83 Linux
Device Boot Start End Sectors Size Id Type
/dev/sda1 2048 1953525167 1953523120 931.5G 83 Linux
Disk /dev/sdb: 931.5 GiB, 1000204886016 bytes, 1953525168 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x6aa4f598
Device     Boot Start        End    Sectors   Size Id Type
/dev/sdb1  *     2048 1953521663 1953519616 931.5G  83 Linux
Device Boot Start End Sectors Size Id Type
/dev/sdb1 * 2048 1953521663 1953519616 931.5G 83 Linux
```
@@ -86,163 +64,101 @@ Device     Boot Start        End    Sectors   Size Id Type
```
pi@raspberrypi:~ $ sudo fdisk /dev/sda
Welcome to fdisk (util-linux 2.29.2).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.
Command (m for help): o
Created a new DOS disklabel with disk identifier 0x9c310964.
Command (m for help): n
Partition type
   p   primary (0 primary, 0 extended, 4 free)
   e   extended (container for logical partitions)
p primary (0 primary, 0 extended, 4 free)
e extended (container for logical partitions)
Select (default p): p
Partition number (1-4, default 1):
First sector (2048-1953525167, default 2048):
Last sector, +sectors or +size{K,M,G,T,P} (2048-1953525167, default 1953525167):
Created a new partition 1 of type 'Linux' and of size 931.5 GiB.
Command (m for help): p
Disk /dev/sda: 931.5 GiB, 1000204886016 bytes, 1953525168 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x9c310964
Device     Boot Start        End    Sectors   Size Id Type
/dev/sda1        2048 1953525167 1953523120 931.5G 83 Linux
Device Boot Start End Sectors Size Id Type
/dev/sda1 2048 1953525167 1953523120 931.5G 83 Linux
Command (m for help): w
The partition table has been altered.
Syncing disks.
```
现在,我们将用 ext4 文件系统格式化新创建的分区 `/dev/sda1`
```
pi@raspberrypi:~ $ sudo mkfs.ext4 /dev/sda1
mke2fs 1.43.4 (31-Jan-2017)
Discarding device blocks: done
<...>
Allocating group tables: done
Writing inode tables: done
Creating journal (1024 blocks): done
Writing superblocks and filesystem accounting information: done
```
重复以上步骤后,让我们根据用途来对它们建立标签:
```
pi@raspberrypi:~ $ sudo e2label /dev/sda1 data
pi@raspberrypi:~ $ sudo e2label /dev/sdb1 backup
```
现在让我们安装这些磁盘并存储一些数据。以我运营该系统超过一年的经验来看当树莓派启动时例如在断电后USB 磁盘驱动器并不是总被安装,因此我建议使用 autofs 在需要的时候进行安装
现在让我们安装这些磁盘并存储一些数据。以我运营该系统超过一年的经验来看当树莓派启动时例如在断电后USB 磁盘驱动器并不是总被挂载,因此我建议使用 autofs 在需要的时候进行挂载
首先,安装 autofs 并创建挂载点:
```
pi@raspberrypi:~ $ sudo apt install autofs
pi@raspberrypi:~ $ sudo mkdir /nas
```
然后添加下面这行来挂载设备
`/etc/auto.master`:
然后添加下面这行来挂载设备 `/etc/auto.master`
```
/nas    /etc/auto.usb
```
如果不存在以下内容,则创建 `/etc/auto.usb`,然后重新启动 autofs 服务:
```
data -fstype=ext4,rw :/dev/disk/by-label/data
backup -fstype=ext4,rw :/dev/disk/by-label/backup
pi@raspberrypi3:~ $ sudo service autofs restart
```
现在你应该可以分别访问 `/nas/data` 以及 `/nas/backup` 磁盘了。显然,到此还不会令人太兴奋,因为你只是擦除了磁盘中的数据。不过,你可以执行以下命令来确认设备是否已经挂载成功:
```
pi@raspberrypi3:~ $ cd /nas/data
pi@raspberrypi3:/nas/data $ cd /nas/backup
pi@raspberrypi3:/nas/backup $ mount
<...>
/etc/auto.usb on /nas type autofs (rw,relatime,fd=6,pgrp=463,timeout=300,minproto=5,maxproto=5,indirect)
<...>
/dev/sda1 on /nas/data type ext4 (rw,relatime,data=ordered)
/dev/sdb1 on /nas/backup type ext4 (rw,relatime,data=ordered)
```
首先进入对应目录以确保 autofs 能够挂载设备。Autofs 会跟踪文件系统的访问记录,并随时挂载所需要的设备。然后 `mount` 命令会显示这两个 USB 磁盘驱动器已经挂载到我们想要的位置了。
首先进入对应目录以确保 autofs 能够挂载设备。autofs 会跟踪文件系统的访问记录,并随时挂载所需要的设备。然后 `mount` 命令会显示这两个 USB 磁盘驱动器已经挂载到我们想要的位置了。
设置 autofs 的过程容易出错,如果第一次尝试失败,请不要沮丧。你可以上网搜索有关教程。
@@ -252,25 +168,21 @@ pi@raspberrypi3:/nas/backup $ mount
```
pi@raspberrypi:~ $ sudo apt install nfs-kernel-server
```
然后,需要告诉 NFS 服务器公开 `/nas/data` 目录,这是从树莓派外部可以访问的唯一设备(另一个用于备份)。编辑 `/etc/exports` 添加如下内容以允许所有可以访问 NAS 云盘的设备挂载存储:
```
/nas/data *(rw,sync,no_subtree_check)
```
更多有关限制挂载到单个设备的详细信息,请参阅 `man exports`。经过上面的配置,任何人都可以访问数据,只要他们可以访问 NFS 所需的端口:`111``2049`。我通过上面的配置,只允许通过路由器防火墙访问到我的家庭网络的 22 和 443 端口。这样,只有在家庭网络中的设备才能访问 NFS 服务器。
更多有关限制挂载到单个设备的详细信息,请参阅 `man exports`。经过上面的配置,任何人都可以访问数据,只要他们可以访问 NFS 所需的端口:`111``2049`。我通过上面的配置,只允许通过路由器防火墙访问到我的家庭网络的 22 和 443 端口。这样,只有在家庭网络中的设备才能访问 NFS 服务器。
如果要在 Linux 计算机挂载存储,运行以下命令:
```
you@desktop:~ $ sudo mkdir /nas/data
you@desktop:~ $ sudo mount -t nfs <raspberry-pi-hostname-or-ip>:/nas/data /nas/data
```
同样,我建议使用 autofs 来挂载该网络设备。如果需要其他帮助,请参看 [如何使用 Autofs 来挂载 NFS 共享][6]。
@@ -284,7 +196,7 @@ via: https://opensource.com/article/18/7/network-attached-storage-Raspberry-Pi
作者:[Manuel Dewald][a]
选题:[lujun9972](https://github.com/lujun9972)
译者:[jrg](https://github.com/jrglinux)
校对:[校对者ID](https://github.com/校对者ID)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
@@ -296,3 +208,4 @@ via: https://opensource.com/article/18/7/network-attached-storage-Raspberry-Pi
[5]: https://www.raspberrypi.org/blog/raspbian-stretch/
[6]: https://opensource.com/article/18/6/using-autofs-mount-nfs-shares

View File

@@ -1,19 +1,16 @@
Part-II 树莓派自建 NAS 云盘之数据自动备份
树莓派自建 NAS 云盘之——数据自动备份
======
> 把你的树莓派变成数据的安全之所。
![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/brain_data.png?itok=RH6NA32X)
在《树莓派自建 NAS 云盘》系列的 [第一篇][1] 文章中,我们讨论了建立 NAS 的一些基本步骤,添加了两块 1TB 的存储硬盘驱动(一个用于数据存储,一个用于数据备份),并且通过 网络文件系统NFS将数据存储盘挂载到远程终端上。本文是此系列的第二篇文章我们将探讨数据自动备份。数据自动备份保证了数据的安全为硬件损坏后的数据恢复提供便利以及减少了文件误操作带来的不必要的麻烦。
在《树莓派自建 NAS 云盘》系列的 [第一篇][1] 文章中,我们讨论了建立 NAS 的一些基本步骤,添加了两块 1TB 的存储硬盘驱动一个用于数据存储一个用于数据备份并且通过网络文件系统NFS将数据存储盘挂载到远程终端上。本文是此系列的第二篇文章我们将探讨数据自动备份。数据自动备份保证了数据的安全为硬件损坏后的数据恢复提供便利以及减少了文件误操作带来的不必要的麻烦。
![](https://opensource.com/sites/default/files/uploads/nas_part2.png)
### 备份策略
我们就从为小型 NAS 构想一个备份策略着手开始吧。我建议每天有时间节点有计划的去备份数据,以防止干扰到我们正常的访问 NAS比如备份时间点避开正在访问 NAS 并写入文件的时间点。举个例子,你可以每天凌晨 2 点去进行数据备份。
我们就从为小型 NAS 构想一个备份策略着手开始吧。我建议每天有时间节点有计划的去备份数据,以防止干扰到我们正常的访问 NAS比如备份时间点避开正在访问 NAS 并写入文件的时间点。举个例子,你可以每天凌晨 2 点去进行数据备份。
另外,你还得决定每天的备份需要被保留的时间长短,因为如果没有时间限制,存储空间很快就会被用完。一般每天的备份保留一周便可以,如果数据出了问题,你便可以很方便的从备份中恢复出来原数据。但是如果需要恢复数据到更久之前怎么办?可以将每周一的备份文件保留一个月、每个月的备份保留更长时间。让我们把每月的备份保留一年时间,每一年的备份保留更长时间、例如五年。
@@ -24,27 +21,24 @@ Part-II 树莓派自建 NAS 云盘之数据自动备份
* 每年 12 个月备份
* 每五年 5 个年备份
你应该还记得,我们搭建的备份盘和数据盘大小相同(每个 1 TB。如何将不止 10 个 1TB 数据的备份从数据盘存放到只有 1TB 大小的备份盘呢?如果你创建的是完整备份,这显然不可能。因此,你需要创建增量备份,它是每一份备份都基于上一份备份数据而创建的。增量备份方式不会每隔一天就成倍的去占用存储空间,它每天只会增加一点占用空间。
以下是我的情况:我的 NAS 自 2016 年 8 月开始运行,备份盘上有 20 个备份。目前,我在数据盘上存储了 406GB 的文件。我的备份盘用了 726GB。当然备份盘空间使用率在很大程度上取决于数据的更改频率但正如你所看到的增量备份不会占用 20 个完整备份所需的空间。然而随着时间的推移1TB 空间也可能不足以进行备份。一旦数据增长接近 1TB 限制(或任何备份盘容量),应该选择更大的备份盘空间并将数据移动转移过去。
### 利用 rsync 进行数据备份
利用 rsync 命令行工具可以生成完整备份。
利用 `rsync` 命令行工具可以生成完整备份。
```
pi@raspberrypi:~ $ rsync -a /nas/data/ /nas/backup/2018-08-01
```
这段命令将挂载在 /nas/data/ 目录下的数据盘中的数据进行了完整的复制备份。备份文件保存在 /nas/backup/2018-08-01 目录下。`-a` 参数是以归档模式进行备份,这将会备份所有的元数据,例如文件的修改日期、权限、拥有者以及软连接文件。
这段命令将挂载在 `/nas/data/` 目录下的数据盘中的数据进行了完整的复制备份。备份文件保存在 `/nas/backup/2018-08-01` 目录下。`-a` 参数是以归档模式进行备份,这将会备份所有的元数据,例如文件的修改日期、权限、拥有者以及软连接文件。
现在,你已经在 8 月 1 日创建了完整的初始备份,你将在 8 月 2 日创建第一个增量备份。
```
pi@raspberrypi:~ $ rsync -a --link-dest /nas/backup/2018-08-01/ /nas/data/ /nas/backup/2018-08-02
```
上面这行代码又创建了一个关于 `/nas/data` 目录中数据的备份。备份路径是 `/nas/backup/2018-08-02`。这里的参数 `--link-dest` 指定了一个备份文件所在的路径。这样,这次备份会与 `/nas/backup/2018-08-01` 的备份进行比对,只备份已经修改过的文件,未做修改的文件将不会被复制,而是创建一个到上一个备份文件中它们的硬链接。
@@ -53,142 +47,81 @@ pi@raspberrypi:~ $ rsync -a --link-dest /nas/backup/2018-08-01/ /nas/data/ /nas/
![](https://opensource.com/sites/default/files/uploads/backup_flow.png)
左侧框是在进行了第二次备份后的原数据状态。中间的盒子是昨天的备份。昨天的备份中只有图片 `file1.jpg` 并没有 `file2.txt` 。右侧的框反映了今天的增量备份。增量备份命令创建昨天不存在的 `file2.txt`。由于 `file1.jpg` 自昨天以来没有被修改,所以今天创建了一个硬链接,它不会额外占用磁盘上的空间。
左侧框是在进行了第二次备份后的原数据状态。中间的方块是昨天的备份。昨天的备份中只有图片 `file1.jpg` 并没有 `file2.txt` 。右侧的框反映了今天的增量备份。增量备份命令创建昨天不存在的 `file2.txt`。由于 `file1.jpg` 自昨天以来没有被修改,所以今天创建了一个硬链接,它不会额外占用磁盘上的空间。
### 自动化备份
你肯定也不想每天凌晨去输入命令进行数据备份吧。你可以创建一个任务定时去调用下面的脚本让它自动化备份
你肯定也不想每天凌晨去输入命令进行数据备份吧。你可以创建一个任务定时去调用下面的脚本让它自动化备份
```
#!/bin/bash
TODAY=$(date +%Y-%m-%d)
DATADIR=/nas/data/
BACKUPDIR=/nas/backup/
SCRIPTDIR=/nas/data/backup_scripts
LASTDAYPATH=${BACKUPDIR}/$(ls ${BACKUPDIR} | tail -n 1)
TODAYPATH=${BACKUPDIR}/${TODAY}
if [[ ! -e ${TODAYPATH} ]]; then
        mkdir -p ${TODAYPATH}
mkdir -p ${TODAYPATH}
fi
rsync -a --link-dest ${LASTDAYPATH} ${DATADIR} ${TODAYPATH} $@
${SCRIPTDIR}/deleteOldBackups.sh
```
第一段代码指定了数据路径、备份路、脚本路径以及昨天和今天的备份路径。第二段代码调用 rsync 命令。最后一段代码执行 `deleteOldBackups.sh` 脚本,它会清除一些过期的没有必要的备份数据。如果不想频繁的调用 `deleteOldBackups.sh`,你也可以手动去执行它。
第一段代码指定了数据路径、备份路、脚本路径以及昨天和今天的备份路径。第二段代码调用 `rsync` 命令。最后一段代码执行 `deleteOldBackups.sh` 脚本,它会清除一些过期的没有必要的备份数据。如果不想频繁的调用 `deleteOldBackups.sh`,你也可以手动去执行它。
下面是今天讨论的备份策略的一个简单完整的示例脚本。
```
#!/bin/bash
BACKUPDIR=/nas/backup/
function listYearlyBackups() {
        for i in 0 1 2 3 4 5
                do ls ${BACKUPDIR} | egrep "$(date +%Y -d "${i} year ago")-[0-9]{2}-[0-9]{2}" | sort -u | head -n 1
        done
for i in 0 1 2 3 4 5
do ls ${BACKUPDIR} | egrep "$(date +%Y -d "${i} year ago")-[0-9]{2}-[0-9]{2}" | sort -u | head -n 1
done
}
function listMonthlyBackups() {
        for i in 0 1 2 3 4 5 6 7 8 9 10 11 12
                do ls ${BACKUPDIR} | egrep "$(date +%Y-%m -d "${i} month ago")-[0-9]{2}" | sort -u | head -n 1
        done
for i in 0 1 2 3 4 5 6 7 8 9 10 11 12
do ls ${BACKUPDIR} | egrep "$(date +%Y-%m -d "${i} month ago")-[0-9]{2}" | sort -u | head -n 1
done
}
function listWeeklyBackups() {
        for i in 0 1 2 3 4
                do ls ${BACKUPDIR} | grep "$(date +%Y-%m-%d -d "last monday -${i} weeks")"
        done
for i in 0 1 2 3 4
do ls ${BACKUPDIR} | grep "$(date +%Y-%m-%d -d "last monday -${i} weeks")"
done
}
function listDailyBackups() {
        for i in 0 1 2 3 4 5 6
                do ls ${BACKUPDIR} | grep "$(date +%Y-%m-%d -d "-${i} day")"
        done
for i in 0 1 2 3 4 5 6
do ls ${BACKUPDIR} | grep "$(date +%Y-%m-%d -d "-${i} day")"
done
}
function getAllBackups() {
        listYearlyBackups
        listMonthlyBackups
        listWeeklyBackups
        listDailyBackups
listYearlyBackups
listMonthlyBackups
listWeeklyBackups
listDailyBackups
}
function listUniqueBackups() {
        getAllBackups | sort -u
getAllBackups | sort -u
}
function listBackupsToDelete() {
        ls ${BACKUPDIR} | grep -v -e "$(echo -n $(listUniqueBackups) |sed "s/ /\\\|/g")"
ls ${BACKUPDIR} | grep -v -e "$(echo -n $(listUniqueBackups) |sed "s/ /\\\|/g")"
}
cd ${BACKUPDIR}
listBackupsToDelete | while read file_to_delete; do
        rm -rf ${file_to_delete}
rm -rf ${file_to_delete}
done
```
这段脚本会首先根据你的备份策略列出所有需要保存的备份文件,然后它会删除那些再也不需要了的备份目录。
@@ -197,7 +130,6 @@ done
```
0 2 * * * /nas/data/backup_scripts/daily.sh
```
有关创建定时任务请参考 [cron 创建定时任务][2]。
@@ -218,12 +150,12 @@ via: https://opensource.com/article/18/8/automate-backups-raspberry-pi
作者:[Manuel Dewald][a]
选题:[lujun9972](https://github.com/lujun9972)
译者:[jrg](https://github.com/jrglinux)
校对:[校对者ID](https://github.com/校对者ID)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://opensource.com/users/ntlx
[1]: https://opensource.com/article/18/7/network-attached-storage-Raspberry-Pi
[1]: https://linux.cn/article-10104-1.html
[2]: https://opensource.com/article/17/11/how-use-cron-linux
[3]: https://nextcloud.com/

View File

@@ -1,17 +1,18 @@
使用 browser-mpris2Chrome 扩展将 YouTube 播放器控件添加到 Linux 桌面
使用 Chrome 扩展将 YouTube 播放器控件添加到 Linux 桌面
======
一个我怀念的 Unity 功能(虽然只使用了一小段时间)是在 Web 浏览器中访问 YouTube 等网站时自动获取 Ubuntu 声音指示器中的播放器控件,因此你可以直接从顶部栏暂停或停止视频,以及浏览视频/歌曲信息和预览。
这个 Unity 功能已经消失很久了,但我正在为 Gnome Shell 寻找类似的东西,然后我遇到了 **[browser-mpris2][1],这是一个为 Google Chrome/Chromium 实现 MPRIS v2 接口的扩展,目前只支持 YouTube**,我想可能会有一些 Linux Uprising 的读者会喜欢这个
一个我怀念的 Unity 功能(虽然只使用了一小段时间)是在 Web 浏览器中访问 YouTube 等网站时在 Ubuntu 声音指示器中自动出现播放器控件,因此你可以直接从顶部栏暂停或停止视频,以及浏览视频/歌曲信息和预览
**该扩展还适用于 Opera 和 Vivaldi 等基于 Chromium 的 Web 浏览器。**
**
** **browser-mpris2 也支持 Firefox但因为通过 about:debugging 加载扩展是临时的,而这是 browser-mpris2 所需要的,因此本文不包括 Firefox 的指导。开发人员[打算][2]将来将扩展提交到 Firefox 插件网站上。**
这个 Unity 功能已经消失很久了,但我正在为 Gnome Shell 寻找类似的东西,然后我遇到了 [browser-mpris2][1],这是一个为 Google Chrome/Chromium 实现 MPRIS v2 接口的扩展,目前只支持 YouTube我想可能会有一些读者会喜欢这个。
**使用此 Chrome 扩展,你可以在支持 MPRIS2 的 applets 中获得 YouTube 媒体播放器控件(播放、暂停、停止和查找
**。例如,如果你使用 Gnome Shell你可将 YouTube 媒体播放器控件作为永久通知,或者你可以使用 Media Player Indicator 之类的扩展来实现此目的。在 Cinnamon /Linux Mint with Cinnamon 中,它出现在声音 Applet 中。
该扩展还适用于 Opera 和 Vivaldi 等基于 Chromium 的 Web 浏览器。
**我无法在 Unity 上用它**我不知道为什么。我没有在不同桌面环境KDE、Xfce、MATE 等)中使用其他支持 MPRIS2 的 applet 尝试此扩展。如果你尝试过,请告诉我们它是否适用于你的桌面环境/支持 MPRIS2 的 applet
browser-mpris2 也支持 Firefox但因为通过 `about:debugging` 加载扩展是临时的,而这是 browser-mpris2 所需要的,因此本文不包括 Firefox 的指导。开发人员[打算][2]将来将扩展提交到 Firefox 插件网站上
使用此 Chrome 扩展,你可以在支持 MPRIS2 的 applets 中获得 YouTube 媒体播放器控件(播放、暂停、停止和查找
)。例如,如果你使用 Gnome Shell你可将 YouTube 媒体播放器控件作为永久显示的控件,或者你可以使用 Media Player Indicator 之类的扩展来实现此目的。在 Cinnamon /Linux Mint with Cinnamon 中,它出现在声音 Applet 中。
我无法在 Unity 上用它我不知道为什么。我没有在不同桌面环境KDE、Xfce、MATE 等)中使用其他支持 MPRIS2 的 applet 尝试此扩展。如果你尝试过,请告诉我们它是否适用于你的桌面环境/支持 MPRIS2 的 applet。
以下是在使用 Gnome Shell 的 Ubuntu 18.04 并装有 Chromium 浏览器的[媒体播放器指示器][3]的截图,其中显示了有关当前正在播放的 YouTube 视频的信息及其控件(播放/暂停,停止和查找):
@@ -19,42 +20,41 @@
在 Linux Mint 19 Cinnamon 中使用其默认声音 applet 和 Chromium 浏览器的截图:
![](https://2.bp.blogspot.com/-I2DuYetv7eQ/W3VtUUcg26I/AAAAAAAABXc/Tv-RemkyO60k6CC_mYUxewG-KfVgpFefACLcBGAs/s1600/browser-mpris2-cinnamon-linux-mint.png)
### 如何为 Google Chrom/Chromium安装 browser-mpris2
**1\. 如果你还没有安装 Git 就安装它**
1、 如果你还没有安装 Git 就安装它
在 Debian/Ubuntu/Linux Mint 中,使用此命令安装 git
```
sudo apt install git
```
**2\. 下载并安装 [browser-mpris2][1] 所需文件。**
2、 下载并安装 [browser-mpris2][1] 所需文件。
下面的命令克隆了 browser-mpris2 的 Git 仓库并将 chrome-mpris2 安装到 `/usr/local/bin/`(在一个你可以保存 browser-mpris2 文件夹的地方运行 `git clone ...` 命令,由于它会被 Chrome/Chromium 使用,你不能删除它):
下面的命令克隆了 browser-mpris2 的 Git 仓库并将 chrome-mpris2 安装到 `/usr/local/bin/`(在一个你可以保存 browser-mpris2 文件夹的地方运行 “git clone ...” 命令,由于它会被 Chrome/Chromium 使用,你不能删除它):
```
git clone https://github.com/otommod/browser-mpris2
sudo install browser-mpris2/native/chrome-mpris2 /usr/local/bin/
```
**3\. 在基于 Chrome/Chromium 的 Web 浏览器中加载此扩展。**
3、 在基于 Chrome/Chromium 的 Web 浏览器中加载此扩展。
![](https://3.bp.blogspot.com/-yEoNFj2wAXM/W3Vvewa979I/AAAAAAAABXo/dmltlNZk3J4sVa5jQenFFrT28ecklY92QCLcBGAs/s640/browser-mpris2-chrome-developer-load-unpacked.png)
打开 Google Chrome、Chromium、Opera 或 Vivaldi 浏览器,进入 Extensions 页面(在 URL 栏中输入 `chrome://extensions`),在屏幕右上角切换到`开发者模式`。然后选择 `Load Unpacked` 并选择 chrome-mpris2 目录(确保没有选择子文件夹)。
打开 Google Chrome、Chromium、Opera 或 Vivaldi 浏览器,进入 Extensions 页面(在 URL 栏中输入 `chrome://extensions`),在屏幕右上角切换到开发者模式。然后选择 Load Unpacked 并选择 chrome-mpris2 目录(确保没有选择子文件夹)。
复制扩展 ID 并保存它,因为你以后需要它(它类似于这样:`emngjajgcmeiligomkgpngljimglhhii`,但它会与你的不一样,因此确保使用你计算机中的 ID
**4\. 运行 **`install-chrome.py`**(在 `browser-mpris2/native` 文件夹中),指定扩展 id 和 chrome-mpris2 路径。
4、 运行 `install-chrome.py`(在 `browser-mpris2/native` 文件夹中),指定扩展 id 和 chrome-mpris2 路径。
在终端中使用此命令(将 `REPLACE-THIS-WITH-EXTENSION-ID` 替换为上一步中 `chrome://extensions` 下显示的 browser-mpris2 扩展 ID安装此扩展
```
browser-mpris2/native/install-chrome.py REPLACE-THIS-WITH-EXTENSION-ID /usr/local/bin/chrome-mpris2
```
你只需要运行此命令一次,无需将其添加到启动或其他类似的地方。你在 Google Chrome 或 Chromium 浏览器中播放的任何 YouTube 视频都应显示在你正在使用的任何 MPRISv2 applet 中。你无需重启 Web 浏览器。
@@ -66,7 +66,7 @@ via: https://www.linuxuprising.com/2018/08/add-youtube-player-controls-to-your.h
作者:[Logix][a]
选题:[lujun9972](https://github.com/lujun9972)
译者:[geekpi](https://github.com/geekpi)
校对:[校对者ID](https://github.com/校对者ID)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出

View File

@@ -0,0 +1,153 @@
如何提交你的第一个 Linux 内核补丁
======
> 学习如何做出你的首个 Linux 内核贡献,以及在开始之前你应该知道什么。
![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/linux_penguin_green.png?itok=ENdVzW22)
Linux 内核是最大且变动最快的开源项目之一,它由大约 53,600 个文件和近 2,000 万行代码组成。在全世界范围内超过 15,600 位程序员为它贡献代码Linux 内核项目的维护者使用了如下的协作模型。
![](https://opensource.com/sites/default/files/karnik_figure1.png)
本文中,为了便于在 Linux 内核中提交你的第一个贡献,我将为你提供一个必需的快速检查列表,以告诉你在提交补丁时,应该去查看和了解的内容。对于你贡献的第一个补丁的提交流程方面的更多内容,请阅读 [KernelNewbies 的第一个内核补丁教程][1]。
### 为内核作贡献
**第 1 步:准备你的系统。**
本文开始之前,假设你的系统已经具备了如下的工具:
+ 文本编辑器
+ Email 客户端
+ 版本控制系统例如git
**第 2 步:下载 Linux 内核代码仓库。**
```
git clone -b staging-testing
git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging.git
```
复制你的当前配置:
```
cp /boot/config-`uname -r`* .config
```
**第 3 步:构建/安装你的内核。**
```
make -jX
sudo make modules_install install
```
**第 4 步:创建一个分支并切换到该分支。**
```
git checkout -b first-patch
```
**第 5 步:更新你的内核并指向到最新的代码。**
```
git fetch origin
git rebase origin/staging-testing
```
**第 6 步:在最新的代码库上产生一个变更。**
使用 `make` 命令重新编译,确保你的变更没有错误。
**第 7 步:提交你的变更并创建一个补丁。**
```
git add <file>
git commit -s -v
git format-patch -o /tmp/ HEAD^
```
![](https://opensource.com/sites/default/files/karnik_figure2.png)
主题是由冒号分隔的文件名组成,跟着是使用祈使语态来描述补丁做了什么。空行之后是强制的 `signed off` 标记,最后是你的补丁的 `diff` 信息。
下面是另外一个简单补丁的示例:
![](https://opensource.com/sites/default/files/karnik_figure3.png)
接下来,[从命令行使用邮件][2](在本例子中使用的是 Mutt发送这个补丁
```
mutt -H /tmp/0001-<whatever your filename is>
```
使用 [get_maintainer.pl 脚本][11],去了解你的补丁应该发送给哪位维护者的列表。
### 提交你的第一个补丁之前,你应该知道的事情
* [Greg Kroah-Hartman](3) 的 [staging tree][4] 是提交你的 [第一个补丁][1] 的最好的地方,因为他更容易接受新贡献者的补丁。在你熟悉了补丁发送流程以后,你就可以去发送复杂度更高的子系统专用的补丁。
* 你也可以从纠正代码中的编码风格开始。想学习更多关于这方面的内容,请阅读 [Linux 内核编码风格文档][5]。
* [checkpatch.pl][6] 脚本可以帮你检测编码风格方面的错误。例如,运行如下的命令:`perl scripts/checkpatch.pl -f drivers/staging/android/* | less`
* 你可以去补全开发者留下的 TODO 注释中未完成的内容:`find drivers/staging -name TODO`
* [Coccinelle][7] 是一个模式匹配的有用工具。
* 阅读 [归档的内核邮件][8]。
* 为找到灵感,你可以去遍历 [linux.git 日志][9]去查看以前的作者的提交内容。
* 注意:不要与你的补丁的审核者在邮件顶部交流!下面就是一个这样的例子:
**错误的方式:**
```
Chris,
Yes lets schedule the meeting tomorrow, on the second floor.
> On Fri, Apr 26, 2013 at 9:25 AM, Chris wrote:
> Hey John, I had some questions:
> 1. Do you want to schedule the meeting tomorrow?
> 2. On which floor in the office?
> 3. What time is suitable to you?
```
(注意那最后一个问题,在回复中无意中落下了。)
**正确的方式:**
```
Chris,
See my answers below...
> On Fri, Apr 26, 2013 at 9:25 AM, Chris wrote:
> Hey John, I had some questions:
> 1. Do you want to schedule the meeting tomorrow?
Yes tomorrow is fine.
> 2. On which floor in the office?
Let's keep it on the second floor.
> 3. What time is suitable to you?
09:00 am would be alright.
```
(所有问题全部回复,并且这种方式还保存了阅读的时间。)
* [Eudyptula challenge][10] 是学习内核基础知识的非常好的方式。
想学习更多内容,阅读 [KernelNewbies 的第一个内核补丁教程][1]。之后如果你还有任何问题,可以在 [kernelnewbies 邮件列表][12] 或者 [#kernelnewbies IRC channel][13] 中提问。
--------------------------------------------------------------------------------
via: https://opensource.com/article/18/8/first-linux-kernel-patch
作者:[Sayli Karnik][a]
选题:[lujun9972](https://github.com/lujun9972)
译者:[qhwdw](https://github.com/qhwdw)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://opensource.com/users/sayli
[1]:https://kernelnewbies.org/FirstKernelPatch
[2]:https://opensource.com/life/15/8/top-4-open-source-command-line-email-clients
[3]:https://twitter.com/gregkh
[4]:https://www.kernel.org/doc/html/v4.15/process/2.Process.html
[5]:https://www.kernel.org/doc/html/v4.10/process/coding-style.html
[6]:https://github.com/torvalds/linux/blob/master/scripts/checkpatch.pl
[7]:http://coccinelle.lip6.fr/
[8]:linux-kernel@vger.kernel.org
[9]:https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/log/
[10]:http://eudyptula-challenge.org/
[11]:https://github.com/torvalds/linux/blob/master/scripts/get_maintainer.pl
[12]:https://kernelnewbies.org/MailingList
[13]:https://kernelnewbies.org/IRC

View File

@@ -0,0 +1,133 @@
我应该使用哪些稳定版内核?
======
> 本文作者 Greg Kroah-Hartman 是 Linux 稳定版内核的维护负责人。
很多人都问我这样的问题,在他们的产品/设备/笔记本/服务器等上面应该使用什么样的稳定版内核。一直以来,尤其是那些现在已经延长支持时间的内核,都是由我和其他人提供支持,因此,给出这个问题的答案并不是件容易的事情。在这篇文章我将尝试去给出我在这个问题上的看法。当然,你可以任意选用任何一个你想去使用的内核版本,这里只是我的建议。
和以前一样,在这里给出的这些看法只代表我个人的意见。
### 可选择的内核有哪些
下面列出了我建议你应该去使用的内核的列表,从最好的到最差的都有。我在下面将详细介绍,但是如果你只想得到一个结论,它就是你想要的:
建议你使用的内核的分级,从最佳的方案到最差的方案如下:
* 你最喜欢的 Linux 发行版支持的内核
* 最新的稳定版
* 最新的 LTS (长期支持)版本
* 仍然处于维护状态的老的 LTS 版本
绝对不要去使用的内核:
* 不再维护的内核版本
给上面的列表给出具体的数字,今天是 2018 年 8 月 24 日kernel.org 页面上可以看到是这样:
![][1]
因此,基于上面的列表,那它应该是:
* 4.18.5 是最新的稳定版
* 4.14.67 是最新的 LTS 版本
* 4.9.124、4.4.152、以及 3.16.57 是仍然处于维护状态的老的 LTS 版本
* 4.17.19 和 3.18.119 是过去 60 天内有过发布的 “生命周期终止” 的内核版本,它们仍然保留在 kernel.org 站点上,是为了仍然想去使用它们的那些人。
非常容易,对吗?
Ok现在我给出这样选择的一些理由
### Linux 发行版内核
对于大多数 Linux 用户来说,最好的方案就是使用你喜欢的 Linux 发行版的内核。就我本人而言,我比较喜欢基于社区的、内核不断滚动升级的用最新内核的 Linux 发行版,并且它也是由开发者社区来支持的。这种类型的发行版有 Fedora、openSUSE、Arch、Gentoo、CoreOS以及其它的。
所有这些发行版都使用了上游的最新的稳定版内核,并且确保定期打了需要的 bug 修复补丁。当它拥有了最新的修复之后([记住所有的修复都是安全修复][2]),这就是你可以使用的最安全、最好的内核之一。
有些社区的 Linux 发行版需要很长的时间才发行一个新内核版本但是最终发行的版本和所支持的内核都是非常好的。这些也都非常好用Debian 和 Ubuntu 就是这样的例子。
如果我没有在这里列出你所喜欢的发行版,并不是意味着它们的内核不够好。查看这些发行版的网站,确保它们的内核包是不断应用最新的安全补丁进行升级过的,那么它就应该是很好的。
许多人好像喜欢旧式、“传统” 模式的发行版,使用 RHEL、SLES、CentOS 或者 “LTS” Ubuntu 发行版。这些发行版挑选一个特定的内核版本,然后使用好几年,甚至几十年。他们反向移植了最新的 bug 修复,有时也有一些内核的新特性,所有的只是追求堂吉诃德式的保持版本号不变而已,尽管他们已经在那个旧的内核版本上做了成千上万的变更。这项工作是一项真正吃力不讨好的工作,分配到这些任务的开发人员做了一些精彩的工作才能实现这些目标。所以如果你希望永远不看到你的内核版本号发生过变化,那么就使用这些发行版。他们通常会为使用而付出一些钱,当发生错误时能够从这些公司得到一些支持,那就是值得的。
所以,你能使用的最好的内核是你可以求助于别人,而别人可以为你提供支持的内核。使用那些支持,你通常都已经为它支付过费用了(对于企业发行版),而这些公司也知道他们职责是什么。
但是,如果你不希望去依赖别人,而是希望你自己管理你的内核,或者你有发行版不支持的硬件,那么你应该去使用最新的稳定版:
### 最新的稳定版
最新的稳定版内核是 Linux 内核开发者社区宣布为“稳定版”的最新的一个内核。大约每三个月,社区发行一个包含了对所有新硬件支持的、新的稳定版内核,最新版的内核不但改善内核性能,同时还包含内核各部分的 bug 修复。接下来的三个月之后,进入到下一个内核版本的 bug 修复将被反向移植进入这个稳定版内核中,因此,使用这个内核版本的用户将确保立即得到这些修复。
最新的稳定版内核通常也是主流社区发行版所使用的内核,因此你可以确保它是经过测试和拥有大量用户使用的内核。另外,内核社区(全部开发者超过 4000 人)也将帮助这个发行版提供对用户的支持,因为这是他们做的最新的一个内核。
三个月之后,将发行一个新的稳定版内核,你应该去更新到它以确保你的内核始终是最新的稳定版,因为当最新的稳定版内核发布之后,对你的当前稳定版内核的支持通常会落后几周时间。
如果你在上一个 LTS (长期支持)版本发布之后购买了最新的硬件,为了能够支持最新的硬件,你几乎是绝对需要去运行这个最新的稳定版内核。对于台式机或新的服务器,最新的稳定版内核通常是推荐运行的内核。
### 最新的 LTS 版本
如果你的硬件为了保证正常运行(像大多数的嵌入式设备),需要依赖供应商的源码<ruby>树外<rt>out-of-tree</rt></ruby>的补丁,那么对你来说,最好的内核版本是最新的 LTS 版本。这个版本拥有所有进入稳定版内核的最新 bug 修复,以及大量的用户测试和使用。
请注意,这个最新的 LTS 版本没有新特性,并且也几乎不会增加对新硬件的支持,因此,如果你需要使用一个新设备,那你的最佳选择就是最新的稳定版内核,而不是最新的 LTS 版内核。
另外,对于这个 LTS 版本的用户来说,他也不用担心每三个月一次的“重大”升级。因此,他们将一直坚持使用这个 LTS 版本,并每年升级一次,这是一个很好的实践。
使用这个 LTS 版本的不利方面是,你没法得到在最新版本内核上实现的内核性能提升,除非在未来的一年中,你升级到下一个 LTS 版内核。
另外,如果你使用的这个内核版本有问题,你所做的第一件事情就是向任意一位内核开发者报告发生的问题,并向他们询问,“最新的稳定版内核中是否也存在这个问题?”并且,你需要意识到,对它的支持不会像使用最新的稳定版内核那样容易得到。
现在,如果你坚持使用一个有大量的补丁集的内核,并且不希望升级到每年一次的新 LTS 版内核上,那么,或许你应该去使用老的 LTS 版内核:
### 老的 LTS 版本
传统上,这些版本都由社区提供 2 年时间的支持,有时候当一个重要的 Linux 发行版(像 Debian 或 SLES依赖它时这个支持时间会更长。然而在过去一年里感谢 Google、Linaro、Linaro 成员公司、[kernelci.org][3]、以及其它公司在测试和基础设施上的大量投入,使得这些老的 LTS 版内核得到更长时间的支持。
最新的 LTS 版本以及它们将被支持多长时间,这是 2018 年 8 月 24 日显示在 [kernel.org/category/releases.html][4] 上的信息:
![][5]
Google 和其它公司希望这些内核使用的时间更长的原因是,由于现在几乎所有的 SoC 芯片的疯狂的(也有人说是打破常规)开发模型。这些设备在芯片发行前几年就启动了他们的开发周期,而那些代码从来不会合并到上游,最终结果是新打造的芯片是基于一个 2 年以前的老内核发布的。这些 SoC 的代码树通常增加了超过 200 万行的代码,这使得它们成为我们前面称之为“类 Linux 内核“的东西。
如果在 2 年后,这个 LTS 版本停止支持,那么来自社区的支持将立即停止,并且没有人对它再进行 bug 修复。这导致了在全球各地数以百万计的非常不安全的设备仍然在使用中,这对任何生态系统来说都不是什么好事情。
由于这种依赖,这些公司现在要求新设备不断更新到最新的 LTS 版本——这些为它们特定发布的版本(例如现在的每个 4.9.y 版本)。其中一个这样的例子就是新 Android 设备对内核版本的要求,这些新设备所带的 “Andrid O” 版本(和现在的 “Android P” 版本)指定了最低允许使用的内核版本,并且 Andoird 安全更新版本也开始越来越频繁在设备上要求使用这些 “.y” 版本。
我注意到一些生产商现在已经在做这些事情。Sony 是其中一个非常好的例子,在他们的大多数新手机上,通过他们每季度的安全更新版本,将设备更新到最新的 4.4.y 发行版上。另一个很好的例子是一家小型公司 Essential据我所知他们持续跟踪 4.4.y 版本的速度比其它公司都快。
当使用这种老的内核时有个重大警告。反向移植到这种内核中的安全修复不如最新版本的 LTS 内核多,因为这些使用老的 LTS 内核的设备的传统模式是一个更加简化的用户模式。这些内核不能用于任何“通用计算”模式中,在这里用的是<ruby>不可信用户<rt>untrusted user</rt></ruby>或虚拟机,极大地削弱了对老的内核做像最近的 Spectre 这样的修复的能力,如果在一些分支中存在这样的 bug 的话。
因此,仅在你能够完全控制的设备,或者限定在一个非常强大的安全模型(像 Android 一样强制使用 SELinux 和应用程序隔离)时使用老的 LTS 版本。绝对不要在有不可信用户/程序,或虚拟机的服务器上使用这些老的 LTS 版内核。
此外,如果社区对它有支持的话,社区对这些老的 LTS 版内核相比正常的 LTS 版内核的支持要少的多。如果你使用这些内核,那么你只能是一个人在战斗,你需要有能力去独自支持这些内核,或者依赖你的 SoC 供应商为你提供支持(需要注意的是,几乎没有供应商会为你提供支持,因此,你要特别注意 ……)。
### 不再维护的内核发行版
更让人感到惊讶的事情是,许多公司只是随便选一个内核发行版,然后将它封装到它们的产品里,并将它毫不犹豫地承载到数十万的部件中。其中一个这样的糟糕例子是 Lego Mindstorm 系统,不知道是什么原因在它们的设备上随意选取了一个 -rc 的内核发行版。-rc 的发行版是开发中的版本,根本没有 Linux 内核开发者认为它适合任何人使用,更不用说是数百万的用户了。
当然,如果你愿意,你可以随意地使用它,但是需要注意的是,可能真的就只有你一个人在使用它。社区不会为你提供支持,因为他们不可能关注所有内核版本的特定问题,因此如果出现错误,你只能独自去解决它。对于一些公司和系统来说,这么做可能还行,但是如果没有为此有所规划,那么要当心因此而产生的“隐性”成本。
### 总结
基于以上原因,下面是一个针对不同类型设备的简短列表,这些设备我推荐适用的内核如下:
* 笔记本 / 台式机:最新的稳定版内核
* 服务器:最新的稳定版内核或最新的 LTS 版内核
* 嵌入式设备:最新的 LTS 版内核或老的 LTS 版内核(如果使用的安全模型非常强大和严格)
至于我,在我的机器上运行什么样的内核?我的笔记本运行的是最新的开发版内核(即 Linus 的开发树)再加上我正在做修改的内核,我的服务器上运行的是最新的稳定版内核。因此,尽管我负责 LTS 发行版的支持工作,但我自己并不使用 LTS 版内核,除了在测试系统上。我依赖于开发版和最新的稳定版内核,以确保我的机器运行的是目前我们所知道的最快的也是最安全的内核版本。
--------------------------------------------------------------------------------
via: http://kroah.com/log/blog/2018/08/24/what-stable-kernel-should-i-use/
作者:[Greg Kroah-Hartman][a]
选题:[lujun9972](https://github.com/lujun9972)
译者:[qhwdw](https://github.com/qhwdw)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:http://kroah.com
[1]:https://s3.amazonaws.com/kroah.com/images/kernel.org_2018_08_24.png
[2]:http://kroah.com/log/blog/2018/02/05/linux-kernel-release-model/
[3]:https://kernelci.org/
[4]:https://www.kernel.org/category/releases.html
[5]:https://s3.amazonaws.com/kroah.com/images/kernel.org_releases_2018_08_24.png

View File

@@ -3,25 +3,28 @@
![](https://www.ostechnix.com/wp-content/uploads/2018/06/arch_linux_wallpaper-720x340.png)
自我更新 Arch Linux 桌面以来已经有一个月了。今天我试着更新我的 Arch Linux 系统,然后遇到一个错误 **“errorfailed to commit transaction (conflicting files) stfl/usr/lib/libstfl.so.0 exists in filesystem”**。看起来是 pacman 无法更新一个已经存在于文件系统上的库 (/usr/lib/libstfl.so.0)。如果你也遇到了同样的问题,下面是一个快速解决方案。
自我更新 Arch Linux 桌面以来已经有一个月了。今天我试着更新我的 Arch Linux 系统,然后遇到一个错误 “errorfailed to commit transaction (conflicting files) stfl/usr/lib/libstfl.so.0 exists in filesystem”。看起来是 pacman 无法更新一个已经存在于文件系统上的库 (/usr/lib/libstfl.so.0)。如果你也遇到了同样的问题,下面是一个快速解决方案。
### 解决 Arch Linux 中出现的 “errorfailed to commit transaction (conflicting files)”
有三种方法。
1。简单在升级时忽略导致问题的 **stfl** 库并尝试再次更新系统。请参阅此指南以了解 [**如何在更新时忽略软件包 **][1]。
1。简单在升级时忽略导致问题的 stfl 库并尝试再次更新系统。请参阅此指南以了解 [如何在更新时忽略软件包][1]。
2。使用命令覆盖这个包
```
$ sudo pacman -Syu --overwrite /usr/lib/libstfl.so.0
```
3。手工删掉 stfl 库然后再次升级系统。请确保目标包不被其他任何重要的包所依赖。可以通过去 archlinux.org 查看是否有这种冲突。
```
$ sudo rm /usr/lib/libstfl.so.0
```
现在,尝试更新系统:
```
$ sudo pacman -Syu
```
@@ -41,7 +44,7 @@ via: https://www.ostechnix.com/how-to-solve-error-failed-to-commit-transaction-c
作者:[SK][a]
选题:[lujun9972](https://github.com/lujun9972)
译者:[lujun9972](https://github.com/lujun9972)
校对:[校对者ID](https://github.com/校对者ID)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出

View File

@@ -1,10 +1,11 @@
如何在 Linux 中列出可用的软件包组
======
我们知道,如果想要在 Linux 中安装软件包,可以使用软件包管理器来进行安装。由于系统管理员需要频繁用到软件包管理器,所以它是 Linux 当中的一个重要工具。
但是如果想一次性安装一个软件包组,在 Linux 中有可能吗?又如何通过命令去实现呢?
在 Linux 中确实可以用软件包管理器来达到这样的目的。很多软件包管理器都有这样的选项来实现这个功能,但就我所知,`apt``apt-get` 软件包管理器却并没有这个选项。因此对基于 Debian 的系统,需要使用的命令是 `tasksel`,而不是 `apt``apt-get` 这样的官方软件包管理器。
在 Linux 中确实可以用软件包管理器来达到这样的目的。很多软件包管理器都有这样的选项来实现这个功能,但就我所知,`apt``apt-get` 软件包管理器却并没有这个选项。因此对基于 Debian 的系统,需要使用的命令是 `tasksel`,而不是 `apt` `apt-get` 这样的官方软件包管理器。
在 Linux 中安装软件包组有很多好处。对于 LAMP 来说,安装过程会包含多个软件包,但如果安装软件包组命令来安装,只安装一个包就可以了。
@@ -13,19 +14,20 @@
软件包组是一组用于公共功能的软件包,包括系统工具、声音和视频。 安装软件包组的过程中,会获取到一系列的依赖包,从而大大节省了时间。
**推荐阅读:**
**(#)** [如何在 Linux 上按照大小列出已安装的软件包][1]
**(#)** [如何在 Linux 上查看/列出可用的软件包更新][2]
**(#)** [如何在 Linux 上查看软件包的安装/更新/升级/移除/卸载时间][3]
**(#)** [如何在 Linux 上查看一个软件包的详细信息][4]
**(#)** [如何查看一个软件包是否在你的 Linux 发行版上可用][5]
**(#)** [萌新指导:一个可视化的 Linux 包管理工具][6]
**(#)** [老手必会:命令行软件包管理器的用法][7]
- [如何在 Linux 上按照大小列出已安装的软件包][1]
- [如何在 Linux 上查看/列出可用的软件包更新][2]
- [如何在 Linux 上查看软件包的安装/更新/升级/移除/卸载时间][3]
- [如何在 Linux 上查看一个软件包的详细信息][4]
- [如何查看一个软件包是否在你的 Linux 发行版上可用][5]
- [萌新指导:一个可视化的 Linux 包管理工具][6]
- [老手必会:命令行软件包管理器的用法][7]
### 如何在 CentOS/RHEL 系统上列出可用的软件包组
RHEL 和 CentOS 系统使用的是 RPM 软件包,因此可以使用 `yum` 软件包管理器来获取相关的软件包信息。
`yum` 是 Yellowdog Updater, Modified 的缩写,它是一个用于基于 RPM 系统(例如 RHEL 和 CentOS开源的命令行软件包管理工具。它是从发库或其它第三方库中获取、安装、删除、查询和管理 RPM 包的主要工具。
`yum`Yellowdog Updater, Modified 的缩写,它是一个用于基于 RPM 系统(例如 RHEL 和 CentOS开源的命令行软件包管理工具。它是从发行版仓库或其它第三方库中获取、安装、删除、查询和管理 RPM 包的主要工具。
**推荐阅读:** [使用 yum 命令在 RHEL/CentOS 系统上管理软件包][8]
@@ -69,10 +71,9 @@ Available Language Groups:
.
.
Done
```
如果需要列出相关联的软件包,可以执行以下这个命令。下面的例子是列出和 Performance Tools 组相关联的软件包。
如果需要列出相关联的软件包,可以执行以下这个命令。下面的例子是列出和 Performance Tools 组相关联的软件包。
```
# yum groupinfo "Performance Tools"
@@ -103,18 +104,17 @@ Group: Performance Tools
tiobench
tuned
tuned-utils
```
### 如何在 Fedora 系统上列出可用的软件包组
Fedora 系统使用的是 DNF 软件包管理器,因此可以通过 DNF 软件包管理器来获取相关的信息。
DNF 的含义是 Dandified yum。DNF 软件包管理器是 YUM 软件包管理器的一个分支,它使用 hawkey/libsolv 库作为后端。从 Fedora 18 开始Aleš Kozumplík 开始着手 DNF 的开发直到在Fedora 22 开始加入到系统中。
DNF 的含义是 Dandified yum。DNF 软件包管理器是 YUM 软件包管理器的一个分支,它使用 hawkey/libsolv 库作为后端。从 Fedora 18 开始Aleš Kozumplík 开始着手 DNF 的开发,直到在 Fedora 22 开始加入到系统中。
`dnf` 命令可以在 Fedora 22 及更高版本上安装、更新、搜索和删除软件包, 它可以自动解决软件包的依赖关系并其顺利安装,不会产生问题。
由于一些长期未被解决的问题的存在YUM 被 DNF 逐渐取代了。而 Aleš Kozumplík 的 DNF 却并未对 yum 的这些问题作出修补,他认为这是技术上的难题YUM 团队也不接受这些更改。而且 YUM 的代码量有 5.6 万行,而 DNF 只有 2.9 万行。因此已经不需要沿着 YUM 的方向继续开发了,重新开一个分支才是更好的选择。
YUM 被 DNF 取代是由于 YUM 中存在一些长期未被解决的问题。为什么 Aleš Kozumplík 没有对 yum 的这些问题作出修补,他认为补丁解决存在技术上的难题,YUM 团队也不会马上接受这些更改,还有一些重要的问题。而且 YUM 的代码量有 5.6 万行,而 DNF 只有 2.9 万行。因此已经不需要沿着 YUM 的方向继续开发了,重新开一个分支才是更好的选择。
**推荐阅读:** [在 Fedora 系统上使用 DNF 命令管理软件包][9]
@@ -167,13 +167,11 @@ Available Groups:
Hardware Support
Sound and Video
System Tools
```
如果需要列出相关联的软件包,可以执行以下这个命令。下面的例子是列出和 Editor 组相关联的软件包。
如果需要列出相关联的软件包,可以执行以下这个命令。下面的例子是列出和 Editor 组相关联的软件包。
```
# dnf groupinfo Editors
Last metadata expiration check: 0:04:57 ago on Sun 09 Sep 2018 07:10:36 PM IST.
@@ -267,7 +265,7 @@ i | yast2_basis | 20150918-25.1 | @System |
| yast2_install_wf | 20150918-25.1 | Main Repository (OSS) |
```
如果需要列出相关联的软件包,可以执行以下这个命令。下面的例子是列出和 file_server 组相关联的软件包。另外 `zypper` 还允许用户使用不同的选项执行相同的操作。
如果需要列出相关联的软件包,可以执行以下这个命令。下面的例子是列出和 file_server 组相关联的软件包。另外 `zypper` 还允许用户使用不同的选项执行相同的操作。
```
# zypper info file_server
@@ -346,7 +344,7 @@ Contents :
| yast2-tftp-server | package | Recommended
```
如果需要列出相关联的软件包,可以执行以下这个命令。
如果需要列出相关联的软件包,可以执行以下这个命令。
```
# zypper info pattern file_server
@@ -385,7 +383,7 @@ Contents :
| yast2-tftp-server | package | Recommended
```
如果需要列出相关联的软件包,可以执行以下这个命令。
如果需要列出相关联的软件包,可以执行以下这个命令。
```
# zypper info -t pattern file_server
@@ -431,7 +429,7 @@ Contents :
[tasksel][11] 是 Debian/Ubuntu 系统上一个很方便的工具,只需要很少的操作就可以用它来安装好一组软件包。可以在 `/usr/share/tasksel` 目录下的 `.desc` 文件中安排软件包的安装任务。
默认情况下,`tasksel` 工具是作为 Debian 系统的一部分安装的,但桌面版 Ubuntu 则没有自带 `tasksel`类似软件包管理器中的元包meta-packages
默认情况下,`tasksel` 工具是作为 Debian 系统的一部分安装的,但桌面版 Ubuntu 则没有自带 `tasksel`这个功能类似软件包管理器中的元包meta-packages
`tasksel` 工具带有一个基于 zenity 的简单用户界面,例如命令行中的弹出图形对话框。
@@ -483,7 +481,7 @@ u openssh-server OpenSSH server
u server Basic Ubuntu server
```
如果需要列出相关联的软件包,可以执行以下这个命令。下面的例子是列出和 lamp-server 组相关联的软件包。
如果需要列出相关联的软件包,可以执行以下这个命令。下面的例子是列出和 lamp-server 组相关联的软件包。
```
# tasksel --task-desc "lamp-server"
@@ -494,7 +492,7 @@ Selects a ready-made Linux/Apache/MySQL/PHP server.
基于 Arch Linux 的系统使用的是 pacman 软件包管理器,因此可以通过 pacman 软件包管理器来获取相关的信息。
pacman 是 package manager 的缩写。`pacman` 可以用于安装、构建、删除和管理 Arch Linux 软件包。`pacman` 使用 libalpmArch Linux Package Management 库ALPM作为后端来执行所有操作。
pacman 是 package manager 的缩写。`pacman` 可以用于安装、构建、删除和管理 Arch Linux 软件包。`pacman` 使用 libalpmArch Linux Package Management 库ALPM作为后端来执行所有操作。
**推荐阅读:** [使用 pacman 在基于 Arch Linux 的系统上管理软件包][13]
@@ -536,10 +534,9 @@ realtime
sugar-fructose
tesseract-data
vim-plugins
```
如果需要列出相关联的软件包,可以执行以下这个命令。下面的例子是列出和 gnome 组相关联的软件包。
如果需要列出相关联的软件包,可以执行以下这个命令。下面的例子是列出和 gnome 组相关联的软件包。
```
# pacman -Sg gnome
@@ -603,7 +600,6 @@ Interrupt signal received
```
# pacman -Sg gnome | wc -l
64
```
--------------------------------------------------------------------------------
@@ -613,7 +609,7 @@ via: https://www.2daygeek.com/how-to-list-an-available-package-groups-in-linux/
作者:[Prakash Subramanian][a]
选题:[lujun9972](https://github.com/lujun9972)
译者:[HankChow](https://github.com/HankChow)
校对:[校对者ID](https://github.com/校对者ID)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出

View File

@@ -1,10 +1,9 @@
Clinews - 从命令行阅读新闻和最新头条
Clinews从命令行阅读新闻和最新头条
======
![](https://www.ostechnix.com/wp-content/uploads/2018/09/clinews-720x340.jpeg)
不久前,我们写了一个名为 [**InstantNews**][1] 的命令行新闻客户端,它可以帮助你立即在命令行阅读新闻和最新头条新闻。今天,我偶然发现了一个名为 **Clinews** 的类似,它的其功能与此相同 - 在终端阅读来自热门网站的新闻和最新头条,还有博客。你无需安装 GUI 应用或移动应用。你可以直接从终端阅读世界上正在发生的事情。它是使用 **NodeJS** 编写的免费开源程序。
不久前,我们写了一个名为 [InstantNews][1] 的命令行新闻客户端,它可以帮助你立即在命令行阅读新闻和最新头条新闻。今天,我偶然发现了一个名为 **Clinews** 的类似,它的其功能与此相同 —— 在终端阅读来自热门网站的新闻和最新头条,还有博客。你无需安装 GUI 应用或移动应用。你可以直接从终端阅读世界上正在发生的事情。它是使用 **NodeJS** 编写的自由开源程序。
### 安装 Clinews
@@ -30,22 +29,20 @@ $ npm -i yarn
### 配置 News API
Clinews 从 [**News API**][2] 中检索所有新闻标题。News API 是一个简单易用的API它返回当前在一系列新闻源和博客上发布的头条的 JSON 元数据。它目前提供来自 70 个热门源的实时头条,包括 Ars Technica、BBC、Blooberg、CNN、每日邮报、Engadget、ESPN、金融时报、谷歌新闻、hacker NewsIGN、Mashable、国家地理、Reddit r/all、路透社、 Speigel Online、Techcrunch、The Guardian、The Hindu、赫芬顿邮报、纽约时报、The Next Web、华尔街日报今日美国和[**等等**][3]。
Clinews 从 [News API][2] 中检索所有新闻标题。News API 是一个简单易用的 API它返回当前在一系列新闻源和博客上发布的头条的 JSON 元数据。它目前提供来自 70 个热门源的实时头条,包括 Ars Technica、BBC、Blooberg、CNN、每日邮报、Engadget、ESPN、金融时报、谷歌新闻、hacker NewsIGN、Mashable、国家地理、Reddit r/all、路透社、 Speigel Online、Techcrunch、The Guardian、The Hindu、赫芬顿邮报、纽约时报、The Next Web、华尔街日报今日美国和[等等][3]。
首先,你需要 News API 的 API 密钥。进入 [**https://newsapi.org/register**][4] 并注册一个免费帐户来获取 API 密钥。
首先,你需要 News API 的 API 密钥。进入 [https://newsapi.org/register][4] 并注册一个免费帐户来获取 API 密钥。
从 News API 获得 API 密钥后,编辑 **.bashrc**
从 News API 获得 API 密钥后,编辑 `.bashrc`
```
$ vi ~/.bashrc
```
在最后添加 newsapi API 密钥,如下所示:
```
export IN_API_KEY="Paste-API-key-here"
```
请注意,你需要将密钥粘贴在双引号内。保存并关闭文件。
@@ -54,7 +51,6 @@ export IN_API_KEY="Paste-API-key-here"
```
$ source ~/.bashrc
```
完成。现在继续并从新闻源获取最新的头条新闻。
@@ -65,10 +61,9 @@ $ source ~/.bashrc
```
$ news fetch the-hindu
```
这里,**“the-hindu”** 是新闻源的源id获取 id
这里,`the-hindu` 是新闻源的源id获取 id
上述命令将从 The Hindu 新闻站获取最新的 10 个头条,并将其显示在终端中。此外,它还显示新闻的简要描述、发布的日期和时间以及到源的实际链接。
@@ -82,7 +77,6 @@ $ news fetch the-hindu
```
$ news sources
```
**示例输出:**
@@ -91,22 +85,20 @@ $ news sources
正如你在上面的截图中看到的Clinews 列出了所有新闻源,包括新闻源的名称、获取 ID、网站描述、网站 URL 以及它所在的国家/地区。在撰写本指南时Clinews 目前支持 70 多个新闻源。
Clinews 还可以搜索符合搜索条件/术语的所有源的新闻报道。例如,要列出包含单词 **“Tamilnadu”** 的所有新闻报道,请使用以下命令:
Clinews 还可以搜索符合搜索条件/术语的所有源的新闻报道。例如,要列出包含单词 “Tamilnadu” 的所有新闻报道,请使用以下命令:
```
$ news search "Tamilnadu"
```
此命令将会筛选所有新闻源中含有 **Tamilnadu** 的报道。
此命令将会筛选所有新闻源中含有 Tamilnadu 的报道。
Clinews有一些额外的标志可以帮助你
Clinews 有一些其它选项可以帮助你
* 限制你想看的新闻报道的数量,
  * 排序新闻报道(热门、最新),
  * 智能显示新闻报道分类(例如商业、娱乐、游戏、大众、音乐、政治、科学和自然、体育、技术)
更多详细信息,请参阅帮助部分:
```
@@ -126,7 +118,7 @@ via: https://www.ostechnix.com/clinews-read-news-and-latest-headlines-from-comma
作者:[SK][a]
选题:[lujun9972](https://github.com/lujun9972)
译者:[geekpi](https://github.com/geekpi)
校对:[校对者ID](https://github.com/校对者ID)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出

View File

@@ -1,27 +1,25 @@
Hegemon - 使用 Rust 编写的模块化系统监视程序
Hegemon使用 Rust 编写的模块化系统监视程序
======
![](https://www.ostechnix.com/wp-content/uploads/2018/09/hegemon-720x340.png)
在类 Unix 系统中监视运行进程时,最常用的程序是 **top** 和 top 的增强版 **htop**。我个人最喜欢的是 htop。但是开发人员不时会发布这些程序的替代品。top 和 htop 工具的一个替代品是 **Hegemon**。它是使用 **Rust** 语言编写的模块化系统监视程序。
在类 Unix 系统中监视运行进程时,最常用的程序是 `top` 和它的增强版 `htop`。我个人最喜欢的是 `htop`。但是,开发人员不时会发布这些程序的替代品。`top``htop` 工具的一个替代品是 `Hegemon`。它是使用 Rust 语言编写的模块化系统监视程序。
关于 Hegemon 的功能,我们可以列出以下这些:
* Hegemon 会监控 CPU、内存和交换页的使用情况。
  * 它监控系统的温度和风扇速度。
  * 更新间隔时间可以调整。默认值为 3 秒。
  * 我们可以通过扩展数据流来展示更详细的图表和其他信息。
  * 单元测试
  * 干净的界面
  * 免费且开源。
* Hegemon 会监控 CPU、内存和交换页的使用情况。
* 它监控系统的温度和风扇速度。
* 更新间隔时间可以调整。默认值为 3 秒。
* 我们可以通过扩展数据流来展示更详细的图表和其他信息。
* 单元测试
* 干净的界面
* 自由开源。
### 安装 Hegemon
确保已安装 **Rust 1.26** 或更高版本。要在 Linux 发行版中安装 Rust请参阅以下指南
确保已安装 Rust 1.26 或更高版本。要在 Linux 发行版中安装 Rust请参阅以下指南
[Install Rust Programming Language In Linux][2]
- [在 Linux 中安装 Rust 编程语言][2]
另外要安装 [libsensors][1] 库。它在大多数 Linux 发行版的默认仓库中都有。例如,你可以使用以下命令将其安装在基于 RPM 的系统(如 Fedora
@@ -51,10 +49,10 @@ $ hegemon
![](https://www.ostechnix.com/wp-content/uploads/2018/09/Hegemon-in-action.gif)
要退出,请按 **Q**
要退出,请按 `Q`
请注意hegemon 仍处于早期开发阶段,并不能完全取代 **top** 命令。它可能存在 bug 和功能缺失。如果你遇到任何 bug请在项目的 github 页面中报告它们。开发人员计划在即将推出的版本中引入更多功能。所以,请关注这个项目。
请注意hegemon 仍处于早期开发阶段,并不能完全取代 `top` 命令。它可能存在 bug 和功能缺失。如果你遇到任何 bug请在项目的 GitHub 页面中报告它们。开发人员计划在即将推出的版本中引入更多功能。所以,请关注这个项目。
就是这些了。希望这篇文章有用。还有更多的好东西。敬请关注!
@@ -69,7 +67,7 @@ via: https://www.ostechnix.com/hegemon-a-modular-system-monitor-application-writ
作者:[SK][a]
选题:[lujun9972](https://github.com/lujun9972)
译者:[geekpi](https://github.com/geekpi)
校对:[校对者ID](https://github.com/校对者ID)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出

View File

@@ -0,0 +1,281 @@
Linux 系统上交换空间的介绍
======
> 学习如何修改你的系统上的交换空间的容量,以及你到底需要多大的交换空间。
![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/fail_progress_cycle_momentum_arrow.png?itok=q-ZFa_Eh)
当今无论什么操作系统<ruby>交换<rt>Swap</rt></ruby>空间是非常常见的。Linux 使用交换空间来增加主机可用的虚拟内存。它可以在常规文件或逻辑卷上使用一个或多个专用交换分区或交换文件。
典型计算机中有两种基本类型的内存。第一种类型,随机存取存储器 (RAM),用于存储计算机使用的数据和程序。只有程序和数据存储在 RAM 中,计算机才能使用它们。随机存储器是易失性存储器;也就是说,如果计算机关闭了,存储在 RAM 中的数据就会丢失。
硬盘是用于长期存储数据和程序的磁性介质。该磁介质可以很好的保存数据即使计算机断电存储在磁盘上的数据也会保留下来。CPU中央处理器不能直接访问硬盘上的程序和数据它们必须首先复制到 RAM 中RAM 是 CPU 访问代码指令和操作数据的地方。在引导过程中计算机将特定的操作系统程序如内核、init 或 systemd以及硬盘上的数据复制到 RAM 中,在 RAM 中,计算机的处理器 CPU 可以直接访问这些数据。
### 交换空间
交换空间是现代 Linux 系统中的第二种内存类型。交换空间的主要功能是当全部的 RAM 被占用并且需要更多内存时,用磁盘空间代替 RAM 内存。
例如,假设你有一个 8GB RAM 的计算机。如果你启动的程序没有填满 RAM一切都好不需要交换。假设你在处理电子表格当添加更多的行时你电子表格会增长加上所有正在运行的程序将会占用全部的 RAM 。如果这时没有可用的交换空间,你将不得不停止处理电子表格,直到关闭一些其他程序来释放一些 RAM 。
内核使用一个内存管理程序来检测最近没有使用的内存块(内存页)。内存管理程序将这些相对不经常使用的内存页交换到硬盘上专门指定用于“分页”或交换的特殊分区。这会释放 RAM为输入电子表格更多数据腾出了空间。那些换出到硬盘的内存页面被内核的内存管理代码跟踪如果需要可以被分页回 RAM。
Linux 计算机中的内存总量是 RAM + 交换分区,交换分区被称为虚拟内存.
### Linux 交换分区类型
Linux 提供了两种类型的交换空间。默认情况下,大多数 Linux 在安装时都会创建一个交换分区,但是也可以使用一个特殊配置的文件作为交换文件。交换分区顾名思义就是一个标准磁盘分区,由 `mkswap` 命令指定交换空间。
如果没有可用磁盘空间来创建新的交换分区,或者卷组中没有空间为交换空间创建逻辑卷,则可以使用交换文件。这只是一个创建好并预分配指定大小的常规文件。然后运行 `mkswap` 命令将其配置为交换空间。除非绝对必要否则我不建议使用文件来做交换空间。LCTT 译注Ubuntu 近来的版本采用了交换文件而非交换空间,所以我对于这种说法保留看法)
### 频繁交换
当总虚拟内存RAM 和交换空间)变得快满时,可能会发生频繁交换。系统花了太多时间在交换空间和 RAM 之间做内存块的页面切换,以至于几乎没有时间用于实际工作。这种情况的典型症状是:系统变得缓慢或完全无反应,硬盘指示灯几乎持续亮起。
使用 `free` 的命令来显示 CPU 负载和内存使用情况,你会发现 CPU 负载非常高,可能达到系统中 CPU 内核数量的 30 到 40 倍。另一个情况是 RAM 和交换空间几乎完全被分配了。
事实上,查看 SAR系统活动报告数据也可以显示这些内容。在我的每个系统上都安装 SAR ,并将这些用于数据分析。
### 交换空间的正确大小是多少?
许多年前,硬盘上分配给交换空间大小是计算机上的 RAM 的两倍(当然,这是大多数计算机的 RAM 以 KB 或 MB 为单位的时候)。因此,如果一台计算机有 64KB 的 RAM应该分配 128KB 的交换分区。该规则考虑到了这样的事实情况,即 RAM 大小在当时非常小,分配超过 2 倍的 RAM 用于交换空间并不能提高性能。使用超过两倍的 RAM 进行交换,比实际执行有用的工作的时候,大多数系统将花费更多的时间。
RAM 现在已经很便宜了,如今大多数计算机的 RAM 都达到了几十亿字节。我的大多数新电脑至少有 8GB 内存,一台有 32GB 内存,我的主工作站有 64GB 内存。我的旧电脑有 4 到 8GB 的内存。
当操作具有大量 RAM 的计算机时,交换空间的限制性能系数远低于 2 倍。[Fedora 28 在线安装指南][1] 定义了当前关于交换空间分配的方法。下面内容是我提出的建议。
下表根据系统中的 RAM 大小以及是否有足够的内存让系统休眠,提供了交换分区的推荐大小。建议的交换分区大小是在安装过程中自动建立的。但是,为了满足系统休眠,您需要在自定义分区阶段编辑交换空间。
_表 1: Fedora 28 文档中推荐的系统交换空间_
| **系统内存大小** | **推荐的交换空间** | **推荐的交换空间大小(支持休眠模式)** |
|--------------------------|-----------------------------|---------------------------------------|
| 小于 2 GB | 2 倍 RAM | 3 倍 RAM |
| 2 GB - 8 GB | 等于 RAM 大小 | 2 倍 RAM |
| 8 GB - 64 GB | 0.5 倍 RAM | 1.5 倍 RAM |
| 大于 64 GB | 工作量相关 | 不建议休眠模式 |
在上面列出的每个范围之间的边界(例如,具有 2GB、8GB 或 64GB 的系统 RAM),请根据所选交换空间和支持休眠功能请谨慎使用。如果你的系统资源允许,增加交换空间可能会带来更好的性能。
当然,大多数 Linux 管理员对多大的交换空间量有自己的想法。下面的表2 包含了基于我在多种环境中的个人经历所做出的建议。这些可能不适合你,但是和表 1 一样,它们可能对你有所帮助。
_表 2: 作者推荐的系统交换空间_
| RAM 大小 | 推荐的交换空间 |
|---------------|------------------------|
| ≤ 2GB | 2X RAM |
| 2GB 8GB | = RAM |
| >8GB | 8GB |
这两个表中共同点,随着 RAM 数量的增加,超过某一点增加更多交换空间只会导致在交换空间几乎被全部使用之前就发生频繁交换。根据以上建议,则应尽可能添加更多 RAM而不是增加更多交换空间。如类似影响系统性能的情况一样请使用最适合你的建议。根据 Linux 环境中的条件进行测试和更改是需要时间和精力的。
### 向非 LVM 磁盘环境添加更多交换空间
面对已安装 Linux 的主机并对交换空间的需求不断变化,有时有必要修改系统定义的交换空间的大小。此过程可用于需要增加交换空间大小的任何情况。它假设有足够的可用磁盘空间。此过程还假设磁盘分区为 “原始的” EXT4 和交换分区而不是使用逻辑卷管理LVM
基本步骤很简单:
1. 关闭现有的交换空间。
2. 创建所需大小的新交换分区。
3. 重读分区表。
4. 将分区配置为交换空间。
5. 添加新分区到 `/etc/fstab`
6. 打开交换空间。
应该不需要重新启动机器。
为了安全起见,在关闭交换空间前,至少你应该确保没有应用程序在运行,也没有交换空间在使用。`free``top` 命令可以告诉你交换空间是否在使用中。为了更安全,您可以恢复到运行级别 1 或单用户模式。
使用关闭所有交换空间的命令关闭交换分区:
```
swapoff -a
```
现在查看硬盘上的现有分区。
```
fdisk -l
```
这将显示每个驱动器上的分区表。按编号标识当前的交换分区。
使用以下命令在交互模式下启动 `fdisk`
```
fdisk /dev/<device name>
```
例如:
```
fdisk /dev/sda
```
此时,`fdisk` 是交互方式的,只在指定的磁盘驱动器上进行操作。
使用 `fdisk``p` 子命令验证磁盘上是否有足够的可用空间来创建新的交换分区。硬盘上的空间以 512 字节的块以及起始和结束柱面编号的形式显示,因此您可能需要做一些计算来确定分配分区之间和末尾的可用空间。
使用 `n` 子命令创建新的交换分区。`fdisk` 会问你开始柱面。默认情况下,它选择编号最低的可用柱面。如果你想改变这一点,输入开始柱面的编号。
`fdisk` 命令允许你以多种格式输入分区的大小包括最后一个柱面号或字节、KB 或 MB 的大小。例如,键入 4000M ,这将在新分区上提供大约 4GB 的空间,然后按回车键。
使用 `p` 子命令来验证分区是否按照指定的方式创建的。请注意,除非使用结束柱面编号,否则分区可能与你指定的不完全相同。`fdisk` 命令只能在整个柱面上增量的分配磁盘空间,因此你的分区可能比你指定的稍小或稍大。如果分区不是您想要的,你可以删除它并重新创建它。
现在指定新分区是交换分区了 。子命令 `t` 允许你指定定分区的类型。所以输入 `t`,指定分区号,当它要求十六进制分区类型时,输入 `82`,这是 Linux 交换分区类型,然后按回车键。
当你对创建的分区感到满意时,使用 `w` 子命令将新的分区表写入磁盘。`fdisk` 程序将退出,并在完成修改后的分区表的编写后返回命令提示符。当 `fdisk` 完成写入新分区表时,会收到以下消息:
```
The partition table has been altered!
Calling ioctl() to re-read partition table.
WARNING: Re-reading the partition table failed with error 16: Device or resource busy.
The kernel still uses the old table.
The new table will be used at the next reboot.
Syncing disks.
```
此时,你使用 `partprobe` 命令强制内核重新读取分区表,这样就不需要执行重新启动机器。
```
partprobe
```
使用命令 `fdisk -l` 列出分区,新交换分区应该在列出的分区中。确保新的分区类型是 “Linux swap”。
修改 `/etc/fstab` 文件以指向新的交换分区。如下所示:
```
LABEL=SWAP-sdaX   swap        swap    defaults        0 0
```
其中 `X` 是分区号。根据新交换分区的位置,添加以下内容:
```
/dev/sdaY         swap        swap    defaults        0 0
```
请确保使用正确的分区号。现在,可以执行创建交换分区的最后一步。使用 `mkswap` 命令将分区定义为交换分区。
```
mkswap /dev/sdaY
```
最后一步是使用以下命令启用交换空间:
```
swapon -a
```
你的新交换分区现在与以前存在的交换分区一起在线。您可以使用 `free``top` 命令来验证这一点。
#### 在 LVM 磁盘环境中添加交换空间
如果你的磁盘使用 LVM 更改交换空间将相当容易。同样假设当前交换卷所在的卷组中有可用空间。默认情况下LVM 环境中的 Fedora Linux 在安装过程将交换分区创建为逻辑卷。您可以非常简单地增加交换卷的大小。
以下是在 LVM 环境中增加交换空间大小的步骤:
1. 关闭所有交换空间。
2. 增加指定用于交换空间的逻辑卷的大小。
3. 为交换空间调整大小的卷配置。
4. 启用交换空间。
首先,让我们使用 `lvs` 命令(列出逻辑卷)来验证交换空间是否存在以及交换空间是否是逻辑卷。
```
[root@studentvm1 ~]# lvs
LV VG Attr LSize Pool Origin Data% Meta% Move Log Cpy%Sync Convert
home fedora_studentvm1 -wi-ao---- 2.00g
pool00 fedora_studentvm1 twi-aotz-- 2.00g 8.17 2.93
root fedora_studentvm1 Vwi-aotz-- 2.00g pool00 8.17
swap fedora_studentvm1 -wi-ao---- 8.00g
tmp fedora_studentvm1 -wi-ao---- 5.00g
usr fedora_studentvm1 -wi-ao---- 15.00g
var fedora_studentvm1 -wi-ao---- 10.00g
[root@studentvm1 ~]#
```
你可以看到当前的交换空间大小为 8GB。在这种情况下我们希望将 2GB 添加到此交换卷中。首先,停止现有的交换空间。如果交换空间正在使用,终止正在运行的程序。
```
swapoff -a
```
现在增加逻辑卷的大小。
```
[root@studentvm1 ~]# lvextend -L +2G /dev/mapper/fedora_studentvm1-swap
  Size of logical volume fedora_studentvm1/swap changed from 8.00 GiB (2048 extents) to 10.00 GiB (2560 extents).
  Logical volume fedora_studentvm1/swap successfully resized.
[root@studentvm1 ~]#
```
运行 `mkswap` 命令将整个 10GB 分区变成交换空间。
```
[root@studentvm1 ~]# mkswap /dev/mapper/fedora_studentvm1-swap
mkswap: /dev/mapper/fedora_studentvm1-swap: warning: wiping old swap signature.
Setting up swapspace version 1, size = 10 GiB (10737414144 bytes)
no label, UUID=3cc2bee0-e746-4b66-aa2d-1ea15ef1574a
[root@studentvm1 ~]#
```
重新启用交换空间。
```
[root@studentvm1 ~]# swapon -a
[root@studentvm1 ~]#
```
现在,使用 `lsblk ` 命令验证新交换空间是否存在。同样,不需要重新启动机器。
```
[root@studentvm1 ~]# lsblk
NAME                                 MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
sda                                    8:0    0   60G  0 disk
|-sda1                                 8:1    0    1G  0 part /boot
`-sda2                                 8:2    0   59G  0 part
  |-fedora_studentvm1-pool00_tmeta   253:0    0    4M  0 lvm  
  | `-fedora_studentvm1-pool00-tpool 253:2    0    2G  0 lvm  
  |   |-fedora_studentvm1-root       253:3    0    2G  0 lvm  /
  |   `-fedora_studentvm1-pool00     253:6    0    2G  0 lvm  
  |-fedora_studentvm1-pool00_tdata   253:1    0    2G  0 lvm  
  | `-fedora_studentvm1-pool00-tpool 253:2    0    2G  0 lvm  
  |   |-fedora_studentvm1-root       253:3    0    2G  0 lvm  /
  |   `-fedora_studentvm1-pool00     253:6    0    2G  0 lvm  
  |-fedora_studentvm1-swap           253:4    0   10G  0 lvm  [SWAP]
  |-fedora_studentvm1-usr            253:5    0   15G  0 lvm  /usr
  |-fedora_studentvm1-home           253:7    0    2G  0 lvm  /home
  |-fedora_studentvm1-var            253:8    0   10G  0 lvm  /var
  `-fedora_studentvm1-tmp            253:9    0    5G  0 lvm  /tmp
sr0                                   11:0    1 1024M  0 rom  
[root@studentvm1 ~]#
```
您也可以使用 `swapon -s` 命令或 `top``free` 或其他几个命令来验证这一点。
```
[root@studentvm1 ~]# free
              total        used        free      shared  buff/cache   available
Mem:        4038808      382404     2754072        4152      902332     3404184
Swap:      10485756           0    10485756
[root@studentvm1 ~]#
```
请注意,不同的命令以不同的形式显示或要求输入设备文件。在 `/dev` 目录中访问特定设备有多种方式。在我的文章 [在 Linux 中管理设备][2] 中有更多关于 `/dev` 目录及其内容说明。
--------------------------------------------------------------------------------
via: https://opensource.com/article/18/9/swap-space-linux-systems
作者:[David Both][a]
选题:[lujun9972](https://github.com/lujun9972)
译者:[heguangzhi](https://github.com/heguangzhi)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://opensource.com/users/dboth
[1]: https://docs.fedoraproject.org/en-US/fedora/f28/install-guide/
[2]: https://linux.cn/article-8099-1.html

View File

@@ -0,0 +1,239 @@
如何将 Scikit-learn Python 库用于数据科学项目
======
> 灵活多样的 Python 库为数据分析和数据挖掘提供了强力的机器学习工具。
![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/brain_data.png?itok=RH6NA32X)
Scikit-learn Python 库最初于 2007 年发布,通常用于解决各种方面的机器学习和数据科学问题。这个多种功能的库提供了整洁、一致、高效的 API 和全面的在线文档。
### 什么是 Scikit-learn
[Scikit-learn][1] 是一个开源 Python 库,拥有强大的数据分析和数据挖掘工具。 在 BSD 许可下可用,并建立在以下机器学习库上:
- `NumPy`,一个用于操作多维数组和矩阵的库。它还具有广泛的数学函数汇集,可用于执行各种计算。
- `SciPy`,一个由各种库组成的生态系统,用于完成技术计算任务。
- `Matplotlib`,一个用于绘制各种图表和图形的库。
Scikit-learn 提供了广泛的内置算法,可以充分用于数据科学项目。
以下是使用 Scikit-learn 库的主要方法。
#### 1、分类
[分类][2]工具识别与提供的数据相关联的类别。例如,它们可用于将电子邮件分类为垃圾邮件或非垃圾邮件。
Scikit-learn 中的分类算法包括:
- <ruby>支持向量机<rt>Support vector machines</rt></ruby>SVM
- <ruby>最邻近<rt>Nearest neighbors</rt></ruby>
- <ruby>随机森林<rt>Random forest</rt></ruby>
#### 2、回归
回归涉及到创建一个模型去试图理解输入和输出数据之间的关系。例如,回归工具可用于理解股票价格的行为。
回归算法包括:
- <ruby>支持向量机<rt>Support vector machines</rt></ruby>SVM
- <ruby>岭回归<rt>Ridge regression</rt></ruby>
- LassoLCTT 译注Lasso 即 least absolute shrinkage and selection operator又译为最小绝对值收敛和选择算子、套索算法
#### 3、聚类
Scikit-learn 聚类工具用于自动将具有相同特征的数据分组。 例如,可以根据客户数据的地点对客户数据进行细分。
聚类算法包括:
- K-means
- <ruby>谱聚类<rt>Spectral clustering</rt></ruby>
- Mean-shift
#### 4、降维
降维降低了用于分析的随机变量的数量。例如,为了提高可视化效率,可能不会考虑外围数据。
降维算法包括:
- <ruby>主成分分析<rt>Principal component analysis</rt></ruby>PCA
- <ruby>功能选择<rt>Feature selection</rt></ruby>
- <ruby>非负矩阵分解<rt>Non-negative matrix factorization</rt></ruby>
#### 5、模型选择
模型选择算法提供了用于比较、验证和选择要在数据科学项目中使用的最佳参数和模型的工具。
通过参数调整能够增强精度的模型选择模块包括:
- <ruby>网格搜索<rt>Grid search</rt></ruby>
- <ruby>交叉验证<rt>Cross-validation</rt></ruby>
- <ruby>指标<rt>Metrics</rt></ruby>
#### 6、预处理
Scikit-learn 预处理工具在数据分析期间的特征提取和规范化中非常重要。 例如,您可以使用这些工具转换输入数据(如文本)并在分析中应用其特征。
预处理模块包括:
- 预处理
- 特征提取
### Scikit-learn 库示例
让我们用一个简单的例子来说明如何在数据科学项目中使用 Scikit-learn 库。
我们将使用[鸢尾花花卉数据集][3],该数据集包含在 Scikit-learn 库中。 鸢尾花数据集包含有关三种花种的 150 个细节,三种花种分别为:
- Setosa标记为 0
- Versicolor标记为 1
- Virginica标记为 2
数据集包括每种花种的以下特征(以厘米为单位):
- 萼片长度
- 萼片宽度
- 花瓣长度
- 花瓣宽度
#### 第 1 步:导入库
由于鸢尾花花卉数据集包含在 Scikit-learn 数据科学库中,我们可以将其加载到我们的工作区中,如下所示:
```
from sklearn import datasets
iris = datasets.load_iris()
```
这些命令从 `sklearn` 导入数据集 `datasets` 模块,然后使用 `datasets` 中的 `load_iris()` 方法将数据包含在工作空间中。
#### 第 2 步:获取数据集特征
数据集 `datasets` 模块包含几种方法,使您更容易熟悉处理数据。
在 Scikit-learn 中,数据集指的是类似字典的对象,其中包含有关数据的所有详细信息。 使用 `.data` 键存储数据,该数据列是一个数组列表。
例如,我们可以利用 `iris.data` 输出有关鸢尾花花卉数据集的信息。
```
print(iris.data)
```
这是输出(结果已被截断):
```
[[5.1 3.5 1.4 0.2]
 [4.9 3.  1.4 0.2]
 [4.7 3.2 1.3 0.2]
 [4.6 3.1 1.5 0.2]
 [5.  3.6 1.4 0.2]
 [5.4 3.9 1.7 0.4]
 [4.6 3.4 1.4 0.3]
 [5.  3.4 1.5 0.2]
 [4.4 2.9 1.4 0.2]
 [4.9 3.1 1.5 0.1]
 [5.4 3.7 1.5 0.2]
 [4.8 3.4 1.6 0.2]
 [4.8 3.  1.4 0.1]
 [4.3 3.  1.1 0.1]
 [5.8 4.  1.2 0.2]
 [5.7 4.4 1.5 0.4]
 [5.4 3.9 1.3 0.4]
 [5.1 3.5 1.4 0.3]
```
我们还使用 `iris.target` 向我们提供有关花朵不同标签的信息。
```
print(iris.target)
```
这是输出:
```
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2
 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
 2 2]
```
如果我们使用 `iris.target_names`,我们将输出数据集中找到的标签名称的数组。
```
print(iris.target_names)
```
以下是运行 Python 代码后的结果:
```
['setosa' 'versicolor' 'virginica']
```
#### 第 3 步:可视化数据集
我们可以使用[箱形图][4]来生成鸢尾花数据集的视觉描绘。 箱形图说明了数据如何通过四分位数在平面上分布的。
以下是如何实现这一目标:
```
import seaborn as sns
box_data = iris.data # 表示数据数组的变量
box_target = iris.target # 表示标签数组的变量
sns.boxplot(data = box_data,width=0.5,fliersize=5)
sns.set(rc={'figure.figsize':(2,15)})
```
让我们看看结果:
![](https://opensource.com/sites/default/files/uploads/scikit_boxplot.png)
在横轴上:
* 0 是萼片长度
* 1 是萼片宽度
* 2 是花瓣长度
* 3 是花瓣宽度
垂直轴的尺寸以厘米为单位。
### 总结
以下是这个简单的 Scikit-learn 数据科学教程的完整代码。
```
from sklearn import datasets
iris = datasets.load_iris()
print(iris.data)
print(iris.target)
print(iris.target_names)
import seaborn as sns
box_data = iris.data # 表示数据数组的变量
box_target = iris.target # 表示标签数组的变量
sns.boxplot(data = box_data,width=0.5,fliersize=5)
sns.set(rc={'figure.figsize':(2,15)})
```
Scikit-learn 是一个多功能的 Python 库,可用于高效完成数据科学项目。
如果您想了解更多信息,请查看 [LiveEdu][5] 上的教程,例如 Andrey Bulezyuk 关于使用 Scikit-learn 库创建[机器学习应用程序][6]的视频。
有什么评价或者疑问吗? 欢迎在下面分享。
--------------------------------------------------------------------------------
via: https://opensource.com/article/18/9/how-use-scikit-learn-data-science-projects
作者:[Dr.Michael J.Garbade][a]
选题:[lujun9972](https://github.com/lujun9972)
译者:[Flowsnow](https://github.com/Flowsnow)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://opensource.com/users/drmjg
[1]: http://scikit-learn.org/stable/index.html
[2]: https://blog.liveedu.tv/regression-versus-classification-machine-learning-whats-the-difference/
[3]: https://en.wikipedia.org/wiki/Iris_flower_data_set
[4]: https://en.wikipedia.org/wiki/Box_plot
[5]: https://www.liveedu.tv/guides/data-science/
[6]: https://www.liveedu.tv/andreybu/REaxr-machine-learning-model-python-sklearn-kera/oPGdP-machine-learning-model-python-sklearn-kera/

View File

@@ -0,0 +1,86 @@
一款免费且安全的在线 PDF 转换软件
======
![](https://www.ostechnix.com/wp-content/uploads/2018/09/easypdf-720x340.jpg)
我们总在寻找一个更好用且更高效的解决方案,来我们的生活理加方便。 比方说,在处理 PDF 文档时,你肯定会想拥有一款工具,它能够在任何情形下都显得快速可靠。在这,我们想向你推荐 **EasyPDF** —— 一款可以胜任所有场合的在线 PDF 软件。通过大量的测试,我们可以保证:这款工具能够让你的 PDF 文档管理更加容易。
不过,关于 EasyPDF 有一些十分重要的事情,你必须知道。
* EasyPDF 是免费的、匿名的在线 PDF 转换软件。
* 能够将 PDF 文档转换成 Word、Excel、PowerPoint、AutoCAD、JPG、GIF 和文本等格式格式的文档。
* 能够从 Word、Excel、PowerPoint 等其他格式的文件创建 PDF 文件。
* 能够进行 PDF 文档的合并、分割和压缩。
* 能够识别扫描的 PDF 和图片中的内容。
* 可以从你的设备或者云存储Google Drive 和 DropBox中上传文档。
* 可以在 Windows、Linux、Mac 和智能手机上通过浏览器来操作。
* 支持多种语言。
### EasyPDF的用户界面
![](http://www.ostechnix.com/wp-content/uploads/2018/09/easypdf-interface.png)
EasyPDF 最吸引你眼球的就是平滑的用户界面营造一种整洁的环境这会让使用者感觉更加舒服。由于网站完全没有一点广告EasyPDF 的整体使用体验相比以前会好很多。
每种不同类型的转换都有它们专门的菜单,只需要简单地向其中添加文件,你并不需要知道太多知识来进行操作。
许多类似网站没有做好相关的优化使得在手机上的使用体验并不太友好。然而EasyPDF 突破了这一个瓶颈。在智能手机上EasyPDF 几乎可以秒开,并且可以顺畅的操作。你也通过 Chrome 的“三点菜单”把 EasyPDF 添加到手机的主屏幕上。
![](http://www.ostechnix.com/wp-content/uploads/2018/09/EasyPDF-fs8.png)
### 特性
除了好看的界面EasyPDF 还非常易于使用。为了使用它,你 **不需要注册一个账号** 或者**留下一个邮箱**,它是完全匿名的。另外, EasyPDF 也不会对要转换的文件进行数量或者大小的限制,完全不需要安装!酷极了,不是吗?
首先,你需要选择一种想要进行的格式转换,比如,将 PDF 转换成 Word。然后选择你想要转换的 PDF 文件。你可以通过两种方式来上传文件:直接拖拉或者从设备上的文件夹进行选择。还可以选择从[Google Drive][1] 或 [Dropbox][2]来上传文件。
选择要进行格式转换的文件后,点击 Convert 按钮开始转换过程。转换过程会在一分钟内完成,你并不需要等待太长时间。如果你还有对其他文件进行格式转换,在接着转换前,不要忘了将前面已经转换完成的文件下载保存。不然的话,你将会丢失前面的文件。
![](https://www.ostechnix.com/wp-content/uploads/2018/09/EasyPDF1.png)
要进行其他类型的格式转换,直接返回到主页。
目前支持的几种格式转换类型如下:
* **PDF to Word** 将 PDF 文档 转换成 Word 文档
* **PDF 转换成 PowerPoint** 将 PDF 文档 转换成 PowerPoint 演示讲稿
* **PDF 转换成 Excel** 将 PDF 文档 转换成 Excel 文档
* **PDF 创建** 从一些其他类型的文件文本、doc、odt来创建PDF文档
* **Word 转换成 PDF** 将 Word 文档 转换成 PDF 文档
* **JPG 转换成 PDF** 将 JPG images 转换成 PDF 文档
* **PDF 转换成 AutoCAD** 将 PDF 文档 转换成 .dwg 格式DWG 是 CAD 文件的原生的格式)
* **PDF 转换成 Text** 将 PDF 文档 转换成 Text 文档
* **PDF 分割** 把 PDF 文件分割成多个部分
* **PDF 合并** 把多个 PDF 文件合并成一个文件
* **PDF 压缩** 将 PDF 文档进行压缩
* **PDF 转换成 JPG** 将 PDF 文档 转换成 JPG 图片
* **PDF 转换成 PNG** 将 PDF 文档 转换成 PNG 图片
* **PDF 转换成 GIF** 将 PDF 文档 转换成 GIF 文件
* **在线文字内容识别** 将扫描的纸质文档转换成能够进行编辑的文件Word、Excel、文本
想试一试吗?好极了!点击下面的链接,然后开始格式转换吧!
[![](https://www.ostechnix.com/wp-content/uploads/2018/09/EasyPDF-online-pdf.png)][https://easypdf.com/]
### 总结
EasyPDF 名符其实,能够让 PDF 管理更加容易。就我测试过的 EasyPDF 服务而言,它提供了**完全免费**的简单易用的转换功能。它十分快速、安全和可靠。你会对它的服务质量感到非常满意,因为它不用支付任何费用,也不用留下像邮箱这样的个人信息。值得一试,也许你会找到你自己更喜欢的 PDF 工具。
好吧,我就说这些。更多的好东西还在后后面,请继续关注!
加油!
--------------------------------------------------------------------------------
via: https://www.ostechnix.com/easypdf-a-free-and-secure-online-pdf-conversion-suite/
作者:[SK][a]
选题:[lujun9972](https://github.com/lujun9972)
译者:[zhousiyu325](https://github.com/zhousiyu325)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://www.ostechnix.com/author/sk/
[1]: https://www.ostechnix.com/how-to-mount-google-drive-locally-as-virtual-file-system-in-linux/
[2]: https://www.ostechnix.com/install-dropbox-in-ubuntu-18-04-lts-desktop/

View File

@@ -0,0 +1,168 @@
如何在 Ubuntu 上安装 pip
======
**`pip` 是一个命令行工具,允许你安装 Python 编写的软件包。 学习如何在 Ubuntu 上安装 `pip` 以及如何使用它来安装 Python 应用程序。**
有许多方法可以[在 Ubuntu 上安装软件][1]。 你可以从软件中心安装应用程序,也可以从下载的 DEB 文件、PPALCTT 译注PPA 即 Personal Package Archives个人软件包集、[Snap 软件包][2],也可以使用 [Flatpak][3]、使用 [AppImage][4],甚至用旧的源代码安装方式。
还有一种方法可以在 [Ubuntu][5] 中安装软件包。 它被称为 `pip`,你可以使用它来安装基于 Python 的应用程序。
### 什么是 pip
[pip][6] 代表 “pip Installs Packages”。 [pip][7] 是一个基于命令行的包管理系统。 用于安装和管理 [Python 语言][8]编写的软件。
你可以使用 `pip` 来安装 Python 包索引([PyPI][9])中列出的包。
作为软件开发人员,你可以使用 `pip` 为你自己的 Python 项目安装各种 Python 模块和包。
作为最终用户,你可能需要使用 `pip` 来安装一些 Python 开发的并且可以使用 `pip` 轻松安装的应用程序。 一个这样的例子是 [Stress Terminal][10] 应用程序,你可以使用 `pip` 轻松安装。
让我们看看如何在 Ubuntu 和其他基于 Ubuntu 的发行版上安装 `pip`
### 如何在 Ubuntu 上安装 pip
![Install pip on Ubuntu Linux][11]
默认情况下,`pip` 未安装在 Ubuntu 上。 你必须首先安装它才能使用。 在 Ubuntu 上安装 `pip` 非常简单。 我马上展示给你。
Ubuntu 18.04 默认安装了 Python 2 和 Python 3。 因此,你应该为两个 Python 版本安装 `pip`
`pip`,默认情况下是指 Python 2。`pip3` 代表 Python 3 中的 pip。
注意:我在本教程中使用的是 Ubuntu 18.04。 但是这里的教程应该适用于其他版本如Ubuntu 16.04、18.10 等。你也可以在基于 Ubuntu 的其他 Linux 发行版上使用相同的命令,如 Linux Mint、Linux Lite、Xubuntu、Kubuntu 等。
#### 为 Python 2 安装 pip
首先,确保已经安装了 Python 2。 在 Ubuntu 上,可以使用以下命令进行验证。
```
python2 --version
```
如果没有错误并且显示了 Python 版本的有效输出,则说明安装了 Python 2。 所以现在你可以使用这个命令为 Python 2 安装 `pip`
```
sudo apt install python-pip
```
这将安装 `pip` 和它的许多其他依赖项。 安装完成后,请确认你已正确安装了 `pip`
```
pip --version
```
它应该显示一个版本号,如下所示:
```
pip 9.0.1 from /usr/lib/python2.7/dist-packages (python 2.7)
```
这意味着你已经成功在 Ubuntu 上安装了 `pip`
#### 为 Python 3 安装 pip
你必须确保在 Ubuntu 上安装了 Python 3。 可以使用以下命令检查一下:
```
python3 --version
```
如果显示了像 Python 3.6.6 这样的数字,则说明 Python 3 在你的 Linux 系统上安装好了。
现在,你可以使用以下命令安装 `pip3`
```
sudo apt install python3-pip
```
你应该使用以下命令验证 `pip3` 是否已正确安装:
```
pip3 --version
```
它应该显示一个这样的数字:
```
pip 9.0.1 from /usr/lib/python3/dist-packages (python 3.6)
```
这意味着 `pip3` 已成功安装在你的系统上。
### 如何使用 pip 命令
现在你已经安装了 `pip`,让我们快速看一些基本的 `pip` 命令。 这些命令将帮助你使用 `pip` 命令来搜索、安装和删除 Python 包。
要从 Python 包索引 PyPI 中搜索包,可以使用以下 `pip` 命令:
```
pip search <search_string>
```
例如如果你搜索“stress”这个词将会显示名称或描述中包含字符串“stress”的所有包。
```
pip search stress
stress (1.0.0) - A trivial utility for consuming system resources.
s-tui (0.8.2) - Stress Terminal UI stress test and monitoring tool
stressypy (0.0.12) - A simple program for calling stress and/or stress-ng from python
fuzzing (0.3.2) - Tools for stress testing applications.
stressant (0.4.1) - Simple stress-test tool
stressberry (0.1.7) - Stress tests for the Raspberry Pi
mobbage (0.2) - A HTTP stress test and benchmark tool
stresser (0.2.1) - A large-scale stress testing framework.
cyanide (1.3.0) - Celery stress testing and integration test support.
pysle (1.5.7) - An interface to ISLEX, a pronunciation dictionary with stress markings.
ggf (0.3.2) - global geometric factors and corresponding stresses of the optical stretcher
pathod (0.17) - A pathological HTTP/S daemon for testing and stressing clients.
MatPy (1.0) - A toolbox for intelligent material design, and automatic yield stress determination
netblow (0.1.2) - Vendor agnostic network testing framework to stress network failures
russtress (0.1.3) - Package that helps you to put lexical stress in russian text
switchy (0.1.0a1) - A fast FreeSWITCH control library purpose-built on traffic theory and stress testing.
nx4_selenium_test (0.1) - Provides a Python class and apps which monitor and/or stress-test the NoMachine NX4 web interface
physical_dualism (1.0.0) - Python library that approximates the natural frequency from stress via physical dualism, and vice versa.
fsm_effective_stress (1.0.0) - Python library that uses the rheological-dynamical analogy (RDA) to compute damage and effective buckling stress in prismatic shell structures.
processpathway (0.3.11) - A nifty little toolkit to create stress-free, frustrationless image processing pathways from your webcam for computer vision experiments. Or observing your cat.
```
如果要使用 `pip` 安装应用程序,可以按以下方式使用它:
```
pip install <package_name>
```
`pip` 不支持使用 tab 键补全包名,因此包名称需要准确指定。 它将下载所有必需的文件并安装该软件包。
如果要删除通过 `pip` 安装的 Python 包,可以使用 `pip` 中的 `uninstall` 选项。
```
pip uninstall <installed_package_name>
```
你可以在上面的命令中使用 `pip3` 代替 `pip`
我希望这个快速提示可以帮助你在 Ubuntu 上安装 `pip`。 如果你有任何问题或建议,请在下面的评论部分告诉我。
--------------------------------------------------------------------------------
via: https://itsfoss.com/install-pip-ubuntu/
作者:[Abhishek Prakash][a]
选题:[lujun9972](https://github.com/lujun9972)
译者:[Flowsnow](https://github.com/Flowsnow)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://itsfoss.com/author/abhishek/
[1]: https://itsfoss.com/how-to-add-remove-programs-in-ubuntu/
[2]: https://itsfoss.com/use-snap-packages-ubuntu-16-04/
[3]: https://itsfoss.com/flatpak-guide/
[4]: https://itsfoss.com/use-appimage-linux/
[5]: https://www.ubuntu.com/
[6]: https://en.wikipedia.org/wiki/pip_(package_manager)
[7]: https://pypi.org/project/pip/
[8]: https://www.python.org/
[9]: https://pypi.org/
[10]: https://itsfoss.com/stress-terminal-ui/
[11]: https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2018/10/install-pip-ubuntu.png

View File

@@ -0,0 +1,177 @@
cloc计算不同编程语言源代码的行数
======
![](https://www.ostechnix.com/wp-content/uploads/2018/10/cloc-720x340.png)
作为一个开发人员,你可能需要不时地向你的领导或者同事分享你目前的工作与代码开发进展,抑或你的领导想对代码进行全方位的分析。这时,你就需要用到一些代码统计的工具,我知道其中一个是 [**Ohcount**][1]。今天,我遇到了另一个程序,**cloc**。你可以用 cloc 很容易地统计多种语言的源代码行数。它还可以计算空行数、代码行数、实际代码的行数并通过整齐的表格进行结果输出。cloc 是自由开源的跨平台程序,使用 **Perl** 进行开发。
### 特点
cloc 有很多优势:
* 安装方便而且易用,不需要额外的依赖项
* 可移植
* 支持多种的结果格式导出包括纯文本、SQL、JSON、XML、YAML、CSV
* 可以计算 git 的提交数
* 可递归计算文件夹内的代码行数
* 可计算压缩后的文件tar、zip、Java 的 .ear 等类型
* 开源,跨平台
### 安装
cloc 的安装包在大多数的类 Unix 操作系统的默认软件库内,所以你只需要使用默认的包管理器安装即可。
Arch Linux:
```
$ sudo pacman -S cloc
```
Debian/Ubuntu:
```
$ sudo apt-get install cloc
```
CentOS/Red Hat/Scientific Linux:
```
$ sudo yum install cloc
```
Fedora:
```
$ sudo dnf install cloc
```
FreeBSD:
```
$ sudo pkg install cloc
```
当然你也可以使用第三方的包管理器,比如 [**NPM**][2]。
```
$ npm install -g cloc
```
### 统计多种语言代码数据的使用举例
首先来几个简单的例子,比如下面在我目前工作目录中的的 C 代码。
```
$ cat hello.c
#include <stdio.h>
int main()
{
// printf() displays the string inside quotation
printf("Hello, World!");
return 0;
}
```
想要计算行数,只需要简单运行:
```
$ cloc hello.c
```
输出:
![](https://www.ostechnix.com/wp-content/uploads/2018/10/Hello-World-Program.png)
第一列是被分析文件的编程语言,上面我们可以看到这个文件是用 C 语言编写的。
第二列显示的是该种语言有多少文件,图中说明只有一个。
第三列显示空行的数量,图中显示是 0 行。
第四列显示注释的行数。
第五列显示该文件中实际的代码总行数。
这是一个有只有 6 行代码的源文件,我们看到统计的还算准确,那么如果用来统计一个行数较多的源文件呢?
```
$ cloc file.tar.gz
```
输出:
![](https://www.ostechnix.com/wp-content/uploads/2018/10/cloc-1.png)
上述输出结果如果手动统计准确的代码行数非常困难,但是 cloc 只需要几秒,而且以易读的表格格式显示结果。你还可以在最后查看每个部分的总计,这在分析程序的源代码时非常方便。
除了源代码文件cloc 还能递归计算各个目录及其子目录下的文件、压缩包、甚至 git commit 数目等。
文件夹中使用的例子:
```
$ cloc dir/
```
![][3]
子文件夹中使用的例子*
```
$ cloc dir/cloc/tests
```
![][4]
计算一个压缩包中源代码的行数:
```
$ cloc archive.zip
```
![][5]
你还可以计算一个 git 项目,也可以像下面这样针对某次提交时的状态统计:
```
$ git clone https://github.com/AlDanial/cloc.git
$ cd cloc
$ cloc 157d706
```
![][6]
cloc 可以自动识别一些语言,使用下面的命令查看 cloc 支持的语言:
```
$ cloc --show-lang
```
更新信息请查阅 cloc 的使用帮助。
```
$ cloc --help
```
开始使用吧!
--------------------------------------------------------------------------------
via: https://www.ostechnix.com/cloc-count-the-lines-of-source-code-in-many-programming-languages/
作者:[SK][a]
选题:[lujun9972][b]
译者:[littleji](https://github.com/littleji)
校对:[pityonline](https://github.com/pityonline)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://www.ostechnix.com/author/sk/
[b]: https://github.com/lujun9972
[1]: https://www.ostechnix.com/ohcount-the-source-code-line-counter-and-analyzer/
[2]: https://www.ostechnix.com/install-node-js-linux/
[3]: http://www.ostechnix.com/wp-content/uploads/2018/10/cloc-2-1.png
[4]: http://www.ostechnix.com/wp-content/uploads/2018/10/cloc-4.png
[5]: http://www.ostechnix.com/wp-content/uploads/2018/10/cloc-3.png
[6]: http://www.ostechnix.com/wp-content/uploads/2018/10/cloc-5.png

View File

@@ -0,0 +1,167 @@
Sysget给主流的包管理器加个前端
======
![](https://www.ostechnix.com/wp-content/uploads/2018/10/sysget-720x340.png)
你是一个喜欢每隔几天尝试 Linux 操作系统的新发行版的发行版收割机吗?如果是这样,我有一些东西对你有用。 尝试 Sysget这是一个类 Unix 操作系统中的流行软件包管理器的前端。 你不需要学习每个包管理器来执行基本的操作,例如安装、更新、升级和删除包。 你只需要对每个运行在类 Unix 操作系统上的包管理器记住一种语法即可。 Sysget 是包管理器的包装脚本,它是用 C++ 编写的。 源代码可在 GitHub 上免费获得。
使用 Sysget你可以执行各种基本的包管理操作包括
- 安装包,
- 更新包,
- 升级包,
- 搜索包,
- 删除包,
- 删除弃用包,
- 更新数据库,
- 升级系统,
- 清除包管理器缓存。
**给 Linux 学习者的一个重要提示:**
Sysget 不会取代软件包管理器,绝对不适合所有人。如果你是经常切换到新 Linux 操作系统的新手Sysget 可能会有所帮助。当在不同的 Linux 发行版中使用不同的软件包管理器时,就必须学习安装、更新、升级、搜索和删除软件包的新命令,这时 Sysget 就是帮助<ruby>发行版收割机<rt>distro hopper</rt></ruby>(或新 Linux 用户)的包装脚本。
如果你是 Linux 管理员或想要学习 Linux 深层的爱好者,你应该坚持使用你的发行版的软件包管理器并学习如何使用它。
### 安装 Sysget
安装 Sysget 很简单。 转到[发布页面][1]并下载最新的 Sysget 二进制文件并按如下所示进行安装。 在编写本指南时Sysget 最新版本为1.2。
```
$ sudo wget -O /usr/local/bin/sysget https://github.com/emilengler/sysget/releases/download/v1.2/sysget
$ sudo mkdir -p /usr/local/share/sysget
$ sudo chmod a+x /usr/local/bin/sysget
```
### 用法
Sysget 命令与 APT 包管理器大致相同,因此它应该适合新手使用。
当你第一次运行 Sysget 时,系统会要求你选择要使用的包管理器。 由于我在 Ubuntu我选择了 apt-get。
![](https://www.ostechnix.com/wp-content/uploads/2018/10/sysget-1.png)
你必须根据正在运行的发行版选择正确的包管理器。 例如,如果你使用的是 Arch Linux请选择 pacman。 对于 CentOS请选择 yum。 对于 FreeBSD请选择 pkg。 当前支持的包管理器列表是:
1. apt-get (Debian)
2. xbps (Void)
3. dnf (Fedora)
4. yum (Enterprise Linux/Legacy Fedora)
5. zypper (OpenSUSE)
6. eopkg (Solus)
7. pacman (Arch)
8. emerge (Gentoo)
9. pkg (FreeBSD)
10. chromebrew (ChromeOS)
11. homebrew (Mac OS)
12. nix (Nix OS)
13. snap (Independent)
14. npm (Javascript, Global)
如果你分配了错误的包管理器,则可以使用以下命令设置新的包管理器:
```
$ sudo sysget set yum
Package manager changed to yum
```
只需确保你选择了本地包管理器。
现在,你可以像使用本机包管理器一样执行包管理操作。
要安装软件包,例如 Emacs只需运行
```
$ sudo sysget install emacs
```
上面的命令将调用本机包管理器(在我的例子中是 “apt-get”并安装给定的包。
![](https://www.ostechnix.com/wp-content/uploads/2018/10/Install-package-using-Sysget.png)
同样,要删除包,只需运行:
```
$ sudo sysget remove emacs
```
![](https://www.ostechnix.com/wp-content/uploads/2018/10/Remove-package-using-Sysget.png)
更新软件仓库(数据库):
```
$ sudo sysget update
```
搜索特定包:
```
$ sudo sysget search emacs
```
升级单个包:
```
$ sudo sysget upgrade emacs
```
升级所有包:
```
$ sudo sysget upgrade
```
移除废弃的包:
```
$ sudo sysget autoremove
```
清理包管理器的缓存:
```
$ sudo sysget clean
```
有关更多详细信息,请参阅帮助部分:
```
$ sysget help
Help of sysget
sysget [OPTION] [ARGUMENT]
search [query] search for a package in the resporitories
install [package] install a package from the repos
remove [package] removes a package
autoremove removes not needed packages (orphans)
update update the database
upgrade do a system upgrade
upgrade [package] upgrade a specific package
clean clean the download cache
set [NEW MANAGER] set a new package manager
```
请记住,不同 Linux 发行版中的所有包管理器的 Sysget 语法都是相同的。 你不需要记住每个包管理器的命令。
同样,我必须告诉你 Sysget 不是包管理器的替代品。 它只是类 Unix 系统中流行的包管理器的包装器,它只执行基本的包管理操作。
Sysget 对于不想去学习不同包管理器的新命令的新手和发行版收割机用户可能有些用处。 如果你有兴趣,试一试,看看它是否有帮助。
而且,这就是本次所有的内容了。 更多干货即将到来。 敬请关注!
祝快乐!
--------------------------------------------------------------------------------
via: https://www.ostechnix.com/sysget-a-front-end-for-popular-package-managers/
作者:[SK][a]
选题:[lujun9972][b]
译者:[Flowsnow](https://github.com/Flowsnow)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://www.ostechnix.com/author/sk/
[b]: https://github.com/lujun9972
[1]: https://github.com/emilengler/sysget/releases

View File

@@ -1,3 +1,4 @@
Translating by ranchong
How technology changes the rules for doing agile
======

View File

@@ -1,67 +0,0 @@
LuuMing translating
9 ways to improve collaboration between developers and designers
======
![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/BUS_consensuscollab1.png?itok=ULQdGjlV)
This article was co-written with [Jason Porter][1].
Design is a crucial element in any software project. Sooner or later, the developers' reasons for writing all this code will be communicated to the designers, human beings who aren't as familiar with its inner workings as the development team.
Stereotypes exist on both side of the divide; engineers often expect designers to be flaky and irrational, while designers often expect engineers to be inflexible and demanding. The truth is considerably more nuanced and, at the end of the day, the fates of designers and developers are forever intertwined.
Here are nine things that can improve collaboration between the two.
### 1\. First, knock down the wall. Seriously.
There are loads of memes about the "wall of confusion" in just about every industry. No matter what else you do, the first step toward tearing down this wall is getting both sides to agree it needs to be gone. Once everyone agrees the existing processes aren't functioning optimally, you can pick and choose from the rest of these ideas to begin fixing the problems.
### 2\. Learn to empathize.
Before rolling up any sleeves to build better communication, take a break. This is a great junction point for team building. A time to recognize that we're all people, we all have strengths and weaknesses, and most importantly, we're all on the same team. Discussions around workflows and productivity can become feisty, so it's crucial to build a foundation of trust and cooperation before diving on in.
### 3\. Recognize differences.
Designers and developers attack the same problem from different angles. Given a similar problem, designers will seek the solution with the biggest impact while developers will seek the solution with the least amount of waste. These two viewpoints do not have to be mutually exclusive. There is plenty of room for negotiation and compromise, and somewhere in the middle is where the end user receives the best experience possible.
### 4\. Embrace similarities.
This is all about workflow. CI/CD, scrum, agile, etc., are all basically saying the same thing: Ideate, iterate, investigate, and repeat. Iteration and reiteration are common denominators for both kinds of work. So instead of running a design cycle followed by a development cycle, it makes much more sense to run them concurrently and in tandem. Syncing cycles allows teams to communicate, collaborate, and influence each other every step of the way.
### 5\. Manage expectations.
All conflict can be distilled down to one simple idea: incompatible expectations. Therefore, an easy way to prevent systemic breakdowns is to manage expectations by ensuring that teams are thinking before talking and talking before doing. Setting expectations often evolves organically through everyday conversation. Forcing them to happen by having meetings can be counterproductive.
### 6\. Meet early and meet often.
Meeting once at the beginning of work and once at the end simply isn't enough. This doesn't mean you need daily or even weekly meetings. Setting a cadence for meetings can also be counterproductive. Let them happen whenever they're necessary. Great things can happen with impromptu meetings—even at the watercooler! If your team is distributed or has even one remote employee, video conferencing, text chat, or phone calls are all excellent ways to meet. It's important that everyone on the team has multiple ways to communicate with each other.
### 7\. Build your own lexicon.
Designers and developers sometimes have different terms for similar ideas. One person's card is another person's tile is a third person's box. Ultimately, the fit and accuracy of a term aren't as important as everyone's agreement to use the same term consistently.
### 8\. Make everyone a communication steward.
Everyone in the group is responsible for maintaining effective communication, regardless of how or when it happens. Each person should strive to say what they mean and mean what they say.
### 9\. Give a darn.
It only takes one member of a team to sabotage progress. Go all in. If every individual doesn't care about the product or the goal, there will be problems with motivation to make changes or continue the process.
This article is based on [Designers and developers: Finding common ground for effective collaboration][2], a talk the authors will be giving at [Red Hat Summit 2018][3], which will be held May 8-10 in San Francisco. [Register by May 7][3] to save US$ 500 off of registration. Use discount code **OPEN18** on the payment page to apply the discount.
--------------------------------------------------------------------------------
via: https://opensource.com/article/18/5/9-ways-improve-collaboration-developers-designers
作者:[Jason Brock][a]
选题:[lujun9972](https://github.com/lujun9972)
译者:[译者ID](https://github.com/译者ID)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://opensource.com/users/jkbrock
[1]:https://opensource.com/users/lightguardjp
[2]:https://agenda.summit.redhat.com/SessionDetail.aspx?id=154267
[3]:https://www.redhat.com/en/summit/2018

View File

@@ -1,133 +0,0 @@
Translating by Ryze-Borgia
Linux vs Mac: 7 Reasons Why Linux is a Better Choice than Mac
======
Recently, we highlighted a few points about [why Linux is better than Windows][1]. Unquestionably, Linux is a superior platform. But, like other operating systems it has its drawbacks as well. For a very particular set of tasks (such as Gaming), Windows OS might prove to be better. And, likewise, for another set of tasks (such as video editing), a Mac-powered system might come in handy. It all trickles down to your preference and what you would like to do with your system. So, in this article, we will highlight a number of reasons why Linux is better than Mac.
If youre already using a Mac or planning to get one, we recommend you to thoroughly analyze the reasons and decide whether you want to switch/keep using Linux or continue using Mac.
### 7 Reasons Why Linux is Better Than Mac
![Linux vs Mac: Why Linux is a Better Choice][2]
Both Linux and macOS are Unix-like OS and give access to Unix commands, BASH and other shells. Both of them have fewer applications and games than Windows. But the similarity ends here.
Graphic designers and video editors swear by macOS whereas Linux is a favorite of developers, sysadmins and devops.
So the question is should you use Linux over Mac? If yes, why? Let me give you some practical and some ideological reasons why Linux is better than Mac.
#### 1\. Price
![Linux vs Mac: Why Linux is a Better Choice][3]
Lets suppose, you use the system only to browse stuff, watch movies, download photos, write a document, create a spreadsheet, and other similar stuff. And, in addition to those activities, you want to have a secure operating system.
In that case, you could choose to spend a couple of hundred bucks for a system to get things done. Or do you think spending more for a MacBook is a good idea? Well, you are the judge.
So, it really depends on what you prefer. Whether you want to spend on a Mac-powered system or get a budget laptop/PC and install any Linux distro for free. Personally, Ill be happy with a Linux system except for editing videos and music production. In that case, Final Cut Pro (for video editing) and Logic Pro X (for music production) will be my preference.
#### 2\. Hardware Choices
![Linux vs Mac: Why Linux is a Better Choice][4]
Linux is free. You can install it on computers with any configuration. No matter how powerful/old your system is, Linux will work. [Even if you have an 8-year old PC laying around, you can have Linux installed and expect it to run smoothly by selecting the right distro][5].
But, Mac is as an Apple-exclusive. If you want to assemble a PC or get a budget laptop (with DOS) and expect to install Mac OS, its almost impossible. Mac comes baked in with the system Apple manufactures.
There are [ways to install macOS on non Apple devices][6]. However, the kind of expertise and troubles it requires, it makes you question whether its worth the effort.
You will have a wide range of hardware choices when you go with Linux but a minimal set of configurations when it comes to Mac OS.
#### 3\. Security
![Linux vs Mac: Why Linux is a Better Choice][7]
A lot of people are all praises for iOS and Mac for being a secure platform. Well, yes, it is secure in a way (maybe more secure than Windows OS), but probably not as secure as Linux.
I am not bluffing. There are malware and adware targeting macOS and the [number is growing every day][8]. I have seen not-so-techie users struggling with their slow mac. A quick investigation revealed that a [browser hijacking malware][9] was the culprit.
There are no 100% secure operating systems and Linux is not an exception. There are vulnerabilities in the Linux world as well but they are duly patched by the timely updates provided by Linux distributions.
Thankfully, we dont have auto-running viruses or browser hijacking malwares in Linux world so far. And thats one more reason why you should use Linux instead of a Mac.
#### 4\. Customization & Flexibility
![Linux vs Mac: Why Linux is a Better Choice][10]
You dont like something? Customize it or remove it. End of the story.
For example, if you do not like the [Gnome desktop environment][11] on Ubuntu 18.04.1, you might as well change it to [KDE Plasma][11]. You can also try some of the [Gnome extensions][12] to enhance your desktop experience. You wont find this level of freedom and customization on Mac OS.
Besides, you can even modify the source code of your OS to add/remove something (which requires necessary technical knowledge) and create your own custom OS. Can you do that on Mac OS?
Moreover, you get an array of Linux distributions to choose from as per your needs. For instance, if you need to mimic the workflow on Mac OS, [Elementary OS][13] would help. Do you want to have a lightweight Linux distribution installed on your old PC? Weve got you covered in our list of [lightweight Linux distros][5]. Mac OS lacks this kind of flexibility.
#### 5\. Using Linux helps your professional career [For IT/Tech students]
![Linux vs Mac: Why Linux is a Better Choice][14]
This is kind of controversial and applicable to students and job seekers in the IT field. Using Linux doesnt make you a super-intelligent being and could possibly get you any IT related job.
However, as you start using Linux and exploring it, you gain experience. As a techie, sooner or later you dive into the terminal, learning your way to move around the file system, installing applications via command line. You wont even realize that you have learned the skills that newcomers in IT companies get trained on.
In addition to that, Linux has enormous scope in the job market. There are so many Linux related technologies (Cloud, Kubernetes, Sysadmin etc.) you can learn, earn certifications and get a nice paying job. And to learn these, you have to use Linux.
#### 6\. Reliability
![Linux vs Mac: Why Linux is a Better Choice][15]
Ever wondered why Linux is the best OS to run on any server? Because it is more reliable!
But, why is that? Why is Linux more reliable than Mac OS?
The answer is simple more control to the user while providing better security. Mac OS does not provide you with the full control of its platform. It does that to make things easier for you simultaneously enhancing your user experience. With Linux, you can do whatever you want which may result in poor user experience (for some) but it does make it more reliable.
#### 7\. Open Source
![Linux vs Mac: Why Linux is a Better Choice][16]
Open Source is something not everyone cares about. But to me, the most important aspect of Linux being a superior choice is its Open Source nature. And, most of the points discussed below are the direct advantages of an Open Source software.
To briefly explain, you get to see/modify the source code yourself if it is an open source software. But, for Mac, Apple gets an exclusive control. Even if you have the required technical knowledge, you will not be able to independently take a look at the source code of Mac OS.
In other words, a Mac-powered system enables you to get a car for yourself but the downside is you cannot open up the hood to see whats inside. Thats bad!
If you want to dive in deeper to know about the benefits of an open source software, you should go through [Ben Balters article][17] on OpenSource.com.
### Wrapping Up
Now that youve known why Linux is better than Mac OS. What do you think about it? Are these reasons enough for you to choose Linux over Mac OS? If not, then what do you prefer and why?
Let us know your thoughts in the comments below.
Note: The artwork here is based on Club Penguins.
--------------------------------------------------------------------------------
via: https://itsfoss.com/linux-vs-mac/
作者:[Ankush Das][a]
选题:[lujun9972](https://github.com/lujun9972)
译者:[译者ID](https://github.com/译者ID)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://itsfoss.com/author/ankush/
[1]: https://itsfoss.com/linux-better-than-windows/
[2]: https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2018/09/Linux-vs-mac-featured.png
[3]: https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2018/09/linux-vs-mac-1.jpeg
[4]: https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2018/09/linux-vs-mac-4.jpeg
[5]: https://itsfoss.com/lightweight-linux-beginners/
[6]: https://hackintosh.com/
[7]: https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2018/09/linux-vs-mac-2.jpeg
[8]: https://www.computerworld.com/article/3262225/apple-mac/warning-as-mac-malware-exploits-climb-270.html
[9]: https://www.imore.com/how-to-remove-browser-hijack
[10]: https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2018/09/linux-vs-mac-3.jpeg
[11]: https://www.gnome.org/
[12]: https://itsfoss.com/best-gnome-extensions/
[13]: https://elementary.io/
[14]: https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2018/09/linux-vs-mac-5.jpeg
[15]: https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2018/09/linux-vs-mac-6.jpeg
[16]: https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2018/09/linux-vs-mac-7.jpeg
[17]: https://opensource.com/life/15/12/why-open-source

View File

@@ -0,0 +1,105 @@
Talk over text: Conversational interface design and usability
======
To make conversational interfaces more human-centered, we must free our thinking from the trappings of web and mobile design.
![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/migration_innovation_computer_software.png?itok=VCFLtd0q)
Conversational interfaces are unique among the screen-based and physically manipulated user interfaces that characterize the range of digital experiences we encounter on a daily basis. As [Conversational Design][1] author Erika Hall eloquently writes, "Conversation is not a new interface. It's the oldest interface." And the conversation, the most human interaction of all, lies at the nexus of the aural and verbal rather than the visual and physical. This makes it particularly challenging for machines to meet the high expectations we tend to have when it comes to typical human conversations.
How do we design for conversational interfaces, which run the gamut from omnichannel chatbots on our websites and mobile apps to mono-channel voice assistants on physical devices such as the Amazon Echo and Google Home? What recommendations do other experts on conversational design and usability have when it comes to crafting the most robust chatbot or voice interface possible? In this overview, we focus on three areas: information architecture, design, and usability testing.
### Information architecture: Trees, not sitemaps
Consider the websites we visit and the visual interfaces we use regularly. Each has a navigational tool, whether it is a list of links or a series of buttons, that helps us gain some understanding of the interface. In a web-optimized information architecture, we can see the entire hierarchy of a website and its contents in the form of such navigation bars and sitemaps.
On the other hand, in a conversational information architecture—whether articulated in a chatbot or a voice assistant—the structure of our interactions must be provided to us in a simple and straightforward way. For instance, in lieu of a navigation bar that has links to pages like About, Menu, Order, and Locations with further links underneath, we can create a conversational means of describing how to navigate the options we wish to pursue.
Consider the differences between the two examples of navigation below.
| **Web-based navigation:** | **Conversational navigation:** |
| Present all options in the navigation bar | Present only certain top-level options to access deeper options |
|-------------------------------------------|-----------------------------------------------------------------|
| • Floss's Pizza | • "To learn more about us, say About" |
| • About | • "To hear our menu, say Menu" |
| ◦ Team | • "To place an order, say Order" |
| ◦ Our story | • "To find out where we are, say Where" |
| • Menu | |
| ◦ Pizzas | |
| ◦ Pastas | |
| ◦ Platters | |
| • Order | |
| ◦ Pickup | |
| ◦ Delivery | |
| • Where we are | |
| ◦ Area map • "Welcome to Floss's Pizza!" | |
In a conversational context, an appropriate information architecture that focuses on decision trees is of paramount importance, because one of the biggest issues many conversational interfaces face is excessive verbosity. By avoiding information overload, prizing structural simplicity, and prescribing one-word directions, your users can traverse conversational interfaces without any additional visual aid.
### Design: Finessing flows and language
![Well-designed language example][3]
An example of well-designed language that encapsulates Hall's conversational key moments.
In her book Conversational Design, Hall emphasizes the need for all conversational interfaces to adhere to conversational maxims outlined by Paul Grice and advanced by Robin Lakoff. These conversational maxims highlight the characteristics every conversational interface should have to succeed: quantity (just enough information but not too much), quality (truthfulness), relation (relevance), manner (concision, orderliness, and lack of ambiguity), and politeness (Lakoff's addition).
In the process, Hall spotlights four key moments that build trust with users of conversational interfaces and give them all of the information they need to interact successfully with the conversational experience, whether it is a chatbot or a voice assistant.
* **Introduction:** Invite the user's interest and encourage trust with a friendly but brief greeting that welcomes them to an unfamiliar interface.
* **Orientation:** Offer system options, such as how to exit out of certain interactions, and provide a list of options that help the user achieve their goal.
* **Action:** After each response from the user, offer a new set of tasks and corresponding controls for the user to proceed with further interaction.
* **Guidance:** Provide feedback to the user after every response and give clear instructions.
Taken as a whole, these key moments indicate that good conversational design obligates us to consider how we write machine utterances to be both inviting and informative and to structure our decision flows in such a way that they flow naturally to the user. In other words, rather than visual design chops or an eye for style, conversational design requires us to be good writers and thoughtful architects of decision trees.
![Decision flow example ][5]
An example decision flow that adheres to Hall's key moments.
One metaphor I use on a regular basis to conceive of each point in a conversational interface that presents a choice to the user is the dichotomous key. In tree science, dichotomous keys are used to identify trees in their natural habitat through certain salient characteristics. What makes dichotomous keys special, however, is the fact that each card in a dichotomous key only offers two choices (hence the moniker "dichotomous") with a clearly defined characteristic that cannot be mistaken for another. Eventually, after enough dichotomous choices have been made, we can winnow down the available options to the correct genus of tree.
We should design conversational interfaces in the same way, with particular attention given to disambiguation and decision-making that never verges on too much complexity. Because conversational interfaces require deeply nested hierarchical structures to reach certain outcomes, we can never be too helpful in the instructions and options we offer our users.
### Usability testing: Dialogues, not dialogs
Conversational usability is a relatively unexplored and less-understood area because it is frequently based on verbal and aural interactions rather than visual or physical ones. Whereas chatbots can be evaluated for their usability using traditional means such as think-aloud, voice assistants and other voice-driven interfaces have no such luxury.
For voice interfaces, we are unable to pursue approaches involving eye-tracking or think-aloud, since these interfaces are purely aural and users' utterances outside of responses to interface prompts can introduce bad data. For this reason, when our Acquia Labs team built [Ask GeorgiaGov][6], the first Alexa skill for residents of the state of Georgia, we chose retrospective probing (RP) for our usability tests.
In retrospective probing, the conversational interaction proceeds until the completion of the task, at which point the user is asked about their impressions of the interface. Retrospective probing is well-positioned for voice interfaces because it allows the conversation to proceed unimpeded by interruptions such as think-aloud feedback. Nonetheless, it does come with the disadvantage of suffering from our notoriously unreliable memories, as it forces us to recollect past interactions rather than ones we completed immediately before recollection.
### Challenges and opportunities
Conversational interfaces are here to stay in our rapidly expanding spectrum of digital experiences. Though they enrich the range of ways we have to engage users, they also present unprecedented challenges when it comes to information architecture, design, and usability testing. With the help of previous work such as Grice's conversational maxims and Hall's key moments, we can design and build effective conversational interfaces by focusing on strong writing and well-considered decision flows.
The fact that conversation is the oldest and most human of interfaces is also edifying when we approach other user interfaces that lack visual or physical manipulation. As Hall writes, "The ideal interface is an interface that's not noticeable at all." Whether or not we will eventually reach the utopian outcome of conversational interfaces that feel completely natural to the human ear, we can make conversational interfaces more human-centered by freeing our thinking from the trappings of web and mobile.
Preston So will present [Talk Over Text: Conversational Interface Design and Usability][7] at [All Things Open][8], October 21-23 in Raleigh, North Carolina.
--------------------------------------------------------------------------------
via: https://opensource.com/article/18/10/conversational-interface-design-and-usability
作者:[Preston So][a]
选题:[lujun9972][b]
译者:[译者ID](https://github.com/译者ID)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://opensource.com/users/prestonso
[b]: https://github.com/lujun9972
[1]: https://abookapart.com/products/conversational-design
[2]: /file/411001
[3]: https://opensource.com/sites/default/files/uploads/conversational-interfaces_1.png (Well-designed language example)
[4]: /file/411006
[5]: https://opensource.com/sites/default/files/uploads/conversational-interfaces_2.png (Decision flow example )
[6]: https://www.acquia.com/blog/ask-georgiagov-alexa-skill-citizens-georgia-acquia-labs/12/10/2017/3312516
[7]: https://allthingsopen.org/talk/talk-over-text-conversational-interface-design-and-usability/
[8]: https://allthingsopen.org/

View File

@@ -0,0 +1,147 @@
How to level up your organization's security expertise
======
These best practices will make your employees more savvy and your organization more secure.
![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/checklist_hands_team_collaboration.png?itok=u82QepPk)
IT security is critical to every company these days. In the words of former FBI director Robert Mueller: “There are only two types of companies: Those that have been hacked, and those that will be.”
At the same time, IT security is constantly evolving. We all know we need to keep up with the latest trends in cybersecurity and security tooling, but how can we do that without sacrificing our ability to keep moving forward on our business priorities?
No single person in your organization can handle all of the security work alone; your entire development and operations team will need to develop an awareness of security tooling and best practices, just like they all need to build skills in open source and in agile software delivery. There are a number of best practices that can help you level up the overall security expertise in your company through basic and intermediate education, subject matter experts, and knowledge-sharing.
### Basic education: Annual cybersecurity education and security contact information
At IBM, we all complete an online cybersecurity training class each year. I recommend this as a best practice for other companies as well. The online training is taught at a basic level, and it doesnt assume that anyone has a technical background. Topics include social engineering, phishing and spearfishing attacks, problematic websites, viruses and worms, and so on. We learn how to avoid situations that may put ourselves or our systems at risk, how to recognize signs of an attempted security breach, and how to report a problem if we notice something that seems suspicious. This online education serves the purpose of raising the overall security awareness and readiness of the organization at a low per-person cost. A nice side effect of this education is that this basic knowledge can be applied to our personal lives, and we can share what we learned with our family and friends as well.
In addition to the general cybersecurity education, all employees should have annual training on data security and privacy regulations and how to comply with those.
Finally, we make it easy to find the Corporate Security Incident Response team by sharing the link to its website in prominent places, including Slack, and setting up suggested matches to ensure that a search of our internal website will send people to the right place:
![](https://opensource.com/sites/default/files/uploads/security_search_screen.png)
### Intermediate education: Learn from your tools
Another great source of security expertise is through pre-built security tools. For example, we have set up a set of automated security tests that run against our web services using IBM AppScan, and the reports it generates include background knowledge about the vulnerabilities it finds, the severity of the threat, how to determine if your application is susceptible to the vulnerability, and how to fix the problem, with code examples.
Similarly, the free [npm audit command-line tool from npm, Inc.][1] will scan your open source Node.js modules and report any known vulnerabilities it finds. This tool also generates educational audit reports that include the severity of the threat, the vulnerable package, and versions with the vulnerability, an alternative package or versions that do not have the vulnerability, dependencies, and a link to more detailed information about the vulnerability. Heres an example of a report from npm audit:
| High | Regular Expression Denial of Service |
| --------------| ----------------------------------------- |
| Package | minimath |
| --------------| ----------------------------------------- |
| Dependency of | gulp [dev] |
| --------------| ----------------------------------------- |
| Path | gulp > vinyl-fs > glob-stream > minimatch |
| --------------| ----------------------------------------- |
| More info | https://nodesecurity.io/advisories/118 |
Any good network-level security tool will also give you information on the types of attacks the tool is blocking and how it recognizes likely attacks. This information is available in the marketing materials online as well as the tools console and reports if you have access to those.
Each of your development teams or squads should have at least one subject matter expert who takes the time to read and fully understand the vulnerability reports that are relevant to you. This is often the technical lead, but it could be anyone who is interested in learning more about security. Your local subject matter expert will be able to recognize similar security holes in the future earlier in the development and deployment process.
Using the npm audit example above, a developer who reads and understands security advisory #118 from this report will be more likely to notice changes that may allow for a Regular Expression Denial of Service when reviewing code in the future. The teams subject matter expert should also develop the skills needed to determine which of the vulnerability reports dont actually apply to his or her specific project.
### Intermediate education: Conferences
Lets not forget the value of attending security-related conferences, such as the [OWASP AppSec Conferences][2]. Conferences provide a great way for members of your team to focus on learning for a few days and bring back some of the newest ideas in the field. The “hallway track” of a conference, where we can learn from other practitioners, is also a valuable source of information. As much as most of us dislike being “sold to,” the sponsor hall at a conference is a good place to casually check out new security tools to see which ones you might be interested in evaluating later.
If your organization is big enough, ask your DevOps and security tool vendors to come to you! If youve already procured some great tools, but adoption isnt going as quickly as you would like, many vendors would be happy to provide your teams with some additional practical training. Its in their best interests to increase the adoption of their tools (making you more likely to continue paying for their services and to increase your license count), just like its in your best interests to maximize the value you get out of the tools youre paying for. We recently hosted a [Toolbox@IBM][3] \+ DevSecOps summit at our largest sites (those with a couple thousand IT professionals). More than a dozen vendors sponsored each event, came onsite, set up booths, and gave conference talks, just like they would at a technical conference. We also had several of our own presenters speaking about DevOps and security best practices that were working well for them, and we had booths set up by our Corporate Information Security Office, agile coaching, onsite tech support, and internal toolchain teams. We had several hundred attendees at each site. It was great for our technical community because we could focus on the tools that we had already procured, learn how other teams in our company were using them, and make connections to help each other in the future.
When you send someone to a conference, its important to set the expectation that they will come back and share what theyve learned with the team. We usually do this via an informal brown-bag lunch-and-learn, where people are encouraged to discuss new ideas interactively.
### Subject-matter experts and knowledge-sharing: The secure engineering guild
In the IBM Digital Business Group, weve adopted the squad model as described by [Spotify][4] and tweaked it to make it work for us. One sometimes-forgotten aspect of the squad model is the guild. Guilds are centers of excellence, focused around one topic or skill set, with members from many squads. Guild members learn together, share best practices with each other and their broader teams, and work to advance the state of the art. If you would like to establish your own secure engineering guild, here are some tips that have worked for me in setting up guilds in the past:
**Step 1: Advertise and recruit**
Your co-workers are busy people, so for many of them, a secure engineering guild could feel like just one more thing they have to cram into the week that doesnt involve writing code. Its important from the outset that the guild has a value proposition that will benefit its members as well as the organization.
Zane Lackey from [Signal Sciences][5] gave me some excellent advice: Its important to call out the truth. In the past, he said, security initiatives may have been more of a hindrance or even a blocker to getting work done. Your secure engineering guild needs to focus on ways to make your engineering teams lives easier and more efficient instead. You need to find ways to automate more of the busywork related to security and to make your development teams more self-sufficient so you dont have to rely on security “gates” or hurdles late in the development process.
Here are some things that may attract people to your guild:
* Learn about security vulnerabilities and what you can do to combat them
* Become a subject matter expert
* Participate in penetration testing
* Evaluate and pilot new security tools
* Add “Secure Engineering Guild” to your resume
Here are some additional guild recruiting tips:
* Reach out directly to your security experts and ask them to join: security architects, network security administrators, people from your corporate security department, and so on.
* Bring in an external speaker who can get people excited about secure engineering. Advertise it as “sponsored by the Secure Engineering Guild” and collect names and contact information for people who want to join your guild, both before and after the talk.
* Get executive support for the program. Perhaps one of your VPs will write a blog post extolling the virtues of secure engineering skills and asking people to join the guild (or perhaps you can draft the blog post for her or him to edit and publish). You can combine that blog post with advertising the external speaker if the timing allows.
* Ask your management team to nominate someone from each squad to join the guild. This hardline approach is important if you have an urgent need to drive rapid improvement in your security posture.
**Step 2: Build a team**
Guild meetings should be structured for action. Its important to keep an agenda so people know what you plan to cover in each meeting, but leave time at the end for members to bring up any topics they want to discuss. Also be sure to take note of action items, and assign an owner and a target date for each of them. Finally, keep meeting minutes and send a brief summary out after each meeting.
Your first few guild meetings are your best opportunity to set off on the right foot, with a bit of team-building. I like to run a little design thinking exercise where you ask team members to share their ideas for the guilds mission statement, vote on their favorites, and use those to craft a simple and exciting mission statement. The mission statement should include three components: WHO will benefit, WHAT the guild will do, and the WOW factor. The exercise itself is valuable because you can learn why people have decided to volunteer to be a part of the guild in the first place, and what they hope will come of it.
Another thing I like to do from the outset is ask people what theyre hoping to achieve as a guild. The guild should learn together, have fun, and do real work. Once you have those ideas out on the table, start putting owners and target dates next to those goals.
* Would they like to run a book club? Get someone to suggest a book and set up book club meetings.
* Would they like to share useful articles and blogs? Get someone to set up a Slack channel and invite everyone to it, or set up a shared document where people can contribute their favorite resources.
* Would they like to pilot a new tool? Get someone to set up a free trial, try it out for their own team, and report back in a few weeks.
* Would they like to continue a series of talks? Get someone to create a list of topics and speakers and send out the invitations.
If a few goals end up without owners or dates, thats OK; just start a to-do list or backlog for people to refer to when theyve completed their first task.
Finally, survey the team to find the best time and day of the week for ongoing meetings and set those up. I recommend starting with weekly 30-minute meetings and adjust as needed.
**Step 3: Keep the energy going, or reboot**
As the months go on, your guild could start to lose energy. Here are some ways to keep the excitement going or reboot a guild thats losing energy.
* Dont be an echo chamber. Invite people in from various parts of the organization to talk for a few minutes about what theyre doing with respect to security engineering, and where they have concerns or see gaps.
* Show measurable progress. If youve been assigning owners to action items and completing them all along, youve certainly made progress, but if you look at it only from week to week, the progress can feel small or insignificant. Once per quarter, take a step back and write a blog about all youve accomplished and send it out to your organization. Showing off what youve accomplished makes the team proud of what theyve accomplished, and its another opportunity to recruit even more people for your guild.
* Dont be afraid to take on a large project. The guild should not be an ivory tower; it should get things done. Your guild may, for example, decide to roll out a new security tool that you love across a large organization. With a little bit of project management and a lot of executive support, you can and should tackle cross-squad projects. The guild members can and should be responsible for getting stories from the large projects prioritized in their own squads backlogs and completed in a timely manner.
* Periodically brainstorm the next set of action items. As time goes by, the most critical or pressing needs of your organization will likely change. People will be more motivated to work on the things they consider most important and urgent.
* Reward the extra work. You might offer an executive-sponsored cash award for the most impactful secure engineering projects. You might also have the guild itself choose someone to send to a security conference now and then.
### Go forth, and make your company more secure
A more secure company starts with a more educated team. Building upon that expertise, a secure engineering guild can drive real changes by developing and sharing best practices, finding the right owners for each action item, and driving them to closure. I hope you found a few tips here that will help you level up the security expertise in your organization. Please add your own helpful tips in the comments.
--------------------------------------------------------------------------------
via: https://opensource.com/article/18/10/how-level-security-expertise-your-organization
作者:[Ann Marie Fred][a]
选题:[lujun9972][b]
译者:[译者ID](https://github.com/译者ID)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://opensource.com/users/annmarie99
[b]: https://github.com/lujun9972
[1]: https://www.npmjs.com/about
[2]: https://www.owasp.org/index.php/Category:OWASP_AppSec_Conference
[3]: mailto:Toolbox@IBM
[4]: https://medium.com/project-management-learnings/spotify-squad-framework-part-i-8f74bcfcd761
[5]: https://www.signalsciences.com/

View File

@@ -1,3 +1,5 @@
BriFuture is translating this article
# Compiling Lisp to JavaScript From Scratch in 350
In this article we will look at a from-scratch implementation of a compiler from a simple LISP-like calculator language to JavaScript. The complete source code can be found [here][7].

View File

@@ -1,3 +1,6 @@
Translating by MjSeven
# [Improve your Bash scripts with Argbash][1]
![](https://fedoramagazine.org/wp-content/uploads/2017/11/argbash-1-945x400.png)

View File

@@ -1,3 +1,5 @@
translating by Flowsnow
Peeking into your Linux packages
======
Do you ever wonder how many _thousands_ of packages are installed on your Linux system? And, yes, I said "thousands." Even a fairly modest Linux system is likely to have well over a thousand packages installed. And there are many ways to get details on what they are.

View File

@@ -1,3 +1,6 @@
**translating by [ivo-wang](https://github.com/ivo-wang)**
10 keys to quick game development
======
![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/computer_keyboard_laptop_development_code_woman.png?itok=vbYz6jjb)

View File

@@ -1,4 +1,3 @@
imquanquan Translating
Trying Other Go Versions
============================================================
@@ -110,4 +109,4 @@ via: https://pocketgophers.com/trying-other-versions/
[8]:https://pocketgophers.com/trying-other-versions/#trying-a-specific-release
[9]:https://pocketgophers.com/guide-to-json/
[10]:https://pocketgophers.com/trying-other-versions/#trying-any-release
[11]:https://pocketgophers.com/trying-other-versions/#trying-a-source-build-e-g-tip
[11]:https://pocketgophers.com/trying-other-versions/#trying-a-source-build-e-g-tip

View File

@@ -1,4 +1,3 @@
Zafiry translating...
Writing eBPF tracing tools in Rust
============================================================

View File

@@ -1,3 +1,5 @@
translating by Flowsnow
Build a bikesharing app with Redis and Python
======

View File

@@ -1,3 +1,5 @@
translating by Flowsnow
How To Rename Multiple Files At Once In Linux
======

View File

@@ -1,3 +1,5 @@
HankChow translating
Why is Python so slow?
============================================================

View File

@@ -1,190 +0,0 @@
How To Lock The Keyboard And Mouse, But Not The Screen In Linux
======
![](https://www.ostechnix.com/wp-content/uploads/2017/09/Lock-The-Keyboard-And-Mouse-720x340.jpg)
My 4-years-old niece is a curious-kid. She loves “Avatar” movie very much. When the Avatar movie is on, she became so focused and her eyes are glued to the screen. But the problem is she often touches a key in the keyboard or move the mouse or click the mouse button while watching the movie. Sometimes, she accidentally close or pause the movie by pressing a key in the keyboard. So I was looking for a way to lock down both the keyboard and mouse, but not the screen. Luckily, I came across a perfect solution in Ubuntu forum. If you dont want your cat or puppy walking on your keyboard or your kid messing up with the keyboard and mouse while you watching something important on the screen, I suggest you to try **“xtrlock”** utility. It is a simple, yet useful utility to lock the X display till the user enters their password at the keyboard. In this brief tutorial, I will show you how to lock the keyboard and mouse, but not the screen in Linux. This trick will work on all Linux operating systems.
### Install xtrlock
The xtrlock package is available in the default repositories of most Linux operating systems. So, you can install it using your distributions package manager.
On **Arch Linux** and derivatives, run the following command to install it.
```
$ sudo pacman -S xtrlock
```
On **Fedora** :
```
$ sudo dnf install xtrlock
```
On **RHEL, CentOS** :
```
$ sudo yum install xtrlock
```
On **SUSE/openSUSE** :
```
$ sudo zypper install xtrlock
```
On **Debian, Ubuntu, Linux Mint** :
```
$ sudo apt-get install xtrlock
```
### Lock the Keyboard and Mouse, but not the Screen using xtrlock
Once xtrlock installed, create a keyboard shortcut. You need this to lock the keyboard and mouse using the key combination of your choice.
Create a new file called **lockkbmouse** in **/usr/local/bin**.
```
$ sudo vi /usr/local/bin/lockkbmouse
```
Add the following lines into it.
```
#!/bin/bash
sleep 1 && xtrlock
```
Save the file and close the file.
Make it as executable using the following command:
```
$ sudo chmod a+x /usr/local/bin/lockkbmouse
```
Next, we need to create keyboard a shortcut.
**In Arch Linux MATE desktop:**
Go to **System - > Preferences -> Hardware -> keyboard Shortcuts**.
Click **Add** to create a new shortcut.
![][2]
Enter the name for your shortcut and add the following line in the command box, and click **Apply** button.
```
bash -c "sleep 1 && xtrlock"
```
![][3]
To assign the shortcut key, just select or double click on it and type the key combination of your choice. For example, I use **Alt+k**.
![][4]
To clear the key combination, press BACKSPACE key. Once you finished, close the Keyboard Settings window.
**In Ubuntu GNOME DE:**
Go to **System Settings - > Devices -> Keyboard**. Click the **+** symbol at the end.
Enter the name for your shortcut and add the following line in the command box, and click **Add** button.
```
bash -c "sleep 1 && xtrlock"
```
![][5]
Next, assign the shortcut key to the newly created shortcut. To do so, just select or double click on it and click on **“Set shortcut”** button.
![][6]
You will now see the following screen.
![][7]
Type the key combination of your choice. For example, I use **Alt+k**.
![][8]
To clear the key combination, press BACKSPACE key. The shortcut key has been assigned. Once you finished, close the Keyboard Settings window.
From now on, whenever you press the keyboard shortcut key (ALT+k in our case), the mouse pointer will turn into a a padlock. Now, the keyboard and mouse have been locked, so you can freely watch the movies or whatever you want to. Even your kid or pet touches some keys on the keyboard or clicks a mouse button, they wont work.
Here is xtrclock in action.
![][9]
Do you see the a small lock button? It means that the keyboard and mouse have been locked. Even if you move the lock button, nothing will happen. The task in the background will keep running until you unlock your screen and manually close the running task.
### Unlock keyboard and mouse
To unlock the keyboard and mouse, simply type your password and hit “Enter”. You will not see the password as you type it. Just type the password anyway and hit ENTER key. The mouse and keyboard will start to work after you entered the correct password. If you entered an incorrect password, you will hear a bell sound. Press **ESC** key to clear the incorrect password and re-enter the correct password again. To remove one character of a partially typed password, press either **BACKSPACE** or **DELETE** keys.
### What if I permanently get locked out of the screen?
The xtrclock tool may not work on some DEs, for example GDM. It may permanently lock you out of the screen. Please test it in a virtual machine and then try it in your personal or official desktop if it really works. I tested this on Arch Linux MATE desktop and Ubuntu 18.04 GNOME desktop. It worked just fine.
Just in case, you are locked out of the screen permanently, switch to the TTY (CTRL+ALT+F2) then run:
```
$ sudo killall xtrlock
```
Alternatively, you can use the **chvt** command to switch between TTY and X session.
For example, to switch to TTY1, run:
```
$ sudo chvt 1
```
To switch back to the X session again, type:
```
$ sudo chvt 7
```
Different distros uses different key combinations to switch between TTYs. Please refer your distributions official website for more details.
For more details about xtrlock, refer man pages.
```
$ man xtrlock
```
And, thats all for now. Hope this helps. If you find our guides useful, please spend a moment to share them on your social, professional networks and support OSTechNix.
**Resource:**
* [**Ubuntu forum**][10]
--------------------------------------------------------------------------------
via: https://www.ostechnix.com/lock-keyboard-mouse-not-screen-linux/
作者:[SK][a]
选题:[lujun9972](https://github.com/lujun9972)
译者:[译者ID](https://github.com/译者ID)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://www.ostechnix.com/author/sk/
[1]:data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7
[2]:http://www.ostechnix.com/wp-content/uploads/2017/09/Keyboard-Shortcuts_001.png
[3]:http://www.ostechnix.com/wp-content/uploads/2017/09/Keyboard-Shortcuts_002.png
[4]:http://www.ostechnix.com/wp-content/uploads/2017/09/Keyboard-Shortcuts_003.png
[5]:http://www.ostechnix.com/wp-content/uploads/2018/01/Add-xtrlock-shortcut.png
[6]:http://www.ostechnix.com/wp-content/uploads/2018/01/set-shortcut-key-1.png
[7]:http://www.ostechnix.com/wp-content/uploads/2018/01/set-shortcut-key-2.png
[8]:http://www.ostechnix.com/wp-content/uploads/2018/01/set-shortcut-key-3.png
[9]:http://www.ostechnix.com/wp-content/uploads/2018/01/xtrclock-1.png
[10]:https://ubuntuforums.org/showthread.php?t=993800

View File

@@ -0,0 +1,201 @@
6.828 lab tools guide
======
### 6.828 lab tools guide
Familiarity with your environment is crucial for productive development and debugging. This page gives a brief overview of the JOS environment and useful GDB and QEMU commands. Don't take our word for it, though. Read the GDB and QEMU manuals. These are powerful tools that are worth knowing how to use.
#### Debugging tips
##### Kernel
GDB is your friend. Use the qemu-gdb target (or its `qemu-gdb-nox` variant) to make QEMU wait for GDB to attach. See the GDB reference below for some commands that are useful when debugging kernels.
If you're getting unexpected interrupts, exceptions, or triple faults, you can ask QEMU to generate a detailed log of interrupts using the -d argument.
To debug virtual memory issues, try the QEMU monitor commands info mem (for a high-level overview) or info pg (for lots of detail). Note that these commands only display the _current_ page table.
(Lab 4+) To debug multiple CPUs, use GDB's thread-related commands like thread and info threads.
##### User environments (lab 3+)
GDB also lets you debug user environments, but there are a few things you need to watch out for, since GDB doesn't know that there's a distinction between multiple user environments, or between user and kernel.
You can start JOS with a specific user environment using make run- _name_ (or you can edit `kern/init.c` directly). To make QEMU wait for GDB to attach, use the run- _name_ -gdb variant.
You can symbolically debug user code, just like you can kernel code, but you have to tell GDB which symbol table to use with the symbol-file command, since it can only use one symbol table at a time. The provided `.gdbinit` loads the kernel symbol table, `obj/kern/kernel`. The symbol table for a user environment is in its ELF binary, so you can load it using symbol-file obj/user/ _name_. _Don't_ load symbols from any `.o` files, as those haven't been relocated by the linker (libraries are statically linked into JOS user binaries, so those symbols are already included in each user binary). Make sure you get the _right_ user binary; library functions will be linked at different EIPs in different binaries and GDB won't know any better!
(Lab 4+) Since GDB is attached to the virtual machine as a whole, it sees clock interrupts as just another control transfer. This makes it basically impossible to step through user code because a clock interrupt is virtually guaranteed the moment you let the VM run again. The stepi command works because it suppresses interrupts, but it only steps one assembly instruction. Breakpoints generally work, but watch out because you can hit the same EIP in a different environment (indeed, a different binary altogether!).
#### Reference
##### JOS makefile
The JOS GNUmakefile includes a number of phony targets for running JOS in various ways. All of these targets configure QEMU to listen for GDB connections (the `*-gdb` targets also wait for this connection). To start once QEMU is running, simply run gdb from your lab directory. We provide a `.gdbinit` file that automatically points GDB at QEMU, loads the kernel symbol file, and switches between 16-bit and 32-bit mode. Exiting GDB will shut down QEMU.
* make qemu
Build everything and start QEMU with the VGA console in a new window and the serial console in your terminal. To exit, either close the VGA window or press `Ctrl-c` or `Ctrl-a x` in your terminal.
* make qemu-nox
Like `make qemu`, but run with only the serial console. To exit, press `Ctrl-a x`. This is particularly useful over SSH connections to Athena dialups because the VGA window consumes a lot of bandwidth.
* make qemu-gdb
Like `make qemu`, but rather than passively accepting GDB connections at any time, this pauses at the first machine instruction and waits for a GDB connection.
* make qemu-nox-gdb
A combination of the `qemu-nox` and `qemu-gdb` targets.
* make run- _name_
(Lab 3+) Run user program _name_. For example, `make run-hello` runs `user/hello.c`.
* make run- _name_ -nox, run- _name_ -gdb, run- _name_ -gdb-nox,
(Lab 3+) Variants of `run-name` that correspond to the variants of the `qemu` target.
The makefile also accepts a few useful variables:
* make V=1 ...
Verbose mode. Print out every command being executed, including arguments.
* make V=1 grade
Stop after any failed grade test and leave the QEMU output in `jos.out` for inspection.
* make QEMUEXTRA=' _args_ ' ...
Specify additional arguments to pass to QEMU.
##### JOS obj/
The JOS GNUmakefile includes a number of phony targets for running JOS in various ways. All of these targets configure QEMU to listen for GDB connections (thetargets also wait for this connection). To start once QEMU is running, simply runfrom your lab directory. We provide afile that automatically points GDB at QEMU, loads the kernel symbol file, and switches between 16-bit and 32-bit mode. Exiting GDB will shut down QEMU.The makefile also accepts a few useful variables:
When building JOS, the makefile also produces some additional output files that may prove useful while debugging:
* `obj/boot/boot.asm`, `obj/kern/kernel.asm`, `obj/user/hello.asm`, etc.
Assembly code listings for the bootloader, kernel, and user programs.
* `obj/kern/kernel.sym`, `obj/user/hello.sym`, etc.
Symbol tables for the kernel and user programs.
* `obj/boot/boot.out`, `obj/kern/kernel`, `obj/user/hello`, etc
Linked ELF images of the kernel and user programs. These contain symbol information that can be used by GDB.
##### GDB
See the [GDB manual][1] for a full guide to GDB commands. Here are some particularly useful commands for 6.828, some of which don't typically come up outside of OS development.
* Ctrl-c
Halt the machine and break in to GDB at the current instruction. If QEMU has multiple virtual CPUs, this halts all of them.
* c (or continue)
Continue execution until the next breakpoint or `Ctrl-c`.
* si (or stepi)
Execute one machine instruction.
* b function or b file:line (or breakpoint)
Set a breakpoint at the given function or line.
* b * _addr_ (or breakpoint)
Set a breakpoint at the EIP _addr_.
* set print pretty
Enable pretty-printing of arrays and structs.
* info registers
Print the general purpose registers, `eip`, `eflags`, and the segment selectors. For a much more thorough dump of the machine register state, see QEMU's own `info registers` command.
* x/ _N_ x _addr_
Display a hex dump of _N_ words starting at virtual address _addr_. If _N_ is omitted, it defaults to 1. _addr_ can be any expression.
* x/ _N_ i _addr_
Display the _N_ assembly instructions starting at _addr_. Using `$eip` as _addr_ will display the instructions at the current instruction pointer.
* symbol-file _file_
(Lab 3+) Switch to symbol file _file_. When GDB attaches to QEMU, it has no notion of the process boundaries within the virtual machine, so we have to tell it which symbols to use. By default, we configure GDB to use the kernel symbol file, `obj/kern/kernel`. If the machine is running user code, say `hello.c`, you can switch to the hello symbol file using `symbol-file obj/user/hello`.
QEMU represents each virtual CPU as a thread in GDB, so you can use all of GDB's thread-related commands to view or manipulate QEMU's virtual CPUs.
* thread _n_
GDB focuses on one thread (i.e., CPU) at a time. This command switches that focus to thread _n_ , numbered from zero.
* info threads
List all threads (i.e., CPUs), including their state (active or halted) and what function they're in.
##### QEMU
QEMU includes a built-in monitor that can inspect and modify the machine state in useful ways. To enter the monitor, press Ctrl-a c in the terminal running QEMU. Press Ctrl-a c again to switch back to the serial console.
For a complete reference to the monitor commands, see the [QEMU manual][2]. Here are some particularly useful commands:
* xp/ _N_ x _paddr_
Display a hex dump of _N_ words starting at _physical_ address _paddr_. If _N_ is omitted, it defaults to 1. This is the physical memory analogue of GDB's `x` command.
* info registers
Display a full dump of the machine's internal register state. In particular, this includes the machine's _hidden_ segment state for the segment selectors and the local, global, and interrupt descriptor tables, plus the task register. This hidden state is the information the virtual CPU read from the GDT/LDT when the segment selector was loaded. Here's the CS when running in the JOS kernel in lab 1 and the meaning of each field:
```
CS =0008 10000000 ffffffff 10cf9a00 DPL=0 CS32 [-R-]
```
* `CS =0008`
The visible part of the code selector. We're using segment 0x8. This also tells us we're referring to the global descriptor table (0x8 &4=0), and our CPL (current privilege level) is 0x8&3=0.
* `10000000`
The base of this segment. Linear address = logical address + 0x10000000.
* `ffffffff`
The limit of this segment. Linear addresses above 0xffffffff will result in segment violation exceptions.
* `10cf9a00`
The raw flags of this segment, which QEMU helpfully decodes for us in the next few fields.
* `DPL=0`
The privilege level of this segment. Only code running with privilege level 0 can load this segment.
* `CS32`
This is a 32-bit code segment. Other values include `DS` for data segments (not to be confused with the DS register), and `LDT` for local descriptor tables.
* `[-R-]`
This segment is read-only.
* info mem
(Lab 2+) Display mapped virtual memory and permissions. For example,
```
ef7c0000-ef800000 00040000 urw
efbf8000-efc00000 00008000 -rw
```
tells us that the 0x00040000 bytes of memory from 0xef7c0000 to 0xef800000 are mapped read/write and user-accessible, while the memory from 0xefbf8000 to 0xefc00000 is mapped read/write, but only kernel-accessible.
* info pg
(Lab 2+) Display the current page table structure. The output is similar to `info mem`, but distinguishes page directory entries and page table entries and gives the permissions for each separately. Repeated PTE's and entire page tables are folded up into a single line. For example,
```
VPN range Entry Flags Physical page
[00000-003ff] PDE[000] -------UWP
[00200-00233] PTE[200-233] -------U-P 00380 0037e 0037d 0037c 0037b 0037a ..
[00800-00bff] PDE[002] ----A--UWP
[00800-00801] PTE[000-001] ----A--U-P 0034b 00349
[00802-00802] PTE[002] -------U-P 00348
```
This shows two page directory entries, spanning virtual addresses 0x00000000 to 0x003fffff and 0x00800000 to 0x00bfffff, respectively. Both PDE's are present, writable, and user and the second PDE is also accessed. The second of these page tables maps three pages, spanning virtual addresses 0x00800000 through 0x00802fff, of which the first two are present, user, and accessed and the third is only present and user. The first of these PTE's maps physical page 0x34b.
QEMU also takes some useful command line arguments, which can be passed into the JOS makefile using the
* make QEMUEXTRA='-d int' ...
Log all interrupts, along with a full register dump, to `qemu.log`. You can ignore the first two log entries, "SMM: enter" and "SMM: after RMS", as these are generated before entering the boot loader. After this, log entries look like
```
4: v=30 e=0000 i=1 cpl=3 IP=001b:00800e2e pc=00800e2e SP=0023:eebfdf28 EAX=00000005
EAX=00000005 EBX=00001002 ECX=00200000 EDX=00000000
ESI=00000805 EDI=00200000 EBP=eebfdf60 ESP=eebfdf28
...
```
The first line describes the interrupt. The `4:` is just a log record counter. `v` gives the vector number in hex. `e` gives the error code. `i=1` indicates that this was produced by an `int` instruction (versus a hardware interrupt). The rest of the line should be self-explanatory. See info registers for a description of the register dump that follows.
Note: If you're running a pre-0.15 version of QEMU, the log will be written to `/tmp` instead of the current directory.
--------------------------------------------------------------------------------
via: https://pdos.csail.mit.edu/6.828/2018/labguide.html
作者:[csail.mit][a]
选题:[lujun9972][b]
译者:[译者ID](https://github.com/译者ID)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://pdos.csail.mit.edu
[b]: https://github.com/lujun9972
[1]: http://sourceware.org/gdb/current/onlinedocs/gdb/
[2]: http://wiki.qemu.org/download/qemu-doc.html#pcsys_005fmonitor

View File

@@ -0,0 +1,247 @@
Tools Used in 6.828
======
### Tools Used in 6.828
You'll use two sets of tools in this class: an x86 emulator, QEMU, for running your kernel; and a compiler toolchain, including assembler, linker, C compiler, and debugger, for compiling and testing your kernel. This page has the information you'll need to download and install your own copies. This class assumes familiarity with Unix commands throughout.
We highly recommend using a Debathena machine, such as athena.dialup.mit.edu, to work on the labs. If you use the MIT Athena machines that run Linux, then all the software tools you will need for this course are located in the 6.828 locker: just type 'add -f 6.828' to get access to them.
If you don't have access to a Debathena machine, we recommend you use a virtual machine with Linux. If you really want to, you can build and install the tools on your own machine. We have instructions below for Linux and MacOS computers.
It should be possible to get this development environment running under windows with the help of [Cygwin][1]. Install cygwin, and be sure to install the flex and bison packages (they are under the development header).
For an overview of useful commands in the tools used in 6.828, see the [lab tools guide][2].
#### Compiler Toolchain
A "compiler toolchain" is the set of programs, including a C compiler, assemblers, and linkers, that turn code into executable binaries. You'll need a compiler toolchain that generates code for 32-bit Intel architectures ("x86" architectures) in the ELF binary format.
##### Test Your Compiler Toolchain
Modern Linux and BSD UNIX distributions already provide a toolchain suitable for 6.828. To test your distribution, try the following commands:
```
% objdump -i
```
The second line should say `elf32-i386`.
```
% gcc -m32 -print-libgcc-file-name
```
The command should print something like `/usr/lib/gcc/i486-linux-gnu/version/libgcc.a` or `/usr/lib/gcc/x86_64-linux-gnu/version/32/libgcc.a`
If both these commands succeed, you're all set, and don't need to compile your own toolchain.
If the gcc command fails, you may need to install a development environment. On Ubuntu Linux, try this:
```
% sudo apt-get install -y build-essential gdb
```
On 64-bit machines, you may need to install a 32-bit support library. The symptom is that linking fails with error messages like "`__udivdi3` not found" and "`__muldi3` not found". On Ubuntu Linux, try this to fix the problem:
```
% sudo apt-get install gcc-multilib
```
##### Using a Virtual Machine
Otherwise, the easiest way to get a compatible toolchain is to install a modern Linux distribution on your computer. With platform virtualization, Linux can cohabitate with your normal computing environment. Installing a Linux virtual machine is a two step process. First, you download the virtualization platform.
* [**VirtualBox**][3] (free for Mac, Linux, Windows) — [Download page][3]
* [VMware Player][4] (free for Linux and Windows, registration required)
* [VMware Fusion][5] (Downloadable from IS&T for free).
VirtualBox is a little slower and less flexible, but free!
Once the virtualization platform is installed, download a boot disk image for the Linux distribution of your choice.
* [Ubuntu Desktop][6] is what we use.
This will download a file named something like `ubuntu-10.04.1-desktop-i386.iso`. Start up your virtualization platform and create a new (32-bit) virtual machine. Use the downloaded Ubuntu image as a boot disk; the procedure differs among VMs but is pretty simple. Type `objdump -i`, as above, to verify that your toolchain is now set up. You will do your work inside the VM.
##### Building Your Own Compiler Toolchain
This will take longer to set up, but give slightly better performance than a virtual machine, and lets you work in your own familiar environment (Unix/MacOS). Fast-forward to the end for MacOS instructions.
###### Linux
You can use your own tool chain by adding the following line to `conf/env.mk`:
```
GCCPREFIX=
```
We assume that you are installing the toolchain into `/usr/local`. You will need a fair amount of disk space to compile the tools (around 1GiB). If you don't have that much space, delete each directory after its `make install` step.
Download the following packages:
+ ftp://ftp.gmplib.org/pub/gmp-5.0.2/gmp-5.0.2.tar.bz2
+ https://www.mpfr.org/mpfr-3.1.2/mpfr-3.1.2.tar.bz2
+ http://www.multiprecision.org/downloads/mpc-0.9.tar.gz
+ http://ftpmirror.gnu.org/binutils/binutils-2.21.1.tar.bz2
+ http://ftpmirror.gnu.org/gcc/gcc-4.6.4/gcc-core-4.6.4.tar.bz2
+ http://ftpmirror.gnu.org/gdb/gdb-7.3.1.tar.bz2
(You may also use newer versions of these packages.) Unpack and build the packages. The `green bold` text shows you how to install into `/usr/local`, which is what we recommend. To install into a different directory, $PFX, note the differences in lighter type ([hide][7]). If you have problems, see below.
```
export PATH=$PFX/bin:$PATH
export LD_LIBRARY_PATH=$PFX/lib:$LD_LIBRARY_PATH
tar xjf gmp-5.0.2.tar.bz2
cd gmp-5.0.2
./configure --prefix=$PFX
make
make install # This step may require privilege (sudo make install)
cd ..
tar xjf mpfr-3.1.2.tar.bz2
cd mpfr-3.1.2
./configure --prefix=$PFX --with-gmp=$PFX
make
make install # This step may require privilege (sudo make install)
cd ..
tar xzf mpc-0.9.tar.gz
cd mpc-0.9
./configure --prefix=$PFX --with-gmp=$PFX --with-mpfr=$PFX
make
make install # This step may require privilege (sudo make install)
cd ..
tar xjf binutils-2.21.1.tar.bz2
cd binutils-2.21.1
./configure --prefix=$PFX --target=i386-jos-elf --disable-werror
make
make install # This step may require privilege (sudo make install)
cd ..
i386-jos-elf-objdump -i
# Should produce output like:
# BFD header file version (GNU Binutils) 2.21.1
# elf32-i386
# (header little endian, data little endian)
# i386...
tar xjf gcc-core-4.6.4.tar.bz2
cd gcc-4.6.4
mkdir build # GCC will not compile correctly unless you build in a separate directory
cd build
../configure --prefix=$PFX --with-gmp=$PFX --with-mpfr=$PFX --with-mpc=$PFX \
--target=i386-jos-elf --disable-werror \
--disable-libssp --disable-libmudflap --with-newlib \
--without-headers --enable-languages=c MAKEINFO=missing
make all-gcc
make install-gcc # This step may require privilege (sudo make install-gcc)
make all-target-libgcc
make install-target-libgcc # This step may require privilege (sudo make install-target-libgcc)
cd ../..
i386-jos-elf-gcc -v
# Should produce output like:
# Using built-in specs.
# COLLECT_GCC=i386-jos-elf-gcc
# COLLECT_LTO_WRAPPER=/usr/local/libexec/gcc/i386-jos-elf/4.6.4/lto-wrapper
# Target: i386-jos-elf
tar xjf gdb-7.3.1.tar.bz2
cd gdb-7.3.1
./configure --prefix=$PFX --target=i386-jos-elf --program-prefix=i386-jos-elf- \
--disable-werror
make all
make install # This step may require privilege (sudo make install)
cd ..
```
###### Linux troubleshooting
* Q. I can't run `make install` because I don't have root permission on this machine.
A. Our instructions assume you are installing into the `/usr/local` directory. However, this may not be allowed in your environment. If you can only install code into your home directory, that's OK. In the instructions above, replace `--prefix=/usr/local` with `--prefix=$HOME` (and [click here][7] to update the instructions further). You will also need to change your `PATH` and `LD_LIBRARY_PATH` environment variables, to inform your shell where to find the tools. For example:
```
export PATH=$HOME/bin:$PATH
export LD_LIBRARY_PATH=$HOME/lib:$LD_LIBRARY_PATH
```
Enter these lines in your `~/.bashrc` file so you don't need to type them every time you log in.
* Q. My build fails with an inscrutable message about "library not found".
A. You need to set your `LD_LIBRARY_PATH`. The environment variable must include the `PREFIX/lib` directory (for instance, `/usr/local/lib`).
#### MacOS
First begin by installing developer tools on Mac OSX:
`xcode-select --install`
First begin by installing developer tools on Mac OSX:
You can install the qemu dependencies from homebrew, however do not install qemu itself as you will need the 6.828 patched version.
`brew install $(brew deps qemu)`
The gettext utility does not add installed binaries to the path, so you will need to run
`PATH=${PATH}:/usr/local/opt/gettext/bin make install`
when installing qemu below.
### QEMU Emulator
[QEMU][8] is a modern and fast PC emulator. QEMU version 2.3.0 is set up on Athena for x86 machines in the 6.828 locker (`add -f 6.828`)
Unfortunately, QEMU's debugging facilities, while powerful, are somewhat immature, so we highly recommend you use our patched version of QEMU instead of the stock version that may come with your distribution. The version installed on Athena is already patched. To build your own patched version of QEMU:
1. Clone the IAP 6.828 QEMU git repository `git clone https://github.com/mit-pdos/6.828-qemu.git qemu`
2. On Linux, you may need to install several libraries. We have successfully built 6.828 QEMU on Debian/Ubuntu 16.04 after installing the following packages: libsdl1.2-dev, libtool-bin, libglib2.0-dev, libz-dev, and libpixman-1-dev.
3. Configure the source code (optional arguments are shown in square brackets; replace PFX with a path of your choice)
1. Linux: `./configure --disable-kvm --disable-werror [--prefix=PFX] [--target-list="i386-softmmu x86_64-softmmu"]`
2. OS X: `./configure --disable-kvm --disable-werror --disable-sdl [--prefix=PFX] [--target-list="i386-softmmu x86_64-softmmu"]` The `prefix` argument specifies where to install QEMU; without it QEMU will install to `/usr/local` by default. The `target-list` argument simply slims down the architectures QEMU will build support for.
4. Run `make && make install`
--------------------------------------------------------------------------------
via: https://pdos.csail.mit.edu/6.828/2018/tools.html
作者:[csail.mit][a]
选题:[lujun9972][b]
译者:[译者ID](https://github.com/译者ID)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://pdos.csail.mit.edu
[b]: https://github.com/lujun9972
[1]: http://www.cygwin.com
[2]: labguide.html
[3]: http://www.oracle.com/us/technologies/virtualization/oraclevm/
[4]: http://www.vmware.com/products/player/
[5]: http://www.vmware.com/products/fusion/
[6]: http://www.ubuntu.com/download/desktop
[7]:
[8]: http://www.nongnu.org/qemu/
[9]: mailto:6828-staff@lists.csail.mit.edu
[10]: https://i.creativecommons.org/l/by/3.0/us/88x31.png
[11]: https://creativecommons.org/licenses/by/3.0/us/
[12]: https://pdos.csail.mit.edu/6.828/2018/index.html

View File

@@ -0,0 +1,616 @@
Lab 1: PC Bootstrap and GCC Calling Conventions
======
### Lab 1: Booting a PC
#### Introduction
This lab is split into three parts. The first part concentrates on getting familiarized with x86 assembly language, the QEMU x86 emulator, and the PC's power-on bootstrap procedure. The second part examines the boot loader for our 6.828 kernel, which resides in the `boot` directory of the `lab` tree. Finally, the third part delves into the initial template for our 6.828 kernel itself, named JOS, which resides in the `kernel` directory.
##### Software Setup
The files you will need for this and subsequent lab assignments in this course are distributed using the [Git][1] version control system. To learn more about Git, take a look at the [Git user's manual][2], or, if you are already familiar with other version control systems, you may find this [CS-oriented overview of Git][3] useful.
The URL for the course Git repository is <https://pdos.csail.mit.edu/6.828/2018/jos.git>. To install the files in your Athena account, you need to _clone_ the course repository, by running the commands below. You must use an x86 Athena machine; that is, `uname -a` should mention `i386 GNU/Linux` or `i686 GNU/Linux` or `x86_64 GNU/Linux`. You can log into a public Athena host with `ssh -X athena.dialup.mit.edu`.
```
athena% mkdir ~/6.828
athena% cd ~/6.828
athena% add git
athena% git clone https://pdos.csail.mit.edu/6.828/2018/jos.git lab
Cloning into lab...
athena% cd lab
athena%
```
Git allows you to keep track of the changes you make to the code. For example, if you are finished with one of the exercises, and want to checkpoint your progress, you can _commit_ your changes by running:
```
athena% git commit -am 'my solution for lab1 exercise 9'
Created commit 60d2135: my solution for lab1 exercise 9
1 files changed, 1 insertions(+), 0 deletions(-)
athena%
```
You can keep track of your changes by using the git diff command. Running git diff will display the changes to your code since your last commit, and git diff origin/lab1 will display the changes relative to the initial code supplied for this lab. Here, `origin/lab1` is the name of the git branch with the initial code you downloaded from our server for this assignment.
We have set up the appropriate compilers and simulators for you on Athena. To use them, run add -f 6.828. You must run this command every time you log in (or add it to your `~/.environment` file). If you get obscure errors while compiling or running `qemu`, double check that you added the course locker.
If you are working on a non-Athena machine, you'll need to install `qemu` and possibly `gcc` following the directions on the [tools page][4]. We've made several useful debugging changes to `qemu` and some of the later labs depend on these patches, so you must build your own. If your machine uses a native ELF toolchain (such as Linux and most BSD's, but notably _not_ OS X), you can simply install `gcc` from your package manager. Otherwise, follow the directions on the tools page.
##### Hand-In Procedure
You will turn in your assignments using the [submission website][5]. You need to request an API key from the submission website before you can turn in any assignments or labs.
The lab code comes with GNU Make rules to make submission easier. After committing your final changes to the lab, type make handin to submit your lab.
```
athena% git commit -am "ready to submit my lab"
[lab1 c2e3c8b] ready to submit my lab
2 files changed, 18 insertions(+), 2 deletions(-)
athena% make handin
git archive --prefix=lab1/ --format=tar HEAD | gzip > lab1-handin.tar.gz
Get an API key for yourself by visiting https://6828.scripts.mit.edu/2018/handin.py/
Please enter your API key: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 50199 100 241 100 49958 414 85824 --:--:-- --:--:-- --:--:-- 85986
athena%
```
make handin will store your API key in _myapi.key_. If you need to change your API key, just remove this file and let make handin generate it again ( _myapi.key_ must not include newline characters).
If use make handin and you have either uncomitted changes or untracked files, you will see output similar to the following:
```
M hello.c
?? bar.c
?? foo.pyc
Untracked files will not be handed in. Continue? [y/N]
```
Inspect the above lines and make sure all files that your lab solution needs are tracked i.e. not listed in a line that begins with ??.
In the case that make handin does not work properly, try fixing the problem with the curl or Git commands. Or you can run make tarball. This will make a tar file for you, which you can then upload via our [web interface][5].
You can run make grade to test your solutions with the grading program. The [web interface][5] uses the same grading program to assign your lab submission a grade. You should check the output of the grader (it may take a few minutes since the grader runs periodically) and ensure that you received the grade which you expected. If the grades don't match, your lab submission probably has a bug -- check the output of the grader (resp-lab*.txt) to see which particular test failed.
For Lab 1, you do not need to turn in answers to any of the questions below. (Do answer them for yourself though! They will help with the rest of the lab.)
#### Part 1: PC Bootstrap
The purpose of the first exercise is to introduce you to x86 assembly language and the PC bootstrap process, and to get you started with QEMU and QEMU/GDB debugging. You will not have to write any code for this part of the lab, but you should go through it anyway for your own understanding and be prepared to answer the questions posed below.
##### Getting Started with x86 assembly
If you are not already familiar with x86 assembly language, you will quickly become familiar with it during this course! The [PC Assembly Language Book][6] is an excellent place to start. Hopefully, the book contains mixture of new and old material for you.
_Warning:_ Unfortunately the examples in the book are written for the NASM assembler, whereas we will be using the GNU assembler. NASM uses the so-called _Intel_ syntax while GNU uses the _AT &T_ syntax. While semantically equivalent, an assembly file will differ quite a lot, at least superficially, depending on which syntax is used. Luckily the conversion between the two is pretty simple, and is covered in [Brennan's Guide to Inline Assembly][7].
Exercise 1. Familiarize yourself with the assembly language materials available on [the 6.828 reference page][8]. You don't have to read them now, but you'll almost certainly want to refer to some of this material when reading and writing x86 assembly.
We do recommend reading the section "The Syntax" in [Brennan's Guide to Inline Assembly][7]. It gives a good (and quite brief) description of the AT&T assembly syntax we'll be using with the GNU assembler in JOS.
Certainly the definitive reference for x86 assembly language programming is Intel's instruction set architecture reference, which you can find on [the 6.828 reference page][8] in two flavors: an HTML edition of the old [80386 Programmer's Reference Manual][9], which is much shorter and easier to navigate than more recent manuals but describes all of the x86 processor features that we will make use of in 6.828; and the full, latest and greatest [IA-32 Intel Architecture Software Developer's Manuals][10] from Intel, covering all the features of the most recent processors that we won't need in class but you may be interested in learning about. An equivalent (and often friendlier) set of manuals is [available from AMD][11]. Save the Intel/AMD architecture manuals for later or use them for reference when you want to look up the definitive explanation of a particular processor feature or instruction.
##### Simulating the x86
Instead of developing the operating system on a real, physical personal computer (PC), we use a program that faithfully emulates a complete PC: the code you write for the emulator will boot on a real PC too. Using an emulator simplifies debugging; you can, for example, set break points inside of the emulated x86, which is difficult to do with the silicon version of an x86.
In 6.828 we will use the [QEMU Emulator][12], a modern and relatively fast emulator. While QEMU's built-in monitor provides only limited debugging support, QEMU can act as a remote debugging target for the [GNU debugger][13] (GDB), which we'll use in this lab to step through the early boot process.
To get started, extract the Lab 1 files into your own directory on Athena as described above in "Software Setup", then type make (or gmake on BSD systems) in the `lab` directory to build the minimal 6.828 boot loader and kernel you will start with. (It's a little generous to call the code we're running here a "kernel," but we'll flesh it out throughout the semester.)
```
athena% cd lab
athena% make
+ as kern/entry.S
+ cc kern/entrypgdir.c
+ cc kern/init.c
+ cc kern/console.c
+ cc kern/monitor.c
+ cc kern/printf.c
+ cc kern/kdebug.c
+ cc lib/printfmt.c
+ cc lib/readline.c
+ cc lib/string.c
+ ld obj/kern/kernel
+ as boot/boot.S
+ cc -Os boot/main.c
+ ld boot/boot
boot block is 380 bytes (max 510)
+ mk obj/kern/kernel.img
```
(If you get errors like "undefined reference to `__udivdi3'", you probably don't have the 32-bit gcc multilib. If you're running Debian or Ubuntu, try installing the gcc-multilib package.)
Now you're ready to run QEMU, supplying the file `obj/kern/kernel.img`, created above, as the contents of the emulated PC's "virtual hard disk." This hard disk image contains both our boot loader (`obj/boot/boot`) and our kernel (`obj/kernel`).
```
athena% make qemu
```
or
```
athena% make qemu-nox
```
This executes QEMU with the options required to set the hard disk and direct serial port output to the terminal. Some text should appear in the QEMU window:
```
Booting from Hard Disk...
6828 decimal is XXX octal!
entering test_backtrace 5
entering test_backtrace 4
entering test_backtrace 3
entering test_backtrace 2
entering test_backtrace 1
entering test_backtrace 0
leaving test_backtrace 0
leaving test_backtrace 1
leaving test_backtrace 2
leaving test_backtrace 3
leaving test_backtrace 4
leaving test_backtrace 5
Welcome to the JOS kernel monitor!
Type 'help' for a list of commands.
K>
```
Everything after '`Booting from Hard Disk...`' was printed by our skeletal JOS kernel; the `K>` is the prompt printed by the small _monitor_ , or interactive control program, that we've included in the kernel. If you used make qemu, these lines printed by the kernel will appear in both the regular shell window from which you ran QEMU and the QEMU display window. This is because for testing and lab grading purposes we have set up the JOS kernel to write its console output not only to the virtual VGA display (as seen in the QEMU window), but also to the simulated PC's virtual serial port, which QEMU in turn outputs to its own standard output. Likewise, the JOS kernel will take input from both the keyboard and the serial port, so you can give it commands in either the VGA display window or the terminal running QEMU. Alternatively, you can use the serial console without the virtual VGA by running make qemu-nox. This may be convenient if you are SSH'd into an Athena dialup. To quit qemu, type Ctrl+a x.
There are only two commands you can give to the kernel monitor, `help` and `kerninfo`.
```
K> help
help - display this list of commands
kerninfo - display information about the kernel
K> kerninfo
Special kernel symbols:
entry f010000c (virt) 0010000c (phys)
etext f0101a75 (virt) 00101a75 (phys)
edata f0112300 (virt) 00112300 (phys)
end f0112960 (virt) 00112960 (phys)
Kernel executable memory footprint: 75KB
K>
```
The `help` command is obvious, and we will shortly discuss the meaning of what the `kerninfo` command prints. Although simple, it's important to note that this kernel monitor is running "directly" on the "raw (virtual) hardware" of the simulated PC. This means that you should be able to copy the contents of `obj/kern/kernel.img` onto the first few sectors of a _real_ hard disk, insert that hard disk into a real PC, turn it on, and see exactly the same thing on the PC's real screen as you did above in the QEMU window. (We don't recommend you do this on a real machine with useful information on its hard disk, though, because copying `kernel.img` onto the beginning of its hard disk will trash the master boot record and the beginning of the first partition, effectively causing everything previously on the hard disk to be lost!)
##### The PC's Physical Address Space
We will now dive into a bit more detail about how a PC starts up. A PC's physical address space is hard-wired to have the following general layout:
```
+------------------+ <- 0xFFFFFFFF (4GB)
| 32-bit |
| memory mapped |
| devices |
| |
/\/\/\/\/\/\/\/\/\/\
/\/\/\/\/\/\/\/\/\/\
| |
| Unused |
| |
+------------------+ <- depends on amount of RAM
| |
| |
| Extended Memory |
| |
| |
+------------------+ <- 0x00100000 (1MB)
| BIOS ROM |
+------------------+ <- 0x000F0000 (960KB)
| 16-bit devices, |
| expansion ROMs |
+------------------+ <- 0x000C0000 (768KB)
| VGA Display |
+------------------+ <- 0x000A0000 (640KB)
| |
| Low Memory |
| |
+------------------+ <- 0x00000000
```
The first PCs, which were based on the 16-bit Intel 8088 processor, were only capable of addressing 1MB of physical memory. The physical address space of an early PC would therefore start at 0x00000000 but end at 0x000FFFFF instead of 0xFFFFFFFF. The 640KB area marked "Low Memory" was the _only_ random-access memory (RAM) that an early PC could use; in fact the very earliest PCs only could be configured with 16KB, 32KB, or 64KB of RAM!
The 384KB area from 0x000A0000 through 0x000FFFFF was reserved by the hardware for special uses such as video display buffers and firmware held in non-volatile memory. The most important part of this reserved area is the Basic Input/Output System (BIOS), which occupies the 64KB region from 0x000F0000 through 0x000FFFFF. In early PCs the BIOS was held in true read-only memory (ROM), but current PCs store the BIOS in updateable flash memory. The BIOS is responsible for performing basic system initialization such as activating the video card and checking the amount of memory installed. After performing this initialization, the BIOS loads the operating system from some appropriate location such as floppy disk, hard disk, CD-ROM, or the network, and passes control of the machine to the operating system.
When Intel finally "broke the one megabyte barrier" with the 80286 and 80386 processors, which supported 16MB and 4GB physical address spaces respectively, the PC architects nevertheless preserved the original layout for the low 1MB of physical address space in order to ensure backward compatibility with existing software. Modern PCs therefore have a "hole" in physical memory from 0x000A0000 to 0x00100000, dividing RAM into "low" or "conventional memory" (the first 640KB) and "extended memory" (everything else). In addition, some space at the very top of the PC's 32-bit physical address space, above all physical RAM, is now commonly reserved by the BIOS for use by 32-bit PCI devices.
Recent x86 processors can support _more_ than 4GB of physical RAM, so RAM can extend further above 0xFFFFFFFF. In this case the BIOS must arrange to leave a _second_ hole in the system's RAM at the top of the 32-bit addressable region, to leave room for these 32-bit devices to be mapped. Because of design limitations JOS will use only the first 256MB of a PC's physical memory anyway, so for now we will pretend that all PCs have "only" a 32-bit physical address space. But dealing with complicated physical address spaces and other aspects of hardware organization that evolved over many years is one of the important practical challenges of OS development.
##### The ROM BIOS
In this portion of the lab, you'll use QEMU's debugging facilities to investigate how an IA-32 compatible computer boots.
Open two terminal windows and cd both shells into your lab directory. In one, enter make qemu-gdb (or make qemu-nox-gdb). This starts up QEMU, but QEMU stops just before the processor executes the first instruction and waits for a debugging connection from GDB. In the second terminal, from the same directory you ran `make`, run make gdb. You should see something like this,
```
athena% make gdb
GNU gdb (GDB) 6.8-debian
Copyright (C) 2008 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "i486-linux-gnu".
+ target remote localhost:26000
The target architecture is assumed to be i8086
[f000:fff0] 0xffff0: ljmp $0xf000,$0xe05b
0x0000fff0 in ?? ()
+ symbol-file obj/kern/kernel
(gdb)
```
We provided a `.gdbinit` file that set up GDB to debug the 16-bit code used during early boot and directed it to attach to the listening QEMU. (If it doesn't work, you may have to add an `add-auto-load-safe-path` in your `.gdbinit` in your home directory to convince `gdb` to process the `.gdbinit` we provided. `gdb` will tell you if you have to do this.)
The following line:
```
[f000:fff0] 0xffff0: ljmp $0xf000,$0xe05b
```
is GDB's disassembly of the first instruction to be executed. From this output you can conclude a few things:
* The IBM PC starts executing at physical address 0x000ffff0, which is at the very top of the 64KB area reserved for the ROM BIOS.
* The PC starts executing with `CS = 0xf000` and `IP = 0xfff0`.
* The first instruction to be executed is a `jmp` instruction, which jumps to the segmented address `CS = 0xf000` and `IP = 0xe05b`.
Why does QEMU start like this? This is how Intel designed the 8088 processor, which IBM used in their original PC. Because the BIOS in a PC is "hard-wired" to the physical address range 0x000f0000-0x000fffff, this design ensures that the BIOS always gets control of the machine first after power-up or any system restart - which is crucial because on power-up there _is_ no other software anywhere in the machine's RAM that the processor could execute. The QEMU emulator comes with its own BIOS, which it places at this location in the processor's simulated physical address space. On processor reset, the (simulated) processor enters real mode and sets CS to 0xf000 and the IP to 0xfff0, so that execution begins at that (CS:IP) segment address. How does the segmented address 0xf000:fff0 turn into a physical address?
To answer that we need to know a bit about real mode addressing. In real mode (the mode that PC starts off in), address translation works according to the formula: _physical address_ = 16 选题模板.txt 中文排版指北.md comic core.md Dict.md lctt2014.md lctt2016.md lctt2018.md LCTT翻译规范.md LICENSE Makefile published README.md sign.md sources translated _segment_ \+ _offset_. So, when the PC sets CS to 0xf000 and IP to 0xfff0, the physical address referenced is:
```
16 * 0xf000 + 0xfff0 # in hex multiplication by 16 is
= 0xf0000 + 0xfff0 # easy--just append a 0.
= 0xffff0
```
`0xffff0` is 16 bytes before the end of the BIOS (`0x100000`). Therefore we shouldn't be surprised that the first thing that the BIOS does is `jmp` backwards to an earlier location in the BIOS; after all how much could it accomplish in just 16 bytes?
Exercise 2. Use GDB's si (Step Instruction) command to trace into the ROM BIOS for a few more instructions, and try to guess what it might be doing. You might want to look at [Phil Storrs I/O Ports Description][14], as well as other materials on the [6.828 reference materials page][8]. No need to figure out all the details - just the general idea of what the BIOS is doing first.
When the BIOS runs, it sets up an interrupt descriptor table and initializes various devices such as the VGA display. This is where the "`Starting SeaBIOS`" message you see in the QEMU window comes from.
After initializing the PCI bus and all the important devices the BIOS knows about, it searches for a bootable device such as a floppy, hard drive, or CD-ROM. Eventually, when it finds a bootable disk, the BIOS reads the _boot loader_ from the disk and transfers control to it.
#### Part 2: The Boot Loader
Floppy and hard disks for PCs are divided into 512 byte regions called _sectors_. A sector is the disk's minimum transfer granularity: each read or write operation must be one or more sectors in size and aligned on a sector boundary. If the disk is bootable, the first sector is called the _boot sector_ , since this is where the boot loader code resides. When the BIOS finds a bootable floppy or hard disk, it loads the 512-byte boot sector into memory at physical addresses 0x7c00 through 0x7dff, and then uses a `jmp` instruction to set the CS:IP to `0000:7c00`, passing control to the boot loader. Like the BIOS load address, these addresses are fairly arbitrary - but they are fixed and standardized for PCs.
The ability to boot from a CD-ROM came much later during the evolution of the PC, and as a result the PC architects took the opportunity to rethink the boot process slightly. As a result, the way a modern BIOS boots from a CD-ROM is a bit more complicated (and more powerful). CD-ROMs use a sector size of 2048 bytes instead of 512, and the BIOS can load a much larger boot image from the disk into memory (not just one sector) before transferring control to it. For more information, see the ["El Torito" Bootable CD-ROM Format Specification][15].
For 6.828, however, we will use the conventional hard drive boot mechanism, which means that our boot loader must fit into a measly 512 bytes. The boot loader consists of one assembly language source file, `boot/boot.S`, and one C source file, `boot/main.c` Look through these source files carefully and make sure you understand what's going on. The boot loader must perform two main functions:
1. First, the boot loader switches the processor from real mode to _32-bit protected mode_ , because it is only in this mode that software can access all the memory above 1MB in the processor's physical address space. Protected mode is described briefly in sections 1.2.7 and 1.2.8 of [PC Assembly Language][6], and in great detail in the Intel architecture manuals. At this point you only have to understand that translation of segmented addresses (segment:offset pairs) into physical addresses happens differently in protected mode, and that after the transition offsets are 32 bits instead of 16.
2. Second, the boot loader reads the kernel from the hard disk by directly accessing the IDE disk device registers via the x86's special I/O instructions. If you would like to understand better what the particular I/O instructions here mean, check out the "IDE hard drive controller" section on [the 6.828 reference page][8]. You will not need to learn much about programming specific devices in this class: writing device drivers is in practice a very important part of OS development, but from a conceptual or architectural viewpoint it is also one of the least interesting.
After you understand the boot loader source code, look at the file `obj/boot/boot.asm`. This file is a disassembly of the boot loader that our GNUmakefile creates _after_ compiling the boot loader. This disassembly file makes it easy to see exactly where in physical memory all of the boot loader's code resides, and makes it easier to track what's happening while stepping through the boot loader in GDB. Likewise, `obj/kern/kernel.asm` contains a disassembly of the JOS kernel, which can often be useful for debugging.
You can set address breakpoints in GDB with the `b` command. For example, b *0x7c00 sets a breakpoint at address 0x7C00. Once at a breakpoint, you can continue execution using the c and si commands: c causes QEMU to continue execution until the next breakpoint (or until you press Ctrl-C in GDB), and si _N_ steps through the instructions _`N`_ at a time.
To examine instructions in memory (besides the immediate next one to be executed, which GDB prints automatically), you use the x/i command. This command has the syntax x/ _N_ i _ADDR_ , where _N_ is the number of consecutive instructions to disassemble and _ADDR_ is the memory address at which to start disassembling.
Exercise 3. Take a look at the [lab tools guide][16], especially the section on GDB commands. Even if you're familiar with GDB, this includes some esoteric GDB commands that are useful for OS work.
Set a breakpoint at address 0x7c00, which is where the boot sector will be loaded. Continue execution until that breakpoint. Trace through the code in `boot/boot.S`, using the source code and the disassembly file `obj/boot/boot.asm` to keep track of where you are. Also use the `x/i` command in GDB to disassemble sequences of instructions in the boot loader, and compare the original boot loader source code with both the disassembly in `obj/boot/boot.asm` and GDB.
Trace into `bootmain()` in `boot/main.c`, and then into `readsect()`. Identify the exact assembly instructions that correspond to each of the statements in `readsect()`. Trace through the rest of `readsect()` and back out into `bootmain()`, and identify the begin and end of the `for` loop that reads the remaining sectors of the kernel from the disk. Find out what code will run when the loop is finished, set a breakpoint there, and continue to that breakpoint. Then step through the remainder of the boot loader.
Be able to answer the following questions:
* At what point does the processor start executing 32-bit code? What exactly causes the switch from 16- to 32-bit mode?
* What is the _last_ instruction of the boot loader executed, and what is the _first_ instruction of the kernel it just loaded?
* _Where_ is the first instruction of the kernel?
* How does the boot loader decide how many sectors it must read in order to fetch the entire kernel from disk? Where does it find this information?
##### Loading the Kernel
We will now look in further detail at the C language portion of the boot loader, in `boot/main.c`. But before doing so, this is a good time to stop and review some of the basics of C programming.
Exercise 4. Read about programming with pointers in C. The best reference for the C language is _The C Programming Language_ by Brian Kernighan and Dennis Ritchie (known as 'K &R'). We recommend that students purchase this book (here is an [Amazon Link][17]) or find one of [MIT's 7 copies][18].
Read 5.1 (Pointers and Addresses) through 5.5 (Character Pointers and Functions) in K&R. Then download the code for [pointers.c][19], run it, and make sure you understand where all of the printed values come from. In particular, make sure you understand where the pointer addresses in printed lines 1 and 6 come from, how all the values in printed lines 2 through 4 get there, and why the values printed in line 5 are seemingly corrupted.
There are other references on pointers in C (e.g., [A tutorial by Ted Jensen][20] that cites K&R heavily), though not as strongly recommended.
_Warning:_ Unless you are already thoroughly versed in C, do not skip or even skim this reading exercise. If you do not really understand pointers in C, you will suffer untold pain and misery in subsequent labs, and then eventually come to understand them the hard way. Trust us; you don't want to find out what "the hard way" is.
To make sense out of `boot/main.c` you'll need to know what an ELF binary is. When you compile and link a C program such as the JOS kernel, the compiler transforms each C source ('`.c`') file into an _object_ ('`.o`') file containing assembly language instructions encoded in the binary format expected by the hardware. The linker then combines all of the compiled object files into a single _binary image_ such as `obj/kern/kernel`, which in this case is a binary in the ELF format, which stands for "Executable and Linkable Format".
Full information about this format is available in [the ELF specification][21] on [our reference page][8], but you will not need to delve very deeply into the details of this format in this class. Although as a whole the format is quite powerful and complex, most of the complex parts are for supporting dynamic loading of shared libraries, which we will not do in this class. The [Wikipedia page][22] has a short description.
For purposes of 6.828, you can consider an ELF executable to be a header with loading information, followed by several _program sections_ , each of which is a contiguous chunk of code or data intended to be loaded into memory at a specified address. The boot loader does not modify the code or data; it loads it into memory and starts executing it.
An ELF binary starts with a fixed-length _ELF header_ , followed by a variable-length _program header_ listing each of the program sections to be loaded. The C definitions for these ELF headers are in `inc/elf.h`. The program sections we're interested in are:
* `.text`: The program's executable instructions.
* `.rodata`: Read-only data, such as ASCII string constants produced by the C compiler. (We will not bother setting up the hardware to prohibit writing, however.)
* `.data`: The data section holds the program's initialized data, such as global variables declared with initializers like `int x = 5;`.
When the linker computes the memory layout of a program, it reserves space for _uninitialized_ global variables, such as `int x;`, in a section called `.bss` that immediately follows `.data` in memory. C requires that "uninitialized" global variables start with a value of zero. Thus there is no need to store contents for `.bss` in the ELF binary; instead, the linker records just the address and size of the `.bss` section. The loader or the program itself must arrange to zero the `.bss` section.
Examine the full list of the names, sizes, and link addresses of all the sections in the kernel executable by typing:
```
athena% objdump -h obj/kern/kernel
(If you compiled your own toolchain, you may need to use i386-jos-elf-objdump)
```
You will see many more sections than the ones we listed above, but the others are not important for our purposes. Most of the others are to hold debugging information, which is typically included in the program's executable file but not loaded into memory by the program loader.
Take particular note of the "VMA" (or _link address_ ) and the "LMA" (or _load address_ ) of the `.text` section. The load address of a section is the memory address at which that section should be loaded into memory.
The link address of a section is the memory address from which the section expects to execute. The linker encodes the link address in the binary in various ways, such as when the code needs the address of a global variable, with the result that a binary usually won't work if it is executing from an address that it is not linked for. (It is possible to generate _position-independent_ code that does not contain any such absolute addresses. This is used extensively by modern shared libraries, but it has performance and complexity costs, so we won't be using it in 6.828.)
Typically, the link and load addresses are the same. For example, look at the `.text` section of the boot loader:
```
athena% objdump -h obj/boot/boot.out
```
The boot loader uses the ELF _program headers_ to decide how to load the sections. The program headers specify which parts of the ELF object to load into memory and the destination address each should occupy. You can inspect the program headers by typing:
```
athena% objdump -x obj/kern/kernel
```
The program headers are then listed under "Program Headers" in the output of objdump. The areas of the ELF object that need to be loaded into memory are those that are marked as "LOAD". Other information for each program header is given, such as the virtual address ("vaddr"), the physical address ("paddr"), and the size of the loaded area ("memsz" and "filesz").
Back in boot/main.c, the `ph->p_pa` field of each program header contains the segment's destination physical address (in this case, it really is a physical address, though the ELF specification is vague on the actual meaning of this field).
The BIOS loads the boot sector into memory starting at address 0x7c00, so this is the boot sector's load address. This is also where the boot sector executes from, so this is also its link address. We set the link address by passing `-Ttext 0x7C00` to the linker in `boot/Makefrag`, so the linker will produce the correct memory addresses in the generated code.
Exercise 5. Trace through the first few instructions of the boot loader again and identify the first instruction that would "break" or otherwise do the wrong thing if you were to get the boot loader's link address wrong. Then change the link address in `boot/Makefrag` to something wrong, run make clean, recompile the lab with make, and trace into the boot loader again to see what happens. Don't forget to change the link address back and make clean again afterward!
Look back at the load and link addresses for the kernel. Unlike the boot loader, these two addresses aren't the same: the kernel is telling the boot loader to load it into memory at a low address (1 megabyte), but it expects to execute from a high address. We'll dig in to how we make this work in the next section.
Besides the section information, there is one more field in the ELF header that is important to us, named `e_entry`. This field holds the link address of the _entry point_ in the program: the memory address in the program's text section at which the program should begin executing. You can see the entry point:
```
athena% objdump -f obj/kern/kernel
```
You should now be able to understand the minimal ELF loader in `boot/main.c`. It reads each section of the kernel from disk into memory at the section's load address and then jumps to the kernel's entry point.
Exercise 6. We can examine memory using GDB's x command. The [GDB manual][23] has full details, but for now, it is enough to know that the command x/ _N_ x _ADDR_ prints _`N`_ words of memory at _`ADDR`_. (Note that both '`x`'s in the command are lowercase.) _Warning_ : The size of a word is not a universal standard. In GNU assembly, a word is two bytes (the 'w' in xorw, which stands for word, means 2 bytes).
Reset the machine (exit QEMU/GDB and start them again). Examine the 8 words of memory at 0x00100000 at the point the BIOS enters the boot loader, and then again at the point the boot loader enters the kernel. Why are they different? What is there at the second breakpoint? (You do not really need to use QEMU to answer this question. Just think.)
#### Part 3: The Kernel
We will now start to examine the minimal JOS kernel in a bit more detail. (And you will finally get to write some code!). Like the boot loader, the kernel begins with some assembly language code that sets things up so that C language code can execute properly.
##### Using virtual memory to work around position dependence
When you inspected the boot loader's link and load addresses above, they matched perfectly, but there was a (rather large) disparity between the _kernel's_ link address (as printed by objdump) and its load address. Go back and check both and make sure you can see what we're talking about. (Linking the kernel is more complicated than the boot loader, so the link and load addresses are at the top of `kern/kernel.ld`.)
Operating system kernels often like to be linked and run at very high _virtual address_ , such as 0xf0100000, in order to leave the lower part of the processor's virtual address space for user programs to use. The reason for this arrangement will become clearer in the next lab.
Many machines don't have any physical memory at address 0xf0100000, so we can't count on being able to store the kernel there. Instead, we will use the processor's memory management hardware to map virtual address 0xf0100000 (the link address at which the kernel code _expects_ to run) to physical address 0x00100000 (where the boot loader loaded the kernel into physical memory). This way, although the kernel's virtual address is high enough to leave plenty of address space for user processes, it will be loaded in physical memory at the 1MB point in the PC's RAM, just above the BIOS ROM. This approach requires that the PC have at least a few megabytes of physical memory (so that physical address 0x00100000 works), but this is likely to be true of any PC built after about 1990.
In fact, in the next lab, we will map the _entire_ bottom 256MB of the PC's physical address space, from physical addresses 0x00000000 through 0x0fffffff, to virtual addresses 0xf0000000 through 0xffffffff respectively. You should now see why JOS can only use the first 256MB of physical memory.
For now, we'll just map the first 4MB of physical memory, which will be enough to get us up and running. We do this using the hand-written, statically-initialized page directory and page table in `kern/entrypgdir.c`. For now, you don't have to understand the details of how this works, just the effect that it accomplishes. Up until `kern/entry.S` sets the `CR0_PG` flag, memory references are treated as physical addresses (strictly speaking, they're linear addresses, but boot/boot.S set up an identity mapping from linear addresses to physical addresses and we're never going to change that). Once `CR0_PG` is set, memory references are virtual addresses that get translated by the virtual memory hardware to physical addresses. `entry_pgdir` translates virtual addresses in the range 0xf0000000 through 0xf0400000 to physical addresses 0x00000000 through 0x00400000, as well as virtual addresses 0x00000000 through 0x00400000 to physical addresses 0x00000000 through 0x00400000. Any virtual address that is not in one of these two ranges will cause a hardware exception which, since we haven't set up interrupt handling yet, will cause QEMU to dump the machine state and exit (or endlessly reboot if you aren't using the 6.828-patched version of QEMU).
Exercise 7. Use QEMU and GDB to trace into the JOS kernel and stop at the `movl %eax, %cr0`. Examine memory at 0x00100000 and at 0xf0100000. Now, single step over that instruction using the stepi GDB command. Again, examine memory at 0x00100000 and at 0xf0100000. Make sure you understand what just happened.
What is the first instruction _after_ the new mapping is established that would fail to work properly if the mapping weren't in place? Comment out the `movl %eax, %cr0` in `kern/entry.S`, trace into it, and see if you were right.
##### Formatted Printing to the Console
Most people take functions like `printf()` for granted, sometimes even thinking of them as "primitives" of the C language. But in an OS kernel, we have to implement all I/O ourselves.
Read through `kern/printf.c`, `lib/printfmt.c`, and `kern/console.c`, and make sure you understand their relationship. It will become clear in later labs why `printfmt.c` is located in the separate `lib` directory.
Exercise 8. We have omitted a small fragment of code - the code necessary to print octal numbers using patterns of the form "%o". Find and fill in this code fragment.
Be able to answer the following questions:
1. Explain the interface between `printf.c` and `console.c`. Specifically, what function does `console.c` export? How is this function used by `printf.c`?
2. Explain the following from `console.c`:
```
1 if (crt_pos >= CRT_SIZE) {
2 int i;
3 memmove(crt_buf, crt_buf + CRT_COLS, (CRT_SIZE - CRT_COLS) 选题模板.txt 中文排版指北.md comic core.md Dict.md lctt2014.md lctt2016.md lctt2018.md LCTT翻译规范.md LICENSE Makefile published README.md sign.md sources translated sizeof(uint16_t));
4 for (i = CRT_SIZE - CRT_COLS; i < CRT_SIZE; i++)
5 crt_buf[i] = 0x0700 | ' ';
6 crt_pos -= CRT_COLS;
7 }
```
3. For the following questions you might wish to consult the notes for Lecture 2. These notes cover GCC's calling convention on the x86.
Trace the execution of the following code step-by-step:
```
int x = 1, y = 3, z = 4;
cprintf("x %d, y %x, z %d\n", x, y, z);
```
* In the call to `cprintf()`, to what does `fmt` point? To what does `ap` point?
* List (in order of execution) each call to `cons_putc`, `va_arg`, and `vcprintf`. For `cons_putc`, list its argument as well. For `va_arg`, list what `ap` points to before and after the call. For `vcprintf` list the values of its two arguments.
4. Run the following code.
```
unsigned int i = 0x00646c72;
cprintf("H%x Wo%s", 57616, &i);
```
What is the output? Explain how this output is arrived at in the step-by-step manner of the previous exercise. [Here's an ASCII table][24] that maps bytes to characters.
The output depends on that fact that the x86 is little-endian. If the x86 were instead big-endian what would you set `i` to in order to yield the same output? Would you need to change `57616` to a different value?
[Here's a description of little- and big-endian][25] and [a more whimsical description][26].
5. In the following code, what is going to be printed after `'y='`? (note: the answer is not a specific value.) Why does this happen?
```
cprintf("x=%d y=%d", 3);
```
6. Let's say that GCC changed its calling convention so that it pushed arguments on the stack in declaration order, so that the last argument is pushed last. How would you have to change `cprintf` or its interface so that it would still be possible to pass it a variable number of arguments?
Challenge Enhance the console to allow text to be printed in different colors. The traditional way to do this is to make it interpret [ANSI escape sequences][27] embedded in the text strings printed to the console, but you may use any mechanism you like. There is plenty of information on [the 6.828 reference page][8] and elsewhere on the web on programming the VGA display hardware. If you're feeling really adventurous, you could try switching the VGA hardware into a graphics mode and making the console draw text onto the graphical frame buffer.
##### The Stack
In the final exercise of this lab, we will explore in more detail the way the C language uses the stack on the x86, and in the process write a useful new kernel monitor function that prints a _backtrace_ of the stack: a list of the saved Instruction Pointer (IP) values from the nested `call` instructions that led to the current point of execution.
Exercise 9. Determine where the kernel initializes its stack, and exactly where in memory its stack is located. How does the kernel reserve space for its stack? And at which "end" of this reserved area is the stack pointer initialized to point to?
The x86 stack pointer (`esp` register) points to the lowest location on the stack that is currently in use. Everything _below_ that location in the region reserved for the stack is free. Pushing a value onto the stack involves decreasing the stack pointer and then writing the value to the place the stack pointer points to. Popping a value from the stack involves reading the value the stack pointer points to and then increasing the stack pointer. In 32-bit mode, the stack can only hold 32-bit values, and esp is always divisible by four. Various x86 instructions, such as `call`, are "hard-wired" to use the stack pointer register.
The `ebp` (base pointer) register, in contrast, is associated with the stack primarily by software convention. On entry to a C function, the function's _prologue_ code normally saves the previous function's base pointer by pushing it onto the stack, and then copies the current `esp` value into `ebp` for the duration of the function. If all the functions in a program obey this convention, then at any given point during the program's execution, it is possible to trace back through the stack by following the chain of saved `ebp` pointers and determining exactly what nested sequence of function calls caused this particular point in the program to be reached. This capability can be particularly useful, for example, when a particular function causes an `assert` failure or `panic` because bad arguments were passed to it, but you aren't sure _who_ passed the bad arguments. A stack backtrace lets you find the offending function.
Exercise 10. To become familiar with the C calling conventions on the x86, find the address of the `test_backtrace` function in `obj/kern/kernel.asm`, set a breakpoint there, and examine what happens each time it gets called after the kernel starts. How many 32-bit words does each recursive nesting level of `test_backtrace` push on the stack, and what are those words?
Note that, for this exercise to work properly, you should be using the patched version of QEMU available on the [tools][4] page or on Athena. Otherwise, you'll have to manually translate all breakpoint and memory addresses to linear addresses.
The above exercise should give you the information you need to implement a stack backtrace function, which you should call `mon_backtrace()`. A prototype for this function is already waiting for you in `kern/monitor.c`. You can do it entirely in C, but you may find the `read_ebp()` function in `inc/x86.h` useful. You'll also have to hook this new function into the kernel monitor's command list so that it can be invoked interactively by the user.
The backtrace function should display a listing of function call frames in the following format:
```
Stack backtrace:
ebp f0109e58 eip f0100a62 args 00000001 f0109e80 f0109e98 f0100ed2 00000031
ebp f0109ed8 eip f01000d6 args 00000000 00000000 f0100058 f0109f28 00000061
...
```
Each line contains an `ebp`, `eip`, and `args`. The `ebp` value indicates the base pointer into the stack used by that function: i.e., the position of the stack pointer just after the function was entered and the function prologue code set up the base pointer. The listed `eip` value is the function's _return instruction pointer_ : the instruction address to which control will return when the function returns. The return instruction pointer typically points to the instruction after the `call` instruction (why?). Finally, the five hex values listed after `args` are the first five arguments to the function in question, which would have been pushed on the stack just before the function was called. If the function was called with fewer than five arguments, of course, then not all five of these values will be useful. (Why can't the backtrace code detect how many arguments there actually are? How could this limitation be fixed?)
The first line printed reflects the _currently executing_ function, namely `mon_backtrace` itself, the second line reflects the function that called `mon_backtrace`, the third line reflects the function that called that one, and so on. You should print _all_ the outstanding stack frames. By studying `kern/entry.S` you'll find that there is an easy way to tell when to stop.
Here are a few specific points you read about in K&R Chapter 5 that are worth remembering for the following exercise and for future labs.
* If `int *p = (int*)100`, then `(int)p + 1` and `(int)(p + 1)` are different numbers: the first is `101` but the second is `104`. When adding an integer to a pointer, as in the second case, the integer is implicitly multiplied by the size of the object the pointer points to.
* `p[i]` is defined to be the same as `*(p+i)`, referring to the i'th object in the memory pointed to by p. The above rule for addition helps this definition work when the objects are larger than one byte.
* `&p[i]` is the same as `(p+i)`, yielding the address of the i'th object in the memory pointed to by p.
Although most C programs never need to cast between pointers and integers, operating systems frequently do. Whenever you see an addition involving a memory address, ask yourself whether it is an integer addition or pointer addition and make sure the value being added is appropriately multiplied or not.
Exercise 11. Implement the backtrace function as specified above. Use the same format as in the example, since otherwise the grading script will be confused. When you think you have it working right, run make grade to see if its output conforms to what our grading script expects, and fix it if it doesn't. _After_ you have handed in your Lab 1 code, you are welcome to change the output format of the backtrace function any way you like.
If you use `read_ebp()`, note that GCC may generate "optimized" code that calls `read_ebp()` _before_ `mon_backtrace()`'s function prologue, which results in an incomplete stack trace (the stack frame of the most recent function call is missing). While we have tried to disable optimizations that cause this reordering, you may want to examine the assembly of `mon_backtrace()` and make sure the call to `read_ebp()` is happening after the function prologue.
At this point, your backtrace function should give you the addresses of the function callers on the stack that lead to `mon_backtrace()` being executed. However, in practice you often want to know the function names corresponding to those addresses. For instance, you may want to know which functions could contain a bug that's causing your kernel to crash.
To help you implement this functionality, we have provided the function `debuginfo_eip()`, which looks up `eip` in the symbol table and returns the debugging information for that address. This function is defined in `kern/kdebug.c`.
Exercise 12. Modify your stack backtrace function to display, for each `eip`, the function name, source file name, and line number corresponding to that `eip`.
In `debuginfo_eip`, where do `__STAB_*` come from? This question has a long answer; to help you to discover the answer, here are some things you might want to do:
* look in the file `kern/kernel.ld` for `__STAB_*`
* run objdump -h obj/kern/kernel
* run objdump -G obj/kern/kernel
* run gcc -pipe -nostdinc -O2 -fno-builtin -I. -MD -Wall -Wno-format -DJOS_KERNEL -gstabs -c -S kern/init.c, and look at init.s.
* see if the bootloader loads the symbol table in memory as part of loading the kernel binary
Complete the implementation of `debuginfo_eip` by inserting the call to `stab_binsearch` to find the line number for an address.
Add a `backtrace` command to the kernel monitor, and extend your implementation of `mon_backtrace` to call `debuginfo_eip` and print a line for each stack frame of the form:
```
K> backtrace
Stack backtrace:
ebp f010ff78 eip f01008ae args 00000001 f010ff8c 00000000 f0110580 00000000
kern/monitor.c:143: monitor+106
ebp f010ffd8 eip f0100193 args 00000000 00001aac 00000660 00000000 00000000
kern/init.c:49: i386_init+59
ebp f010fff8 eip f010003d args 00000000 00000000 0000ffff 10cf9a00 0000ffff
kern/entry.S:70: <unknown>+0
K>
```
Each line gives the file name and line within that file of the stack frame's `eip`, followed by the name of the function and the offset of the `eip` from the first instruction of the function (e.g., `monitor+106` means the return `eip` is 106 bytes past the beginning of `monitor`).
Be sure to print the file and function names on a separate line, to avoid confusing the grading script.
Tip: printf format strings provide an easy, albeit obscure, way to print non-null-terminated strings like those in STABS tables. `printf("%.*s", length, string)` prints at most `length` characters of `string`. Take a look at the printf man page to find out why this works.
You may find that some functions are missing from the backtrace. For example, you will probably see a call to `monitor()` but not to `runcmd()`. This is because the compiler in-lines some function calls. Other optimizations may cause you to see unexpected line numbers. If you get rid of the `-O2` from `GNUMakefile`, the backtraces may make more sense (but your kernel will run more slowly).
**This completes the lab.** In the `lab` directory, commit your changes with git commit and type make handin to submit your code.
--------------------------------------------------------------------------------
via: https://pdos.csail.mit.edu/6.828/2018/labs/lab1/
作者:[csail.mit][a]
选题:[lujun9972][b]
译者:[译者ID](https://github.com/译者ID)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:
[b]: https://github.com/lujun9972
[1]: http://www.git-scm.com/
[2]: http://www.kernel.org/pub/software/scm/git/docs/user-manual.html
[3]: http://eagain.net/articles/git-for-computer-scientists/
[4]: https://pdos.csail.mit.edu/6.828/2018/tools.html
[5]: https://6828.scripts.mit.edu/2018/handin.py/
[6]: https://pdos.csail.mit.edu/6.828/2018/readings/pcasm-book.pdf
[7]: http://www.delorie.com/djgpp/doc/brennan/brennan_att_inline_djgpp.html
[8]: https://pdos.csail.mit.edu/6.828/2018/reference.html
[9]: https://pdos.csail.mit.edu/6.828/2018/readings/i386/toc.htm
[10]: http://www.intel.com/content/www/us/en/processors/architectures-software-developer-manuals.html
[11]: http://developer.amd.com/resources/developer-guides-manuals/
[12]: http://www.qemu.org/
[13]: http://www.gnu.org/software/gdb/
[14]: http://web.archive.org/web/20040404164813/members.iweb.net.au/~pstorr/pcbook/book2/book2.htm
[15]: https://pdos.csail.mit.edu/6.828/2018/readings/boot-cdrom.pdf
[16]: https://pdos.csail.mit.edu/6.828/2018/labguide.html
[17]: http://www.amazon.com/C-Programming-Language-2nd/dp/0131103628/sr=8-1/qid=1157812738/ref=pd_bbs_1/104-1502762-1803102?ie=UTF8&s=books
[18]: http://library.mit.edu/F/AI9Y4SJ2L5ELEE2TAQUAAR44XV5RTTQHE47P9MKP5GQDLR9A8X-10422?func=item-global&doc_library=MIT01&doc_number=000355242&year=&volume=&sub_library=
[19]: https://pdos.csail.mit.edu/6.828/2018/labs/lab1/pointers.c
[20]: https://pdos.csail.mit.edu/6.828/2018/readings/pointers.pdf
[21]: https://pdos.csail.mit.edu/6.828/2018/readings/elf.pdf
[22]: http://en.wikipedia.org/wiki/Executable_and_Linkable_Format
[23]: https://sourceware.org/gdb/current/onlinedocs/gdb/Memory.html
[24]: http://web.cs.mun.ca/~michael/c/ascii-table.html
[25]: http://www.webopedia.com/TERM/b/big_endian.html
[26]: http://www.networksorcery.com/enp/ien/ien137.txt
[27]: http://rrbrandt.dee.ufcg.edu.br/en/docs/ansi/

View File

@@ -1,3 +1,5 @@
translating by ypingcn
Control your data with Syncthing: An open source synchronization tool
======
Decide how to store and share your personal information.

View File

@@ -1,90 +0,0 @@
translating---geekpi
How to Boot Ubuntu 18.04 / Debian 9 Server in Rescue (Single User mode) / Emergency Mode
======
Booting a Linux Server into a single user mode or **rescue mode** is one of the important troubleshooting that a Linux admin usually follow while recovering the server from critical conditions. In Ubuntu 18.04 and Debian 9, single user mode is known as a rescue mode.
Apart from the rescue mode, Linux servers can be booted in **emergency mode** , the main difference between them is that, emergency mode loads a minimal environment with read only root file system file system, also it does not enable any network or other services. But rescue mode try to mount all the local file systems & try to start some important services including network.
In this article we will discuss how we can boot our Ubuntu 18.04 LTS / Debian 9 Server in rescue mode and emergency mode.
#### Booting Ubuntu 18.04 LTS Server in Single User / Rescue Mode:
Reboot your server and go to boot loader (Grub) screen and Select “ **Ubuntu** “, bootloader screen would look like below,
![](https://www.linuxtechi.com/wp-content/uploads/2018/09/Bootloader-Screen-Ubuntu18-04-Server.jpg)
Press “ **e** ” and then go the end of line which starts with word “ **linux** ” and append “ **systemd.unit=rescue.target** “. Remove the word “ **$vt_handoff** ” if it exists.
![](https://www.linuxtechi.com/wp-content/uploads/2018/09/rescue-target-ubuntu18-04.jpg)
Now Press Ctrl-x or F10 to boot,
![](https://www.linuxtechi.com/wp-content/uploads/2018/09/rescue-mode-ubuntu18-04.jpg)
Now press enter and then you will get the shell where all file systems will be mounted in read-write mode and do the troubleshooting. Once you are done with troubleshooting, you can reboot your server using “ **reboot** ” command.
#### Booting Ubuntu 18.04 LTS Server in emergency mode
Reboot the server and go the boot loader screen and select “ **Ubuntu** ” and then press “ **e** ” and go to the end of line which starts with word linux, and append “ **systemd.unit=emergency.target**
![](https://www.linuxtechi.com/wp-content/uploads/2018/09/Emergecny-target-ubuntu18-04-server.jpg)
Now Press Ctlr-x or F10 to boot in emergency mode, you will get a shell and do the troubleshooting from there. As we had already discussed that in emergency mode, file systems will be mounted in read-only mode and also there will be no networking in this mode,
![](https://www.linuxtechi.com/wp-content/uploads/2018/09/Emergency-prompt-debian9.jpg)
Use below command to mount the root file system in read-write mode,
```
# mount -o remount,rw /
```
Similarly, you can remount rest of file systems in read-write mode .
#### Booting Debian 9 into Rescue & Emergency Mode
Reboot your Debian 9.x server and go to grub screen and select “ **Debian GNU/Linux**
![](https://www.linuxtechi.com/wp-content/uploads/2018/09/Debian9-Grub-Screen.jpg)
Press “ **e** ” and go to end of line which starts with word linux and append “ **systemd.unit=rescue.target** ” to boot the system in rescue mode and to boot in emergency mode then append “ **systemd.unit=emergency.target**
#### Rescue mode :
![](https://www.linuxtechi.com/wp-content/uploads/2018/09/Rescue-mode-Debian9.jpg)
Now press Ctrl-x or F10 to boot in rescue mode
![](https://www.linuxtechi.com/wp-content/uploads/2018/09/Rescue-Mode-Shell-Debian9.jpg)
Press Enter to get the shell and from there you can start troubleshooting.
#### Emergency Mode:
![](https://www.linuxtechi.com/wp-content/uploads/2018/09/Emergency-target-grub-debian9.jpg)
Now press ctrl-x or F10 to boot your system in emergency mode
![](https://www.linuxtechi.com/wp-content/uploads/2018/09/Emergency-prompt-debian9.jpg)
Press enter to get the shell and use “ **mount -o remount,rw /** ” command to mount the root file system in read-write mode.
**Note:** In case root password is already set in Ubuntu 18.04 and Debian 9 Server then you must enter root password to get shell in rescue and emergency mode
Thats all from this article, please do share your feedback and comments in case you like this article.
--------------------------------------------------------------------------------
via: https://www.linuxtechi.com/boot-ubuntu-18-04-debian-9-rescue-emergency-mode/
作者:[Pradeep Kumar][a]
选题:[lujun9972](https://github.com/lujun9972)
译者:[译者ID](https://github.com/译者ID)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: http://www.linuxtechi.com/author/pradeep/

View File

@@ -1,162 +0,0 @@
HankChow translating
How to Replace one Linux Distro With Another in Dual Boot [Guide]
======
**If you have a Linux distribution installed, you can replace it with another distribution in the dual boot. You can also keep your personal documents while switching the distribution.**
![How to Replace One Linux Distribution With Another From Dual Boot][1]
Suppose you managed to [successfully dual boot Ubuntu and Windows][2]. But after reading the [Linux Mint versus Ubuntu discussion][3], you realized that [Linux Mint][4] is more suited for your needs. What would you do now? How would you [remove Ubuntu][5] and [install Mint in dual boot][6]?
You might think that you need to uninstall [Ubuntu][7] from dual boot first and then repeat the dual booting steps with Linux Mint. Let me tell you something. You dont need to do all of that.
If you already have a Linux distribution installed in dual boot, you can easily replace it with another. You dont have to uninstall the existing Linux distribution. You simply delete its partition and install the new distribution on the disk space vacated by the previous distribution.
Another good news is that you may be able to keep your Home directory with all your documents and pictures while switching the Linux distributions.
Let me show you how to switch Linux distributions.
### Replace one Linux with another from dual boot
<https://youtu.be/ptF2RUehbKs>
Let me describe the scenario I am going to use here. I have Linux Mint 19 installed on my system in dual boot mode with Windows 10. I am going to replace it with elementary OS 5. Ill also keep my personal files (music, pictures, videos, documents from my home directory) while switching distributions.
Lets first take a look at the requirements:
* A system with Linux and Windows dual boot
* Live USB of Linux you want to install
* Backup of your important files in Windows and in Linux on an external disk (optional yet recommended)
#### Things to keep in mind for keeping your home directory while changing Linux distribution
If you want to keep your files from existing Linux install as it is, you must have a separate root and home directory. You might have noticed that in my [dual boot tutorials][8], I always go for Something Else option and then manually create root and home partitions instead of choosing Install alongside Windows option. This is where all the troubles in manually creating separate home partition pay off.
Keeping Home on a separate partition is helpful in situations when you want to replace your existing Linux install with another without losing your files.
Note: You must remember the exact username and password of your existing Linux install in order to use the same home directory as it is in the new distribution.
If you dont have a separate Home partition, you may create it later as well BUT I wont recommend that. That process is slightly complicated and I dont want you to mess up your system.
With that much background information, its time to see how to replace a Linux distribution with another.
#### Step 1: Create a live USB of the new Linux distribution
Alright! I already mentioned it in the requirements but I still included it in the main steps to avoid confusion.
You can create a live USB using a start up disk creator like [Etcher][9] in Windows or Linux. The process is simple so I am not going to list the steps here.
#### Step 2: Boot into live USB and proceed to installing Linux
Since you have already dual booted before, you probably know the drill. Plugin the live USB, restart your system and at the boot time, press F10 or F12 repeatedly to enter BIOS settings.
In here, choose to boot from the USB. And then youll see the option to try the live environment or installing it immediately.
You should start the installation procedure. When you reach the Installation type screen, choose the Something else option.
![Replacing one Linux with another from dual boot][10]
Select Something else here
#### Step 3: Prepare the partition
Youll see the partitioning screen now. Look closely and youll see your Linux installation with Ext4 file system type.
![Identifying Linux partition in dual boot][11]
Identify where your Linux is installed
In the above picture, the Ext4 partition labeled as Linux Mint 19 is the root partition. The second Ext4 partition of 82691 MB is the Home partition. I [havent used any swap space][12] here.
Now, if you have just one Ext4 partition, that means that your home directory is on the same partition as root. In this case, you wont be able to keep your Home directory. I suggest that you copy the important files to an external disk else youll lose them forever.
Its time to delete the root partition. Select the root partition and click the sign. This will create some free space.
![Delete root partition of your existing Linux install][13]
Delete root partition
When you have the free space, click on + sign.
![Create root partition for the new Linux][14]
Create a new root partition
Now you should create a new partition out of this free space. If you had just one root partition in your previous Linux install, you should create root and home partitions here. You can also create the swap partition if you want to.
If you had root and home partition separately, just create a root partition from the deleted root partition.
![Create root partition for the new Linux][15]
Creating root partition
You may ask why did I use delete and add instead of using the change option. Its because a few years ago, using change didnt work for me. So I prefer to do a and +. Is it superstition? Maybe.
One important thing to do here is to mark the newly created partition for format. f you dont change the size of the partition, it wont be formatted unless you explicitly ask it to format. And if the partition is not formatted, youll have issues.
![][16]
Its important to format the root partition
Now if you already had a separate Home partition on your existing Linux install, you should select it and click on change.
![Recreate home partition][17]
Retouch the already existing home partition (if any)
You just have to specify that you are mounting it as home partition.
![Specify the home mount point][18]
Specify the home mount point
If you had a swap partition, you can repeat the same steps as the home partition. This time specify that you want to use the space as swap.
At this stage, you should have a root partition (with format option selected) and a home partition (and a swap if you want to). Hit the install now button to start the installation.
![Verify partitions while replacing one Linux with another][19]
Verify the partitions
The next few screens would be familiar to you. What matters is the screen where you are asked to create user and password.
If you had a separate home partition previously and you want to use the same home directory, you MUST use the same username and password that you had before. Computer name doesnt matter.
![To keep the home partition intact, use the previous user and password][20]
To keep the home partition intact, use the previous user and password
Your struggle is almost over. You dont have to do anything else other than waiting for the installation to finish.
![Wait for installation to finish][21]
Wait for installation to finish
Once the installation is over, restart your system. Youll have a new Linux distribution or version.
In my case, I had the entire home directory of Linux Mint 19 as it is in the elementary OS. All the videos, pictures I had remained as it is. Isnt that nice?
--------------------------------------------------------------------------------
via: https://itsfoss.com/replace-linux-from-dual-boot/
作者:[Abhishek Prakash][a]
选题:[lujun9972](https://github.com/lujun9972)
译者:[译者ID](https://github.com/译者ID)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://itsfoss.com/author/abhishek/
[1]: https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2018/09/Replace-Linux-Distro-from-dual-boot.png
[2]: https://itsfoss.com/install-ubuntu-1404-dual-boot-mode-windows-8-81-uefi/
[3]: https://itsfoss.com/linux-mint-vs-ubuntu/
[4]: https://www.linuxmint.com/
[5]: https://itsfoss.com/uninstall-ubuntu-linux-windows-dual-boot/
[6]: https://itsfoss.com/guide-install-linux-mint-16-dual-boot-windows/
[7]: https://www.ubuntu.com/
[8]: https://itsfoss.com/guide-install-elementary-os-luna/
[9]: https://etcher.io/
[10]: https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2018/09/replace-linux-with-another-1.jpg
[11]: https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2018/09/replace-linux-with-another-2.jpg
[12]: https://itsfoss.com/swap-size/
[13]: https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2018/09/replace-linux-with-another-3.jpg
[14]: https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2018/09/replace-linux-with-another-4.jpg
[15]: https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2018/09/replace-linux-with-another-5.jpg
[16]: https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2018/09/replace-linux-with-another-6.jpg
[17]: https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2018/09/replace-linux-with-another-7.jpg
[18]: https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2018/09/replace-linux-with-another-8.jpg
[19]: https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2018/09/replace-linux-with-another-9.jpg
[20]: https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2018/09/replace-linux-with-another-10.jpg
[21]: https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2018/09/replace-linux-with-another-11.jpg

View File

@@ -1,3 +1,5 @@
translating---geekpi
5 cool tiling window managers
======

View File

@@ -0,0 +1,272 @@
Lab 2: Memory Management
======
### Lab 2: Memory Management
#### Introduction
In this lab, you will write the memory management code for your operating system. Memory management has two components.
The first component is a physical memory allocator for the kernel, so that the kernel can allocate memory and later free it. Your allocator will operate in units of 4096 bytes, called _pages_. Your task will be to maintain data structures that record which physical pages are free and which are allocated, and how many processes are sharing each allocated page. You will also write the routines to allocate and free pages of memory.
The second component of memory management is _virtual memory_ , which maps the virtual addresses used by kernel and user software to addresses in physical memory. The x86 hardware's memory management unit (MMU) performs the mapping when instructions use memory, consulting a set of page tables. You will modify JOS to set up the MMU's page tables according to a specification we provide.
##### Getting started
In this and future labs you will progressively build up your kernel. We will also provide you with some additional source. To fetch that source, use Git to commit changes you've made since handing in lab 1 (if any), fetch the latest version of the course repository, and then create a local branch called `lab2` based on our lab2 branch, `origin/lab2`:
```
athena% cd ~/6.828/lab
athena% add git
athena% git pull
Already up-to-date.
athena% git checkout -b lab2 origin/lab2
Branch lab2 set up to track remote branch refs/remotes/origin/lab2.
Switched to a new branch "lab2"
athena%
```
The git checkout -b command shown above actually does two things: it first creates a local branch `lab2` that is based on the `origin/lab2` branch provided by the course staff, and second, it changes the contents of your `lab` directory to reflect the files stored on the `lab2` branch. Git allows switching between existing branches using git checkout _branch-name_ , though you should commit any outstanding changes on one branch before switching to a different one.
You will now need to merge the changes you made in your `lab1` branch into the `lab2` branch, as follows:
```
athena% git merge lab1
Merge made by recursive.
kern/kdebug.c | 11 +++++++++--
kern/monitor.c | 19 +++++++++++++++++++
lib/printfmt.c | 7 +++----
3 files changed, 31 insertions(+), 6 deletions(-)
athena%
```
In some cases, Git may not be able to figure out how to merge your changes with the new lab assignment (e.g. if you modified some of the code that is changed in the second lab assignment). In that case, the git merge command will tell you which files are _conflicted_ , and you should first resolve the conflict (by editing the relevant files) and then commit the resulting files with git commit -a.
Lab 2 contains the following new source files, which you should browse through:
* `inc/memlayout.h`
* `kern/pmap.c`
* `kern/pmap.h`
* `kern/kclock.h`
* `kern/kclock.c`
`memlayout.h` describes the layout of the virtual address space that you must implement by modifying `pmap.c`. `memlayout.h` and `pmap.h` define the `PageInfo` structure that you'll use to keep track of which pages of physical memory are free. `kclock.c` and `kclock.h` manipulate the PC's battery-backed clock and CMOS RAM hardware, in which the BIOS records the amount of physical memory the PC contains, among other things. The code in `pmap.c` needs to read this device hardware in order to figure out how much physical memory there is, but that part of the code is done for you: you do not need to know the details of how the CMOS hardware works.
Pay particular attention to `memlayout.h` and `pmap.h`, since this lab requires you to use and understand many of the definitions they contain. You may want to review `inc/mmu.h`, too, as it also contains a number of definitions that will be useful for this lab.
Before beginning the lab, don't forget to add -f 6.828 to get the 6.828 version of QEMU.
##### Lab Requirements
In this lab and subsequent labs, do all of the regular exercises described in the lab and _at least one_ challenge problem. (Some challenge problems are more challenging than others, of course!) Additionally, write up brief answers to the questions posed in the lab and a short (e.g., one or two paragraph) description of what you did to solve your chosen challenge problem. If you implement more than one challenge problem, you only need to describe one of them in the write-up, though of course you are welcome to do more. Place the write-up in a file called `answers-lab2.txt` in the top level of your `lab` directory before handing in your work.
##### Hand-In Procedure
When you are ready to hand in your lab code and write-up, add your `answers-lab2.txt` to the Git repository, commit your changes, and then run make handin.
```
athena% git add answers-lab2.txt
athena% git commit -am "my answer to lab2"
[lab2 a823de9] my answer to lab2
4 files changed, 87 insertions(+), 10 deletions(-)
athena% make handin
```
As before, we will be grading your solutions with a grading program. You can run make grade in the `lab` directory to test your kernel with the grading program. You may change any of the kernel source and header files you need to in order to complete the lab, but needless to say you must not change or otherwise subvert the grading code.
#### Part 1: Physical Page Management
The operating system must keep track of which parts of physical RAM are free and which are currently in use. JOS manages the PC's physical memory with _page granularity_ so that it can use the MMU to map and protect each piece of allocated memory.
You'll now write the physical page allocator. It keeps track of which pages are free with a linked list of `struct PageInfo` objects (which, unlike xv6, are not embedded in the free pages themselves), each corresponding to a physical page. You need to write the physical page allocator before you can write the rest of the virtual memory implementation, because your page table management code will need to allocate physical memory in which to store page tables.
Exercise 1. In the file `kern/pmap.c`, you must implement code for the following functions (probably in the order given).
`boot_alloc()`
`mem_init()` (only up to the call to `check_page_free_list(1)`)
`page_init()`
`page_alloc()`
`page_free()`
`check_page_free_list()` and `check_page_alloc()` test your physical page allocator. You should boot JOS and see whether `check_page_alloc()` reports success. Fix your code so that it passes. You may find it helpful to add your own `assert()`s to verify that your assumptions are correct.
This lab, and all the 6.828 labs, will require you to do a bit of detective work to figure out exactly what you need to do. This assignment does not describe all the details of the code you'll have to add to JOS. Look for comments in the parts of the JOS source that you have to modify; those comments often contain specifications and hints. You will also need to look at related parts of JOS, at the Intel manuals, and perhaps at your 6.004 or 6.033 notes.
#### Part 2: Virtual Memory
Before doing anything else, familiarize yourself with the x86's protected-mode memory management architecture: namely _segmentation_ and _page translation_.
Exercise 2. Look at chapters 5 and 6 of the [Intel 80386 Reference Manual][1], if you haven't done so already. Read the sections about page translation and page-based protection closely (5.2 and 6.4). We recommend that you also skim the sections about segmentation; while JOS uses the paging hardware for virtual memory and protection, segment translation and segment-based protection cannot be disabled on the x86, so you will need a basic understanding of it.
##### Virtual, Linear, and Physical Addresses
In x86 terminology, a _virtual address_ consists of a segment selector and an offset within the segment. A _linear address_ is what you get after segment translation but before page translation. A _physical address_ is what you finally get after both segment and page translation and what ultimately goes out on the hardware bus to your RAM.
```
Selector +--------------+ +-----------+
---------->| | | |
| Segmentation | | Paging |
Software | |-------->| |----------> RAM
Offset | Mechanism | | Mechanism |
---------->| | | |
+--------------+ +-----------+
Virtual Linear Physical
```
A C pointer is the "offset" component of the virtual address. In `boot/boot.S`, we installed a Global Descriptor Table (GDT) that effectively disabled segment translation by setting all segment base addresses to 0 and limits to `0xffffffff`. Hence the "selector" has no effect and the linear address always equals the offset of the virtual address. In lab 3, we'll have to interact a little more with segmentation to set up privilege levels, but as for memory translation, we can ignore segmentation throughout the JOS labs and focus solely on page translation.
Recall that in part 3 of lab 1, we installed a simple page table so that the kernel could run at its link address of 0xf0100000, even though it is actually loaded in physical memory just above the ROM BIOS at 0x00100000. This page table mapped only 4MB of memory. In the virtual address space layout you are going to set up for JOS in this lab, we'll expand this to map the first 256MB of physical memory starting at virtual address 0xf0000000 and to map a number of other regions of the virtual address space.
Exercise 3. While GDB can only access QEMU's memory by virtual address, it's often useful to be able to inspect physical memory while setting up virtual memory. Review the QEMU [monitor commands][2] from the lab tools guide, especially the `xp` command, which lets you inspect physical memory. To access the QEMU monitor, press Ctrl-a c in the terminal (the same binding returns to the serial console).
Use the xp command in the QEMU monitor and the x command in GDB to inspect memory at corresponding physical and virtual addresses and make sure you see the same data.
Our patched version of QEMU provides an info pg command that may also prove useful: it shows a compact but detailed representation of the current page tables, including all mapped memory ranges, permissions, and flags. Stock QEMU also provides an info mem command that shows an overview of which ranges of virtual addresses are mapped and with what permissions.
From code executing on the CPU, once we're in protected mode (which we entered first thing in `boot/boot.S`), there's no way to directly use a linear or physical address. _All_ memory references are interpreted as virtual addresses and translated by the MMU, which means all pointers in C are virtual addresses.
The JOS kernel often needs to manipulate addresses as opaque values or as integers, without dereferencing them, for example in the physical memory allocator. Sometimes these are virtual addresses, and sometimes they are physical addresses. To help document the code, the JOS source distinguishes the two cases: the type `uintptr_t` represents opaque virtual addresses, and `physaddr_t` represents physical addresses. Both these types are really just synonyms for 32-bit integers (`uint32_t`), so the compiler won't stop you from assigning one type to another! Since they are integer types (not pointers), the compiler _will_ complain if you try to dereference them.
The JOS kernel can dereference a `uintptr_t` by first casting it to a pointer type. In contrast, the kernel can't sensibly dereference a physical address, since the MMU translates all memory references. If you cast a `physaddr_t` to a pointer and dereference it, you may be able to load and store to the resulting address (the hardware will interpret it as a virtual address), but you probably won't get the memory location you intended.
To summarize:
C typeAddress type `T*` Virtual `uintptr_t` Virtual `physaddr_t` Physical
Question
1. Assuming that the following JOS kernel code is correct, what type should variable `x` have, `uintptr_t` or `physaddr_t`?
```
mystery_t x;
char* value = return_a_pointer();
*value = 10;
x = (mystery_t) value;
```
The JOS kernel sometimes needs to read or modify memory for which it knows only the physical address. For example, adding a mapping to a page table may require allocating physical memory to store a page directory and then initializing that memory. However, the kernel cannot bypass virtual address translation and thus cannot directly load and store to physical addresses. One reason JOS remaps all of physical memory starting from physical address 0 at virtual address 0xf0000000 is to help the kernel read and write memory for which it knows just the physical address. In order to translate a physical address into a virtual address that the kernel can actually read and write, the kernel must add 0xf0000000 to the physical address to find its corresponding virtual address in the remapped region. You should use `KADDR(pa)` to do that addition.
The JOS kernel also sometimes needs to be able to find a physical address given the virtual address of the memory in which a kernel data structure is stored. Kernel global variables and memory allocated by `boot_alloc()` are in the region where the kernel was loaded, starting at 0xf0000000, the very region where we mapped all of physical memory. Thus, to turn a virtual address in this region into a physical address, the kernel can simply subtract 0xf0000000. You should use `PADDR(va)` to do that subtraction.
##### Reference counting
In future labs you will often have the same physical page mapped at multiple virtual addresses simultaneously (or in the address spaces of multiple environments). You will keep a count of the number of references to each physical page in the `pp_ref` field of the `struct PageInfo` corresponding to the physical page. When this count goes to zero for a physical page, that page can be freed because it is no longer used. In general, this count should be equal to the number of times the physical page appears below `UTOP` in all page tables (the mappings above `UTOP` are mostly set up at boot time by the kernel and should never be freed, so there's no need to reference count them). We'll also use it to keep track of the number of pointers we keep to the page directory pages and, in turn, of the number of references the page directories have to page table pages.
Be careful when using `page_alloc`. The page it returns will always have a reference count of 0, so `pp_ref` should be incremented as soon as you've done something with the returned page (like inserting it into a page table). Sometimes this is handled by other functions (for example, `page_insert`) and sometimes the function calling `page_alloc` must do it directly.
##### Page Table Management
Now you'll write a set of routines to manage page tables: to insert and remove linear-to-physical mappings, and to create page table pages when needed.
Exercise 4. In the file `kern/pmap.c`, you must implement code for the following functions.
```
pgdir_walk()
boot_map_region()
page_lookup()
page_remove()
page_insert()
```
`check_page()`, called from `mem_init()`, tests your page table management routines. You should make sure it reports success before proceeding.
#### Part 3: Kernel Address Space
JOS divides the processor's 32-bit linear address space into two parts. User environments (processes), which we will begin loading and running in lab 3, will have control over the layout and contents of the lower part, while the kernel always maintains complete control over the upper part. The dividing line is defined somewhat arbitrarily by the symbol `ULIM` in `inc/memlayout.h`, reserving approximately 256MB of virtual address space for the kernel. This explains why we needed to give the kernel such a high link address in lab 1: otherwise there would not be enough room in the kernel's virtual address space to map in a user environment below it at the same time.
You'll find it helpful to refer to the JOS memory layout diagram in `inc/memlayout.h` both for this part and for later labs.
##### Permissions and Fault Isolation
Since kernel and user memory are both present in each environment's address space, we will have to use permission bits in our x86 page tables to allow user code access only to the user part of the address space. Otherwise bugs in user code might overwrite kernel data, causing a crash or more subtle malfunction; user code might also be able to steal other environments' private data. Note that the writable permission bit (`PTE_W`) affects both user and kernel code!
The user environment will have no permission to any of the memory above `ULIM`, while the kernel will be able to read and write this memory. For the address range `[UTOP,ULIM)`, both the kernel and the user environment have the same permission: they can read but not write this address range. This range of address is used to expose certain kernel data structures read-only to the user environment. Lastly, the address space below `UTOP` is for the user environment to use; the user environment will set permissions for accessing this memory.
##### Initializing the Kernel Address Space
Now you'll set up the address space above `UTOP`: the kernel part of the address space. `inc/memlayout.h` shows the layout you should use. You'll use the functions you just wrote to set up the appropriate linear to physical mappings.
Exercise 5. Fill in the missing code in `mem_init()` after the call to `check_page()`.
Your code should now pass the `check_kern_pgdir()` and `check_page_installed_pgdir()` checks.
Question
2. What entries (rows) in the page directory have been filled in at this point? What addresses do they map and where do they point? In other words, fill out this table as much as possible:
| Entry | Base Virtual Address | Points to (logically): |
|-------|----------------------|---------------------------------------|
| 1023 | ? | Page table for top 4MB of phys memory |
| 1022 | ? | ? |
| . | ? | ? |
| . | ? | ? |
| . | ? | ? |
| 2 | 0x00800000 | ? |
| 1 | 0x00400000 | ? |
| 0 | 0x00000000 | [see next question] |
3. We have placed the kernel and user environment in the same address space. Why will user programs not be able to read or write the kernel's memory? What specific mechanisms protect the kernel memory?
4. What is the maximum amount of physical memory that this operating system can support? Why?
5. How much space overhead is there for managing memory, if we actually had the maximum amount of physical memory? How is this overhead broken down?
6. Revisit the page table setup in `kern/entry.S` and `kern/entrypgdir.c`. Immediately after we turn on paging, EIP is still a low number (a little over 1MB). At what point do we transition to running at an EIP above KERNBASE? What makes it possible for us to continue executing at a low EIP between when we enable paging and when we begin running at an EIP above KERNBASE? Why is this transition necessary?
```
Challenge! We consumed many physical pages to hold the page tables for the KERNBASE mapping. Do a more space-efficient job using the PTE_PS ("Page Size") bit in the page directory entries. This bit was _not_ supported in the original 80386, but is supported on more recent x86 processors. You will therefore have to refer to [Volume 3 of the current Intel manuals][3]. Make sure you design the kernel to use this optimization only on processors that support it!
```
```
Challenge! Extend the JOS kernel monitor with commands to:
* Display in a useful and easy-to-read format all of the physical page mappings (or lack thereof) that apply to a particular range of virtual/linear addresses in the currently active address space. For example, you might enter `'showmappings 0x3000 0x5000'` to display the physical page mappings and corresponding permission bits that apply to the pages at virtual addresses 0x3000, 0x4000, and 0x5000.
* Explicitly set, clear, or change the permissions of any mapping in the current address space.
* Dump the contents of a range of memory given either a virtual or physical address range. Be sure the dump code behaves correctly when the range extends across page boundaries!
* Do anything else that you think might be useful later for debugging the kernel. (There's a good chance it will be!)
```
##### Address Space Layout Alternatives
The address space layout we use in JOS is not the only one possible. An operating system might map the kernel at low linear addresses while leaving the _upper_ part of the linear address space for user processes. x86 kernels generally do not take this approach, however, because one of the x86's backward-compatibility modes, known as _virtual 8086 mode_ , is "hard-wired" in the processor to use the bottom part of the linear address space, and thus cannot be used at all if the kernel is mapped there.
It is even possible, though much more difficult, to design the kernel so as not to have to reserve _any_ fixed portion of the processor's linear or virtual address space for itself, but instead effectively to allow user-level processes unrestricted use of the _entire_ 4GB of virtual address space - while still fully protecting the kernel from these processes and protecting different processes from each other!
```
Challenge! Each user-level environment maps the kernel. Change JOS so that the kernel has its own page table and so that a user-level environment runs with a minimal number of kernel pages mapped. That is, each user-level environment maps just enough pages mapped so that the user-level environment can enter and leave the kernel correctly. You also have to come up with a plan for the kernel to read/write arguments to system calls.
```
```
Challenge! Write up an outline of how a kernel could be designed to allow user environments unrestricted use of the full 4GB virtual and linear address space. Hint: do the previous challenge exercise first, which reduces the kernel to a few mappings in a user environment. Hint: the technique is sometimes known as " _follow the bouncing kernel_. " In your design, be sure to address exactly what has to happen when the processor transitions between kernel and user modes, and how the kernel would accomplish such transitions. Also describe how the kernel would access physical memory and I/O devices in this scheme, and how the kernel would access a user environment's virtual address space during system calls and the like. Finally, think about and describe the advantages and disadvantages of such a scheme in terms of flexibility, performance, kernel complexity, and other factors you can think of.
```
```
Challenge! Since our JOS kernel's memory management system only allocates and frees memory on page granularity, we do not have anything comparable to a general-purpose `malloc`/`free` facility that we can use within the kernel. This could be a problem if we want to support certain types of I/O devices that require _physically contiguous_ buffers larger than 4KB in size, or if we want user-level environments, and not just the kernel, to be able to allocate and map 4MB _superpages_ for maximum processor efficiency. (See the earlier challenge problem about PTE_PS.)
Generalize the kernel's memory allocation system to support pages of a variety of power-of-two allocation unit sizes from 4KB up to some reasonable maximum of your choice. Be sure you have some way to divide larger allocation units into smaller ones on demand, and to coalesce multiple small allocation units back into larger units when possible. Think about the issues that might arise in such a system.
```
**This completes the lab.** Make sure you pass all of the make grade tests and don't forget to write up your answers to the questions and a description of your challenge exercise solution in `answers-lab2.txt`. Commit your changes (including adding `answers-lab2.txt`) and type make handin in the `lab` directory to hand in your lab.
--------------------------------------------------------------------------------
via: https://pdos.csail.mit.edu/6.828/2018/labs/lab2/
作者:[csail.mit][a]
选题:[lujun9972][b]
译者:[译者ID](https://github.com/译者ID)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://pdos.csail.mit.edu
[b]: https://github.com/lujun9972
[1]: https://pdos.csail.mit.edu/6.828/2018/readings/i386/toc.htm
[2]: https://pdos.csail.mit.edu/6.828/2018/labguide.html#qemu
[3]: https://pdos.csail.mit.edu/6.828/2018/readings/ia32/IA32-3A.pdf

View File

@@ -1,3 +1,5 @@
[translating by jrg 20181014]
Using Grails with jQuery and DataTables
======

View File

@@ -1,100 +0,0 @@
认领by sd886393
What containers can teach us about DevOps
======
The use of containers supports the three pillars of DevOps practices: flow, feedback, and continual experimentation and learning.
![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/LAW-patent_reform_520x292_10136657_1012_dc.png?itok=Cd2PmDWf)
One can argue that containers and DevOps were made for one another. Certainly, the container ecosystem benefits from the skyrocketing popularity of DevOps practices, both in design choices and in DevOps use by teams developing container technologies. Because of this parallel evolution, the use of containers in production can teach teams the fundamentals of DevOps and its three pillars: [The Three Ways][1].
### Principles of flow
**Container flow**
A container can be seen as a silo, and from inside, it is easy to forget the rest of the system: the host node, the cluster, the underlying infrastructure. Inside the container, it might appear that everything is functioning in an acceptable manner. From the outside perspective, though, the application inside the container is a part of a larger ecosystem of applications that make up a service: the web API, the web app user interface, the database, the workers, and caching services and garbage collectors. Teams put constraints on the container to limit performance impact on infrastructure, and much has been done to provide metrics for measuring container performance because overloaded or slow container workloads have downstream impact on other services or customers.
**Real-world flow**
This lesson can be applied to teams functioning in a silo as well. Every process (be it code release, infrastructure creation or even, say, manufacturing of [Spacelys Sprockets][2]), follows a linear path from conception to realization. In technology, this progress flows from development to testing to operations and release. If a team working alone becomes a bottleneck or introduces a problem, the impact is felt all along the entire pipeline. A defect passed down the line destroys productivity downstream. While the broken process within the scope of the team itself may seem perfectly correct, it has a negative impact on the environment as a whole.
**DevOps and flow**
The first way of DevOps, principles of flow, is about approaching the process as a whole, striving to comprehend how the system works together and understanding the impact of issues on the entire process. To increase the efficiency of the process, pain points and waste are identified and removed. This is an ongoing process; teams must continually strive to increase visibility into the process and find and fix trouble spots and waste.
> “The outcomes of putting the First Way into practice include never passing a known defect to downstream work centers, never allowing local optimization to create global degradation, always seeking to increase flow, and always seeking to achieve a profound understanding of the system (as per Deming).”
Gene Kim, [The Three Ways: The Principles Underpinning DevOps][3], IT Revolution, 25 Apr. 2017
### Principles of feedback
**Container feedback**
In addition to limiting containers to prevent impact elsewhere, many products have been created to monitor and trend container metrics in an effort to understand what they are doing and notify when they are misbehaving. [Prometheus][4], for example, is [all the rage][5] for collecting metrics from containers and clusters. Containers are excellent at separating applications and providing a way to ship an environment together with the code, sometimes at the cost of opacity, so much is done to try to provide rapid feedback so issues can be addressed promptly within the silo.
**Real-world feedback**
The same is necessary for the flow of the system. From inception to realization, an efficient process quickly provides relevant feedback to identify when there is an issue. The key words here are “quick” and “relevant.” Burying teams in thousands of irrelevant notifications make it difficult or even impossible to notice important events that need immediate action, and receiving even relevant information too late may allow small, easily solved issues to move downstream and become bigger problems. Imagine [if Lucy and Ethel][6] had provided immediate feedback that the conveyor belt was too fast—there would have been no problem with the chocolate production (though that would not have been nearly as funny).
**DevOps and feedback**
The Second Way of DevOps, principles of feedback, is all about getting relevant information quickly. With immediate, useful feedback, problems can be identified as they happen and addressed before impact is felt elsewhere in the development process. DevOps teams strive to “optimize for downstream” and immediately move to fix problems that might impact other teams that come after them. As with flow, feedback is a continual process to identify ways to quickly get important data and act on problems as they occur.
> “Creating fast feedback is critical to achieving quality, reliability, and safety in the technology value stream.”
Gene Kim, et al., The DevOps Handbook: How to Create World-Class Agility, Reliability, and Security in Technology Organizations, IT Revolution Press, 2016
### Principles of continual experimentation and learning
**Container continual experimentation and learning**
It is a bit more challenging applying operational learning to the Third Way of DevOps:continual experimentation and learning. Trying to salvage what we can grasp of the very edges of the metaphor, containers make development easy, allowing developers and operations teams to test new code or configurations locally and safely outside of production and incorporate discovered benefits into production in a way that was difficult in the past. Changes can be radical and still version-controlled, documented, and shared quickly and easily.
**Real-world continual experimentation and learning**
For example, consider this anecdote from my own experience: Years ago, as a young, inexperienced sysadmin (just three weeks into the job), I was asked to make changes to an Apache virtual host running the website of the central IT department for a university. Without an easy-to-use test environment, I made a configuration change to the production site that I thought would accomplish the task and pushed it out. Within a few minutes, I overheard coworkers in the next cube:
“Wait, is the website down?”
“Hrm, yeah, it looks like it. What the heck?”
There was much eye-rolling involved.
Mortified (the shame is real, folks), I sunk down as far as I could into my seat and furiously tried to back out the changes Id introduced. Later that same afternoon, the director of the department—the boss of my bosss boss—appeared in my cube to talk about what had happened. “Dont worry,” she told me. “Were not mad at you. It was a mistake and now you have learned.”
In the world of containers, this could have been easily changed and tested on my own laptop and the broken configuration identified by more skilled team members long before it ever made it into production.
**DevOps continual experimentation and learning**
A real culture of experimentation promotes the individuals ability to find where a change in the process may be beneficial, and to test that assumption without the fear of retaliation if they fail. For DevOps teams, failure becomes an educational tool that adds to the knowledge of the individual and organization, rather than something to be feared or punished. Individuals in the DevOps team dedicate themselves to continuous learning, which in turn benefits the team and wider organization as that knowledge is shared.
As the metaphor completely falls apart, focus needs to be given to a specific point: The other two principles may appear at first glance to focus entirely on process, but continual learning is a human task—important for the future of the project, the person, the team, and the organization. It has an impact on the process, but it also has an impact on the individual and other people.
> “Experimentation and risk-taking are what enable us to relentlessly improve our system of work, which often requires us to do things very differently than how weve done it for decades.”
Gene Kim, et al., [The Phoenix Project: A Novel about IT, DevOps, and Helping Your Business Win][7], IT Revolution Press, 2013
### Containers can teach us DevOps
Learning to work effectively with containers can help teach DevOps and the Three Ways: principles of flow, principles of feedback, and principles of continuous experimentation and learning. Looking holistically at the application and infrastructure rather than putting on blinders to everything outside the container teaches us to take all parts of the system and understand their upstream and downstream impacts, break out of silos, and work as a team to increase global performance and deep understanding of the entire system. Working to provide timely and accurate feedback teaches us to create effective feedback patterns within our organizations to identify problems before their impact grows. Finally, providing a safe environment to try new ideas and learn from them teaches us to create a culture where failure represents a positive addition to our knowledge and the ability to take big chances with educated guesses can result in new, elegant solutions to complex problems.
--------------------------------------------------------------------------------
via: https://opensource.com/article/18/9/containers-can-teach-us-devops
作者:[Chris Hermansen][a]
选题:[lujun9972](https://github.com/lujun9972)
译者:[译者ID](https://github.com/译者ID)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://opensource.com/users/clhermansen
[1]: https://itrevolution.com/the-three-ways-principles-underpinning-devops/
[2]: https://en.wikipedia.org/wiki/The_Jetsons
[3]: http://itrevolution.com/the-three-ways-principles-underpinning-devops
[4]: https://prometheus.io/
[5]: https://opensource.com/article/18/9/prometheus-operational-advantage
[6]: https://www.youtube.com/watch?v=8NPzLBSBzPI
[7]: https://itrevolution.com/book/the-phoenix-project/

View File

@@ -1,3 +1,5 @@
[translating by jrg, 20181014]
16 iptables tips and tricks for sysadmins
======
Iptables provides powerful capabilities to control traffic coming in and out of your system.

View File

@@ -1,179 +0,0 @@
How to Install Pip on Ubuntu
======
**Pip is a command line tool that allows you to install software packages written in Python. Learn how to install Pip on Ubuntu and how to use it for installing Python applications.**
There are numerous ways to [install software on Ubuntu][1]. You can install applications from the software center, from downloaded DEB files, from PPA, from [Snap packages][2], [using Flatpak][3], using [AppImage][4] and even from the good old source code.
There is one more way to install packages in [Ubuntu][5]. Its called Pip and you can use it to install Python-based applications.
### What is Pip
[Pip][6] stands for “Pip Installs Packages”. [Pip][7] is a command line based package management system. It is used to install and manage software written in [Python language][8].
You can use Pip to install packages listed in the Python Package Index ([PyPI][9]).
As a software developer, you can use pip to install various Python module and packages for your own Python projects.
As an end user, you may need pip in order to install some applications that are developed using Python and can be installed easily using pip. One such example is [Stress Terminal][10] application that you can easily install with pip.
Lets see how you can install pip on Ubuntu and other Ubuntu-based distributions.
### How to install Pip on Ubuntu
![Install pip on Ubuntu Linux][11]
Pip is not installed on Ubuntu by default. Youll have to install it. Installing pip on Ubuntu is really easy. Ill show it to you in a moment.
Ubuntu 18.04 has both Python 2 and Python 3 installed by default. And hence, you should install pip for both Python versions.
Pip, by default, refers to the Python 2. Pip in Python 3 is referred by pip3.
Note: I am using Ubuntu 18.04 in this tutorial. But the instructions here should be valid for other versions like Ubuntu 16.04, 18.10 etc. You may also use the same commands on other Linux distributions based on Ubuntu such as Linux Mint, Linux Lite, Xubuntu, Kubuntu etc.
#### Install pip for Python 2
First, make sure that you have Python 2 installed. On Ubuntu, use the command below to verify.
```
python2 --version
```
If there is no error and a valid output that shows the Python version, you have Python 2 installed. So now you can install pip for Python 2 using this command:
```
sudo apt install python-pip
```
It will install pip and a number of other dependencies with it. Once installed, verify that you have pip installed correctly.
```
pip --version
```
It should show you a version number, something like this:
```
pip 9.0.1 from /usr/lib/python2.7/dist-packages (python 2.7)
```
This mans that you have successfully installed pip on Ubuntu.
#### Install pip for Python 3
You have to make sure that Python 3 is installed on Ubuntu. To check that, use this command:
```
python3 --version
```
If it shows you a number like Python 3.6.6, Python 3 is installed on your Linux system.
Now, you can install pip3 using the command below:
```
sudo apt install python3-pip
```
You should verify that pip3 has been installed correctly using this command:
```
pip3 --version
```
It should show you a number like this:
```
pip 9.0.1 from /usr/lib/python3/dist-packages (python 3.6)
```
It means that pip3 is successfully installed on your system.
### How to use Pip command
Now that you have installed pip, lets quickly see some of the basic pip commands. These commands will help you use pip commands for searching, installing and removing Python packages.
To search packages from the Python Package Index, you can use the following pip command:
```
pip search <search_string>
```
For example, if you search or stress, it will show all the packages that have the string stress in its name or description.
```
pip search stress
stress (1.0.0) - A trivial utility for consuming system resources.
s-tui (0.8.2) - Stress Terminal UI stress test and monitoring tool
stressypy (0.0.12) - A simple program for calling stress and/or stress-ng from python
fuzzing (0.3.2) - Tools for stress testing applications.
stressant (0.4.1) - Simple stress-test tool
stressberry (0.1.7) - Stress tests for the Raspberry Pi
mobbage (0.2) - A HTTP stress test and benchmark tool
stresser (0.2.1) - A large-scale stress testing framework.
cyanide (1.3.0) - Celery stress testing and integration test support.
pysle (1.5.7) - An interface to ISLEX, a pronunciation dictionary with stress markings.
ggf (0.3.2) - global geometric factors and corresponding stresses of the optical stretcher
pathod (0.17) - A pathological HTTP/S daemon for testing and stressing clients.
MatPy (1.0) - A toolbox for intelligent material design, and automatic yield stress determination
netblow (0.1.2) - Vendor agnostic network testing framework to stress network failures
russtress (0.1.3) - Package that helps you to put lexical stress in russian text
switchy (0.1.0a1) - A fast FreeSWITCH control library purpose-built on traffic theory and stress testing.
nx4_selenium_test (0.1) - Provides a Python class and apps which monitor and/or stress-test the NoMachine NX4 web interface
physical_dualism (1.0.0) - Python library that approximates the natural frequency from stress via physical dualism, and vice versa.
fsm_effective_stress (1.0.0) - Python library that uses the rheological-dynamical analogy (RDA) to compute damage and effective buckling stress in prismatic shell structures.
processpathway (0.3.11) - A nifty little toolkit to create stress-free, frustrationless image processing pathways from your webcam for computer vision experiments. Or observing your cat.
```
If you want to install an application using pip, you can use it in the following manner:
```
pip install <package_name>
```
Pip doesnt support tab completion so the package name should be exact. It will download all the necessary files and installed that package.
If you want to remove a Python package installed via pip, you can use the remove option in pip.
```
pip uninstall <installed_package_name>
```
You can use pip3 instead of pip in the above commands.
I hope this quick tip helped you to install pip on Ubuntu. If you have any questions or suggestions, please let me know in the comment section below.
--------------------------------------------------------------------------------
via: https://itsfoss.com/install-pip-ubuntu/
作者:[Abhishek Prakash][a]
选题:[lujun9972](https://github.com/lujun9972)
译者:[译者ID](https://github.com/译者ID)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://itsfoss.com/author/abhishek/
[1]: https://itsfoss.com/how-to-add-remove-programs-in-ubuntu/
[2]: https://itsfoss.com/use-snap-packages-ubuntu-16-04/
[3]: https://itsfoss.com/flatpak-guide/
[4]: https://itsfoss.com/use-appimage-linux/
[5]: https://www.ubuntu.com/
[6]: https://en.wikipedia.org/wiki/Pip_(package_manager)
[7]: https://pypi.org/project/pip/
[8]: https://www.python.org/
[9]: https://pypi.org/
[10]: https://itsfoss.com/stress-terminal-ui/
[11]: https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2018/10/install-pip-ubuntu.png

View File

@@ -1,78 +0,0 @@
translating by singledo
How to use the SSH and SFTP protocols on your home network
======
Use the SSH and SFTP protocols to access other devices, efficiently and securely transfer files, and more.
![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/openwires_fromRHT_520_0612LL.png?itok=PqZi55Ab)
Years ago, I decided to set up an extra computer (I always have extra computers) so that I could access it from work to transfer files I might need. To do this, the basic first step is to have your ISP assign a fixed IP address.
The not-so-basic but much more important next step is to set up your accessible system safely. In this particular case, I was planning to access it only from work, so I could restrict access to that IP address. Even so, you want to use all possible security features. What is amazing—and scary—is that as soon as you set this up, people from all over the world will immediately attempt to access your system. You can discover this by checking the logs. I presume there are bots constantly searching for open doors wherever they can find them.
Not long after I set up my computer, I decided my access was more a toy than a need, so I turned it off and gave myself one less thing to worry about. Nonetheless, there is another use for SSH and SFTP inside your home network, and it is more or less already set up for you.
One requirement, of course, is that the other computer in your home must be turned on, although it doesnt matter whether someone is logged on or not. You also need to know its IP address. There are two ways to find this out. One is to get access to the router, which you can do through a browser. Typically, its address is something like **192.168.1.254**. With some searching, it should be easy enough to find out what is currently on and hooked up to the system by eth0 or WiFi. What can be challenging is recognizing the computer youre interested in.
I find it easier to go to the computer in question, bring up a shell, and type:
```
ifconfig
```
This spits out a lot of information, but the bit you want is right after `inet` and might look something like **192.168.1.234**. After you find that, go back to the client computer you want to access this host, and on the command line, type:
```
ssh gregp@192.168.1.234
```
For this to work, **gregp** must be a valid user on that system. You will then be asked for his password, and if you enter it correctly, you will be connected to that other computer in a shell environment. I confess that I dont use SSH in this way very often. I have used it at times so I can run `dnf` to upgrade some other computer than the one Im sitting at. Usually, I use SFTP:
```
sftp gregp@192.168.1.234
```
because I have a greater need for an easy method of transferring files from one computer to another. Its certainly more convenient and less time-consuming than using a USB stick or an external drive.
`get`, to receive files from the host; and `put`, to send files to the host. I usually migrate to the directory on my client where I either want to save files I will get from the host or send to the host before I connect. When you connect, you will be in the top-level directory—in this example, **home/gregp**. Once connected, you can then use `cd` just as you would in your client, except now youre changing your working directory on the host. You may need to use `ls` to make sure you know where you are.
Once youre connected, the two basic commands for SFTP are, to receive files from the host; and, to send files to the host. I usually migrate to the directory on my client where I either want to save files I will get from the host or send to the host before I connect. When you connect, you will be in the top-level directory—in this example,. Once connected, you can then usejust as you would in your client, except now youre changing your working directory on the host. You may need to useto make sure you know where you are.
If you need to change the working directory on your client, use the command `lcd` (as in **local change directory** ). Similarly, use `lls` to show the working directory contents on your client system.
What if the host doesnt have a directory with the name you would like? Use `mkdir` to make a new directory on it. Or you might copy a whole directory of files to the host with this:
```
put -r ThisDir/
```
which creates the directory and then copies all of its files and subdirectories to the host. These transfers are extremely fast, as fast as your hardware allows, and have none of the bottlenecks you might encounter on the internet. To see a list of commands you can use in an SFTP session, check:
```
man sftp
```
I have also been able to put SFTP to use on a Windows VM on my computer, yet another advantage of setting up a VM rather than a dual-boot system. This lets me move files to or from the Linux part of the system. So far I have only done this using a client in Windows.
You can also use SSH and SFTP to access any devices connected to your router by wire or WiFi. For a while, I used an app called [SSHDroid][1], which runs SSH in a passive mode. In other words, you use your computer to access the Android device that is the host. Recently I found another app, [Admin Hands][2], where the tablet or phone is the client and can be used for either SSH or SFTP operations. This app is great for backing up or sharing photos from your phone.
--------------------------------------------------------------------------------
via: https://opensource.com/article/18/10/ssh-sftp-home-network
作者:[Geg Pittman][a]
选题:[lujun9972](https://github.com/lujun9972)
译者:[译者ID](https://github.com/译者ID)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://opensource.com/users/greg-p
[1]: https://play.google.com/store/apps/details?id=berserker.android.apps.sshdroid
[2]: https://play.google.com/store/apps/details?id=com.arpaplus.adminhands&hl=en_US

View File

@@ -1,72 +0,0 @@
translating---geekpi
Introducing Swift on Fedora
======
![](https://fedoramagazine.org/wp-content/uploads/2018/09/swift-816x345.jpg)
Swift is a general-purpose programming language built using a modern approach to safety, performance, and software design patterns. It aims to be the best language for a variety of programming projects, ranging from systems programming to desktop applications and scaling up to cloud services. Read more about it and how to try it out in Fedora.
### Safe, Fast, Expressive
Like many modern programming languages, Swift was designed to be safer than C-based languages. For example, variables are always initialized before they can be used. Arrays and integers are checked for overflow. Memory is automatically managed.
Swift puts intent right in the syntax. To declare a variable, use the var keyword. To declare a constant, use let.
Swift also guarantees that objects can never be nil; in fact, trying to use an object known to be nil will cause a compile-time error. When using a nil value is appropriate, it supports a mechanism called **optionals**. An optional may contain nil, but is safely unwrapped using the **?** operator.
Some additional features include:
* Closures unified with function pointers
* Tuples and multiple return values
* Generics
* Fast and concise iteration over a range or collection
* Structs that support methods, extensions, and protocols
* Functional programming patterns, e.g., map and filter
* Powerful error handling built-in
* Advanced control flow with do, guard, defer, and repeat keywords
### Try Swift out
Swift is available in Fedora 28 under then package name **swift-lang**. Once installed, run swift and the REPL console starts up.
```
$ swift
Welcome to Swift version 4.2 (swift-4.2-RELEASE). Type :help for assistance.
1> let greeting="Hello world!"
greeting: String = "Hello world!"
2> print(greeting)
Hello world!
3> greeting = "Hello universe!"
error: repl.swift:3:10: error: cannot assign to value: 'greeting' is a 'let' constant
greeting = "Hello universe!"
~~~~~~~~ ^
3>
```
Swift has a growing community, and in particular, a [work group][1] dedicated to making it an efficient and effective server-side programming language. Be sure to visit [its home page][2] for more ways to get involved.
Photo by [Uillian Vargas][3] on [Unsplash][4].
--------------------------------------------------------------------------------
via: https://fedoramagazine.org/introducing-swift-fedora/
作者:[Link Dupont][a]
选题:[lujun9972](https://github.com/lujun9972)
译者:[译者ID](https://github.com/译者ID)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://fedoramagazine.org/author/linkdupont/
[1]: https://swift.org/server/
[2]: http://swift.org
[3]: https://unsplash.com/photos/7oJpVR1inGk?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText
[4]: https://unsplash.com/search/photos/fast?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText

View File

@@ -0,0 +1,102 @@
4 Must-Have Tools for Monitoring Linux
======
![](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/monitoring-main.jpg?itok=YHLK-gn6)
Linux. Its powerful, flexible, stable, secure, user-friendly… the list goes on and on. There are so many reasons why people have adopted the open source operating system. One of those reasons which particularly stands out is its flexibility. Linux can be and do almost anything. In fact, it will (in most cases) go well above what most platforms can. Just ask any enterprise business why they use Linux and open source.
But once youve deployed those servers and desktops, you need to be able to keep track of them. Whats going on? How are they performing? Is something afoot? In other words, you need to be able to monitor your Linux machines. “How?” you ask. Thats a great question, and one with many answers. I want to introduce you to a few such tools—from command line, to GUI, to full-blown web interfaces (with plenty of bells and whistles). From this collection of tools, you can gather just about any kind of information you need. I will stick only with tools that are open source, which will exempt some high-quality, proprietary solutions. But its always best to start with open source, and, chances are, youll find everything you need to monitor your desktops and servers. So, lets take a look at four such tools.
### Top
Well first start with the obvious. The top command is a great place to start, when you need to monitor what processes are consuming resources. The top command has been around for a very long time and has, for years, been the first tool I turn to when something is amiss. What top does is provide a real-time view of all running systems on a Linux machine. The top command not only displays dynamic information about each running process (as well as the necessary information to manage those processes), but also gives you an overview of the machine (such as, how many CPUs are found, and how much RAM and swap space is available). When I feel something is going wrong with a machine, I immediately turn to top to see what processes are gobbling up the most CPU and MEM (Figure 1). From there, I can act accordingly.
![top][2]
Figure 1: Top running on Elementary OS.
[Used with permission][3]
There is no need to install anything to use the top command, because it is installed on almost every Linux distribution by default. For more information on top, issue the command man top.
### Glances
If you thought the top command offered up plenty of information, youve yet to experience Glances. Glances is another text-based monitoring tool. In similar fashion to top, glances offers a real-time listing of more information about your system than nearly any other monitor of its kind. Youll see disk/network I/O, thermal readouts, fan speeds, disk usage by hardware device and logical volume, processes, warnings, alerts, and much more. Glances also includes a handy sidebar that displays information about disk, filesystem, network, sensors, and even Docker stats. To enable the sidebar, hit the 2 key (while glances is running). Youll then see the added information (Figure 2).
![glances][5]
Figure 2: The glances monitor displaying docker stats along with all the other information it offers.
[Used with permission][3]
You wont find glances installed by default. However, the tool is available in most standard repositories, so it can be installed from the command line or your distributions app store, without having to add a third-party repository.
### GNOME System Monitor
If you're not a fan of the command line, there are plenty of tools to make your monitoring life a bit easier. One such tool is GNOME System Monitor, which is a front-end for the top tool. But if you prefer a GUI, you cant beat this app.
With GNOME System Monitor, you can scroll through the listing of running apps (Figure 3), select an app, and then either end the process (by clicking End Process) or view more details about said process (by clicking the gear icon).
![GNOME System Monitor][7]
Figure 3: GNOME System Monitor in action.
[Used with permission][3]
You can also click any one of the tabs at the top of the window to get even more information about your system. The Resources tab is a very handy way to get real-time data on CPU, Memory, Swap, and Network (Figure 4).
![GNOME System Monitor][9]
Figure 4: The GNOME System Monitor Resources tab in action.
[Used with permission][3]
If you dont find GNOME System Monitor installed by default, it can be found in the standard repositories, so its very simple to add to your system.
### Nagios
If youre looking for an enterprise-grade networking monitoring system, look no further than [Nagios][10]. But dont think Nagios is limited to only monitoring network traffic. This system has over 5,000 different add-ons that can be added to expand the system to perfectly meet (and exceed your needs). The Nagios monitor doesnt come pre-installed on your Linux distribution and although the install isnt quite as difficult as some similar tools, it does have some complications. And, because the Nagios version found in many of the default repositories is out of date, youll definitely want to install from source. Once installed, you can log into the Nagios web GUI and start monitoring (Figure 5).
![Nagios ][12]
Figure 5: With Nagios you can even start and stop services.
[Used with permission][3]
Of course, at this point, youve only installed the core and will also need to walk through the process of installing the plugins. Trust me when I say its worth the extra time.
The one caveat with Nagios is that you must manually install any remote hosts to be monitored (outside of the host the system is installed on) via text files. Fortunately, the installation will include sample configuration files (found in /usr/local/nagios/etc/objects) which you can use to create configuration files for remote servers (which are placed in /usr/local/nagios/etc/servers).
Although Nagios can be a challenge to install, it is very much worth the time, as you will wind up with an enterprise-ready monitoring system capable of handling nearly anything you throw at it.
### Theres More Where That Came From
Weve barely scratched the surface in terms of monitoring tools that are available for the Linux platform. No matter whether youre looking for a general system monitor or something very specific, a command line or GUI application, youll find what you need. These four tools offer an outstanding starting point for any Linux administrator. Give them a try and see if you dont find exactly the information you need.
Learn more about Linux through the free ["Introduction to Linux" ][13] course from The Linux Foundation and edX.
--------------------------------------------------------------------------------
via: https://www.linux.com/learn/intro-to-linux/2018/10/4-must-have-tools-monitoring-linux
作者:[Jack Wallen][a]
选题:[lujun9972][b]
译者:[译者ID](https://github.com/译者ID)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://www.linux.com/users/jlwallen
[b]: https://github.com/lujun9972
[1]: /files/images/monitoring1jpg
[2]: https://www.linux.com/sites/lcom/files/styles/rendered_file/public/monitoring_1.jpg?itok=UiyNGji0 (top)
[3]: /licenses/category/used-permission
[4]: /files/images/monitoring2jpg
[5]: https://www.linux.com/sites/lcom/files/styles/rendered_file/public/monitoring_2.jpg?itok=K3OxLcvE (glances)
[6]: /files/images/monitoring3jpg
[7]: https://www.linux.com/sites/lcom/files/styles/rendered_file/public/monitoring_3.jpg?itok=UKcyEDcT (GNOME System Monitor)
[8]: /files/images/monitoring4jpg
[9]: https://www.linux.com/sites/lcom/files/styles/rendered_file/public/monitoring_4.jpg?itok=orLRH3m0 (GNOME System Monitor)
[10]: https://www.nagios.org/
[11]: /files/images/monitoring5jpg
[12]: https://www.linux.com/sites/lcom/files/styles/rendered_file/public/monitoring_5.jpg?itok=RGcLLWL7 (Nagios )
[13]: https://training.linuxfoundation.org/linux-courses/system-administration-training/introduction-to-linux

View File

@@ -0,0 +1,524 @@
Lab 3: User Environments
======
### Lab 3: User Environments
#### Introduction
In this lab you will implement the basic kernel facilities required to get a protected user-mode environment (i.e., "process") running. You will enhance the JOS kernel to set up the data structures to keep track of user environments, create a single user environment, load a program image into it, and start it running. You will also make the JOS kernel capable of handling any system calls the user environment makes and handling any other exceptions it causes.
**Note:** In this lab, the terms _environment_ and _process_ are interchangeable - both refer to an abstraction that allows you to run a program. We introduce the term "environment" instead of the traditional term "process" in order to stress the point that JOS environments and UNIX processes provide different interfaces, and do not provide the same semantics.
##### Getting Started
Use Git to commit your changes after your Lab 2 submission (if any), fetch the latest version of the course repository, and then create a local branch called `lab3` based on our lab3 branch, `origin/lab3`:
```
athena% cd ~/6.828/lab
athena% add git
athena% git commit -am 'changes to lab2 after handin'
Created commit 734fab7: changes to lab2 after handin
4 files changed, 42 insertions(+), 9 deletions(-)
athena% git pull
Already up-to-date.
athena% git checkout -b lab3 origin/lab3
Branch lab3 set up to track remote branch refs/remotes/origin/lab3.
Switched to a new branch "lab3"
athena% git merge lab2
Merge made by recursive.
kern/pmap.c | 42 +++++++++++++++++++
1 files changed, 42 insertions(+), 0 deletions(-)
athena%
```
Lab 3 contains a number of new source files, which you should browse:
```
inc/ env.h Public definitions for user-mode environments
trap.h Public definitions for trap handling
syscall.h Public definitions for system calls from user environments to the kernel
lib.h Public definitions for the user-mode support library
kern/ env.h Kernel-private definitions for user-mode environments
env.c Kernel code implementing user-mode environments
trap.h Kernel-private trap handling definitions
trap.c Trap handling code
trapentry.S Assembly-language trap handler entry-points
syscall.h Kernel-private definitions for system call handling
syscall.c System call implementation code
lib/ Makefrag Makefile fragment to build user-mode library, obj/lib/libjos.a
entry.S Assembly-language entry-point for user environments
libmain.c User-mode library setup code called from entry.S
syscall.c User-mode system call stub functions
console.c User-mode implementations of putchar and getchar, providing console I/O
exit.c User-mode implementation of exit
panic.c User-mode implementation of panic
user/ * Various test programs to check kernel lab 3 code
```
In addition, a number of the source files we handed out for lab2 are modified in lab3. To see the differences, you can type:
```
$ git diff lab2
```
You may also want to take another look at the [lab tools guide][1], as it includes information on debugging user code that becomes relevant in this lab.
##### Lab Requirements
This lab is divided into two parts, A and B. Part A is due a week after this lab was assigned; you should commit your changes and make handin your lab before the Part A deadline, making sure your code passes all of the Part A tests (it is okay if your code does not pass the Part B tests yet). You only need to have the Part B tests passing by the Part B deadline at the end of the second week.
As in lab 2, you will need to do all of the regular exercises described in the lab and _at least one_ challenge problem (for the entire lab, not for each part). Write up brief answers to the questions posed in the lab and a one or two paragraph description of what you did to solve your chosen challenge problem in a file called `answers-lab3.txt` in the top level of your `lab` directory. (If you implement more than one challenge problem, you only need to describe one of them in the write-up.) Do not forget to include the answer file in your submission with git add answers-lab3.txt.
##### Inline Assembly
In this lab you may find GCC's inline assembly language feature useful, although it is also possible to complete the lab without using it. At the very least, you will need to be able to understand the fragments of inline assembly language ("`asm`" statements) that already exist in the source code we gave you. You can find several sources of information on GCC inline assembly language on the class [reference materials][2] page.
#### Part A: User Environments and Exception Handling
The new include file `inc/env.h` contains basic definitions for user environments in JOS. Read it now. The kernel uses the `Env` data structure to keep track of each user environment. In this lab you will initially create just one environment, but you will need to design the JOS kernel to support multiple environments; lab 4 will take advantage of this feature by allowing a user environment to `fork` other environments.
As you can see in `kern/env.c`, the kernel maintains three main global variables pertaining to environments:
```
struct Env *envs = NULL; // All environments
struct Env *curenv = NULL; // The current env
static struct Env *env_free_list; // Free environment list
```
Once JOS gets up and running, the `envs` pointer points to an array of `Env` structures representing all the environments in the system. In our design, the JOS kernel will support a maximum of `NENV` simultaneously active environments, although there will typically be far fewer running environments at any given time. (`NENV` is a constant `#define`'d in `inc/env.h`.) Once it is allocated, the `envs` array will contain a single instance of the `Env` data structure for each of the `NENV` possible environments.
The JOS kernel keeps all of the inactive `Env` structures on the `env_free_list`. This design allows easy allocation and deallocation of environments, as they merely have to be added to or removed from the free list.
The kernel uses the `curenv` symbol to keep track of the _currently executing_ environment at any given time. During boot up, before the first environment is run, `curenv` is initially set to `NULL`.
##### Environment State
The `Env` structure is defined in `inc/env.h` as follows (although more fields will be added in future labs):
```
struct Env {
struct Trapframe env_tf; // Saved registers
struct Env *env_link; // Next free Env
envid_t env_id; // Unique environment identifier
envid_t env_parent_id; // env_id of this env's parent
enum EnvType env_type; // Indicates special system environments
unsigned env_status; // Status of the environment
uint32_t env_runs; // Number of times environment has run
// Address space
pde_t *env_pgdir; // Kernel virtual address of page dir
};
```
Here's what the `Env` fields are for:
* **env_tf** :
This structure, defined in `inc/trap.h`, holds the saved register values for the environment while that environment is _not_ running: i.e., when the kernel or a different environment is running. The kernel saves these when switching from user to kernel mode, so that the environment can later be resumed where it left off.
* **env_link** :
This is a link to the next `Env` on the `env_free_list`. `env_free_list` points to the first free environment on the list.
* **env_id** :
The kernel stores here a value that uniquely identifiers the environment currently using this `Env` structure (i.e., using this particular slot in the `envs` array). After a user environment terminates, the kernel may re-allocate the same `Env` structure to a different environment - but the new environment will have a different `env_id` from the old one even though the new environment is re-using the same slot in the `envs` array.
* **env_parent_id** :
The kernel stores here the `env_id` of the environment that created this environment. In this way the environments can form a “family tree,” which will be useful for making security decisions about which environments are allowed to do what to whom.
* **env_type** :
This is used to distinguish special environments. For most environments, it will be `ENV_TYPE_USER`. We'll introduce a few more types for special system service environments in later labs.
* **env_status** :
This variable holds one of the following values:
* `ENV_FREE`:
Indicates that the `Env` structure is inactive, and therefore on the `env_free_list`.
* `ENV_RUNNABLE`:
Indicates that the `Env` structure represents an environment that is waiting to run on the processor.
* `ENV_RUNNING`:
Indicates that the `Env` structure represents the currently running environment.
* `ENV_NOT_RUNNABLE`:
Indicates that the `Env` structure represents a currently active environment, but it is not currently ready to run: for example, because it is waiting for an interprocess communication (IPC) from another environment.
* `ENV_DYING`:
Indicates that the `Env` structure represents a zombie environment. A zombie environment will be freed the next time it traps to the kernel. We will not use this flag until Lab 4.
* **env_pgdir** :
This variable holds the kernel _virtual address_ of this environment's page directory.
Like a Unix process, a JOS environment couples the concepts of "thread" and "address space". The thread is defined primarily by the saved registers (the `env_tf` field), and the address space is defined by the page directory and page tables pointed to by `env_pgdir`. To run an environment, the kernel must set up the CPU with _both_ the saved registers and the appropriate address space.
Our `struct Env` is analogous to `struct proc` in xv6. Both structures hold the environment's (i.e., process's) user-mode register state in a `Trapframe` structure. In JOS, individual environments do not have their own kernel stacks as processes do in xv6. There can be only one JOS environment active in the kernel at a time, so JOS needs only a _single_ kernel stack.
##### Allocating the Environments Array
In lab 2, you allocated memory in `mem_init()` for the `pages[]` array, which is a table the kernel uses to keep track of which pages are free and which are not. You will now need to modify `mem_init()` further to allocate a similar array of `Env` structures, called `envs`.
```
Exercise 1. Modify `mem_init()` in `kern/pmap.c` to allocate and map the `envs` array. This array consists of exactly `NENV` instances of the `Env` structure allocated much like how you allocated the `pages` array. Also like the `pages` array, the memory backing `envs` should also be mapped user read-only at `UENVS` (defined in `inc/memlayout.h`) so user processes can read from this array.
```
You should run your code and make sure `check_kern_pgdir()` succeeds.
##### Creating and Running Environments
You will now write the code in `kern/env.c` necessary to run a user environment. Because we do not yet have a filesystem, we will set up the kernel to load a static binary image that is _embedded within the kernel itself_. JOS embeds this binary in the kernel as a ELF executable image.
The Lab 3 `GNUmakefile` generates a number of binary images in the `obj/user/` directory. If you look at `kern/Makefrag`, you will notice some magic that "links" these binaries directly into the kernel executable as if they were `.o` files. The `-b binary` option on the linker command line causes these files to be linked in as "raw" uninterpreted binary files rather than as regular `.o` files produced by the compiler. (As far as the linker is concerned, these files do not have to be ELF images at all - they could be anything, such as text files or pictures!) If you look at `obj/kern/kernel.sym` after building the kernel, you will notice that the linker has "magically" produced a number of funny symbols with obscure names like `_binary_obj_user_hello_start`, `_binary_obj_user_hello_end`, and `_binary_obj_user_hello_size`. The linker generates these symbol names by mangling the file names of the binary files; the symbols provide the regular kernel code with a way to reference the embedded binary files.
In `i386_init()` in `kern/init.c` you'll see code to run one of these binary images in an environment. However, the critical functions to set up user environments are not complete; you will need to fill them in.
```
Exercise 2. In the file `env.c`, finish coding the following functions:
* `env_init()`
Initialize all of the `Env` structures in the `envs` array and add them to the `env_free_list`. Also calls `env_init_percpu`, which configures the segmentation hardware with separate segments for privilege level 0 (kernel) and privilege level 3 (user).
* `env_setup_vm()`
Allocate a page directory for a new environment and initialize the kernel portion of the new environment's address space.
* `region_alloc()`
Allocates and maps physical memory for an environment
* `load_icode()`
You will need to parse an ELF binary image, much like the boot loader already does, and load its contents into the user address space of a new environment.
* `env_create()`
Allocate an environment with `env_alloc` and call `load_icode` to load an ELF binary into it.
* `env_run()`
Start a given environment running in user mode.
As you write these functions, you might find the new cprintf verb `%e` useful -- it prints a description corresponding to an error code. For example,
r = -E_NO_MEM;
panic("env_alloc: %e", r);
will panic with the message "env_alloc: out of memory".
```
Below is a call graph of the code up to the point where the user code is invoked. Make sure you understand the purpose of each step.
* `start` (`kern/entry.S`)
* `i386_init` (`kern/init.c`)
* `cons_init`
* `mem_init`
* `env_init`
* `trap_init` (still incomplete at this point)
* `env_create`
* `env_run`
* `env_pop_tf`
Once you are done you should compile your kernel and run it under QEMU. If all goes well, your system should enter user space and execute the `hello` binary until it makes a system call with the `int` instruction. At that point there will be trouble, since JOS has not set up the hardware to allow any kind of transition from user space into the kernel. When the CPU discovers that it is not set up to handle this system call interrupt, it will generate a general protection exception, find that it can't handle that, generate a double fault exception, find that it can't handle that either, and finally give up with what's known as a "triple fault". Usually, you would then see the CPU reset and the system reboot. While this is important for legacy applications (see [this blog post][3] for an explanation of why), it's a pain for kernel development, so with the 6.828 patched QEMU you'll instead see a register dump and a "Triple fault." message.
We'll address this problem shortly, but for now we can use the debugger to check that we're entering user mode. Use make qemu-gdb and set a GDB breakpoint at `env_pop_tf`, which should be the last function you hit before actually entering user mode. Single step through this function using si; the processor should enter user mode after the `iret` instruction. You should then see the first instruction in the user environment's executable, which is the `cmpl` instruction at the label `start` in `lib/entry.S`. Now use b *0x... to set a breakpoint at the `int $0x30` in `sys_cputs()` in `hello` (see `obj/user/hello.asm` for the user-space address). This `int` is the system call to display a character to the console. If you cannot execute as far as the `int`, then something is wrong with your address space setup or program loading code; go back and fix it before continuing.
##### Handling Interrupts and Exceptions
At this point, the first `int $0x30` system call instruction in user space is a dead end: once the processor gets into user mode, there is no way to get back out. You will now need to implement basic exception and system call handling, so that it is possible for the kernel to recover control of the processor from user-mode code. The first thing you should do is thoroughly familiarize yourself with the x86 interrupt and exception mechanism.
```
Exercise 3. Read Chapter 9, Exceptions and Interrupts in the 80386 Programmer's Manual (or Chapter 5 of the IA-32 Developer's Manual), if you haven't already.
```
In this lab we generally follow Intel's terminology for interrupts, exceptions, and the like. However, terms such as exception, trap, interrupt, fault and abort have no standard meaning across architectures or operating systems, and are often used without regard to the subtle distinctions between them on a particular architecture such as the x86. When you see these terms outside of this lab, the meanings might be slightly different.
##### Basics of Protected Control Transfer
Exceptions and interrupts are both "protected control transfers," which cause the processor to switch from user to kernel mode (CPL=0) without giving the user-mode code any opportunity to interfere with the functioning of the kernel or other environments. In Intel's terminology, an _interrupt_ is a protected control transfer that is caused by an asynchronous event usually external to the processor, such as notification of external device I/O activity. An _exception_ , in contrast, is a protected control transfer caused synchronously by the currently running code, for example due to a divide by zero or an invalid memory access.
In order to ensure that these protected control transfers are actually _protected_ , the processor's interrupt/exception mechanism is designed so that the code currently running when the interrupt or exception occurs _does not get to choose arbitrarily where the kernel is entered or how_. Instead, the processor ensures that the kernel can be entered only under carefully controlled conditions. On the x86, two mechanisms work together to provide this protection:
1. **The Interrupt Descriptor Table.** The processor ensures that interrupts and exceptions can only cause the kernel to be entered at a few specific, well-defined entry-points _determined by the kernel itself_ , and not by the code running when the interrupt or exception is taken.
The x86 allows up to 256 different interrupt or exception entry points into the kernel, each with a different _interrupt vector_. A vector is a number between 0 and 255. An interrupt's vector is determined by the source of the interrupt: different devices, error conditions, and application requests to the kernel generate interrupts with different vectors. The CPU uses the vector as an index into the processor's _interrupt descriptor table_ (IDT), which the kernel sets up in kernel-private memory, much like the GDT. From the appropriate entry in this table the processor loads:
* the value to load into the instruction pointer (`EIP`) register, pointing to the kernel code designated to handle that type of exception.
* the value to load into the code segment (`CS`) register, which includes in bits 0-1 the privilege level at which the exception handler is to run. (In JOS, all exceptions are handled in kernel mode, privilege level 0.)
2. **The Task State Segment.** The processor needs a place to save the _old_ processor state before the interrupt or exception occurred, such as the original values of `EIP` and `CS` before the processor invoked the exception handler, so that the exception handler can later restore that old state and resume the interrupted code from where it left off. But this save area for the old processor state must in turn be protected from unprivileged user-mode code; otherwise buggy or malicious user code could compromise the kernel.
For this reason, when an x86 processor takes an interrupt or trap that causes a privilege level change from user to kernel mode, it also switches to a stack in the kernel's memory. A structure called the _task state segment_ (TSS) specifies the segment selector and address where this stack lives. The processor pushes (on this new stack) `SS`, `ESP`, `EFLAGS`, `CS`, `EIP`, and an optional error code. Then it loads the `CS` and `EIP` from the interrupt descriptor, and sets the `ESP` and `SS` to refer to the new stack.
Although the TSS is large and can potentially serve a variety of purposes, JOS only uses it to define the kernel stack that the processor should switch to when it transfers from user to kernel mode. Since "kernel mode" in JOS is privilege level 0 on the x86, the processor uses the `ESP0` and `SS0` fields of the TSS to define the kernel stack when entering kernel mode. JOS doesn't use any other TSS fields.
##### Types of Exceptions and Interrupts
All of the synchronous exceptions that the x86 processor can generate internally use interrupt vectors between 0 and 31, and therefore map to IDT entries 0-31. For example, a page fault always causes an exception through vector 14. Interrupt vectors greater than 31 are only used by _software interrupts_ , which can be generated by the `int` instruction, or asynchronous _hardware interrupts_ , caused by external devices when they need attention.
In this section we will extend JOS to handle the internally generated x86 exceptions in vectors 0-31. In the next section we will make JOS handle software interrupt vector 48 (0x30), which JOS (fairly arbitrarily) uses as its system call interrupt vector. In Lab 4 we will extend JOS to handle externally generated hardware interrupts such as the clock interrupt.
##### An Example
Let's put these pieces together and trace through an example. Let's say the processor is executing code in a user environment and encounters a divide instruction that attempts to divide by zero.
1. The processor switches to the stack defined by the `SS0` and `ESP0` fields of the TSS, which in JOS will hold the values `GD_KD` and `KSTACKTOP`, respectively.
2. The processor pushes the exception parameters on the kernel stack, starting at address `KSTACKTOP`:
```
+--------------------+ KSTACKTOP
| 0x00000 | old SS | " - 4
| old ESP | " - 8
| old EFLAGS | " - 12
| 0x00000 | old CS | " - 16
| old EIP | " - 20 <---- ESP
+--------------------+
```
3. Because we're handling a divide error, which is interrupt vector 0 on the x86, the processor reads IDT entry 0 and sets `CS:EIP` to point to the handler function described by the entry.
4. The handler function takes control and handles the exception, for example by terminating the user environment.
For certain types of x86 exceptions, in addition to the "standard" five words above, the processor pushes onto the stack another word containing an _error code_. The page fault exception, number 14, is an important example. See the 80386 manual to determine for which exception numbers the processor pushes an error code, and what the error code means in that case. When the processor pushes an error code, the stack would look as follows at the beginning of the exception handler when coming in from user mode:
```
+--------------------+ KSTACKTOP
| 0x00000 | old SS | " - 4
| old ESP | " - 8
| old EFLAGS | " - 12
| 0x00000 | old CS | " - 16
| old EIP | " - 20
| error code | " - 24 <---- ESP
+--------------------+
```
##### Nested Exceptions and Interrupts
The processor can take exceptions and interrupts both from kernel and user mode. It is only when entering the kernel from user mode, however, that the x86 processor automatically switches stacks before pushing its old register state onto the stack and invoking the appropriate exception handler through the IDT. If the processor is _already_ in kernel mode when the interrupt or exception occurs (the low 2 bits of the `CS` register are already zero), then the CPU just pushes more values on the same kernel stack. In this way, the kernel can gracefully handle _nested exceptions_ caused by code within the kernel itself. This capability is an important tool in implementing protection, as we will see later in the section on system calls.
If the processor is already in kernel mode and takes a nested exception, since it does not need to switch stacks, it does not save the old `SS` or `ESP` registers. For exception types that do not push an error code, the kernel stack therefore looks like the following on entry to the exception handler:
```
+--------------------+ <---- old ESP
| old EFLAGS | " - 4
| 0x00000 | old CS | " - 8
| old EIP | " - 12
+--------------------+
```
For exception types that push an error code, the processor pushes the error code immediately after the old `EIP`, as before.
There is one important caveat to the processor's nested exception capability. If the processor takes an exception while already in kernel mode, and _cannot push its old state onto the kernel stack_ for any reason such as lack of stack space, then there is nothing the processor can do to recover, so it simply resets itself. Needless to say, the kernel should be designed so that this can't happen.
##### Setting Up the IDT
You should now have the basic information you need in order to set up the IDT and handle exceptions in JOS. For now, you will set up the IDT to handle interrupt vectors 0-31 (the processor exceptions). We'll handle system call interrupts later in this lab and add interrupts 32-47 (the device IRQs) in a later lab.
The header files `inc/trap.h` and `kern/trap.h` contain important definitions related to interrupts and exceptions that you will need to become familiar with. The file `kern/trap.h` contains definitions that are strictly private to the kernel, while `inc/trap.h` contains definitions that may also be useful to user-level programs and libraries.
Note: Some of the exceptions in the range 0-31 are defined by Intel to be reserved. Since they will never be generated by the processor, it doesn't really matter how you handle them. Do whatever you think is cleanest.
The overall flow of control that you should achieve is depicted below:
```
IDT trapentry.S trap.c
+----------------+
| &handler1 |---------> handler1: trap (struct Trapframe *tf)
| | // do stuff {
| | call trap // handle the exception/interrupt
| | // ... }
+----------------+
| &handler2 |--------> handler2:
| | // do stuff
| | call trap
| | // ...
+----------------+
.
.
.
+----------------+
| &handlerX |--------> handlerX:
| | // do stuff
| | call trap
| | // ...
+----------------+
```
Each exception or interrupt should have its own handler in `trapentry.S` and `trap_init()` should initialize the IDT with the addresses of these handlers. Each of the handlers should build a `struct Trapframe` (see `inc/trap.h`) on the stack and call `trap()` (in `trap.c`) with a pointer to the Trapframe. `trap()` then handles the exception/interrupt or dispatches to a specific handler function.
```
Exercise 4. Edit `trapentry.S` and `trap.c` and implement the features described above. The macros `TRAPHANDLER` and `TRAPHANDLER_NOEC` in `trapentry.S` should help you, as well as the T_* defines in `inc/trap.h`. You will need to add an entry point in `trapentry.S` (using those macros) for each trap defined in `inc/trap.h`, and you'll have to provide `_alltraps` which the `TRAPHANDLER` macros refer to. You will also need to modify `trap_init()` to initialize the `idt` to point to each of these entry points defined in `trapentry.S`; the `SETGATE` macro will be helpful here.
Your `_alltraps` should:
1. push values to make the stack look like a struct Trapframe
2. load `GD_KD` into `%ds` and `%es`
3. `pushl %esp` to pass a pointer to the Trapframe as an argument to trap()
4. `call trap` (can `trap` ever return?)
Consider using the `pushal` instruction; it fits nicely with the layout of the `struct Trapframe`.
Test your trap handling code using some of the test programs in the `user` directory that cause exceptions before making any system calls, such as `user/divzero`. You should be able to get make grade to succeed on the `divzero`, `softint`, and `badsegment` tests at this point.
```
```
Challenge! You probably have a lot of very similar code right now, between the lists of `TRAPHANDLER` in `trapentry.S` and their installations in `trap.c`. Clean this up. Change the macros in `trapentry.S` to automatically generate a table for `trap.c` to use. Note that you can switch between laying down code and data in the assembler by using the directives `.text` and `.data`.
```
```
Questions
Answer the following questions in your `answers-lab3.txt`:
1. What is the purpose of having an individual handler function for each exception/interrupt? (i.e., if all exceptions/interrupts were delivered to the same handler, what feature that exists in the current implementation could not be provided?)
2. Did you have to do anything to make the `user/softint` program behave correctly? The grade script expects it to produce a general protection fault (trap 13), but `softint`'s code says `int $14`. _Why_ should this produce interrupt vector 13? What happens if the kernel actually allows `softint`'s `int $14` instruction to invoke the kernel's page fault handler (which is interrupt vector 14)?
```
This concludes part A of the lab. Don't forget to add `answers-lab3.txt`, commit your changes, and run make handin before the part A deadline.
#### Part B: Page Faults, Breakpoints Exceptions, and System Calls
Now that your kernel has basic exception handling capabilities, you will refine it to provide important operating system primitives that depend on exception handling.
##### Handling Page Faults
The page fault exception, interrupt vector 14 (`T_PGFLT`), is a particularly important one that we will exercise heavily throughout this lab and the next. When the processor takes a page fault, it stores the linear (i.e., virtual) address that caused the fault in a special processor control register, `CR2`. In `trap.c` we have provided the beginnings of a special function, `page_fault_handler()`, to handle page fault exceptions.
```
Exercise 5. Modify `trap_dispatch()` to dispatch page fault exceptions to `page_fault_handler()`. You should now be able to get make grade to succeed on the `faultread`, `faultreadkernel`, `faultwrite`, and `faultwritekernel` tests. If any of them don't work, figure out why and fix them. Remember that you can boot JOS into a particular user program using make run- _x_ or make run- _x_ -nox. For instance, make run-hello-nox runs the _hello_ user program.
```
You will further refine the kernel's page fault handling below, as you implement system calls.
##### The Breakpoint Exception
The breakpoint exception, interrupt vector 3 (`T_BRKPT`), is normally used to allow debuggers to insert breakpoints in a program's code by temporarily replacing the relevant program instruction with the special 1-byte `int3` software interrupt instruction. In JOS we will abuse this exception slightly by turning it into a primitive pseudo-system call that any user environment can use to invoke the JOS kernel monitor. This usage is actually somewhat appropriate if we think of the JOS kernel monitor as a primitive debugger. The user-mode implementation of `panic()` in `lib/panic.c`, for example, performs an `int3` after displaying its panic message.
```
Exercise 6. Modify `trap_dispatch()` to make breakpoint exceptions invoke the kernel monitor. You should now be able to get make grade to succeed on the `breakpoint` test.
```
```
Challenge! Modify the JOS kernel monitor so that you can 'continue' execution from the current location (e.g., after the `int3`, if the kernel monitor was invoked via the breakpoint exception), and so that you can single-step one instruction at a time. You will need to understand certain bits of the `EFLAGS` register in order to implement single-stepping.
Optional: If you're feeling really adventurous, find some x86 disassembler source code - e.g., by ripping it out of QEMU, or out of GNU binutils, or just write it yourself - and extend the JOS kernel monitor to be able to disassemble and display instructions as you are stepping through them. Combined with the symbol table loading from lab 1, this is the stuff of which real kernel debuggers are made.
```
```
Questions
3. The break point test case will either generate a break point exception or a general protection fault depending on how you initialized the break point entry in the IDT (i.e., your call to `SETGATE` from `trap_init`). Why? How do you need to set it up in order to get the breakpoint exception to work as specified above and what incorrect setup would cause it to trigger a general protection fault?
4. What do you think is the point of these mechanisms, particularly in light of what the `user/softint` test program does?
```
##### System calls
User processes ask the kernel to do things for them by invoking system calls. When the user process invokes a system call, the processor enters kernel mode, the processor and the kernel cooperate to save the user process's state, the kernel executes appropriate code in order to carry out the system call, and then resumes the user process. The exact details of how the user process gets the kernel's attention and how it specifies which call it wants to execute vary from system to system.
In the JOS kernel, we will use the `int` instruction, which causes a processor interrupt. In particular, we will use `int $0x30` as the system call interrupt. We have defined the constant `T_SYSCALL` to 48 (0x30) for you. You will have to set up the interrupt descriptor to allow user processes to cause that interrupt. Note that interrupt 0x30 cannot be generated by hardware, so there is no ambiguity caused by allowing user code to generate it.
The application will pass the system call number and the system call arguments in registers. This way, the kernel won't need to grub around in the user environment's stack or instruction stream. The system call number will go in `%eax`, and the arguments (up to five of them) will go in `%edx`, `%ecx`, `%ebx`, `%edi`, and `%esi`, respectively. The kernel passes the return value back in `%eax`. The assembly code to invoke a system call has been written for you, in `syscall()` in `lib/syscall.c`. You should read through it and make sure you understand what is going on.
```
Exercise 7. Add a handler in the kernel for interrupt vector `T_SYSCALL`. You will have to edit `kern/trapentry.S` and `kern/trap.c`'s `trap_init()`. You also need to change `trap_dispatch()` to handle the system call interrupt by calling `syscall()` (defined in `kern/syscall.c`) with the appropriate arguments, and then arranging for the return value to be passed back to the user process in `%eax`. Finally, you need to implement `syscall()` in `kern/syscall.c`. Make sure `syscall()` returns `-E_INVAL` if the system call number is invalid. You should read and understand `lib/syscall.c` (especially the inline assembly routine) in order to confirm your understanding of the system call interface. Handle all the system calls listed in `inc/syscall.h` by invoking the corresponding kernel function for each call.
Run the `user/hello` program under your kernel (make run-hello). It should print "`hello, world`" on the console and then cause a page fault in user mode. If this does not happen, it probably means your system call handler isn't quite right. You should also now be able to get make grade to succeed on the `testbss` test.
```
```
Challenge! Implement system calls using the `sysenter` and `sysexit` instructions instead of using `int 0x30` and `iret`.
The `sysenter/sysexit` instructions were designed by Intel to be faster than `int/iret`. They do this by using registers instead of the stack and by making assumptions about how the segmentation registers are used. The exact details of these instructions can be found in Volume 2B of the Intel reference manuals.
The easiest way to add support for these instructions in JOS is to add a `sysenter_handler` in `kern/trapentry.S` that saves enough information about the user environment to return to it, sets up the kernel environment, pushes the arguments to `syscall()` and calls `syscall()` directly. Once `syscall()` returns, set everything up for and execute the `sysexit` instruction. You will also need to add code to `kern/init.c` to set up the necessary model specific registers (MSRs). Section 6.1.2 in Volume 2 of the AMD Architecture Programmer's Manual and the reference on SYSENTER in Volume 2B of the Intel reference manuals give good descriptions of the relevant MSRs. You can find an implementation of `wrmsr` to add to `inc/x86.h` for writing to these MSRs [here][4].
Finally, `lib/syscall.c` must be changed to support making a system call with `sysenter`. Here is a possible register layout for the `sysenter` instruction:
eax - syscall number
edx, ecx, ebx, edi - arg1, arg2, arg3, arg4
esi - return pc
ebp - return esp
esp - trashed by sysenter
GCC's inline assembler will automatically save registers that you tell it to load values directly into. Don't forget to either save (push) and restore (pop) other registers that you clobber, or tell the inline assembler that you're clobbering them. The inline assembler doesn't support saving `%ebp`, so you will need to add code to save and restore it yourself. The return address can be put into `%esi` by using an instruction like `leal after_sysenter_label, %%esi`.
Note that this only supports 4 arguments, so you will need to leave the old method of doing system calls around to support 5 argument system calls. Furthermore, because this fast path doesn't update the current environment's trap frame, it won't be suitable for some of the system calls we add in later labs.
You may have to revisit your code once we enable asynchronous interrupts in the next lab. Specifically, you'll need to enable interrupts when returning to the user process, which `sysexit` doesn't do for you.
```
##### User-mode startup
A user program starts running at the top of `lib/entry.S`. After some setup, this code calls `libmain()`, in `lib/libmain.c`. You should modify `libmain()` to initialize the global pointer `thisenv` to point at this environment's `struct Env` in the `envs[]` array. (Note that `lib/entry.S` has already defined `envs` to point at the `UENVS` mapping you set up in Part A.) Hint: look in `inc/env.h` and use `sys_getenvid`.
`libmain()` then calls `umain`, which, in the case of the hello program, is in `user/hello.c`. Note that after printing "`hello, world`", it tries to access `thisenv->env_id`. This is why it faulted earlier. Now that you've initialized `thisenv` properly, it should not fault. If it still faults, you probably haven't mapped the `UENVS` area user-readable (back in Part A in `pmap.c`; this is the first time we've actually used the `UENVS` area).
```
Exercise 8. Add the required code to the user library, then boot your kernel. You should see `user/hello` print "`hello, world`" and then print "`i am environment 00001000`". `user/hello` then attempts to "exit" by calling `sys_env_destroy()` (see `lib/libmain.c` and `lib/exit.c`). Since the kernel currently only supports one user environment, it should report that it has destroyed the only environment and then drop into the kernel monitor. You should be able to get make grade to succeed on the `hello` test.
```
##### Page faults and memory protection
Memory protection is a crucial feature of an operating system, ensuring that bugs in one program cannot corrupt other programs or corrupt the operating system itself.
Operating systems usually rely on hardware support to implement memory protection. The OS keeps the hardware informed about which virtual addresses are valid and which are not. When a program tries to access an invalid address or one for which it has no permissions, the processor stops the program at the instruction causing the fault and then traps into the kernel with information about the attempted operation. If the fault is fixable, the kernel can fix it and let the program continue running. If the fault is not fixable, then the program cannot continue, since it will never get past the instruction causing the fault.
As an example of a fixable fault, consider an automatically extended stack. In many systems the kernel initially allocates a single stack page, and then if a program faults accessing pages further down the stack, the kernel will allocate those pages automatically and let the program continue. By doing this, the kernel only allocates as much stack memory as the program needs, but the program can work under the illusion that it has an arbitrarily large stack.
System calls present an interesting problem for memory protection. Most system call interfaces let user programs pass pointers to the kernel. These pointers point at user buffers to be read or written. The kernel then dereferences these pointers while carrying out the system call. There are two problems with this:
1. A page fault in the kernel is potentially a lot more serious than a page fault in a user program. If the kernel page-faults while manipulating its own data structures, that's a kernel bug, and the fault handler should panic the kernel (and hence the whole system). But when the kernel is dereferencing pointers given to it by the user program, it needs a way to remember that any page faults these dereferences cause are actually on behalf of the user program.
2. The kernel typically has more memory permissions than the user program. The user program might pass a pointer to a system call that points to memory that the kernel can read or write but that the program cannot. The kernel must be careful not to be tricked into dereferencing such a pointer, since that might reveal private information or destroy the integrity of the kernel.
For both of these reasons the kernel must be extremely careful when handling pointers presented by user programs.
You will now solve these two problems with a single mechanism that scrutinizes all pointers passed from userspace into the kernel. When a program passes the kernel a pointer, the kernel will check that the address is in the user part of the address space, and that the page table would allow the memory operation.
Thus, the kernel will never suffer a page fault due to dereferencing a user-supplied pointer. If the kernel does page fault, it should panic and terminate.
```
Exercise 9. Change `kern/trap.c` to panic if a page fault happens in kernel mode.
Hint: to determine whether a fault happened in user mode or in kernel mode, check the low bits of the `tf_cs`.
Read `user_mem_assert` in `kern/pmap.c` and implement `user_mem_check` in that same file.
Change `kern/syscall.c` to sanity check arguments to system calls.
Boot your kernel, running `user/buggyhello`. The environment should be destroyed, and the kernel should _not_ panic. You should see:
[00001000] user_mem_check assertion failure for va 00000001
[00001000] free env 00001000
Destroyed the only environment - nothing more to do!
Finally, change `debuginfo_eip` in `kern/kdebug.c` to call `user_mem_check` on `usd`, `stabs`, and `stabstr`. If you now run `user/breakpoint`, you should be able to run backtrace from the kernel monitor and see the backtrace traverse into `lib/libmain.c` before the kernel panics with a page fault. What causes this page fault? You don't need to fix it, but you should understand why it happens.
```
Note that the same mechanism you just implemented also works for malicious user applications (such as `user/evilhello`).
```
Exercise 10. Boot your kernel, running `user/evilhello`. The environment should be destroyed, and the kernel should not panic. You should see:
[00000000] new env 00001000
...
[00001000] user_mem_check assertion failure for va f010000c
[00001000] free env 00001000
```
**This completes the lab.** Make sure you pass all of the make grade tests and don't forget to write up your answers to the questions and a description of your challenge exercise solution in `answers-lab3.txt`. Commit your changes and type make handin in the `lab` directory to submit your work.
Before handing in, use git status and git diff to examine your changes and don't forget to git add answers-lab3.txt. When you're ready, commit your changes with git commit -am 'my solutions to lab 3', then make handin and follow the directions.
--------------------------------------------------------------------------------
via: https://pdos.csail.mit.edu/6.828/2018/labs/lab3/
作者:[csail.mit][a]
选题:[lujun9972][b]
译者:[译者ID](https://github.com/译者ID)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://pdos.csail.mit.edu
[b]: https://github.com/lujun9972
[1]: https://pdos.csail.mit.edu/6.828/2018/labs/labguide.html
[2]: https://pdos.csail.mit.edu/6.828/2018/labs/reference.html
[3]: http://blogs.msdn.com/larryosterman/archive/2005/02/08/369243.aspx
[4]: http://ftp.kh.edu.tw/Linux/SuSE/people/garloff/linux/k6mod.c

View File

@@ -1,3 +1,4 @@
distant1219 is translating
PyTorch 1.0 Preview Release: Facebooks newest Open Source AI
======
Facebook already uses its own Open Source AI, PyTorch quite extensively in its own artificial intelligence projects. Recently, they have gone a league ahead by releasing a pre-release preview version 1.0.

View File

@@ -1,3 +1,5 @@
translating by hopefully2333
Play Windows games on Fedora with Steam Play and Proton
======

View File

@@ -1,101 +0,0 @@
Python at the pump: A script for filling your gas tank
======
Here's how I used Python to discover a strategy for cost-effective fill-ups.
![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/bulb-light-energy-power-idea.png?itok=zTEEmTZB)
I recently began driving a car that had traditionally used premium gas (93 octane). According to the maker, though, it requires only 91 octane. The thing is, in the US, you can buy only 87, 89, or 93 octane. Where I live, gas prices jump 30 cents per gallon jump from one grade to the next, so premium costs 60 cents more than regular. So why not try to save some money?
Its easy enough to wait until the gas gauge shows that the tank is half full and then fill it with 89 octane, and there you have 91 octane. But it gets tricky to know what to do next—half a tank of 91 octane plus half a tank of 93 ends up being 92, and where do you go from there? You can make continuing calculations, but they get increasingly messy. This is where Python came into the picture.
I wanted to come up with a simple scheme in which I could fill the tank at some level with 93 octane, then at the same or some other level with 89 octane, with the primary goal to never get below 91 octane with the final mixture. What I needed to do was create some recurring calculation that uses the previous octane value for the preceding fill-up. I suppose there would be some polynomial equation that would solve this, but in Python, this sounds like a loop.
```
#!/usr/bin/env python
# octane.py
o = 93.0
newgas = 93.0   # this represents the octane of the last fillup
i = 1
while i < 21:                   # 20 iterations (trips to the pump)
    if newgas == 89.0:          # if the last fillup was with 89 octane
                                # switch to 93
        newgas = 93.0
        o = newgas/2 + o/2      # fill when gauge is 1/2 full
    else:                       # if it wasn't 89 octane, switch to that
        newgas = 89.0
        o = newgas/2 + o/2      # fill when gauge says 1/2 full
    print str(i) + ': '+ str(o)
    i += 1
```
As you can see, I am initializing the variable o (the current octane mixture in the tank) and the variable newgas (what I last filled the tank with) at the same value of 93. The loop then will repeat 20 times, for 20 fill-ups, switching from 89 octane and 93 octane for every other trip to the station.
```
1: 91.0
2: 92.0
3: 90.5
4: 91.75
5: 90.375
6: 91.6875
7: 90.34375
8: 91.671875
9: 90.3359375
10: 91.66796875
11: 90.333984375
12: 91.6669921875
13: 90.3334960938
14: 91.6667480469
15: 90.3333740234
16: 91.6666870117
17: 90.3333435059
18: 91.6666717529
19: 90.3333358765
20: 91.6666679382
```
This shows is that I probably need only 10 or 15 loops to see stabilization. It also shows that soon enough, I undershoot my 91 octane target. Its also interesting to see this stabilization of the alternating mixture values, and it turns out this happens with any scheme where you choose the same amounts each time. In fact, it is true even if the amount of the fill-up is different for 89 and 93 octane.
So at this point, I began playing with fractions, reasoning that I would probably need a bigger 93 octane fill-up than the 89 fill-up. I also didnt want to make frequent trips to the gas station. What I ended up with (which seemed pretty good to me) was to wait until the tank was about 712 full and fill it with 89 octane, then wait until it was ¼ full and fill it with 93 octane.
Here is what the changes in the loop look like:
```
    if newgas == 89.0:            
                                 
        newgas = 93.0
        o = 3*newgas/4 + o/4      
    else:                        
        newgas = 89.0
        o = 5*newgas/12 + 7*o/12
```
Here are the numbers, starting with the tenth fill-up:
```
10: 92.5122272978
11: 91.0487992571
12: 92.5121998143
13: 91.048783225
14: 92.5121958062
15: 91.048780887
```
As you can see, this keeps the final octane very slightly above 91 all the time. Of course, my gas gauge isnt marked in twelfths, but 712 is slightly less than 58, and I can handle that.
An alternative simple solution might have been run the tank to empty and fill with 93 octane, then next time only half-fill it for 89—and perhaps this will be my default plan. Personally, Im not a fan of running the tank all the way down since this isnt always convenient. On the other hand, it could easily work on a long trip. And sometimes I buy gas because of a sudden drop in prices. So in the end, this scheme is one of a series of options that I can consider.
The most important thing for Python users: Dont code while driving!
--------------------------------------------------------------------------------
via: https://opensource.com/article/18/10/python-gas-pump
作者:[Greg Pittman][a]
选题:[lujun9972](https://github.com/lujun9972)
译者:[译者ID](https://github.com/译者ID)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://opensource.com/users/greg-p

View File

@@ -1,3 +1,6 @@
translating---cyleft
====
6 Commands To Shutdown And Reboot The Linux System From Terminal
======
Linux administrator performing many tasks in their routine work. The system Shutdown and Reboot task also included in it.

View File

@@ -1,3 +1,5 @@
translating---geekpi
Convert Screenshots of Equations into LaTeX Instantly With This Nifty Tool
======
**Mathpix is a nifty little tool that allows you to take screenshots of complex mathematical equations and instantly converts it into LaTeX editable text.**

View File

@@ -1,3 +1,4 @@
Translating by way-ww
How To Create And Maintain Your Own Man Pages
======

View File

@@ -1,3 +1,5 @@
[translation by jrg]
An introduction to using tcpdump at the Linux command line
======

View File

@@ -1,197 +0,0 @@
Cloc Count The Lines Of Source Code In Many Programming Languages
======
![](https://www.ostechnix.com/wp-content/uploads/2018/10/cloc-720x340.png)
As a developer, you may need to share the progress and statistics of your code to your boss or colleagues. Your boss might want to analyze the code and give any additional inputs. In such cases, there are few programs, as far as I know, available to analyze the source code. One such program is [**Ohcount**][1]. Today, I came across yet another similar utility namely **“Cloc”**. Using the Cloc, you can easily count the lines of source code in several programming languages. It counts the blank lines, comment lines, and physical lines of source code and displays the result in a neat tabular-column format. Cloc is free, open source and cross-platform utility entirely written in **Perl** programming language.
### Features
Cloc ships with numerous advantages including the following:
* Easy to install/use. Requires no dependencies.
* Portable
* It can produce results in a variety of formats, such as plain text, SQL, JSON, XML, YAML, comma separated values.
* Can count your git commits.
* Count the code in directories and sub-directories.
* Count codes count code within compressed archives like tar balls, Zip files, Java .ear files etc.
* Open source and cross platform.
### Installing Cloc
The Cloc utility is available in the default repositories of most Unix-like operating systems. So, you can install it using the default package manager as shown below.
On Arch Linux and its variants:
```
$ sudo pacman -S cloc
```
On Debian, Ubuntu:
```
$ sudo apt-get install cloc
```
On CentOS, Red Hat, Scientific Linux:
```
$ sudo yum install cloc
```
On Fedora:
```
$ sudo dnf install cloc
```
On FreeBSD:
```
$ sudo pkg install cloc
```
It can also installed using third-party package manager like [**NPM**][2] as well.
```
$ npm install -g cloc
```
### Count The Lines Of Source Code In Many Programming Languages
Let us start with a simple example. I have a “hello world” program written in C in my current working directory.
```
$ cat hello.c
#include <stdio.h>
int main()
{
// printf() displays the string inside quotation
printf("Hello, World!");
return 0;
}
```
To count the lines of code in the hello.c program, simply run:
```
$ cloc hello.c
```
Sample output:
![](https://www.ostechnix.com/wp-content/uploads/2018/10/Hello-World-Program.png)
The first column specifies the **name of programming languages that the source code consists of**. As you can see in the above output, the source code of “hello world” program is written using **C** programming language.
The second column displays the **number of files in each programming languages**. So, our code contains **1 file** in total.
The third column displays the **total number of blank lines**. We have zero blank files in our code.
The fourth column displays **number of comment lines**.
And the final and fifth column displays **total physical lines of given source code**.
It is just a 6 line code program, so counting the lines in the code is not a big deal. What about the some big source code file? Have a look at the following example:
```
$ cloc file.tar.gz
```
Sample output:
![](https://www.ostechnix.com/wp-content/uploads/2018/10/cloc-1.png)
As per the above output, it is quite difficult to manually find exact count of code. But, Cloc displays the result in seconds with nice tabular-column format. You can view the gross total of each section at the end which is quite handy when it comes to analyze the source code of a program.
Cloc not only counts the individual source code files, but also files inside directories and sub-directories, archives, and even in specific git commits etc.
**Count the lines of codes in a directory:**
```
$ cloc dir/
```
![][4]
**Sub-directory:**
```
$ cloc dir/cloc/tests
```
![][5]
**Count the lines of codes in archive file:**
```
$ cloc archive.zip
```
![][6]
You can also count lines in a git repository, using a specific commit like below.
```
$ git clone https://github.com/AlDanial/cloc.git
$ cd cloc
$ cloc 157d706
```
![][7]
Cloc can recognize several programming languages. To view the complete list of recognized languages, run:
```
$ cloc --show-lang
```
For more details, refer the help section.
```
$ cloc --help
```
Cheers!
--------------------------------------------------------------------------------
via: https://www.ostechnix.com/cloc-count-the-lines-of-source-code-in-many-programming-languages/
作者:[SK][a]
选题:[lujun9972][b]
译者:[译者ID](https://github.com/译者ID)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://www.ostechnix.com/author/sk/
[b]: https://github.com/lujun9972
[1]: https://www.ostechnix.com/ohcount-the-source-code-line-counter-and-analyzer/
[2]: https://www.ostechnix.com/install-node-js-linux/
[3]: data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7
[4]: http://www.ostechnix.com/wp-content/uploads/2018/10/cloc-2-1.png
[5]: http://www.ostechnix.com/wp-content/uploads/2018/10/cloc-4.png
[6]: http://www.ostechnix.com/wp-content/uploads/2018/10/cloc-3.png
[7]: http://www.ostechnix.com/wp-content/uploads/2018/10/cloc-5.png

View File

@@ -0,0 +1,289 @@
How To List The Enabled/Active Repositories In Linux
======
There are many ways to list enabled repositories in Linux.
Here we are going to show you the easy methods to list active repositories.
It will helps you to know what are the repositories enabled on your system.
Once you have this information in handy then you can add any repositories that you want if its not already enabled.
Say for example, if you would like to enable `epel repository` then you need to check whether the epel repository is enabled or not. In this case this tutorial would help you.
### What Is Repository?
A software repository is a central place which stores the software packages for the particular application.
All the Linux distributions are maintaining their own repositories and they allow users to retrieve and install packages on their machine.
Each vendor offered a unique package management tool to manage their repositories such as search, install, update, upgrade, remove, etc.
Most of the Linux distributions comes as freeware except RHEL and SUSE. To access their repositories you need to buy a subscriptions.
**Suggested Read :**
**(#)** [How To Add, Enable And Disable A Repository By Using The DNF/YUM Config Manager Command On Linux][1]
**(#)** [How To List Installed Packages By Size (Largest) On Linux][2]
**(#)** [How To View/List The Available Packages Updates In Linux][3]
**(#)** [How To View A Particular Package Installed/Updated/Upgraded/Removed/Erased Date On Linux][4]
**(#)** [How To View Detailed Information About A Package In Linux][5]
**(#)** [How To Search If A Package Is Available On Your Linux Distribution Or Not][6]
**(#)** [How To List An Available Package Groups In Linux][7]
**(#)** [Newbies corner A Graphical frontend tool for Linux Package Manager][8]
**(#)** [Linux Expert should knows, list of Command line Package Manager & Usage][9]
### How To List The Enabled Repositories on RHEL/CentOS
RHEL & CentOS systems are using RPM packages hence we can use the `Yum Package Manager` to get this information.
YUM stands for Yellowdog Updater, Modified is an open-source command-line front-end package-management utility for RPM based systems such as Red Hat Enterprise Linux (RHEL) and CentOS.
Yum is the primary tool for getting, installing, deleting, querying, and managing RPM packages from distribution repositories, as well as other third-party repositories.
**Suggested Read :** [YUM Command To Manage Packages on RHEL/CentOS Systems][10]
RHEL based systems are mainly offering the below three major repositories. These repository will be enabled by default.
* **`base:`** Its containing all the core packages and base packages.
* **`extras:`** It provides additional functionality to CentOS without breaking upstream compatibility or updating base components. It is an upstream repository, as well as additional CentOS packages.
* **`updates:`** Its offering bug fixed packages, Security packages and Enhancement packages.
```
# yum repolist
or
# yum repolist enabled
Loaded plugins: fastestmirror
Determining fastest mirrors
选题模板.txt 中文排版指北.md comic core.md Dict.md lctt2014.md lctt2016.md lctt2018.md LCTT翻译规范.md LICENSE Makefile published README.md sign.md sources translated epel: ewr.edge.kernel.org
repo id repo name status
!base/7/x86_64 CentOS-7 - Base 9,911
!epel/x86_64 Extra Packages for Enterprise Linux 7 - x86_64 12,687
!extras/7/x86_64 CentOS-7 - Extras 403
!updates/7/x86_64 CentOS-7 - Updates 1,348
repolist: 24,349
```
### How To List The Enabled Repositories on Fedora
DNF stands for Dandified yum. We can tell DNF, the next generation of yum package manager (Fork of Yum) using hawkey/libsolv library for backend. Aleš Kozumplík started working on DNF since Fedora 18 and its implemented/launched in Fedora 22 finally.
Dnf command is used to install, update, search & remove packages on Fedora 22 and later system. It automatically resolve dependencies and make it smooth package installation without any trouble.
Yum replaced by DNF due to several long-term problems in Yum which was not solved. Asked why ? he did not patches the Yum issues. Aleš Kozumplík explains that patching was technically hard and YUM team wont accept the changes immediately and other major critical, YUM is 56K lines but DNF is 29K lies. So, there is no option for further development, except to fork.
**Suggested Read :** [DNF (Fork of YUM) Command To Manage Packages on Fedora System][11]
Fedora system is mainly offering the below two major repositories. These repository will be enabled by default.
* **`fedora:`** Its containing all the core packages and base packages.
* **`updates:`** Its offering bug fixed packages, Security packages and Enhancement packages from the stable release branch.
```
# dnf repolist
or
# dnf repolist enabled
Last metadata expiration check: 0:02:56 ago on Wed 10 Oct 2018 06:12:22 PM IST.
repo id repo name status
docker-ce-stable Docker CE Stable - x86_64 6
*fedora Fedora 26 - x86_64 53,912
home_mhogomchungu mhogomchungu's Home Project (Fedora_25) 19
home_moritzmolch_gencfsm Gnome Encfs Manager (Fedora_25) 5
mystro256-gnome-redshift Copr repo for gnome-redshift owned by mystro256 6
nodesource Node.js Packages for Fedora Linux 26 - x86_64 83
rabiny-albert Copr repo for albert owned by rabiny 3
*rpmfusion-free RPM Fusion for Fedora 26 - Free 536
*rpmfusion-free-updates RPM Fusion for Fedora 26 - Free - Updates 278
*rpmfusion-nonfree RPM Fusion for Fedora 26 - Nonfree 202
*rpmfusion-nonfree-updates RPM Fusion for Fedora 26 - Nonfree - Updates 95
*updates Fedora 26 - x86_64 - Updates 14,595
```
### How To List The Enabled Repositories on Debian/Ubuntu
Debian based systems are using APT/APT-GET package manager hence we can use the `APT/APT-GET Package Manager` to get this information.
APT stands for Advanced Packaging Tool (APT) which is replacement for apt-get, like how DNF came to picture instead of YUM. Its feature rich command-line tools with included all the futures in one command (APT) such as apt-cache, apt-search, dpkg, apt-cdrom, apt-config, apt-key, etc..,. and several other unique features. For example we can easily install .dpkg packages through APT but we cant do through Apt-Get similar more features are included into APT command. APT-GET replaced by APT Due to lock of futures missing in apt-get which was not solved.
Apt-Get stands for Advanced Packaging Tool (APT). apg-get is a powerful command-line tool which is used to automatically download and install new software packages, upgrade existing software packages, update the package list index, and to upgrade the entire Debian based systems.
```
# apt-cache policy
Package files:
100 /var/lib/dpkg/status
release a=now
500 http://ppa.launchpad.net/peek-developers/stable/ubuntu artful/main amd64 Packages
release v=17.10,o=LP-PPA-peek-developers-stable,a=artful,n=artful,l=Peek stable releases,c=main,b=amd64
origin ppa.launchpad.net
500 http://ppa.launchpad.net/notepadqq-team/notepadqq/ubuntu artful/main amd64 Packages
release v=17.10,o=LP-PPA-notepadqq-team-notepadqq,a=artful,n=artful,l=Notepadqq,c=main,b=amd64
origin ppa.launchpad.net
500 http://dl.google.com/linux/chrome/deb stable/main amd64 Packages
release v=1.0,o=Google, Inc.,a=stable,n=stable,l=Google,c=main,b=amd64
origin dl.google.com
500 https://download.docker.com/linux/ubuntu artful/stable amd64 Packages
release o=Docker,a=artful,l=Docker CE,c=stable,b=amd64
origin download.docker.com
500 http://security.ubuntu.com/ubuntu artful-security/multiverse amd64 Packages
release v=17.10,o=Ubuntu,a=artful-security,n=artful,l=Ubuntu,c=multiverse,b=amd64
origin security.ubuntu.com
500 http://security.ubuntu.com/ubuntu artful-security/universe amd64 Packages
release v=17.10,o=Ubuntu,a=artful-security,n=artful,l=Ubuntu,c=universe,b=amd64
origin security.ubuntu.com
500 http://security.ubuntu.com/ubuntu artful-security/restricted i386 Packages
release v=17.10,o=Ubuntu,a=artful-security,n=artful,l=Ubuntu,c=restricted,b=i386
origin security.ubuntu.com
.
.
origin in.archive.ubuntu.com
500 http://in.archive.ubuntu.com/ubuntu artful/restricted amd64 Packages
release v=17.10,o=Ubuntu,a=artful,n=artful,l=Ubuntu,c=restricted,b=amd64
origin in.archive.ubuntu.com
500 http://in.archive.ubuntu.com/ubuntu artful/main i386 Packages
release v=17.10,o=Ubuntu,a=artful,n=artful,l=Ubuntu,c=main,b=i386
origin in.archive.ubuntu.com
500 http://in.archive.ubuntu.com/ubuntu artful/main amd64 Packages
release v=17.10,o=Ubuntu,a=artful,n=artful,l=Ubuntu,c=main,b=amd64
origin in.archive.ubuntu.com
Pinned packages:
```
### How To List The Enabled Repositories on openSUSE
openSUSE system uses zypper package manager hence we can use the zypper Package Manager to get this information.
Zypper is a command line package manager for suse & openSUSE distributions. Its used to install, update, search & remove packages & manage repositories, perform various queries, and more. Zypper command-line interface to ZYpp system management library (libzypp).
**Suggested Read :** [Zypper Command To Manage Packages On openSUSE & suse Systems][12]
```
# zypper repos
# | Alias | Name | Enabled | GPG Check | Refresh
--+-----------------------+-----------------------------------------------------+---------+-----------+--------
1 | packman-repository | packman-repository | Yes | (r ) Yes | Yes
2 | google-chrome | google-chrome | Yes | (r ) Yes | Yes
3 | home_lazka0_ql-stable | Stable Quod Libet / Ex Falso Builds (openSUSE_42.1) | Yes | (r ) Yes | No
4 | repo-non-oss | openSUSE-leap/42.1-Non-Oss | Yes | (r ) Yes | Yes
5 | repo-oss | openSUSE-leap/42.1-Oss | Yes | (r ) Yes | Yes
6 | repo-update | openSUSE-42.1-Update | Yes | (r ) Yes | Yes
7 | repo-update-non-oss | openSUSE-42.1-Update-Non-Oss | Yes | (r ) Yes | Yes
```
List Repositories with URI.
```
# zypper lr -u
# | Alias | Name | Enabled | GPG Check | Refresh | URI
--+-----------------------+-----------------------------------------------------+---------+-----------+---------+---------------------------------------------------------------------------------
1 | packman-repository | packman-repository | Yes | (r ) Yes | Yes | http://ftp.gwdg.de/pub/linux/packman/suse/openSUSE_Leap_42.1/
2 | google-chrome | google-chrome | Yes | (r ) Yes | Yes | http://dl.google.com/linux/chrome/rpm/stable/x86_64
3 | home_lazka0_ql-stable | Stable Quod Libet / Ex Falso Builds (openSUSE_42.1) | Yes | (r ) Yes | No | http://download.opensuse.org/repositories/home:/lazka0:/ql-stable/openSUSE_42.1/
4 | repo-non-oss | openSUSE-leap/42.1-Non-Oss | Yes | (r ) Yes | Yes | http://download.opensuse.org/distribution/leap/42.1/repo/non-oss/
5 | repo-oss | openSUSE-leap/42.1-Oss | Yes | (r ) Yes | Yes | http://download.opensuse.org/distribution/leap/42.1/repo/oss/
6 | repo-update | openSUSE-42.1-Update | Yes | (r ) Yes | Yes | http://download.opensuse.org/update/leap/42.1/oss/
7 | repo-update-non-oss | openSUSE-42.1-Update-Non-Oss | Yes | (r ) Yes | Yes | http://download.opensuse.org/update/leap/42.1/non-oss/
```
List Repositories by priority.
```
# zypper lr -p
# | Alias | Name | Enabled | GPG Check | Refresh | Priority
--+-----------------------+-----------------------------------------------------+---------+-----------+---------+---------
1 | packman-repository | packman-repository | Yes | (r ) Yes | Yes | 99
2 | google-chrome | google-chrome | Yes | (r ) Yes | Yes | 99
3 | home_lazka0_ql-stable | Stable Quod Libet / Ex Falso Builds (openSUSE_42.1) | Yes | (r ) Yes | No | 99
4 | repo-non-oss | openSUSE-leap/42.1-Non-Oss | Yes | (r ) Yes | Yes | 99
5 | repo-oss | openSUSE-leap/42.1-Oss | Yes | (r ) Yes | Yes | 99
6 | repo-update | openSUSE-42.1-Update | Yes | (r ) Yes | Yes | 99
7 | repo-update-non-oss | openSUSE-42.1-Update-Non-Oss | Yes | (r ) Yes | Yes | 99
```
### How To List The Enabled Repositories on ArchLinux
Arch Linux based systems are using pacman package manager hence we can use the pacman Package Manager to get this information.
pacman stands for package manager utility (pacman). pacman is a command-line utility to install, build, remove and manage Arch Linux packages. pacman uses libalpm (Arch Linux Package Management (ALPM) library) as a back-end to perform all the actions.
**Suggested Read :** [Pacman Command To Manage Packages On Arch Linux Based Systems][13]
```
# pacman -Syy
:: Synchronizing package databases...
core 132.6 KiB 1524K/s 00:00 [############################################] 100%
extra 1859.0 KiB 750K/s 00:02 [############################################] 100%
community 3.5 MiB 149K/s 00:24 [############################################] 100%
multilib 182.7 KiB 1363K/s 00:00 [############################################] 100%
```
### How To List The Enabled Repositories on Linux using INXI Utility
inxi is a nifty tool to check hardware information on Linux and offers wide range of option to get all the hardware information on Linux system that i never found in any other utility which are available in Linux. It was forked from the ancient and mindbendingly perverse yet ingenius infobash, by locsmif.
inxi is a script that quickly shows system hardware, CPU, drivers, Xorg, Desktop, Kernel, GCC version(s), Processes, RAM usage, and a wide variety of other useful information, also used for forum technical support & debugging tool.
Additionally this utility will display all the distribution repository data information such as RHEL, CentOS, Fedora, Debain, Ubuntu, LinuxMint, ArchLinux, openSUSE, Manjaro, etc.,
**Suggested Read :** [inxi A Great Tool to Check Hardware Information on Linux][14]
```
# inxi -r
Repos: Active apt sources in file: /etc/apt/sources.list
deb http://in.archive.ubuntu.com/ubuntu/ yakkety main restricted
deb http://in.archive.ubuntu.com/ubuntu/ yakkety-updates main restricted
deb http://in.archive.ubuntu.com/ubuntu/ yakkety universe
deb http://in.archive.ubuntu.com/ubuntu/ yakkety-updates universe
deb http://in.archive.ubuntu.com/ubuntu/ yakkety multiverse
deb http://in.archive.ubuntu.com/ubuntu/ yakkety-updates multiverse
deb http://in.archive.ubuntu.com/ubuntu/ yakkety-backports main restricted universe multiverse
deb http://security.ubuntu.com/ubuntu yakkety-security main restricted
deb http://security.ubuntu.com/ubuntu yakkety-security universe
deb http://security.ubuntu.com/ubuntu yakkety-security multiverse
Active apt sources in file: /etc/apt/sources.list.d/arc-theme.list
deb http://download.opensuse.org/repositories/home:/Horst3180/xUbuntu_16.04/ /
Active apt sources in file: /etc/apt/sources.list.d/snwh-ubuntu-pulp-yakkety.list
deb http://ppa.launchpad.net/snwh/pulp/ubuntu yakkety main
```
--------------------------------------------------------------------------------
via: https://www.2daygeek.com/how-to-list-the-enabled-active-repositories-in-linux/
作者:[Prakash Subramanian][a]
选题:[lujun9972][b]
译者:[译者ID](https://github.com/译者ID)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://www.2daygeek.com/author/prakash/
[b]: https://github.com/lujun9972
[1]: https://www.2daygeek.com/how-to-add-enable-disable-a-repository-dnf-yum-config-manager-on-linux/
[2]: https://www.2daygeek.com/how-to-list-installed-packages-by-size-largest-on-linux/
[3]: https://www.2daygeek.com/how-to-view-list-the-available-packages-updates-in-linux/
[4]: https://www.2daygeek.com/how-to-view-a-particular-package-installed-updated-upgraded-removed-erased-date-on-linux/
[5]: https://www.2daygeek.com/how-to-view-detailed-information-about-a-package-in-linux/
[6]: https://www.2daygeek.com/how-to-search-if-a-package-is-available-on-your-linux-distribution-or-not/
[7]: https://www.2daygeek.com/how-to-list-an-available-package-groups-in-linux/
[8]: https://www.2daygeek.com/list-of-graphical-frontend-tool-for-linux-package-manager/
[9]: https://www.2daygeek.com/list-of-command-line-package-manager-for-linux/
[10]: https://www.2daygeek.com/yum-command-examples-manage-packages-rhel-centos-systems/
[11]: https://www.2daygeek.com/dnf-command-examples-manage-packages-fedora-system/
[12]: https://www.2daygeek.com/zypper-command-examples-manage-packages-opensuse-system/
[13]: https://www.2daygeek.com/pacman-command-examples-manage-packages-arch-linux-system/
[14]: https://www.2daygeek.com/inxi-system-hardware-information-on-linux/

View File

@@ -0,0 +1,257 @@
Exploring the Linux kernel: The secrets of Kconfig/kbuild
======
Dive into understanding how the Linux config/build system works.
![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/compass_map_explore_adventure.jpg?itok=ecCoVTrZ)
The Linux kernel config/build system, also known as Kconfig/kbuild, has been around for a long time, ever since the Linux kernel code migrated to Git. As supporting infrastructure, however, it is seldom in the spotlight; even kernel developers who use it in their daily work never really think about it.
To explore how the Linux kernel is compiled, this article will dive into the Kconfig/kbuild internal process, explain how the .config file and the vmlinux/bzImage files are produced, and introduce a smart trick for dependency tracking.
### Kconfig
The first step in building a kernel is always configuration. Kconfig helps make the Linux kernel highly modular and customizable. Kconfig offers the user many config targets:
| config | Update current config utilizing a line-oriented program |
| nconfig | Update current config utilizing a ncurses menu-based program |
| menuconfig | Update current config utilizing a menu-based program |
| xconfig | Update current config utilizing a Qt-based frontend |
| gconfig | Update current config utilizing a GTK+ based frontend |
| oldconfig | Update current config utilizing a provided .config as base |
| localmodconfig | Update current config disabling modules not loaded |
| localyesconfig | Update current config converting local mods to core |
| defconfig | New config with default from Arch-supplied defconfig |
| savedefconfig | Save current config as ./defconfig (minimal config) |
| allnoconfig | New config where all options are answered with 'no' |
| allyesconfig | New config where all options are accepted with 'yes' |
| allmodconfig | New config selecting modules when possible |
| alldefconfig | New config with all symbols set to default |
| randconfig | New config with a random answer to all options |
| listnewconfig | List new options |
| olddefconfig | Same as oldconfig but sets new symbols to their default value without prompting |
| kvmconfig | Enable additional options for KVM guest kernel support |
| xenconfig | Enable additional options for xen dom0 and guest kernel support |
| tinyconfig | Configure the tiniest possible kernel |
I think **menuconfig** is the most popular of these targets. The targets are processed by different host programs, which are provided by the kernel and built during kernel building. Some targets have a GUI (for the user's convenience) while most don't. Kconfig-related tools and source code reside mainly under **scripts/kconfig/** in the kernel source. As we can see from **scripts/kconfig/Makefile** , there are several host programs, including **conf** , **mconf** , and **nconf**. Except for **conf** , each of them is responsible for one of the GUI-based config targets, so, **conf** deals with most of them.
Logically, Kconfig's infrastructure has two parts: one implements a [new language][1] to define the configuration items (see the Kconfig files under the kernel source), and the other parses the Kconfig language and deals with configuration actions.
Most of the config targets have roughly the same internal process (shown below):
![](https://opensource.com/sites/default/files/uploads/kconfig_process.png)
Note that all configuration items have a default value.
The first step reads the Kconfig file under source root to construct an initial configuration database; then it updates the initial database by reading an existing configuration file according to this priority:
> .config
> /lib/modules/$(shell,uname -r)/.config
> /etc/kernel-config
> /boot/config-$(shell,uname -r)
> ARCH_DEFCONFIG
> arch/$(ARCH)/defconfig
If you are doing GUI-based configuration via **menuconfig** or command-line-based configuration via **oldconfig** , the database is updated according to your customization. Finally, the configuration database is dumped into the .config file.
But the .config file is not the final fodder for kernel building; this is why the **syncconfig** target exists. **syncconfig** used to be a config target called **silentoldconfig** , but it doesn't do what the old name says, so it was renamed. Also, because it is for internal use (not for users), it was dropped from the list.
Here is an illustration of what **syncconfig** does:
![](https://opensource.com/sites/default/files/uploads/syncconfig.png)
**syncconfig** takes .config as input and outputs many other files, which fall into three categories:
* **auto.conf & tristate.conf** are used for makefile text processing. For example, you may see statements like this in a component's makefile:
```
obj-$(CONFIG_GENERIC_CALIBRATE_DELAY) += calibrate.o
```
* **autoconf.h** is used in C-language source files.
* Empty header files under **include/config/** are used for configuration-dependency tracking during kbuild, which is explained below.
After configuration, we will know which files and code pieces are not compiled.
### kbuild
Component-wise building, called _recursive make_ , is a common way for GNU `make` to manage a large project. Kbuild is a good example of recursive make. By dividing source files into different modules/components, each component is managed by its own makefile. When you start building, a top makefile invokes each component's makefile in the proper order, builds the components, and collects them into the final executive.
Kbuild refers to different kinds of makefiles:
* **Makefile** is the top makefile located in source root.
* **.config** is the kernel configuration file.
* **arch/$(ARCH)/Makefile** is the arch makefile, which is the supplement to the top makefile.
* **scripts/Makefile.*** describes common rules for all kbuild makefiles.
* Finally, there are about 500 **kbuild makefiles**.
The top makefile includes the arch makefile, reads the .config file, descends into subdirectories, invokes **make** on each component's makefile with the help of routines defined in **scripts/Makefile.*** , builds up each intermediate object, and links all the intermediate objects into vmlinux. Kernel document [Documentation/kbuild/makefiles.txt][2] describes all aspects of these makefiles.
As an example, let's look at how vmlinux is produced on x86-64:
![vmlinux overview][4]
(The illustration is based on Richard Y. Steven's [blog][5]. It was updated and is used with the author's permission.)
All the **.o** files that go into vmlinux first go into their own **built-in.a** , which is indicated via variables **KBUILD_VMLINUX_INIT** , **KBUILD_VMLINUX_MAIN** , **KBUILD_VMLINUX_LIBS** , then are collected into the vmlinux file.
Take a look at how recursive make is implemented in the Linux kernel, with the help of simplified makefile code:
```
# In top Makefile
vmlinux: scripts/link-vmlinux.sh $(vmlinux-deps)
                +$(call if_changed,link-vmlinux)
# Variable assignments
vmlinux-deps := $(KBUILD_LDS) $(KBUILD_VMLINUX_INIT) $(KBUILD_VMLINUX_MAIN) $(KBUILD_VMLINUX_LIBS)
export KBUILD_VMLINUX_INIT := $(head-y) $(init-y)
export KBUILD_VMLINUX_MAIN := $(core-y) $(libs-y2) $(drivers-y) $(net-y) $(virt-y)
export KBUILD_VMLINUX_LIBS := $(libs-y1)
export KBUILD_LDS          := arch/$(SRCARCH)/kernel/vmlinux.lds
init-y          := init/
drivers-y       := drivers/ sound/ firmware/
net-y           := net/
libs-y          := lib/
core-y          := usr/
virt-y          := virt/
# Transform to corresponding built-in.a
init-y          := $(patsubst %/, %/built-in.a, $(init-y))
core-y          := $(patsubst %/, %/built-in.a, $(core-y))
drivers-y       := $(patsubst %/, %/built-in.a, $(drivers-y))
net-y           := $(patsubst %/, %/built-in.a, $(net-y))
libs-y1         := $(patsubst %/, %/lib.a, $(libs-y))
libs-y2         := $(patsubst %/, %/built-in.a, $(filter-out %.a, $(libs-y)))
virt-y          := $(patsubst %/, %/built-in.a, $(virt-y))
# Setup the dependency. vmlinux-deps are all intermediate objects, vmlinux-dirs
# are phony targets, so every time comes to this rule, the recipe of vmlinux-dirs
# will be executed. Refer "4.6 Phony Targets" of `info make`
$(sort $(vmlinux-deps)): $(vmlinux-dirs) ;
# Variable vmlinux-dirs is the directory part of each built-in.a
vmlinux-dirs    := $(patsubst %/,%,$(filter %/, $(init-y) $(init-m) \
                     $(core-y) $(core-m) $(drivers-y) $(drivers-m) \
                     $(net-y) $(net-m) $(libs-y) $(libs-m) $(virt-y)))
# The entry of recursive make
$(vmlinux-dirs):
                $(Q)$(MAKE) $(build)=$@ need-builtin=1
```
The recursive make recipe is expanded, for example:
```
make -f scripts/Makefile.build obj=init need-builtin=1
```
This means **make** will go into **scripts/Makefile.build** to continue the work of building each **built-in.a**. With the help of **scripts/link-vmlinux.sh** , the vmlinux file is finally under source root.
#### Understanding vmlinux vs. bzImage
Many Linux kernel developers may not be clear about the relationship between vmlinux and bzImage. For example, here is their relationship in x86-64:
![](https://opensource.com/sites/default/files/uploads/vmlinux-bzimage.png)
The source root vmlinux is stripped, compressed, put into **piggy.S** , then linked with other peer objects into **arch/x86/boot/compressed/vmlinux**. Meanwhile, a file called setup.bin is produced under **arch/x86/boot**. There may be an optional third file that has relocation info, depending on the configuration of **CONFIG_X86_NEED_RELOCS**.
A host program called **build** , provided by the kernel, builds these two (or three) parts into the final bzImage file.
#### Dependency tracking
Kbuild tracks three kinds of dependencies:
1. All prerequisite files (both * **.c** and * **.h** )
2. **CONFIG_** options used in all prerequisite files
3. Command-line dependencies used to compile the target
The first one is easy to understand, but what about the second and third? Kernel developers often see code pieces like this:
```
#ifdef CONFIG_SMP
__boot_cpu_id = cpu;
#endif
```
When **CONFIG_SMP** changes, this piece of code should be recompiled. The command line for compiling a source file also matters, because different command lines may result in different object files.
When a **.c** file uses a header file via a **#include** directive, you need write a rule like this:
```
main.o: defs.h
        recipe...
```
When managing a large project, you need a lot of these kinds of rules; writing them all would be tedious and boring. Fortunately, most modern C compilers can write these rules for you by looking at the **#include** lines in the source file. For the GNU Compiler Collection (GCC), it is just a matter of adding a command-line parameter: **-MD depfile**
```
# In scripts/Makefile.lib
c_flags        = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE)     \
                 -include $(srctree)/include/linux/compiler_types.h       \
                 $(__c_flags) $(modkern_cflags)                           \
                 $(basename_flags) $(modname_flags)
```
This would generate a **.d** file with content like:
```
init_task.o: init/init_task.c include/linux/kconfig.h \
 include/generated/autoconf.h include/linux/init_task.h \
 include/linux/rcupdate.h include/linux/types.h \
 ...
```
Then the host program **[fixdep][6]** takes care of the other two dependencies by taking the **depfile** and command line as input, then outputting a **. <target>.cmd** file in makefile syntax, which records the command line and all the prerequisites (including the configuration) for a target. It looks like this:
```
# The command line used to compile the target
cmd_init/init_task.o := gcc -Wp,-MD,init/.init_task.o.d  -nostdinc ...
...
# The dependency files
deps_init/init_task.o := \
$(wildcard include/config/posix/timers.h) \
$(wildcard include/config/arch/task/struct/on/stack.h) \
$(wildcard include/config/thread/info/in/task.h) \
...
  include/uapi/linux/types.h \
  arch/x86/include/uapi/asm/types.h \
  include/uapi/asm-generic/types.h \
  ...
```
A **. <target>.cmd** file will be included during recursive make, providing all the dependency info and helping to decide whether to rebuild a target or not.
The secret behind this is that **fixdep** will parse the **depfile** ( **.d** file), then parse all the dependency files inside, search the text for all the **CONFIG_** strings, convert them to the corresponding empty header file, and add them to the target's prerequisites. Every time the configuration changes, the corresponding empty header file will be updated, too, so kbuild can detect that change and rebuild the target that depends on it. Because the command line is also recorded, it is easy to compare the last and current compiling parameters.
### Looking ahead
Kconfig/kbuild remained the same for a long time until the new maintainer, Masahiro Yamada, joined in early 2017, and now kbuild is under active development again. Don't be surprised if you soon see something different from what's in this article.
--------------------------------------------------------------------------------
via: https://opensource.com/article/18/10/kbuild-and-kconfig
作者:[Cao Jin][a]
选题:[lujun9972][b]
译者:[译者ID](https://github.com/译者ID)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://opensource.com/users/pinocchio
[b]: https://github.com/lujun9972
[1]: https://github.com/torvalds/linux/blob/master/Documentation/kbuild/kconfig-language.txt
[2]: https://www.mjmwired.net/kernel/Documentation/kbuild/makefiles.txt
[3]: https://opensource.com/file/411516
[4]: https://opensource.com/sites/default/files/uploads/vmlinux_generation_process.png (vmlinux overview)
[5]: https://blog.csdn.net/richardysteven/article/details/52502734
[6]: https://github.com/torvalds/linux/blob/master/scripts/basic/fixdep.c

View File

@@ -0,0 +1,87 @@
The First Beta of Haiku is Released After 16 Years of Development
======
There are a number of small operating systems out there that are designed to replicate the past. Haiku is one of those. We will look to see where Haiku came from and what the new release has to offer.
![Haiku OS desktop screenshot][1]Haiku desktop
### What is Haiku?
Haikus history begins with the now defunct [Be Inc][2]. Be Inc was founded by former Apple executive [Jean-Louis Gassée][3] after he was ousted by CEO [John Sculley][4]. Gassée wanted to create a new operating system from the ground up. BeOS was created with digital media work in mind and was designed to take advantage of the most modern hardware of the time. Originally, Be Inc attempted to create their own platform encompassing both hardware and software. The result was called the [BeBox][5]. After BeBox failed to sell well, Be turned their attention to BeOS.
In the 1990s, Apple was looking for a new operating system to replace the aging Classic Mac OS. The two contenders were Gassées BeOS and Steve Jobs NeXTSTEP. In the end, Apple went with NeXTSTEP. Be tried to license BeOS to hardware makers, but [in at least one case][6] Microsoft threatened to revoke a manufacturers Windows license if they sold BeOS machines. Eventually, Be Inc was sold to Palm in 2001 for $11 million. BeOS was subsequently discontinued.
Following the news of Palms purchase, a number of loyal fans decided they wanted to keep the operating system alive. The original name of the project was OpenBeOS, but was changed to Haiku to avoid infringing on Palms trademarks. The name is a reference to reference to the [haikus][7] used as error messages by many of the applications. Haiku is completely written from scratch and is compatible with BeOS.
### Why Haiku?
According to the projects website, [Haiku][8] “is a fast, efficient, simple to use, easy to learn, and yet very powerful system for computer users of all levels”. Haiku comes with a kernel that have been customized for performance. Like FreeBSD, there is a “single team writing everything from the kernel, drivers, userland services, toolkit, and graphics stack to the included desktop applications and preflets”.
### New Features in Haiku Beta Release
A number of new features have been introduced since the release of Alpha 4.1. (Please note that Haiku is a passion project and all the devs are part-time, so some they cant spend as much time working on Haiku as they would like.)
![Haiku OS software][9]
HaikuDepot, Haikus package manager
One of the biggest features is the inclusion of a complete package management system. HaikuDepot allows you to sort through many applications. Many are built specifically for Haiku, but a number have been ported to the platform, such as [LibreOffice][10], [Otter Browser][11], and [Calligra][12]. Interestingly, each Haiku package is [“a special type of compressed filesystem image, which is mounted upon installation”][13]. There is also a command line interface for package management named `pkgman`.
Another big feature is an upgraded browser. Haiku was able to hire a developer to work full-time for a year to improve the performance of WebPositive, the built-in browser. This included an update to a newer version of WebKit. WebPositive will now play Youtube videos properly.
![Haiku OS WebPositive browser][14]
WebPositive, Haikus built-in browser
Other features include:
* A completely rewritten network preflet
* User interface cleanup
* Media subsystem improvements, including better streaming support, HDA driver improvements, and FFmpeg decoder plugin improvements
* Native RemoteDesktop improved
* Add EFI bootloader and GPT support
* Updated Ethernet & WiFi drivers
* Updated filesystem drivers
* General system stabilization
* Experimental Bluetooth stack
### Thoughts on Haiku OS
I have been following Haiku for many years. Ive installed and played with the nightly builds a dozen times over the last couple of years. I even took some time to start learning one of its programming languages, so that I could write apps. But I got busy with other things.
Im very conflicted about it. I like Haiku because it is a neat non-Linux project, but it is only just getting features that everyone else takes for granted, like a package manager.
If youve got a couple of minutes, download the [ISO][15] and install it on the virtual machine of your choice. You just might like it.
Have you ever used Haiku or BeOS? If so, what are your favorite features? Let us know in the comments below.
If you found this article interesting, please take a minute to share it on social media, Hacker News or [Reddit][16].
--------------------------------------------------------------------------------
via: https://itsfoss.com/haiku-os-release/
作者:[John Paul][a]
选题:[lujun9972][b]
译者:[译者ID](https://github.com/译者ID)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://itsfoss.com/author/john/
[b]: https://github.com/lujun9972
[1]: https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2018/10/haiku.jpg
[2]: https://en.wikipedia.org/wiki/Be_Inc.
[3]: https://en.wikipedia.org/wiki/Jean-Louis_Gass%C3%A9e
[4]: https://en.wikipedia.org/wiki/John_Sculley
[5]: https://en.wikipedia.org/wiki/BeBox
[6]: https://birdhouse.org/beos/byte/30-bootloader/
[7]: https://en.wikipedia.org/wiki/Haiku
[8]: https://www.haiku-os.org/about/
[9]: https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2018/10/haiku-depot.png
[10]: https://www.libreoffice.org/
[11]: https://itsfoss.com/otter-browser-review/
[12]: https://www.calligra.org/
[13]: https://www.haiku-os.org/get-haiku/release-notes/
[14]: https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2018/10/webpositive.jpg
[15]: https://www.haiku-os.org/get-haiku
[16]: http://reddit.com/r/linuxusersgroup

View File

@@ -0,0 +1,118 @@
Command line quick tips: Reading files different ways
======
![](https://fedoramagazine.org/wp-content/uploads/2018/10/commandlinequicktips-816x345.jpg)
Fedora is delightful to use as a graphical operating system. You can point and click your way through just about any task easily. But youve probably seen there is a powerful command line under the hood. To try it out in a shell, just open the Terminal application in your Fedora system. This article is one in a series that will show you some common command line utilities.
In this installment youll learn how to read files in different ways. If you open a Terminal to do some work on your system, chances are good that youll need to read a file or two.
### The whole enchilada
The **cat** command is well known to terminal users. When you **cat** a file, youre simply displaying the whole file to the screen. Really whats happening under the hood is the file is read one line at a time, then each line is written to the screen.
Imagine you have a file with one word per line, called myfile. To make this clear, the file will contain the word equivalent for a number on each line, like this:
```
one
two
three
four
five
```
So if you **cat** that file, youll see this output:
```
$ cat myfile
one
two
three
four
five
```
Nothing too surprising there, right? But heres an interesting twist. You can also **cat** that file backward. For this, use the **tac** command. (Note that Fedora takes no blame for this debatable humor!)
```
$ tac myfile
five
four
three
two
one
```
The **cat** file also lets you ornament the file in different ways, in case thats helpful. For instance, you can number lines:
```
$ cat -n myfile
1 one
2 two
3 three
4 four
5 five
```
There are additional options that will show special characters and other features. To learn more, run the command **man cat** , and when done just hit **q** to exit back to the shell.
### Picking over your food
Often a file is too long to fit on a screen, and you may want to be able to go through it like a document. In that case, try the **less** command:
```
$ less myfile
```
You can use your arrow keys as well as **PgUp/PgDn** to move around the file. Again, you can use the **q** key to quit back to the shell.
Theres actually a **more** command too, based on an older UNIX command. If its important to you to still see the file when youre done, you might want to use it. The **less** command brings you back to the shell the way you left it, and clears the display of any sign of the file you looked at.
### Just the appetizer (or dessert)
Sometimes the output you want is just the beginning of a file. For instance, the file might be so long that when you **cat** the whole thing, the first few lines scroll past before you can see them. The **head** command will help you grab just those lines:
```
$ head -n 2 myfile
one
two
```
In the same way, you can use **tail** to just grab the end of a file:
```
$ tail -n 3 myfile
three
four
five
```
Of course these are only a few simple commands in this area. But theyll get you started when it comes to reading files.
--------------------------------------------------------------------------------
via: https://fedoramagazine.org/commandline-quick-tips-reading-files-different-ways/
作者:[Paul W. Frields][a]
选题:[lujun9972][b]
译者:[译者ID](https://github.com/译者ID)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://fedoramagazine.org/author/pfrields/
[b]: https://github.com/lujun9972

View File

@@ -0,0 +1,58 @@
Happy birthday, KDE: 11 applications you never knew existed
======
Which fun or quirky app do you need today?
![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/BIZ_DebucketizeOrgChart_A.png?itok=RB3WBeQQ)
The Linux desktop environment KDE celebrates its 22nd anniversary on October 14 this year. There are a gazillion* applications created by the KDE community of users, many of which provide fun and quirky services. We perused the list and picked out 11 applications you might like to know exist.
*Not really, but [there are a lot][1].
### 11 KDE applications you never knew existed
1\. [KTeaTime][2] is a timer for steeping tea. Set it by choosing the type of tea you are drinking—green, black, herbal, etc.—and the timer will ding when it's ready to remove the tea bag and drink.
2\. [KTux][3] is just a screensaver... or is it? Tux is flying in outer space in his green spaceship.
3\. [Blinken][4] is a memory game based on Simon Says, an electronic game released in 1978. Players are challenged to remember sequences of increasing length.
4\. [Tellico][5] is a collection manager for organizing your favorite hobby. Maybe you still collect baseball cards. Maybe you're part of a wine club. Maybe you're a serious bookworm. Maybe all three!
5\. [KRecipes][6] is **not** a simple recipe manager. It's got a lot going on! Shopping lists, nutrient analysis, advanced search, recipe ratings, import/export various formats, and more.
6\. [KHangMan][7] is based on the classic game Hangman where you guess the word letter by letter. This game is available in several languages, and it can be used to improve your learning of another language. It has four categories, one of which is "animals" which is great for kids.
7\. [KLettres][8] is another app that may help you learn a new language. It teaches the alphabet and challenges the user to read and pronounce syllables.
8\. [KDiamond][9] is similar to Bejeweled or other single player puzzle games where the goal of the game is to build lines of a certain number of the same type of jewel or object. In this case, diamonds.
9\. [KolourPaint][10] is a very simple editing tool for your images or app for creating simple vectors.
10\. [Kiriki][11] is a dice game for 2-6 players similar to Yahtzee.
11\. [RSIBreak][12] doesn't start with a K. What!? It starts with an "RSI" for "Repetitive Strain Injury," which can occur from working for long hours, day in and day out, with a mouse and keyboard. This app reminds you to take breaks and can be personalized to meet your needs.
--------------------------------------------------------------------------------
via: https://opensource.com/article/18/10/kde-applications
作者:[Opensource.com][a]
选题:[lujun9972][b]
译者:[译者ID](https://github.com/译者ID)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://opensource.com
[b]: https://github.com/lujun9972
[1]: https://www.kde.org/applications/
[2]: https://www.kde.org/applications/games/kteatime/
[3]: https://userbase.kde.org/KTux
[4]: https://www.kde.org/applications/education/blinken
[5]: http://tellico-project.org/
[6]: https://www.kde.org/applications/utilities/krecipes/
[7]: https://edu.kde.org/khangman/
[8]: https://edu.kde.org/klettres/
[9]: https://games.kde.org/game.php?game=kdiamond
[10]: https://www.kde.org/applications/graphics/kolourpaint/
[11]: https://www.kde.org/applications/games/kiriki/
[12]: https://userbase.kde.org/RSIBreak

View File

@@ -0,0 +1,129 @@
How To Lock Virtual Console Sessions On Linux
======
![](https://www.ostechnix.com/wp-content/uploads/2018/10/vlock-720x340.png)
When youre working on a shared system, you might not want the other users to sneak peak in your console to know what youre actually doing. If so, I know a simple trick to lock your own session while still allowing other users to use the system on other virtual consoles. Thanks to **Vlock** , stands for **V** irtual Console **lock** , a command line program to lock one or more sessions on the Linux console. If necessary, you can lock the entire console and disable the virtual console switching functionality altogether. Vlock is especially useful for the shared Linux systems which have multiple users with access to the console.
### Installing Vlock
On Arch-based systems, the Vlock package is replaced with **kpd** package which is preinstalled by default, so you need not to bother with installation.
On Debian, Ubuntu, Linux Mint, run the following command to install Vlock:
```
$ sudo apt-get install vlock
```
On Fedora:
```
$ sudo dnf install vlock
```
On RHEL, CentOS:
```
$ sudo yum install vlock
```
### Lock Virtual Console Sessions On Linux
The general syntax for Vlock is:
```
vlock [ -acnshv ] [ -t <timeout> ] [ plugins... ]
```
Where,
* **a** Lock all virtual console sessions,
* **c** Lock current virtual console session,
* **n** Switch to new empty console before locking all sessions,
* **s** Disable SysRq key mechanism,
* **t** Specify the timeout for the screensaver plugins,
* **h** Display help section,
* **v** Display version.
Let me show you some examples.
**1\. Lock current console session**
When running Vlock without any arguments, it locks the current console session (TYY) by default. To unlock the session, you need to enter either the current users password or the root password.
```
$ vlock
```
![](https://www.ostechnix.com/wp-content/uploads/2018/10/vlock-1-1.gif)
You can also use **-c** flag to lock the current console session.
```
$ vlock -c
```
Please note that this command will only lock the current console. You can switch to other consoles by pressing **ALT+F2**. For more details about switching between TTYs, refer the following guide.
Also, if the system has multiple users, the other users can still access their respective TTYs.
**2\. Lock all console sessions**
To lock all TTYs at the same time and also disable the virtual console switching functionality, run:
```
$ vlock -a
```
Again, to unlock the console sessions, just press ENTER key and type your current users password or root user password.
Please keep in mind that the **root user can always unlock any vlock session** at any time, unless disabled at compile time.
**3. Switch to new virtual console before locking all consoles
**
It is also possible to make Vlock to switch to new empty virtual console from X session before locking all consoles. To do so, use **-n** flag.
```
$ vlock -n
```
**4. Disable SysRq mechanism
**
As you may know, the Magic SysRq key mechanism allows the users to perform some operations when the system freeze. So the users can unlock the consoles using SysRq. In order to prevent this, pass the **-s** option to disable SysRq mechanism. Please remember, this only works if the **-a** option is given.
```
$ vlock -sa
```
For more options and its usage, refer the help section or the man pages.
```
$ vlock -h
$ man vlock
```
Vlock prevents the unauthorized users from gaining the console access. If youre looking for a simple console locking mechanism to your Linux machine, Vlock is worth checking!
And, thats all for now. Hope this was useful. More good stuffs to come. Stay tuned!
Cheers!
--------------------------------------------------------------------------------
via: https://www.ostechnix.com/how-to-lock-virtual-console-sessions-on-linux/
作者:[SK][a]
选题:[lujun9972][b]
译者:[译者ID](https://github.com/译者ID)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://www.ostechnix.com/author/sk/
[b]: https://github.com/lujun9972

View File

@@ -0,0 +1,74 @@
How to Install GRUB on Arch Linux (UEFI)
======
![](http://fasterland.net/wp-content/uploads/2018/10/Arch-Linux-Boot-Menu-750x375.jpg)
Some time ago, I wrote a tutorial on **[how to reinstall Grub][1] on Arch Linux after installing Windows.**
A few weeks ago, I had to reinstall **Arch Linux** from scratch on my laptop and I discovered installing **Grub** was not as straightforward as I remembered.
For this reason, Im going to write this tutorial since **installing Grub on a UEFI bios** during a new **Arch Linux** installation its not too easy.
### Locating the EFI partition
The first important thing to do for installing **Grub** on **Arch Linux** is to locate the **EFI** partition.
Lets run the following command in order to locate this partition:
```
# fdisk -l
```
We need to check the partition marked as **EFI System
**In my case is **/dev/sda2**
After that, we need to mount this partition, for example, on /boot/efi:
```
# mkdir /boot/efi
# mount /dev/sdb2 /boot/efi
```
Another important thing to do is adding this partition into the **/etc/fstab** file.
#### Installing Grub
Now we can install Grub in our system:
```
# grub-mkconfig -o /boot/grub/grub.cfg
# grub-install --target=x86_64-efi --efi-directory=/boot/efi --bootloader-id=GRUB
```
#### Adding Windows Automatically into the Grub Menu
In order to automatically add the **Windows entry into the Grub menu** , we need to install the **os-prober** program:
```
# pacman -Sy os-prober
```
In order to add the entry item lets run the following commands:
```
# os-prober
# grub-mkconfig -o /boot/grub/grub.cfg
# grub-install --target=x86_64-efi --efi-directory=/boot/efi --bootloader-id=GRUB
```
You can find more about Grub on Arch Linux [here][2].
--------------------------------------------------------------------------------
via: http://fasterland.net/how-to-install-grub-on-arch-linux-uefi.html
作者:[Francesco Mondello][a]
选题:[lujun9972][b]
译者:[译者ID](https://github.com/译者ID)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: http://fasterland.net/
[b]: https://github.com/lujun9972
[1]: http://fasterland.net/reinstall-grub-arch-linux.html
[2]: https://wiki.archlinux.org/index.php/GRUB

View File

@@ -0,0 +1,66 @@
9 个方法,提升开发者与设计师之间的协作
======
![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/BUS_consensuscollab1.png?itok=ULQdGjlV)
本文由我与 [Jason Porter][1] 共同完成。
在任何软件项目中,设计至关重要。设计师不像开发团队那样熟悉其内部工作,但迟早都要知道开发人员写代码的意图。
两边都有自己的成见。工程师经常认为设计师们古怪不理性,而设计师也认为工程师们死板要求高。在一天的工作快要结束时,情况会变得更加微妙。设计师和开发者们的命运永远交织在一起。
做到以下九件事,便可以增强他们之间的合作
### 1\. 首先,说实在的,打破壁垒。
几乎每一个行业都有“<ruby>迷惑之墙<rt>wall of confusion</rt></ruby>”的模子。无论你干什么工作,拆除这堵墙的第一步就是要双方都认同它需要拆除。一旦所有的人都认为现有的流程效率低下,你就可以从其他想法中获得灵感,然后解决问题。
### 2\. 学会共情
在撸起袖子开始干之前,休息一下。这是团队建设的重要的交汇点。一个时机去认识到:我们都是成人,我们都有自己的优点与缺点,更重要的是,我们是一个团队。围绕工作流程与工作效率的讨论会经常发生,因此在开始之前,建立一个信任与协作的基础至关重要。
### 3\. 认识差异
设计师和开发者从不同的角度攻克问题。对于相同的问题,设计师会追求更好的效果,而开发者会寻求更高的效率。这两种观点不必互相排斥。谈判和妥协的余地很大,并且在二者之间必然存在一个用户满意度最佳的中点。
### 4\. 拥抱共性
这一切都是与工作流程相关的。<ruby>持续集成<rt>Continuous Integration</rt></ruby>/<ruby>持续交付<rt>Continuous Delivery</rt></ruby>scrumagille 等等,都基本上说了一件事:构思,迭代,考察,重复。迭代和重复是两种工作的相同点。因此,不再让开发周期紧跟设计周期,而是同时并行地运行它们,这样会更有意义。<ruby>同步周期<rt>Syncing cycles</rt></ruby>允许团队在每一步上交流、协作、互相影响。
### 5\. 管理期望
一切冲突的起因一言以蔽之:期望不符。因此,防止系统性分裂的简单办法就是通过确保团队成员在说之前先想、在做之前先说来管理期望。设定的期望往往会通过日常对话不断演变。强迫团队通过开会以达到其效果可能会适得其反。
### 6\. 按需开会
只在工作开始和工作结束开一次会远远不够。但也不意味着每天或每周都要开会。定期开会也可能会适得其反。试着按需开会吧。即兴会议可能会发生很棒的事情,即使是在开水房。如果你的团队是分散式的或者甚至有一名远程员工,视频会议,文本聊天或者打电话都是开会的好方法。团队中的每人都有多种方式互相沟通,这一点非常重要。
### 7\. 建立词库
设计师和开发者有时候对相似的想法有着不同的术语,就像把猫叫了个咪。毕竟,所有人都用的惯比起术语的准确度和适应度更重要。
### 8\. 学会沟通
无论什么时候,团队中的每个人都有责任去维持一个有效的沟通。每个人都应该努力做到一字一板。
### 9\. 不断改善
仅一名团队成员就能破坏整个进度。全力以赴。如果每个人都不关心产品或目标,继续项目或者做出改变的动机就会出现问题。
本文参考 [Designers and developers: Finding common ground for effective collaboration][2],演讲的作者将会出席在旧金山五月 8-10 号举办的[Red Hat Summit 2018][3]。[五月 7 号][3]注册将节省 500 美元。支付时使用优惠码 **OPEN18** 以获得更多折扣。
--------------------------------------------------------------------------------
via: https://opensource.com/article/18/5/9-ways-improve-collaboration-developers-designers
作者:[Jason Brock][a]
选题:[lujun9972](https://github.com/lujun9972)
译者:[LuuMing](https://github.com/LuuMing)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://opensource.com/users/jkbrock
[1]:https://opensource.com/users/lightguardjp
[2]:https://agenda.summit.redhat.com/SessionDetail.aspx?id=154267
[3]:https://www.redhat.com/en/summit/2018

View File

@@ -0,0 +1,131 @@
Linux vs Mac: Linux 比 Mac 好的七个原因
======
最近我们谈论了一些[为什么 Linux 比 Windows 好][1]的原因。毫无疑问, Linux 是个非常优秀的平台。但是它和其他的操作系统一样也会有缺点。对于某些专门的领域,像是游戏, Windows 当然更好。 而对于视频编辑等任务, Mac 系统可能更为方便。这一切都取决于你的爱好,以及你想用你的系统做些什么。在这篇文章中,我们将会介绍一些 Linux 相对于 Mac 更好的一些地方。
如果你已经在用 Mac 或者打算买一台 Mac 电脑,我们建议你仔细考虑一下,看看是改为使用 Linux 还是继续使用 Mac 。
### Linux 比 Mac 好的 7 个原因
![Linux vs Mac: 为什么 Linux 更好][2]
Linux 和 macOS 都是类 Unix 操作系统,并且都支持 Unix 命令行、 bash 和其他一些命令行工具,相比于 Windows ,他们所支持的应用和游戏比较少。但缺点也仅仅如此。
平面设计师和视频剪辑师更加倾向于使用 Mac 系统,而 Linux 更加适合做开发、系统管理、运维的工程师。
那要不要使用 Linux 呢,为什么要选择 Linux 呢?下面是根据实际经验和理性分析给出的一些建议。
#### 1\. 价格
![Linux vs Mac: 为什么 Linux 更好][3]
假设你只是需要浏览文件、看电影、下载图片、写文档、制作报表或者做一些类似的工作,并且你想要一个更加安全的系统。
那在这种情况下,你觉得花费几百块买个系统完成这项工作,或者花费更多直接买个 Macbook 划算吗?当然,最终的决定权还是在你。
买个装好 Mac 系统的电脑还是买个便宜的电脑,然后自己装上免费的 Linux 系统这个要看你自己的偏好。就我个人而言除了音视频剪辑创作之外Linux 都非常好地用,而对于音视频方面,我更倾向于使用 Final Cut Pro (专业的视频编辑软件) 和 Logic Pro X (专业的音乐制作软件)(这两款软件都是苹果公司推出的)。
#### 2\. 硬件支持
![Linux vs Mac: 为什么 Linux 更好][4]
Linux 支持多种平台. 无论你的电脑配置如何,你都可以在上面安装 Linux无论性能好或者差Linux 都可以运行。[即使你的电脑已经使用很久了, 你仍然可以通过选择安装合适的发行版让 Linux 在你的电脑上流畅的运行][5].
而 Mac 不同,它是苹果机专用系统。如果你希望买个便宜的电脑,然后自己装上 Mac 系统,这几乎是不可能的。一般来说 Mac 都是和苹果设备连在一起的。
这是[在非苹果系统上安装 Mac OS 的教程][6]. 这里面需要用到的专业技术以及可能遇到的一些问题将会花费你许多时间,你需要想好这样做是否值得。
总之Linux 所支持的硬件平台很广泛,而 MacOS 相对而言则非常少。
#### 3\. 安全性
![Linux vs Mac: 为什么 Linux 更好][7]
很多人都说 ios 和 Mac 是非常安全的平台。的确,相比于 Windows ,它确实比较安全,可并不一定有 Linux 安全。
我不是在危言耸听。 Mac 系统上也有不少恶意软件和广告,并且[数量与日俱增][8]。我认识一些不太懂技术的用户 使用着非常缓慢的 Mac 电脑并且为此苦苦挣扎。一项快速调查显示[浏览器恶意劫持软件][9]是罪魁祸首.
从来没有绝对安全的操作系统Linux 也不例外。 Linux 也有漏洞,但是 Linux 发行版提供的及时更新弥补了这些漏洞。另外,到目前为止在 Linux 上还没有自动运行的病毒或浏览器劫持恶意软件的案例发生。
这可能也是一个你应该选择 Linux 而不是 Mac 的原因。
#### 4\. 可定制性与灵活性
![Linux vs Mac: 为什么 Linux 更好][10]
如果你有不喜欢的东西,自己定制或者修改它都行。
举个例子,如果你不喜欢 Ubuntu 18.04.1 的 [Gnome 桌面环境][11],你可以换成 [KDE Plasma][11]。 你也可以尝试一些 [Gnome 扩展][12]丰富你的桌面选择。这种灵活性和可定制性在 Mac OS 是不可能有的。
除此之外你还可以根据需要修改一些操作系统的代码(但是可能需要一些专业知识)以创造出适合你的系统。这个在 Mac OS 上可以做吗?
另外你可以根据需要从一系列的 Linux 发行版进行选择。比如说,如果你想喜欢 Mac OS上的工作流 [Elementary OS][13] 可能是个不错的选择。你想在你的旧电脑上装上一个轻量级的 Linux 发行版系统吗?这里是一个[轻量级 Linux 发行版列表][5]。相比较而言, Mac OS 缺乏这种灵活性。
#### 5\. 使用 Linux 有助于你的职业生涯 [针对 IT 行业和科学领域的学生]
![Linux vs Mac: 为什么 Linux 更好][14]
对于 IT 领域的学生和求职者而言,这是有争议的但是也是有一定的帮助的。使用 Linux 并不会让你成为一个优秀的人,也不一定能让你得到任何与 IT 相关的工作。
但是当你开始使用 Linux 并且开始探索如何使用的时候,你将会获得非常多的经验。作为一名技术人员,你迟早会接触终端,学习通过命令行实现文件系统管理以及应用程序安装。你可能不会知道这些都是一些 IT 公司的新职员需要培训的内容。
除此之外Linux 在就业市场上还有很大的发展空间。 Linux 相关的技术有很多( Cloud 、 Kubernetes 、Sysadmin 等),您可以学习,获得证书并获得一份相关的高薪的工作。要学习这些,你必须使用 Linux 。
#### 6\. 可靠
![Linux vs Mac: 为什么 Linux 更好][15]
想想为什么服务器上用的都是 Linux 系统,当然是因为它可靠。
但是它为什么可靠呢,相比于 Mac OS ,它的可靠体现在什么方面呢?
答案很简单——给用户更多的控制权,同时提供更好的安全性。在 Mac OS 上,你并不能完全控制它,这样做是为了让操作变得更容易,同时提高你的用户体验。使用 Linux ,你可以做任何你想做的事情——这可能会导致(对某些人来说)糟糕的用户体验——但它确实使其更可靠。
#### 7\. 开源
![Linux vs Mac: 为什么 Linux 更好][16]
开源并不是每个人都关心的。但对我来说Linux 最重要的优势在于它的开源特性。下面讨论的大多数观点都是开源软件的直接优势。
简单解释一下,如果是开源软件,你可以自己查看或者修改它。但对 Mac 来说,苹果拥有独家控制权。即使你有足够的技术知识,也无法查看 Mac OS 的源代码。
形象点说Mac 驱动的系统可以让你得到一辆车,但缺点是你不能打开引擎盖看里面是什么。那可能非常糟糕!
如果你想深入了解开源软件的优势,可以在 OpenSource.com 上浏览一下 [Ben Balter 的文章][17]。
### 总结
现在你应该知道为什么 Linux 比 Mac 好了吧,你觉得呢?上面的这些原因可以说服你选择 Linux 吗?如果不行的话那又是为什么呢?
在下方评论让我们知道你的想法。
Note: 这里的图片是以企鹅俱乐部为原型的。
--------------------------------------------------------------------------------
via: https://itsfoss.com/linux-vs-mac/
作者:[Ankush Das][a]
选题:[lujun9972](https://github.com/lujun9972)
译者:[Ryze-Borgia](https://github.com/Ryze-Borgia)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://itsfoss.com/author/ankush/
[1]: https://itsfoss.com/linux-better-than-windows/
[2]: https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2018/09/Linux-vs-mac-featured.png
[3]: https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2018/09/linux-vs-mac-1.jpeg
[4]: https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2018/09/linux-vs-mac-4.jpeg
[5]: https://itsfoss.com/lightweight-linux-beginners/
[6]: https://hackintosh.com/
[7]: https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2018/09/linux-vs-mac-2.jpeg
[8]: https://www.computerworld.com/article/3262225/apple-mac/warning-as-mac-malware-exploits-climb-270.html
[9]: https://www.imore.com/how-to-remove-browser-hijack
[10]: https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2018/09/linux-vs-mac-3.jpeg
[11]: https://www.gnome.org/
[12]: https://itsfoss.com/best-gnome-extensions/
[13]: https://elementary.io/
[14]: https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2018/09/linux-vs-mac-5.jpeg
[15]: https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2018/09/linux-vs-mac-6.jpeg
[16]: https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2018/09/linux-vs-mac-7.jpeg
[17]: https://opensource.com/life/15/12/why-open-source

View File

@@ -0,0 +1,171 @@
如何在 Linux 下锁住键盘和鼠标而不锁屏
======
![](https://www.ostechnix.com/wp-content/uploads/2017/09/Lock-The-Keyboard-And-Mouse-720x340.jpg)
我四岁的侄女是个好奇的孩子,她非常喜爱“阿凡达”电影,当阿凡达电影在播放时,她是如此的专注,好似眼睛粘在了屏幕上。但问题是当她观看电影时,她经常会碰到键盘上的某个键或者移动了鼠标,又或者是点击了鼠标的按钮。有时她非常意外地按了键盘上的某个键,从而将电影关闭或者暂停了。所以我就想找个方法来将键盘和鼠标都锁住,但屏幕不会被锁住。幸运的是,我在 Ubuntu 论坛上找到了一个完美的解决方法。假如在你正看着屏幕上的某些重要的事情时,你不想让你的小猫或者小狗在你的键盘上行走,或者让你的孩子在键盘上瞎搞一气,那我建议你试试 **xtrlock** 这个工具。它很简单但非常实用,你可以锁定屏幕的显示直到用户在键盘上输入自己设定的密码(译者注:就是用户自己的密码,例如用来打开屏保的那个密码,不需要单独设定)。在这篇简单的教程中,我将为你展示如何在 Linux 下锁住键盘和鼠标,而不锁掉屏幕。这个技巧几乎可以在所有的 Linux 操作系统中生效。
### 安装 xtrlock
xtrlock 软件包在大多数 Linux 操作系统的默认软件仓库中都可以获取到。所以你可以使用你安装的发行版的包管理器来安装它。
**Arch Linux** 及其衍生发行版中,运行下面的命令来安装它:
```
$ sudo pacman -S xtrlock
```
**Fedora** 上使用:
```
$ sudo dnf install xtrlock
```
**RHEL, CentOS** 上使用:
```
$ sudo yum install xtrlock
```
**SUSE/openSUSE** 上使用:
```
$ sudo zypper install xtrlock
```
**Debian, Ubuntu, Linux Mint** 上使用:
```
$ sudo apt-get install xtrlock
```
### 使用 xtrlock 锁住键盘和鼠标但不锁屏
安装好 xtrlock 后,你需要根据你的选择来创建一个快捷键,通过这个快捷键来锁住键盘和鼠标。
**/usr/local/bin** 目录下创建一个名为 **lockkbmouse** 的新文件:
```
$ sudo vi /usr/local/bin/lockkbmouse
```
然后将下面的命令添加到这个文件中:
```
#!/bin/bash
sleep 1 && xtrlock
```
保存并关闭这个文件。
然后使用下面的命令来使得它可以被执行:
```
$ sudo chmod a+x /usr/local/bin/lockkbmouse
```
接着,我们就需要创建快捷键了。
**在 Arch Linux MATE 桌面中**
依次点击 **System -> Preferences -> Hardware -> keyboard Shortcuts**
然后点击 **Add** 来创建快捷键。
![][2]
首先键入你的这个快捷键的名称,然后将下面的命令填入命令框中,最后点击 **Apply** 按钮。
```
bash -c "sleep 1 && xtrlock"
```
![][3]
为了能够给这个快捷键赋予快捷方式,需要选中它或者双击它然后输入你选定的快捷键组合,例如我使用 **Alt+k** 这组快捷键。
![][4]
如果要清除这个快捷键组合,按住 `BACKSPACE` 键就可以了。完成后,关闭键盘设定窗口。
**在 Ubuntu GNOME 桌面中**
依次进入 **System Settings -> Devices -> Keyboard**,然后点击 **+** 这个符号。
键入你快捷键的名称并将下面的命令加到命令框里面,然后点击 **Add** 按钮。
```
bash -c "sleep 1 && xtrlock"
```
![][5]
接下来为这个新建的快捷键赋予快捷方式。我们只需要选择或者双击 **“Set shortcut”** 这个按钮就可以了。
![][6]
然后你将看到下面的一屏。
![][7]
输入你选定的快捷键组合,例如我使用 **Alt+k**
![][8]
如果要清除这个快捷键组合,则可以按 `BACKSPACE` 这个键。这样快捷键便设定好了,完成这个后,关闭键盘设定窗口。
从现在起,每当你输入刚才设定的快捷键(在我们的示例中是 `ATL+K`),鼠标的指针便会变成一个挂锁的模样。现在,键盘和鼠标便被锁定了,这时你便可以自在地观看你的电影或者做其他你想做的事儿。即便是你的孩子或者宠物碰了键盘上的某些键或者点击了鼠标,这些操作都不会起作用。
因为 `xtrlock` 已经在工作了。
![][9]
你看到了那个小的锁按钮了吗?它意味着键盘和鼠标已经被锁定了。即便你移动这个锁按钮,也不会发生任何事情。后台的任务在一直执行,直到你将屏幕解除,然后手动停掉运行中的任务。
### 将键盘和鼠标解锁
要将键盘和鼠标解锁只需要输入你的密码然后敲击“Enter”键就可以了在输入的过程中你将看不到密码。只需要输入然后敲 `ENTER` 键就可以了。在你输入了正确的密码后,鼠标和键盘就可以再工作了。假如你输入了一个错误的密码,你将听到警告声。按 **ESC** 来清除输入的错误密码,然后重新输入正确的密码。要去掉未完全输入完的密码中的一个字符,只需要按 **BACKSPACE** 或者 **DELETE** 键就可以了。
### 要是我被永久地锁住了怎么办?
以防你被永久地锁定了屏幕,切换至一个 TTY例如 CTRL+ALT+F2然后运行
```
$ sudo killall xtrlock
```
或者你还可以使用 **chvt** 命令来在 TTY 和 X 会话之间切换。
例如,如果要切换到 TTY1则运行
```
$ sudo chvt 1
```
要切换回 X 会话,则键入:
```
$ sudo chvt 7
```
不同的发行版使用了不同的快捷键组合来在不同的 TTY 间切换。请参考你安装的对应发行版的官方网站了解更多详情。
如果想知道更多 xtrlock 的信息,请参考 man 页:
```
$ man xtrlock
```
那么这就是全部了。希望这个指南可以帮到你。假如你发现这个指南很有用请花点时间将这个指南共享到你的朋友圈并支持我们OSTechNix
**资源:**
* [**Ubuntu 论坛**][10]
--------------------------------------------------------------------------------
via: https://www.ostechnix.com/lock-keyboard-mouse-not-screen-linux/
作者:[SK][a]
选题:[lujun9972](https://github.com/lujun9972)
译者:[FSSlc](https://github.com/FSSlc)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://www.ostechnix.com/author/sk/
[1]:data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7
[2]:http://www.ostechnix.com/wp-content/uploads/2017/09/Keyboard-Shortcuts_001.png
[3]:http://www.ostechnix.com/wp-content/uploads/2017/09/Keyboard-Shortcuts_002.png
[4]:http://www.ostechnix.com/wp-content/uploads/2017/09/Keyboard-Shortcuts_003.png
[5]:http://www.ostechnix.com/wp-content/uploads/2018/01/Add-xtrlock-shortcut.png
[6]:http://www.ostechnix.com/wp-content/uploads/2018/01/set-shortcut-key-1.png
[7]:http://www.ostechnix.com/wp-content/uploads/2018/01/set-shortcut-key-2.png
[8]:http://www.ostechnix.com/wp-content/uploads/2018/01/set-shortcut-key-3.png
[9]:http://www.ostechnix.com/wp-content/uploads/2018/01/xtrlock-1.png
[10]:https://ubuntuforums.org/showthread.php?t=993800

View File

@@ -1,173 +0,0 @@
提交你的第一个 Linux 内核补丁时的一个检查列表
======
![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/linux_penguin_green.png?itok=ENdVzW22)
Linux 内核是最大的且变动最快的开源项目之一,它由大约 53,600 个文件和近 2,000 万行代码组成。在全世界范围内超过 15,600 位程序员为它贡献代码Linux 内核项目的维护者使用了如下的协作模型。
![](https://opensource.com/sites/default/files/karnik_figure1.png)
本文中,为了便于在 Linux 内核中提交你的第一个贡献,我将为你提供一个必需的快速检查列表,以告诉你在提交补丁时,应该去查看和了解的内容。对于你贡献的第一个补丁的提交流程方面的更多内容,请阅读 [KernelNewbies 第一个内核补丁教程][1]。
### 为内核作贡献
#### 第 1 步:准备你的系统
本文开始之前,假设你的系统已经具备了如下的工具:
+ 文本编辑器
+ Email 客户端
+ 版本控制系统git
#### 第 2 步:下载 Linux 内核代码仓库:
```
git clone -b staging-testing
git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging.git
```
### 复制你的当前配置:
```
cp /boot/config-`uname -r`* .config
```
### 第 3 步:构建/安装你的内核
```
make -jX
sudo make modules_install install
```
### 第 4 步:创建一个分支并切换到它
```
git checkout -b first-patch
```
### 第 5 步:更新你的内核并指向到最新的代码
```
git fetch origin
git rebase origin/staging-testing
```
### 第 6 步:在最新的代码基础上产生一个变更
使用 `make` 命令重新编译,确保你的变更没有错误。
### 第 7 步:提交你的变更并创建一个补丁
```
git add <file>
git commit -s -v
git format-patch -o /tmp/ HEAD^
```
![](https://opensource.com/sites/default/files/karnik_figure2.png)
主题是由冒号分隔的文件名组成,接下来是使用祈使语态来描述补丁做了什么。空行之后是强制规定的 `off` 标记,最后是你的补丁的 `diff` 信息。
下面是另外一个简单补丁的示例:
![](https://opensource.com/sites/default/files/karnik_figure3.png)
接下来,[使用 email 从命令行][2](在本例子中使用的是 Mutt发送这个补丁
```
mutt -H /tmp/0001-<whatever your filename is>
```
使用 [get_maintainer.pl 脚本][11],去了解你的补丁应该发送给哪位维护者的列表。
### 提交你的第一个补丁之前,你应该知道的事情
* [Greg Kroah-Hartman](3) 的 [staging tree][4] 是提交你的 [第一个补丁][1] 的最好的地方,因为他更容易接受新贡献者的补丁。在你熟悉了补丁发送流程以后,你就可以去发送复杂度更高的子系统专用的补丁。
* 你也可以从纠正代码中的编码风格开始。想学习更多关于这方面的内容,请阅读 [Linux 内核编码风格文档][5]。
* [checkpatch.pl][6] 脚本可以检测你的编码风格方面的错误。例如,运行如下的命令:
```
perl scripts/checkpatch.pl -f drivers/staging/android/* | less
```
* 你可以去补全开发者留下的 TODO 注释中未完成的内容:
```
find drivers/staging -name TODO
```
* [Coccinelle][7] 是一个模式匹配的有用工具。
* 阅读 [归档的内核邮件][8]。
* 为找到灵感,你可以去遍历 [linux.git log][9] 查看以前的作者的提交内容。
* 注意:不要为了评估你的补丁而在社区置顶帖子!下面就是一个这样的例子:
**错误的方式:**
Chris,
_Yes lets schedule the meeting tomorrow, on the second floor._
> On Fri, Apr 26, 2013 at 9:25 AM, Chris wrote:
> Hey John, I had some questions:
> 1\. Do you want to schedule the meeting tomorrow?
> 2\. On which floor in the office?
> 3\. What time is suitable to you?
(注意那最后一个问题,在回复中无意中落下了。)
**正确的方式:**
Chris,
See my answers below...
> On Fri, Apr 26, 2013 at 9:25 AM, Chris wrote:
> Hey John, I had some questions:
> 1\. Do you want to schedule the meeting tomorrow?
_Yes tomorrow is fine._
> 2\. On which floor in the office?
_Let's keep it on the second floor._
> 3\. What time is suitable to you?
_09:00 am would be alright._
(所有问题全部回复,并且这种方式还保存了阅读的时间。)
* [Eudyptula challenge][10] 是学习内核基础知识的非常好的方式。
想学习更多内容,阅读 [KernelNewbies 第一个内核补丁教程][1]。之后如果你还有任何问题,可以在 [kernelnewbies 邮件列表][12] 或者 [#kernelnewbies IRC channel][13] 中提问。
--------------------------------------------------------------------------------
via: https://opensource.com/article/18/8/first-linux-kernel-patch
作者:[Sayli Karnik][a]
选题:[lujun9972](https://github.com/lujun9972)
译者:[qhwdw](https://github.com/qhwdw)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://opensource.com/users/sayli
[1]:https://kernelnewbies.org/FirstKernelPatch
[2]:https://opensource.com/life/15/8/top-4-open-source-command-line-email-clients
[3]:https://twitter.com/gregkh
[4]:https://www.kernel.org/doc/html/v4.15/process/2.Process.html
[5]:https://www.kernel.org/doc/html/v4.10/process/coding-style.html
[6]:https://github.com/torvalds/linux/blob/master/scripts/checkpatch.pl
[7]:http://coccinelle.lip6.fr/
[8]:linux-kernel@vger.kernel.org
[9]:https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/log/
[10]:http://eudyptula-challenge.org/
[11]:https://github.com/torvalds/linux/blob/master/scripts/get_maintainer.pl
[12]:https://kernelnewbies.org/MailingList
[13]:https://kernelnewbies.org/IRC

View File

@@ -1,139 +0,0 @@
我应该使用哪些稳定版内核?
======
很多人都问我这样的问题,在他们的产品/设备/笔记本/服务器等上面应该使用什么样的稳定版内核。一直以来,尤其是那些现在已经延长支持时间的内核,都是由我和其他人提供支持,因此,给出这个问题的答案并不是件容易的事情。因此这篇文章我将尝试去给出我在这个问题上的看法。当然,你可以任意选用任何一个你想去使用的内核版本,这里只是我的建议。
和以前一样,在这里给出的这些看法只代表我个人的意见。
### 可选择的内核有哪些
下面列出了我建议你应该去使用的内核的列表,从最好的到最差的都有。我在下面将详细介绍,但是如果你只想得到一个结论,它就是你想要的:
建议你使用的内核的分级,从最佳的方案到最差的方案如下:
* 你最喜欢的 Linux 发行版支持的内核
* 最新的稳定版
* 最新的 LTS 发行版
* 仍然处于维护状态的老的 LTS 发行版
绝对不要去使用的内核:
* 不再维护的内核发行版
给上面的列表给出具体的数字,今天是 2018 年 8 月 24 日kernel.org 页面上可以看到是这样:
![][1]
因此,基于上面的列表,那它应该是:
* 4.18.5 是最新的稳定版
* 4.14.67 是最新的 LTS 发行版
* 4.9.124、4.4.152、以及 3.16.57 是仍然处于维护状态的老的 LTS 发行版
* 4.17.19 和 3.18.119 是过去 60 天内 “生命周期终止” 的内核版本,它们仍然保留在 kernel.org 站点上,是为了仍然想去使用它们的那些人。
非常容易,对吗?
Ok现在我给出这样选择的一些理由
### Linux 发行版内核
对于大多数 Linux 用户来说,最好的方案就是使用你喜欢的 Linux 发行版的内核。就我本人而言,我比较喜欢基于社区的、内核不断滚动升级的用最新内核的 Linux 发行版,并且它也是由开发者社区来支持的。这种类型的发行版有 Fedora、openSUSE、Arch、Gentoo、CoreOS、以及其它的。
所有这些发行版都使用了上游的最新的稳定版内核,并且确保定期打了需要的 bug 修复补丁。当它拥有了最新的修复之后([记住所有的修复都是安全修复][2]),这就是你可以使用的最安全、最好的内核之一。
有些社区的 Linux 发行版需要很长的时间才发行一个新内核的发行版但是最终发行的版本和所支持的内核都是非常好的。这些也都非常好用Debian 和 Ubuntu 就是这样的例子。
我没有在这里列出你所喜欢的发行版,并不是意味着它们的内核不够好。查看这些发行版的网站,确保它们的内核包是不断应用最新的安全补丁进行升级过的,那么它就应该是很好的。
许多人好像喜欢旧的、“传统” 模式的发行版,以及使用 RHEL、SLES、CentOS 或者 “LTS” Ubuntu 发行版。这些发行版挑选一个特定的内核版本,然后使用好几年,而不是几十年。他们移植了最新的 bug 修复,有时也有一些内核的新特性,所有的只是追求堂吉诃德式的保持版本号不变而已,尽管他们已经在那个旧的内核版本上做了成千上万的变更。这其实是一个吃力不讨好的工作,开发者分配去做这些任务,看上去做的很不错,其实就是为了实现这些目标。如果你从来没有看到你的内核版本号发生过变化,而仍然在使用这些发行版。他们通常会为使用而付出一些成本,当发生错误时能够从这些公司得到一些支持,那就是值得的。
所以,你能使用的最好的内核是你可以求助于别人,而别人可以为你提供支持的内核。使用那些支持,你通常都已经为它支付过费用了(对于企业发行版),而这些公司也知道他们职责是什么。
但是,如果你不希望去依赖别人,而是希望你自己管理你的内核,或者你有发行版不支持的硬件,那么你应该去使用最新的稳定版:
### 最新的稳定版
最新的稳定版内核是 Linux 内核开发者社区宣布为“稳定版”的最新的一个内核。大约每三个月,社区发行一个包含了对所有新硬件支持的、新的稳定版内核,最新版的内核不但改善内核性能,同时还包含内核各部分的 bug 修复。再经过三个月之后,进入到下一个内核版本的 bug 修复将被移植进入这个稳定版内核中,因此,使用这个内核版本的用户将确保立即得到这些修复。
最新的稳定版内核通常也是主流社区发行版使用的较好的内核,因此你可以确保它是经过测试和拥有大量用户使用的内核。另外,内核社区(全部开发者超过 4000 人)也将帮助这个发行版提供对用户的支持,因为这是他们做的最新的一个内核。
三个月之后,将发行一个新的稳定版内核,你应该去更新到它以确保你的内核始终是最新的稳定版,当最新的稳定版内核发布之后,对你的当前稳定版内核的支持通常会落后几周时间。
如果你在上一个 LTS 版本发布之后购买了最新的硬件,为了能够支持最新的硬件,你几乎是绝对需要去运行这个最新的稳定版内核。对于台式机或新的服务器,它们通常需要运行在它们推荐的内核版本上。
### 最新的 LTS 发行版
如果你的硬件为了保证正常运行(像大多数的嵌入式设备),需要依赖供应商的源码树外的补丁,那么对你来说,最好的内核版本是最新的 LTS 发行版。这个发行版拥有所有进入稳定版内核的最新 bug 修复,以及大量的用户测试和使用。
请注意,这个最新的 LTS 发行版没有新特性,并且也几乎不会增加对新硬件的支持,因此,如果你需要使用一个新设备,那你的最佳选择就是最新的稳定版内核,而不是最新的 LTS 版内核。
另外,对于这个 LTS 发行版内核的用户来说,他也不用担心每三个月一次的“重大”升级。因此,他们将一直坚持使用这个 LTS 内核发行版,并每年升级一次,这是一个很好的实践。
使用这个 LTS 发行版的不利方面是,你没法得到在最新版本内核上实现的内核性能提升,除非在未来的一年中,你升级到下一个 LTS 版内核。
另外,如果你使用的这个内核版本有问题,你所做的第一件事情就是向任意一位内核开发者报告发生的问题,并向他们询问,“最新的稳定版内核中是否也存在这个问题?”并且,你将意识到,对它的支持不会像使用最新的稳定版内核那样容易得到。
现在,如果你坚持使用一个有大量的补丁集的内核,并且不希望升级到每年一次的新 LTS 内核版本上,那么,或许你应该去使用老的 LTS 发行版内核:
### 老的 LTS 发行版
这些发行版传统上都由社区提供 2 年时间的支持,有时候当一个重要的 Linux 发行版(像 Debian 或 SLES 一样)依赖它时,这个支持时间会更长。然而在过去一年里,感谢 Google、Linaro、Linaro 成员公司、[kernelci.org][3]、以及其它公司在测试和基础设施上的大量投入,使得这些老的 LTS 发行版内核得到更长时间的支持。
这是最新的 LTS 发行版,它们将被支持多长时间,这是 2018 年 8 月 24 日显示在 [kernel.org/category/releases.html][4] 上的信息:
![][5]
Google 和其它公司希望这些内核使用的时间更长的原因是,由于现在几乎所有的 SoC 芯片的疯狂(也有人说是打破常规)的开发模型。这些设备在芯片发行前几年就启动了他们的开发生命周期,而那些代码从来不会合并到上游,最终结果是始终在一个分支中,新的芯片基于一个 2 年以前的老内核发布。这些 SoC 的代码树通常增加了超过 200 万行的代码,这使得它们成为我们前面称之为“类 Linux 内核“的东西。
如果在 2 年后,这个 LTS 发行版停止支持,那么来自社区的支持将立即停止,并且没有人对它再进行 bug 修复。这导致了在全球各地数以百万计的不安全设备仍然在使用中,这对任何生态系统来说都不是什么好事情。
由于这种依赖,这些公司现在要求新设备不断更新到最新的 LTS 发行版,而这些特定的发行版(即每个 4.9.y 发行版)就是为它们发行的。其中一个这样的例子就是新 Android 设备对内核版本的要求,这些新设备的 “O” 版本和现在的 “P” 版本指定了最低允许使用的内核版本,并且在设备上越来越频繁升级的、安全的 Android 发行版开始要求使用这些 “.y” 发行版。
我注意到一些生产商现在已经在做这些事情。Sony 是其中一个非常好的例子,在他们的大多数新手机上,通过他们每季度的安全发行版,将设备更新到最新的 4.4.y 发行版上。另一个很好的例子是一家小型公司 Essential他们持续跟踪 4.4.y 发行版,据我所知,他们发布新版本的速度比其它公司都快。
当使用这种很老的内核时有个重大警告。移植到这种内核中的 bug 修复比起最新版本的 LTS 内核来说数量少很多,因为这些使用很老的 LTS 内核的传统设备型号要远少于现在的用户使用的型号。如果你打算将它们用在有不可信的用户或虚拟机的地方,那么这些内核将不再被用于任何”通用计算“的模型中,因为对于这些内核不会去做像最近的 Spectre 这样的修复,如果在一些分支中存在这样的 bug那么将极大地降低安全性。
因此,仅当在你能够完全控制的设备中使用老的 LTS 发行版,或者是使用在有一个非常强大的安全模型(像 Android 一样强制使用 SELinux 和应用程序隔离)去限制的情况下。绝对不要在有不可信用户、程序、或虚拟机的服务器上使用这些老的 LTS 发行版内核。
此外,如果社区对它有支持的话,社区对这些老的 LTS 内核发行版相比正常的 LTS 内核发行版的支持要少的多。如果你使用这些内核,那么你只能是一个人在战斗,你需要有能力去独自支持这些内核,或者依赖你的 SoC 供应商为你提供支持(需要注意的是,对于大部分供应商来说是不会为你提供支持的,因此,你要特别注意 …)。
### 不再维护的内核发行版
更让人感到惊讶的事情是,许多公司只是随便选一个内核发行版,然后将它封装到它们的产品里,并将它毫不犹豫地承载到数十万的部件中。其中一个这样的糟糕例子是 Lego Mindstorm 系统,不知道是什么原因在它们的设备上随意选取了一个 `-rc` 的内核发行版。`-rc` 的发行版是开发中的版本Linux 内核开发者认为它根本就不适合任何人使用,更不用说是数百万的用户了。
当然,如果你愿意,你可以随意地使用它,但是需要注意的是,可能真的就只有你一个人在使用它。社区不会为你提供支持,因为他们不可能关注所有内核版本的特定问题,因此如果出现错误,你只能独自去解决它。对于一些公司和系统来说,这么做可能还行,但是如果没有为此有所规划,那么要当心因此而产生的”隐性“成本。
### 总结
基于以上原因,下面是一个针对不同类型设备的简短列表,这些设备我推荐适用的内核如下:
* 笔记本 / 台式机:最新的稳定版内核
* 服务器:最新的稳定版内核或最新的 LTS 版内核
* 嵌入式设备:最新的 LTS 版内核或老的 LTS 版内核(如果使用的安全模型非常强大和严格)
至于我,在我的机器上运行什么样的内核?我的笔记本运行的是最新的开发版内核(即 Linus 的开发树)再加上我正在做修改的内核,我的服务器上运行的是最新的稳定版内核。因此,尽管我负责 LTS 发行版的支持工作,但我自己并不使用 LTS 版内核,除了在测试系统上。我依赖于开发版和最新的稳定版内核,以确保我的机器运行的是目前我们所知道的最快的也是最安全的内核版本。
--------------------------------------------------------------------------------
via: http://kroah.com/log/blog/2018/08/24/what-stable-kernel-should-i-use/
作者:[Greg Kroah-Hartman][a]
选题:[lujun9972](https://github.com/lujun9972)
译者:[qhwdw](https://github.com/qhwdw)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:http://kroah.com
[1]:https://s3.amazonaws.com/kroah.com/images/kernel.org_2018_08_24.png
[2]:http://kroah.com/log/blog/2018/02/05/linux-kernel-release-model/
[3]:https://kernelci.org/
[4]:https://www.kernel.org/category/releases.html
[5]:https://s3.amazonaws.com/kroah.com/images/kernel.org_releases_2018_08_24.png

View File

@@ -0,0 +1,88 @@
如何在救援(单用户模式)/紧急模式下启动 Ubuntu 18.04/Debian 9 服务器
======
将 Linux 服务器引导到单用户模式或**救援模式**是 Linux 管理员在关键时刻恢复服务器时通常使用的重要故障排除方法之一。在 Ubuntu 18.04 和 Debian 9 中,单用户模式被称为救援模式。
除了救援模式外Linux 服务器可以在**紧急模式**下启动,它们之间的主要区别在于,紧急模式加载了带有只读根文件系统文件系统的最小环境,也没有启用任何网络或其他服务。但救援模式尝试挂载所有本地文件系统并尝试启动一些重要的服务,包括网络。
在本文中,我们将讨论如何在救援模式和紧急模式下启动 Ubuntu 18.04 LTS/Debian 9 服务器。
#### 在单用户/救援模式下启动 Ubuntu 18.04 LTS 服务器:
重启服务器并进入启动加载程序 Grub 屏幕并选择 “**Ubuntu**”,启动加载器页面如下所示,
![](https://www.linuxtechi.com/wp-content/uploads/2018/09/Bootloader-Screen-Ubuntu18-04-Server.jpg)
按下 “**e**”,然后移动到以 “**linux**” 开头的行尾,并添加 “**systemd.unit=rescue.target**”。如果存在单词 “**$vt_handoff**” 就删除它。
![](https://www.linuxtechi.com/wp-content/uploads/2018/09/rescue-target-ubuntu18-04.jpg)
现在按 Ctrl-x 或 F10 启动,
![](https://www.linuxtechi.com/wp-content/uploads/2018/09/rescue-mode-ubuntu18-04.jpg)
现在按回车键,然后你将得到所有文件系统都以读写模式挂载的 shell 并进行故障排除。完成故障排除后,可以使用 “**reboot**” 命令重新启动服务器。
#### 在紧急模式下启动 Ubuntu 18.04 LTS 服务器
重启服务器并进入启动加载程序页面并选择 “**Ubuntu**”,然后按 “**e**” 并移动到以 linux 开头的行尾,并添加 “**systemd.unit=emergency.target**“。
![](https://www.linuxtechi.com/wp-content/uploads/2018/09/Emergecny-target-ubuntu18-04-server.jpg)
现在按 Ctlr-x 或 F10 以紧急模式启动,你将获得一个 shell 并从那里进行故障排除。正如我们已经讨论过的那样,在紧急模式下,文件系统将以只读模式挂载,并且在这种模式下也不会有网络,
![](https://www.linuxtechi.com/wp-content/uploads/2018/09/Emergency-prompt-debian9.jpg)
使用以下命令将根文件系统挂载到读写模式,
```
# mount -o remount,rw /
```
同样,你可以在读写模式下重新挂载其余文件系统。
#### 将 Debian 9 引导到救援和紧急模式
重启 Debian 9.x 服务器并进入 grub页面选择 “**Debian GNU/Linux**”。
![](https://www.linuxtechi.com/wp-content/uploads/2018/09/Debian9-Grub-Screen.jpg)
按下 “**e**” 并移动到 linux 开头的行尾并添加 “**systemd.unit=rescue.target**” 以在救援模式下启动系统, 要在紧急模式下启动,那就添加 “**systemd.unit=emergency.target**“
#### 救援模式:
![](https://www.linuxtechi.com/wp-content/uploads/2018/09/Rescue-mode-Debian9.jpg)
现在按 Ctrl-x 或 F10 以救援模式启动
![](https://www.linuxtechi.com/wp-content/uploads/2018/09/Rescue-Mode-Shell-Debian9.jpg)
按下回车键以获取 shell然后从这里开始故障排除。
#### 紧急模式:
![](https://www.linuxtechi.com/wp-content/uploads/2018/09/Emergency-target-grub-debian9.jpg)
现在按下 ctrl-x 或 F10 以紧急模式启动系统
![](https://www.linuxtechi.com/wp-content/uploads/2018/09/Emergency-prompt-debian9.jpg)
按下回车获取 shell 并使用 “**mount -o remount,rw /**” 命令以读写模式挂载根文件系统。
**注意:**如果已经在 Ubuntu 18.04 和 Debian 9 Server 中设置了 root 密码,那么你必须输入 root 密码才能在救援和紧急模式下获得 shell
就是这些了,如果您喜欢这篇文章,请分享你的反馈和评论。
--------------------------------------------------------------------------------
via: https://www.linuxtechi.com/boot-ubuntu-18-04-debian-9-rescue-emergency-mode/
作者:[Pradeep Kumar][a]
选题:[lujun9972](https://github.com/lujun9972)
译者:[geekpi](https://github.com/geekpi)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: http://www.linuxtechi.com/author/pradeep/

View File

@@ -0,0 +1,155 @@
如何在双系统引导下替换 Linux 发行版
======
在双系统引导的状态下,你可以将已安装的 Linux 发行版替换为另一个发行版,同时还可以保留原本的个人数据。
![How to Replace One Linux Distribution With Another From Dual Boot][1]
假设你的电脑上已经[以双系统的形式安装了 Ubuntu 和 Windows][2],但经过[将 Linux Mint 与 Ubuntu 比较][3]之后,你又觉得 [Linux Mint][4] 会更适合自己的时候,你会怎样做?又该如何在[删除 Ubuntu][5] 的同时[在双系统中安装 Mint][6] 呢?
你或许觉得应该首先从在双系统中卸载 [Ubuntu][7],然后使用 Linux Mint 重新安装成双系统。但实际上并不需要这么麻烦。
如果你已经在双系统引导中安装了一种 Linux 发行版,就可以轻松替换成另一个发行版了,而且也不必卸载已有的 Linux 发行版,只需要删除其所在的分区,然后在腾出的磁盘空间上安装另一个 Linux 发行版就可以了。
与此同时,更换 Linux 发行版后,仍然会保留原本 home 目录中包含所有文件。
下面就来详细介绍一下。
### 在双系统引导中替换 Linux 发行版
<https://youtu.be/ptF2RUehbKs>
这是我的演示范例。我使用双系统引导同时安装了 Windows 10 和 Linux Mint 19然后我会把 Linux Mint 19 替换成 Elementary OS 5同时在替换后保留我的个人文件包括音乐、图片、视频和 home 目录中的文件)。
你需要做好以下这些准备:
* 使用 Linux 和 Windows 双系统引导
* 需要安装的 Linux 发行版的 USB live 版
* 在外部磁盘备份 Windows 和 Linux 中的重要文件(并非必要,但建议备份一下)
#### 在替换 Linux 发行版时要记住保留你的 home 目录
如果想让个人文件在安装新 Linux 系统的过程中不受影响,原有的 Linux 系统必须具有单独的 root 目录和 home 目录。你可能会发现我的[双系统引导教程][8]在安装过程中不选择“与 Windows 一起安装”选项,而选择“其它”选项,然后手动创建 root 和 home 分区。所以,手动创建单独的 home 分区也算是一个磨刀不误砍柴工的操作。因为如果要在不丢失文件的情况下,将现有的 Linux 发行版替换为另一个发行版,需要将 home 目录存放在一个单独的分区上。
不过,你必须记住现有 Linux 系统的用户名和密码才能使用与新系统中相同的 home 目录。
如果你没有单独的 home 分区,也可以后续再进行创建。但这并不是推荐做法,因为这个过程会比较复杂,有可能会把你的系统搞乱。
下面来看看如何替换到另一个 Linux 发行版。
#### 步骤 1为新的 Linux 发行版创建一个 USB live 版
尽管上文中已经提到了它,但我还是要重复一次以免忽略。
你可以使用 Windows 或 Linux 中的启动盘创建器(例如 [Etcher][9])来创建 USB live 版,这个过程比较简单,这里不再详细叙述。
#### 步骤 2启动 USB live 版并安装 Linux
你应该已经使用过双系统启动,对这个过程不会陌生。使用 USB live 版重新启动系统,在启动时反复按 F10 或 F12 进入 BIOS 设置。选择从 USB 启动,就可以看到进入 live 环境或立即安装的选项。
在安装过程中,进入“安装类型”界面时,选择“其它”选项。
![Replacing one Linux with another from dual boot][10]
(在这里选择“其它”选项)
#### 步骤 3准备分区操作
下图是分区界面。你会看到使用 Ext4 文件系统类型来安装 Linux。
![Identifying Linux partition in dual boot][11]
(确定 Linux 的安装位置)
在上图中,标记为 Linux Mint 19 的 Ext4 分区是 root 分区,大小为 82691 MB 的第二个 Ext4 分区是 home 分区。在这里我这里没有使用[交换空间][12]。
如果你只有一个 Ext4 分区,就意味着你的 home 目录与 root 目录位于同一分区。在这种情况下,你就无法保留 home 目录中的文件了,这个时候我建议将重要文件复制到外部磁盘,否则这些文件将不会保留。
然后是删除 root 分区。选择 root 分区,然后点击 - 号,这个操作释放了一些磁盘空间。
![Delete root partition of your existing Linux install][13]
(删除 root 分区)
磁盘空间释放出来后,点击 + 号。
![Create root partition for the new Linux][14]
(创建新的 root 分区)
现在已经在可用空间中创建一个新分区。如果你之前的 Linux 系统中只有一个 root 分区,就应该在这里创建 root 分区和 home 分区。如果需要,还可以创建交换分区。
如果你之前已经有 root 分区和 home 分区,那么只需要从已删除的 root 分区创建 root 分区就可以了。
![Create root partition for the new Linux][15]
(创建 root 分区)
你可能有疑问,为什么要经过“删除”和“添加”两个过程,而不使用“更改”选项。这是因为以前使用“更改”选项好像没有效果,所以我更喜欢用 - 和 +。这是迷信吗?也许是吧。
这里有一个重要的步骤,对新创建的 root 分区进行格式化。在没有更改分区大小的情况下,默认是不会对分区进行格式化的。如果分区没有被格式化,之后可能会出现问题。
![][16]
(格式化 root 分区很重要)
如果你在新的 Linux 系统上已经划分了单独的 home 分区,选中它并点击更改。
![Recreate home partition][17]
(修改已有的 home 分区)
然后指定将其作为 home 分区挂载即可。
![Specify the home mount point][18]
(指定 home 分区的挂载点)
如果你还有交换分区,可以重复与 home 分区相同的步骤,唯一不同的是要指定将空间用作交换空间。
现在的状态应该是有一个 root 分区(将被格式化)和一个 home 分区(如果需要,还可以使用交换分区)。点击“立即安装”可以开始安装。
![Verify partitions while replacing one Linux with another][19]
(检查分区情况)
接下来的几个界面就很熟悉了,要重点注意的是创建用户和密码的步骤。如果你之前有一个单独的 home 分区,并且还想使用相同的 home 目录,那你必须使用和之前相同的用户名和密码,至于设备名称则可以任意指定。
![To keep the home partition intact, use the previous user and password][20]
(要保持 home 分区不变,请使用之前的用户名和密码)
接下来只要静待安装完成,不需执行任何操作。
![Wait for installation to finish][21]
(等待安装完成)
安装完成后重新启动系统,你就能使用新的 Linux 发行版。
在以上的例子中,我可以在新的 Linux Mint 19 中使用原有的 Elementary OS 中的整个 home 目录,并且其中所有视频和图片都原封不动。岂不美哉?
--------------------------------------------------------------------------------
via: https://itsfoss.com/replace-linux-from-dual-boot/
作者:[Abhishek Prakash][a]
选题:[lujun9972](https://github.com/lujun9972)
译者:[HankChow](https://github.com/HankChow)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://itsfoss.com/author/abhishek/
[1]: https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2018/09/Replace-Linux-Distro-from-dual-boot.png
[2]: https://itsfoss.com/install-ubuntu-1404-dual-boot-mode-windows-8-81-uefi/
[3]: https://itsfoss.com/linux-mint-vs-ubuntu/
[4]: https://www.linuxmint.com/
[5]: https://itsfoss.com/uninstall-ubuntu-linux-windows-dual-boot/
[6]: https://itsfoss.com/guide-install-linux-mint-16-dual-boot-windows/
[7]: https://www.ubuntu.com/
[8]: https://itsfoss.com/guide-install-elementary-os-luna/
[9]: https://etcher.io/
[10]: https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2018/09/replace-linux-with-another-1.jpg
[11]: https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2018/09/replace-linux-with-another-2.jpg
[12]: https://itsfoss.com/swap-size/
[13]: https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2018/09/replace-linux-with-another-3.jpg
[14]: https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2018/09/replace-linux-with-another-4.jpg
[15]: https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2018/09/replace-linux-with-another-5.jpg
[16]: https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2018/09/replace-linux-with-another-6.jpg
[17]: https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2018/09/replace-linux-with-another-7.jpg
[18]: https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2018/09/replace-linux-with-another-8.jpg
[19]: https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2018/09/replace-linux-with-another-9.jpg
[20]: https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2018/09/replace-linux-with-another-10.jpg
[21]: https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2018/09/replace-linux-with-another-11.jpg

View File

@@ -1,315 +0,0 @@
Linux 系统上 swap 空间的介绍
======
![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/fail_progress_cycle_momentum_arrow.png?itok=q-ZFa_Eh)
当今无论什么操作系统 Swap 空间是非常常见的。Linux 使用 Swap 空间来增加主机可用的虚拟内存。它可以是常规文件或逻辑卷上使用一个或多个专用swap 分区或 swap 文件。
典型计算机中有两种基本类型的内存。第一种类型,随机存取存储器 (RAM),用于存储计算机使用的数据和程序。只有程序和数据存储在 RAM 中,计算机才能使用它们。随机存储器是易失性存储器;也就是说,如果计算机关闭了,存储在 RAM 中的数据就会丢失。
硬盘是用于长期存储数据和程序的磁性介质。该磁介质可以很好的保存数据即使计算机断电存储在磁盘上的数据也会保留下来。CPU (中央处理器)不能直接访问硬盘上的程序和数据;他们必须首先复制到 RAM 中RAM 是 CPU 访问代码指令和操作数据的地方。在引导过程中,计算机将特定的操作系统程序(如内核、init 或 systemd )以及硬盘上的数据复制到 RAM 中,在 RAM 中,计算机的处理器 CPU 可以直接访问这些数据。
### Swap 空间
Swap 空间是现代 Linux 系统中的第二种内存类型。Swap 空间的主要功能是当全部的 RAM 被占用并且需要更多内存时,用磁盘空间代替 RAM 内存。
例如,假设你有一个 8GB RAM 的计算机。如果你启动的程序没有填满 RAM一切好不需要 Swap。假设你在处理电子表格当添加更多的行时你电子表格会增长加上所有正在运行的程序将会占用全部的 RAM 。如果这时没有可用的 Swap 空间,你将不得不停止处理电子表格,直到关闭一些其他程序来释放一些 RAM 。
内核使用一个内存管理程序来检测最近没有使用的内存块,也就是内存页面。内存管理程序将这些相对不经常使用的内存页交换到硬盘上专门指定用于“分页”或 swap 的特殊分区。释放 RAM ,为输入电子表格更多数据腾出了空间。那些换出到硬盘的内存页面被内核的内存管理代码跟踪,如果需要,可以被分页回 RAM。
Linux 计算机中的内存总量是 RAM + swap 分区swap 分区被称为虚拟内存.
### Linux swap 分区类型
Linux 提供了两种类型的 swap 空间。默认情况下,大多数 Linux 在安装时都会创建一个 swap 分区,但是也可以使用一个特殊配置的文件作为 swap 文件。swap 分区顾名思义就是一个标准磁盘分区,由 `mkswap` 命令指定 swap 空间。
如果没有可用磁盘空间来创建新的 swap 分区,或者卷组中没有空间为 swap 空间创建逻辑卷,则可以使用 swap 文件。这只是一个创建并预分配指定大小的常规文件。然后运行 `mkswap` 命令将其配置为 swap 空间。除非绝对必要,否则我不建议使用文件来做 swap 空间。
### 频繁交换
当总虚拟内存( RAM 和 swap 空间 )变得快满时,可能会发生频繁交换 。系统花了太多时间在 swap 空间和 RAM 之间做内存块页面切换,以至于几乎没有时间用于实际工作。这种情况是显而易见的:系统变得缓慢或完全无反应,硬盘指示灯几乎持续亮起。
使用 `free` 的命令来显示 CPU 负载和内存使用情况,你会发现 CPU 负载非常高,可能达到系统中 CPU 内核数量的30到40倍。另一个情况是 RAM 和 swap 空间几乎完全被分配了。
事实上,查看 SAR (系统活动报告)数据也可以显示这些内容。在我的每个系统上都安装 SAR ,并将这些用于数据分析。
### swap 空间的正确大小是多少?
许多年前,硬盘上分配给 swap 空间大小是计算机上的 RAM 的两倍(当然,这是大多数计算机的 RAM 以 KB 或 MB 为单位的时候)。因此,如果一台计算机有 64KB 的 RAM应该分配 128KB 的 swap 分区。该规则考虑到了这样的事实情况,即 RAM 大小在当时非常小分配超过2倍的 RAM 用于 swap 空间并不能提高性能。使用超过两倍的 RAM 进行交换,比实际执行有用的工作的时候,大多数系统将花费更多的时间。
RAM 现在已经很便宜了,如今大多数计算机的 RAM 都达到了几十亿字节。我的大多数新电脑至少有 8GB 内存一台有32GB 内存,我的主工作站有 64GB 内存。我的旧电脑有4到 8GB 的内存。
当操作具有大 RAM 的计算机时swap 空间的限制性能系数远低于 2倍。[Fedora 28在线安装指南][1] 定义了当前关于 swap 空间分配的方法。下面内容是我提出的建议。
下表根据系统中的 RAM 大小以及是否有足够的内存让系统休眠,提供了交换分区的推荐大小。建议的 swap 分区大小是在安装过程中自动建立的。但是,为了满足系统休眠,您需要在自定义分区阶段编辑 swap 空间。
_表 1: Fedora 28文档中推荐的系统 swap 空间_
| **系统内存大小 ** | **推荐 swap 空间 ** | **建议 swap 大小用休眠模式 ** |
|--------------------------|-----------------------------|---------------------------------------|
| 小于 2 GB | 2倍 RAM | 3 倍 RAM |
| 2 GB - 8 GB | 等于 RAM 大小 | 2 倍 RAM |
| 8 GB - 64 GB | 0.5 倍 RAM | 1.5 倍 RAM |
| 大于 64 GB | 工作量相关 | 不建议休眠模式 |
在上面列出的每个范围之间的边界(例如,具有 2GB、8GB 或 64GB 的系统 RAM),请根据所选 swap 空间和支持休眠功能请谨慎使用。如果你的系统资源允许,增加 swap 空间可能会带来更好的性能。
当然,大多数 Linux 管理员对多大的 swap 空间量有自己的想法。下面的表2包含了基于我在多种环境中的个人经历所做出的建议。这些可能不适合你但是和表1一样它们可能对你有所帮助。
_表 2: 作者推荐的系统 swap 空间_
| RAM 大小 | 推荐 swap 空间 |
|---------------|------------------------|
| ≤ 2GB | 2X RAM |
| 2GB 8GB | = RAM |
| >8GB | 8GB |
这两个表中共同点,随着 RAM 数量的增加,超过某一点增加更多 swap 空间只会导致在 swap 空间几乎被全部使用之前就发生频繁交换。根据以上建议,则应尽可能添加更多 RAM而不是增加更多 swap 空间。如类似影响系统性能的情况一样,请使用最适合你的建议。根据 Linux 环境中的条件进行测试和更改是需要时间和精力的。
### 向非 LVM 磁盘环境添加更多 swap 空间
面对已安装 Linux 的主机并对 swap 空间的需求不断变化,有时有必要修改系统定义的 swap 空间的大小。此过程可用于需要增加 swap 空间大小的任何情况。它假设有足够的可用磁盘空间。此过程还假设磁盘在 “raw” EXT4 和 swap 分区中分区,并且不使用逻辑卷 (LVM)。
要基本步骤很简单:
1. 关闭现有的 swap 空间。
2. 创建所需大小的新 swap 分区。
3. 重读分区表。
4. 将分区配置为 swap 空间。
5. 添加新分区到 /etc/fstab。
6. 打开 swap 空间。
不应需要重新启动机器。
为了安全起见,在关闭 swap 空间前,至少你应该确保没有应用程序在运行,也没有 swap 空间在使用。`free``top` 命令可以告诉你 swap 空间是否在使用中。为了更安全您可以恢复到运行级别1或单用户模式。
使用关闭所有 swap 空间的命令关闭 swap 分区:
```
swapoff -a
```
现在查看硬盘上的现有分区。
```
fdisk -l
```
这将显示每个驱动器上的分区表。按编号标识当前的 swap 分区。
使用以下命令在交互模式下启动 `fdisk`:
```
fdisk /dev/<device name>
```
例如:
```
fdisk /dev/sda
```
此时,`fdisk` 是交互方式的,只在指定的磁盘驱动器上进行操作。
使用 fdisk `p` 子命令验证磁盘上是否有足够的可用空间来创建新的 swap 分区。硬盘上的空间以 512字节 以及起始和结束柱面编号的形式显示,因此您可能需要做一些计算来确定分配分区之间和末尾的可用空间。
使用 `n` 子命令创建新的交换分区。fdisk 会问你开始柱面。默认情况下,它选择编号最低的可用柱面。如果你想改变这一点,输入开始柱面的编号。
`fdisk` 命令允许你以多种格式输入分区的大小包括最后一个柱面号或字节、KB 或 MB 的大小。键入 4000M ,这将在新分区上提供大约 4GB 的空间(例如),然后按 Enter 键。
使用 `p` 子命令来验证分区是否按照指定的方式创建的。请注意,除非使用结束柱面编号,否则分区可能与你指定的不完全相同。`fdisk` 命令只能在整个柱面上增量的分配磁盘空间,因此你的分区可能比你指定的稍小或稍大。如果分区不是您想要的,你可以删除它并重新创建它。
现在指定新分区是 swap 分区了 。子命令 `t` 允许你指定定分区的类型。所以输入 `t`指定分区号当它要求十六进制分区类型时输入82这是Linux swap 分区类型,然后按 Enter。
当你对创建的分区感到满意时,使用 `w` 子命令将新的分区表写入磁盘。`fdisk` 程序将退出,并在完成修改后的分区表的编写后返回命令提示符。当`fdisk` 完成写入新分区表时,会收到以下消息:
```
The partition table has been altered!
Calling ioctl() to re-read partition table.
WARNING: Re-reading the partition table failed with error 16: Device or resource busy.
The kernel still uses the old table.
The new table will be used at the next reboot.
Syncing disks.
```
此时,你使用 `partprobe` 命令强制内核重新读取分区表,这样就不需要执行重新启动机器。
```
partprobe
```
使用命令 `fdisk -l` 列出分区,新 swap 分区应该在列出的分区中。确保新的分区类型是 “Linux swap”。
修改 /etc/fstab 文件以指向新的 swap 分区。如下所示:
```
LABEL=SWAP-sdaX   swap        swap    defaults        0 0
```
其中 `X` 是分区号。根据新 swap 分区的位置,添加以下内容:
```
/dev/sdaY         swap        swap    defaults        0 0
```
请确保使用正确的分区号。现在,可以执行创建 swap 分区的最后一步。使用 `mkswap` 命令将分区定义为 swap 分区。
```
mkswap /dev/sdaY
```
最后一步是使用以下命令启用 swap 空间:
```
swapon -a
```
你的新 swap 分区现在与以前存在的 swap 分区一起在线。您可以使用 `free``top` 命令来验证这一点。
#### 在 LVM 磁盘环境中添加 swap 空间
如果你的磁盘使用 LVM ,更改 swap 空间将相当容易。同样,假设当前 swap 卷所在的卷组中有可用空间。默认情况下LVM 环境中的 Fedora Linux 在安装过程将 swap 分区创建为逻辑卷。您可以非常简单地增加 swap 卷的大小。
以下是在 LVM 环境中增加 swap 空间大小的步骤:
1. 关闭所有 swap 。
2. 增加指定用于 swap 的逻辑卷的大小。
3. 为 swap 空间调整大小的卷配置。
4. 启用 swap。
首先,让我们使用 `lvs` 命令(列出逻辑卷)来验证 swap 是否存在以及 swap 是否是逻辑卷。
```
[root@studentvm1 ~]# lvs
  LV     VG                Attr       LSize  Pool   Origin Data%  Meta%  Move Log Cpy%Sync Convert
  home   fedora_studentvm1 -wi-ao----  2.00g                                                      
  pool00 fedora_studentvm1 twi-aotz--  2.00g               8.17   2.93                            
  root   fedora_studentvm1 Vwi-aotz--  2.00g pool00        8.17                                  
  swap   fedora_studentvm1 -wi-ao----  8.00g                                                      
  tmp    fedora_studentvm1 -wi-ao----  5.00g                                                      
  usr    fedora_studentvm1 -wi-ao---- 15.00g                                                      
  var    fedora_studentvm1 -wi-ao---- 10.00g                                                      
[root@studentvm1 ~]#
```
你可以看到当前的 swap 大小为 8GB。在这种情况下我们希望将 2GB 添加到此 swap 卷中。首先,停止现有的 swap 。如果 swap 空间正在使用,终止正在运行的程序。
```
swapoff -a
```
现在增加逻辑卷的大小。
```
[root@studentvm1 ~]# lvextend -L +2G /dev/mapper/fedora_studentvm1-swap
  Size of logical volume fedora_studentvm1/swap changed from 8.00 GiB (2048 extents) to 10.00 GiB (2560 extents).
  Logical volume fedora_studentvm1/swap successfully resized.
[root@studentvm1 ~]#
```
运行 `mkswap` 命令将整个 10GB 分区变成 swap 空间。
```
[root@studentvm1 ~]# mkswap /dev/mapper/fedora_studentvm1-swap
mkswap: /dev/mapper/fedora_studentvm1-swap: warning: wiping old swap signature.
Setting up swapspace version 1, size = 10 GiB (10737414144 bytes)
no label, UUID=3cc2bee0-e746-4b66-aa2d-1ea15ef1574a
[root@studentvm1 ~]#
```
重新启用 swap 。
```
[root@studentvm1 ~]# swapon -a
[root@studentvm1 ~]#
```
现在,使用 `lsblk ` 命令验证新 swap 空间是否存在。同样,不需要重新启动机器。
```
[root@studentvm1 ~]# lsblk
NAME                                 MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
sda                                    8:0    0   60G  0 disk
|-sda1                                 8:1    0    1G  0 part /boot
`-sda2                                 8:2    0   59G  0 part
  |-fedora_studentvm1-pool00_tmeta   253:0    0    4M  0 lvm  
  | `-fedora_studentvm1-pool00-tpool 253:2    0    2G  0 lvm  
  |   |-fedora_studentvm1-root       253:3    0    2G  0 lvm  /
  |   `-fedora_studentvm1-pool00     253:6    0    2G  0 lvm  
  |-fedora_studentvm1-pool00_tdata   253:1    0    2G  0 lvm  
  | `-fedora_studentvm1-pool00-tpool 253:2    0    2G  0 lvm  
  |   |-fedora_studentvm1-root       253:3    0    2G  0 lvm  /
  |   `-fedora_studentvm1-pool00     253:6    0    2G  0 lvm  
  |-fedora_studentvm1-swap           253:4    0   10G  0 lvm  [SWAP]
  |-fedora_studentvm1-usr            253:5    0   15G  0 lvm  /usr
  |-fedora_studentvm1-home           253:7    0    2G  0 lvm  /home
  |-fedora_studentvm1-var            253:8    0   10G  0 lvm  /var
  `-fedora_studentvm1-tmp            253:9    0    5G  0 lvm  /tmp
sr0                                   11:0    1 1024M  0 rom  
[root@studentvm1 ~]#
```
您也可以使用`swapon -s` 命令或 `top``free` 或其他几个命令来验证这一点。
```
[root@studentvm1 ~]# free
              total        used        free      shared  buff/cache   available
Mem:        4038808      382404     2754072        4152      902332     3404184
Swap:      10485756           0    10485756
[root@studentvm1 ~]#
```
请注意,不同的命令以不同的形式显示或要求输入设备文件。在 /dev 目录中访问特定设备有多种方式。在我的文章[Managing Devices in Linux][2] 中有更多关于 /dev 目录及其内容说明。
--------------------------------------------------------------------------------
via: https://opensource.com/article/18/9/swap-space-linux-systems
作者:[David Both][a]
选题:[lujun9972](https://github.com/lujun9972)
译者:[heguangzhi](https://github.com/heguangzhi)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://opensource.com/users/dboth
[1]: https://docs.fedoraproject.org/en-US/fedora/f28/install-guide/
[2]: https://opensource.com/article/16/11/managing-devices-linux

View File

@@ -1,238 +0,0 @@
如何将Scikit-learn Python库用于数据科学项目
======
![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/brain_data.png?itok=RH6NA32X)
Scikit-learn Python库最初于2007年发布从头到尾都通常用于解决机器学习和数据科学问题。 多功能库提供整洁一致高效的API和全面的在线文档。
### 什么是Scikit-learn
[Scikit-learn][1]是一个开源Python库拥有强大的数据分析和数据挖掘工具。 在BSD许可下可用并建立在以下机器学习库上
- **NumPy**,一个用于操作多维数组和矩阵的库。 它还具有广泛的数学函数汇集,可用于执行各种计算。
- **SciPy**,一个由各种库组成的生态系统,用于完成技术计算任务。
- **Matplotlib**,一个用于绘制各种图表和图形的库。
Scikit-learn提供了广泛的内置算法可以充分用于数据科学项目。
以下是使用Scikit-learn库的主要方法。
#### 1. 分类
[分类][2]工具识别与提供的数据相关联的类别。 例如,它们可用于将电子邮件分类为垃圾邮件或非垃圾邮件。
Scikit-learn中的分类算法包括
- 支持向量机SVM
- 最邻近
- 随机森林
#### 2. 回归
回归涉及到创建一个模型去试图理解输入和输出数据之间的关系。 例如,回归工具可用于了解股票价格的行为。
回归算法包括:
- SVM
- 岭回归Ridge regression
- LassoLCTT译者注Lasso 即 least absolute shrinkage and selection operator又译最小绝对值收敛和选择算子、套索算法
#### 3. 聚类
Scikit-learn聚类工具用于自动将具有相同特征的数据分组。 例如,可以根据客户数据的地点对客户数据进行细分。
聚类算法包括:
- K-means
- 谱聚类Spectral clustering
- Mean-shift
#### 4. 降维
降维降低了用于分析的随机变量的数量。 例如,为了提高可视化效率,可能不会考虑外围数据。
降维算法包括:
- 主成分分析Principal component analysisPCA
- 功能选择Feature selection
- 非负矩阵分解Non-negative matrix factorization
#### 5. 模型选择
模型选择算法提供了用于比较,验证和选择要在数据科学项目中使用的最佳参数和模型的工具。
通过参数调整能够增强精度的模型选择模块包括:
- 网格搜索Grid search
- 交叉验证Cross-validation
- 指标Metrics
#### 6. 预处理
Scikit-learn预处理工具在数据分析期间的特征提取和规范化中非常重要。 例如,您可以使用这些工具转换输入数据(如文本)并在分析中应用其特征。
预处理模块包括:
- 预处理
- 特征提取
### Scikit-learn库示例
让我们用一个简单的例子来说明如何在数据科学项目中使用Scikit-learn库。
我们将使用[鸢尾花花卉数据集][3]该数据集包含在Scikit-learn库中。 鸢尾花数据集包含有关三种花种的150个细节三种花种分别为
- Setosa-标记为0
- Versicolor-标记为1
- Virginica-标记为2
数据集包括每种花种的以下特征(以厘米为单位):
- 萼片长度
- 萼片宽度
- 花瓣长度
- 花瓣宽度
#### 第1步导入库
由于Iris数据集包含在Scikit-learn数据科学库中我们可以将其加载到我们的工作区中如下所示
```
from sklearn import datasets
iris = datasets.load_iris()
```
这些命令从**sklearn**导入数据集**datasets**模块,然后使用**datasets**中的**load_iris()**方法将数据包含在工作空间中。
#### 第2步获取数据集特征
数据集**datasets**模块包含几种方法,使您更容易熟悉处理数据。
在Scikit-learn中数据集指的是类似字典的对象其中包含有关数据的所有详细信息。 使用**.data**键存储数据,该数据列是一个数组列表。
例如,我们可以利用**iris.data**输出有关Iris花卉数据集的信息。
```
print(iris.data)
```
这是输出(结果已被截断):
```
[[5.1 3.5 1.4 0.2]
 [4.9 3.  1.4 0.2]
 [4.7 3.2 1.3 0.2]
 [4.6 3.1 1.5 0.2]
 [5.  3.6 1.4 0.2]
 [5.4 3.9 1.7 0.4]
 [4.6 3.4 1.4 0.3]
 [5.  3.4 1.5 0.2]
 [4.4 2.9 1.4 0.2]
 [4.9 3.1 1.5 0.1]
 [5.4 3.7 1.5 0.2]
 [4.8 3.4 1.6 0.2]
 [4.8 3.  1.4 0.1]
 [4.3 3.  1.1 0.1]
 [5.8 4.  1.2 0.2]
 [5.7 4.4 1.5 0.4]
 [5.4 3.9 1.3 0.4]
 [5.1 3.5 1.4 0.3]
```
我们还使用**iris.target**向我们提供有关花朵不同标签的信息。
```
print(iris.target)
```
这是输出:
```
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2
 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
 2 2]
```
如果我们使用**iris.target_names**,我们将输出数据集中找到的标签名称的数组。
```
print(iris.target_names)
```
以下是运行Python代码后的结果
```
['setosa' 'versicolor' 'virginica']
```
#### 第3步可视化数据集
我们可以使用[箱形图][4]来生成鸢尾花数据集的视觉描绘。 箱形图说明了数据如何通过四分位数在平面上分布的。
以下是如何实现这一目标:
```
import seaborn as sns
box_data = iris.data # 表示数据数组的变量
box_target = iris.target # 表示标签数组的变量
sns.boxplot(data = box_data,width=0.5,fliersize=5)
sns.set(rc={'figure.figsize':(2,15)})
```
让我们看看结果:
![](https://opensource.com/sites/default/files/uploads/scikit_boxplot.png)
在横轴上:
* 0是萼片长度
* 1是萼片宽度
* 2是花瓣长度
* 3是花瓣宽度
垂直轴的尺寸以厘米为单位。
### 总结
以下是这个简单的Scikit-learn数据科学教程的完整代码。
```
from sklearn import datasets
iris = datasets.load_iris()
print(iris.data)
print(iris.target)
print(iris.target_names)
import seaborn as sns
box_data = iris.data # 表示数据数组的变量
box_target = iris.target # 表示标签数组的变量
sns.boxplot(data = box_data,width=0.5,fliersize=5)
sns.set(rc={'figure.figsize':(2,15)})
```
Scikit-learn是一个多功能的Python库可用于高效完成数据科学项目。
如果您想了解更多信息,请查看[LiveEdu][5]上的教程例如Andrey Bulezyuk关于使用Scikit-learn库创建[机器学习应用程序][6]的视频。
有什么评价或者疑问吗? 欢迎在下面分享。
--------------------------------------------------------------------------------
via: https://opensource.com/article/18/9/how-use-scikit-learn-data-science-projects
作者:[Dr.Michael J.Garbade][a]
选题:[lujun9972](https://github.com/lujun9972)
译者:[Flowsnow](https://github.com/Flowsnow)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://opensource.com/users/drmjg
[1]: http://scikit-learn.org/stable/index.html
[2]: https://blog.liveedu.tv/regression-versus-classification-machine-learning-whats-the-difference/
[3]: https://en.wikipedia.org/wiki/Iris_flower_data_set
[4]: https://en.wikipedia.org/wiki/Box_plot
[5]: https://www.liveedu.tv/guides/data-science/
[6]: https://www.liveedu.tv/andreybu/REaxr-machine-learning-model-python-sklearn-kera/oPGdP-machine-learning-model-python-sklearn-kera/

View File

@@ -1,104 +0,0 @@
一款免费且安全的在线PDF转换软件
======
![](https://www.ostechnix.com/wp-content/uploads/2018/09/easypdf-720x340.jpg)
我们总在寻找一个更好用且更高效的解决方案,来我们的生活理加方便。 比方说在处理PDF文档时你会迫切地想拥有一款工具它能够在任何情形下都显得快速可靠。在这我们想向你推荐**EasyPDF**——一款可以胜任所有场合的在线PDF软件。通过大量的测试我们可以保证这款工具能够让你的PDF文档管理更加容易。
不过关于EasyPDF有一些十分重要的事情你必须知道。
* EasyPDF是免费的、匿名的在线PDF转换软件。
* 能够将PDF文档转换成Word、Excel、PowerPoint、AutoCAD、JPG, GIF和Text等格式格式的文档。
* 能够从ord、Excel、PowerPoint等其他格式的文件创建PDF文件。
* 能够进行PDF文档的合并、分割和压缩。
* 能够识别扫描的PDF和图片中的内容。
* 可以从你的设备或者云存储(Google Drive 和 DropBox)中上传文档。
* 可以在Windows、Linux、Mac和智能手机上通过浏览器来操作。
* 支持多种语言。
### EasyPDF的用户界面
![](http://www.ostechnix.com/wp-content/uploads/2018/09/easypdf-interface.png)
EasyPDF最吸引你眼球的就是平滑的用户界面营造一种整洁的环境这会让使用者感觉更加舒服。由于网站完全没有一点广告EasyPDF的整体使用体验相比以前会好很多。
每种不同类型的转换都有它们专门的菜单,只需要简单地向其中添加文件,你并不需要知道太多知识来进行操作。
许多类似网站没有做好相关的优化使得在手机上的使用体验并不太友好。然而EasyPDF突破了这一个瓶颈。在智能手机上EasyPDF几乎可以秒开并且可以顺畅的操作。你也通过Chrome app的**three dots menu**把EasyPDF添加到手机的主屏幕上。
![](http://www.ostechnix.com/wp-content/uploads/2018/09/EasyPDF-fs8.png)
### 特性
除了好看的界面EasyPDF还非常易于使用。为了使用它**不需要注册一个账号** 或者**留下一个邮箱**它是完全匿名的。另外EasyPDF也不会对要转换的文件进行数量或者大小的限制完全不需要安装酷极了不是吗
首先你需要选择一种想要进行的格式转换比如将PDF转换成Word。然后选择你想要转换的PDF文件。你可以通过两种方式来上传文件直接拖拉或者从设备上的文件夹进行选择。还可以选择从[**Google Drive**][1] 或 [**Dropbox**][2]来上传文件。
选择要进行格式转换的文件后点击Convert按钮开始转换过程。转换过程会在一分钟内完成你并不需要等待太长时间。如果你还有对其他文件进行格式转换在接着转换前不要忘了将前面已经转换完成的文件下载保存。不然的话你将会丢失前面的文件。
![](https://www.ostechnix.com/wp-content/uploads/2018/09/EasyPDF1.png)
要进行其他类型的格式转换,直接返回到主页。
目前支持的几种格式转换类型如下:
* **PDF to Word** 将 PDF 文档 转换成 Word 文档
* **PDF 转换成 PowerPoint** 将 PDF 文档 转换成 PowerPoint 演示讲稿
* **PDF 转换成 Excel** 将 PDF 文档 转换成 Excel 文档
* **PDF 创建** 从一些其他类型的文件(如, text, doc, odt)来创建PDF文档
* **Word 转换成 PDF** 将 Word 文档 转换成 PDF 文档
* **JPG 转换成 PDF** 将 JPG images 转换成 PDF 文档
* **PDF 转换成 Au转换成CAD** 将 PDF 文档 转换成 .dwg 格式 (DWG 是 CAD 文件的原生的格式)
* **PDF 转换成 Text** 将 PDF 文档 转换成 Text 文档
* **PDF 分割** 把 PDF 文件分割成多个部分
* **PDF 合并** 把多个PDF文件合并成一个文件
* **PDF 压缩** 将 PDF 文档进行压缩
* **PDF 转换成 JPG** 将 PDF 文档 转换成 JPG 图片
* **PDF 转换成 PNG** 将 PDF 文档 转换成 PNG 图片
* **PDF 转换成 GIF** 将 PDF 文档 转换成 GIF 文件
* **在线文字内容识别** 将扫描的纸质文档转换成能够进行编辑的文件Word,Excel,Text)
想试一试吗?好极了!点击下面的链接,然后开始格式转换吧!
[![](https://www.ostechnix.com/wp-content/uploads/2018/09/EasyPDF-online-pdf.png)][https://easypdf.com/]
### 总结
EasyPDF 名符其实能够让PDF 管理更加容易。就我测试过的 EasyPDF 服务而言,它提供了**完全免费**的简单易用的转换功能。它十分快速、安全和可靠。你会对它的服务质量感到非常满意,因为它不用支付任何费用,也不用留下像邮箱这样的个人信息。值得一试,也许你会找到你自己更喜欢的 PDF 工具。
好吧,我就说这些。更多的好东西还在后后面,请继续关注!
加油!
--------------------------------------------------------------------------------
via: https://www.ostechnix.com/easypdf-a-free-and-secure-online-pdf-conversion-suite/
作者:[SK][a]
选题:[lujun9972](https://github.com/lujun9972)
译者:[译者ID](https://github.com/zhousiyu325)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://www.ostechnix.com/author/sk/
[1]: https://www.ostechnix.com/how-to-mount-google-drive-locally-as-virtual-file-system-in-linux/
[2]: https://www.ostechnix.com/install-dropbox-in-ubuntu-18-04-lts-desktop/

View File

@@ -0,0 +1,105 @@
容器技术对指导我们 DevOps 的一些启发
======
容器技术的使用支撑了目前 DevOps 三大主要实践:流水线,及时反馈,持续实验与学习以改进。
![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/LAW-patent_reform_520x292_10136657_1012_dc.png?itok=Cd2PmDWf)
容器技术与 DevOps 二者在发展的过程中是互相促进的关系。得益于 DevOps 的设计理念愈发先进,容器生态系统在设计上与组件选择上也有相应发展。同时,由于容器技术在生产环境中的使用,反过来也促进了 DevOps 三大主要实践:[支撑DevOps的三个实践][1].
### 工作流
**容器中的工作流**
每个容器都可以看成一个独立的封闭仓库,当你置身其中,不需要管外部的系统环境、集群环境、以及其他基础设施,不管你在里面如何折腾,只要对外提供正常的功能就好。一般来说,容器内运行的应用,一般作为整个应用系统架构的一部分:比如 web API数据库任务执行缓存系统垃圾回收器等。运维团队一般会限制容器的资源使用并在此基础上建立完善的容器性能监控服务从而降低其对基础设施或者下游其他用户的影响。
**现实中的工作流**
那些跟“容器”一样独立工作的团队,也可以借鉴这种限制容器占用资源的策略。因为无论是在现实生活中的工作流(代码发布、构建基础设施,甚至制造[Spacelys Sprockets][2]等),还是技术中的工作流(开发、测试、试运行、发布)都使用了这样的线性工作流,一旦某个独立的环节或者工作团队出现了问题,那么整个下游都会受到影响,虽然使用我们这种线性的工作流有效降低了工作耦合性。
**DevOps 中的工作流**
DevOps 中的第一条原则,就是掌控整个执行链路的情况,努力理解系统如何协同工作,并理解其中出现的问题如何对整个过程产生影响。为了提高流程的效率,团队需要持续不断的找到系统中可能存在的性能浪费以及忽视的点,并最终修复它们。
> “践行这样的工作流后,可以避免传递一个已知的缺陷到工作流的下游,避免产生一个可能会导致全局性能退化的局部优化,持续优化工作流的性能,持续加深对于系统的理解”
Gene Kim, [支撑DevOps的三个实践][3], IT 革命, 2017.4.25
### 反馈
**容器中的反馈**
除了限制容器的资源,很多产品还提供了监控和通知容器性能指标的功能,从而了解当容器工作不正常时,容器内部处于什么样的工作状态。比如 目前[流行的][5][Prometheus][4],可以用来从容器和容器集群中收集相应的性能指标数据。容器本身特别适用于分隔应用系统,以及打包代码和其运行环境,但也同时带来不透明的特性,这时从中快速的收集信息,从而解决发生在其内部出现的问题,就显得尤为重要了。
**现实中的反馈**
在现实中,从始至终同样也需要反馈。一个高效的处理流程中,及时的反馈能够快速的定位事情发生的时间。反馈的关键词是“快速”和“相关”。当一个团队处理大量不相关的事件时,那些真正需要快速反馈的重要信息,很容易就被忽视掉,并向下游传递形成更严重的问题。想象下[如果露西和埃塞尔][6]能够很快的意识到:传送带太快了,那么制作出的巧克力可能就没什么问题了(尽管这样就不太有趣了)。
**DevOps and feedback**
DevOps 中的第二条原则就是快速收集所有的相关有用信息这样在出现的问题影响到其他开发进程之前就可以被识别出。DevOps 团队应该努力去“优化下游“,以及快速解决那些可能会影响到之后团队的问题。同工作流一样,反馈也是一个持续的过程,目标是快速的获得重要的信息以及当问题出现后能够及时的响应。
> "快速的反馈对于提高技术的质量、可用性、安全性至关重要。"
Gene Kim, et al., DevOps 手册:如何在技​​术组织中创造世界级的敏捷性,可靠性和安全性, IT 革命, 2016
### 持续实验与学习
**容器中的持续实验与学习**
如何让”持续的实验与学习“更具操作性是一个不小的挑战。容器让我们的开发工程师和运营团队,在不需要掌握太多边缘或难以理解的东西情况下,依然可以安全地进行本地和生产环境的测试,这在之前是难以做到的。即便是一些激进的实验,容器技术仍然让我们轻松地进行版本控制、记录、分享。
**现实中的持续实验与学习**
举个我自己的例子多年前作为一个年轻、初出茅庐的系统管理员仅仅工作三周我被要求对一个运行某个大学核心IT部门网站的Apache虚拟主机进行更改。由于没有易于使用的测试环境我直接在生产的站点上进行了配置修改当时觉得配置没问题就发布了几分钟后我隔壁无意中听到了同事说
”等会,网站挂了?“
“没错,怎么回事?”
很多人蒙圈了……
在被嘲讽之后(真实的嘲讽),我一头扎在工作台上,赶紧撤销我之前的更改。当天下午晚些时候,部门主管 - 我老板的老板的老板来到我的工位上,问发生了什么事。
“别担心,”她告诉我。“我们不会生你的气,这是一个错误,现在你已经学会了。“
而在容器中,这种情形很容易的进行测试,并且也很容易在部署生产环境之前,被那些经验老道的团队成员发现。
**DevOps 中的持续实验与学习**
做实验的初衷是我们每个人都希望通过一些改变从而能够提高一些东西,并勇敢地通过实验来验证我们的想法。对于 DevOps 团队来说,失败无论对团队还是个人来说都是经验,所要不要担心失败。团队中的每个成员不断学习、共享,也会不断提升其所在团队与组织的水平。
随着系统变得越来越琐碎,我们更需要将注意力发在特殊的点上:上面提到的两条原则主要关注的是流程的目前全貌,而持续的学习则是关注的则是整个项目、人员、团队、组织的未来。它不仅对流程产生了影响,还对流程中的每个人产生影响。
> "无风险的实验让我们能够不懈的改进我们的工作,但也要求我们使用之前没有用过的工作方式"
Gene Kim, et al., [凤凰计划:让你了解 IT、DevOps以及如何取得商业成功][7], IT 革命, 2013
### 容器技术给我们 DevOps 上的启迪
学习如何有效地使用容器可以学习DevOps的三条原则工作流反馈以及持续实验和学习。从整体上看应用程序和基础设施而不是对容器外的东西置若罔闻教会我们考虑到系统的所有部分了解其上游和下游影响打破孤岛并作为一个团队工作以提高全局性能和深度
了解整个系统。通过努力提供及时准确的反馈,我们可以在组织内部创建有效的反馈模式,以便在问题发生影响之前发现问题。
最后,提供一个安全的环境来尝试新的想法并从中学习,教会我们创造一种文化,在这种文化中,失败一方面促进了我们知识的增长,另一方面通过有根据的猜测,可以为复杂的问题带来新的、优雅的解决方案。
--------------------------------------------------------------------------------
via: https://opensource.com/article/18/9/containers-can-teach-us-devops
作者:[Chris Hermansen][a]
选题:[lujun9972](https://github.com/lujun9972)
译者:[译者ID](https://github.com/littleji)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://opensource.com/users/clhermansen
[1]: https://itrevolution.com/the-three-ways-principles-underpinning-devops/
[2]: https://en.wikipedia.org/wiki/The_Jetsons
[3]: http://itrevolution.com/the-three-ways-principles-underpinning-devops
[4]: https://prometheus.io/
[5]: https://opensource.com/article/18/9/prometheus-operational-advantage
[6]: https://www.youtube.com/watch?v=8NPzLBSBzPI
[7]: https://itrevolution.com/book/the-phoenix-project/

View File

@@ -0,0 +1,74 @@
如何在家中使用 SSH 和 SFTP 协议
======
通过 SSH 和 SFTP 协议 ,我们能够访问其他设备 ,有效而且安全的传输文件及更多 。
![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/openwires_fromRHT_520_0612LL.png?itok=PqZi55Ab)
多年前 ,我决定配置一个额外的电脑 ,以便我能在工作时能够访问它来传输我所需要的文件 。最基本的一步是要求你的网络提供商 ISP )提供一个固定的地址 IP Address )。
保证你系统的访问是安全的 ,这是一个不必要但很重要的步骤 。在此种特殊情况下 ,我计划只在工作的时候能够访问它 。所以我能够约束访问的 IP 地址 。即使如此 ,你依然要尽多的采用安全措施 。一旦你建立起来这个 ,全世界的人们都能立即访问你的系统 。这是非常令人惊奇及恐慌的 。你能通过日志文件来发现这一点 。我推测有探测机器人在尽它们所能的搜索那些没有安全措施的系统 。
在我建立系统不久后 ,我觉得我的访问是一个简单的玩具而不是我想要的 ,为此 ,我将它关闭了好让我不在为它而担心 。尽管如此 ,这个系统在家庭网络中对于 SSH 和 SFTP 还有其他的用途 ,它至少已经为你而创建了 。
一个必备条件 ,你家的另一台电脑必须已经开机了 ,至于电脑是否已经非常老旧是没有影响的 。你也需要知道另一台电脑的 IP 地址 。有两个方法能够知道做到 ,一个是通过网页进入你的路由器 ,一般情况下你的地址格式类似于 **192.168.1.254** 。通过一些搜索 ,找出当前是开机的并且和系统 eth0 或者 wifi 挂钩的系统是足够简单的 。如何组织你所敢兴趣的电脑是一个挑战 。
询问电脑问题是简单的 ,打开 shell ,输入
```
ifconfig
```
命令会输出一些信息 ,你所需要的信息在 `inet` 后面 ,看起来和 **192.168.1.234** 类似 。当你发现这个后 ,回到你的客户端电脑 ,在命令行中输入
```
ssh gregp@192.168.1.234
```
上面的命令能够正常执行 **gregp** 必须在主机系统中是中确的用户名 。用户的密码也会被需要 。如果你键入的密码和用户名都是正确的 ,你将通过 shell 环境连接上了其他电脑 。我坦诚 ,对于 SSH 我并不是经常使用的 。我偶尔使用它 ,所以我能够运行 `dnf` 来更新我就坐的其他电脑 。通常 ,我用 SFTP
```
sftp grego@192.168.1.234
```
对于用更简单的方法来把一个文件传输到另一个文件 ,我有很强烈的需求 。相对于闪存棒和额外的设备 ,它更加方便 ,耗时更少 。
一旦连接建立成功 SFTP 有两个基本的命令 `get` ,从主机接收文件 `put` ,向主机发送文件 。在客户端 ,我经常移动到我想接收或者传输的文件夹下 ,在开始连接之前 。在连接之后 ,你将在顶层目录 **home/gregp** 。一旦连接成功 ,你将和在客户端一样的使用 `cd` ,除非在主机上你改变了你的工作路径 。你会需要用 `ls` 来确认你的位置 。
在客户端 ,如果你想改变工作路劲 。用 `lcd` 命令 **local change directory**)。相同的 ,用 `lls` 来显示客户端工作目录的内容 。
如果你不喜欢主机工作目录的名字时 ,你该怎么办 ?用 `mkdir` 在主机上创建一个新的文件夹 。或者将整个文件全拷贝到主机
```
put -r thisDir/
```
在主机上创建文件夹和传输文件以及子文件夹是非常快速的 ,能达到硬件的上限 。在网络传输的过程中不会遇到瓶颈 。查看 SFTP 能够使用的功能 ,查看
```
man sftp
```
在我的电脑上我也可以在 windows 虚拟机上用 SFTP ,另一个优势是配置一个虚拟机而不是一个双系统 。这让我能够在系统的 Linux 部分移入或者移出文件 。到目前为止 ,我只用了 windows 的客户端 。
你能够进入到任何通过无线或者 WIFI 连接到你路由器的设备 。暂时 ,我使用一个叫做 [SSHDroid][1] 的应用 ,能够在被动模式下运行 SSH 。换句话来说 ,你能够用你的电脑访问作为主机的 Android 设备 。近来我还发现了另外一个应用 [Admin Hands][2] ,不管你的客户端是桌面还是手机 ,都能使用 SSH 或者 SFTP 操作 。这个应用对于备份和手机分享照片是极好的 。
--------------------------------------------------------------------------------
via: https://opensource.com/article/18/10/ssh-sftp-home-network
作者:[Geg Pittman][a]
选题:[lujun9972](https://github.com/lujun9972)
译者:[singledo](https://github.com/singledo)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://opensource.com/users/greg-p
[1]: https://play.google.com/store/apps/details?id=berserker.android.apps.sshdroid
[2]: https://play.google.com/store/apps/details?id=com.arpaplus.adminhands&hl=en_US

View File

@@ -0,0 +1,70 @@
介绍 Fedora上的 Swift
======
![](https://fedoramagazine.org/wp-content/uploads/2018/09/swift-816x345.jpg)
Swift 是一种使用现代方法构建安全性、性能和软件设计模式的通用编程语言。它旨在成为各种编程项目的最佳语言,从系统编程到桌面应用程序,以及扩展到云服务。阅读更多关于它的内容以及如何在 Fedora 中尝试它。
### 安全、快速、富有表现力
与许多现代编程语言一样Swift 被设计为比基于 C 的语言更安全。例如,变量总是在可以使用之前初始化。检查数组和整数是否溢出。内存自动管理。
Swift 将意图放在语法中。要声明变量,请使用 var 关键字。要声明常量,请使用 let。
Swift 还保证对象永远不会是 nil。实际上尝试使用已知为 nil 的对象将导致编译时错误。当使用 nil 值时,它支持一种称为 **optional** 的机制。optional 可能包含 nil但使用 **?** 运算符可以安全地解包。
一些额外的功能包括:
* 与函数指针统一的闭包
  * 元组和多个返回值
  * 泛型
  * 对范围或集合进行快速而简洁的迭代
  * 支持方法、扩展和协议的结构体
  * 函数式编程模式,例如 map 和 filter
  * 内置强大的错误处理
  * 拥有 do、guard、defer 和 repeat 关键字的高级控制流
### 尝试 Swift
Swift 在 Fedora 28 中可用,包名为 **swift-lang**。安装完成后,运行 swift 并启动 REPL 控制台。
```
$ swift
Welcome to Swift version 4.2 (swift-4.2-RELEASE). Type :help for assistance.
1> let greeting="Hello world!"
greeting: String = "Hello world!"
2> print(greeting)
Hello world!
3> greeting = "Hello universe!"
error: repl.swift:3:10: error: cannot assign to value: 'greeting' is a 'let' constant
greeting = "Hello universe!"
~~~~~~~~ ^
3>
```
Swift 有一个不断发展的社区,特别底,有一个[工作组][1]致力于使其成为一种高效且有力的服务器端编程语言。请访问[主页][2]了解更多参与方式。
图片由 [Uillian Vargas][3] 发布在 [Unsplash][4] 上。
--------------------------------------------------------------------------------
via: https://fedoramagazine.org/introducing-swift-fedora/
作者:[Link Dupont][a]
选题:[lujun9972](https://github.com/lujun9972)
译者:[geekpi](https://github.com/geekpi)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://fedoramagazine.org/author/linkdupont/
[1]: https://swift.org/server/
[2]: http://swift.org
[3]: https://unsplash.com/photos/7oJpVR1inGk?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText
[4]: https://unsplash.com/search/photos/fast?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText

View File

@@ -0,0 +1,101 @@
使用 Python 为你的油箱加油
======
我来介绍一下我是如何使用 Python 来节省成本的。
![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/bulb-light-energy-power-idea.png?itok=zTEEmTZB)
我最近在开一辆烧 93 号汽油的车子。根据汽车制造商的说法,它只需要加 91 号汽油就可以了。然而,在美国只能买到 87 号、89 号、93 号汽油。而我家附近的汽油的物价水平是每增加一号,每加仑就要多付 30 美分,因此如果加 93 号汽油,每加仑就要多花 60 美分。为什么不能节省一些钱呢?
一开始很简单,只需要先加满 93 号汽油,然后在油量表显示油箱半满的时候,用 89 号汽油加满,就得到一整箱 91 号汽油了。但接下来就麻烦了,剩下半箱 91 号汽油加上半箱 93 号汽油,只会变成一箱 92 号汽油,再接下来呢?如果继续算下去,只会越来越混乱。这个时候 Python 就派上用场了。
我的方案是,可以根据汽油的实时状态,不断向油箱中加入 93 号汽油或者 89 号汽油,而最终目标是使油箱内汽油的号数不低于 91。我需要做的是只是通过一些算法来判断新旧汽油混合之后的号数。使用多项式方程或许也可以解决这个问题但如果使用 Python好像只需要进行循环就可以了。
```
#!/usr/bin/env python
# octane.py
o = 93.0
newgas = 93.0 # 这个变量记录上一次加入的汽油号数
i = 1
while i < 21: # 20 次迭代 (加油次数)
if newgas == 89.0: # 如果上一次加的是 89 号汽油,改加 93 号汽油
newgas = 93.0
o = newgas/2 + o/2 # 当油箱半满的时候就加油
else: # 如果上一次加的是 93 号汽油,则改加 89 号汽油
newgas = 89.0
o = newgas/2 + o/2 # 当油箱半满的时候就加油
print str(i) + ': '+ str(o)
i += 1
```
在代码中,我首先将变量 `o`(油箱中的当前混合汽油号数)和变量 `newgas`(上一次加入的汽油号数)的初始值都设为 93然后循环 20 次,也就是分别加入 89 号汽油和 93 号汽油一共 20 次,以保持混合汽油号数稳定。
```
1: 91.0
2: 92.0
3: 90.5
4: 91.75
5: 90.375
6: 91.6875
7: 90.34375
8: 91.671875
9: 90.3359375
10: 91.66796875
11: 90.333984375
12: 91.6669921875
13: 90.3334960938
14: 91.6667480469
15: 90.3333740234
16: 91.6666870117
17: 90.3333435059
18: 91.6666717529
19: 90.3333358765
20: 91.6666679382
```
从以上数据来看,只需要 10 到 15 次循环,汽油号数就比较稳定了,也相当接近 91 号汽油的目标。这种交替混合直到稳定的现象看起来很有趣,每次交替加入同等量的不同号数汽油,都会趋于稳定。实际上,即使加入的 89 号汽油和 93 号汽油的量不同,也会趋于稳定。
因此,我尝试了不同的比例,我认为加入的 93 号汽油需要比 89 号汽油更多一点。在尽量少补充新汽油的情况下,我最终计算到的结果是 89 号汽油要在油箱大约 7/12 满的时候加进去,而 93 号汽油则要在油箱 1/4 满的时候才加进去。
我的循环将会更改成这样:
```
if newgas == 89.0:
newgas = 93.0
o = 3*newgas/4 + o/4
else:
newgas = 89.0
o = 5*newgas/12 + 7*o/12
```
以下是从第十次加油开始的混合汽油号数:
```
10: 92.5122272978
11: 91.0487992571
12: 92.5121998143
13: 91.048783225
14: 92.5121958062
15: 91.048780887
```
如你所见,这个调整会令混合汽油号数始终略高于 91。当然我的油量表并没有 1/12 的刻度,但是 7/12 略小于 5/8我可以近似地计算。
一个更简单地方案是每次都首先加满 93 号汽油,然后在油箱半满时加入 89 号汽油直到耗尽,这可能会是我的常规方案。但就我个人而言,这种方法并不太好,有时甚至会产生一些麻烦。但对于长途旅行来说,这种方案会相对简便一些。有时我也会因为油价突然下跌而购买一些汽油,所以,这个方案是我可以考虑的一系列选项之一。
当然最重要的是:开车不写码,写码不开车!
--------------------------------------------------------------------------------
via: https://opensource.com/article/18/10/python-gas-pump
作者:[Greg Pittman][a]
选题:[lujun9972](https://github.com/lujun9972)
译者:[HankChow](https://github.com/HankChow)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://opensource.com/users/greg-p

View File

@@ -0,0 +1,183 @@
设计更快的网页——第一部分:图片压缩
======
![](https://fedoramagazine.org/wp-content/uploads/2018/02/fasterwebsites1-816x345.jpg)
很多 Web 开发者都希望做出加载速度很快的网页。在移动设备浏览占比越来越大的背景下使用响应式设计使得网站在小屏幕下看起来更漂亮只是其中一个方面。Browser Calories 可以展示网页的加载时间——这不单单关系到用户,还会影响到通过加载速度来进行评级的搜索引擎。这个系列的文章介绍了如何使用 Fedora 提供的工具来给网页“瘦身”。
### 准备工作
在你开始缩减网页之前,你需要明确核心问题所在。为此,你可以使用 [Browserdiet][1]. 这是一个浏览器插件,适用于 Firefox, Opera, Chrome 和其它浏览器。它会对打开的网页进行性能分析,这样你就可以知道应该从哪里入手来缩减网页。
然后,你需要一些用来处理的页面。下面的例子是针对 [getferoda.org][2] 的测试截图。一开始,它看起来非常简单,也符合响应式设计。
![Browser Diet - getfedora.org 的评分][3]
然而BroserDiet 的网页分析表明,这个网页需要加载 1.8MB 的文件。所以,我们现在有活干了!
### Web 优化
网页中包含 281 KB 的 JavaScript 文件203 KB 的 CSS 文件,还有 1.2 MB 的图片。我们先从最严重的问题——图片开始入手。为了解决问题,你需要的工具集有 GIMP, ImageMagick 和 optipng. 你可以使用如下命令轻松安装它们:
```
sudo dnf install gimp imagemagick optipng
```
比如,我们先拿到这个 6.4 KB 的[文件][4]
![][4]
首先,使用 file 命令来获取这张图片的一些基本信息:
```
$ file cinnamon.png
cinnamon.png: PNG image data, 60 x 60, 8-bit/color RGBA, non-interlaced
```
这张只由白色和灰色构成的图片使用 8 位 / RGBA 模式来存储。这种方式并没有那么高效。
使用 GIMP你可以为这张图片设置一个更合适的颜色模式。在 GIMP 中打开 cinnamon.png. 然后,在“图片 > 模式”菜单中将其设置为“灰度模式”。将这张图片以 PNG 格式导出。导出时使用压缩因子 9导出对话框中的其它配置均使用默认选项。
```
$ file cinnamon.png
cinnamon.png: PNG image data, 60 x 60, 8-bit gray+alpha, non-interlaced
```
输出显示,现在这个文件现在处于 8 位 / 灰阶+aplha 模式。文件大小从 6.4 KB 缩小到了 2.8 KB. 这已经是原来大小的 43.75% 了。但是,我们能做的还有很多!
你可以使用 ImageMagick 工具来查看这张图片的更多信息。
```
$ identify cinnamon2.png
cinnamon.png PNG 60x60 60x60+0+0 8-bit Grayscale Gray 2831B 0.000u 0:00.000
```
它告诉你,这个文件的大小为 2831 字节。我们回到 GIMP重新导出文件。在导出对话框中取消存储时间戳和 alpha 通道色值,来让文件更小一点。现在文件输出显示:
```
$ identify cinnamon.png
cinnamon.png PNG 60x60 60x60+0+0 8-bit Grayscale Gray 2798B 0.000u 0:00.000
```
下面,用 optipng 来无损优化你的 PNG 图片。具有相似功能的工具有很多,包括 **advdef**(这是 advancecomp 的一部分),**pngquant** 和 **pngcrush**
对你的文件运行 optipng. 注意,这个操作会覆盖你的原文件:
```
$ optipng -o7 cinnamon.png
** Processing: cinnamon.png
60x60 pixels, 2x8 bits/pixel, grayscale+alpha
Reducing image to 8 bits/pixel, grayscale
Input IDAT size = 2720 bytes
Input file size = 2812 bytes
Trying:
zc = 9 zm = 8 zs = 0 f = 0 IDAT size = 1922
zc = 9 zm = 8 zs = 1 f = 0 IDAT size = 1920
Selecting parameters:
zc = 9 zm = 8 zs = 1 f = 0 IDAT size = 1920
Output IDAT size = 1920 bytes (800 bytes decrease)
Output file size = 2012 bytes (800 bytes = 28.45% decrease)
```
-o7 选项处理起来最慢,但最终效果最好。于是你又将文件缩小了 800 字节,现在它只有 2012 字节了。
要压缩文件夹下的所有 PNG可以使用这个命令
```
$ optipng -o7 -dir=<directory> *.png
```
-dir 选项用来指定输出文件夹。如果不加这个选项optipng 会覆盖原文件。
### 选择正确的文件格式
当涉及到在互联网中使用的图片时,你可以选择:
+ [JPG 或 JPEG][9]
+ [GIF][10]
+ [PNG][11]
+ [aPNG][12]
+ [JPG-LS][13]
+ [JPG 2000 或 JP2][14]
+ [SVG][15]
JPG-LS 和 JPG 2000 没有得到广泛使用。只有一部分数码相机支持这些格式所以我们可以忽略它们。aPNG 是动态的 PNG 格式,也没有广泛使用。
可以通过更改压缩率或者使用其它文件格式来节省下更多字节。我们无法在 GIMP 中应用第一种方法,因为现在的图片已经使用了最高的压缩率了。因为我们的图片中不再包含 [aplha 通道][5],你可以使用 JPG 类型来替代 PNG. 现在使用默认值90% 质量——你可以将它减小至 85%,但这样会导致可见的叠影。这样又省下一些字节:
```
$ identify cinnamon.jpg
cinnamon.jpg JPEG 60x60 60x60+0+0 8-bit sRGB 2676B 0.000u 0:00.000
```
只将这张图转成正确的色域,并使用 JPG 作为文件格式,就可以将它从 23 KB 缩小到 12.3 KB减少了近 50%.
#### PNG vs JPG: 质量和压缩率
那么,剩下的文件我们要怎么办呢?除了 Fedora “风味”图标和四个特性图标之外,此方法适用于所有其他图片。我们能够处理的图片都有一个白色的背景。
PNG 和 JPG 的一个主要区别在于JPG 没有 alpha 通道。所以,它没有透明度选项。如果你使用 JPG 并为它添加白色背景,你可以将文件从 40.7 KB 缩小至 28.3 KB.
现在又有了四个可以处理的图片:背景图。对于灰色背景,你可以再次使用灰阶模式。对更大的图片,我们就可以节省下更多的空间。它从 216.2 KB 缩小到了 51 KB——基本上只有原图的 25% 了。整体下来,你把这些图片从 481.1 KB 缩小到了 191.5 KB——只有一开始的 39.8%.
#### 质量 vs 大小
PNG 和 JPG 的另外一个区别在于质量。PNG 是一种无损压缩光栅图形格式。但是 JPG 虽然使用压缩来缩小体积,可是这会影响到质量。不过,这并不意味着你不应该使用 JPG只是你需要在文件大小和质量中找到一个平衡。
### 成就
这就是第一部分的结尾了。在使用上述技术后,得到的结果如下:
![][6]
你将一开始 1.2 MB 的图片体积缩小到了 488.9 KB. 只需通过 optipng 进行优化,就可以达到之前体积的三分之一。这可能使得页面更快地加载。不过,要是使用蜗牛到超音速来对比,这个速度还没到达赛车的速度呢!
最后,你可以在 [Google Insights][7] 中查看结果,例如:
![][8]
在移动端部分,这个页面的得分提升了 10 分,但它依然处于“中等”水平。对于桌面端,结果看起来完全不同,从 62/100 分提升至了 91/100 分,等级也达到了“好”的水平。如我们之前所说的,这个测试并不意味着我们的工作就做完了。通过参考这些分数可以让你朝着正确的方向前进。请记住,你正在为用户体验来进行优化,而不是搜索引擎。
--------------------------------------------------------------------------------
via: https://fedoramagazine.org/design-faster-web-pages-part-1-image-compression/
作者:[Sirko Kemter][a]
选题:[lujun9972][b]
译者:[StdioA](https://github.com/StdioA)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://fedoramagazine.org/author/gnokii/
[b]: https://github.com/lujun9972
[1]: https://browserdiet.com/calories/
[2]: http://getfedora.org
[3]: https://fedoramagazine.org/wp-content/uploads/2018/02/ff-addon-diet.jpg
[4]: https://getfedora.org/static/images/cinnamon.png
[5]: https://www.webopedia.com/TERM/A/alpha_channel.html
[6]: https://fedoramagazine.org/wp-content/uploads/2018/02/ff-addon-diet-i.jpg
[7]: https://developers.google.com/speed/pagespeed/insights/?url=getfedora.org&tab=mobile
[8]: https://fedoramagazine.org/wp-content/uploads/2018/02/PageSpeed_Insights.png
[9]: https://en.wikipedia.org/wiki/JPEG
[10]: https://en.wikipedia.org/wiki/GIF
[11]: https://en.wikipedia.org/wiki/Portable_Network_Graphics
[12]: https://en.wikipedia.org/wiki/APNG
[13]: https://en.wikipedia.org/wiki/JPEG_2000
[14]: https://en.wikipedia.org/wiki/JPEG_2000
[15]: https://en.wikipedia.org/wiki/Scalable_Vector_Graphics

View File

@@ -0,0 +1,123 @@
Minikube入门笔记本上的Kubernetes
======
运行Minikube的分步指南。
![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/cube_innovation_process_block_container.png?itok=vkPYmSRQ)
在[Hello Minikube][1]教程页面上Minikube被宣传为基于Docker运行Kubernetes的一种简单方法。 虽然该文档非常有用但它主要是为MacOS编写的。 你可以深入挖掘在Windows或某个Linux发行版上的使用说明但它们不是很清楚。 许多文档都是针对Debian / Ubuntu用户的比如[安装Minikube的驱动程序][2]。
### 先决条件
1. 你已经[安装了Docker][3]。
2. 你的计算机是一个RHEL / CentOS / 基于Fedora的工作站。
3. 你已经[安装了正常运行的KVM2虚拟机管理程序][4]。
4. 你有一个运行的**docker-machine-driver-kvm2**。 以下命令将安装驱动程序:
```
curl -Lo docker-machine-driver-kvm2 https://storage.googleapis.com/minikube/releases/latest/docker-machine-driver-kvm2 \
chmod +x docker-machine-driver-kvm2 \
&& sudo cp docker-machine-driver-kvm2 /usr/local/bin/ \
&& rm docker-machine-driver-kvm2
```
### 下载安装和启动Minikube
1. 为你要即将下载的两个文件创建一个目录,两个文件分别是:[minikube][5]和[kubectl][6]。
2. 打开终端窗口并运行以下命令来安装minikube。
```
curl -Lo minikube https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
```
请注意minikube版本例如minikube-linux-amd64可能因计算机的规格而有所不同。
3. **chmod**加执行权限。
```
chmod +x minikube
```
4. 将文件移动到**/usr/local/bin**路径下,以便你能将其作为命令运行。
```
mv minikube /usr/local/bin
```
5. 使用以下命令安装kubectl类似于minikube的安装过程
```
curl -Lo kubectl https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl
```
使用**curl**命令确定最新版本的Kubernetes。
6. **chmod**给kubectl加执行权限。
```
chmod +x kubectl
```
7. 将kubectl移动到**/usr/local/bin**路径下作为命令运行。
```
mv kubectl /usr/local/bin
```
8. 运行**minikube start**命令。 为此,你需要有虚拟机管理程序。 我使用过KVM2你也可以使用Virtualbox。 确保是用户而不是root身份运行以下命令以便为用户而不是root存储配置。
```
minikube start --vm-driver=kvm2
```
这可能需要一段时间,等一会。
9. Minikube应该下载并开始。 使用以下命令确保成功。
```
cat ~/.kube/config
```
10. 执行以下命令以运行Minikube作为上下文。 上下文决定了kubectl与哪个集群交互。 你可以在~/.kube/config文件中查看所有可用的上下文。
```
kubectl config use-context minikube
```
11. 再次查看**config** 文件以检查Minikube是否存在上下文。
```
cat ~/.kube/config
```
12. 最后运行以下命令打开浏览器查看Kubernetes仪表板。
```
minikube dashboard
```
本指南旨在使RHEL / Fedora / CentOS操作系统用户操作更轻松。
现在Minikube已启动并运行请阅读[通过Minikube在本地运行Kubernetes][7]这篇官网教程开始使用它。
--------------------------------------------------------------------------------
via: https://opensource.com/article/18/10/getting-started-minikube
作者:[Bryant Son][a]
选题:[lujun9972][b]
译者:[Flowsnow](https://github.com/Flowsnow)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:
[b]: https://github.com/lujun9972
[1]: https://kubernetes.io/docs/tutorials/hello-minikube
[2]: https://github.com/kubernetes/minikube/blob/master/docs/drivers.md
[3]: https://docs.docker.com/install
[4]: https://github.com/kubernetes/minikube/blob/master/docs/drivers.md#kvm2-driver
[5]: https://github.com/kubernetes/minikube/releases
[6]: https://kubernetes.io/docs/tasks/tools/install-kubectl/#install-kubectl-binary-using-curl
[7]: https://kubernetes.io/docs/setup/minikube