Merge pull request #29 from LCTT/master

Sync from LCTT
This commit is contained in:
perfiffer
2022-07-24 09:52:33 +08:00
committed by GitHub
453 changed files with 44865 additions and 12385 deletions

View File

@@ -0,0 +1,267 @@
[#]: collector: (lujun9972)
[#]: translator: (hanszhao80)
[#]: reviewer: (wxy)
[#]: publisher: (wxy)
[#]: url: (https://linux.cn/article-14792-1.html)
[#]: subject: (Djinn: A Code Generator and Templating Language Inspired by Jinja2)
[#]: via: (https://theartofmachinery.com/2021/01/01/djinn.html)
[#]: author: (Simon Arneaud https://theartofmachinery.com)
Djinn一个受 Jinja2 启发的代码生成器和模板语言
======
![](https://img.linux.net.cn/data/attachment/album/202207/04/101711nq2we7z7x7wz2z7e.jpg)
代码生成器是非常有用的工具。我有时使用 [jinja2][1] 的命令行版本来生成高度冗余的配置文件和其他文本文件但它在转换数据方面功能有限。显然Jinja2 的作者有不同的想法,而我想要类似于 <ruby>列表推导<rt>list comprehensions</rt></ruby> 或 D 语言的 <ruby>可组合范围<rt>composable range</rt></ruby> 算法之类的东西。
我决定制作一个类似于 Jinja2 的工具,但让我可以通过使用范围算法转换数据来生成复杂的文件。这个想法非常简单:一个直接用 D 语言代码重写的模板语言。因为它 _就是_ D 语言,它可以支持 D 语言所能做的一切。我想要一个独立的代码生成器,但是由于 [D 语言的 `mixin` 特性][2]同样的模板语言可以作为嵌入式模板语言工作例如Web 应用程序中的 HTML。有关该技巧的更多信息请参阅 [这篇关于在编译时使用 mixins 将 Brainfuck 转换为 D 和机器代码的文章][3]。
像往常一样,[源码在 GitLab 上][4]。[这篇文章中的例子也可以在这里找到][5]。
### Hello world 示例
这是一个演示这个想法的例子:
```
Hello [= retro("dlrow") ]!
[: enum one = 1; :]
1 + 1 = [= one + one ]
```
`[= some_expression ]` 类似于 Jinja2 中的 `{{ some_expression }}`,它在输出中呈现一个值。`[: some_statement; :]` 类似于 `{% some_statement %}` ,用于执行完整的代码语句。我更改了语法,因为 D 也大量使用花括号,并且将两者混合使模板难以阅读(还有一些特殊的非 D 指令,比如 `include`,它们被包裹在 `[<``>]` 中)。
如果你将上面的内容保存到一个名为 `hello.txt.dj` 的文件中并运行 `djinn` 命令行工具,你会得到一个名为 `hello.txt` 的文件,其中包含你可能猜到的内容:
```
Hello world!
1 + 1 = 2
```
如果你使用过 Jinja2你可能想知道第二行发生了什么。Djinn 有一个简化格式化和空格处理的特殊规则:如果源代码行包含 `[:` 语句或 `[<` 指令但不包含任何非空格输出,则整行都会被忽略输出。空行则仍会原样呈现。
### 生成数据
好的,现在来讲一些更实用的东西:生成 CSV 数据。
```
x,f(x)
[: import std.mathspecial;
foreach (x; iota(-1.0, 1.0, 0.1)) :]
[= "%0.1f,%g", x, normalDistribution(x) ]
```
一个 `[=``]` 对可以包含多个用逗号分隔的表达式。如果第一个表达式是一个由双引号包裹的字符串,则会被解释为 [格式化字符串][6]。下面是输出结果:
```
x,f(x)
-1.0,0.158655
-0.9,0.18406
-0.8,0.211855
-0.7,0.241964
-0.6,0.274253
-0.5,0.308538
-0.4,0.344578
-0.3,0.382089
-0.2,0.42074
-0.1,0.460172
0.0,0.5
0.1,0.539828
0.2,0.57926
0.3,0.617911
0.4,0.655422
0.5,0.691462
0.6,0.725747
0.7,0.758036
0.8,0.788145
0.9,0.81594
```
### 制作图片
这个例子展示了一个图片的生成过程。[经典的 Netpbm 图像库定义了一堆图像格式][7],其中一些是基于文本的。例如,这是一个 3 x 3 向量的图像:
```
P2 # PGM 格式标识
3 3 # 宽和高
7 # 代表纯白色的值0 代表黑色)
7 0 7
0 0 0
7 0 7
```
你可以将上述文本保存到名为 `cross.pgm` 之类的文件中,很多图像工具都知道如何解析它。下面是一些 Djinn 代码,它以相同的格式生成 [Mandelbrot 集][8] 分形:
```
[:
import std.complex;
enum W = 640;
enum H = 480;
enum kMaxIter = 20;
ubyte mb(uint x, uint y)
{
const c = complex(3.0 * (x - W / 1.5) / W, 2.0 * (y - H / 2.0) / H);
auto z = complex(0.0);
ubyte ret = kMaxIter;
while (abs(z) <= 2 && --ret) z = z * z + c;
return ret;
}
:]
P2
[= W ] [= H ]
[= kMaxIter ]
[: foreach (y; 0..H) :]
[= "%(%s %)", iota(W).map!(x => mb(x, y)) ]
```
生成的文件大约为 800 kB但它可以很好地被压缩为 PNG
```
$ # 使用 GraphicsMagick 进行转换
$ gm convert mandelbrot.pgm mandelbrot.png
```
结果如下:
![][9]
### 解决谜题
这里有一个谜题:
![][10]
一个 5 行 5 列的网格需要用 1 到 5 的数字填充,每个数字在每一行中限使用一次,在每列中限使用一次(即,制作一个 5 行 5 列的<ruby>拉丁方格<rt>Latin square</rt></ruby>)。相邻单元格中的数字还必须满足所有 `>` 大于号表示的不等式。
[几个月前我使用了 <ruby>线性规划<rt>linear programming</rt></ruby>LP][11]。线性规划问题是具有线性约束的连续变量系统。这次我将使用<ruby>混合整数线性规划<rt>mixed integer linear programming</rt></ruby>MILP它通过允许整数约束变量来归纳 LP。事实证明这足以成为 NP 完备的,而 MILP 恰好可以很好地模拟这个谜题。
在上一篇文章中,我使用 Julia 库 JuMP 来帮助解决这个问题。这次我将使用 [CPLEX基于文本的格式][12],它受到多个 LP 和 MILP 求解器的支持(如果需要,可以通过现成的工具轻松转换为其他格式)。这是上一篇文章中 CPLEX 格式的 LP
```
Minimize
obj: v
Subject To
ptotal: pr + pp + ps = 1
rock: 4 ps - 5 pp - v <= 0
paper: 5 pr - 8 ps - v <= 0
scissors: 8 pp - 4 pr - v <= 0
Bounds
0 <= pr <= 1
0 <= pp <= 1
0 <= ps <= 1
End
```
CPLEX 格式易于阅读,但复杂度高的问题需要大量变量和约束来建模,这使得手工编码既痛苦又容易出错。有一些特定领域的语言,例如 [ZIMPL][13],用于以高级方式描述 MILP 和 LP。对于许多问题来说它们非常酷但最终它们不如具有良好库如 JuMP支持的通用语言或使用 D 语言的代码生成器那样富有表现力。
我将使用两组变量来模拟这个谜题:`v_{r,c}``i_{r,c,v}``v_{r,c}` 将保存 r 行 c 列单元格的值(从 1 到 5`i_{r,c,v}` 是一个二进制指示器,如果 r 行 c 列的单元格的值是 v则该指示器值为 1否则为 0。这两组变量是网格的冗余表示但第一种表示更容易对不等式约束进行建模而第二种表示更容易对唯一性约束进行建模。我只需要添加一些额外的约束来强制这两个表示是一致的。但首先让我们从每个单元格必须只有一个值的基本约束开始。从数学上讲这意味着给定行和列的所有指示器都必须为 0但只有一个值为 1 的例外。这可以通过以下等式强制约束:
```
[i_{r,c,1} + i_{r,c,2} + i_{r,c,3} + i_{r,c,4} + i_{r,c,5} = 1]
```
可以使用以下 Djinn 代码生成对所有行和列的 CPLEX 约束:
```
\ 单元格只有一个值
[:
foreach (r; iota(N))
foreach (c; iota(N))
:]
[= "%-(%s + %)", vs.map!(v => ivar(r, c, v)) ] = 1
[::]
```
`ivar()` 是一个辅助函数,它为我们提供变量名为 `i` 的字符串标识符,而 `vs` 存储从 1 到 5 的数字以方便使用。行和列内唯一性的约束完全相同,但在 `i` 的其他两个维度上迭代。
为了使变量组 `i` 与变量组 `v` 保持一致,我们需要如下约束(请记住,变量组 `i` 中只有一个元素的值是非零的):
```
[i_{r,c,1} + 2i_{r,c,2} + 3i_{r,c,3} + 4i_{r,c,4} + 5i_{r,c,5} = v_{r,c}]
```
CPLEX 要求所有变量都位于左侧,因此 Djinn 代码如下所示:
```
\ 连接变量组 i 和变量组 v
[:
foreach (r; iota(N))
foreach (c; iota(N))
:]
[= "%-(%s + %)", vs.map!(v => text(v, ' ', ivar(r, c, v))) ] - [= vvar(r,c) ] = 0
[::]
```
不等符号相邻的和左下角值为为 4 单元格的约束写起来都很简单。剩下的便是将指示器变量声明为二进制,并为变量组 `v` 设置边界。加上变量的边界,总共有 150 个变量和 111 个约束 [你可以在仓库中看到完整的代码][14]。
[GNU 线性规划工具集][15] 有一个命令行工具可以解决这个 CPLEX MILP。不幸的是它的输出是一个包含了所有内容的体积很大的转储所以我使用 awk 命令来提取需要的内容:
```
$ time glpsol --lp inequality.lp -o /dev/stdout | awk '/v[0-9][0-9]/ { print $2, $4 }' | sort
v00 1
v01 3
v02 2
v03 5
v04 4
v10 2
v11 5
v12 4
v13 1
v14 3
v20 3
v21 1
v22 5
v23 4
v24 2
v30 5
v31 4
v32 3
v33 2
v34 1
v40 4
v41 2
v42 1
v43 3
v44 5
real 0m0.114s
user 0m0.106s
sys 0m0.005s
```
这是在原始网格中写出的解决方案:
![][16]
这些例子只是用来玩的但我相信你已经明白了。顺便说一下Djinn 代码仓库的 `README.md` 文件本身是使用 Djinn 模板生成的。
正如我所说Djinn 也可以用作嵌入在 D 语言代码中的编译期模板语言。我最初只是想要一个代码生成器,得益于 D 语言的元编程功能,这算是一个额外获得的功能。
--------------------------------------------------------------------------------
via: https://theartofmachinery.com/2021/01/01/djinn.html
作者:[Simon Arneaud][a]
选题:[lujun9972][b]
译者:[hanszhao80](https://github.com/hanszhao80)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://theartofmachinery.com
[b]: https://github.com/lujun9972
[1]: https://jinja2docs.readthedocs.io/en/stable/
[2]: https://dlang.org/articles/mixin.html
[3]: https://theartofmachinery.com/2017/12/31/compile_time_brainfuck.html
[4]: https://gitlab.com/sarneaud/djinn
[5]: https://gitlab.com/sarneaud/djinn/-/tree/v0.1.0/examples
[6]: https://dlang.org/phobos/std_format.html#format-string
[7]: http://netpbm.sourceforge.net/doc/#formats
[8]: https://en.wikipedia.org/wiki/Mandelbrot_set
[9]: https://theartofmachinery.com/images/djinn/mandelbrot.png
[10]: https://theartofmachinery.com/images/djinn/inequality.svg
[11]: https://theartofmachinery.com/2020/05/21/glico_weighted_rock_paper_scissors.html
[12]: http://lpsolve.sourceforge.net/5.0/CPLEX-format.htm
[13]: https://zimpl.zib.de/
[14]: https://gitlab.com/sarneaud/djinn/-/tree/v0.1.0/examples/inequality.lp.dj
[15]: https://www.gnu.org/software/glpk/
[16]: https://theartofmachinery.com/images/djinn/inequality_solution.svg

View File

@@ -0,0 +1,547 @@
[#]: subject: "A hands-on tutorial for using the GNU Project Debugger"
[#]: via: "https://opensource.com/article/21/1/gnu-project-debugger"
[#]: author: "Stephan Avenwedde https://opensource.com/users/hansic99"
[#]: collector: "lkxed"
[#]: translator: "Maisie-x"
[#]: reviewer: "wxy"
[#]: publisher: "wxy"
[#]: url: "https://linux.cn/article-14853-1.html"
手把手教你使用 GNU 调试器
======
![](https://img.linux.net.cn/data/attachment/album/202207/22/122211c2fgo53m9tw3xe2p.jpg)
> GNU 调试器是一个发现程序缺陷的强大工具。
如果你是一个程序员,想在你的软件增加某些功能,你首先考虑实现它的方法:例如写一个方法、定义一个类,或者创建新的数据类型。然后你用编译器或解释器可以理解的编程语言来实现这个功能。但是,如果你觉得你所有代码都正确,但是编译器或解释器依然无法理解你的指令怎么办?如果软件大多数情况下都运行良好,但是在某些环境下出现缺陷怎么办?这种情况下,你得知道如何正确使用调试器找到问题的根源。
<ruby>GNU 调试器<rt>GNU Project Debugger</rt></ruby>[GDB][2]是一个发现项目缺陷的强大工具。它通过追踪程序运行过程中发生了什么来帮助你发现程序错误或崩溃的原因。LCTT 校注GDB 全程是“GNU Project Debugger”即 “GNU 项目调试器”但是通常我们简称为“GNU 调试器”)
本文是 GDB 基本用法的实践教程。请跟随示例,打开命令行并克隆此仓库:
```
git clone https://github.com/hANSIc99/core_dump_example.git
```
### 快捷方式
GDB 的每条命令都可以缩短。例如:显示设定的断点的 `info break` 命令可以被缩短为 `i break`。你可能在其他地方看到过这种缩写,但在本文中,为了清晰展现使用的函数,我将所写出整个命令。
### 命令行参数
你可以将 GDB 附加到每个可执行文件。进入你克隆的仓库(`core_dump_example`),运行 `make` 进行编译。你现在能看到一个名为 `coredump` 的可执行文件。(更多信息,请参考我的文章《[创建和调试 Linux 的转储文件][3]》。)
要将 GDB 附加到这个可执行文件,请输入: `gdb coredump`
你的输出应如下所示:
![gdb coredump output][4]
返回结果显示没有找到调试符号。
调试信息是<ruby>目标文件<rt>object file</rt></ruby>(可执行文件)的组成部分,调试信息包括数据类型、函数签名、源代码和操作码之间的关系。此时,你有两种选择:
* 继续调试汇编代码(参见下文“无符号调试”)
* 使用调试信息进行编译,参见下一节内容
### 使用调试信息进行编译
为了在二进制文件中包含调试信息,你必须重新编译。打开 `Makefile`,删除第 9 行的注释标签(`#`)后重新编译:
```
CFLAGS =-Wall -Werror -std=c++11 -g
```
`-g` 告诉编译器包含调试信息。运行 `make clean`,接着运行 `make`,然后再次调用 GDB。你得到如下输出后就可以调试代码了
![GDB output with symbols][5]
新增的调试信息会增加可执行文件的大小。在这种情况下,执行文件增加了 2.5 倍(从 26,088 字节 增加到 65,480 字节)。
输入 `run -c1`,使用 `-c1` 开关启动程序。当程序运行到达 `State_4` 时将崩溃:
![gdb output crash on c1 switch][6]
你可以检索有关程序的其他信息,`info source` 命令提供了当前文件的信息:
![gdb info source output][7]
* 101 行代码
* 语言: C++
* 编译器(版本、调优、架构、调试标志、语言标准)
* 调试格式:[DWARF 2][8]
* 没有预处理器宏指令(使用 GCC 编译时,宏仅在 [使用 -g3 标志编译][9] 时可用)。
`info shared` 命令打印了动态库列表机器在虚拟地址空间的地址,它们在启动时被加载到该地址,以便程序运行:
![gdb info shared output][10]
如果你想了解 Linux 中的库处理方式,请参见我的文章 [在 Linux 中如何处理动态库和静态库][11]。
### 调试程序
你可能已经注意到,你可以在 GDB 中使用 `run` 命令启动程序。`run` 命令接受命令行参数,就像从控制台启动程序一样。`-c1` 开关会导致程序在第 4 阶段崩溃。要从头开始运行程序,你不用退出 GDB只需再次运行 `run` 命令。如果没有 `-c1` 开关,程序将陷入死循环,你必须使用 `Ctrl+C` 来结束死循环。
![gdb output stopped by sigint][12]
你也可以一步一步运行程序。在 C/C++ 中,入口是 `main` 函数。使用 `list main` 命令打开显示 `main` 函数的部分源代码:
![gdb output list main][13]
`main` 函数在第 33 行,因此可以输入 `break 33` 在 33 行添加断点:
![gdb output breakpoint added][14]
输入 `run` 运行程序。正如预期的那样,程序在 `main` 函数处停止。输入 `layout src` 并排查看源代码:
![gdb output break at main][15]
你现在处于 GDB 的文本用户界面TUI模式。可以使用键盘向上和向下箭头键滚动查看源代码。
GDB 高亮显示当前执行行。你可以输入 `next``n`命令逐行执行命令。如果你没有指定新的命令GBD 会执行上一条命令。要逐行运行代码,只需按回车键。
有时,你会发现文本的输出有点显示不正常:
![gdb output corrupted][16]
如果发生这种情况,请按 `Ctrl+L` 重置屏幕。
使用 `Ctrl+X+A` 可以随时进入和退出 TUI 模式。你可以在手册中找到 [其他的键绑定][17] 。
要退出 GDB只需输入 `quit`
### 设置监察点
这个示例程序的核心是一个在无限循环中运行的状态机。`n_state` 变量枚举了当前所有状态:
```
while(true){
        switch(n_state){
        case State_1:
                std::cout << "State_1 reached" << std::flush;
                n_state = State_2;
                break;
        case State_2:
                std::cout << "State_2 reached" << std::flush;
                n_state = State_3;
                break;
       
        (.....)
       
        }
}
```
如果你希望当 `n_state` 的值为 `State_5` 时停止程序。为此,请在 `main` 函数处停止程序并为 `n_state` 设置监察点:
```
watch n_state == State_5
```
只有当所需的变量在当前上下文中可用时,使用变量名设置监察点才有效。
当你输入 `continue` 继续运行程序时,你会得到如下输出:
![gdb output stop on watchpoint_1][18]
如果你继续运行程序,当监察点表达式评估为 `false` 时 GDB 将停止:
![gdb output stop on watchpoint_2][19]
你可以为一般的值变化、特定的值、读取或写入时来设置监察点。
### 更改断点和监察点
输入 `info watchpoints` 打印先前设置的监察点列表:
![gdb output info watchpoints][20]
#### 删除断点和监察点
如你所见,监察点就是数字。要删除特定的监察点,请先输入 `delete` 后输入监察点的编号。例如,我的监察点编号为 2要删除此监察点输入 `delete 2`
*注意:* 如果你使用 `delete` 而没有指定数字,*所有* 监察点和断点将被删除。
这同样适用于断点。在下面的截屏中,我添加了几个断点,输入 `info breakpoint` 打印断点列表:
![gdb output info breakpoints][21]
要删除单个断点,请先输入 `delete` 后输入断点的编号。另外一种方式:你可以通过指定断点的行号来删除断点。例如,`clear 78` 命令将删除第 78 行设置的断点号 7。
#### 禁用或启用断点和监察点
除了删除断点或监察点之外,你可以通过输入 `disable`,后输入编号禁用断点或监察点。在下文中,断点 3 和 4 被禁用,并在代码窗口中用减号标记:
![disabled breakpoints][22]
也可以通过输入类似 `disable 2 - 4` 修改某个范围内的断点或监察点。如果要重新激活这些点,请输入 `enable`,然后输入它们的编号。
### 条件断点
首先,输入 `delete` 删除所有断点和监察点。你仍然想使程序停在 `main` 函数处,如果你不想指定行号,可以通过直接指明该函数来添加断点。输入 `break main` 从而在 `main` 函数处添加断点。
输入 `run` 从头开始运行程序,程序将在 `main` 函数处停止。
`main` 函数包括变量 `n_state_3_count`,当状态机达到状态 3 时,该变量会递增。
基于 `n_state_3_count` 的值添加一个条件断点,请输入:
```
break 54 if n_state_3_count == 3
```
![Set conditional breakpoint][23]
继续运行程序。程序将在第 54 行停止之前运行状态机 3 次。要查看 `n_state_3_count` 的值,请输入:
```
print n_state_3_count
```
![print variable][24]
#### 使断点成为条件断点
你也可以使现有断点成为条件断点。用 `clear 54` 命令删除最近添加的断点,并通过输入 `break 54` 命令添加一个简单的断点。你可以输入以下内容使此断点成为条件断点:
```
condition 3 n_state_3_count == 9
```
`3` 指的是断点编号。
![modify breakpoint][25]
#### 在其他源文件中设置断点
如果你的程序由多个源文件组成,你可以在行号前指定文件名来设置断点,例如,`break main. cpp:54`
#### 捕捉点
除了断点和监察点之外,你还可以设置捕获点。捕获点适用于执行系统调用、加载共享库或引发异常等事件。
要捕获用于写入 STDOUT 的 `write` 系统调用,请输入:
```
catch syscall write
```
![catch syscall write output][26]
每当程序写入控制台输出时GDB 将中断执行。
在手册中,你可以找到一整章关于 [断点、监察点和捕捉点][27] 的内容。
### 评估和操作符号
`print` 命令可以打印变量的值。一般语法是 `print <表达式> <值>`。修改变量的值,请输入:
```
set variable <variable-name> <new-value>.
```
在下面的截屏中,我将变量 `n_state_3_count` 的值设为 `123`
![catch syscall write output][28]
`/x` 表达式以十六进制打印值;使用 `&` 运算符,你可以打印虚拟地址空间内的地址。
如果你不确定某个符号的数据类型,可以使用 `whatis` 来查明。
![whatis output][29]
如果你要列出 `main` 函数范围内可用的所有变量,请输入 `info scope main` :
![info scope main output][30]
`DW_OP_fbreg` 值是指基于当前子程序的堆栈偏移量。
或者,如果你已经在一个函数中并且想要列出当前堆栈帧上的所有变量,你可以使用 `info locals` :
![info locals output][31]
查看手册以了解更多 [检查符号][32] 的内容。
### 附加调试到一个正在运行的进程
`gdb attach <进程 ID>` 命令允许你通过指定进程 IDPID附加到一个已经在运行的进程进行调试。幸运的是`coredump` 程序将其当前 PID 打印到屏幕上,因此你不必使用 [ps][33] 或 [top][34] 手动查找 PID。
启动 `coredump` 应用程序的一个实例:
```
./coredump
```
![coredump application][35]
操作系统显示 PID 为 `2849`。打开一个单独的控制台窗口,移动到 `coredump` 应用程序的根目录,然后用 GDB 附加到该进程进行调试:
```
gdb attach 2849
```
![attach GDB to coredump][36]
当你用 GDB 附加到进程时GDB 会立即停止进程运行。输入 `layout src``backtrace` 来检查调用堆栈:
![layout src and backtrace output][37]
输出显示在 `main.cpp` 第 92 行调用 `std::this_thread::sleep_for<...>(. ..)` 函数时进程中断。
只要你退出 GDB该进程将继续运行。
你可以在 GDB 手册中找到有关 [附加调试正在运行的进程][38] 的更多信息。
#### 在堆栈中移动
在命令窗口,输入 `up` 两次可以在堆栈中向上移动到 `main.cpp` :
![moving up the stack to main.cpp][39]
通常,编译器将为每个函数或方法创建一个子程序。每个子程序都有自己的栈帧,所以在栈帧中向上移动意味着在调用栈中向上移动。
你可以在手册中找到有关 [堆栈计算][40] 的更多信息。
#### 指定源文件
当调试一个已经在运行的进程时GDB 将在当前工作目录中寻找源文件。你也可以使用 [目录命令][41] 手动指定源目录。
### 评估转储文件
阅读 [创建和调试 Linux 的转储文件][42] 了解有关此主题的信息。
参考文章太长,简单来说就是:
1. 假设你使用的是最新版本的 Fedora
2. 使用 `-c1` 开关调用 coredump`coredump -c1`
![Crash meme][44]
3. 使用 GDB 加载最新的转储文件:`coredumpctl debug`
4. 打开 TUI 模式并输入 `layout src`
![coredump output][45]
`backtrace` 的输出显示崩溃发生在距离 `main.cpp` 五个栈帧之外。回车直接跳转到 `main.cpp` 中的错误代码行:
![up 5 output][46]
看源码发现程序试图释放一个内存管理函数没有返回的指针。这会导致未定义的行为并引起 `SIGABRT`
### 无符号调试
如果没有源代码,调试就会变得非常困难。当我在尝试解决逆向工程的挑战时,我第一次体验到了这一点。了解一些 [汇编语言][47] 的知识会很有用。
我们用例子看看它是如何运行的。
找到根目录,打开 `Makefile`,然后像下面一样编辑第 9 行:
```
CFLAGS =-Wall -Werror -std=c++11 #-g
```
要重新编译程序,先运行 `make clean`,再运行 `make`,最后启动 GDB。该程序不再有任何调试符号来引导源代码的走向。
![no debugging symbols][48]
`info file` 命令显示二进制文件的内存区域和入口点:
![info file output][49]
`.text` 区段始终从入口点开始,其中包含实际的操作码。要在入口点添加断点,输入 `break *0x401110` 然后输入 `run` 开始运行程序:
![breakpoint at the entry point][50]
要在某个地址设置断点,使用取消引用运算符 `*` 来指定地址。
#### 选择反汇编程序风格
在深入研究汇编之前,你可以选择要使用的 [汇编风格][51]。 GDB 默认是 AT&T但我更喜欢 Intel 语法。变更风格如下:
```
set disassembly-flavor intel
```
![changing assembly flavor][52]
现在输入 `layout asm` 调出汇编代码窗口,输入 `layout reg` 调出寄存器窗口。你现在应该看到如下输出:
![layout asm and layout reg output][53]
#### 保存配置文件
尽管你已经输入了许多命令,但实际上还没有开始调试。如果你正在大量调试应用程序或尝试解决逆向工程的难题,则将 GDB 特定设置保存在文件中会很有用。
该项目的 GitHub 存储库中的 [gdbinit][54] 配置文件包含最近使用的命令:
```
set disassembly-flavor intel
set write on
break *0x401110
run -c2
layout asm
layout reg
```
`set write on` 命令使你能够在程序运行期间修改二进制文件。
退出 GDB 并使用配置文件重新启动 GDB `gdb -x gdbinit coredump`
#### 阅读指令
应用 `c2` 开关后,程序将崩溃。程序在入口函数处停止,因此你必须写入 `continue` 才能继续运行:
![continuing execution after crash][55]
`idiv` 指令进行整数除法运算:`RAX` 寄存器中为被除数,指定参数为除数。商被加载到 `RAX` 寄存器中,余数被加载到 `RDX` 中。
从寄存器角度,你可以看到 `RAX` 包含 `5`,因此你必须找出存储堆栈中位置为 `rbp-0x4` 的值。
#### 读取内存
要读取原始内存内容,你必须指定比读取符号更多的参数。在汇编输出中向上滚动一点,可以看到堆栈的划分:
![stack division output][56]
你最感兴趣的应该是 `rbp-0x4` 的值,因为它是 `idiv` 的存储参数。你可以从截图中看到`rbp-0x8` 位置的下一个变量,所以 `rbp-0x4` 位置的变量是 4 字节宽。
在 GDB 中,你可以使用 `x` 命令*查看*任何内存内容:
> `x/` < 可选参数 `n`、`f`、`u` > < 内存地址 `addr` >
可选参数:
* `n`单元大小的重复计数默认值1
* `f`:格式说明符,如 [printf][57]
* `u`:单元大小
* `b`:字节
* `h`半字2 个字节)
* w: 字4 个字节)(默认)
* g: 双字8 个字节)
要打印 `rbp-0x4` 的值,请输入 `x/u $rbp-4` :
![print value][58]
如果你能记住这种模式,则可以直接查看内存。参见手册中的 [查看内存][59] 部分。
#### 操作汇编
子程序 `zeroDivide()` 发生运算异常。当你用向上箭头键向上滚动一点时,你会找到下面信息:
```
0x401211 <_Z10zeroDividev>              push   rbp
0x401212 <_Z10zeroDividev+1>            mov    rbp,rsp
```
这被称为 [函数前言][60]
1. 调用函数的基指针(`rbp`)存放在栈上
2. 栈指针(`rsp`)的值被加载到基指针(`rbp`
完全跳过这个子程序。你可以使用 `backtrace` 查看调用堆栈。在 `main` 函数之前只有一个堆栈帧,所以你可以用一次 `up` 回到 `main` :
![Callstack assembly][61]
在你的 `main` 函数中,你会找到下面信息:
```
0x401431 <main+497>     cmp    BYTE PTR [rbp-0x12],0x0
0x401435 <main+501>     je     0x40145f <main+543>
0x401437 <main+503>     call   0x401211<_Z10zeroDividev>
```
子程序 `zeroDivide()` 仅在 `jump equal (je)``true` 时进入。你可以轻松地将其替换为 `jump-not-equal (jne)` 指令,该指令的操作码为 `0x75`(假设你使用的是 x86/64 架构;其他架构上的操作码不同)。输入 `run` 重新启动程序。当程序在入口函数处停止时,设置操作码:
```
set *(unsigned char*)0x401435 = 0x75
```
最后,输入 `continue` 。该程序将跳过子程序 `zeroDivide()` 并且不会再崩溃。
### 总结
你会在许多集成开发环境IDE中发现 GDB 运行在后台,包括 Qt Creator 和 VSCodium 的 [本地调试][62] 扩展。
![GDB in VSCodium][63]
了解如何充分利用 GDB 的功能很有用。一般情况下,并非所有 GDB 的功能都可以在 IDE 中使用,因此你可以从命令行使用 GDB 的经验中受益。
--------------------------------------------------------------------------------
via: https://opensource.com/article/21/1/gnu-project-debugger
作者:[Stephan Avenwedde][a]
选题:[lkxed][b]
译者:[Maisie-x](https://github.com/Maisie-x)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://opensource.com/users/hansic99
[b]: https://github.com/lkxed
[1]: https://opensource.com/sites/default/files/lead-images/mistake_bug_fix_find_error.png
[2]: https://www.gnu.org/software/gdb/
[3]: https://opensource.com/article/20/8/linux-dump
[4]: https://opensource.com/sites/default/files/uploads/gdb_output_no_dbg_symbols.png
[5]: https://opensource.com/sites/default/files/uploads/gdb_output_with_symbols.png
[6]: https://opensource.com/sites/default/files/uploads/gdb_output_crash_on_c1_switch.png
[7]: https://opensource.com/sites/default/files/uploads/gdb_output_info_source.png
[8]: http://dwarfstd.org/
[9]: https://sourceware.org/gdb/current/onlinedocs/gdb/Compilation.html#Compilation
[10]: https://opensource.com/sites/default/files/uploads/gdb_output_info_shared.png
[11]: https://opensource.com/article/20/6/linux-libraries
[12]: https://opensource.com/sites/default/files/uploads/gdb_output_stopped_by_sigint.png
[13]: https://opensource.com/sites/default/files/uploads/gdb_output_list_main.png
[14]: https://opensource.com/sites/default/files/uploads/gdb_output_breakpoint_added.png
[15]: https://opensource.com/sites/default/files/uploads/gdb_output_break_at_main.png
[16]: https://opensource.com/sites/default/files/images/gdb_output_screen_corrupted.png
[17]: https://sourceware.org/gdb/onlinedocs/gdb/TUI-Keys.html#TUI-Keys
[18]: https://opensource.com/sites/default/files/uploads/gdb_output_stop_on_watchpoint_1.png
[19]: https://opensource.com/sites/default/files/uploads/gdb_output_stop_on_watchpoint_2.png
[20]: https://opensource.com/sites/default/files/uploads/gdb_output_info_watchpoints.png
[21]: https://opensource.com/sites/default/files/uploads/gdb_output_info_breakpoints.png
[22]: https://opensource.com/sites/default/files/uploads/gdb_output_disabled_breakpoints.png
[23]: https://opensource.com/sites/default/files/uploads/gdb_output_set_conditional_breakpoint.png
[24]: https://opensource.com/sites/default/files/uploads/gdb_output_print_variable.png
[25]: https://opensource.com/sites/default/files/uploads/gdb_output_modify_breakpoint.png
[26]: https://opensource.com/sites/default/files/uploads/gdb_output_syscall_catch.png
[27]: https://sourceware.org/gdb/current/onlinedocs/gdb/Breakpoints.html#Breakpoints
[28]: https://opensource.com/sites/default/files/uploads/gdb_output_print_and_modify.png
[29]: https://opensource.com/sites/default/files/uploads/gdb_output_whatis.png
[30]: https://opensource.com/sites/default/files/uploads/gdb_output_info_scope_main.png
[31]: https://opensource.com/sites/default/files/uploads/gdb_output_info_locals_main.png
[32]: https://sourceware.org/gdb/current/onlinedocs/gdb/Symbols.html
[33]: https://man7.org/linux/man-pages/man1/ps.1.html
[34]: https://man7.org/linux/man-pages/man1/top.1.html
[35]: https://opensource.com/sites/default/files/uploads/coredump_running.png
[36]: https://opensource.com/sites/default/files/uploads/gdb_output_attaching_to_process.png
[37]: https://opensource.com/sites/default/files/uploads/gdb_output_backtrace.png
[38]: https://sourceware.org/gdb/current/onlinedocs/gdb/Attach.html#Attach
[39]: https://opensource.com/sites/default/files/uploads/gdb_output_stackframe_up.png
[40]: https://sourceware.org/gdb/current/onlinedocs/gdb/Stack.html#Stack
[41]: https://ftp.gnu.org/old-gnu/Manuals/gdb/html_node/gdb_48.html#SEC49
[42]: https://opensource.com/article/20/8/linux-dump
[43]: https://creativecommons.org/licenses/by-sa/4.0/
[44]: https://opensource.com/sites/default/files/uploads/crash.png
[45]: https://opensource.com/sites/default/files/uploads/gdb_output_coredump.png
[46]: https://opensource.com/sites/default/files/uploads/gdb_output_up_five.png
[47]: https://en.wikipedia.org/wiki/Assembly_language
[48]: https://opensource.com/sites/default/files/uploads/gdb_output_no_debugging_symbols.png
[49]: https://opensource.com/sites/default/files/uploads/gdb_output_info_file.png
[50]: https://opensource.com/sites/default/files/uploads/gdb_output_break_at_start.png
[51]: https://en.wikipedia.org/wiki/X86_assembly_language#Syntax
[52]: https://opensource.com/sites/default/files/uploads/gdb_output_disassembly_flavor.png
[53]: https://opensource.com/sites/default/files/uploads/gdb_output_layout_reg_asm.png
[54]: https://github.com/hANSIc99/core_dump_example/blob/master/gdbinit
[55]: https://opensource.com/sites/default/files/uploads/gdb_output_asm_div_zero.png
[56]: https://opensource.com/sites/default/files/uploads/gdb_output_stack_division.png
[57]: https://en.wikipedia.org/wiki/Printf_format_string#Type_field
[58]: https://opensource.com/sites/default/files/uploads/gdb_output_examine_1.png
[59]: https://sourceware.org/gdb/current/onlinedocs/gdb/Memory.html
[60]: https://en.wikipedia.org/wiki/Function_prologue
[61]: https://opensource.com/sites/default/files/uploads/gdb_output_callstack_assembly_0.png
[62]: https://github.com/WebFreak001/code-debug
[63]: https://opensource.com/sites/default/files/uploads/vs_codium_native_debug.png

View File

@@ -0,0 +1,84 @@
[#]: collector: "lujun9972"
[#]: translator: "void-mori"
[#]: reviewer: "wxy"
[#]: publisher: "wxy"
[#]: url: "https://linux.cn/article-14833-1.html"
[#]: subject: "Highlighted Text Not Visible in gedit in Dark Mode? Heres What You Can Do"
[#]: via: "https://itsfoss.com/gedit-dark-mode-problem/"
[#]: author: "Abhishek Prakash https://itsfoss.com/author/abhishek/"
gedit 深色模式下高亮文本不可见?以下是你能做的
======
![](https://img.linux.net.cn/data/attachment/album/202207/16/094145b0gdwez5zo0zyuhz.jpg)
我喜欢 [在 Ubuntu 中使用深色模式][1]。在我看来深色模式能够缓解视觉疲劳,让系统看起来更加的赏心悦目。
我发现了一个 [gedit][2] 文本编辑器的小麻烦,如果你在深色模式下使用它,你也许也会遇到。
默认情况下 gedit 高亮当前光标所在的行。这是一个非常有用的功能,但是如果你在 Linux 系统中开启了深色模式,那么你将会感到痛苦。为什么?因为被高亮的文本将不再变得可读。你自己看吧:
![Text on the highlighted line is hardly visible][3]
如果你选择文本它将变得可读但这并不是一个让人感到有多么愉快的阅读或者编辑体验。LCTT 校注:在新的 Ubuntu 22.04 中,这一情况已经有所改善,“高亮当前行”已被取消勾选)
![Selecting the text makes it better but thats not a convenient thing to do for all lines][4]
好消息是你不需要再忍受它。我将演示几个步骤让你能够同时享受 gedit 以及系统的深色模式。
### 让 gedit 在深色模式下阅读体验友好
你基本上有两个选择:
1. 禁用高亮当前行,但也同时意味着你必须清楚地知道你在哪一行。
2. 改变默认的颜色设置,但编辑器的颜色会变得稍微有些不同,而且如果你更改系统主题,它不会自动切换到浅色模式。
在 gedit 或者 GNOME 的开发者解决这个问题之前,这是你必须要做的应变和妥协。
#### 选项1 禁止高亮当前行
当你打开 gedit 后,点击汉堡菜单然后选择“<ruby>首选项<rt>Preferences</rt></ruby>”。
![Go to Preferences][5]
在查看选项卡,你应该看到在 “<ruby>高亮<rt>Highlighting</rt></ruby>” 区域的下方的 “<ruby>高亮当前行<rt>Highlight current line</rt></ruby>” 选项。取消勾选这个选项,马上就可以看到效果。
![Disable highlighting current line][6]
“高亮当前行”是一个有用的功能,如果你想继续使用它,请选择第二个选项。
#### 选项2 更改编辑器的颜色主题
在“<ruby>首选项<rt>Preferences</rt></ruby>”窗口,找到 “字体与颜色<rt>Font & Colors</rt></ruby>” 标签页,然后将颜色主题更改为 “Oblivion”、“Solarized Dark”或者 “Cobalt”。
![Change the color scheme][7]
正如我前面所提到的,缺点就是当你把系统主题切换为浅色模式时,编辑器将不会自动切换到浅色模式。
### 开发者应该修复的一个 bug
这里 [有几个 Linux 可用的文本编辑器][8] ,但是为了快速阅读或编辑文本文件,我更推荐使用 gedit。尽管如此小烦恼仍旧是小烦恼。开发者应该在将来的版本中为这个很好的文本编辑器修复这个问题让我们不再求助于这些应对办法。
你呢?你在你的系统上使用深色模式还是浅色模式?你注意到 gedit 的这个问题了吗?你有使用什么方法去解决它吗?欢迎分享你的经验。
--------------------------------------------------------------------------------
via: https://itsfoss.com/gedit-dark-mode-problem/
作者:[Abhishek Prakash][a]
选题:[lujun9972][b]
译者:[void-mori](https://github.com/void-mori)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://itsfoss.com/author/abhishek/
[b]: https://github.com/lujun9972
[1]: https://itsfoss.com/dark-mode-ubuntu/
[2]: https://wiki.gnome.org/Apps/Gedit
[3]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2021/01/gedit-dark-mode-problem.png?resize=779%2C367&ssl=1
[4]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2021/01/gedit-dark-mode-issue.png?resize=779%2C367&ssl=1
[5]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2021/01/gedit-preference.jpg?resize=777%2C527&ssl=1
[6]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2021/01/disable-highlight-line-gedit.jpg?resize=781%2C530&ssl=1
[7]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2021/01/change-color-scheme-gedit.jpg?resize=785%2C539&ssl=1
[8]: https://itsfoss.com/best-modern-open-source-code-editors-for-linux/

View File

@@ -0,0 +1,67 @@
[#]: subject: (What is fog computing?)
[#]: via: (https://opensource.com/article/21/5/fog-computing)
[#]: author: (Seth Kenlon https://opensource.com/users/seth)
[#]: collector: (lujun9972)
[#]: translator: (hanszhao80)
[#]: reviewer: (wxy)
[#]: publisher: (wxy)
[#]: url: (https://linux.cn/article-14782-1.html)
什么是雾计算?
======
> 了解由我们生活中的所有连接设备组成的网络。
![](https://img.linux.net.cn/data/attachment/album/202207/01/120728yne9qv0e2vc5ucm3.jpg)
在早期,计算机既笨重又昂贵,计算机用户很少,他们必须在计算机上的预留时间内亲自来处理他们的<ruby>打孔卡<rt>punchcard</rt></ruby>。被称为 <ruby>[大型机][2]<rt>Mainframe</rt></ruby> 的系统进行了许多创新,并在<ruby>终端机<rt>terminal</rt></ruby>(没有自己的 CPU 的桌面计算机)上实现了<ruby>分时<rt>time-shared</rt></ruby>任务。
时至今日,强大的计算设备能做到 [价格低至 35 美元,且大小不超过一张信用卡][3]。这甚至还没有涵盖现代生活中负责收集和处理数据的所有小设备。从高层次的角度来看这些计算机的集合,你可以想象得到,所有这些设备多得像云中的水滴一样。
碰巧“<ruby>云计算<rt>cloud computing</rt></ruby>”一词已经被占用因此需要为由物联网IoT和其他具有战略意义的服务器组成的网络提供一个独特的名称。此外如果已经有一个代表数据中心节点的云那么在云之外与我们交融的这些节点肯定有其独特之处。
### 欢迎来到雾计算
云通过互联网提供计算服务。构成云的数据中心很大,但与潜在客户的数量相比相对较少。这表明当数据在云及其众多用户之间来回传送时存在潜在的瓶颈。
相比之下,<ruby>雾计算<rt>Fog Computing</rt></ruby>可以在数量上超过其潜在客户,而不会出现瓶颈,因为设备执行大部分数据的收集或计算。它是云的外部“边缘”,是云落地的部分。
### 雾和边缘计算
雾计算和 <ruby>[边缘计算][4]<rt>edge computing</rt></ruby> 本质上是同义词。两者都与云和物联网密切相关,并做出相同的架构假设:
- 你离 CPU 越近,数据传输就越快。
- 像 [Linux][5] 一样,小型专用计算机,可以“做一件事并把它做好”,这是一个强大的优势(当然,我们的设备实际上不仅仅做一件事,但从高层次上看,你购买的用于监测健康的智能手表本质上是在做“一”件事)。
- 离线是不可避免的,但好的设备可以在此期间同样有效地运行,然后在重新连接时同步。
- 本地设备能比大型数据中心更简单、更便宜。
### 边缘网络
将雾计算视为与云完全分离的实体很诱人,但它们毕竟是组成一个整体的两个部分。云需要数字企业的基础设施,包括公共云提供商、电信公司,甚至是运行自己服务的专业公司。本地化服务也很重要,可以在云核心与其数以百万计的客户之间提供<ruby>中转站<rt>waystations</rt></ruby>。
雾计算位于云的边缘,无论客户身在何处,都与他们紧密联系在一起。有时这是一个消费环境,例如你自己的家或汽车,而另一些时候这是一种商业利益,例如零售店中的价格监控设备或工厂车间的重要的安全传感器。
### 雾计算就在你身边
雾计算由我们生活中的所有连接设备组成:<ruby>无人机<rt>drone</rt></ruby>、电话、手表、健身监视器、安全监视器、家庭自动化、便携式游戏设备、园艺自动化、天气传感器、空气质量监视器等等。理想情况下,它提供的数据有助于建立一个更好、更明智的未来。有许多伟大的开源项目正朝着改善健康的方向而努力 —— 甚至只是让生活变得更有趣一点儿 —— 这一切都得益于雾和云计算。无论如何_我们的_ 工作是确保它 [保持开放][7]。
--------------------------------------------------------------------------------
via: https://opensource.com/article/21/5/fog-computing
作者:[Seth Kenlon][a]
选题:[lujun9972][b]
译者:[hanszhao80](https://github.com/hanszhao80)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://opensource.com/users/seth
[b]: https://github.com/lujun9972
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/computer_laptop_code_programming_mountain_view.jpg?itok=yx5buqkr (Man at laptop on a mountain)
[2]: https://opensource.com/article/19/9/linux-mainframes-part-1
[3]: https://opensource.com/resources/raspberry-pi
[4]: https://www.redhat.com/en/topics/edge-computing/what-is-edge-computing
[5]: https://opensource.com/resources/linux
[6]: https://www.redhat.com/architect/edge-computing-essentials
[7]: https://opensource.com/article/20/10/keep-cloud-open

View File

@@ -0,0 +1,93 @@
[#]: subject: (What is the OSI model?)
[#]: via: (https://jvns.ca/blog/2021/05/11/what-s-the-osi-model-/)
[#]: author: (Julia Evans https://jvns.ca/)
[#]: collector: (lujun9972)
[#]: translator: (hanszhao80)
[#]: reviewer: (wxy)
[#]: publisher: (wxy)
[#]: url: (https://linux.cn/article-14786-1.html)
OSI 模型是什么?
======
![](https://img.linux.net.cn/data/attachment/album/202207/02/153620k7nwc6nn2b6n6p2c.jpg)
LCTT 校注:作者原文已经大篇幅进行了修订更新,本文据之前的版本翻译。)
今天我在推特上发布了一些关于 OSI 模型如何与 TCP/IP 工作原理的实际表现不相符的观点这让我思考——OSI 模型到底是什么?通过阅读推特上的一些回复发现,似乎至少存在三种不同的思考方式:
1. TCP/IP 工作原理的字面描述
2. 一个可以用来描述和比较很多不同的网络协议的抽象模型
3. 对 1980 年代的一些计算机网络协议的字面描述,这些协议如今大多已不再使用
在这篇文章中,我不打算试图争辩以上哪一个才是“真正”的 OSI 模型——似乎不同的人以所有这些方式思考它。这不重要。
### OSI 模型有七层
在我们讨论 OSI 模型的含义之前,让我们大致地讨论一下它是什么。它是一个抽象模型,用于描述网络如何在七个编号的层上工作:
- 第一层:物理层
- 第二层:数据链路层
- 第三层:网络层
- 第四层:传输层
- 第五层:会话层
- 第六层:表示层
- 第七层:应用层
我不会再费时地去解释每一层的含义,网上有上千种解释可供查询。
### OSI 模型TCP/IP 工作原理的字面描述
首先,我想谈谈人们在实践中使用 OSI 模型的一种常见方式:作为对 TCP/IP 工作原理的字面描述。OSI 模型的某些层非常容易映射到 TCP/IP
- 第二层对应以太网
- 第三层对应 IP
- 第四层对应 TCP 或 UDP或 ICMP 等)
- 第七层对应 TCP 或 UDP 包内的任何内容(例如 DNS 查询)
这种映射对第二、三、四层很有意义——TCP 数据包有三个<ruby>标头<rt>header</rt></ruby>对应于这三个层以太网标头、IP 标头和 TCP 标头)。
用数字来描述 TCP 数据包中的不同标头非常有用——如果你说“第二层”,很显然它位于第三层“下方”,因为二比三小。
“OSI 模型作为字面描述”的古怪之处在于,第五层和第六层并不真正对应于 TCP/IP 中的任何内容——我听说过很多关于第五层或第六层可能是什么的不同解释(你可以说第五层是 TLS 或其他东西!)但它们没有像第二、三、四层那样“每一层在 TCP 数据包中都有相应的标头”这样的明确对应关系。
此外TCP/IP 的某些部分即使在第二层到第四层也不能很好地适应 OSI 模型——例如,哪一层是 ARP 数据包ARP 数据包发送一些带有以太网标头的数据,这是否意味着它们是第三层?或是第二层?列出不同 OSI 层的维基百科文章将其归类为“第 2.5 层”,这并不令人满意。
因为 OSI 模型有时用于教授 TCP/IP若搞不清楚它的哪些部分可以映射到 TCP/IP而哪些部分不能则会令人困惑。这才是真的问题。
### OSI 模型:用于比较网络协议的一个抽象
我听说过的另一种关于 OSI 的思考方式是,它是一种抽象,可以用来在许多不同的网络协议之间进行类比。例如,如果你想了解蓝牙协议的工作原理,也许你可以使用 OSI 模型来帮助你——这是我在 [这个网页][1] 上找到的一张图表,显示了蓝牙协议如何适配 OSI 模型。
![][2]
另一个例子是,[这篇维基百科文章][3] 有一个 OSI 层列表,详细划分了哪些特定的网络协议对应于这些 OSI 层。
### OSI 模型:一些过时协议的字面描述
维基百科上的一些非常简短的研究表明除了对这七层的抽象描述之外OSI 模型还包含了 [一组实现这些层的特定协议][4]。显然,这发生在 70 年代和 80 年代的 [协议战争][5] 时期OSI 模型失败了TCP/IP 则取得了胜利。
这就解释了为什么 OSI 模型无法与 TCP/IP 很好地对应,因为如果当时“获胜”的是 OSI 协议,那么 OSI 模型 __ 完全对应于互联网网络的实际工作方式。
### 结语
我写这篇文章的初衷是,当我最初学习 OSI 模型时,我发现它非常令人困惑(所有这些层是什么?它们是真实存在的吗?这是网络的实际工作原理吗?发生了什么?)我希望有人告诉我这个只使用 TCP/IP 网络协议的人,只需了解 OSI 模型第二、三、四和七层与 TCP/IP 的关系,然后忽略它的所有其他内容即可。所以我希望这篇文章对某些人能有所帮助!
--------------------------------------------------------------------------------
via: https://jvns.ca/blog/2021/05/11/what-s-the-osi-model-/
作者:[Julia Evans][a]
选题:[lujun9972][b]
译者:[hanszhao80](https://github.com/hanszhao80)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://jvns.ca/
[b]: https://github.com/lujun9972
[1]: https://flylib.com/books/en/4.215.1.116/1/
[2]: https://jvns.ca/images/bluetooth.gif
[3]: https://en.wikipedia.org/wiki/List_of_network_protocols_(OSI_model)
[4]: https://en.wikipedia.org/wiki/OSI_protocols
[5]: https://en.wikipedia.org/wiki/Protocol_Wars

View File

@@ -0,0 +1,207 @@
[#]: subject: (Establish an SSH connection between Windows and Linux)
[#]: via: (https://opensource.com/article/21/6/ssh-windows)
[#]: author: (Stephan Avenwedde https://opensource.com/users/hansic99)
[#]: collector: (lujun9972)
[#]: translator: (yjacks)
[#]: reviewer: (wxy)
[#]: publisher: (wxy)
[#]: url: (https://linux.cn/article-14855-1.html)
如何从 Windows 上用 SSH 连接到 Linux
======
> 使用开源的 PuTTY 工具,从 Windows 建立到 Linux 的 SSH 连接。
![](https://img.linux.net.cn/data/attachment/album/202207/23/110039pjbd9jbbc84gbz2f.jpg)
在 Linux 世界中,<ruby>安全外壳<rt>secure shell</rt></ruby>SSH协议是最为常用的、通过命令行控制远程计算机的方式。SSH 是真正的 Linux 原创,但是它在 Windows 世界中也越来越流行。甚至有了一份官方的 [Windows 的 SSH 文档][2],那篇文档阐述了使用 [OpenSSH][3] 控制 Windows 的方法。
这篇文章展示了如何使用了流行的开源工具 [PuTTY][4],建立一个从 Windows 到 Fedora 33 Linux 系统的 SSH 连接。
### 使用 SSH 的方法
SSH 使用客户端-服务器模式,即 SSH 客户端会创建到 SSH 服务端的连接。SSH 服务器通常会作为<ruby>守护进程<rt>Daemon</rt></ruby>运行,所以它常被称为 SSHD。你很难找到一个不自带 SSH 守护进程的 Linux 发行版。在 Fedora 33 中,已安装了 SSH 守护进程,但是并未激活。
你可以使用 SSH 控制几乎所有的 Linux 机器,无论它是作为虚拟机还是作为网络上的物理设备运行。一个常见的用例是<ruby>无头<rt>headless</rt></ruby>配置的嵌入式设备如树莓派。SSH 也可以用做一个其它网络服务的隧道。因为 SSH 连接是加密的,所以你可以使用 SSH 作为一个任何默认不提供加密的协议的传输层。
在这篇文章中,我将解释使用 SSH 的四个方式1、如何在 Linux 端配置 SSH 守护进程2、如何设置远程控制台连接3、如何通过网络复制文件4. 如何将 SSH 作为某些协议的隧道。
### 1、配置 SSHD
将 Linux 系统(文中是 Fedora 33作为 SSH 服务器,允许 PuTTY SSH 客户端进行连接。首先,检查守护进程的 SSH 配置。配置文件放在 `/etc/ssh/sshd_config`,它包含了许多选项,通过取消掉相关行的注释就可以激活:
```
#       $OpenBSD: sshd_config,v 1.100 2016/08/15 12:32:04 naddy Exp $
# This is the sshd server system-wide configuration file.  See
# sshd_config(5) for more information.
# This sshd was compiled with PATH=/usr/local/sbin:/usr/sbin:/sbin:/usr/local/bin:/usr/bin:/bin
# The strategy used for options in the default sshd_config shipped with
# OpenSSH is to specify options with their default value where
# possible, but leave them commented.  Uncommented options override the
# default value.
Include /etc/ssh/sshd_config.d/*.conf
#Port 22
#AddressFamily any
#ListenAddress 0.0.0.0
#ListenAddress ::
```
没有取消任何注释的默认配置在这个示例中应该是可以工作的。要检查 SSH 守护进程是否已经运行,输入 `systemctl status sshd`
```
$ systemctl status sshd
● sshd.service - OpenSSH server daemon
   Loaded: loaded (/usr/lib/systemd/system/sshd.service; enabled; vendor preset: enabled)
   Active: active (running) since Fri 2018-06-22 11:12:05 UTC; 2 years 11 months ago
     Docs: man:sshd(8)
           man:sshd_config(5)
 Main PID: 577 (sshd)
    Tasks: 1 (limit: 26213)
   CGroup: /system.slice/sshd.service
           └─577 /usr/sbin/sshd -D -oCiphers=[aes256-gcm@openssh.com][5],chacha20-[...]
```
如果它处于<ruby>未激活<rt>inactive</rt></ruby>状态,使用 `systemctl start sshd` 命令启动它。
### 2、设置远程控制台
在 Windows 下 [下载 PuTTY 安装程序][6],然后安装并打开它。你应看到一个像这样的窗口:
![PuTTY configuration screen][7]
在“<ruby>主机名(或 IP 地址)<rt>Host Name (or IP address)</rt></ruby>”输入框,键入你的 Linux 系统的连接信息。本文设置了一个 Fedora 33 虚拟机,它使用桥接网络适配器,使我可以由 IP 地址 `192.168.1.60` 连接这个系统。点击“<ruby>打开<rt>Open</rt></ruby>”,应会如图示的打开一个窗口:
![PutTTY security alert][9]
这是 SSH 的安全措施之一,是为了防止<ruby>[中间人攻击][10]<rt>man-in-the-middle attack</rt></ruby>。消息中的指纹应该匹配 Linux 系统中放在 `/etc/ssh/ssh_host_ed25519_key.pub` 的密钥。PuTTY 将这个密钥以 [MD5 哈希值][11] 的方式打印出来。要检查它的真实性,切换到 Linux 系统并打开一个控制台,然后输入:
```
ssh-keygen -l -E md5 -f /etc/ssh/ssh_host_ed25519_key.pub
```
输出应该和 PuTTY 展示的指纹一致:
```
$ ssh-keygen -l -E md5 -f /etc/ssh/ssh_host_ed25519_key.pub
256 MD5:E4:5F:01:05:D0:F7:DC:A6:32 no comment (ED25519)
```
点击“<ruby>是<rt>Yes</rt></ruby>”以确认 PuTTY 的安全提示。主机系统的指纹现在存储在 PuTTY 的信任列表中,其位于 Windows 的注册表中的:
```
HKEY_CURRENT_USER\SOFTWARE\SimonTatham\PuTTY\SshHostKeys
```
输入正确的登录凭证,然后你应该进入控制台了,位置在你的用户主目录。
![Logged in to SSH][12]
### 3、通过网络复制文件
除了远程控制台,你同样可以使用 PuTTY 通过 SSH 来传输文件。PuTTY 的安装目录在 `C:\Program Files (x86)\PuTTY`,在该目录下寻找 `ppscp.exe`。你既可以使用它从 Linux 系统复制文件,也可以复制文件到 Linux 系统。
使用 `Windows + R` 然后输入 `cmd` 来打开命令提示符,从你的 Linux 用户主目录复制 `MYFile.txt` 到你的 Windows 主目录,输入:
```
C:\"Program Files (x86)"\PuTTY\pscp.exe stephan@192.168.1.60:/home/stephan/MyFile.txt .
```
要从 Windows 主目录复制文件到 Linux 用户主目录,输入:
```
C:\"Program Files (x86)"\PuTTY\pscp.exe MyFile.txt stephan@192.168.1.60:/home/stephan/
```
就像你也许已经发现的那样,复制的命令通常构造为:
```
pscp.exe <source> <target>
```
### 4、隧道化一个协议
假设你拥有一个 Linux 机器,为某些特别的应用运行一个基于 HTTP 的服务。你想从你的 Windows 机器通过互联网访问这个 HTTP 服务。而且,你不能将相关的 TCP 端口暴露在公网,因为:
1. 这个服务通过 HTTP 而非 HTTPS 运行
2. 根本没有用户管理和登录系统
乍一看,建立这种架构不产生可怕的漏洞似乎是不可能的。但是 SSH 可简单的为这种情况建立一个安全的解决方案。
我将用我的软件项目 [Pythonic][13] 来演示这个过程。在容器中运行。Pythonic 作为容器运行,开放两个 TCP 端口TCP 端口 7000主要编辑器和 TCP 端口 8000[code-server][14] 代码编辑器)。
要在一个 Linux 机器上安装 Pythonic ,运行:
```
podman pull pythonicautomation/pythonic
podman run -d -p 7000:7000 -p 8000:8000 pythonic
```
转向你的 Windows 机器,打开 PuTTy转到 “<ruby>连接<rt>Connection</rt></ruby> -> SSH -> <ruby>隧道<rt>Tunnels</rt></ruby>”。加入你要转发的两个 TCP 端口:
* 源:`7000` / 目标:`localhost:7000`
* 源:`8000` / 目标:`localhost:8000`
![Port forwarding in PuTTY][15]
然后返回 “<ruby>会话<rt>Session</rt></ruby>” 部分,并像之前那样建立一个 SSH 链接。打开网页浏览器,然后转到 `http://localhost:7000`;你应该看见像这样的窗口:
![Pythonic][16]
你成功的设置了端口转发!
**警告**: 如果你选择在公网上暴露 TCP 端口 22 ,不要使用易于猜测的登录凭证。你将接受来自全世界的登录请求,它们使用常见的、标准的登录凭证以尝试登录你的 Linux 机器。相反,只允许已知的用户登录。这种登录限制可以通过 [公钥加密][17] 来实现,它使用一个密钥对,其中公钥存储在 SSH 主机上,而私钥保留在客户端。
### 调试
如果你难以连接你的 Linux 机器,你可以跟踪你的 SSH 守护进程的处理过程:
```
journalctl -f -u sshd
```
这是一个普通的登录进程,但是其日志级别为 DEBUG它看起来是这样的 :
![LogLevel DEBUG output][18]
### 了解更多
这篇文章几乎没有涉及到使用 SSH 的方法。如果你正在寻找一个特定用例的信息,你也许可以在互联网中找到无数的教程。我在工作中使用 PuTTY ,因为它易于设置,在两个操作系统间又具有良好的可操作性,使得它成为连接解决方案里的瑞士军刀。
文内图片来自Stephan Avenwedde[CC BY-SA 4.0][8]
--------------------------------------------------------------------------------
via: https://opensource.com/article/21/6/ssh-windows
作者:[Stephan Avenwedde][a]
选题:[lujun9972][b]
译者:[yjacks](https://github.com/yjacks)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://opensource.com/users/hansic99
[b]: https://github.com/lujun9972
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/cloud-windows-building-containers.png?itok=0XvZLZ8k (clouds in windows)
[2]: https://docs.microsoft.com/en-us/windows-server/administration/openssh/openssh_overview
[3]: https://www.openssh.com/
[4]: https://www.putty.org/
[5]: mailto:aes256-gcm@openssh.com
[6]: https://www.chiark.greenend.org.uk/~sgtatham/putty/latest.html
[7]: https://opensource.com/sites/default/files/uploads/putty_connection_settings.png (PuTTY configuration screen)
[8]: https://creativecommons.org/licenses/by-sa/4.0/
[9]: https://opensource.com/sites/default/files/uploads/putty_host_key.png (PutTTY security alert)
[10]: https://en.wikipedia.org/wiki/Man-in-the-middle_attack
[11]: https://en.wikipedia.org/wiki/MD5
[12]: https://opensource.com/sites/default/files/uploads/ssh_successfull_login.png (Logged in to SSH)
[13]: https://github.com/hANSIc99/Pythonic
[14]: https://github.com/cdr/code-server
[15]: https://opensource.com/sites/default/files/uploads/ssh_port_forwarding.png (Port forwarding in PuTTY)
[16]: https://opensource.com/sites/default/files/uploads/pythonic_screen.png (Pythonic)
[17]: https://opensource.com/article/21/4/encryption-decryption-openssl
[18]: https://opensource.com/sites/default/files/uploads/sshd_debug_log.png (LogLevel DEBUG output)

View File

@@ -0,0 +1,80 @@
[#]: subject: (How to use the FreeDOS text editor)
[#]: via: (https://opensource.com/article/21/6/freedos-text-editor)
[#]: author: (Jim Hall https://opensource.com/users/jim-hall)
[#]: collector: (lujun9972)
[#]: translator: (yjacks)
[#]: reviewer: (wxy)
[#]: publisher: (wxy)
[#]: url: (https://linux.cn/article-14847-1.html)
如何使用 FreeDOS Edit
======
> FreeDOS 提供了一个叫做 FreeDOS Edit 的用户友好的文本编辑器。
![](https://img.linux.net.cn/data/attachment/album/202207/20/173027t6ctk5cwf9u988p9.jpg)
在任何操作系统中,编辑文件都是一项常有的任务。当你想去做一个某事的笔记、写封信给朋友或升级一个系统配置 —— 你需要一个文本编辑器。FreeDOS 提供了一个用户友好的文本编辑器(也许没啥想象力)叫做 “FreeDOS Edit”。
### 编辑文件
最简单的启用 FreeDOS Edit 的方式就就是输入 `EDIT`。它提供一个空的编辑器窗口。图案背景显示为一个空的“桌面”——提醒你没有编辑任何文件。
![FreeDOS Edit未加载任何文件][2]
就像多数 DOS 应用程序一样,你可以按下你键盘上的 `Alt` 键来访问 Edit 的菜单。这就激活了这个菜单。在你按下 `Alt`Edit 将切换到“菜单”访问方式,并高亮 “<ruby>文件<rt>File</rt></ruby>” 菜单。如果你想要访问菜单栏上的一个不同的菜单,可以使用左右方向键。按向下的方向键并按下回车键来“进入”菜单。
![高亮菜单][3]
你注意到所有菜单标题的第一个字母是不同的颜色么?这种高亮字母显示了一种快捷方式。例如,“<ruby>文件<rt>File</rt></ruby>”菜单的“F”高亮为红色。所以你可以按下 `Alt+F``Alt``F` 同时按下Edit 会显示“<ruby>文件<rt>File</rt></ruby>”菜单。
![文件菜单][4]
你可以使用“<ruby>文件<rt>File</rt></ruby>”菜单来开始一个新的(空)文件,或打开一个存在的文件。让我们开始一个新文件,使用方向键移动到“<ruby>新建<rt>New</rt></ruby>“然后按下回车键。你也可以用 `Ctrl+N` `Ctrl``N` 同时按下)打开一个新文件。
![编辑一个新的文件][5]
此后,编辑文件应该非常简单。大多数熟悉的快捷键都可以在 FreeDOS Edit 中使用:`Ctrl+C` 复制文本,`Ctrl+X` 剪贴文本,和 `Ctrl+V` 将复制的或剪贴的文本粘贴到新的地方。如果你需要在一个长文档中寻找一个特殊文本,按下 `Ctrl+F`。保存你的工作成果,请使用 `Ctrl+S` 以将变更提交到硬盘。
### 在 Edit 中编程
如果你是个程序员,你也许会发现扩展的 ASCII 表是一个有用的工具。DOS 系统支持“拓展的” ASCII字符集通常被称之为“代码页 437”。0 到 127 的标准字符包括字母 A 到 Z大写和小写、数字和特殊字符如标点符号。但是从 128 到 255 的 DOS 拓展字符包括其它语言字符和“画线”元素。DOS 程序员有时需要使用这些拓展 ASCII 字符,所以 FreeDOS Edit 可以很容易地查看所有 ASCII 码和它们的相关字符的表格。
要查看这个 ASCII 表,请使用“<ruby>工具<rt>Utilities</rt></ruby>”菜单,选择“<ruby>ASCII 表<rt>ASCII Table</rt></ruby>”菜单项,这将显示一个包含该表格的窗口。
![在工具菜单找到 ASCII 表][6]
沿着左边这张表显示十六进制值“00”到“F0”顶部展示了单一值“0”到“F”。这些为每个字符的十六进制代码提供了一个快速参考。例如第一行00和第一列0中的项目具有十六进制值 00 + 0即0x00“NULL”值。而第五行40和第二列1中的字符其数值为 40 + 1即 0x41字母 “A”
![ASCII 表提供一个便于参考的扩展字符表][7]
当你在表格内移动光标高亮不同的字符时,你会看到表格底部的值发生变化,展示了字符的十进制、十六进制和八进制编码。例如,移动光标以高亮在 C0 行和第 5 列的“行交叉”字符,显示这个扩展字符的代码为 197十进制、0xc5十六进制和 305八进制。在一个程序中你可以通过输入十六进制值 0xc5 或八进制“转义代码” \305 来引用这个扩展字符。
![“行交叉”字符是 197十进制、0xc5十六进制和 305八进制][8]
请随意浏览 Edit 中的菜单,以发现其他不错的功能。例如,“<ruby>选项<rt>Options</rt></ruby>”菜单允许你更改 Edit 的行为和外观。如果你喜欢使用更密集的显示,可以使用“<ruby>显示<rt>Display</rt></ruby>”菜单(在“<ruby>选项<rt>Options</rt></ruby>”下)将 Edit
设置为 25、43 或 50 行。你还可以强制 Edit 以单色(黑底白字)或反转模式(白底黑字)显示。
(文内图片来自 Jim HallCC-BY SA 4.0
--------------------------------------------------------------------------------
via: https://opensource.com/article/21/6/freedos-text-editor
作者:[Jim Hall][a]
选题:[lujun9972][b]
译者:[yjacks](https://github.com/yjacks)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://opensource.com/users/jim-hall
[b]: https://github.com/lujun9972
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/laptop_screen_desk_work_chat_text.png?itok=UXqIDRDD (Person using a laptop)
[2]: https://opensource.com/sites/default/files/uploads/edit.png (FreeDOS Edit without any files loaded)
[3]: https://opensource.com/sites/default/files/uploads/edit-menu.png (Highlighting the menu)
[4]: https://opensource.com/sites/default/files/uploads/edit-file.png (The File menu)
[5]: https://opensource.com/sites/default/files/uploads/edit-new.png (Editing a new file)
[6]: https://opensource.com/sites/default/files/uploads/utilities-ascii.png (Find the ASCII Table in the Utilities menu)
[7]: https://opensource.com/sites/default/files/uploads/ascii-table-0x00.png (The ASCII Table provides a handy reference for extended characters)
[8]: https://opensource.com/sites/default/files/uploads/ascii-0xc5.png

View File

@@ -0,0 +1,137 @@
[#]: subject: (How to Convert File Formats With Pandoc in Linux [Quick Guide])
[#]: via: (https://itsfoss.com/pandoc-convert-file/)
[#]: author: (Bill Dyer https://itsfoss.com/author/bill/)
[#]: collector: (lujun9972)
[#]: translator: (lkxed)
[#]: reviewer: (wxy)
[#]: publisher: (wxy)
[#]: url: (https://linux.cn/article-14785-1.html)
如何在 Linux 中使用 Pandoc 转换文件格式
======
在之前的一篇文章中,我介绍了 [使用 pandoc 将少量 Markdown 文件批量转换为 HTML 的过程][1]。在那篇文章中,我创建了多个 HTML 文件,但 Pandoc 可以做的更多。它被称为文档转换的“瑞士军刀” —— 这是有充分理由的。很少有它做不到的事情。
[Pandoc][2] 可以将 .docx、.odt、.html、.epub、LaTeX、DocBook 等格式互相转换,或者转换为其他格式,例如 JATS、TEI Simple、AsciiDoc 等。
是的,这意味着 Pandoc 可以将 .docx 文件转换为 .pdf 和 .html 文件但你可能会想“Word 也可以将文件导出为 .pdf 和 .html。为什么我需要 Pandoc 呢?”
嗯,本来呢,你这个说法也没错,但考虑到 Pandoc 可以转换这么多格式,它很可能成为你所有转换任务的首选工具。例如,我们中的许多人都知道 [Markdown 编辑器][3] 可以将其 Markdown 文件导出为 .html。而使用 Pandoc 文件也可以转换为许多其他格式。
我很少将 Markdown 导出为 HTML。我通常让 Pandoc 来做这件事。
### 使用 Pandoc 转换文件格式
![][4]
本文中,我会将 Markdown 文件转换成几种不同的格式。我几乎所有的写作都使用 Markdown 语法,但我经常需要转换为另一种格式:学校作业通常需要的 .docx 格式;我创建的网页通常需要的 .html 格式;工作需要的 .epub 格式;传单和讲义需要的 .pdf 格式;甚至包括一个大学数字人文项目偶尔需要的 TEI Simple 格式。Pandoc 可以轻松处理所有这些格式,甚至更多。
首先,你需要 [安装 pandoc][5]。此外,要创建 .pdf 文件,还需要 LaTeX。我最喜欢的套件是 [TeX Live][6]。
**注意**:如果你想在安装前试用 pandoc这里有一个在线试用页面<http://pandoc.org/try/>。
#### 安装 pandoc 和 texlive
Ubuntu 和其他 Debian 发行版的用户可以在终端中输入以下命令:
```
sudo apt-get update
sudo apt-get install pandoc texlive
```
请注意第二行,你将一次性安装 `pandoc``texlive`。[apt-get 命令][7] 支持你这样做。不过,我建议你先去喝杯咖啡,因为这可能需要几分钟的时间。
#### 开始转换
安装完成 `pandoc``texlive` 后,你就可以尝试用它们来完成一些工作了!
该项目的示例文档将是一篇文章,该文章于 1894 年 12 月首次发表在《北美评论》上,标题为“如何击退火车劫匪”。我将使用的 Markdown 文件是前一段时间创建的该文章的一个恢复项目的一部分LCTT 译注:这是篇一百多年前发表的文章,这是一个数字化“恢复”项目)。
我把这篇文章保存为 `how_to_repel_train_robbers.md`,它位于我的 `Documents` 目录下,名为 `samples` 的子目录中。它在 Ghostwriter 中看起来是这样的:
![在 Ghostwriter 中查看原始的 Markdown 文件][8]
我想创建此文件的 .docx、.pdf 和 .html 版本。
#### 第一次转换
首先,我将制作一个 .pdf 副本,因为我在安装 LaTeX 包时遇到了些麻烦。
`~/Documents/samples/` 目录中,我输入以下,以创建一个 .pdf 文件:
```
pandoc -o htrtr.pdf how_to_repel_train_robbers.md
```
上述命令将基于 `how_to_repel_train_robbers.md` 文件,创建一个名为 `htrtr.pdf` 的文件。我使用 `htrtr` 作为名称的原因是:嗯,它比 `how_to_repel_train_robbers` 短。`htrtr` 其实是长标题中的单词首字母排列。
这是 .pdf 文件制作完成后的一个截图:
![在 Ocular 中查看的转换后的 PDF 文件][9]
#### 第二次转换
接下来,我想创建一个 .docx 文件。该命令与我用来创建 .pdf 的命令几乎相同,它是:
```
pandoc -o htrtr.docx how_to_repel_train_robbers.md
```
很快,一个 .docx 文件就创建好了。这是它在 Libre Writer 中的样子:
![在 Libre Writer 中查看转换后的 DOCX 文件][10]
#### 第三次转换
我可能会想在网上发布这个,所以再多一个支持网页的格式也不错。我将使用以下命令创建一个 .html 文件:
```
pandoc -o htrtr.html how_to_repel_train_robbers.md
```
同样,创建它的命令与前两次转换非常相似。这是该 .html 文件在浏览器中的样子:
![在 Firefox 中查看的转换后的 HTML 文件][11]
#### 注意到什么了吗?
让我们再看看之前的命令。它们是:
```
pandoc -o htrtr.pdf how_to_repel_train_robbers.md
pandoc -o htrtr.docx how_to_repel_train_robbers.md
pandoc -o htrtr.html how_to_repel_train_robbers.md
```
这三个命令唯一不同的是 `htrtr` 后的扩展名。这提示你 pandoc 会依赖于你提供的输出文件扩展名(来决定目标转换格式)。
### 总结
Pandoc 可以做的远不止这里完成的三个小转换。如果你选择使用一个首选格式编写文件但时不时又需要将文件转换为另一种格式pandoc 很大概率都能为你完成。
现在,既然你已经学会了,你会用它做什么呢?你会把它自动化吗?如果你有一个网站,想供读者下载文章怎么办?你可以修改这些小命令,把它们编写成一个脚本,你的读者可以决定他们想要哪种格式。你可以提供 .docx、.pdf、.odt、.epub 或更多格式。你的读者只需要选择一种格式,然后对应的转换脚本就会执行,最后,你的读者下载他们想要的文件。这是完全可以做到的。
--------------------------------------------------------------------------------
via: https://itsfoss.com/pandoc-convert-file/
作者:[Bill Dyer][a]
选题:[lujun9972][b]
译者:[lkxed](https://github.com/lkxed)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://itsfoss.com/author/bill/
[b]: https://github.com/lujun9972
[1]: https://itsfoss.com/convert-markdown-files/
[2]: https://pandoc.org/
[3]: https://itsfoss.com/best-markdown-editors-linux/
[4]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2021/06/pandoc-quick-guide.png?resize=800%2C450&ssl=1
[5]: https://pandoc.org/installing.html
[6]: https://www.tug.org/texlive/
[7]: https://itsfoss.com/apt-get-linux-guide/
[8]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2021/06/convert_with_pandoc_ghostwriter.png?resize=800%2C516&ssl=1
[9]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2021/06/convert_with_pandoc_ocular.png?resize=800%2C509&ssl=1
[10]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2021/06/convert_with_pandoc_libre_writer.png?resize=800%2C545&ssl=1
[11]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2021/06/convert_with_pandoc_firefox.png?resize=800%2C511&ssl=1

View File

@@ -0,0 +1,107 @@
[#]: subject: "How I use open source to play RPGs"
[#]: via: "https://opensource.com/article/21/10/open-source-rpgs"
[#]: author: "Seth Kenlon https://opensource.com/users/seth"
[#]: collector: "lujun9972"
[#]: translator: "perfiffer"
[#]: reviewer: "wxy"
[#]: publisher: "wxy"
[#]: url: "https://linux.cn/article-14859-1.html"
我如何使用开源玩 RPG 游戏
======
> 为角色扮演游戏的所有元素找到一个开源工具。
![](https://img.linux.net.cn/data/attachment/album/202207/24/075445ymf5nvigh4t4htfd.jpg)
我玩过很多桌面角色扮演游戏RPG无论是从频率还是种类来说。一般来说我更喜欢和朋友一起玩 RPG但在过去的 2 年里我一直在玩网络游戏。LCTT 校注:这里的 RPG 游戏指的是那种“传统”的面对面的桌面游戏,而非很多人最初接触的 RPG 电子游戏。)
起初,我不确定如何在线长期的进行游戏。我知道有很多的工具可以实现,但直到我发现在线桌面游戏的开源世界之前,这些工具没有一个引起我的兴趣。通过一小部分开源应用程序,我已经能够在开源平台上进行我的所有游戏。
这也是一年中的好时机,因为最近是 [免费 RPG 日][2]LCTT 校注:今年的这个节日在 7 月 23 日举办)。在免费 RPG 日,桌面角色扮演游戏行业的发行商们会免费发放游戏,鼓励玩家尝试新游戏和新冒险。尽管它在 2020 年被取消了,但今年它又作为现场活动回归,并通过 [Dungeon Crawl Classics][3] 和 [Paizo][4] 的免费 RPG 示例下载提供了一些虚拟支持。
如果这个活动提供的虚拟产品还不够,我还整理了一份 [你可能尚未尝试过的 5 个开源桌面 RPG 游戏列表][5]。
当你准备好开始玩游戏时,请尝试其中一些开源工具,看看它们能在多大程度上增强你的游戏体验。
### 聊天
在线 RPG 游戏最基本的(从技术上讲,也是唯一的)要求是交流。这是游戏的媒介:玩家需要一种说话的途径。
有几个不错的选择。我发现 [Mumble][6] 是对带宽需求最低的工具。这是一个纯语音聊天应用程序,可以使用非常高效的 Opus 编解码器让每个人一次交谈数小时而不会中断。
![Mumble client][7]
它在世界各地都运行有公共实例,所以下载 Mumble 客户端后,你可以加入其中任何一个开放的实例,并使用它来在线运行游戏。有一个“按下通话”设置,你可以用此来消除背景噪音,当你的其他家庭成员在进行其它工作而不想被你的桌面会话打扰时,这个功能将会非常实用。
还有一个文本聊天客户端。我的游戏组通常使用它来发布与游戏相关的链接,但你也可以将其用于其它无关内容的交谈,而让口头游戏保持在主题上。
如果你的玩家更喜欢看到面部表情,或者只是习惯于视频聊天网页应用。那么 [Jitsi][8] 是面对面围坐在桌子旁聚会的绝佳替代品。Jitsi 和你曾经使用过的其它视频聊天软件几乎一样,甚至更简单。你可以设置一个“房间”,邀请朋友,将陌生人拒之门外,并玩上几个小时。静音和关闭摄像都很直观,界面很吸引人,并且还定期开发和推出了新功能。
![Jitsi][9]
Mumble 和 Jitsi 都有适用于台式机和移动设备的客户端,因此任何人都可以在任何设备上使用。
### 角色表
我发布了我的 [数字角色表][10] 解决方案,但任何 RPG 玩家都知道管理角色不仅仅是统计数据。
在延续多个会话的在线游戏中,我发现每次游戏之间有很长的停止时间。我突然想到,虽然我发现要求我的玩家在现场纸笔游戏中计算损耗是不合理的,但当一切都是数字化时,要求他们跟踪损耗很容易。
网上有很多可用的电子表格,但开源的选择是 [Ethercalc][11]。由于其实例遍布世界各地,因此很容易找到免费的 Ethercalc 主机。或者,你可以使用 Podman 或者 Docker 轻松安装和运行你自己的实例。
![Ethercalc spreadsheet of inventory][12]
Etherclac 提供了一些基本要素:一个共享的账本,这样玩家就可以跟踪他们的团队所携带的物品(以及在任何给定的时间持有该物品的人)、每件物品的重量和价值。当队伍在游戏过程中收集到战利品时,就会输入该物品,所以他们知道什么自己何时会因为负担过重而无法拿起新物品。
在不同的游戏会话之间可以引用和整理这份共享的电子表格以便玩家PC知道哪些物品可以卖掉哪些物品可以放入储物袋哪些物品可以在下一次会话发现更好的战利品时安全的丢弃。
### 地图
Mythic Table 是一款开源的桌面游戏共享地图系统。这意味着你可以加载图片作为游戏地图,并在地图上移动数字标记以表示玩家角色所在的位置。
自从 [上次我介绍了关于 Mythic Table][13] 以来,它已经在 Kickstarter 上成功地进行了一次众筹,以确保它的持续发展。它还增加了一些新功能,其中最引人注目的是“战争迷雾”功能,它允许地下城主掩盖地图并仅显示玩家探索过的部分。
![A dungeon map rendered by Mythic Table and user interface choices for chat, maps, and characters][14]
在过去的几个月里,我一直在 Mythic Table 上运行两款游戏,这是一款优秀且直观的地图系统。它还提供了一个数字骰子筒,所以如果你的玩家没有骰子,或者你更喜欢在公开场合掷骰子,你就可以用它作为共享的骰子池。
你可以在 [mythictable.com][15] 上试用 Mythic Table或者访问他们在 [Github][16] 上的代码库。
### 开源的开放游戏
我使用的开源工具是通用的,因此它们适用于你想玩的任何游戏系统。因为它们都是开源的,所以无论你的玩家使用什么操作系统,他们都可以在线使用,并且它们都可以自托管。
如果你既是程序员又是游戏玩家,请访问他们的 Git 代码仓库,看看是否有任何你可以贡献的东西。如果你是游戏玩家或者游戏管理员,在下次坐在数字版的游戏桌前请尝试使用一下这些工具。你可能会惊讶于你只需要很少的在线账户就可以使用一些可用于游戏的最佳应用程序。
*文内图片来自Seth KenlonCC-BY-SA 4.0*
--------------------------------------------------------------------------------
via: https://opensource.com/article/21/10/open-source-rpgs
作者:[Seth Kenlon][a]
选题:[lujun9972][b]
译者:[perfiffer](https://github.com/perfiffer)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://opensource.com/users/seth
[b]: https://github.com/lujun9972
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/header_dice.png?itok=dOMrHopO (Dice as a random number generator)
[2]: https://www.freerpgday.com/
[3]: https://goodman-games.com/blog/2021/10/06/pdf-previews-of-our-free-rpg-day-releases/
[4]: https://paizo.com/community/blog/v5748dyo6shte
[5]: https://opensource.com/article/21/10/rpg-tabletop-games
[6]: http://mumble.info/
[7]: https://opensource.com/sites/default/files/mumble-client.png (Mumble client)
[8]: https://jitsi.org/
[9]: https://opensource.com/sites/default/files/jitsi-client.jpg (Jitsi)
[10]: https://opensource.com/article/21/10/3-ways-manage-your-character-sheets-open-source
[11]: http://ethercalc.net/
[12]: https://opensource.com/sites/default/files/uploads/ethercalc.jpeg (Ethercalc)
[13]: https://opensource.com/article/20/11/open-source-battle-maps
[14]: https://opensource.com/sites/default/files/uploads/mythic.jpeg (Mythic Table)
[15]: http://mythictable.com/
[16]: https://gitlab.com/mythicteam/mythictable

View File

@@ -0,0 +1,270 @@
[#]: subject: "Beginners Guide to Installing Arch Linux on VirtualBox"
[#]: via: "https://itsfoss.com/install-arch-linux-virtualbox/"
[#]: author: "Ankush Das https://itsfoss.com/author/ankush/"
[#]: collector: "lujun9972"
[#]: translator: "hanszhao80"
[#]: reviewer: "wxy"
[#]: publisher: "wxy"
[#]: url: "https://linux.cn/article-14834-1.html"
在 VirtualBox 安装 Arch Linux 的新手操作指南
======
![](https://img.linux.net.cn/data/attachment/album/202207/16/100738bceesesazv6rsxl4.jpg)
[Arch Linux 在桌面 Linux 世界中非常流行][1]。受欢迎的原因之一是 [安装 Arch Linux][2] 本身就是一项复杂的任务。
我没有夸大其词。安装 [Ubuntu 或 Debian][3] 比 Arch Linux 容易得多,因为官方没给后者提供图形界面的安装程序。
这时虚拟机就派上用场了。
你可以先在 VirtualBox 中尝试安装 Arch Linux看看它是否是你想在实际硬件上运行的系统。通过这种方式你可以在不弄乱当前操作系统的情况下体验 Arch Linux。
在本文,我将一步一步指导你完成一个实用的 Arch Linux 虚拟机的安装过程。
### 在 VirtualBox 上安装 Arch Linux
毫无疑问,你需要先 [在 Linux 上安装 VirtualBox][4](或在 Windows 上)。在 Windows 上,只需访问 Oracle 的网站并下载 VirtualBox。
> **[下载 VirtualBox][5]**
如果你使用的是 Windows 10 或更高版本,请确保你的系统已启用虚拟化。
完成后,你需要到 [Arch Linux 官方网站][6] 下载 ISO 文件。你应该找到 [使用 torrent 下载][7] 或直接下载文件的选项。
![][8]
你可以保留 ISO 文件以备不时之需,安装成功后也可以将其删除以 [释放系统上的空间][9]。
现在,让我们开始在 VirtualBox 上安装 Arch Linux 吧。
#### 第一部分 创建虚拟机
**第一步**:首先,你需要在 VirtualBox 中设置一下。启动 VirtualBox 并单击 “<ruby>新建<rt>New</rt></ruby>” 来创建一个虚拟机。
![][10]
注意,你可以使用 “<ruby>向导模式<rt>guided mode</rt></ruby>” 继续创建虚拟机,但使用 “<ruby>专家模式<rt>expert mode</rt></ruby>” 可以一目了然地获得更多选项。
![][11]
因此,我推荐使用专家模式来创建虚拟机。
不用担心,专家模式同样简单,只是多了一些额外的可选项,无需担心其他任何事情。
**第二步**:输入你的虚拟机名称。当你在 “<ruby>名称<rt>Name</rt></ruby>” 字段中输入 “Arch Linux” 时,它会分别自动检测 “<ruby>类型<rt>Type</rt></ruby>” 和 “<ruby>版本<rt>Version</rt></ruby>”。
![][12]
你应该增加内存大小以舒适地使用虚拟机。如果只是用于小型测试,你可以继续使用默认设置。
我在这个例子中分配了 **4 GB 左右的内存**
另外,请确保在 “<ruby>硬盘<rt>Hard disk</rt></ruby>”选项下选择 “<ruby>现在创建虚拟硬盘<rt>create a virtual hard disk</rt></ruby>”。它应该是默认选项。
现在,继续设置虚拟硬盘大小。
**第三步**你可以选择虚拟硬盘的存放位置并根据你的需求调整大小。最小分配大小8 GB对于安装系统应该不是问题但安全起见你可能得分配至少 10 到 15 GB。
![][13]
接下来,你需要将硬盘硬盘文件类型选择为 “VDIVirtualBox Disk Image” ,将存储选择为 “<ruby>动态分配<rt>Dynamically assigned</rt></ruby>”,如上图所示。
VDI 是虚拟硬盘最常见的硬盘类型。
当你为硬盘存储选择 “<ruby>动态分配<rt>Dynamically allocated</rt></ruby>” 选项时,这意味着存储空间将根据使用情况进行使用。换言之,当创建虚拟机后,并不会立即将这 15 GB 的空间从你的磁盘中锁定。
现在,你所要做的就是点击 “<ruby>创建<rt>Create</rt></ruby>” 来添加虚拟机。
#### 第二部分 添加 ISO 文件以开始安装 Arch Linux
![][14]
当虚拟机在左侧列表中出现后,你可以查看其配置并在 “<ruby>存储<rt>Storage</rt></ruby>” 选项下选择 ISO 文件作为磁盘驱动。
你也可以单独前往虚拟机设置以探索更多内容并选择 ISO 文件。
![][15]
为此,你需要导航至虚拟机设置的 “<ruby>存储<rt>Storage</rt></ruby>” 标签页。
![][16]
在这里,你必须单击 “<ruby>控制器<rt>Controller</rt></ruby>” 下的 “<ruby>没有盘片<rt>Empty</rt></ruby>”,然后继续选择 Arch Linux ISO 文件作为磁盘文件(如上图所示)。
![][17]
完成选择后,点击 “OK” 以保存设置的变更。
将 ISO 设置为要引导的磁盘时,虚拟机设置应如下所示:
![][18]
现在,点击 “<ruby>启动<rt>Start</rt></ruby>” 启动虚拟机并开始安装。
#### 第三部分 使用引导式安装程序安装 Arch Linux
使用 [介绍一个引导式安装程序][19] 的方法使安装 Arch Linux 变得更容易,也就是说,它为你提供了设置成熟的 Arch Linux 系统所需的所有选项。
因此,在引导式安装程序的帮助下,你不必单独安装桌面环境和其他基本软件包。你所要做的就是按照屏幕上的说明选择适合你的选项。
在本文中,我们将重点介绍引导式安装程序。如果你想自己做,你应该遵循我们的 [Arch 安装指南][2]。
继续安装流程,当你启动虚拟机时,将看到以下屏幕:
![][20]
第一个选项是理想的处理方式。如果你有特定的要求,可以选择其他选项来启动 Arch Linux。
现在,你应该正在查看一个终端窗口。以下是如何开始:
**第一步**:输入 `archinstall` 以使用引导式安装程序启动安装。
![][21]
**第二步**根据你的要求选择键盘布局美式布局应该是最常见的选择。简单地输入一个数字即可进行选择如下图所示例如26
![][22]
**第三步**:接下来,你需要选择一个区域来下载包。
![][23]
选择首选地区而不是 “<ruby>全球<rt>Worldwide</rt></ruby>”。这至关重要,因为如果你选择 **全球** 作为你的地区,它会下载许多不必要的包。
**第四步**:选择区域后,它会要求你选择驱动器进行安装。在这个例子中,我们已经创建了一个大约 15 GB 的虚拟驱动器,显示为 `/dev/sda`
类似的,根据大小检查你创建的驱动器,然后选择该磁盘继续。在这里,我输入 `1` 作为输入;你的可能会有所不同。
![][24]
**第五步**:接下来,你将被询问以下内容:
- 选择文件系统类型
- 加密密码(可选的)
- 主机名
- 创建 root 密码(可选的)
- 创建超级用户
- 选择一个预编程的配置文件
![][25]
在我的测试中,我选择了 btrfs 作为文件系统,没有设置任何磁盘加密密码。
主机名可随心所欲的设置,但我建议保持简短。
你可以选择创建一个 root 密码,即使不这么做也应该没什么问题。不过,你需要创建一个具有 sudo 权限的超级用户。
我使用 `admin`/`pass` 作为用户名和密码。不过,如果你不想让其他人访问你计算机上的虚拟机,则不应使用易于猜测的密码。
然后,你将看到一个选择配置文件的选项。在这种情况下,我们需要一个成熟的 Arch Linux 桌面。因此,我们通过输入 `0` 来选择 “<ruby>桌面<rt>desktop</rt></ruby>”。
**第六步**:接下来,你将被要求选择桌面环境。我决定使用 KDE。你可以选择任何你喜欢的。
![][26]
**第七步**:最后,你将被要求选择显卡驱动程序。由于我们是在 VirtualBox 上安装的 Arch Linux你可以选择选项 4VMware/VirtualBox如下图所示
![][27]
你可能还会被要求输入“是(`y`)或否(`n`)”选择 pipewire 而不是 PulseAudio 作为音频服务。选任何一个都应该都可以。
**第八步**:接下来是重要的一步。在这里,如果你需要内核的 LTS 版本,你可以选择使用 “linux-lts”或者继续使用默认值。
![][28]
安装程序会提示你输入想安装的软件包。在这里,我们没有任何特殊要求,因此我们将其留空并按回车键跳过。
**第九步**:你将被要求选择所需的网络适配器以启用互联网访问。你必须选择以下选项:
“<ruby>使用网络管理器来控制和管理你的互联网连接<rt>Use network manager to control and manage your internet connection</rt></ruby>”
![][29]
**第十步**:下一步需要定义时区。选择适用于你的时区,或继续使用默认选项。
**第十一步**:完成后,它将显示你选择的大部分选项以供确认。按回车键继续。
![][30]
**第十二步**:安装完成需要花费几分钟时间,这取决于你的互联网连接速度。
安装完成后,它会要求你 “chroot 进入新创建的安装以进行安装后配置”,但我们不需要。因此输入 `N` 以完成安装。
**第十三步**:最后,你应该会再次看到终端窗口。输入:
```
shutdown now
```
这将安全地退出安装并关闭虚拟机。
一切就绪!在启动安装了 Arch 的虚拟机之前,你还需要做一件事 —— **移除选择作为光驱的 ISO 磁盘**。与添加启动 ISO 的方式类似,你可以前往虚拟机设置并将其删除,如下所示:
![][31]
到此为止你已在 VirtualBox 上安装了 Arch Linux。
你所要做的就是启动虚拟机,在我的例子中它是这样的:
![virtualbox arch][32]
尽管浏览这些选项需要一些时间,但 Arch Linux 上新的引导式安装程序可以节省大量时间使必填项配置正确。
![][33]
同样的步骤也适用于在你的计算机上安装 Arch Linux。你需要用 Arch Linux ISO 文件 [使用 Etcher 制作单独的可启动 USB 盘][34]。
### 总结
[Arch Linux 成为一种流行的选择][1] 有多种原因。但是,如果这是你第一次安装,或者你想对其进行测试,那么虚拟机是在不打乱主机的情况下体验它的最佳方式。
我希望这可以帮助你在 VirtualBox 上安装 Arch Linux。在下面的评论中让我知道你的想法。
--------------------------------------------------------------------------------
via: https://itsfoss.com/install-arch-linux-virtualbox/
作者:[Ankush Das][a]
选题:[lujun9972][b]
译者:[hanszhao80](https://github.com/hanszhao80)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://itsfoss.com/author/ankush/
[b]: https://github.com/lujun9972
[1]: https://itsfoss.com/why-arch-linux/
[2]: https://itsfoss.com/install-arch-linux/
[3]: https://itsfoss.com/debian-vs-ubuntu/
[4]: https://itsfoss.com/install-virtualbox-ubuntu/
[5]: https://www.virtualbox.org/wiki/Downloads
[6]: https://archlinux.org/download/
[7]: https://itsfoss.com/best-torrent-ubuntu/
[8]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2021/10/archlinux-downloads.png?resize=800%2C419&ssl=1
[9]: https://itsfoss.com/free-up-space-ubuntu-linux/
[10]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2021/10/virtualbox-new.png?resize=800%2C562&ssl=1
[11]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2021/10/virtualbox-expert-mode.png?resize=707%2C438&ssl=1
[12]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2021/10/virtualbox-create.png?resize=800%2C536&ssl=1
[13]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2021/10/virtualbox-disk.png?resize=800%2C528&ssl=1
[14]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2021/10/choose-disk-virtualbox-arch.png?resize=800%2C440&ssl=1
[15]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2021/10/virtualbox-settings-option.png?resize=800%2C551&ssl=1
[16]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2021/10/virtualbox-choose-iso.png?resize=800%2C314&ssl=1
[17]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2021/10/virtualbox-arch-iso-select.png?resize=800%2C348&ssl=1
[18]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2021/10/virtualbox-set-start.png?resize=800%2C548&ssl=1
[19]: https://news.itsfoss.com/arch-linux-easy-install/
[20]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2021/10/virtualbox-archlinux-boot.png?resize=800%2C593&ssl=1
[21]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2021/10/vb-archinstall-guided.png?resize=800%2C400&ssl=1
[22]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2021/10/vb-archinstall-kb-layout.png?resize=800%2C694&ssl=1
[23]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2021/10/archinstall-region.png?resize=800%2C664&ssl=1
[24]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2021/10/archinstall-selectdisk.png?resize=800%2C199&ssl=1
[25]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2021/10/archinstall-desktop-configure.png?resize=800%2C497&ssl=1
[26]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2021/10/archinstall-virtualbox-desktop-environment.png?resize=800%2C415&ssl=1
[27]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2021/10/virtualbox-environment.png?resize=419%2C173&ssl=1
[28]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2021/10/archinstall-linux-kernel.png?resize=800%2C692&ssl=1
[29]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2021/10/virtualbox-arch-network-manager.png?resize=800%2C151&ssl=1
[30]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2021/10/archinstall-confirmation.png?resize=800%2C697&ssl=1
[31]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2021/10/iso-remove-archinstall.png?resize=800%2C286&ssl=1
[32]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2021/10/virtualbox-arch.png?resize=800%2C635&ssl=1
[33]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2021/10/kde-arch-virtualbox.png?resize=800%2C453&ssl=1
[34]: https://itsfoss.com/install-etcher-linux/

View File

@@ -0,0 +1,93 @@
[#]: subject: "Should Businesses Opt for Serverless Computing?"
[#]: via: "https://www.opensourceforu.com/2021/12/should-businesses-opt-for-serverless-computing/"
[#]: author: "Krishna Mohan Koyya https://www.opensourceforu.com/author/krishna-mohan-koyya/"
[#]: collector: "lkxed"
[#]: translator: "lkxed"
[#]: reviewer: "wxy"
[#]: publisher: "wxy"
[#]: url: "https://linux.cn/article-14781-1.html"
企业应该选择无服务器计算吗?
======
> 无服务器计算将服务器从规划中移除,使企业能够专注于应用功能。那么,企业是不是都应该选择无服务器计算呢?让我们来探究一下吧!
![](https://img.linux.net.cn/data/attachment/album/202207/01/113921u4sjl5cczwj3tjbu.jpg)
直至不久之前,几乎每个产品经理都会将他/她的工程资源,分成两个独立的团队 —— 开发团队和运维团队。开发团队通常参与编码、测试和构建应用功能,而运维团队负责应用程序的交付、部署和运行维护。
当开发团队构建电商应用时,运维团队会搭建好服务器来托管该应用。搭建服务器涉及到许多方面,其中包括:
* 选择合适的硬件和操作系统
* 应用所需的补丁集
* 搭建所需服务器环境,如 JDK、Python、Tomcat、NodeJS 等
* 部署、配置和提供实际的应用
* 打开并固定合适的端口
* 搭建所需的数据库引擎
……这个名单还在继续。
除此之外,管理人员还对容量规划感到头疼。毕竟,任何重要应用都应始终保持 100% 可用、可靠且可扩展。这需要对硬件进行最佳投资。众所周知,在一些关键时期,硬件短缺会导致业务损失,而硬件冗余又会损害利润。因此,无论应用是针对本地数据中心,还是针对云基础架构,容量规划都是至关重要的。到目前为止,很明显,企业不仅在功能构建上投入了大量的精力,还在功能交付上也花费了大量的时间。
<ruby>无服务器计算<rt>Serverless computing</rt></ruby>旨在提供一种无缝的方式来交付功能,而无需担心服务器的设置和维护。换句话说,无服务器计算平台提供了一个“<ruby>即用型<rt>ready-to-use</rt></ruby>”环境,企业可以尽快将应用程序构建和部署为一些较小的功能。这就是为什么这种方法被称为“<ruby>功能即服务<rt>Function as a Service</rt></ruby>”FaaS
请记住,无服务器计算中仍然存在服务器,但它由 AWS、微软和谷歌等 FaaS 供应商负责。
例如AWS 以 “Lambda 函数”的形式提供了一个无服务器计算环境。开发人员可以选择将应用程序构建为一组 Lambda 函数,这些函数可以用 NodeJS、Java、Python 和其他一些语言编写。AWS 提供了一个现成的环境来部署这些函数。它还提供了即用​​型数据库服务器、文件服务器、应用程序网关和身份验证服务器等。
同样,微软 Azure 也提供了一个环境,它可以用 C# 等语言构建和部署 Azure 函数。
### 为什么选择无服务器?
有两个主要因素推动了无服务器计算的普及。
#### 1、即用型环境
显然,这是无服务器计算的最大卖点。企业无需提前采购/预订硬件或实例,也无需操心许可证,以及设置和配置服务器。他们不需要为扩大和缩小规模而烦恼。所有这些都由 FaaS 供应商负责。
#### 2、最优成本
由于 FaaS 供应商总是根据环境的利用率向客户收费按使用付费模式因此企业无需担心前期成本和资源浪费。例如AWS 根据 Lambda 函数接收的请求数量、在数据表上运行的查询数量等指标来向客户端收费。
### 无服务器计算的挑战
与任何其他方法一样,无服务器计算也不是每个人都可以盲目遵循的完美方法。它本身也有一系列限制。以下是其中的几个。
#### 1、供应商锁定
当使用无服务器计算时第一个也是最重要的问题就是Lambda 或 Azure 等函数将使用供应商提供的 API 来编写。例如,使用 AWS Lambda API 编写的函数无法部署到 Google Cloud 中,反之亦然。因此,无服务器计算迫使企业在许多年内,只能使用同一家供应商。并且,应用的成功或失败不仅取决于它的功能,还取决于供应商在性能等方面的能力。
#### 2、编程语言
没有哪家无服务器计算平台支持所有的编程语言。此外,对于它支持的编程语言,它也可能不支持其所有版本。这样一来,应用开发团队只能选择供应商提供的语言。就团队的能力而言,这可能是非常关键的。
#### 3、最优成本真的吗
其实也不一定,这一切都取决于资源的使用情况。如果你的应用正在承受巨大的负载,例如每秒数百万个请求,那么你所支付的费用可能会过高。在这样的规模下,在本地或云端拥有自己的服务器可能会更便宜。这并不意味着具有 Web 规模的应用不适合用无服务器计算。归根结底,它还是取决于你的平台的构建方式,以及你与供应商签署的协议。
#### 4、生态系统
没有哪个应用是为了一个孤立的环境而编写的。它总是需要其他组件如数据存储、数据库、安全引擎、网关、消息服务器、队列、缓存等。每个平台都提供自己的一组此类工具。例如AWS 提供了 Dynamo DB 作为其 NoSQL 解决方案之一。显然,其他供应商也提供了自己的 NoSQL 解决方案。因此,团队又会被迫地基于所选平台来构建应用程序。尽管大多数商业 FaaS 供应商都为特定需求提供了多个组件,但并非每个组件都可能是同类型中最佳的。
### 为什么不考虑容器呢?
在过去十年中,我们中的许多人都迁移到了容器化部署模型,因为它们为昂贵的物理机或虚拟机提供了一种轻量级的替代方案。有了 Kubernetes 等编排工具后,我们乐于部署容器化应用,同时也满足了 Web 规模的要求。容器提供了与底层环境一定程度的隔离,这使得部署相对容易。但是,我们仍然需要在硬件(本地或云)、许可证、网络、配置等方面进行投资,这需要具有前瞻性的规划、合适的技术能力和仔细的监控。无服务器计算,尽管它也有自己的优点和缺点,但它让我们把这些责任也摆脱了。
### 展望未来
我们正处于持续开发、持续集成和持续部署的时代。每个企业都面临着竞争。产品<ruby>上市时间<rt>Time to market</rt></ruby>TTM在吸引客户、留住客户这两个方面发挥着重要作用。在这种背景下企业喜欢花更多时间来尽可能快地推出功能而不是在部署和维护的细节上苦苦挣扎。无服务器计算有可能满足这些需求。大玩家们正在投入巨额资金以使 FaaS 尽可能地无缝且经济。无服务器计算的未来看起来是一片光明。
--------------------------------------------------------------------------------
via: https://www.opensourceforu.com/2021/12/should-businesses-opt-for-serverless-computing/
作者:[Krishna Mohan Koyya][a]
选题:[lkxed][b]
译者:[lkxed](https://github.com/lkxed)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://www.opensourceforu.com/author/krishna-mohan-koyya/
[b]: https://github.com/lkxed
[1]: https://www.opensourceforu.com/wp-content/uploads/2021/10/Severless-Cloud-Computing-Featured-image-OSFY-Oct-2021.jpg

View File

@@ -2,136 +2,107 @@
[#]: via: "https://opensource.com/article/22/1/linux-desktop-notifications"
[#]: author: "Tomasz Waraksa https://opensource.com/users/tomasz"
[#]: collector: "lujun9972"
[#]: translator: " "
[#]: reviewer: " "
[#]: publisher: " "
[#]: url: " "
[#]: translator: "mcfd"
[#]: reviewer: "wxy"
[#]: publisher: "wxy"
[#]: url: "https://linux.cn/article-14826-1.html"
Send desktop notifications and reminders from Linux terminal
如何从 Linux 终端发送桌面通知与提醒
======
This Linux tutorial demonstrates how to use script commands to send
yourself desktop notifications and reminders.
![Person using a laptop][1]
Sometimes it's useful to get visual feedback from a script. For example, when a script or cron job completes, a long-running build fails, or there is an urgent problem during script execution. Desktop applications can do this with popup notifications, but it can be done from a script too! You can use script commands to send yourself desktop notifications and reminders.
> 这篇教程演示如何使用脚本命令来发送自己的桌面通知与提醒。
![](https://img.linux.net.cn/data/attachment/album/202207/14/145103vawkhy6w506thy6h.jpg)
有时候,来自脚本的视觉回馈是很有用的。例如,当一个脚本或计划任务完成时,一个长期运行的构建任务失败时,或者当脚本执行中出现了紧急问题时。桌面应用程序可以通过弹出通知来做到这一点,但脚本也可以做到这一点!你可以使用脚本命令来给自己发送桌面通知与提醒。
![Example notification][2]
(Tomasz Waraksa, CC BY-SA 4.0)
下面的代码是在 Linux 上编写和测试的。它也可以在 macOS 上运行,只需花点功夫。请参见最后一节 [提示与技巧][3]。
The below code has been written and tested on Linux. It can also be done on macOS with a bit of effort. See the last section for some [hints and tips][3].
### 从 Linux 终端发送通知
### Sending notifications from the Linux terminal
To send notifications from the Linux terminal, use the [`notify-send`][4] command. Run `which ``notify-send` to see if it's present on your system. If not, install it with your package manager of choice.
On Fedora, type:
要从 Linux 终端发送通知,请使用 [notify-send][4] 命令。运行 `which notify-send` 命令来查看它是否在于你的系统中。如果没有,请使用包管理器来安装它。
在 Fedora 上,输入:
```
`$ sudo dnf install notify-send`
$ sudo dnf install notify-send
```
On Debian-based distributions, type:
在基于 Debian 的发行版上,输入:
```
`$ sudo apt install notify-send`
$ sudo apt install notify-send
```
A few examples of simple notifications:
几个简单的通知示例:
```
$ notify-send "Dinner ready!"
$ notify-send "Tip of the Day" "How about a nap?"
```
You can customize the notification with options such as urgency level, custom icon, etc. Find out more with `man notify-send`. You can use a small set of HTML tags in the notification body to give your messages a nice touch. On top of that, URLs are rendered as clickable. For example:
你可以用紧急程度、自定义图标等选项来自定义通知。过 `man notify-send` 了解更多。你也可以在通知正文中使用一小组 HTML 标记以使消息有一个棒的视觉感受。最重要的是URL 被呈现为可点击的。例如:
```
$ notify-send -u critical \
  "Build failed!" \
  "There were &lt;b&gt;123&lt;/b&gt; errors. Click here to see the results: <http://buildserver/latest>"
"Build failed!" \
"There were <b>123</b> errors. Click here to see the results: http://buildserver/latest"
```
![Build fail notification][5]
(Tomasz Waraksa, CC BY-SA 4.0)
发送的通知会被桌面环境接收,并像其他通知一样显示。它们将具有相同的外观、交互和行为。
Sent notifications are picked up by the desktop environment and displayed just like any other notification. They will have the same consistent look, feel, and behavior.
### Combine notify-send with at
Cron is commonly used to schedule commands at regular intervals. The `at` command schedules the single execution of a command at a specified time. If you run it like this, it starts in interactive mode, where you can enter commands to execute at a given time:
### 将 notify-send 与 at 结合使用
计划任务通常被用来定期安排命令。`at` 命令安排在一个指定的时间执行一条命令。如果你像这样运行它,它会以交互模式启动,你可以在其中输入要在指定时间执行的命令:
```
`$ at 12:00`
$ at 12:00
```
This isn't useful for scripts. Luckily, `at` accepts parameters from standard input so that we can use it this way:
这对脚本来说并不有用。幸运的是 `at` 接受来自标准输入的参数,所以我们可以这样使用它:
```
$ echo "npm run build" | at now + 1 minute
$ echo "backup-db" | at 13:00
```
There are many ways of specifying time. From absolute time, such as `10:00` through relative time, such as `now + 2 hours`, to special times such as `noon` or `midnight`. We can combine it with `notify-send` to show ourselves reminders at some time in the future. For example:
有许多指定时间的方法。 从绝对时间,如 `10:00`,到相对时间,如 `now + 2 hours` ,再特殊时间,如`noon` `midnight`。我们可以把它和 `notify-send` 结合起来,在未来的某个时间向自己发送提醒。例如:
```
`$ echo "notify-send 'Stop it and go home now?' 'Enough work for today.' -u critical" | at now`
$ echo "notify-send 'Stop it and go home now?' 'Enough work for today.' -u critical" | at now
```
![Stop for the day notification][6]
(Tomasz Waraksa, CC BY-SA 4.0)
### The remind command
Now, build a custom Bash command for sending yourself reminders. How about something as simple and human-friendly as:
### 提醒的命令
现在,建立一个自定义的 Bash 命令来给自己发送提醒信息。像这样简单且人性化的命令:
```
$ remind "I'm still here" now
$ remind "Time to wake up!" in 5 minutes
$ remind "Dinner" in 1 hour
$ remind "Take a break" at noon
$ remind "It's Friday pints time!" at 17:00
```
This is better than Alexa! How to get this goodness?
这比 Alexa 更好!该怎样做?
See the code below. It defines a shell function called **remind**, which supports the above syntax. The actual work is done in the last two lines. The rest is responsible for help, parameter validation, etc., which roughly matches the proportion of useful code vs. necessary white-noise in any large application.
Save the code somewhere, for example, in the `~/bin/remind` file, and source the function in your `.bashrc` profile so that it's loaded when you log in:
请看下面的代码。它定义了一个名为 `remind` 的函数,它支持上述语法。实际工作是在最后两行完成的。其余的部分负责显示帮助信息、参数校验等,这与任何大型应用程序中有用的代码与必要的白噪声的比例大致相同。
把代码保存在某个地方,例如,在 `~/bin/remind` 文件中,并在你的 `.bashrc` 配置文件写入该函数,以便在你登录时加载它:
```
`$ source ~/bin/remind`
$ source ~/bin/remind
```
Reload the terminal, then type remind to see the syntax. Enjoy!
重新打开终端,然后输入 `remind` 来查看语法。尽情享受吧!
```
#!/usr/bin/env bash
function remind () {
  local COUNT="$#"
@@ -195,13 +166,15 @@ function remind () {
```
### Easy notifications
### 简单的提醒
With these few simple open source commands, you can integrate your own scripts, applications, and tasks with your desktop. Try it out!
通过这几个简单的开源命令,你可以将你自己的脚本、应用程序和任务与你的桌面结合起来。试一试吧!
* * *
_This article has been adapted with the author's permission from the original article, found [here][7]._
(文内图片来自 Tomasz Waraksa, CC BY-SA 4.0
本文经作者许可改编自 [原文][7]。
--------------------------------------------------------------------------------
@@ -209,8 +182,8 @@ via: https://opensource.com/article/22/1/linux-desktop-notifications
作者:[Tomasz Waraksa][a]
选题:[lujun9972][b]
译者:[译者ID](https://github.com/译者ID)
校对:[校对者ID](https://github.com/校对者ID)
译者:[mcfd](https://github.com/mcfd)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出

View File

@@ -0,0 +1,80 @@
[#]: subject: "Why use a Raspberry Pi to power your business"
[#]: via: "https://opensource.com/article/22/1/raspberry-pi-business"
[#]: author: "Giuseppe Cassibba https://opensource.com/users/peppe8o"
[#]: collector: "lujun9972"
[#]: translator: "void-mori"
[#]: reviewer: "wxy"
[#]: publisher: "wxy"
[#]: url: "https://linux.cn/article-14829-1.html"
为何要使用树莓派为你的业务提供动力
======
> 为何小小的单板机是智能工作以及小型办公室的未来。
![](https://img.linux.net.cn/data/attachment/album/202207/15/152016pcjh4heez4q0oof6.jpg)
随着疫情的大流行,我们的工作方式也正在发生着改变。工作的分散化正在成为所有公司需要面临的一项重要挑战。
### 智能办公室
即使工厂认为智能办公仅仅是通过虚拟私有网络来对员工的笔记本电脑进行远程控制再稍微增加一点进化也可以让一些基本的办公服务离人们更近一点这些都能够极大降低数据中心的负载并且提高人们的工作体验。这个方案还有一个额外的影响就是从信息和通信技术ICT上来说消除了许多单点故障。
与其在公司外部有成百上千的工作场地,不如在世界范围内有着成百上千的小型办公室/分支,这就是所谓的“智能办公室”。
这种表述可能会让许多 ICT 专家感到恐慌,因为这种文化使得每个办公室都与一台大机器(即服务器)联系在一起,即使分散计算资源的优势非常明显。
### 一个不同的角度
如果你能用一块 50 美元的小开发板提供一个大服务器的服务会怎么样?如果这个小板子只需要一张 SD 卡和一个普通的 USB 电源支持,那又会怎么样呢?这就是 [树莓派][2] 是最灵活的解决方案的原因所在。
树莓派开发板是尺寸非常小的运行 Linux 的计算机。它有一个由树莓派基金会提供和维护的操作系统:<ruby>树莓派操作系统<rt>Raspberry Pi OS</rt></ruby>。它基于 Debian并与这个最知名的 Linux 发行版共享许多软件包。此外,许多树莓派的开发板能够完美运行最知名的 Ubuntu 服务器,它涵盖了 ARM 处理器支持,提供了对低功耗处理器的支持。
但树莓派开发板对小公司来说也是一个很好的机会,以能够承担得起的代价获得大量的(开源)服务。但这种情况下,你必须考虑数据丢失的风险,因为你把所有的服务运行在一个小的、消费级的硬件上。不过设置正确的备份/恢复程序能够降低这些风险。
### 你能从树莓派开发板上提供什么服务?
大多数服务通常由更昂贵的服务器提供。这里的“大多数”取决于一些限制:
* **ARM 处理器:** 一些软件包只支持 x86/x64 处理器。这是最难克服的挑战之一。但另一方面ARM 处理器的市场份额不断增长,使得程序员为他们的软件开发了兼容 ARM 处理器的版本。
* **内存容量:** 这是一个仅限于在复杂应用以复杂的方式进行复杂的计算的情况下讨论的问题。很多时候,这只不过是关于重新审查代码、拆分步骤,并保持简单高效的问题。此外,如果一个服务虽然只服务少数几个用户,但需要大量的内存/CPU这大概也意味着此服务没有正常工作。这可能是你消除浪费资源的旧问题的一个机会。最后最新的树莓派开发板把内存容量升级到了 8GB这是一个很大的提升。
* **对服务器没有经验的用户:** 这是另一个问题,你可以在基础镜像所在的树莓派的 micro-SD 卡中存储系统和运行数据。
也就是说,你能够用树莓派做很多有趣的事情。在 [我的博客][4] 里,我通过运行各种服务进行了测试 —— 从基本的 LAMP 服务器到复杂的 CRM。从简单到复杂系统全部都是开源的例如
* 代理服务器(也能够添加广告拦截服务)
* 电子邮件服务器
* 打印服务器
* [酒店管理][5]
* 联系关系管理CRM
* [私人社交网络][6]
* 私人论坛
* 私有 Git 门户网站
* 网络监控服务器
* [许多其他有用的服务][7]
对树莓派来说,另一个有趣的用法是在你的远程办公室获得提供高级服务的 Wi-Fi 热点,并且可以从它的以太网端口进行控制。 
最后,[树莓派也能够运行容器][8],这是一个额外的工具,从这个不可思议的开发板中获得一个可用的服务世界。
--------------------------------------------------------------------------------
via: https://opensource.com/article/22/1/raspberry-pi-business
作者:[Giuseppe Cassibba][a]
选题:[lujun9972][b]
译者:[void-mori](https://github.com/void-mori)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://opensource.com/users/peppe8o
[b]: https://github.com/lujun9972
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/BIZ_WorkInPublic_4618517_1110_CS_A.png?itok=RwVrWArk "A chair in a field."
[2]: https://opensource.com/resources/raspberry-pi
[3]: https://enterprisersproject.com/article/2020/11/raspberry-pi-7-enterprise-it-uses
[4]: https://peppe8o.com
[5]: https://opensource.com/article/20/4/qloapps-raspberry-pi
[6]: https://opensource.com/article/20/3/raspberry-pi-open-source-social
[7]: https://peppe8o.com/category/raspberrypi/
[8]: https://opensource.com/article/20/8/kubernetes-raspberry-pi

View File

@@ -0,0 +1,165 @@
[#]: subject: "A guide to Kubernetes architecture"
[#]: via: "https://opensource.com/article/22/2/kubernetes-architecture"
[#]: author: "Nived Velayudhan https://opensource.com/users/nivedv"
[#]: collector: "lujun9972"
[#]: translator: "MjSeven"
[#]: reviewer: "turbokernel"
[#]: publisher: "wxy"
[#]: url: "https://linux.cn/article-14789-1.html"
Kubernetes 架构指南
======
> 了解 Kubernetes 架构中不同组件是如何组合在一起的,这样你就可以更好地排查问题、维护一个健康的集群,以及优化工作流。
![](https://img.linux.net.cn/data/attachment/album/202207/03/105135ey33hhx022m9y9fr.jpg)
使用 Kubernetes 来编排容器,这种描述说起来简单,但理解它的实际含义以及如何实现它完全是另外一回事。如果你正在运行或管理 Kubernetes 集群,那么你就会知道 Kubernetes 由一台称为 “<ruby>控制平面<rt>control plane</rt></ruby>” 的机器和许多其他 <ruby>工作节点<rt>worker node</rt></ruby> 机器组成。每种类型都有一个复杂但稳定的堆栈,这使编排成为可能,熟悉每个组件有助于理解它是如何工作的。
![Kubernetes 架构图][2]
*Nived Velayudhan, [CC BY-SA 4.0][3]*
### 控制平面组件
Kubernetes 安装在一个称为“<ruby>控制平面<rt>control plane</rt></ruby>”的机器上,它会运行 Kubernetes 守护进程,并在启动容器和<ruby>容器组<rt>pod</rt></ruby>时与之通信。下面介绍控制平面的各个组件。
#### etcd
etcd 是一种快速、分布式一致性键值存储器,用作 Kubernetes 对象数据的持久存储如容器组、副本控制器、密钥和服务。etcd 是 Kubernetes 存储集群状态和元数据的唯一地方。唯一与 etcd 直连的组件是 Kubernetes API 服务器。其他所有组件都通过 API 服务器间接的从 etcd 读写数据。
etcd 还实现了一个监控功能它提供了一个基于事件的接口用于异步监控键的更改。一旦你更改了一个键它的监控者就会收到通知。API 服务器组件严重依赖于此来获得通知,并将 etcd 变更至期望状态。
_为什么 etcd 实例的数量应该是奇数?_
你通常会运行三个、五个或七个 etcd 实例实现高可用HA环境但这是为什么呢因为 etcd 是分布式数据存储可以水平扩展它但你需要确保每个实例中的数据是一致的。因此需要为系统当前状态达成共识etcd 为此使用 [RAFT 共识算法][4]。
RAFT 算法需要经过选举(或仲裁)集群才能进入下一个状态。如果你只有两个 etcd 实例并且他们其中一个失败的话,那么 etcd 集群无法转换到新的状态,因为不存在过半这个概念。如果你有三个 etcd 实例,一个实例可能会失败,但仍有 2 个实例可用于进行选举。
#### API 服务器
API 服务器是 Kubernetes 中唯一直接与 etcd 交互的组件。Kubernetes 中的其他所有组件都必须通过 API 服务器来处理集群状态包括客户端kubectl。API 服务器具有以下功能:
* 提供在 etcd 中存储对象的一致方式。
* 执行验证对象,防止客户端存储配置不正确的对象(如果它们直接写入 etcd 数据存储,可能会发生这种情况)。
* 提供 RESTful API 来创建、更新、修改或删除资源。
* 提供 [乐观并发锁][5],在发生更新时,其他客户端永远不会有机会重写对象。
* 对客户端发送的请求进行身份验证和授权。它使用插件提取客户端的用户名、ID、所属组并确定通过身份验证的用户是否可以对请求的资源执行请求的操作。
* 如果请求试图创建、修改或删除资源,则负责 [权限控制][6]。例如AlwaysPullImages、DefaultStorageClass 和 ResourceQuota。
* 实现了一种监控机制(类似于 etcd用户客户端监控更改。这允许调度器和控制器管理器等组件以松耦合的方式与 API 服务器交互。
#### 控制器管理器
在 Kubernetes 中,控制器持续监控集群状态,然后根据需要进行或请求更改。每个控制器都尝试将当前集群状态变更至期望状态。控制器至少跟踪一种 Kubernetes 资源类型,这些对象均有一个字段来表示期望的状态。
控制器示例:
* 副本管理器(管理<ruby>副本控制器<rt>ReplicationController</rt></ruby>资源的控制器)
* <ruby>副本集<rt>ReplicaSet</rt></ruby>、<rub>守护进程集<rt>DaemonSet</rt></ruby> 和任务控制器
* 部署控制器
* 有状态负载控制器
* 节点控制器
* 服务控制器
* 接入点控制器
* 命名空间控制器
* <ruby>持久卷<rt>PersistentVolume</rt></ruby>控制器
控制器通过监控机制来获得变更通知。它们监视 API 服务器对资源的变更,对每次更改执行操作,无论是新建对象还是更新或删除现有对象。大多数时候,这些操作包括创建其他资源或更新监控的资源本身。不过,由于使用监控并不能保证控制器不会错过任何事件,它们还会定期执行一系列操作,确保没有错过任何事件。
控制器管理器还执行生命周期功能。例如命名空间创建和生命周期、事件垃圾收集、已终止容器组垃圾收集、[级联删除垃圾收集][7] 和节点垃圾收集。有关更多信息,参考 [云控制器管理器][8]。
#### 调度器
调度器是一个将容器组分配给节点的控制平面进程。它会监视新创建没有分配节点的容器组。调度器会给每个发现的容器组分配运行它的最佳节点。
满足容器组调度要求的节点称为可调度节点。如果没有合适的节点,那么容器组会一直处于未调度状态,直到调度器可以安置它。一旦找到可调度节点,它就会运行一组函数来对节点进行评分,并选择得分最高的节点,然后它会告诉 API 服务器所选节点的信息。这个过程称为绑定。
节点的选择分为两步:
1. 过滤所有节点的列表获得可以调度容器组的节点列表例如PodFitsResources 过滤器检查候选节点是否有足够的可用资源来满足容器组的特定资源请求)。
2. 对第一步得到的节点列表进行评分和排序,选择最佳节点。如果得分最高的有多个节点,循环过程可确保容器组会均匀地部署在所有节点上。
调度决策要考虑的因素包括:
* 容器组是否请求硬件/软件资源?节点是否报告内存或磁盘压力情况?
* 节点是否有与容器组规范中的节点选择器匹配的标签?
* 如果容器组请求绑定到特定地主机端口,该端口是否可用?
* 容器组是否容忍节点的污点?
* 容器组是否指定节点亲和性或反亲和性规则?
调度器不会指示所选节点运行容器组。调度器所做的就是通过 API 服务器更新容器组定义。然后 API 服务器通过监控机制通知 kubelet 容器组已被调度,然后目标节点上的 kubelet 服务看到容器组被调度到它的节点,它创建并运行容器组。
### 工作节点组件
工作节点运行 kubelet 代理,这允许控制平面接纳它们来处理负载。与控制平面类似,工作节点使用几个不同的组件来实现这一点。 以下部分描述了工作节点组件。
#### Kubelet
Kubelet 是一个运行在集群中每个节点上的代理,负责在工作节点上运行的所有事情。它确保容器在吊舱中运行。
kubelet服务的主要功能有
* 通过在 API 服务器中创建节点资源来注册它正在运行的节点。
* 持续监控 API 服务器上调度到节点的容器组。
* 使用配置的容器运行时启动容器组的容器。
* 持续监控正在运行的容器,并将其状态、事件和资源消耗报告给 API 服务器。
* 运行容器存活探测,在探测失败时重启容器,当 API 服务器中删除容器组时终止(通知服务器容器组终止的消息)。
#### 服务代理
服务代理kube-proxy在每个节点上运行确保一个容器组可以与另一个容器组通讯一个节点可以与另一个节点对话一个容器可以与另一个容器对话。它负责监视 API 服务器对服务和容器组定义的更改,以保持整个网络配置是最新的。当一项服务得到多个容器组的支持时,代理会在这些容器组之间执行负载平衡。
kube-proxy 之所以叫代理,是因为它最初实际上是一个代理服务器,用于接受连接并将它们代理到容器组。当前的实现是使用 iptables 规则将数据包重定向到随机选择的后端容器组,而无需通过实际的代理服务器。
关于它工作原理的高级视图:
* 当你创建一个服务时,会立即分配一个虚拟 IP 地址。
* API 服务器会通知在工作节点上运行的 kube-proxy 代理有一个新服务。
* 每个 kube-proxy 通过设置 iptables 规则使服务可寻址,确保截获每个服务 IP/端口对,并将目的地址修改为支持服务的一个容器组。
* 监控 API 服务器对服务或其端点对象的更改。
#### 容器运行时
容器运行时有两类:
* **较低级别的容器运行时:** 它们主要关注运行中的容器并为容器设置命名空间和<ruby>控制组<rt>cgroup</rt></ruby>。
* **更高级别的容器运行时(容器引擎):** 它们专注于格式、解包、管理、共享镜像以及为开发人员提供 API。
容器运行时负责:
* 如果容器镜像本地不存在,则从镜像仓库中提取。
* 将镜像解压到写时复制文件系统,所有容器层叠加创建一个合并的文件系统。
* 准备一个容器挂载点。
* 设置容器镜像的元数据,如覆盖命令、用户输入的入口命令,并设置 SECCOMP 规则,确保容器按预期运行。
* 通知内核将进程、网络和文件系统等隔离分配给容器。
* 通知内核分配一些资源限制,如 CPU 或内存限制。
* 将系统调用syscall传递给内核启动容器。
* 确保 SElinux/AppArmor 设置正确。
### 协同
系统级组件协同工作,确保 Kubernetes 集群的每个部分都能实现其目和执行其功能。当你深入编辑 [YAML 文件][10] 时,有时很难理解请求是如何在集群中通信的。现在你已经了解了各个部分是如何组合在一起的,你可以更好地理解 Kubernetes 内部发生了什么,这有助于诊断问题、维护健康的集群并优化你的工作流。
--------------------------------------------------------------------------------
via: https://opensource.com/article/22/2/kubernetes-architecture
作者:[Nived Velayudhan][a]
选题:[lujun9972][b]
译者:[MjSeven](https://github.com/MjSeven)
校对:[turbokernel](https://github.com/turbokernel)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://opensource.com/users/nivedv
[b]: https://github.com/lujun9972
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/containers_modules_networking_hardware_parts.png?itok=rPpVj92- (Parts, modules, containers for software)
[2]: https://opensource.com/sites/default/files/uploads/kubernetes-architecture-diagram.png (Kubernetes architecture diagram)
[3]: https://creativecommons.org/licenses/by-sa/4.0/
[4]: https://www.geeksforgeeks.org/raft-consensus-algorithm/
[5]: https://stackoverflow.com/questions/52910322/kubernetes-resource-versioning#:~:text=Optimistic%20concurrency%20control%20\(sometimes%20referred,updated%2C%20the%20version%20number%20increases.
[6]: https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/
[7]: https://kubernetes.io/docs/concepts/architecture/garbage-collection/
[8]: https://kubernetes.io/docs/concepts/architecture/cloud-controller/
[9]: https://www.redhat.com/architect/how-kubernetes-creates-runs-containers
[10]: https://www.redhat.com/sysadmin/yaml-beginners

View File

@@ -3,17 +3,16 @@
[#]: author: "Mihalis Tsoukalos https://opensource.com/users/mtsouk"
[#]: collector: "lkxed"
[#]: translator: "lkxed"
[#]: reviewer: " "
[#]: publisher: " "
[#]: url: " "
[#]: reviewer: "wxy"
[#]: publisher: "wxy"
[#]: url: "https://linux.cn/article-14658-1.html"
在 Go 中复制文件的三种方法
======
本文是 Go 系列的第三篇文章,我将介绍三种最流行的复制文件的方法。
![][1]
![](https://img.linux.net.cn/data/attachment/album/202205/31/153413kcrth9v8c93r5u8e.jpg)
图源Opensource.com
> 本文是 Go 系列的第三篇文章,我将介绍三种最流行的复制文件的方法。
本文将介绍展示如何使用 [Go 编程语言][3] 来复制文件。在 Go 中复制文件的方法有很多,我只介绍三种最常见的:使用 Go 库中的 `io.Copy()` 函数调用、一次读取输入文件并将其写入另一个文件,以及使用缓冲区一块块地复制文件。
@@ -85,7 +84,7 @@ if err != nil {
}
```
上述代码包括了两个 if 代码块(嗯,用 Go 写程序就是这样的),程序的实际功能其实体现在 `ioutil.ReadFile()``ioutil.WriteFile()` 这两行代码中。
上述代码包括了两个 `if` 代码块(嗯,用 Go 写程序就是这样的),程序的实际功能其实体现在 `ioutil.ReadFile()``ioutil.WriteFile()` 这两行代码中。
运行 `cp2.go`,你会得到下面的输出:
@@ -204,7 +203,7 @@ via: https://opensource.com/article/18/6/copying-files-go
作者:[Mihalis Tsoukalos][a]
选题:[lkxed][b]
译者:[lkxed](https://github.com/lkxed)
校对:[校对者ID](https://github.com/校对者ID)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出

View File

@@ -3,16 +3,14 @@
[#]: author: "Gary Scarborough https://fedoramagazine.org/author/gscarbor/"
[#]: collector: "lujun9972"
[#]: translator: "geekpi"
[#]: reviewer: " "
[#]: publisher: " "
[#]: url: " "
[#]: reviewer: "wxy"
[#]: publisher: "wxy"
[#]: url: "https://linux.cn/article-14657-1.html"
使用自动化时的五个常见错误
======
![][1]
背景图片来自 [“Modern Times”1936][2][United Artists][3],公共领域,通过 Wikimedia Commons
![](https://img.linux.net.cn/data/attachment/album/202205/31/151450ukwk98weqgefgowa.jpg)
随着自动化扩展到涵盖 IT 的更多方面,越来越多的管理员正在学习自动化技能并应用它们来减轻他们的工作量。自动化可以减轻重复性任务的负担,并为基础设施增加一定程度的一致性。但是,当 IT 工作人员部署自动化时,会出现可能对大大小小的基础设施造成严重破坏的常见错误。在自动化部署中通常会出现五个常见错误。
@@ -20,7 +18,7 @@
初学者常犯的错误是自动化脚本没有经过全面测试。由于拼写错误或逻辑错误,简单的 shell 脚本可能会对服务器产生不利影响。将该错误乘以基础架构中的服务器数量,你可能会遇到一大堆问题需要清理。在大规模部署之前始终测试你的自动化脚本。
### 意外的服务器负载
### 意外负载
经常发生的第二个错误是没有预测脚本可能对其他资源施加的系统负载。当目标是十几个服务器时,运行从仓库下载文件或安装包的脚本可能没问题。脚本通常在成百上千台服务器上运行。这种负载可以使支持服务停止或完全崩溃。不要忘记考虑端点影响或设置合理的并发率。
@@ -30,11 +28,11 @@
### 缺乏文档
管理员的一项固定职责应该是记录他们的工作。由于合同到期、升职或定期员工流动,公司可能会在 IT 部门频繁招聘新员工。公司内的工作组相互隔离也很常见。由于这些原因,重要的是记录哪些自动化已经到位。与用户运行脚本不同,自动化可能会在创建它的人离开组之后继续很长时间。管理员可能会发现自己在其基础设施中面临着来自自动化未经检查的奇怪行为。
管理员的一项固定职责应该是记录他们的工作。由于合同到期、升职或定期员工流动,公司可能会在 IT 部门频繁招聘新员工。公司内的工作组相互隔离也很常见。由于这些原因,重要的是记录哪些自动化已经到位。与用户运行脚本不同,自动化可能会在创建它的人离开组之后继续很长时间。管理员可能会发现自己在其基础设施中面临着来自未经检查的自动化的奇怪行为。
### 缺乏经验
列表中的最后一个错误是管理员对他们正在自动化的系统不够了解。管理员经常被雇用到他们没有接受过足够培训且没有人可以学习的职位上工作。自 COVID 以来,当公司努力填补空缺时,这一点尤其重要。然后管理员被迫处理他们没有设置并且可能不完全理解的基础设施。这可能会导致非常低效的脚本浪费资源或配置错误的服务器。
列表中的最后一个错误是管理员对他们正在自动化的系统不够了解。管理员经常被雇用到他们没有接受过足够培训且没有人可以求教的职位上工作。自 COVID 以来,当公司努力填补空缺时,这一点尤其重要。然后管理员被迫处理他们没有设置并且可能不完全理解的基础设施。这可能会导致非常低效的脚本浪费资源或配置错误的服务器。
### 结论
@@ -47,7 +45,7 @@ via: https://fedoramagazine.org/five-common-mistakes-when-using-automation/
作者:[Gary Scarborough][a]
选题:[lujun9972][b]
译者:[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/) 荣誉推出

Some files were not shown because too many files have changed in this diff Show More