diff --git a/published/20150616 Computer Laboratory - Raspberry Pi- Lesson 8 Screen03.md b/published/20150616 Computer Laboratory - Raspberry Pi- Lesson 8 Screen03.md new file mode 100644 index 0000000000..6ec24f8780 --- /dev/null +++ b/published/20150616 Computer Laboratory - Raspberry Pi- Lesson 8 Screen03.md @@ -0,0 +1,460 @@ +[#]: collector: (lujun9972) +[#]: translator: (qhwdw) +[#]: reviewer: (wxy) +[#]: publisher: (wxy) +[#]: url: (https://linux.cn/article-10585-1.html) +[#]: subject: (Computer Laboratory – Raspberry Pi: Lesson 8 Screen03) +[#]: via: (https://www.cl.cam.ac.uk/projects/raspberrypi/tutorials/os/screen03.html) +[#]: author: (Alex Chadwick https://www.cl.cam.ac.uk) + +计算机实验室之树莓派:课程 8 屏幕03 +====== + +屏幕03 课程基于屏幕02 课程来构建,它教你如何绘制文本,和一个操作系统命令行参数上的一个小特性。假设你已经有了[课程 7:屏幕02][1] 的操作系统代码,我们将以它为基础来构建。 + +### 1、字符串的理论知识 + +是的,我们的任务是为这个操作系统绘制文本。我们有几个问题需要去处理,最紧急的那个可能是如何去保存文本。令人难以置信的是,文本是迄今为止在计算机上最大的缺陷之一。原本应该是简单的数据类型却导致了操作系统的崩溃,从而削弱其他方面的加密效果,并给使用其它字母表的用户带来了许多问题。尽管如此,它仍然是极其重要的数据类型,因为它将计算机和用户很好地连接起来。文本是计算机能够理解的非常好的结构,同时人类使用它时也有足够的可读性。 + +那么,文本是如何保存的呢?非常简单,我们使用一种方法,给每个字母分配一个唯一的编号,然后我们保存一系列的这种编号。看起来很容易吧。问题是,那个编号的数量是不固定的。一些文本段可能比其它的长。保存普通数字,我们有一些固有的限制,即:32 位,我们不能超过这个限制,我们要添加方法去使用该长度的数字等等。“文本”这个术语,我们经常也叫它“字符串”,我们希望能够写一个可用于可变长度字符串的函数,否则就需要写很多函数!对于一般的数字来说,这不是个问题,因为只有几种通用的数字格式(字节、字、半字节、双字节)。 + +> 可变数据类型(比如文本)要求能够进行很复杂的处理。 + +因此,如何判断字符串长度?我想显而易见的答案是存储字符串的长度,然后去存储组成字符串的字符。这称为长度前缀,因为长度位于字符串的前面。不幸的是,计算机科学家的先驱们不同意这么做。他们认为使用一个称为空终止符(`NULL`)的特殊字符(用 `\0` 表示)来表示字符串结束更有意义。这样确定简化了许多字符串算法,因为你只需要持续操作直到遇到空终止符为止。不幸的是,这成为了许多安全问题的根源。如果一个恶意用户给你一个特别长的字符串会发生什么状况?如果没有足够的空间去保存这个特别长的字符串会发生什么状况?你可以使用一个字符串复制函数来做复制,直到遇到空终止符为止,但是因为字符串特别长,而覆写了你的程序,怎么办?这看上去似乎有些较真,但是,缓冲区溢出攻击还是经常发生。长度前缀可以很容易地缓解这种问题,因为它可以很容易地推算出保存这个字符串所需要的缓冲区的长度。作为一个操作系统开发者,我留下这个问题,由你去决定如何才能更好地存储文本。 + +> 缓冲区溢出攻击祸害计算机由来已久。最近,Wii、Xbox 和 Playstation 2、以及大型系统如 Microsoft 的 Web 和数据库服务器,都遭受到缓冲区溢出攻击。 + +接下来的事情是,我们需要确定的是如何最好地将字符映射到数字。幸运的是,这是高度标准化的,我们有两个主要的选择,Unicode 和 ASCII。Unicode 几乎将每个有用的符号都映射为数字,作为代价,我们需要有很多很多的数字,和一个更复杂的编码方法。ASCII 为每个字符使用一个字节,因此它仅保存拉丁字母、数字、少数符号和少数特殊字符。因此,ASCII 是非常易于实现的,与之相比,Unicode 的每个字符占用的空间并不相同,这使得字符串算法更棘手。通常,操作系统上字符使用 ASCII,并不是为了显示给最终用户的(开发者和专家用户除外),给终端用户显示信息使用 Unicode,因为 Unicode 能够支持像日语字符这样的东西,并且因此可以实现本地化。 + +幸运的是,在这里我们不需要去做选择,因为它们的前 128 个字符是完全相同的,并且编码也是完全一样的。 + +表 1.1 ASCII/Unicode 符号 0-127 + +| | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | a | b | c | d | e | f | | +|----| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | ----| +| 00 | NUL | SOH | STX | ETX | EOT | ENQ | ACK | BEL | BS | HT | LF | VT | FF | CR | SO | SI | | +| 10 | DLE | DC1 | DC2 | DC3 | DC4 | NAK | SYN | ETB | CAN | EM | SUB | ESC | FS | GS | RS | US | | +| 20 | ! | " | # | $ | % | & | . | ( | ) | * | + | , | - | . | / | | | +| 30 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | : | ; | < | = | > | ? | | +| 40 | @ | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | | +| 50 | P | Q | R | S | T | U | V | W | X | Y | Z | [ | \ | ] | ^ | _ | | +| 60 | ` | a | b | c | d | e | f | g | h | i | j | k | l | m | n | o | | +| 70 | p | q | r | s | t | u | v | w | x | y | z | { | | | } | ~ | DEL | + +这个表显示了前 128 个符号。一个符号的十六进制表示是行的值加上列的值,比如 A 是 4116。你可以惊奇地发现前两行和最后的值。这 33 个特殊字符是不可打印字符。事实上,许多人都忽略了它们。它们之所以存在是因为 ASCII 最初设计是基于计算机网络来传输数据的一种方法。因此它要发送的信息不仅仅是符号。你应该学习的重要的特殊字符是 `NUL`,它就是我们前面提到的空终止符。`HT` 水平制表符就是我们经常说的 `tab`,而 `LF` 换行符用于生成一个新行。你可能想研究和使用其它特殊字符在你的操行系统中的意义。 + +### 2、字符 + +到目前为止,我们已经知道了一些关于字符串的知识,我们可以开始想想它们是如何显示的。为了显示一个字符串,我们需要做的最基础的事情是能够显示一个字符。我们的第一个任务是编写一个 `DrawCharacter` 函数,给它一个要绘制的字符和一个位置,然后它将这个字符绘制出来。 + +这就很自然地引出关于字体的讨论。我们已经知道有许多方式去按照选定的字体去显示任何给定的字母。那么字体又是如何工作的呢?在计算机科学的早期阶段,字体就是所有字母的一系列小图片而已,这种字体称为位图字体,而所有的字符绘制方法就是将图片复制到屏幕上。当人们想去调整字体大小时就出问题了。有时我们需要大的字母,而有时我们需要的是小的字母。尽管我们可以为每个字体、每种大小、每个字符都绘制新图片,但这种作法过于单调乏味。所以,发明了矢量字体。矢量字体不包含字体的图像,它包含的是如何去绘制字符的描述,即:一个 `o` 可能是最大字母高度的一半为半径绘制的圆。现代操作系统都几乎仅使用这种字体,因为这种字体在任何分辨率下都很完美。 + +> 在许多操作系统中使用的 TrueType 字体格式是很强大的,它内置有它自己的汇编语言,以确保在任何分辨率下字母看起来都是正确的。 + +不幸的是,虽然我很想包含一个矢量字体的格式的实现,但它的内容太多了,将占用这个网站的剩余部分。所以,我们将去实现一个位图字体,可是,如果你想去做一个像样的图形操作系统,那么矢量字体将是很有用的。 + +在下载页面上的字体节中,我们提供了几个 `.bin` 文件。这些只是字体的原始二进制数据文件。为完成本教程,从等宽、单色、8x16 节中挑选你喜欢的字体。然后下载它并保存到 `source` 目录中并命名为 `font.bin` 文件。这些文件只是每个字母的单色图片,它们每个字母刚好是 8 x 16 个像素。所以,每个字母占用 16 字节,第一个字节是第一行,第二个字节是第二行,依此类推。 + +![bitmap](https://ws2.sinaimg.cn/large/006tNc79ly1fzzb2064agj305l0apt96.jpg) + +这个示意图展示了等宽、单色、8x16 的字符 A 的 “Bitstream Vera Sans Mono” 字体。在这个文件中,我们可以找到,它从第 4116 × 1016 = 41016 字节开始的十六进制序列: + +``` +00, 00, 00, 10, 28, 28, 28, 44, 44, 7C, C6, 82, 00, 00, 00, 00 +``` + +在这里我们将使用等宽字体,因为等宽字体的每个字符大小是相同的。不幸的是,大多数字体的复杂之处就是因为它的宽度不同,从而导致它的显示代码更复杂。在下载页面上还包含有几个其它的字体,并包含了这种字体的存储格式介绍。 + +我们回到正题。复制下列代码到 `drawing.s` 中的 `graphicsAddress` 的 `.int 0` 之后。 + +```assembly +.align 4 +font: +.incbin "font.bin" +``` + +> `.incbin "file"` 插入来自文件 “file” 中的二进制数据。 + +这段代码复制文件中的字体数据到标签为 `font` 的地址。我们在这里使用了一个 `.align 4` 去确保每个字符都是从 16 字节的倍数开始,这是一个以后经常用到的用于加快访问速度的技巧。 + +现在我们去写绘制字符的方法。我在下面给出了伪代码,你可以尝试自己去实现它。按惯例 `>>` 的意思是逻辑右移。 + +```c +function drawCharacter(r0 is character, r1 is x, r2 is y) + if character > 127 then exit + set charAddress to font + character × 16 + for row = 0 to 15 + set bits to readByte(charAddress + row) + for bit = 0 to 7 + if test(bits >> bit, 0x1) + then setPixel(x + bit, y + row) + next + next + return r0 = 8, r1 = 16 +end function +``` + +如果直接去实现它,这显然不是个高效率的做法。像绘制字符这样的事情,效率是最重要的。因为我们要频繁使用它。我们来探索一些改善的方法,使其成为最优化的汇编代码。首先,因为我们有一个 `× 16`,你应该会马上想到它等价于逻辑左移 4 位。紧接着我们有一个变量 `row`,它只与 `charAddress` 和 `y` 相加。所以,我们可以通过增加替代变量来消除它。现在唯一的问题是如何判断我们何时完成。这时,一个很好用的 `.align 4` 上场了。我们知道,`charAddress` 将从包含 0 的低位半字节开始。这意味着我们可以通过检查低位半字节来看到进入字符数据的程度。 + +虽然我们可以消除对 `bit` 的需求,但我们必须要引入新的变量才能实现,因此最好还是保留它。剩下唯一的改进就是去除嵌套的 `bits >> bit`。 + +```c +function drawCharacter(r0 is character, r1 is x, r2 is y) + if character > 127 then exit + set charAddress to font + character << 4 + loop + set bits to readByte(charAddress) + set bit to 8 + loop + set bits to bits << 1 + set bit to bit - 1 + if test(bits, 0x100) + then setPixel(x + bit, y) + until bit = 0 + set y to y + 1 + set chadAddress to chadAddress + 1 + until charAddress AND 0b1111 = 0 + return r0 = 8, r1 = 16 +end function +``` + +现在,我们已经得到了非常接近汇编代码的代码了,并且代码也是经过优化的。下面就是上述代码用汇编写出来的代码。 + +```assembly +.globl DrawCharacter +DrawCharacter: +cmp r0,#127 +movhi r0,#0 +movhi r1,#0 +movhi pc,lr + +push {r4,r5,r6,r7,r8,lr} +x .req r4 +y .req r5 +charAddr .req r6 +mov x,r1 +mov y,r2 +ldr charAddr,=font +add charAddr, r0,lsl #4 + +lineLoop$: + + bits .req r7 + bit .req r8 + ldrb bits,[charAddr] + mov bit,#8 + + charPixelLoop$: + + subs bit,#1 + blt charPixelLoopEnd$ + lsl bits,#1 + tst bits,#0x100 + beq charPixelLoop$ + + add r0,x,bit + mov r1,y + bl DrawPixel + + teq bit,#0 + bne charPixelLoop$ + + charPixelLoopEnd$: + .unreq bit + .unreq bits + add y,#1 + add charAddr,#1 + tst charAddr,#0b1111 + bne lineLoop$ + +.unreq x +.unreq y +.unreq charAddr + +width .req r0 +height .req r1 +mov width,#8 +mov height,#16 + +pop {r4,r5,r6,r7,r8,pc} +.unreq width +.unreq height +``` + +### 3、字符串 + +现在,我们可以绘制字符了,我们可以绘制文本了。我们需要去写一个方法,给它一个字符串为输入,它通过递增位置来绘制出每个字符。为了做的更好,我们应该去实现新的行和制表符。是时候决定关于空终止符的问题了,如果你想让你的操作系统使用它们,可以按需来修改下面的代码。为避免这个问题,我将给 `DrawString` 函数传递一个字符串长度,以及字符串的地址,和 `x` 和 `y` 的坐标作为参数。 + +```c +function drawString(r0 is string, r1 is length, r2 is x, r3 is y) + set x0 to x + for pos = 0 to length - 1 + set char to loadByte(string + pos) + set (cwidth, cheight) to DrawCharacter(char, x, y) + if char = '\n' then + set x to x0 + set y to y + cheight + otherwise if char = '\t' then + set x1 to x + until x1 > x0 + set x1 to x1 + 5 × cwidth + loop + set x to x1 + otherwise + set x to x + cwidth + end if + next +end function +``` + +同样,这个函数与汇编代码还有很大的差距。你可以随意去尝试实现它,即可以直接实现它,也可以简化它。我在下面给出了简化后的函数和汇编代码。 + +很明显,写这个函数的人并不很有效率(感到奇怪吗?它就是我写的)。再说一次,我们有一个 `pos` 变量,它用于递增及与其它东西相加,这是完全没有必要的。我们可以去掉它,而同时进行长度递减,直到减到 0 为止,这样就少用了一个寄存器。除了那个烦人的乘以 5 以外,函数的其余部分还不错。在这里要做的一个重要事情是,将乘法移到循环外面;即便使用位移运算,乘法仍然是很慢的,由于我们总是加一个乘以 5 的相同的常数,因此没有必要重新计算它。实际上,在汇编代码中它可以在一个操作数中通过参数移位来实现,因此我将代码改变为下面这样。 + +```c +function drawString(r0 is string, r1 is length, r2 is x, r3 is y) + set x0 to x + until length = 0 + set length to length - 1 + set char to loadByte(string) + set (cwidth, cheight) to DrawCharacter(char, x, y) + if char = '\n' then + set x to x0 + set y to y + cheight + otherwise if char = '\t' then + set x1 to x + set cwidth to cwidth + cwidth << 2 + until x1 > x0 + set x1 to x1 + cwidth + loop + set x to x1 + otherwise + set x to x + cwidth + end if + set string to string + 1 + loop +end function +``` + +以下是它的汇编代码: + +```assembly +.globl DrawString +DrawString: +x .req r4 +y .req r5 +x0 .req r6 +string .req r7 +length .req r8 +char .req r9 +push {r4,r5,r6,r7,r8,r9,lr} + +mov string,r0 +mov x,r2 +mov x0,x +mov y,r3 +mov length,r1 + +stringLoop$: + subs length,#1 + blt stringLoopEnd$ + + ldrb char,[string] + add string,#1 + + mov r0,char + mov r1,x + mov r2,y + bl DrawCharacter + cwidth .req r0 + cheight .req r1 + + teq char,#'\n' + moveq x,x0 + addeq y,cheight + beq stringLoop$ + + teq char,#'\t' + addne x,cwidth + bne stringLoop$ + + add cwidth, cwidth,lsl #2 + x1 .req r1 + mov x1,x0 + + stringLoopTab$: + add x1,cwidth + cmp x,x1 + bge stringLoopTab$ + mov x,x1 + .unreq x1 + b stringLoop$ +stringLoopEnd$: +.unreq cwidth +.unreq cheight + +pop {r4,r5,r6,r7,r8,r9,pc} +.unreq x +.unreq y +.unreq x0 +.unreq string +.unreq length +``` + +这个代码中非常聪明地使用了一个新运算,`subs` 是从一个操作数中减去另一个数,保存结果,然后将结果与 0 进行比较。实现上,所有的比较都可以实现为减法后的结果与 0 进行比较,但是结果通常会丢弃。这意味着这个操作与 `cmp` 一样快。 + +> `subs reg,#val` 从寄存器 `reg` 中减去 `val`,然后将结果与 `0` 进行比较。 + +### 4、你的意愿是我的命令行 + +现在,我们可以输出字符串了,而挑战是找到一个有意思的字符串去绘制。一般在这样的教程中,人们都希望去绘制 “Hello World!”,但是到目前为止,虽然我们已经能做到了,我觉得这有点“君临天下”的感觉(如果喜欢这种感觉,请随意!)。因此,作为替代,我们去继续绘制我们的命令行。 + +有一个限制是我们所做的操作系统是用在 ARM 架构的计算机上。最关键的是,在它们引导时,给它一些信息告诉它有哪些可用资源。几乎所有的处理器都有某些方式来确定这些信息,而在 ARM 上,它是通过位于地址 10016 处的数据来确定的,这个数据的格式如下: + + 1. 数据是可分解的一系列的标签。 + 2. 这里有九种类型的标签:`core`、`mem`、`videotext`、`ramdisk`、`initrd2`、`serial`、`revision`、`videolfb`、`cmdline`。 + 3. 每个标签只能出现一次,除了 `core` 标签是必不可少的之外,其它的都是可有可无的。 + 4. 所有标签都依次放置在地址 `0x100` 处。 + 5. 标签列表的结束处总是有两个word,它们全为 0。 + 6. 每个标签的字节数都是 4 的倍数。 + 7. 每个标签都是以标签中(以字为单位)的标签大小开始(标签包含这个数字)。 + 8. 紧接着是包含标签编号的一个半字。编号是按上面列出的顺序,从 1 开始(`core` 是 1,`cmdline` 是 9)。 + 9. 紧接着是一个包含 544116 的半字。 + 10. 之后是标签的数据,它根据标签不同是可变的。数据大小(以字为单位)+ 2 的和总是与前面提到的长度相同。 + 11. 一个 `core` 标签的长度可以是 2 个字也可以是 5 个字。如果是 2 个字,表示没有数据,如果是 5 个字,表示它有 3 个字的数据。 + 12. 一个 `mem` 标签总是 4 个字的长度。数据是内存块的第一个地址,和内存块的长度。 + 13. 一个 `cmdline` 标签包含一个 `null` 终止符字符串,它是个内核参数。 + + +在目前的树莓派版本中,只提供了 `core`、`mem` 和 `cmdline` 标签。你可以在后面找到它们的用法,更全面的参考资料在树莓派的参考页面上。现在,我们感兴趣的是 `cmdline` 标签,因为它包含一个字符串。我们继续写一些搜索这个命令行(`cmdline`)标签的代码,如果找到了,以每个条目一个新行的形式输出它。命令行只是图形处理器或用户认为操作系统应该知道的东西的一个列表。在树莓派上,这包含了 MAC 地址、序列号和屏幕分辨率。字符串本身也是一个由空格隔开的表达式(像 `key.subkey=value` 这样的)的列表。 + +> 几乎所有的操作系统都支持一个“命令行”的程序。它的想法是为选择一个程序所期望的行为而提供一个通用的机制。 + +我们从查找 `cmdline` 标签开始。将下列的代码复制到一个名为 `tags.s` 的新文件中。 + +```assembly +.section .data +tag_core: .int 0 +tag_mem: .int 0 +tag_videotext: .int 0 +tag_ramdisk: .int 0 +tag_initrd2: .int 0 +tag_serial: .int 0 +tag_revision: .int 0 +tag_videolfb: .int 0 +tag_cmdline: .int 0 +``` + +通过标签列表来查找是一个很慢的操作,因为这涉及到许多内存访问。因此,我们只想做一次。代码创建一些数据,用于保存每个类型的第一个标签的内存地址。接下来,用下面的伪代码就可以找到一个标签了。 + +```c +function FindTag(r0 is tag) + if tag > 9 or tag = 0 then return 0 + set tagAddr to loadWord(tag_core + (tag - 1) × 4) + if not tagAddr = 0 then return tagAddr + if readWord(tag_core) = 0 then return 0 + set tagAddr to 0x100 + loop forever + set tagIndex to readHalfWord(tagAddr + 4) + if tagIndex = 0 then return FindTag(tag) + if readWord(tag_core+(tagIndex-1)×4) = 0 + then storeWord(tagAddr, tag_core+(tagIndex-1)×4) + set tagAddr to tagAddr + loadWord(tagAddr) × 4 + end loop +end function +``` + +这段代码已经是优化过的,并且很接近汇编了。它尝试直接加载标签,第一次这样做是有些乐观的,但是除了第一次之外的其它所有情况都是可以这样做的。如果失败了,它将去检查 `core` 标签是否有地址。因为 `core` 标签是必不可少的,如果它没有地址,唯一可能的原因就是它不存在。如果它有地址,那就是我们没有找到我们要找的标签。如果没有找到,那我们就需要查找所有标签的地址。这是通过读取标签编号来做的。如果标签编号为 0,意味着已经到了标签列表的结束位置。这意味着我们已经查找了目录中所有的标签。所以,如果我们再次运行我们的函数,现在它应该能够给出一个答案。如果标签编号不为 0,我们检查这个标签类型是否已经有一个地址。如果没有,我们在目录中保存这个标签的地址。然后增加这个标签的长度(以字节为单位)到标签地址中,然后去查找下一个标签。 + +尝试去用汇编实现这段代码。你将需要简化它。如果被卡住了,下面是我的答案。不要忘了 `.section .text`! + +```assembly +.section .text +.globl FindTag +FindTag: +tag .req r0 +tagList .req r1 +tagAddr .req r2 + +sub tag,#1 +cmp tag,#8 +movhi tag,#0 +movhi pc,lr + +ldr tagList,=tag_core +tagReturn$: +add tagAddr,tagList, tag,lsl #2 +ldr tagAddr,[tagAddr] + +teq tagAddr,#0 +movne r0,tagAddr +movne pc,lr + +ldr tagAddr,[tagList] +teq tagAddr,#0 +movne r0,#0 +movne pc,lr + +mov tagAddr,#0x100 +push {r4} +tagIndex .req r3 +oldAddr .req r4 +tagLoop$: +ldrh tagIndex,[tagAddr,#4] +subs tagIndex,#1 +poplt {r4} +blt tagReturn$ + +add tagIndex,tagList, tagIndex,lsl #2 +ldr oldAddr,[tagIndex] +teq oldAddr,#0 +.unreq oldAddr +streq tagAddr,[tagIndex] + +ldr tagIndex,[tagAddr] +add tagAddr, tagIndex,lsl #2 +b tagLoop$ + +.unreq tag +.unreq tagList +.unreq tagAddr +.unreq tagIndex +``` + +### 5、Hello World + +现在,我们已经万事俱备了,我们可以去绘制我们的第一个字符串了。在 `main.s` 文件中删除 `bl SetGraphicsAddress` 之后的所有代码,然后将下面的代码放进去: + +```assembly +mov r0,#9 +bl FindTag +ldr r1,[r0] +lsl r1,#2 +sub r1,#8 +add r0,#8 +mov r2,#0 +mov r3,#0 +bl DrawString +loop$: +b loop$ +``` + +这段代码简单地使用了我们的 `FindTag` 方法去查找第 9 个标签(`cmdline`),然后计算它的长度,然后传递命令和长度给 `DrawString` 方法,告诉它在 `0,0` 处绘制字符串。现在可以在树莓派上测试它了。你应该会在屏幕上看到一行文本。如果没有,请查看我们的排错页面。 + +如果一切正常,恭喜你已经能够绘制文本了。但它还有很大的改进空间。如果想去写了一个数字,或内存的一部分,或操作我们的命令行,该怎么做呢?在 [课程 9:屏幕04][2] 中,我们将学习如何操作文本和显示有用的数字和信息。 + +-------------------------------------------------------------------------------- + +via: https://www.cl.cam.ac.uk/projects/raspberrypi/tutorials/os/screen03.html + +作者:[Alex Chadwick][a] +选题:[lujun9972][b] +译者:[qhwdw](https://github.com/qhwdw) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]: https://www.cl.cam.ac.uk +[b]: https://github.com/lujun9972 +[1]: https://linux.cn/article-10551-1.html +[2]: https://www.cl.cam.ac.uk/projects/raspberrypi/tutorials/os/screen04.html diff --git a/published/20150616 Computer Laboratory - Raspberry Pi- Lesson 9 Screen04.md b/published/20150616 Computer Laboratory - Raspberry Pi- Lesson 9 Screen04.md new file mode 100644 index 0000000000..523394f8a2 --- /dev/null +++ b/published/20150616 Computer Laboratory - Raspberry Pi- Lesson 9 Screen04.md @@ -0,0 +1,537 @@ +[#]: collector: (lujun9972) +[#]: translator: (qhwdw) +[#]: reviewer: (wxy) +[#]: publisher: (wxy) +[#]: url: (https://linux.cn/article-10605-1.html) +[#]: subject: (Computer Laboratory – Raspberry Pi: Lesson 9 Screen04) +[#]: via: (https://www.cl.cam.ac.uk/projects/raspberrypi/tutorials/os/screen04.html) +[#]: author: (Alex Chadwick https://www.cl.cam.ac.uk) + +计算机实验室之树莓派:课程 9 屏幕04 +====== + +屏幕04 课程基于屏幕03 课程来构建,它教你如何操作文本。假设你已经有了[课程 8:屏幕03][1] 的操作系统代码,我们将以它为基础。 + +### 1、操作字符串 + +能够绘制文本是极好的,但不幸的是,现在你只能绘制预先准备好的字符串。如果能够像命令行那样显示任何东西才是完美的,而理想情况下应该是,我们能够显示任何我们期望的东西。一如既往地,如果我们付出努力而写出一个非常好的函数,它能够操作我们所希望的所有字符串,而作为回报,这将使我们以后写代码更容易。曾经如此复杂的函数,在 C 语言编程中只不过是一个 `sprintf` 而已。这个函数基于给定的另一个字符串和作为描述的额外的一个参数而生成一个字符串。我们对这个函数感兴趣的地方是,这个函数是个变长函数。这意味着它可以带可变数量的参数。参数的数量取决于具体的格式字符串,因此它的参数的数量不能预先确定。 + +> 变长函数在汇编代码中看起来似乎不好理解,然而 ,它却是非常有用和很强大的概念。 + +这个完整的函数有许多选项,而我们在这里只列出了几个。在本教程中将要实现的选项我做了高亮处理,当然,你可以尝试去实现更多的选项。 + +函数通过读取格式化字符串来工作,然后使用下表的意思去解释它。一旦一个参数已经使用了,就不会再次考虑它了。函数的返回值是写入的字符数。如果方法失败,将返回一个负数。 + +表 1.1 sprintf 格式化规则 + +| 选项 | 含义 | +| -------------------------- | ------------------------------------------------------------ | +| ==除了 `%` 之外的任何支付== | 复制字符到输出。 | +| ==`%%`== | 写一个 % 字符到输出。 | +| ==`%c`== | 将下一个参数写成字符格式。 | +| ==`%d` 或 `%i`== | 将下一个参数写成十进制的有符号整数。 | +| `%e` | 将下一个参数写成科学记数法,使用 eN,意思是 ×10N。 | +| `%E` | 将下一个参数写成科学记数法,使用 EN,意思是 ×10N。 | +| `%f` | 将下一个参数写成十进制的 IEEE 754 浮点数。 | +| `%g` | 与 `%e` 和 `%f` 的指数表示形式相同。 | +| `%G` | 与 `%E` 和 `%f` 的指数表示形式相同。 | +| ==`%o`== | 将下一个参数写成八进制的无符号整数。 | +| ==`%s`== | 下一个参数如果是一个指针,将它写成空终止符字符串。 | +| ==`%u`== | 将下一个参数写成十进制无符号整数。 | +| ==`%x`== | 将下一个参数写成十六进制无符号整数(使用小写的 a、b、c、d、e 和 f)。 | +| `%X` | 将下一个参数写成十六进制的无符号整数(使用大写的 A、B、C、D、E 和 F)。 | +| `%p` | 将下一个参数写成指针地址。 | +| ==`%n`== | 什么也不输出。而是复制到目前为止被下一个参数在本地处理的字符个数。 | + +除此之外,对序列还有许多额外的处理,比如指定最小长度,符号等等。更多信息可以在 [sprintf - C++ 参考][2] 上找到。 + +下面是调用方法和返回的结果的示例。 + +表 1.2 sprintf 调用示例 + +| 格式化字符串 | 参数 | 结果 | +|---------------|-------|---------------------| +| `"%d"` | 13 | "13" | +| `"+%d degrees"` | 12 | "+12 degrees" | +| `"+%x degrees"` | 24 | "+1c degrees" | +| `"'%c' = 0%o"` | 65, 65 | "'A' = 0101" | +| `"%d * %d%% = %d"` | 200, 40, 80 | "200 * 40% = 80" | +| `"+%d degrees"` | -5 | "+-5 degrees" | +| `"+%u degrees"` | -5 | "+4294967291 degrees" | + +希望你已经看到了这个函数是多么有用。实现它需要大量的编程工作,但给我们的回报却是一个非常有用的函数,可以用于各种用途。 + +### 2、除法 + +虽然这个函数看起来很强大、也很复杂。但是,处理它的许多情况的最容易的方式可能是,编写一个函数去处理一些非常常见的任务。它是个非常有用的函数,可以为任何底的一个有符号或无符号的数字生成一个字符串。那么,我们如何去实现呢?在继续阅读之前,尝试快速地设计一个算法。 + +> 除法是非常慢的,也是非常复杂的基础数学运算。它在 ARM 汇编代码中不能直接实现,因为如果直接实现的话,它得出答案需要花费很长的时间,因此它不是个“简单的”运算。 + +最简单的方法或许就是我在 [课程 1:OK01][3] 中提到的“除法余数法”。它的思路如下: + + 1. 用当前值除以你使用的底。 + 2. 保存余数。 + 3. 如果得到的新值不为 0,转到第 1 步。 + 4. 将余数反序连起来就是答案。 + +例如: + +表 2.1 以 2 为底的例子 + +转换 + +| 值 | 新值 | 余数 | +| ---- | ---- | ---- | +| 137 | 68 | 1 | +| 68 | 34 | 0 | +| 34 | 17 | 0 | +| 17 | 8 | 1 | +| 8 | 4 | 0 | +| 4 | 2 | 0 | +| 2 | 1 | 0 | +| 1 | 0 | 1 | + +因此答案是 100010012 + +这个过程的不幸之外在于使用了除法。所以,我们必须首先要考虑二进制中的除法。 + +我们复习一下长除法 + +> 假如我们想把 4135 除以 17。 +> +> ``` +> 0243 r 4 +> 17)4135 +> 0 0 × 17 = 0000 +> 4135 4135 - 0 = 4135 +> 34 200 × 17 = 3400 +> 735 4135 - 3400 = 735 +> 68 40 × 17 = 680 +> 55 735 - 680 = 55 +> 51 3 × 17 = 51 +> 4 55 - 51 = 4 +> ``` +> 答案:243 余 4 +> +> 首先我们来看被除数的最高位。我们看到它是小于或等于除数的最小倍数,因此它是 0。我们在结果中写一个 0。 +> +> 接下来我们看被除数倒数第二位和所有的高位。我们看到小于或等于那个数的除数的最小倍数是 34。我们在结果中写一个 2,和减去 3400。 +> +> 接下来我们看被除数的第三位和所有高位。我们看到小于或等于那个数的除数的最小倍数是 68。我们在结果中写一个 4,和减去 680。 +> +> 最后,我们看一下所有的余位。我们看到小于余数的除数的最小倍数是 51。我们在结果中写一个 3,减去 51。减法的结果就是我们的余数。 +> + +在汇编代码中做除法,我们将实现二进制的长除法。我们之所以实现它是因为,数字都是以二进制方式保存的,这让我们很容易地访问所有重要位的移位操作,并且因为在二进制中做除法比在其它高进制中做除法都要简单,因为它的数更少。 + +``` + 1011 r 1 +1010)1101111 + 1010 + 11111 + 1010 + 1011 + 1010 + 1 +``` + +这个示例展示了如何做二进制的长除法。简单来说就是,在不超出被除数的情况下,尽可能将除数右移,根据位置输出一个 1,和减去这个数。剩下的就是余数。在这个例子中,我们展示了 11011112 ÷ 10102 = 10112 余数为 12。用十进制表示就是,111 ÷ 10 = 11 余 1。 + +你自己尝试去实现这个长除法。你应该去写一个函数 `DivideU32` ,其中 `r0` 是被除数,而 `r1` 是除数,在 `r0` 中返回结果,在 `r1` 中返回余数。下面,我们将完成一个有效的实现。 + +```c +function DivideU32(r0 is dividend, r1 is divisor) + set shift to 31 + set result to 0 + while shift ≥ 0 + if dividend ≥ (divisor << shift) then + set dividend to dividend - (divisor << shift) + set result to result + 1 + end if + set result to result << 1 + set shift to shift - 1 + loop + return (result, dividend) +end function +``` + +这段代码实现了我们的目标,但却不能用于汇编代码。我们出现的问题是,我们的寄存器只能保存 32 位,而 `divisor << shift` 的结果可能在一个寄存器中装不下(我们称之为溢出)。这确实是个问题。你的解决方案是否有溢出的问题呢? + +幸运的是,有一个称为 `clz`(计数前导零count leading zeros)的指令,它能计算一个二进制表示的数字的前导零的个数。这样我们就可以在溢出发生之前,可以将寄存器中的值进行相应位数的左移。你可以找出的另一个优化就是,每个循环我们计算 `divisor << shift` 了两遍。我们可以通过将除数移到开始位置来改进它,然后在每个循环结束的时候将它移下去,这样可以避免将它移到别处。 + +我们来看一下进一步优化之后的汇编代码。 + +```assembly +.globl DivideU32 +DivideU32: +result .req r0 +remainder .req r1 +shift .req r2 +current .req r3 + +clz shift,r1 +lsl current,r1,shift +mov remainder,r0 +mov result,#0 + +divideU32Loop$: + cmp shift,#0 + blt divideU32Return$ + cmp remainder,current + + addge result,result,#1 + subge remainder,current + sub shift,#1 + lsr current,#1 + lsl result,#1 + b divideU32Loop$ +divideU32Return$: +.unreq current +mov pc,lr + +.unreq result +.unreq remainder +.unreq shift +``` + +你可能毫无疑问的认为这是个非常高效的作法。它是很好,但是除法是个代价非常高的操作,并且我们的其中一个愿望就是不要经常做除法,因为如果能以任何方式提升速度就是件非常好的事情。当我们查看有循环的优化代码时,我们总是重点考虑一个问题,这个循环会运行多少次。在本案例中,在输入为 1 的情况下,这个循环最多运行 31 次。在不考虑特殊情况的时候,这很容易改进。例如,当 1 除以 1 时,不需要移位,我们将把除数移到它上面的每个位置。这可以通过简单地在被除数上使用新的 `clz` 命令并从中减去它来改进。在 `1 ÷ 1` 的案例中,这意味着移位将设置为 0,明确地表示它不需要移位。如果它设置移位为负数,表示除数大于被除数,因此我们就可以知道结果是 0,而余数是被除数。我们可以做的另一个快速检查就是,如果当前值为 0,那么它是一个整除的除法,我们就可以停止循环了。 + +> `clz dest,src` 将第一个寄存器 `dest` 中二进制表示的值的前导零的数量,保存到第二个寄存器 `src` 中。 + + +```assembly +.globl DivideU32 +DivideU32: +result .req r0 +remainder .req r1 +shift .req r2 +current .req r3 + +clz shift,r1 +clz r3,r0 +subs shift,r3 +lsl current,r1,shift +mov remainder,r0 +mov result,#0 +blt divideU32Return$ + +divideU32Loop$: + cmp remainder,current + blt divideU32LoopContinue$ + + add result,result,#1 + subs remainder,current + lsleq result,shift + beq divideU32Return$ +divideU32LoopContinue$: + subs shift,#1 + lsrge current,#1 + lslge result,#1 + bge divideU32Loop$ + +divideU32Return$: +.unreq current +mov pc,lr + +.unreq result +.unreq remainder +.unreq shift +``` + +复制上面的代码到一个名为 `maths.s` 的文件中。 + +### 3、数字字符串 + +现在,我们已经可以做除法了,我们来看一下另外的一个将数字转换为字符串的实现。下列的伪代码将寄存器中的一个数字转换成以 36 为底的字符串。根据惯例,a % b 表示 a 被 b 相除之后的余数。 + +```c +function SignedString(r0 is value, r1 is dest, r2 is base) + if value ≥ 0 + then return UnsignedString(value, dest, base) + otherwise + if dest > 0 then + setByte(dest, '-') + set dest to dest + 1 + end if + return UnsignedString(-value, dest, base) + 1 + end if +end function + +function UnsignedString(r0 is value, r1 is dest, r2 is base) + set length to 0 + do + + set (value, rem) to DivideU32(value, base) + if rem > 10 + then set rem to rem + '0' + otherwise set rem to rem - 10 + 'a' + if dest > 0 + then setByte(dest + length, rem) + set length to length + 1 + + while value > 0 + if dest > 0 + then ReverseString(dest, length) + return length +end function + +function ReverseString(r0 is string, r1 is length) + set end to string + length - 1 + while end > start + set temp1 to readByte(start) + set temp2 to readByte(end) + setByte(start, temp2) + setByte(end, temp1) + set start to start + 1 + set end to end - 1 + end while +end function +``` + +上述代码实现在一个名为 `text.s` 的汇编文件中。记住,如果你遇到了困难,可以在下载页面找到完整的解决方案。 + +### 4、格式化字符串 + +我们继续回到我们的字符串格式化方法。因为我们正在编写我们自己的操作系统,我们根据我们自己的意愿来添加或修改格式化规则。我们可以发现,添加一个 `a % b` 操作去输出一个二进制的数字比较有用,而如果你不使用空终止符字符串,那么你应该去修改 `%s` 的行为,让它从另一个参数中得到字符串的长度,或者如果你愿意,可以从长度前缀中获取。我在下面的示例中使用了一个空终止符。 + +实现这个函数的一个主要的障碍是它的参数个数是可变的。根据 ABI 规定,额外的参数在调用方法之前以相反的顺序先推送到栈上。比如,我们使用 8 个参数 1、2、3、4、5、6、7 和 8 来调用我们的方法,我们将按下面的顺序来处理: + +1. 设置 r0 = 5、r1 = 6、r2 = 7、r3 = 8 +2. 推入 {r0,r1,r2,r3} +3. 设置 r0 = 1、r1 = 2、r2 = 3、r3 = 4 +4. 调用函数 +5. 将 sp 和 #4*4 加起来 + +现在,我们必须确定我们的函数确切需要的参数。在我的案例中,我将寄存器 `r0` 用来保存格式化字符串地址,格式化字符串长度则放在寄存器 `r1` 中,目标字符串地址放在寄存器 `r2` 中,紧接着是要求的参数列表,从寄存器 `r3` 开始和像上面描述的那样在栈上继续。如果你想去使用一个空终止符格式化字符串,在寄存器 r1 中的参数将被移除。如果你想有一个最大缓冲区长度,你可以将它保存在寄存器 `r3` 中。由于有额外的修改,我认为这样修改函数是很有用的,如果目标字符串地址为 0,意味着没有字符串被输出,但如果仍然返回一个精确的长度,意味着能够精确的判断格式化字符串的长度。 + +如果你希望尝试实现你自己的函数,现在就可以去做了。如果不去实现你自己的,下面我将首先构建方法的伪代码,然后给出实现的汇编代码。 + +```c +function StringFormat(r0 is format, r1 is formatLength, r2 is dest, ...) + set index to 0 + set length to 0 + while index < formatLength + if readByte(format + index) = '%' then + set index to index + 1 + if readByte(format + index) = '%' then + if dest > 0 + then setByte(dest + length, '%') + set length to length + 1 + otherwise if readByte(format + index) = 'c' then + if dest > 0 + then setByte(dest + length, nextArg) + set length to length + 1 + otherwise if readByte(format + index) = 'd' or 'i' then + set length to length + SignedString(nextArg, dest, 10) + otherwise if readByte(format + index) = 'o' then + set length to length + UnsignedString(nextArg, dest, 8) + otherwise if readByte(format + index) = 'u' then + set length to length + UnsignedString(nextArg, dest, 10) + otherwise if readByte(format + index) = 'b' then + set length to length + UnsignedString(nextArg, dest, 2) + otherwise if readByte(format + index) = 'x' then + set length to length + UnsignedString(nextArg, dest, 16) + otherwise if readByte(format + index) = 's' then + set str to nextArg + while getByte(str) != '\0' + if dest > 0 + then setByte(dest + length, getByte(str)) + set length to length + 1 + set str to str + 1 + loop + otherwise if readByte(format + index) = 'n' then + setWord(nextArg, length) + end if + otherwise + if dest > 0 + then setByte(dest + length, readByte(format + index)) + set length to length + 1 + end if + set index to index + 1 + loop + return length +end function +``` + +虽然这个函数很大,但它还是很简单的。大多数的代码都是在检查所有各种条件,每个代码都是很简单的。此外,所有的无符号整数的大小写都是相同的(除了底以外)。因此在汇编中可以将它们汇总。下面是它的汇编代码。 + +```assembly +.globl FormatString +FormatString: +format .req r4 +formatLength .req r5 +dest .req r6 +nextArg .req r7 +argList .req r8 +length .req r9 + +push {r4,r5,r6,r7,r8,r9,lr} +mov format,r0 +mov formatLength,r1 +mov dest,r2 +mov nextArg,r3 +add argList,sp,#7*4 +mov length,#0 + +formatLoop$: + subs formatLength,#1 + movlt r0,length + poplt {r4,r5,r6,r7,r8,r9,pc} + + ldrb r0,[format] + add format,#1 + teq r0,#'%' + beq formatArg$ + +formatChar$: + teq dest,#0 + strneb r0,[dest] + addne dest,#1 + add length,#1 + b formatLoop$ + +formatArg$: + subs formatLength,#1 + movlt r0,length + poplt {r4,r5,r6,r7,r8,r9,pc} + + ldrb r0,[format] + add format,#1 + teq r0,#'%' + beq formatChar$ + + teq r0,#'c' + moveq r0,nextArg + ldreq nextArg,[argList] + addeq argList,#4 + beq formatChar$ + + teq r0,#'s' + beq formatString$ + + teq r0,#'d' + beq formatSigned$ + + teq r0,#'u' + teqne r0,#'x' + teqne r0,#'b' + teqne r0,#'o' + beq formatUnsigned$ + + b formatLoop$ + +formatString$: + ldrb r0,[nextArg] + teq r0,#0x0 + ldreq nextArg,[argList] + addeq argList,#4 + beq formatLoop$ + add length,#1 + teq dest,#0 + strneb r0,[dest] + addne dest,#1 + add nextArg,#1 + b formatString$ + +formatSigned$: + mov r0,nextArg + ldr nextArg,[argList] + add argList,#4 + mov r1,dest + mov r2,#10 + bl SignedString + teq dest,#0 + addne dest,r0 + add length,r0 + b formatLoop$ + +formatUnsigned$: + teq r0,#'u' + moveq r2,#10 + teq r0,#'x' + moveq r2,#16 + teq r0,#'b' + moveq r2,#2 + teq r0,#'o' + moveq r2,#8 + + mov r0,nextArg + ldr nextArg,[argList] + add argList,#4 + mov r1,dest + bl UnsignedString + teq dest,#0 + addne dest,r0 + add length,r0 + b formatLoop$ +``` + +### 5、一个转换操作系统 + +你可以使用这个方法随意转换你希望的任何东西。比如,下面的代码将生成一个换算表,可以做从十进制到二进制到十六进制到八进制以及到 ASCII 的换算操作。 + +删除 `main.s` 文件中 `bl SetGraphicsAddress` 之后的所有代码,然后粘贴以下的代码进去。 + +```assembly +mov r4,#0 +loop$: +ldr r0,=format +mov r1,#formatEnd-format +ldr r2,=formatEnd +lsr r3,r4,#4 +push {r3} +push {r3} +push {r3} +push {r3} +bl FormatString +add sp,#16 + +mov r1,r0 +ldr r0,=formatEnd +mov r2,#0 +mov r3,r4 + +cmp r3,#768-16 +subhi r3,#768 +addhi r2,#256 +cmp r3,#768-16 +subhi r3,#768 +addhi r2,#256 +cmp r3,#768-16 +subhi r3,#768 +addhi r2,#256 + +bl DrawString + +add r4,#16 +b loop$ + +.section .data +format: +.ascii "%d=0b%b=0x%x=0%o='%c'" +formatEnd: +``` + +你能在测试之前推算出将发生什么吗?特别是对于 `r3 ≥ 128` 会发生什么?尝试在树莓派上运行它,看看你是否猜对了。如果不能正常运行,请查看我们的排错页面。 + +如果一切顺利,恭喜你!你已经完成了屏幕04 教程,屏幕系列的课程结束了!我们学习了像素和帧缓冲的知识,以及如何将它们应用到树莓派上。我们学习了如何绘制简单的线条,也学习如何绘制字符,以及将数字格式化为文本的宝贵技能。我们现在已经拥有了在一个操作系统上进行图形输出的全部知识。你可以写出更多的绘制方法吗?三维绘图是什么?你能实现一个 24 位帧缓冲吗?能够从命令行上读取帧缓冲的大小吗? + +接下来的课程是[输入][4]系列课程,它将教我们如何使用键盘和鼠标去实现一个传统的计算机控制台。 + +-------------------------------------------------------------------------------- + +via: https://www.cl.cam.ac.uk/projects/raspberrypi/tutorials/os/screen04.html + +作者:[Alex Chadwick][a] +选题:[lujun9972][b] +译者:[qhwdw](https://github.com/qhwdw) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]: https://www.cl.cam.ac.uk +[b]: https://github.com/lujun9972 +[1]: https://linux.cn/article-10585-1.html +[2]: http://www.cplusplus.com/reference/clibrary/cstdio/sprintf/ +[3]: https://linux.cn/article-10458-1.html +[4]: https://www.cl.cam.ac.uk/projects/raspberrypi/tutorials/os/input01.html diff --git a/published/20170223 Use Emacs to create OAuth 2.0 UML sequence diagrams.md b/published/20170223 Use Emacs to create OAuth 2.0 UML sequence diagrams.md new file mode 100644 index 0000000000..23b1075f74 --- /dev/null +++ b/published/20170223 Use Emacs to create OAuth 2.0 UML sequence diagrams.md @@ -0,0 +1,149 @@ +[#]: collector: (lujun9972) +[#]: translator: (lujun9972) +[#]: reviewer: (wxy) +[#]: publisher: (wxy) +[#]: url: (https://linux.cn/article-10582-1.html) +[#]: subject: (Use Emacs to create OAuth 2.0 UML sequence diagrams) +[#]: via: (https://www.onwebsecurity.com/configuration/use-emacs-to-create-oauth-2-0-uml-sequence-diagrams.html) +[#]: author: (Peter Mosmans https://www.onwebsecurity.com) + +使用 Emacs 创建 OAuth 2.0 的 UML 序列图 +====== + +![OAuth 2.0 abstract protocol flow][6] + +看起来 [OAuth 2.0 框架][7] 已经越来越广泛地应用于 web (和 移动) 应用。太棒了! + +虽然协议本身并不复杂,但有很多的使用场景、流程和实现可供选择。正如生活中的大多数事物一样,魔鬼在于细节之中。 + +在审查 OAuth 2.0 实现或编写渗透测试报告时我习惯画出 UML 图。这方便让人理解发生了什么事情,并发现潜在的问题。毕竟,一图抵千言。 + +使用基于 GPL 开源协议 [Emacs][8] 编辑器来实现,再加上基于 GPL 开源协议的工具 [PlantUML][9] (也可以选择基于 Eclipse Public 协议的 [Graphviz][10]) 很容易做到这一点。 + +Emacs 是世界上最万能的编辑器。在这种场景中,我们用它来编辑文本,并自动将文本转换成图片。PlantUML 是一个允许你用人类可读的文本来写 UML 并完成该转换的工具。Graphviz 是一个可视化的软件,这里我们可以用它来显示图片。 + +下载 [预先编译好了的 PlantUML jar 文件 ][11],[Emacs][12] 还可以选择下载并安装 [Graphviz][13]。 + +安装并启动 Emacs,然后将下面 Lisp 代码(实际上是配置)写入你的启动文件中(`~/.emacs.d/init.d`),这段代码将会: + + * 配置 org 模式(一种用来组织并编辑文本文件的模式)来使用 PlantUML + * 将 `plantuml` 添加到可识别的 “org-babel” 语言中(这让你可以在文本文件中执行源代码) + * 将 PlantUML 代码标注为安全的,从而允许执行 + * 自动显示生成的结果图片 + +```elisp +;; tell org-mode where to find the plantuml JAR file (specify the JAR file) +(setq org-plantuml-jar-path (expand-file-name "~/plantuml.jar")) + +;; use plantuml as org-babel language +(org-babel-do-load-languages 'org-babel-load-languages '((plantuml . t))) + +;; helper function +(defun my-org-confirm-babel-evaluate (lang body) +"Do not ask for confirmation to evaluate code for specified languages." +(member lang '("plantuml"))) + +;; trust certain code as being safe +(setq org-confirm-babel-evaluate 'my-org-confirm-babel-evaluate) + +;; automatically show the resulting image +(add-hook 'org-babel-after-execute-hook 'org-display-inline-images) +``` + +如果你还没有启动文件,那么将该代码加入到 `~/.emacs.d/init.el` 文件中然后重启 Emacs。 + +提示:`Control-c Control-f` 可以让你创建/打开(新)文件。`Control-x Control-s` 保存文件,而 `Control-x Control-c` 退出 Emacs。 + +这就结了! + +要测试该配置,可以创建/打开(`Control-c Control-f`)后缀为 `.org` 的文件,例如 `test.org`。这会让 Emacs 切换到 org 模式并识别 “org-babel” 语法。 + +输入下面代码,然后在代码中输入 `Control-c Control-c` 来测试是否安装正常: + +``` +#+BEGIN_SRC plantuml :file test.png +@startuml +version +@enduml +#+END_SRC +``` + +一切顺利的话,你会在 Emacs 中看到文本下面显示了一张图片。 + +> **注意:** + +> 要快速插入类似 `#+BEGIN_SRC` 和 `#+END_SRC` 这样的代码片段,你可以使用内置的 Easy Templates 系统:输入 ` user : request authorization +note left +**grant types**: +# authorization code +# implicit +# password +# client_credentials +end note +user --> client : authorization grant +end + +group token is generated +client -> authorization : request token\npresent authorization grant +authorization --> client :var: access token +note left +**response types**: +# code +# token +end note +end group + +group resource can be accessed +client -> resource : request resource\npresent token +resource --> client : resource +end group +@enduml +#+END_SRC +``` + +你难道会不喜欢 Emacs 和开源工具的多功能性吗? + +-------------------------------------------------------------------------------- + +via: https://www.onwebsecurity.com/configuration/use-emacs-to-create-oauth-2-0-uml-sequence-diagrams.html + +作者:[Peter Mosmans][a] +选题:[lujun9972][b] +译者:[lujun9972](https://github.com/lujun9972) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]: https://www.onwebsecurity.com +[b]: https://github.com/lujun9972 +[1]: https://www.onwebsecurity.com/category/configuration.html +[2]: https://www.onwebsecurity.com/tag/emacs.html +[3]: https://www.onwebsecurity.com/tag/oauth2.html +[4]: https://www.onwebsecurity.com/tag/pentesting.html +[5]: https://www.onwebsecurity.com/tag/security.html +[6]: https://www.onwebsecurity.com/images/oauth2-abstract-protocol-flow.png +[7]: https://tools.ietf.org/html/rfc6749 +[8]: https://www.gnu.org/software/emacs/ +[9]: https://plantuml.com +[10]: http://www.graphviz.org/ +[11]: http://plantuml.com/download +[12]: https://www.gnu.org/software/emacs/download.html +[13]: http://www.graphviz.org/Download.php diff --git a/published/20170519 zsh shell inside Emacs on Windows.md b/published/20170519 zsh shell inside Emacs on Windows.md new file mode 100644 index 0000000000..894c924416 --- /dev/null +++ b/published/20170519 zsh shell inside Emacs on Windows.md @@ -0,0 +1,103 @@ +[#]: collector: (lujun9972) +[#]: translator: (lujun9972) +[#]: reviewer: (wxy) +[#]: publisher: (wxy) +[#]: url: (https://linux.cn/article-10610-1.html) +[#]: subject: (zsh shell inside Emacs on Windows) +[#]: via: (https://www.onwebsecurity.com/configuration/zsh-shell-inside-emacs-on-windows.html) +[#]: author: (Peter Mosmans https://www.onwebsecurity.com/) + +Windows 下 Emacs 中的 zsh shell +====== + +![zsh shell inside Emacs on Windows][5] + +运行跨平台 shell(例如 Bash 或 zsh)的最大优势在于你能在多平台上使用同样的语法和脚本。在 Windows 上设置(替换)shell 挺麻烦的,但所获得的回报远远超出这小小的付出。 + +MSYS2 子系统允许你在 Windows 上运行 Bash 或 zsh 之类的 shell。使用 MSYS2 很重要的一点在于确保搜索路径都指向 MSYS2 子系统本身:存在太多依赖关系了。 + +MSYS2 安装后默认的 shell 就是 Bash;zsh 则可以通过包管理器进行安装: + +``` +pacman -Sy zsh +``` + +通过修改 `etc/passwd` 文件可以设置 zsh 作为默认 shell,例如: + +``` +mkpasswd -c | sed -e 's/bash/zsh/' | tee -a /etc/passwd +``` + +这会将默认 shell 从 bash 改成 zsh。 + +要在 Windows 上的 Emacs 中运行 zsh ,需要修改 `shell-file-name` 变量,将它指向 MSYS2 子系统中的 zsh 二进制文件。该二进制 shell 文件在 Emacs `exec-path` 变量中的某个地方。 + +``` +(setq shell-file-name (executable-find "zsh.exe")) +``` + +不要忘了修改 Emacs 的 `PATH` 环境变量,因为 MSYS2 路径应该先于 Windows 路径。接上一个例子,假设 MSYS2 安装在 `c:\programs\msys2` 中,那么执行: + +``` +(setenv "PATH" "C:\\programs\\msys2\\mingw64\\bin;C:\\programs\\msys2\\usr\\local\\bin;C:\\programs\\msys2\\usr\\bin;C:\\Windows\\System32;C:\\Windows") +``` + +在 Emacs 配置文件中设置好这两个变量后,在 Emacs 中运行: + +``` +M-x shell +``` + +应该就能看到熟悉的 zsh 提示符了。 + +Emacs 的终端设置(eterm)与 MSYS2 的标准终端设置(xterm-256color)不一样。这意味着某些插件和主题(提示符)可能不能正常工作 - 尤其在使用 oh-my-zsh 时。 + +检测 zsh 否则在 Emacs 中运行很简单,使用变量 `$INSIDE_EMACS`。 + +下面这段代码片段取自 `.zshrc`(当以交互式 shell 模式启动时会被加载),它会在 zsh 在 Emacs 中运行时启动 git 插件并更改主题: + +``` +# Disable some plugins while running in Emacs +if [[ -n "$INSIDE_EMACS" ]]; then + plugins=(git) + ZSH_THEME="simple" +else + ZSH_THEME="compact-grey" +fi +``` + +通过在本地 `~/.ssh/config` 文件中将 `INSIDE_EMACS` 变量设置为 `SendEnv` 变量…… + +``` +Host myhost +SendEnv INSIDE_EMACS +``` + +……同时在 ssh 服务器的 `/etc/ssh/sshd_config` 中设置为 `AcceptEnv` 变量…… + +``` +AcceptEnv LANG LC_* INSIDE_EMACS +``` + +……这使得在 Emacs shell 会话中通过 ssh 登录另一个运行着 zsh 的 ssh 服务器也能工作的很好。当在 Windows 下的 Emacs 中的 zsh 上通过 ssh 远程登录时,记得使用参数 `-t`,`-t` 参数会强制分配伪终端(之所以需要这样,时因为 Windows 下的 Emacs 并没有真正的 tty)。 + +跨平台,开源真是个好东西…… + +-------------------------------------------------------------------------------- + +via: https://www.onwebsecurity.com/configuration/zsh-shell-inside-emacs-on-windows.html + +作者:[Peter Mosmans][a] +选题:[lujun9972][b] +译者:[lujun9972](https://github.com/lujun9972) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]: https://www.onwebsecurity.com/ +[b]: https://github.com/lujun9972 +[1]: https://www.onwebsecurity.com/category/configuration.html +[2]: https://www.onwebsecurity.com/tag/emacs.html +[3]: https://www.onwebsecurity.com/tag/msys2.html +[4]: https://www.onwebsecurity.com/tag/zsh.html +[5]: https://www.onwebsecurity.com//images/zsh-shell-inside-emacs-on-windows.png diff --git a/published/20170721 Firefox and org-protocol URL Capture.md b/published/20170721 Firefox and org-protocol URL Capture.md new file mode 100644 index 0000000000..c9c5bba603 --- /dev/null +++ b/published/20170721 Firefox and org-protocol URL Capture.md @@ -0,0 +1,121 @@ +[#]: collector: (lujun9972) +[#]: translator: (lujun9972) +[#]: reviewer: (wxy) +[#]: publisher: (wxy) +[#]: url: (https://linux.cn/article-10586-1.html) +[#]: subject: (Firefox and org-protocol URL Capture) +[#]: via: (http://www.mediaonfire.com/blog/2017_07_21_org_protocol_firefox.html) +[#]: author: (Andreas Viklund http://andreasviklund.com/) + +在 Firefox 上使用 Org 协议捕获 URL +====== + +### 介绍 + +作为一名 Emacs 人,我尽可能让所有的工作流都在 [Org 模式][1]Org-mode 上进行 —— 我比较喜欢文本。 + +我倾向于将书签记录在 [Org 模式][1] 代办列表中,而 [Org 协议][2]Org-protocol 则允许外部进程利用 [Org 模式][1] 的某些功能。然而,要做到这一点配置起来很麻烦。([搜索引擎上][3])有很多教程,Firefox 也有这类 [扩展][4],然而我对它们都不太满意。 + +因此我决定将我现在的配置记录在这篇博客中,方便其他有需要的人使用。 + +### 配置 Emacs Org 模式 + +启用 Org 协议: + +``` +(require 'org-protocol) +``` + +添加一个捕获模板capture template —— 我的配置是这样的: + +``` +(setq org-capture-templates + (quote (... + ("w" "org-protocol" entry (file "~/org/refile.org") + "* TODO Review %a\n%U\n%:initial\n" :immediate-finish) + ...))) +``` + +你可以从 [Org 模式][1] 手册中 [捕获模板][5] 章节中获取帮助。 + +设置默认使用的模板: + +``` +(setq org-protocol-default-template-key "w") +``` + +执行这些新增配置让它们在当前 Emacs 会话中生效。 + +### 快速测试 + +在下一步开始前,最好测试一下配置: + +``` +emacsclient -n "org-protocol:///capture?url=http%3a%2f%2fduckduckgo%2ecom&title=DuckDuckGo" +``` + +基于的配置的模板,可能会弹出一个捕获窗口。请确保正常工作,否则后面的操作没有任何意义。如果工作不正常,检查刚才的配置并且确保你执行了这些代码块。 + +如果你的 [Org 模式][1] 版本比较老(老于 7 版本),测试的格式会有点不同:这种 URL 编码后的格式需要改成用斜杠来分割 url 和标题。在网上搜一下很容易找出这两者的不同。 + +### Firefox 协议 + +现在开始设置 Firefox。浏览 `about:config`。右击配置项列表,选择 “New -> Boolean”,然后输入 `network.protocol-handler.expose.org-protocol` 作为名字并且将值设置为 `true`。 + +有些教程说这一步是可以省略的 —— 配不配因人而异。 + +### 添加 Desktop 文件 + +大多数的教程都有这一步: + +增加一个文件 `~/.local/share/applications/org-protocol.desktop`: + +``` +[Desktop Entry] +Name=org-protocol +Exec=/path/to/emacsclient -n %u +Type=Application +Terminal=false +Categories=System; +MimeType=x-scheme-handler/org-protocol; +``` + +然后运行更新器。对于 i3 窗口管理器我使用下面命令(跟 gnome 一样): + +``` +update-desktop-database ~/.local/share/applications/ +``` + +KDE 的方法不太一样……你可以查询其他相关教程。 + +### 在 FireFox 中设置捕获按钮 + +创建一个书签(我是在工具栏上创建这个书签的),地址栏输入下面内容: + +``` +javascript:location.href="org-protocol:///capture?url="+encodeURIComponent(location.href)+"&title="+encodeURIComponent(document.title||"[untitled page]") +``` + +保存该书签后,再次编辑该书签,你应该会看到其中的所有空格都被替换成了 `%20` —— 也就是空格的 URL 编码形式。 + +现在当你点击该书签,你就会在某个 Emacs 框架中,可能是一个任意的框架中,打开一个窗口,显示你预定的模板。 + + +-------------------------------------------------------------------------------- + +via: http://www.mediaonfire.com/blog/2017_07_21_org_protocol_firefox.html + +作者:[Andreas Viklund][a] +选题:[lujun9972][b] +译者:[lujun9972](https://github.com/lujun9972) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]: http://andreasviklund.com/ +[b]: https://github.com/lujun9972 +[1]: http://orgmode.org/ +[2]: http://orgmode.org/worg/org-contrib/org-protocol.html +[3]: https://duckduckgo.com/?q=org-protocol+firefox&t=ffab&ia=qa +[4]: https://addons.mozilla.org/en-US/firefox/search/?q=org-protocol&cat=1,0&appver=53.0&platform=linux +[5]: http://orgmode.org/manual/Capture-templates.html diff --git a/published/20171119 Advanced Techniques for Reducing Emacs Startup Time.md b/published/20171119 Advanced Techniques for Reducing Emacs Startup Time.md new file mode 100644 index 0000000000..b6b5819c91 --- /dev/null +++ b/published/20171119 Advanced Techniques for Reducing Emacs Startup Time.md @@ -0,0 +1,245 @@ +[#]: collector: (lujun9972) +[#]: translator: (lujun9972) +[#]: reviewer: (wxy) +[#]: publisher: (wxy) +[#]: url: (https://linux.cn/article-10625-1.html) +[#]: subject: (Advanced Techniques for Reducing Emacs Startup Time) +[#]: via: (https://blog.d46.us/advanced-emacs-startup/) +[#]: author: (Joe Schafer https://blog.d46.us/) + +降低 Emacs 启动时间的高级技术 +====== + +> 《[Emacs Start Up Profiler][1]》 的作者教你六项减少 Emacs 启动时间的技术。 + +简而言之:做下面几个步骤: + +1. 使用 Esup 进行性能检测。 +2. 调整垃圾回收的阀值。 +3. 使用 use-package 来自动(延迟)加载所有东西。 +4. 不要使用会引起立即加载的辅助函数。 +5. 参考我的 [配置][2]。 + +### 从 .emacs.d 的失败到现在 + +我最近宣布了 .emacs.d 的第三次失败,并完成了第四次 Emacs 配置的迭代。演化过程为: + +1. 拷贝并粘贴 elisp 片段到 `~/.emacs` 中,希望它能工作。 +2. 借助 `el-get` 来以更结构化的方式来管理依赖关系。 +3. 放弃自己从零配置,以 Spacemacs 为基础。 +4. 厌倦了 Spacemacs 的复杂性,基于 `use-package` 重写配置。 + +本文汇聚了三次重写和创建 《[Emacs Start Up Profiler][1]》过程中的技巧。非常感谢 Spacemacs、use-package 等背后的团队。没有这些无私的志愿者,这项任务将会困难得多。 + +### 不过守护进程模式又如何呢 + +在我们开始之前,让我反驳一下优化 Emacs 时的常见观念:“Emacs 旨在作为守护进程来运行的,因此你只需要运行一次而已。” + +这个观点很好,只不过: + +- 速度总是越快越好。 +- 配置 Emacs 时,可能会有不得不通过重启 Emacs 的情况。例如,你可能为 `post-command-hook` 添加了一个运行缓慢的 `lambda` 函数,很难删掉它。 +- 重启 Emacs 能帮你验证不同会话之间是否还能保留配置。 + +### 1、估算当前以及最佳的启动时间 + +第一步是测量当前的启动时间。最简单的方法就是在启动时显示后续步骤进度的信息。 + +``` +;; Use a hook so the message doesn't get clobbered by other messages. +(add-hook 'emacs-startup-hook + (lambda () + (message "Emacs ready in %s with %d garbage collections." + (format "%.2f seconds" + (float-time + (time-subtract after-init-time before-init-time))) + gcs-done))) +``` + +第二步、测量最佳的启动速度,以便了解可能的情况。我的是 0.3 秒。 + +``` +# -q ignores personal Emacs files but loads the site files. +emacs -q --eval='(message "%s" (emacs-init-time))' + +;; For macOS users: +open -n /Applications/Emacs.app --args -q --eval='(message "%s" (emacs-init-time))' +``` + +### 2、检测 Emacs 启动指标对你大有帮助 + +《[Emacs StartUp Profiler][1]》(ESUP)将会给你顶层语句执行的详细指标。 + +![esup.png][3] + +*图 1: Emacs Start Up Profiler 截图* + +> 警告:Spacemacs 用户需要注意,ESUP 目前与 Spacemacs 的 init.el 文件有冲突。遵照 上说的进行升级。 + +### 3、调高启动时垃圾回收的阀值 + +这为我节省了 **0.3 秒**。 + +Emacs 默认值是 760kB,这在现代机器看来极其保守。真正的诀窍在于初始化完成后再把它降到合理的水平。这为我节省了 0.3 秒。 + +``` +;; Make startup faster by reducing the frequency of garbage +;; collection. The default is 800 kilobytes. Measured in bytes. +(setq gc-cons-threshold (* 50 1000 1000)) + +;; The rest of the init file. + +;; Make gc pauses faster by decreasing the threshold. +(setq gc-cons-threshold (* 2 1000 1000)) +``` + +*~/.emacs.d/init.el* + +### 4、不要 require 任何东西,而是使用 use-package 来自动加载 + +让 Emacs 变坏的最好方法就是减少要做的事情。`require` 会立即加载源文件,但是很少会出现需要在启动阶段就立即需要这些功能的。 + +在 [use-package][4] 中你只需要声明好需要哪个包中的哪个功能,`use-package` 就会帮你完成正确的事情。它看起来是这样的: + +``` +(use-package evil-lisp-state ; the Melpa package name + + :defer t ; autoload this package + + :init ; Code to run immediately. + (setq evil-lisp-state-global nil) + + :config ; Code to run after the package is loaded. + (abn/define-leader-keys "k" evil-lisp-state-map)) +``` + +可以通过查看 `features` 变量来查看 Emacs 现在加载了那些包。想要更好看的输出可以使用 [lpkg explorer][5] 或者我在 [abn-funcs-benchmark.el][6] 中的变体。输出看起来类似这样的: + +``` +479 features currently loaded + - abn-funcs-benchmark: /Users/jschaf/.dotfiles/emacs/funcs/abn-funcs-benchmark.el + - evil-surround: /Users/jschaf/.emacs.d/elpa/evil-surround-20170910.1952/evil-surround.elc + - misearch: /Applications/Emacs.app/Contents/Resources/lisp/misearch.elc + - multi-isearch: nil + - +``` + +### 5、不要使用辅助函数来设置模式 + +通常,Emacs 包会建议通过运行一个辅助函数来设置键绑定。下面是一些例子: + + * `(evil-escape-mode)` + * `(windmove-default-keybindings) ; 设置快捷键。` + * `(yas-global-mode 1) ; 复杂的片段配置。` + +可以通过 `use-package` 来对此进行重构以提高启动速度。这些辅助函数只会让你立即加载那些尚用不到的包。 + +下面这个例子告诉你如何自动加载 `evil-escape-mode`。 + +``` +;; The definition of evil-escape-mode. +(define-minor-mode evil-escape-mode + (if evil-escape-mode + (add-hook 'pre-command-hook 'evil-escape-pre-command-hook) + (remove-hook 'pre-command-hook 'evil-escape-pre-command-hook))) + +;; Before: +(evil-escape-mode) + +;; After: +(use-package evil-escape + :defer t + ;; Only needed for functions without an autoload comment (;;;###autoload). + :commands (evil-escape-pre-command-hook) + + ;; Adding to a hook won't load the function until we invoke it. + ;; With pre-command-hook, that means the first command we run will + ;; load evil-escape. + :init (add-hook 'pre-command-hook 'evil-escape-pre-command-hook)) +``` + +下面来看一个关于 `org-babel` 的例子,这个例子更为复杂。我们通常的配置时这样的: + +``` +(org-babel-do-load-languages + 'org-babel-load-languages + '((shell . t) + (emacs-lisp . nil))) +``` + +这不是个好的配置,因为 `org-babel-do-load-languages` 定义在 `org.el` 中,而该文件有超过 2 万 4 千行的代码,需要花 0.2 秒来加载。通过查看源代码可以看到 `org-babel-do-load-languages` 仅仅只是加载 `ob-` 包而已,像这样: + +``` +;; From org.el in the org-babel-do-load-languages function. +(require (intern (concat "ob-" lang))) +``` + +而在 `ob-.el` 文件中,我们只关心其中的两个方法 `org-babel-execute:` 和 `org-babel-expand-body:`。我们可以延时加载 org-babel 相关功能而无需调用 `org-babel-do-load-languages`,像这样: + +``` +;; Avoid `org-babel-do-load-languages' since it does an eager require. +(use-package ob-python + :defer t + :ensure org-plus-contrib + :commands (org-babel-execute:python)) + +(use-package ob-shell + :defer t + :ensure org-plus-contrib + :commands + (org-babel-execute:sh + org-babel-expand-body:sh + + org-babel-execute:bash + org-babel-expand-body:bash)) +``` + +### 6、使用惰性定时器来推迟加载非立即需要的包 + +我推迟加载了 9 个包,这帮我节省了 **0.4 秒**。 + +有些包特别有用,你希望可以很快就能使用它们,但是它们本身在 Emacs 启动过程中又不是必须的。这些软件包包括: + +- `recentf`:保存最近的编辑过的那些文件。 +- `saveplace`:保存访问过文件的光标位置。 +- `server`:开启 Emacs 守护进程。 +- `autorevert`:自动重载被修改过的文件。 +- `paren`:高亮匹配的括号。 +- `projectile`:项目管理工具。 +- `whitespace`:高亮行尾的空格。 + +不要 `require` 这些软件包,**而是等到空闲 N 秒后再加载它们**。我在 1 秒后加载那些比较重要的包,在 2 秒后加载其他所有的包。 + +``` +(use-package recentf + ;; Loads after 1 second of idle time. + :defer 1) + +(use-package uniquify + ;; Less important than recentf. + :defer 2) +``` + +### 不值得的优化 + +不要费力把你的 Emacs 配置文件编译成字节码了。这只节省了大约 0.05 秒。把配置文件编译成字节码还可能导致源文件与编译后的文件不一致从而难以重现错误进行调试。 + +-------------------------------------------------------------------------------- + +via: https://blog.d46.us/advanced-emacs-startup/ + +作者:[Joe Schafer][a] +选题:[lujun9972][b] +译者:[lujun9972](https://github.com/lujun9972) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]: https://blog.d46.us/ +[b]: https://github.com/lujun9972 +[1]: https://github.com/jschaf/esup +[2]: https://github.com/jschaf/dotfiles/blob/master/emacs/start.el +[3]: https://blog.d46.us/images/esup.png +[4]: https://github.com/jwiegley/use-package +[5]: https://gist.github.com/RockyRoad29/bd4ca6fdb41196a71662986f809e2b1c +[6]: https://github.com/jschaf/dotfiles/blob/master/emacs/funcs/abn-funcs-benchmark.el diff --git a/published/20171212 Toplip – A Very Strong File Encryption And Decryption CLI Utility.md b/published/20171212 Toplip – A Very Strong File Encryption And Decryption CLI Utility.md new file mode 100644 index 0000000000..8ae771aa28 --- /dev/null +++ b/published/20171212 Toplip – A Very Strong File Encryption And Decryption CLI Utility.md @@ -0,0 +1,227 @@ +toplip:一款十分强大的文件加密解密 CLI 工具 +====== +![](https://www.ostechnix.com/wp-content/uploads/2017/12/Toplip-720x340.jpg) + +在市场上能找到许多用来保护文件的文档加密工具。我们已经介绍过其中一些例如 [Cryptomater][1]、[Cryptkeeper][2]、[CryptGo][3]、[Cryptr][4]、[Tomb][5],以及 [GnuPG][6] 等加密工具。今天我们将讨论另一款叫做 “toplip” 的命令行文件加密解密工具。它是一款使用一种叫做 [AES256][7] 的强大加密方法的自由开源的加密工具。它同时也使用了 XTS-AES 设计以保护你的隐私数据。它还使用了 [Scrypt][8],一种基于密码的密钥生成函数来保护你的密码免于暴力破解。 + +### 优秀的特性 + +相比于其它文件加密工具,toplip 自带以下独特且杰出的特性。 + + * 非常强大的基于 XTS-AES256 的加密方法。 + * 合理的推诿Plausible deniability。 + * 加密并嵌入文件到图片(PNG/JPG)中。 + * 多重密码保护。 + * 可防护直接暴力破解。 + * 无可辨识的输出标记。 + * 开源(GPLv3)。 + +### 安装 toplip + +没有什么需要安装的。`toplip` 是独立的可执行二进制文件。你所要做的仅是从 [产品官方页面][9] 下载最新版的 `toplip` 并赋予它可执行权限。为此你只要运行: + +``` +chmod +x toplip +``` + +### 使用 + +如果你不带任何参数运行 `toplip`,你将看到帮助页面。 + +``` +./toplip +``` + +![][10] + +请允许我给你展示一些例子。 + +为了达到指导目的,我建了两个文件 `file1` 和 `file2`。我同时也有 `toplip` 可执行二进制文件。我把它们全都保存进一个叫做 `test` 的目录。 + +![][12] + +#### 加密/解密单个文件 + +现在让我们加密 `file1`。为此,运行: + +``` +./toplip file1 > file1.encrypted +``` + +这行命令将让你输入密码。一旦你输入完密码,它就会加密 `file1` 的内容并将它们保存进你当前工作目录下一个叫做 `file1.encrypted` 的文件。 + +上述命令行的示例输出将会是这样: + +``` +This is toplip v1.20 (C) 2015, 2016 2 Ton Digital. Author: Jeff Marrison A showcase piece for the HeavyThing library. Commercial support available Proudly made in Cooroy, Australia. More info: https://2ton.com.au/toplip file1 Passphrase #1: generating keys...Done +Encrypting...Done +``` + +为了验证文件是否的确经过加密,试着打开它你会发现一些随机的字符。 + +为了解密加密过的文件,像以下这样使用 `-d` 参数: + +``` +./toplip -d file1.encrypted +``` + +这行命令会解密提供的文档并在终端窗口显示内容。 + +为了保存文档而不是写入到标准输出,运行: + +``` +./toplip -d file1.encrypted > file1.decrypted +``` + +输入正确的密码解密文档。`file1.encrypted` 的所有内容将会存入一个叫做 `file1.decrypted` 的文档。 + +请不要用这种命名方法,我这样用仅仅是为了便于理解。使用其它难以预测的名字。 + +#### 加密/解密多个文件 + +现在我们将使用两个分别的密码加密每个文件。 + +``` +./toplip -alt file1 file2 > file3.encrypted +``` + +你会被要求为每个文件输入一个密码,使用不同的密码。 + +上述命令行的示例输出将会是这样: + +``` +This is toplip v1.20 (C) 2015, 2016 2 Ton Digital. Author: Jeff Marrison A showcase piece for the HeavyThing library. Commercial support available Proudly made in Cooroy, Australia. More info: https://2ton.com.au/toplip +file2 Passphrase #1 : generating keys...Done +file1 Passphrase #1 : generating keys...Done +Encrypting...Done +``` + +上述命令所做的是加密两个文件的内容并将它们保存进一个单独的叫做 `file3.encrypted` 的文件。在保存中分别给予各自的密码。比如说如果你提供 `file1` 的密码,`toplip` 将复原 `file1`。如果你提供 `file2` 的密码,`toplip` 将复原 `file2`。 + +每个 `toplip` 加密输出都可能包含最多四个单独的文件,并且每个文件都建有各自独特的密码。由于加密输出放在一起的方式,一下判断出是否存在多个文档不是一件容易的事。默认情况下,甚至就算确实只有一个文件是由 `toplip` 加密,随机数据都会自动加上。如果指定了多于一个文件,每个都有自己的密码,那么你可以有选择性地独立解码每个文件,以此来否认其它文件存在的可能性。这能有效地使一个用户在可控的暴露风险下打开一个加密的捆绑文件包。并且对于敌人来说,在计算上没有一种低廉的办法来确认额外的秘密数据存在。这叫做“合理的推诿Plausible deniability”,是 toplip 著名的特性之一。 + +为了从 `file3.encrypted` 解码 `file1`,仅需输入: + +``` +./toplip -d file3.encrypted > file1.encrypted +``` + +你将会被要求输入 `file1` 的正确密码。 + +为了从 `file3.encrypted` 解码 `file2`,输入: + +``` +./toplip -d file3.encrypted > file2.encrypted +``` + +别忘了输入 `file2` 的正确密码。 + +#### 使用多重密码保护 + +这是我中意的另一个炫酷特性。在加密过程中我们可以为单个文件提供多重密码。这样可以保护密码免于暴力尝试。 + +``` +./toplip -c 2 file1 > file1.encrypted +``` + +这里,`-c 2` 代表两个不同的密码。上述命令行的示例输出将会是这样: + +``` +This is toplip v1.20 (C) 2015, 2016 2 Ton Digital. Author: Jeff Marrison A showcase piece for the HeavyThing library. Commercial support available Proudly made in Cooroy, Australia. More info: https://2ton.com.au/toplip +file1 Passphrase #1: generating keys...Done +file1 Passphrase #2: generating keys...Done +Encrypting...Done +``` + +正如你在上述示例中所看到的,`toplip` 要求我输入两个密码。请注意你必须提供两个不同的密码,而不是提供两遍同一个密码。 + +为了解码这个文件,这样做: + +``` +$ ./toplip -c 2 -d file1.encrypted > file1.decrypted +This is toplip v1.20 (C) 2015, 2016 2 Ton Digital. Author: Jeff Marrison A showcase piece for the HeavyThing library. Commercial support available Proudly made in Cooroy, Australia. More info: https://2ton.com.au/toplip +file1.encrypted Passphrase #1: generating keys...Done +file1.encrypted Passphrase #2: generating keys...Done +Decrypting...Done +``` + +#### 将文件藏在图片中 + +将一个文件、消息、图片或视频藏在另一个文件里的方法叫做隐写术。幸运的是 `toplip` 默认包含这个特性。 + +为了将文件藏入图片中,像如下所示的样子使用 `-m` 参数。 + +``` +$ ./toplip -m image.png file1 > image1.png +This is toplip v1.20 (C) 2015, 2016 2 Ton Digital. Author: Jeff Marrison A showcase piece for the HeavyThing library. Commercial support available Proudly made in Cooroy, Australia. More info: https://2ton.com.au/toplip +file1 Passphrase #1: generating keys...Done +Encrypting...Done +``` + +这行命令将 `file1` 的内容藏入一张叫做 `image1.png` 的图片中。 + +要解码,运行: + +``` +$ ./toplip -d image1.png > file1.decrypted This is toplip v1.20 (C) 2015, 2016 2 Ton Digital. Author: Jeff Marrison A showcase piece for the HeavyThing library. Commercial support available Proudly made in Cooroy, Australia. More info: https://2ton.com.au/toplip +image1.png Passphrase #1: generating keys...Done +Decrypting...Done +``` + +#### 增加密码复杂度 + +为了进一步使文件变得难以破译,我们可以像以下这样增加密码复杂度: + +``` +./toplip -c 5 -i 0x8000 -alt file1 -c 10 -i 10 file2 > file3.encrypted +``` + +上述命令将会要求你为 `file1` 输入十条密码,为 `file2` 输入五条密码,并将它们存入单个叫做 `file3.encrypted` 的文件。如你所注意到的,我们在这个例子中又用了另一个 `-i` 参数。这是用来指定密钥生成循环次数。这个选项覆盖了 `scrypt` 函数初始和最终 PBKDF2 阶段的默认循环次数 1。十六进制和十进制数值都是允许的。比如说 `0x8000`、`10` 等。请注意这会大大增加计算次数。 + +为了解码 `file1`,使用: + +``` +./toplip -c 5 -i 0x8000 -d file3.encrypted > file1.decrypted +``` + +为了解码 `file2`,使用: + +``` +./toplip -c 10 -i 10 -d file3.encrypted > file2.decrypted +``` + +参考 `toplip` [官网](https://2ton.com.au/toplip/)以了解更多关于其背后的技术信息和使用的加密方式。 + +我个人对所有想要保护自己数据的人的建议是,别依赖单一的方法。总是使用多种工具/方法来加密文件。不要在纸上写下密码也不要将密码存入本地或云。记住密码,阅后即焚。如果你记不住,考虑使用任何了信赖的密码管理器。 + +- [KeeWeb – An Open Source, Cross Platform Password Manager](https://www.ostechnix.com/keeweb-an-open-source-cross-platform-password-manager/) +- [Buttercup – A Free, Secure And Cross-platform Password Manager](https://www.ostechnix.com/buttercup-a-free-secure-and-cross-platform-password-manager/) +- [Titan – A Command line Password Manager For Linux](https://www.ostechnix.com/titan-command-line-password-manager-linux/) + +今天就到此为止了,更多好东西后续推出,请保持关注。 + +顺祝时祺! + +-------------------------------------------------------------------------------- + +via: https://www.ostechnix.com/toplip-strong-file-encryption-decryption-cli-utility/ + +作者:[SK][a] +译者:[tomjlw](https://github.com/tomjlw) +校对:[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/cryptomator-open-source-client-side-encryption-tool-cloud/ +[2]:https://www.ostechnix.com/how-to-encrypt-your-personal-foldersdirectories-in-linux-mint-ubuntu-distros/ +[3]:https://www.ostechnix.com/cryptogo-easy-way-encrypt-password-protect-files/ +[4]:https://www.ostechnix.com/cryptr-simple-cli-utility-encrypt-decrypt-files/ +[5]:https://www.ostechnix.com/tomb-file-encryption-tool-protect-secret-files-linux/ +[6]:https://www.ostechnix.com/an-easy-way-to-encrypt-and-decrypt-files-from-commandline-in-linux/ +[7]:http://en.wikipedia.org/wiki/Advanced_Encryption_Standard +[8]:http://en.wikipedia.org/wiki/Scrypt +[9]:https://2ton.com.au/Products/ +[10]:https://www.ostechnix.com/wp-content/uploads/2017/12/toplip-2.png +[12]:https://www.ostechnix.com/wp-content/uploads/2017/12/toplip-1.png + diff --git a/published/20180122 Ick- a continuous integration system.md b/published/20180122 Ick- a continuous integration system.md new file mode 100644 index 0000000000..3c240f9545 --- /dev/null +++ b/published/20180122 Ick- a continuous integration system.md @@ -0,0 +1,67 @@ +ick:一个持续集成系统 +====== + +> ick 是一个持续集成(CI)系统。访问 获取更多信息。 + +更加详细的内容如下: + +### 首个公开版本发行 + +这个世界可能并不需要又一个持续集成系统(CI),但是我需要。我对我尝试过或者看过的持续集成系统感到不满意。更重要的是,有几样我感兴趣的东西比我所听说过的持续集成系统要强大得多。因此我开始编写我自己的 CI 系统。 + +我的新个人业余项目叫做 ick。它是一个 CI 系统,这意味着它可以运行自动化的步骤来构建、测试软件。它的主页是 ,[下载][1]页面有指向源代码、.deb 包和用来安装的 Ansible 脚本的链接。 + +我现已发布了首个公开版本,绰号 ALPHA-1,版本号 0.23。(LCTT 译注:截止至本译文发布,已经更新到 ALPHA-6)它现在是 alpha 品质,这意味着它并没拥有期望的全部特性,如果任何一个它已有的特性工作的话,那真是运气好。 + +### 诚邀贡献 + +ick 目前是我的个人项目。我希望能让它不仅限于此,同时我也诚邀更多贡献。访问[治理][2]页面查看章程,[入门][3]页面查看如何开始贡献的的小建议,[联系][4]页面查看如何联络。 + +### 架构 + +ick 拥有一个由几个通过 HTTPS 协议通信使用 RESTful API 和 JSON 处理结构化数据的部分组成的架构。访问[架构][5]页面了解细节。 + +### 宣告 + +持续集成(CI)是用于软件开发的强大工具。它不应枯燥、易溃或恼人。它构建起来应简单快速,除非正在测试、构建的代码中有问题,不然它应在后台安静地工作。 + +一个持续集成系统应该简单、易用、清楚、干净、可扩展、快速、综合、透明、可靠,并推动你的生产力。构建它不应花大力气、不应需要专门为 CI 而造的硬件、不应需要频繁留意以使其保持工作、开发者永远不必思考为什么某样东西不工作。 + +一个持续集成系统应该足够灵活以适应你的构建、测试需求。只要 CPU 架构和操作系统版本没问题,它应该支持各种操作者。 + +同时像所有软件一样,CI 应该彻彻底底的免费,你的 CI 应由你做主。 + +(目前的 ick 仅稍具雏形,但是它会尝试着有朝一日变得完美 —— 在最理想的情况下。) + +### 未来的梦想 + +长远来看,我希望 ick 拥有像下面所描述的特性。落实全部特性可能需要一些时间。 + +* 各种事件都可以触发构建。时间是一个明显的事件,因为项目的源代码仓库改变了。更强大的是任何依赖的改变,不管依赖是来自于 ick 构建的另一个项目,或者是包(比如说来自 Debian):ick 应当跟踪所有安装进一个项目构建环境中的包,如果任何一个包的版本改变,都应再次触发项目构建和测试。 +* ick 应该支持构建于(或针对)任何合理的目标平台,包括任何 Linux 发行版,任何自由的操作系统,以及任何一息尚存的不自由的操作系统。 +* ick 应该自己管理构建环境,并且能够执行与构建主机或网络隔离的构建。这部分工作:可以要求 ick 构建容器并在容器中运行构建。容器使用 systemd-nspawn 实现。 然而,这可以改进。(如果您认为 Docker 是唯一的出路,请为此提供支持。) +* ick 应当不需要安装任何专门的代理,就能支持各种它能够通过 ssh 或者串口或者其它这种中性的交流管道控制的操作者worker。ick 不应默认它可以有比如说一个完整的 Java Runtime,如此一来,操作者就可以是一个微控制器了。 +* ick 应当能轻松掌控一大批项目。我觉得不管一个新的 Debian 源包何时上传,ick 都应该要能够跟得上在 Debian 中构建所有东西的进度。(明显这可行与否取决于是否有足够的资源确实用在构建上,但是 ick 自己不应有瓶颈。) +* 如果有需要的话 ick 应当有选择性地补给操作者。如果所有特定种类的操作者处于忙碌中,且 ick 被设置成允许使用更多资源的话,它就应该这么做。这看起来用虚拟机、容器、云提供商等做可能会简单一些。 +* ick 应当灵活提醒感兴趣的团体,特别是关于其失败的方面。它应允许感兴趣的团体通过 IRC、Matrix、Mastodon、Twitter、email、SMS 甚至电话和语音合成来接受通知。例如“您好,感兴趣的团体。现在是四点钟您想被通知 hello 包什么时候为 RISC-V 构建好。” + +### 请提供反馈 + +如果你尝试过 ick 或者甚至你仅仅是读到这,请在上面分享你的想法。在[联系][4]页面查看如何发送反馈。相比私下反馈我更偏爱公开反馈。但如果你偏爱私下反馈,那也行。 + +-------------------------------------------------------------------------------- + +via: https://blog.liw.fi/posts/2018/01/22/ick_a_continuous_integration_system/ + +作者:[Lars Wirzenius][a] +译者:[tomjlw](https://github.com/tomjlw) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://blog.liw.fi/ +[1]:http://ick.liw.fi/download/ +[2]:http://ick.liw.fi/governance/ +[3]:http://ick.liw.fi/getting-started/ +[4]:http://ick.liw.fi/contact/ +[5]:http://ick.liw.fi/architecture/ diff --git a/published/20180202 Tips for success when getting started with Ansible.md b/published/20180202 Tips for success when getting started with Ansible.md new file mode 100644 index 0000000000..ab189fef6f --- /dev/null +++ b/published/20180202 Tips for success when getting started with Ansible.md @@ -0,0 +1,70 @@ +Ansible 入门秘诀 +====== + +> 用 Ansible 自动化你的数据中心的关键点。 + +![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/bus-big-data.png?itok=L34b2exg) + +Ansible 是一个开源自动化工具,可以从中央控制节点统一配置服务器、安装软件或执行各种 IT 任务。它采用一对多、无客户端agentless的机制,从控制节点上通过 SSH 发送指令给远端的客户机来完成任务(当然除了 SSH 外也可以用别的协议)。 + +Ansible 的主要使用群体是系统管理员,他们经常会周期性地执行一些安装、配置应用的工作。尽管如此,一些非特权用户也可以使用 Ansible,例如数据库管理员就可以通过 Ansible 用 `mysql` 这个用户来创建数据库、添加数据库用户、定义访问权限等。 + +让我们来看一个简单的使用场景,一位系统管理员每天要配置 100 台服务器,并且必须在每台机器上执行一系列 Bash 命令,然后交付给用户。 + +![](https://opensource.com/sites/default/files/u128651/mapping-bash-commands-to-ansible.png) + +这是个简单的例子,但应该能够证明:在 yaml 文件里写好命令然后在远程服务器上运行,是一件非常轻松的事。而且如果运行环境不同,就可以加入判断条件,指明某些命令只能在特定的服务器上运行(如:只在那些不是 Ubuntu 或 Debian 的系统上运行 `yum` 命令)。 + +Ansible 的一个重要特性是用剧本playbook来描述一个计算机系统的最终状态,所以一个剧本可以在服务器上反复执行而不影响其最终状态(LCTT 译注:即是幂等的)。如果某个任务已经被实施过了(如,“用户 `sysman` 已经存在”),那么 Ansible 就会忽略它继续执行后续的任务。 + +### 定义 + + * 任务task:是工作的最小单位,它可以是个动作,比如“安装一个数据库服务”、“安装一个 web 服务器”、“创建一条防火墙规则”或者“把这个配置文件拷贝到那个服务器上去”。 + * 动作play: 由任务组成,例如,一个动作的内容是要“设置一个数据库,给 web 服务用”,这就包含了如下任务:1)安装数据库包;2)设置数据库管理员密码;3)创建数据库实例;4)为该实例分配权限。 + * 剧本playbook:(LCTT 译注:playbook 原指美式橄榄球队的[战术手册][5],也常指“剧本”,此处惯例采用“剧本”译名)由动作组成,一个剧本可能像这样:“设置我的网站,包含后端数据库”,其中的动作包括:1)设置数据库服务器;2)设置 web 服务器。 + * 角色role:用来保存和组织剧本,以便分享和再次使用它们。还拿上个例子来说,如果你需要一个全新的 web 服务器,就可以用别人已经写好并分享出来的角色来设置。因为角色是高度可配置的(如果编写正确的话),可以根据部署需求轻松地复用它们。 + * [Ansible 星系][1]Ansible Galaxy:是一个在线仓库,里面保存的是由社区成员上传的角色,方便彼此分享。它与 GitHub 紧密集成,因此这些角色可以先在 Git 仓库里组织好,然后通过 Ansible 星系分享出来。 + +这些定义以及它们之间的关系可以用下图来描述: + +![](https://opensource.com/sites/default/files/u128651/ansible-definitions.png) + +请注意上面的例子只是组织任务的方式之一,我们当然也可以把安装数据库和安装 web 服务器的剧本拆开,放到不同的角色里。Ansible 星系上最常见的角色是独立安装、配置每个应用服务,你可以参考这些安装 [mysql][2] 和 [httpd][3] 的例子。 + +### 编写剧本的小技巧 + +学习 Ansible 最好的资源是其[官方文档][4]。另外,像学习其他东西一样,搜索引擎是你的好朋友。我推荐你从一些简单的任务开始,比如安装应用或创建用户。下面是一些有用的指南: + + * 在测试的时候少选几台服务器,这样你的动作可以执行的更快一些。如果它们在一台机器上执行成功,在其他机器上也没问题。 + * 总是在真正运行前做一次测试dry run,以确保所有的命令都能正确执行(要运行测试,加上 `--check-mode` 参数 )。 + * 尽可能多做测试,别担心搞砸。任务里描述的是所需的状态,如果系统已经达到预期状态,任务会被简单地忽略掉。 + * 确保在 `/etc/ansible/hosts` 里定义的主机名都可以被正确解析。 + * 因为是用 SSH 与远程主机通信,主控节点必须要能接受密钥,所以你面临如下选择:1)要么在正式使用之前就做好与远程主机的密钥交换工作;2)要么在开始管理某台新的远程主机时做好准备输入 “Yes”,因为你要接受对方的 SSH 密钥交换请求(LCTT 译注:还有另一个不那么安全的选择,修改主控节点的 ssh 配置文件,将 `StrictHostKeyChecking` 设置成 “no”)。 + * 尽管你可以在同一个剧本内把不同 Linux 发行版的任务整合到一起,但为每个发行版单独编写剧本会更明晰一些。 + +### 总结一下 + +Ansible 是你在数据中心里实施运维自动化的好选择,因为它: + + * 无需客户端,所以比其他自动化工具更易安装。 + * 将指令保存在 YAML 文件中(虽然也支持 JSON),比写 shell 脚本更简单。 + * 开源,因此你也可以做出自己的贡献,让它更加强大! + +你是怎样使用 Ansible 让数据中心更加自动化的呢?请在评论中分享您的经验。 + +-------------------------------------------------------------------------------- + +via: https://opensource.com/article/18/2/tips-success-when-getting-started-ansible + +作者:[Jose Delarosa][a] +译者:[jdh8383](https://github.com/jdh8383) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://opensource.com/users/jdelaros1 +[1]:https://galaxy.ansible.com/ +[2]:https://galaxy.ansible.com/bennojoy/mysql/ +[3]:https://galaxy.ansible.com/xcezx/httpd/ +[4]:http://docs.ansible.com/ +[5]:https://usafootball.com/football-playbook/ diff --git a/published/20180206 Power(Shell) to the people.md b/published/20180206 Power(Shell) to the people.md new file mode 100644 index 0000000000..6f81e417a1 --- /dev/null +++ b/published/20180206 Power(Shell) to the people.md @@ -0,0 +1,158 @@ +给大家安利一下 PowerShell +====== + +> 代码更简洁、脚本更清晰、跨平台一致性等好处是让 Linux 和 OS X 用户喜爱 PowerShell 的原因。 + +![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/BUSINESS_lightbulbs.png?itok=pwp22hTw) + +今年(2018)早些时候,[Powershell Core][1] 以 [MIT][3] 开源协议发布了[正式可用版(GA)][2]。PowerShell 算不上是新技术。自 2006 年为 Windows 发布了第一版 PowerShell 以来,PowerShell 的创建者在[结合了][4] Unⅸ shell 的强大和灵活的同时也在弥补他们所意识到的缺点,特别是从组合命令中获取值时所要进行的文本操作。 + +在发布了 5 个主要版本之后,PowerShell 已经可以在所有主流操作系统上(包括 OS X 和 Linux)本地运行同样创新的 shell 和命令行环境。一些人(应该说是大多数人)可能依旧在嘲弄这位诞生于 Windows 的闯入者的大胆和冒失:为那些远古以来(从千禧年开始算不算?)便存在着强大的 shell 环境的平台引荐自己。在本帖中,我希望可以将 PowerShell 的优势介绍给大家,甚至是那些经验老道的用户。 + +### 跨平台一致性 + +如果你计划将脚本从一个执行环境迁移到另一个平台时,你需要确保只使用了那些在两个平台下都起作用的命令和语法。比如在 GNU 系统中,你可以通过以下方式获取昨天的日期: + +``` +date --date="1 day ago" +``` + +在 BSD 系统中(比如 OS X),上述语法将没办法工作,因为 BSD 的 date 工具需要以下语法: + +``` +date -v -1d +``` + +因为 PowerShell 具有宽松的许可证,并且在所有的平台都有构建,所以你可以把 PowerShell 和你的应用一起打包。因此,当你的脚本运行在目标系统中时,它们会运行在一样的 shell 环境中,使用与你的测试环境中同样的命令实现。 + +### 对象和结构化数据 + +*nix 命令和工具依赖于你使用和操控非结构化数据的能力。对于那些长期活在 `sed`、 `grep` 和 `awk` 环境下的人们来说,这可能是小菜一碟,但现在有更好的选择。 + +让我们使用 PowerShell 重写那个获取昨天日期的实例。为了获取当前日期,使用 `Get-Date` cmdlet(读作 “commandlet”): + +``` +> Get-Date                         + +Sunday, January 21, 2018 8:12:41 PM +``` + +你所看到的输出实际上并不是一个文本字符串。不如说,这是 .Net Core 对象的一个字符串表现形式。就像任何 OOP 环境中的对象一样,它具有类型以及你可以调用的方法。 + +让我们来证明这一点: + +``` +> $(Get-Date).GetType().FullName +System.DateTime +``` + +`$(...)` 语法就像你所期望的 POSIX shell 中那样,计算括弧中的命令然后替换整个表达式。但是在 PowerShell 中,这种表达式中的 `$` 是可选的。并且,最重要的是,结果是一个 .Net 对象,而不是文本。因此我们可以调用该对象中的 `GetType()` 方法来获取该对象类型(类似于 Java 中的 `Class` 对象),`FullName` [属性][5] 则用来获取该类型的全称。 + +那么,这种对象导向的 shell 是如何让你的工作变得更加简单呢? + +首先,你可将任何对象排进 `Get-Member` cmdlet 来查看它提供的所有方法和属性。 + +``` +> (Get-Date) | Get-Member +PS /home/yevster/Documents/ArticlesInProgress> $(Get-Date) | Get-Member + + + TypeName: System.DateTime + +Name MemberType Definition +---- ---------- ---------- +Add Method datetime Add(timespan value) +AddDays Method datetime AddDays(double value) +AddHours Method datetime AddHours(double value) +AddMilliseconds Method datetime AddMilliseconds(double value) +AddMinutes Method datetime AddMinutes(double value) +AddMonths Method datetime AddMonths(int months) +AddSeconds Method datetime AddSeconds(double value) +AddTicks Method datetime AddTicks(long value) +AddYears Method datetime AddYears(int value) +CompareTo Method int CompareTo(System.Object value), int ... +``` + +你可以很快的看到 DateTime 对象具有一个 `AddDays` 方法,从而可以使用它来快速的获取昨天的日期: + +``` +> (Get-Date).AddDays(-1) + +Saturday, January 20, 2018 8:24:42 PM +``` + +为了做一些更刺激的事,让我们调用 Yahoo 的天气服务(因为它不需要 API 令牌)然后获取你的本地天气。 + +``` +$city="Boston" +$state="MA" +$url="https://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20weather.forecast%20where%20woeid%20in%20(select%20woeid%20from%20geo.places(1)%20where%20text%3D%22${city}%2C%20${state}%22)&format=json&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys" +``` + +现在,我们可以使用老派的方法然后直接运行 `curl $url` 来获取 JSON 二进制对象,或者…… + +``` +$weather=(Invoke-RestMethod $url) +``` + +如果你查看了 `$weather` 类型(运行 `echo $weather.GetType().FullName`),你将会发现它是一个 `PSCustomObject`。这是一个用来反射 JSON 结构的动态对象。 + +然后 PowerShell 可以通过 tab 补齐来帮助你完成命令输入。只需要输入 `$weather.`(确报包含了 `.`)然后按下 `Tab` 键。你将看到所有根级别的 JSON 键。输入其中的一个,然后跟上 `.` ,再一次按下 `Tab` 键,你将看到它所有的子键(如果有的话)。 + +因此,你可以轻易的导航到你所想要的数据: + +``` +> echo $weather.query.results.channel.atmosphere.pressure                       +1019.0 + +> echo $weather.query.results.channel.wind.chill                                 41 +``` + +并且如果你有非结构化的 JSON 或 CSV 数据(通过外部命令返回的),只需要将它相应的排进 `ConverFrom-Json` 或 `ConvertFrom-CSV` cmdlet,然后你可以得到一个漂亮干净的对象。 + +### 计算 vs. 自动化 + +我们使用 shell 用于两种目的。一个是用于计算,运行独立的命令然后手动响应它们的输出。另一个是自动化,通过写脚本执行多个命令,然后以编程的方式相应它们的输出。 + +我们大多数人都能发现这两种目的在 shell 上的不同且互相冲突的要求。计算任务要求 shell 简洁明了。用户输入的越少越好。但如果用户输入对其他用户来说几乎难以理解,那这一点就不重要了。脚本,从另一个角度来讲是代码。可读性和可维护性是关键。这一方面,POSIX 工具通常是失败的。虽然一些命令通常会为它们的参数提供简洁明了的语法(如:`-f` 和 `--force`),但是命令名字本身就不简洁明了。 + +PowerShell 提供了几个机制来消除这种浮士德式的平衡。 + +首先,tab 补齐可以消除键入参数名的需要。比如:键入 `Get-Random -Mi`,按下 `Tab` 然后 PowerShell 将会为你完成参数:`Get-Random -Minimum`。但是如果你想更简洁一些,你甚至不需要按下 `Tab`。如下所示,PowerShell 可以理解: + +``` +Get-Random -Mi 1 -Ma 10 +``` + +因为 `Mi` 和 `Ma` 每一个都具有独立不同的补齐。 + +你可能已经留意到所有的 PowerShell cmdlet 名称具有动名词结构。这有助于脚本的可读性,但是你可能不想一而再、再而三的键入 `Get-`。所以并不需要!如果你之间键入了一个名词而没有动词的话,PowerShell 将查找带有该名词的 `Get-` 命令。 + +> 小心:尽管 PowerShell 不区分大小写,但在使用 PowerShell 命令是时,名词首字母大写是一个好习惯。比如,键入 `date` 将会调用系统中的 `date` 工具。键入 `Date` 将会调用 PowerShell 的 `Get-Date` cmdlet。 + +如果这还不够,PowerShell 还提供了别名,用来创建简单的名字。比如,如果键入 `alias -name cd`,你将会发现 `cd` 在 PowerShell 实际上时 `Set-Location` 命令的别名。 + +所以回顾以下 —— 你可以使用强大的 tab 补全、别名,和名词补全来保持命令名词简洁、自动化和一致性参数名截断,与此同时还可以享受丰富、可读的语法格式。 + +### 那么……你看呢? + +这些只是 PowerShell 的一部分优势。还有更多特性和 cmdlet,我还没讨论(如果你想弄哭 `grep` 的话,可以查看 [Where-Object][6] 或其别称 `?`)。如果你有点怀旧的话,PowerShell 可以为你加载原来的本地工具。但是给自己足够的时间来适应 PowerShell 面向对象 cmdlet 的世界,然后你将发现自己会选择忘记回去的路。 + + +-------------------------------------------------------------------------------- + +via: https://opensource.com/article/18/2/powershell-people + +作者:[Yev Bronshteyn][a] +译者:[sanfusu](https://github.com/sanfusu) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://opensource.com/users/yevster +[1]:https://github.com/PowerShell/PowerShell/blob/master/README.md +[2]:https://blogs.msdn.microsoft.com/powershell/2018/01/10/powershell-core-6-0-generally-available-ga-and-supported/ +[3]:https://spdx.org/licenses/MIT +[4]:http://www.jsnover.com/Docs/MonadManifesto.pdf +[5]:https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/properties +[6]:https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/where-object?view=powershell-6 diff --git a/published/20180307 3 open source tools for scientific publishing.md b/published/20180307 3 open source tools for scientific publishing.md new file mode 100644 index 0000000000..40deb0ee6c --- /dev/null +++ b/published/20180307 3 open source tools for scientific publishing.md @@ -0,0 +1,80 @@ +3 款用于学术出版的开源工具 +====== +> 学术出版业每年的价值超过 260 亿美元。 + +![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/LIFE_science.png?itok=WDKARWGV) + +有一个行业在采用数字化或开源工具方面已落后其它行业,那就是竞争与利润并存的学术出版业。根据 Stephen Buranyi 去年在 [卫报][1] 上发表的一份图表,这个估值超过 190 亿英镑(260 亿美元)的行业,即使是最重要的科学研究方面,至今其系统在选题、出版甚至分享方面仍受限于印刷媒介的诸多限制。全新的数字时代科技展现了一个巨大机遇,可以加速探索、推动科学协作而非竞争,以及将投入从基础建设导向有益于社会的研究。 + +非盈利性的 [eLife 倡议][2] 是由研究资金赞助方建立,旨在通过使用数字或者开源技术来走出上述僵局。除了为生命科学和生物医疗方面的重大成就出版开放式获取的期刊,eLife 已将自己变成了一个在研究交流方面的实验和展示创新的平台 —— 而大部分的实验都是基于开源精神的。 + +致力于开放出版基础设施项目给予我们加速接触、采用科学技术、提升用户体验的机会。我们认为这种机会对于推动学术出版行业是重要的。大而化之地说,开源产品的用户体验经常是有待开发的,而有时候这种情况会阻止其他人去使用它。作为我们在 OSS(开源软件)开发中投入的一部分,为了鼓励更多用户使用这些产品,我们十分注重用户体验。 + +我们所有的代码都是开源的,并且我们也积极鼓励社区参与进我们的项目中。这对我们来说意味着更快的迭代、更多的实验、更大的透明度,同时也拓宽了我们工作的外延。 + +我们现在参与的项目,例如 Libero (之前称作 [eLife Continuum][3])和 [可重现文档栈][4]Reproducible Document Stack 的开发,以及我们最近和 [Hypothesis][5] 的合作,展示了 OSS 是如何在评估、出版以及新发现的沟通方面带来正面影响的。 + +### Libero + +Libero 是面向出版商的服务及应用套餐,它包括一个后期制作出版系统、整套前端用户界面样式套件、Libero 的镜头阅读器、一个 Open API 以及一个搜索及推荐引擎。 + +去年我们采取了用户驱动的方式重新设计了 Libero 的前端,可以使用户较少地分心于网站的“陈设”,而是更多地集中关注于研究文章上。我们和 eLife 社区成员测试并迭代了该站点所有的核心功能,以确保给所有人最好的阅读体验。该网站的新 API 也为机器阅读能力提供了更简单的访问途径,其中包括文本挖掘、机器学习以及在线应用开发。 + +我们网站上的内容以及引领新设计的样式都是开源的,以鼓励 eLife 和其它想要使用它的出版商后续的产品开发。 + +### 可重现文档栈 + +在与 [Substance][6] 和 [Stencila][7] 的合作下,eLife 也参与了一个项目来创建可重现文档栈(RDS)—— 一个开放式的创作、编纂以及在线出版可重现的计算型手稿的工具栈。 + +今天越来越多的研究人员能够通过 [R Markdown][8] 和 [Python][9] 等语言记录他们的计算实验。这些可以作为实验记录的重要部分,但是尽管它们可以独立于最终的研究文章或与之一同分享,但传统出版流程经常将它们视为次级内容。为了发表论文,使用这些语言的研究人员除了将他们的计算结果用图片的形式“扁平化”提交外别无他法。但是这导致了许多实验价值和代码和计算数据可重复利用性的流失。诸如 [Jupyter][10] 这样的电子笔记本解决方案确实可以使研究员以一种可重复利用、可执行的简单形式发布,但是这种方案仍然是出版的手稿的补充,而不是不可或缺的一部分。 + +[可重现文档栈][11] 项目旨在通过开发、发布一个可重现原稿的产品原型来解决这些挑战,该原型将代码和数据视为文档的组成部分,并展示了从创作到出版的完整端对端技术栈。它将最终允许用户以一种包含嵌入代码块和计算结果(统计结果、图表或图形)的形式提交他们的手稿,并在出版过程中保留这些可视、可执行的部分。那时出版商就可以将这些做为出版的在线文章的组成部分而保存。 + +### 用 Hypothesis 进行开放式注解 + +最近,我们与 [Hypothesis][12] 合作引进了开放式注解,使得我们网站的用户们可以写评语、高亮文章重要部分以及与在线阅读的群体互动。 + +通过这样的合作,开源的 Hypothesis 软件被定制得更具有现代化的特性,如单次登录验证、用户界面定制,给予了出版商在他们自己网站上实现更多的控制。这些提升正引导着关于出版学术内容的高质量讨论。 + +这个工具可以无缝集成到出版商的网站,学术出版平台 [PubFactory][13] 和内容解决方案供应商 [Ingenta][14] 已经利用了它优化后的特性集。[HighWire][15] 和 [Silverchair][16] 也为他们的出版商提供了实施这套方案的机会。 + +### 其它产业和开源软件 + +随着时间的推移,我们希望看到更多的出版商采用 Hypothesis、Libero 以及其它开源项目去帮助他们促进重要科学研究的发现以及循环利用。但是 eLife 的创新机遇也能被其它行业所利用,因为这些软件和其它 OSS 技术在其他行业也很普遍。 + +数据科学的世界离不开高质量、良好支持的开源软件和围绕它们形成的社区;[TensorFlow][17] 就是这样一个好例子。感谢 OSS 以及其社区,AI 和机器学习的所有领域相比于计算机的其它领域的提升和发展更加迅猛。与之类似的是以 Linux 作为云端 Web 主机的爆炸性增长、接着是 Docker 容器、以及现在 GitHub 上最流行的开源项目之一的 Kubernetes 的增长。 + +所有的这些技术使得机构们能够用更少的资源做更多的事情,并专注于创新而不是重新发明轮子上。最后,这就是 OSS 真正的好处:它使得我们从互相的失败中学习,在互相的成功中成长。 + +我们总是在寻找与研究和科技界面方面最好的人才和想法交流的机会。你可以在 [eLife Labs][18] 上或者联系 [innovation@elifesciences.org][19] 找到更多这种交流的信息。 + +-------------------------------------------------------------------------------- + +via: https://opensource.com/article/18/3/scientific-publishing-software + +作者:[Paul Shanno][a] +译者:[tomjlw](https://github.com/tomjlw) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://opensource.com/users/pshannon +[1]:https://www.theguardian.com/science/2017/jun/27/profitable-business-scientific-publishing-bad-for-science +[2]:https://elifesciences.org/about +[3]:https://elifesciences.org/inside-elife/33e4127f/elife-introduces-continuum-a-new-open-source-tool-for-publishing +[4]:https://elifesciences.org/for-the-press/e6038800/elife-supports-development-of-open-technology-stack-for-publishing-reproducible-manuscripts-online +[5]:https://elifesciences.org/for-the-press/81d42f7d/elife-enhances-open-annotation-with-hypothesis-to-promote-scientific-discussion-online +[6]:https://github.com/substance +[7]:https://github.com/stencila/stencila +[8]:https://rmarkdown.rstudio.com/ +[9]:https://www.python.org/ +[10]:http://jupyter.org/ +[11]:https://elifesciences.org/labs/7dbeb390/reproducible-document-stack-supporting-the-next-generation-research-article +[12]:https://github.com/hypothesis +[13]:http://www.pubfactory.com/ +[14]:http://www.ingenta.com/ +[15]:https://github.com/highwire +[16]:https://www.silverchair.com/community/silverchair-universe/hypothesis/ +[17]:https://www.tensorflow.org/ +[18]:https://elifesciences.org/labs +[19]:mailto:innovation@elifesciences.org diff --git a/published/20180314 Pi Day- 12 fun facts and ways to celebrate.md b/published/20180314 Pi Day- 12 fun facts and ways to celebrate.md new file mode 100644 index 0000000000..4c03a28074 --- /dev/null +++ b/published/20180314 Pi Day- 12 fun facts and ways to celebrate.md @@ -0,0 +1,59 @@ +关于圆周率日的趣事与庆祝方式 +====== + +> 技术团队喜欢 3 月 14 日的圆周率日:你是否知道这也是阿尔伯特·爱因斯坦的生日和 Linux 内核1.0.0 发布周年纪念日?来看一些树莓派的趣事和 DIY 项目。 + +![](https://enterprisersproject.com/sites/default/files/styles/620x350/public/images/cio_piday.png?itok=kTht0qV9) + +今天,全世界的技术团队都会为一个数字庆祝。3 月 14 日是圆周率日Pi Day,人们会在这一天举行吃派比赛、披萨舞会,玩数学梗math puns。如果这个数学领域中的重要常数不足以让 3 月 14 日成为一个节日的话,再加上爱因斯坦的生日、Linux 内核 1.0.0 发布的周年纪念日,莱伊·惠特尼在这一天申请了轧花机的专利这些原因,应该足够了吧。(LCTT译注:[轧花机](https://zh.wikipedia.org/wiki/%E8%BB%8B%E6%A3%89%E6%A9%9F)是一种快速而且简单地分开棉花纤维和种子的机器,生产力比人手分离高得多。) + +很荣幸,我们能在这一个特殊的日子里一起了解有关它的趣事和与 π 相关的好玩的活动。来吧,和你的团队一起庆祝圆周率日:找一两个点子来进行团队建设,或用新兴技术做一个项目。如果你有为这个大家所喜爱的无限小数庆祝的独特方式,请在评论区与大家分享。 + +### 圆周率日的庆祝方法: + + * 今天是圆周率日的第 31 次周年纪念(LCTT 译注:本文写于 2018 年的圆周率日,故在细节上存在出入。例如今天(2019 年 3 月 14 日)是圆周率日的第 31 次周年纪念)。第一次为它庆祝是在旧金山的探索博物馆Exploratorium由物理学家 Larry Shaw 举行。“在[第 1 次周年纪念日][1]当天,工作人员带来了水果派和茶壶来庆祝它。在 1 点 59 分(圆周率中紧接着 3.14 的数字),Shaw 在博物馆外领着队伍环馆一周。队伍中用扩音器播放着‘Pomp and Circumstance’。” 直到 21 年后,在 2009 年 3 月,圆周率正式成为了美国的法定假日。 + * 虽然该纪念日起源于旧金山,可规模最大的庆祝活动却是在普林斯顿举行的,这个小镇举办了为期五天的[许多活动][2],包括爱因斯坦模仿比赛、掷派比赛,圆周率背诵比赛等等。其中的某些活动甚至会给获胜者提供价值 314.5 美元的奖金。 + * 麻省理工的斯隆管理学院MIT Sloan School of Management正在庆祝圆周率日。他们在 Twitter 上分享着关于 π 和派的圆周率日趣事,详情请关注推特话题Twitter hashtag #PiVersusPie 。 + +### 与圆周率有关的项目与活动: + + * 如果你想锻炼你的数学技能,美国国家航空航天局National Aeronautics and Space Administration(NASA)的喷气推进实验室Jet Propulsion Lab(JPL)发布了[一系列新的数学问题][4],希望通过这些问题展现如何把圆周率用于空间探索。这也是美国国家航天局面向学生举办的第五届圆周率日挑战。 + * 想要领略圆周率日的精神,最好的方法也许就是开展一个[树莓派][5]项目了,无论是和你的孩子还是和你的团队一起完成,都是不错的。树莓派作为一项从 2012 年开启的项目,现在已经售出了数百万块的基本型的电脑主板。事实上,它已经在[通用计算机畅销榜上排名第三][6]了。这里列举一些可能会吸引你的树莓派项目或活动: + * 来自谷歌的自己做 AIAI-Yourself(AIY)项目让你自己创造一个[语音控制的数字助手][7]或者[一个图像识别设备][8]。 + * 在树莓派上[使用 Kubernets][9]。 + * 组装一台[怀旧游戏系统][10],目标:拯救桃子公主! + * 和你的团队举办一场[树莓派 Jam][11]。树莓派基金会发布了一个帮助大家顺利举办活动的[指导手册][12]。据该网站说明,树莓派 Jam 旨在“给数字创作中所有年龄段的人提供支持,让世界各地志同道合的人们汇聚起来讨论和分享他们的最新项目,举办讲习班,讨论和派相关的一切。” + +### 其他有关圆周率的事情: + + * 当前背诵圆周率的[世界纪录保持者][13]是 Suresh Kumar Sharma,他在 2015 年 10 月花了 17 小时零 14 分钟背出了 70,030 位数字。然而,[非官方记录][14]的保持者 Akira Haraguchi 声称他可以背出 111,700 位数字。 + * 现在,已知的圆周率数字的长度比以往都要多。在 2016 年 11 月,R&D 科学家 Peter Trueb 计算出了 22,459,157,718,361 位圆周率数字,比 2013 年的世界记录多了 [9 万亿数字][15]。据新科学家New Scientist所述,“最终文件包含了圆周率的 22 万亿位数字,大小接近 9 TB。如果将其打印出来,能用数百万本 1000 页的书装满一整个图书馆。” + +祝你圆周率日快乐! + +-------------------------------------------------------------------------------- + +via: https://enterprisersproject.com/article/2018/3/pi-day-12-fun-facts-and-ways-celebrate + +作者:[Carla Rudder][a] +译者:[wwhio](https://github.com/wwhio) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://enterprisersproject.com/user/crudder +[1]:https://www.exploratorium.edu/pi/pi-day-history +[2]:https://princetontourcompany.com/activities/pi-day/ +[3]:https://twitter.com/MITSloan +[4]:https://www.jpl.nasa.gov/news/news.php?feature=7074 +[5]:https://opensource.com/resources/raspberry-pi +[6]:https://www.theverge.com/circuitbreaker/2017/3/17/14962170/raspberry-pi-sales-12-5-million-five-years-beats-commodore-64 +[7]:http://www.zdnet.com/article/raspberry-pi-this-google-kit-will-turn-your-pi-into-a-voice-controlled-digital-assistant/ +[8]:http://www.zdnet.com/article/google-offers-raspberry-pi-owners-this-new-ai-vision-kit-to-spot-cats-people-emotions/ +[9]:https://opensource.com/article/17/3/kubernetes-raspberry-pi +[10]:https://opensource.com/article/18/1/retro-gaming +[11]:https://opensource.com/article/17/5/how-run-raspberry-pi-meetup +[12]:https://www.raspberrypi.org/blog/support-raspberry-jam-community/ +[13]:http://www.pi-world-ranking-list.com/index.php?page=lists&category=pi +[14]:https://www.theguardian.com/science/alexs-adventures-in-numberland/2015/mar/13/pi-day-2015-memory-memorisation-world-record-japanese-akira-haraguchi +[15]:https://www.newscientist.com/article/2124418-celebrate-pi-day-with-9-trillion-more-digits-than-ever-before/?utm_medium=Social&utm_campaign=Echobox&utm_source=Facebook&utm_term=Autofeed&cmpid=SOC%7CNSNS%7C2017-Echobox#link_time=1489480071 diff --git a/published/20180329 Python ChatOps libraries- Opsdroid and Errbot.md b/published/20180329 Python ChatOps libraries- Opsdroid and Errbot.md new file mode 100644 index 0000000000..556eb95276 --- /dev/null +++ b/published/20180329 Python ChatOps libraries- Opsdroid and Errbot.md @@ -0,0 +1,204 @@ +Python 的 ChatOps 库:Opsdroid 和 Errbot +====== + +> 学习一下 Python 世界里最广泛使用的 ChatOps 库:每个都能做什么,如何使用。 + +![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/idea_innovation_mobile_phone.png?itok=RqVtvxkd) + +ChatOps 是基于会话导向而进行的开发。其思路是你可以编写能够对聊天窗口中的某些输入进行回复的可执行代码。作为一个开发者,你能够用 ChatOps 从 Slack 合并拉取请求,自动从收到的 Facebook 消息中给某人分配支持工单,或者通过 IRC 检查开发状态。 + +在 Python 世界,最为广泛使用的 ChatOps 库是 Opsdroid 和 Errbot。在这个月的 Python 专栏,让我们一起聊聊使用它们是怎样的体验,它们各自适用于什么方面以及如何着手使用它们。 + +### Opsdroid + +[Opsdroid][2] 是一个相对年轻的(始于 2016)Python 开源聊天机器人库。它有着良好的开发文档,不错的教程,并且包含能够帮助你对接流行的聊天服务的插件。 + +#### 它内置了什么 + +库本身并没有自带所有你需要上手的东西,但这是故意的。轻量级的框架鼓励你去运用它现有的连接器(Opsdroid 所谓的帮你接入聊天服务的插件)或者去编写你自己的,但是它并不会因自带你所不需要的连接器而自贬身价。你可以轻松使用现有的 Opsdroid 连接器来接入: + ++ 命令行 ++ Cisco Spark ++ Facebook ++ GitHub ++ Matrix ++ Slack ++ Telegram ++ Twitter ++ Websocket + +Opsdroid 会调用使聊天机器人能够展现它们的“技能”的函数。这些技能其实是异步 Python 函数,并使用 Opsdroid 叫做“匹配器”的匹配装饰器。你可以设置你的 Opsdroid 项目,来使用同样从你设置文件所在的代码中的“技能”。你也可以从外面的公共或私人仓库调用这些“技能”。 + +你同样可以启用一些现存的 Opsdroid “技能”,包括 [seen][3] —— 它会告诉你聊天机器人上次是什么时候看到某个用户的,以及 [weather][4] —— 会将天气报告给用户。 + +最后,Opdroid 允许你使用现存的数据库模块设置数据库。现在 Opdroid 支持的数据库包括: + ++ Mongo ++ Redis ++ SQLite + +你可以在你的 Opdroid 项目中的 `configuration.yaml` 文件设置数据库、技能和连接器。 + +#### Opsdroid 的优势 + +**Docker 支持:**从一开始 Opsdroid 就打算在 Docker 中良好运行。在 Docker 中的指导是它 [安装文档][5] 中的一部分。使用 Opsdroid 和 Docker Compose 也很简单:将 Opsdroid 设置成一种服务,当你运行 `docker-compose up` 时,你的 Opsdroid 服务将会开启你的聊天机器人也将就绪。 + +``` +version: "3" + +services: + opsdroid: + container_name: opsdroid + build: + context: . + dockerfile: Dockerfile +``` + +**丰富的连接器:** Opsdroid 支持九种像 Slack 和 Github 等从外部接入的服务连接器。你所要做的一切就是在你的设置文件中启用那些连接器,然后把必须的口令或者 API 密匙传过去。比如为了启用 Opsdroid 以在一个叫做 `#updates` 的 Slack 频道发帖,你需要将以下代码加入你设置文件的 `connectors` 部分: + +``` + - name: slack +    api-token: "this-is-my-token" +    default-room: "#updates" +``` + +在设置 Opsdroid 以接入 Slack 之前你需要[添加一个机器人用户][6]。 + +如果你需要接入一个 Opsdroid 不支持的服务,在[文档][7]里有有添加你自己的连接器的教程。 + +**相当不错的文档:** 特别是对于一个在积极开发中的新兴库来说,Opsdroid 的文档十分有帮助。这些文档包括一篇带你创建几个不同的基本技能的[教程][8]。Opsdroid 在[技能][9]、[连接器][7]、[数据库][10],以及[匹配器][11]方面的文档也十分清晰。 + +它所支持的技能和连接器的仓库为它的技能提供了富有帮助的示范代码。 + +**自然语言处理:** Opsdroid 的技能里面能使用正则表达式,但也同样提供了几个包括 [Dialogflow][12],[luis.ai][13],[Recast.AI][14] 以及 [wit.ai][15] 的 NLP API。 + +#### Opsdroid 可能的不足 + +Opsdroid 对它的一部分连接器还没有启用全部的特性。比如说,Slack API 允许你向你的消息添加颜色柱、图片以及其他的“附件”。Opsdroid Slack 连接器并没有启用“附件”特性,所以如果那些特性对你来说很重要的话,你需要编写一个自定义的 Slack 连接器。如果连接器缺少一个你需要的特性,Opsdroid 将欢迎你的[贡献][16]。文档中可以使用更多的例子,特别是对于预料到的使用场景。 + +#### 示例用法 + +``` +from opsdroid.matchers import match_regex +import random + + +@match_regex(r'hi|hello|hey|hallo') +async def hello(opsdroid, config, message): + text = random.choice(["Hi {}", "Hello {}", "Hey {}"]).format(message.user) + await message.respond(text) +``` + +*hello/\_\_init\_\_.py* + + +``` +connectors: + - name: websocket + +skills: + - name: hello + repo: "https://github.com//hello-skill" + +``` + +*configuration.yaml* + + +### Errbot + +[Errbot][17] 是一个功能齐全的开源聊天机器人。Errbot 发行于 2012 年,并且拥有人们从一个成熟的项目能期待的一切,包括良好的文档、优秀的教程以及许多帮你连入现有的流行聊天服务的插件。 + +#### 它内置了什么 + +不像采用了较轻量级方式的 Opsdroid,Errbot 自带了你需要可靠地创建一个自定义机器人的一切东西。 + +Errbot 包括了对于本地 XMPP、IRC、Slack、Hipchat 以及 Telegram 服务的支持。它通过社区支持的后端列出了另外十种服务。 + +#### Errbot 的优势 + +**良好的文档:** Errbot 的文档成熟易读。 + +**动态插件架构:** Errbot 允许你通过和聊天机器人交谈安全地安装、卸载、更新、启用以及禁用插件。这使得开发和添加特性十分简便。感谢 Errbot 的颗粒性授权系统,出于安全意识这所有的一切都可以被锁闭。 + +当某个人输入 `!help`,Errbot 使用你的插件的文档字符串来为可获取的命令生成文档,这使得了解每行命令的作用更加简便。 + +**内置的管理和安全特性:** Errbot 允许你限制拥有管理员权限的用户列表,甚至细粒度访问控制。比如说你可以限制特定用户或聊天房间访问特定命令。 + +**额外的插件框架:** Errbot 支持钩子、回调、子命令、webhook、轮询以及其它[更多特性][18]。如果那些还不够,你甚至可以编写[动态插件][19]。当你需要基于在远程服务器上的可用命令来启用对应的聊天命令时,这个特性十分有用。 + +**自带测试框架:** Errbot 支持 [pytest][20],同时也自带一些能使你简便测试插件的有用功能。它的“[测试你的插件][21]”的文档出于深思熟虑,并提供了足够的资料让你上手。 + +#### Errbot 可能的不足 + +**以 “!” 开头:** 默认情况下,Errbot 命令发出时以一个惊叹号打头(`!help` 以及 `!hello`)。一些人可能会喜欢这样,但是另一些人可能认为这让人烦恼。谢天谢地,这很容易关掉。 + +**插件元数据** 首先,Errbot 的 [Hello World][22] 插件示例看上去易于使用。然而我无法加载我的插件,直到我进一步阅读了教程并发现我还需要一个 `.plug` 文档,这是一个 Errbot 用来加载插件的文档。这可能比较吹毛求疵了,但是在我深挖文档之前,这对我来说都不是显而易见的。 + +### 示例用法 + + +``` +import random +from errbot import BotPlugin, botcmd + +class Hello(BotPlugin): + + @botcmd + def hello(self, msg, args): + text = random.choice(["Hi {}", "Hello {}", "Hey {}"]).format(message.user) + return text +``` + +*hello.py* + +``` +[Core] +Name = Hello +Module = hello + +[Python] +Version = 2+ + +[Documentation] +Description = Example "Hello" plugin +``` + +*hello.plug* + + +你用过 Errbot 或 Opsdroid 吗?如果用过请留下关于你对于这些工具印象的留言。 + +-------------------------------------------------------------------------------- + +via: https://opensource.com/article/18/3/python-chatops-libraries-opsdroid-and-errbot + +作者:[Jeff Triplett][a], [Lacey Williams Henschel][1] +译者:[tomjlw](https://github.com/tomjlw) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://opensource.com/users/laceynwilliams +[1]:https://opensource.com/users/laceynwilliams +[2]:https://opsdroid.github.io/ +[3]:https://github.com/opsdroid/skill-seen +[4]:https://github.com/opsdroid/skill-weather +[5]:https://opsdroid.readthedocs.io/en/stable/#docker +[6]:https://api.slack.com/bot-users +[7]:https://opsdroid.readthedocs.io/en/stable/extending/connectors/ +[8]:https://opsdroid.readthedocs.io/en/stable/tutorials/introduction/ +[9]:https://opsdroid.readthedocs.io/en/stable/extending/skills/ +[10]:https://opsdroid.readthedocs.io/en/stable/extending/databases/ +[11]:https://opsdroid.readthedocs.io/en/stable/matchers/overview/ +[12]:https://opsdroid.readthedocs.io/en/stable/matchers/dialogflow/ +[13]:https://opsdroid.readthedocs.io/en/stable/matchers/luis.ai/ +[14]:https://opsdroid.readthedocs.io/en/stable/matchers/recast.ai/ +[15]:https://opsdroid.readthedocs.io/en/stable/matchers/wit.ai/ +[16]:https://opsdroid.readthedocs.io/en/stable/contributing/ +[17]:http://errbot.io/en/latest/ +[18]:http://errbot.io/en/latest/features.html#extensive-plugin-framework +[19]:http://errbot.io/en/latest/user_guide/plugin_development/dynaplugs.html +[20]:http://pytest.org/ +[21]:http://errbot.io/en/latest/user_guide/plugin_development/testing.html +[22]:http://errbot.io/en/latest/index.html#simple-to-build-upon diff --git a/published/20180330 Asynchronous rsync with Emacs, dired and tramp..md b/published/20180330 Asynchronous rsync with Emacs, dired and tramp..md new file mode 100644 index 0000000000..5091e14afb --- /dev/null +++ b/published/20180330 Asynchronous rsync with Emacs, dired and tramp..md @@ -0,0 +1,77 @@ +[#]: collector: (lujun9972) +[#]: translator: (lujun9972) +[#]: reviewer: (wxy) +[#]: publisher: (wxy) +[#]: url: (https://linux.cn/article-10639-1.html) +[#]: subject: (Asynchronous rsync with Emacs,dired and tramp。) +[#]: via: (https://vxlabs.com/2018/03/30/asynchronous-rsync-with-emacs-dired-and-tramp/) +[#]: author: (cpbotha https://vxlabs.com/author/cpbotha/) + +在 Emacs 的 dired 和 tramp 中异步运行 rsync +====== + +[Trần Xuân Trường][2] 写的 [tmtxt-dired-async][1] 是一个不为人知的 Emacs 包,它可以扩展 dired(Emacs 内置的文件管理器),使之可以异步地运行 `rsync` 和其他命令 (例如压缩、解压缩和下载)。 + +这意味着你可以拷贝上 GB 的目录而不影响 Emacs 的其他任务。 + +它的一个功能时让你可以通过 `C-c C-a` 从不同位置添加任意多的文件到一个等待列表中,然后按下 `C-c C-v` 异步地使用 `rsync` 将整个等待列表中的文件同步到目标目录中。光这个功能就值得一试了。 + +例如这里将 arduino 1.9 的 beta 存档同步到另一个目录中: + +![][4] + +整个进度完成后,底部的窗口会在 5 秒后自动退出。下面是异步解压上面的 arduino 存档后出现的另一个会话: + +![][6] + +这个包进一步增加了我 dired 配置的实用性。 + +我刚刚贡献了 [一个拉取请求来允许 tmtxt-dired-async 同步到远程 tramp 目录中][7],而且我立即使用该功能来将上 GB 的新照片传输到 Linux 服务器上。 + +若你想配置 tmtxt-dired-async,下载 [tmtxt-async-tasks.el][8](被依赖的库)以及 [tmtxt-dired-async.el][9](若你想让它支持 tramp,请确保合并使用了我的拉取请求)到 `~/.emacs.d/` 目录中,然后添加下面配置: + +``` +;; no MELPA packages of this, so we have to do a simple check here +(setq dired-async-el (expand-file-name "~/.emacs.d/tmtxt-dired-async.el")) +(when (file-exists-p dired-async-el) + (load (expand-file-name "~/.emacs.d/tmtxt-async-tasks.el")) + (load dired-async-el) + (define-key dired-mode-map (kbd "C-c C-r") 'tda/rsync) + (define-key dired-mode-map (kbd "C-c C-z") 'tda/zip) + (define-key dired-mode-map (kbd "C-c C-u") 'tda/unzip) + + (define-key dired-mode-map (kbd "C-c C-a") 'tda/rsync-multiple-mark-file) + (define-key dired-mode-map (kbd "C-c C-e") 'tda/rsync-multiple-empty-list) + (define-key dired-mode-map (kbd "C-c C-d") 'tda/rsync-multiple-remove-item) + (define-key dired-mode-map (kbd "C-c C-v") 'tda/rsync-multiple) + + (define-key dired-mode-map (kbd "C-c C-s") 'tda/get-files-size) + + (define-key dired-mode-map (kbd "C-c C-q") 'tda/download-to-current-dir)) +``` + +祝你开心! + + +-------------------------------------------------------------------------------- + +via: https://vxlabs.com/2018/03/30/asynchronous-rsync-with-emacs-dired-and-tramp/ + +作者:[cpbotha][a] +选题:[lujun9972][b] +译者:[lujun9972](https://github.com/lujun9972) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]: https://vxlabs.com/author/cpbotha/ +[b]: https://github.com/lujun9972 +[1]: https://truongtx.me/tmtxt-dired-async.html +[2]: https://truongtx.me/about.html +[3]: https://i0.wp.com/vxlabs.com/wp-content/uploads/2018/03/rsync-arduino-zip.png?resize=660%2C340&ssl=1 +[4]: https://i0.wp.com/vxlabs.com/wp-content/uploads/2018/03/rsync-arduino-zip.png?ssl=1 +[5]: https://i1.wp.com/vxlabs.com/wp-content/uploads/2018/03/progress-window-5s.png?resize=660%2C310&ssl=1 +[6]: https://i1.wp.com/vxlabs.com/wp-content/uploads/2018/03/progress-window-5s.png?ssl=1 +[7]: https://github.com/tmtxt/tmtxt-dired-async/pull/6 +[8]: https://github.com/tmtxt/tmtxt-async-tasks +[9]: https://github.com/tmtxt/tmtxt-dired-async diff --git a/published/20180629 How To Get Flatpak Apps And Games Built With OpenGL To Work With Proprietary Nvidia Graphics Drivers.md b/published/20180629 How To Get Flatpak Apps And Games Built With OpenGL To Work With Proprietary Nvidia Graphics Drivers.md new file mode 100644 index 0000000000..9c95bb2b81 --- /dev/null +++ b/published/20180629 How To Get Flatpak Apps And Games Built With OpenGL To Work With Proprietary Nvidia Graphics Drivers.md @@ -0,0 +1,120 @@ +[#]: collector: (lujun9972) +[#]: translator: (geekpi) +[#]: reviewer: (wxy) +[#]: publisher: ( ) +[#]: url: ( ) +[#]: subject: (How To Get Flatpak Apps And Games Built With OpenGL To Work With Proprietary Nvidia Graphics Drivers) +[#]: via: (https://www.linuxuprising.com/2018/06/how-to-get-flatpak-apps-and-games-built.html) +[#]: author: (Logix https://plus.google.com/118280394805678839070) + +如何使得支持 OpenGL 的 Flatpak 应用和游戏在专有 Nvidia 图形驱动下工作 +====== +> 一些支持 OpenGL 并打包为 Flatpak 的应用和游戏无法使用专有 Nvidia 驱动启动。本文将介绍如何在不安装开源驱动(Nouveau)的情况下启动这些 Flatpak 应用或游戏。 + +![](https://2.bp.blogspot.com/-A6PQn0xS7t8/WzYZDH6L_cI/AAAAAAAAAyE/ZBHroHnrY1scqo-dhSRV3YapO4OeBJlOQCLcBGAs/s1600/flatpak.png) + +这有个例子。我在我的 Ubuntu 18.04 桌面上使用专有的 Nvidia 驱动程序 (`nvidia-driver-390`),当我尝试启动以 Flatpak 形式安装的最新版本 [Krita 4.1][2] (构建了 OpenGL 支持)时,显示了如下错误: + +``` +$ /usr/bin/flatpak run --branch=stable --arch=x86_64 --command=krita --file-forwarding org.kde.krita +Gtk-Message: Failed to load module "canberra-gtk-module" +Gtk-Message: Failed to load module "canberra-gtk-module" +libGL error: No matching fbConfigs or visuals found +libGL error: failed to load driver: swrast +Could not initialize GLX +``` + +[Winepak][3] 游戏(以 Flatpak 方式打包的绑定了 Wine 的 Windows 游戏)似乎也受到了这个问题的影响,这个问题从 2016 年出现至今。 + +要修复使用 OpenGL 和专有 Nvidia 图形驱动时无法启动的 Flatpak 游戏和应用的问题,你需要为已安装的专有驱动安装一个运行时环境。以下是步骤。 + +1、如果尚未添加 FlatHub 仓库,请添加它。你可以在[此处][1]找到针对 Linux 发行版的说明。 + +2、现在,你需要确定系统上安装的专有 Nvidia 驱动的确切版本。 + +_这一步取决于你使用的 Linux 发行版,我无法涵盖所有​​情况。下面的说明是面向 Ubuntu(以及 Ubuntu 风格的版本),但希望你可以自己弄清楚系统上安装的 Nvidia 驱动版本。_ + +要在 Ubuntu 中执行此操作,请打开 “软件与更新”,切换到 “附加驱动” 选项卡并记下 Nvidia 驱动包的名称。 + +比如,你可以看到我的是 “nvidia-driver-390”: + +![](https://1.bp.blogspot.com/-FAfjtGNeUJc/WzYXMYTFBcI/AAAAAAAAAx0/xUhIO83IAjMuK4Hn0jFUYKJhSKw8y559QCLcBGAs/s1600/additional-drivers-nvidia-ubuntu.png) + +这里还没完成。我们只是找到了 Nvidia 驱动的主要版本,但我们还需要知道次要版本。要获得我们下一步所需的确切 Nvidia 驱动版本,请运行此命令(应该适用于任何基于 Debian 的 Linux 发行版,如 Ubuntu、Linux Mint 等): + +``` +apt-cache policy NVIDIA-PACKAGE-NAME +``` + +这里的 “NVIDIA-PACKAGE-NAME” 是 “软件与更新” 中列出的 Nvidia 驱动包名称。例如,要查看 “nvidia-driver-390” 包的确切安装版本,请运行以下命令: + +``` +$ apt-cache policy nvidia-driver-390 +nvidia-driver-390: + Installed: 390.48-0ubuntu3 + Candidate: 390.48-0ubuntu3 + Version table: + *** 390.48-0ubuntu3 500 + 500 http://ro.archive.ubuntu.com/ubuntu bionic/restricted amd64 Packages + 100 /var/lib/dpkg/status +``` + +在这个命令的输出中,查找 “Installed” 部分并记下版本号(不包括 “-0ubuntu3” 之类)。现在我们知道了已安装的 Nvidia 驱动的确切版本(我例子中的是 “390.48”)。记住它,因为下一步我们需要。 + +3、最后,你可以从 FlatHub 为你已安装的专有 Nvidia 图形驱动安装运行时环境。 + +要列出 FlatHub 上所有可用的 Nvidia 运行时包,你可以使用以下命令: + +``` +flatpak remote-ls flathub | grep nvidia +``` + +幸运地是 FlatHub 上提供这个 Nvidia 驱动的运行时环境。你现在可以使用以下命令继续安装运行时: + +针对 64 位系统: + +``` +flatpak install flathub org.freedesktop.Platform.GL.nvidia-MAJORVERSION-MINORVERSION +``` + +将 “MAJORVERSION” 替换为 Nvidia 驱动的主要版本(在上面的示例中为 390),将 “MINORVERSION” 替换为次要版本(步骤2,我例子中的为 48)。 + +例如,要为 Nvidia 图形驱动版本 390.48 安装运行时,你必须使用以下命令: + +``` +flatpak install flathub org.freedesktop.Platform.GL.nvidia-390-48 +``` + +对于 32 位系统(或能够在 64 位上运行 32 位的应用或游戏),使用以下命令安装 32 位运行时: + +``` +flatpak install flathub org.freedesktop.Platform.GL32.nvidia-MAJORVERSION-MINORVERSION +``` + +再说一次,将 “MAJORVERSION” 替换为 Nvidia 驱动的主要版本(在上面的示例中为 390),将 “MINORVERSION” 替换为次要版本(步骤2,我例子中的为 48)。 + +比如,要为 Nvidia 图形驱动版本 390.48 安装 32 位运行时,你需要使用以下命令: + +``` +flatpak install flathub org.freedesktop.Platform.GL32.nvidia-390-48 +``` + +以上就是你要运行支持 OpenGL 的 Flatpak 的应用或游戏的方法。 + +-------------------------------------------------------------------------------- + +via: https://www.linuxuprising.com/2018/06/how-to-get-flatpak-apps-and-games-built.html + +作者:[Logix][a] +选题:[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/) 荣誉推出 + +[a]:https://plus.google.com/118280394805678839070 +[1]:https://flatpak.org/setup/ +[2]:https://www.linuxuprising.com/2018/06/free-painting-software-krita-410.html +[3]:https://www.linuxuprising.com/2018/06/winepak-is-flatpak-repository-for.html +[4]:https://github.com/winepak/applications/issues/23 +[5]:https://github.com/flatpak/flatpak/issues/138 diff --git a/published/20180826 Be productive with Org-mode.md b/published/20180826 Be productive with Org-mode.md new file mode 100644 index 0000000000..5eef4efd7b --- /dev/null +++ b/published/20180826 Be productive with Org-mode.md @@ -0,0 +1,194 @@ +[#]: collector: (lujun9972) +[#]: translator: (lujun9972) +[#]: reviewer: (wxy) +[#]: publisher: (wxy) +[#]: url: (https://linux.cn/article-10634-1.html) +[#]: subject: (Be productive with Org-mode) +[#]: via: (https://www.badykov.com/emacs/2018/08/26/be-productive-with-org-mode/) +[#]: author: (Ayrat Badykov https://www.badykov.com) + +高效使用 Org 模式 +====== + +![org-mode-collage][1] + +### 简介 + +在我 [前一篇关于 Emacs 的文章中][2] 我提到了 [Org 模式][3]Org-mode,这是一个笔记管理工具和组织工具。本文中,我将会描述一下我日常的 Org 模式使用案例。 + +### 笔记和代办列表 + +首先而且最重要的是,Org 模式是一个管理笔记和待办列表的工具,Org 模式的所有工具都聚焦于使用纯文本文件记录笔记。我使用 Org 模式管理多种笔记。 + +#### 一般性笔记 + +Org 模式最基本的应用场景就是以笔记的形式记录下你想记住的事情。比如,下面是我正在学习的笔记内容: + +``` +* Learn +** Emacs LISP +*** Plan + + - [ ] Read best practices + - [ ] Finish reading Emacs Manual + - [ ] Finish Exercism Exercises + - [ ] Write a couple of simple plugins + - Notification plugin + +*** Resources + + https://www.gnu.org/software/emacs/manual/html_node/elisp/index.html + http://exercism.io/languages/elisp/about + [[http://batsov.com/articles/2011/11/30/the-ultimate-collection-of-emacs-resources/][The Ultimate Collection of Emacs Resources]] + +** Rust gamedev +*** Study [[https://github.com/SergiusIW/gate][gate]] 2d game engine with web assembly support +*** [[ggez][https://github.com/ggez/ggez]] +*** [[https://www.amethyst.rs/blog/release-0-8/][Amethyst 0.8 Relesed]] + +** Upgrade Elixir/Erlang Skills +*** Read Erlang in Anger +``` + +借助 [org-bullets][4] 它看起来是这样的: + +![notes][5] + +在这个简单的例子中,你能看到 Org 模式的一些功能: + +- 笔记允许嵌套 +- 链接 +- 带复选框的列表 + +#### 项目待办 + +我在工作时时常会发现一些能够改进或修复的事情。我并不会在代码文件中留下 TODO 注释 (坏味道),相反我使用 [org-projectile][6] 来在另一个文件中记录一个 TODO 事项,并留下一个快捷方式。下面是一个该文件的例子: + +``` +* [[elisp:(org-projectile-open-project%20"mana")][mana]] [3/9] + :PROPERTIES: + :CATEGORY: mana + :END: +** DONE [[file:~/Development/mana/apps/blockchain/lib/blockchain/contract/create_contract.ex::insufficient_gas_before_homestead%20=][fix this check using evm.configuration]] + CLOSED: [2018-08-08 Ср 09:14] + [[https://github.com/ethereum/EIPs/blob/master/EIPS/eip-2.md][eip2]]: + If contract creation does not have enough gas to pay for the final gas fee for + adding the contract code to the state, the contract creation fails (i.e. goes out-of-gas) + rather than leaving an empty contract. +** DONE Upgrade Elixir to 1.7. + CLOSED: [2018-08-08 Ср 09:14] +** TODO [#A] Difficulty tests +** TODO [#C] Upgrage to OTP 21 +** DONE [#A] EIP150 + CLOSED: [2018-08-14 Вт 21:25] +*** DONE operation cost changes + CLOSED: [2018-08-08 Ср 20:31] +*** DONE 1/64th for a call and create + CLOSED: [2018-08-14 Вт 21:25] +** TODO [#C] Refactor interfaces +** TODO [#B] Caching for storage during execution +** TODO [#B] Removing old merkle trees +** TODO do not calculate cost twice +* [[elisp:(org-projectile-open-project%20".emacs.d")][.emacs.d]] [1/3] + :PROPERTIES: + :CATEGORY: .emacs.d + :END: +** TODO fix flycheck issues (emacs config) +** TODO use-package for fetching dependencies +** DONE clean configuration + CLOSED: [2018-08-26 Вс 11:48] +``` + +它看起来是这样的: + +![project-todos][7] + +本例中你能看到更多的 Org 模式的功能: + +- 代办列表具有 `TODO`、`DONE` 两个状态。你还可以定义自己的状态 (`WAITING` 等) +- 关闭的事项有 `CLOSED` 时间戳 +- 有些事项有优先级 - A、B、C +- 链接可以指向文件内部 (`[[file:~/。..]`) + +#### 捕获模板 + +正如 Org 模式的文档中所描述的,捕获可以在不怎么干扰你工作流的情况下让你快速存储笔记。 + +我配置了许多捕获模板,可以帮我快速记录想要记住的事情。 + +``` + (setq org-capture-templates + '(("t" "Todo" entry (file+headline "~/Dropbox/org/todo.org" "Todo soon") + "* TODO %? \n %^t") + ("i" "Idea" entry (file+headline "~/Dropbox/org/ideas.org" "Ideas") + "* %? \n %U") + ("e" "Tweak" entry (file+headline "~/Dropbox/org/tweaks.org" "Tweaks") + "* %? \n %U") + ("l" "Learn" entry (file+headline "~/Dropbox/org/learn.org" "Learn") + "* %? \n") + ("w" "Work note" entry (file+headline "~/Dropbox/org/work.org" "Work") + "* %? \n") + ("m" "Check movie" entry (file+headline "~/Dropbox/org/check.org" "Movies") + "* %? %^g") + ("n" "Check book" entry (file+headline "~/Dropbox/org/check.org" "Books") + "* %^{book name} by %^{author} %^g"))) +``` + +做书本记录时我需要记下它的名字和作者,做电影记录时我需要记下标签,等等。 + +### 规划 + +Org 模式的另一个超棒的功能是你可以用它来作日常规划。让我们来看一个例子: + +![schedule][8] + +我没有挖空心思虚构一个例子,这就是我现在真实文件的样子。它看起来内容并不多,但它有助于你花时间在在重要的事情上并且帮你对抗拖延症。 + +#### 习惯 + +根据 Org 模式的文档,Org 能够跟踪一种特殊的代办事情,称为 “习惯”。当我想养成新的习惯时,我会将该功能与日常规划功能一起连用: + +![habits][9] + +你可以看到,目前我在尝试每天早期并且每两天锻炼一次。另外,它也有助于让我每天阅读书籍。 + +#### 议事日程视图 + +最后,我还使用议事日程视图功能。待办事项可能分散在不同文件中(比如我就是日常规划和习惯分散在不同文件中),议事日程视图可以提供所有待办事项的总览: + +![agenda][10] + +### 更多 Org 模式的功能 + ++ 手机应用([Android](https://play.google.com/store/apps/details?id=com.orgzly&hl=en)、[ios](https://itunes.apple.com/app/id1238649962])) ++ [将 Org 模式文档导出为其他格式](https://orgmode.org/manual/Exporting.html)(html、markdown、pdf、latex 等) ++ 使用 [ledger](https://github.com/ledger/ledger-mode) [追踪财务状况](https://orgmode.org/worg/org-tutorials/weaving-a-budget.html) + +### 总结 + +本文我描述了 Org 模式广泛功能中的一小部分,我每天都用它来提高工作效率,把时间花在重要的事情上。 + + +-------------------------------------------------------------------------------- + +via: https://www.badykov.com/emacs/2018/08/26/be-productive-with-org-mode/ + +作者:[Ayrat Badykov][a] +选题:[lujun9972][b] +译者:[lujun9972](https://github.com/lujun9972) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]: https://www.badykov.com +[b]: https://github.com/lujun9972 +[1]: https://i.imgur.com/hgqCyen.jpg +[2]: http://www.badykov.com/emacs/2018/07/31/why-emacs-is-a-great-editor/ +[3]: https://orgmode.org/ +[4]: https://github.com/sabof/org-bullets +[5]: https://i.imgur.com/lGi60Uw.png +[6]: https://github.com/IvanMalison/org-projectile +[7]: https://i.imgur.com/Hbu8ilX.png +[8]: https://i.imgur.com/z5HpuB0.png +[9]: https://i.imgur.com/YJIp3d0.png +[10]: https://i.imgur.com/CKX9BL9.png diff --git a/published/20180926 HTTP- Brief History of HTTP.md b/published/20180926 HTTP- Brief History of HTTP.md new file mode 100644 index 0000000000..5d95730284 --- /dev/null +++ b/published/20180926 HTTP- Brief History of HTTP.md @@ -0,0 +1,246 @@ +[#]: collector: (lujun9972) +[#]: translator: (MjSeven) +[#]: reviewer: (wxy) +[#]: publisher: (wxy) +[#]: url: (https://linux.cn/article-10621-1.html) +[#]: subject: (HTTP: Brief History of HTTP) +[#]: via: (https://hpbn.co/brief-history-of-http/#http-09-the-one-line-protocol) +[#]: author: (Ilya Grigorik https://www.igvita.com/) + +HTTP 简史 +====== + +译注:本文来源于 2013 年出版的《High Performance Browser Networking》的第九章,因此有些信息略有过时。事实上,现在 HTTP/2 已经有相当的不是,而新的 HTTP/3 也在设计和标准制定当中。 + +### 介绍 + +超文本传输协议Hypertext Transfer Protocol(HTTP)是互联网上最普遍和广泛采用的应用程序协议之一。它是客户端和服务器之间的通用语言,支持现代 Web。从最初作为单个的关键字和文档路径开始,它已成为不仅仅是浏览器的首选协议,而且几乎是所有连接互联网硬件和软件应用程序的首选协议。 + +在本文中,我们将简要回顾 HTTP 协议的发展历史。对 HTTP 不同语义的完整讨论超出了本文的范围,但理解 HTTP 的关键设计变更以及每个变更背后的动机将为我们讨论 HTTP 性能提供必要的背景,特别是在 HTTP/2 中即将进行的许多改进。 + +### HTTP 0.9: 单行协议 + +蒂姆·伯纳斯·李Tim Berners-Lee 最初的 HTTP 提案在设计时考虑到了简单性,以帮助他采用他的另一个新想法:万维网World Wide Web。这个策略看起来奏效了:注意,他是一个有抱负的协议设计者。 + +1991 年,伯纳斯·李概述了这个新协议的动机,并列出了几个高级设计目标:文件传输功能、请求超文档存档索引搜索的能力,格式协商以及将客户端引用到另一个服务器的能力。为了证明该理论的实际应用,构建了一个简单原型,它实现了所提议功能的一小部分。 + + * 客户端请求是一个 ASCII 字符串。 + * 客户端请求以回车符(CRLF)终止。 + * 服务器响应是 ASCII 字符流。 + * 服务器响应是一种超文本标记语言(HTML)。 + * 文档传输完成后连接终止。 + +然而,即使这听起来也比实际复杂得多。这些规则支持的是一种非常简单的,对 Telnet 友好的协议,一些 Web 服务器至今仍然支持这种协议: + +``` +$> telnet google.com 80 + +Connected to 74.125.xxx.xxx + +GET /about/ + +(hypertext response) +(connection closed) +``` + +请求包含这样一行:`GET` 方法和请求文档的路径。响应是一个超文本文档,没有标题或任何其他元数据,只有 HTML。真的是再简单不过了。此外,由于之前的交互是预期协议的子集,因此它获得了一个非官方的 HTTP 0.9 标签。其余的,就像他们所说的,都是历史。 + +从 1991 年这些不起眼的开始,HTTP 就有了自己的生命,并在接下来几年里迅速发展。让我们快速回顾一下 HTTP 0.9 的特性: + + * 采用客户端-服务器架构,是一种请求-响应协议。 + * 采用 ASCII 协议,运行在 TCP/IP 链路上。 + * 旨在传输超文本文档(HTML)。 + * 每次请求后,服务器和客户端之间的连接都将关闭。 + +> 流行的 Web 服务器,如 Apache 和 Nginx,仍然支持 HTTP 0.9 协议,部分原因是因为它没有太多功能!如果你感兴趣,打开 Telnet 会话并尝试通过 HTTP 0.9 访问 google.com 或你最喜欢的网站,并检查早期协议的行为和限制。 + +### HTTP/1.0: 快速增长和 Informational RFC + +1991 年至 1995 年期间,HTML 规范和一种称为 “web 浏览器”的新型软件快速发展,面向消费者的公共互联网基础设施也开始出现并快速增长。 + +> **完美风暴:1990 年代初的互联网热潮** + +> 基于蒂姆·伯纳斯·李最初的浏览器原型,美国国家超级计算机应用中心(NCSA)的一个团队决定实现他们自己的版本。就这样,第一个流行的浏览器诞生了:NCSA Mosaic。1994 年 10 月,NCSA 团队的一名程序员 Marc Andreessen 与 Jim Clark 合作创建了 Mosaic Communications,该公司后来改名为 Netscape(网景),并于 1994 年 12 月发布了 Netscape Navigator 1.0。从这一点来说,已经很清楚了,万维网已经不仅仅是学术上的好奇心了。 + +> 实际上,同年在瑞士日内瓦组织了第一次万维网会议,这导致万维网联盟World Wide Web Consortium(W3C)的成立,以帮助指导 HTML 的发展。同样,在 IETF 内部建立了一个并行的HTTP 工作组HTTP Working Group(HTTP-WG),专注于改进 HTTP 协议。后来这两个团体一直对 Web 的发展起着重要作用。 + +> 最后,完美风暴来临,CompuServe,AOL 和 Prodigy 在 1994-1995 年的同一时间开始向公众提供拨号上网服务。凭借这股迅速的浪潮,Netscape 在 1995 年 8 月 9 日凭借其成功的 IPO 创造了历史。这预示着互联网热潮已经到来,人人都想分一杯羹! + +不断增长的新 Web 所需功能及其在公共网站上的应用场景很快暴露了 HTTP 0.9 的许多基础限制:我们需要一种能够提供超文本文档、提供关于请求和响应的更丰富的元数据,支持内容协商等等的协议。相应地,新兴的 Web 开发人员社区通过一个特殊的过程生成了大量实验性的 HTTP 服务器和客户端实现来回应:实现,部署,并查看其他人是否采用它。 + +从这些急速增长的实验开始,一系列最佳实践和常见模式开始出现。1996 年 5 月,HTTP 工作组HTTP Working Group(HTTP-WG)发布了 RFC 1945,它记录了许多被广泛使用的 HTTP/1.0 实现的“常见用法”。请注意,这只是一个信息性 RFC:HTTP/1.0,如你所知的,它不是一个正式规范或 Internet 标准! + +话虽如此,HTTP/1.0 请求看起来应该是: + +``` +$> telnet website.org 80 + +Connected to xxx.xxx.xxx.xxx + +GET /rfc/rfc1945.txt HTTP/1.0 ❶ +User-Agent: CERN-LineMode/2.15 libwww/2.17b3 +Accept: */* + +HTTP/1.0 200 OK ❷ +Content-Type: text/plain +Content-Length: 137582 +Expires: Thu, 01 Dec 1997 16:00:00 GMT +Last-Modified: Wed, 1 May 1996 12:45:26 GMT +Server: Apache 0.84 + +(plain-text response) +(connection closed) +``` + +- ❶ 请求行有 HTTP 版本号,后面跟请求头 +- ❷ 响应状态,后跟响应头 + +前面的交互并不是 HTTP/1.0 功能的详尽列表,但它确实说明了一些关键的协议更改: + +* 请求可能多个由换行符分隔的请求头字段组成。 +* 响应对象的前缀是响应状态行。 +* 响应对象有自己的一组由换行符分隔的响应头字段。 +* 响应对象不限于超文本。 +* 每次请求后,服务器和客户端之间的连接都将关闭。 + +请求头和响应头都保留为 ASCII 编码,但响应对象本身可以是任何类型:HTML 文件、纯文本文件、图像或任何其他内容类型。因此,HTTP 的“超文本传输”部分在引入后不久就变成了用词不当。实际上,HTTP 已经迅速发展成为一种超媒体传输,但最初的名称没有改变。 + +除了媒体类型协商之外,RFC 还记录了许多其他常用功能:内容编码、字符集支持、多部分类型、授权、缓存、代理行为、日期格式等。 + +> 今天,几乎所有 Web 上的服务器都可以并且仍将使用 HTTP/1.0。不过,现在你应该更加清楚了!每个请求都需要一个新的 TCP 连接,这会对 HTTP/1.0 造成严重的性能损失。参见[三次握手][1],接着会[慢启动][2]。 + +### HTTP/1.1: Internet 标准 + +将 HTTP 转变为官方 IETF 互联网标准的工作与围绕 HTTP/1.0 的文档工作并行进行,并计划从 1995 年至 1999 年完成。事实上,第一个正式的 HTTP/1.1 标准定义于 RFC 2068,它在 HTTP/1.0 发布大约六个月后,即 1997 年 1 月正式发布。两年半后,即 1999 年 6 月,一些新的改进和更新被纳入标准,并作为 RFC 2616 发布。 + +HTTP/1.1 标准解决了早期版本中发现的许多协议歧义,并引入了一些关键的性能优化:保持连接,分块编码传输,字节范围请求,附加缓存机制,传输编码和请求管道。 + +有了这些功能,我们现在可以审视一下由任何现代 HTTP 浏览器和客户端执行的典型 HTTP/1.1 会话: + +``` +$> telnet website.org 80 +Connected to xxx.xxx.xxx.xxx + +GET /index.html HTTP/1.1 ❶ +Host: website.org +User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_4)... (snip) +Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 +Accept-Encoding: gzip,deflate,sdch +Accept-Language: en-US,en;q=0.8 +Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3 +Cookie: __qca=P0-800083390... (snip) + +HTTP/1.1 200 OK ❷ +Server: nginx/1.0.11 +Connection: keep-alive +Content-Type: text/html; charset=utf-8 +Via: HTTP/1.1 GWA +Date: Wed, 25 Jul 2012 20:23:35 GMT +Expires: Wed, 25 Jul 2012 20:23:35 GMT +Cache-Control: max-age=0, no-cache +Transfer-Encoding: chunked + +100 ❸ + +(snip) + +100 +(snip) + +0 ❹ + +GET /favicon.ico HTTP/1.1 ❺ +Host: www.website.org +User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_4)... (snip) +Accept: */* +Referer: http://website.org/ +Connection: close ❻ +Accept-Encoding: gzip,deflate,sdch +Accept-Language: en-US,en;q=0.8 +Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3 +Cookie: __qca=P0-800083390... (snip) + +HTTP/1.1 200 OK ❼ +Server: nginx/1.0.11 +Content-Type: image/x-icon +Content-Length: 3638 +Connection: close +Last-Modified: Thu, 19 Jul 2012 17:51:44 GMT +Cache-Control: max-age=315360000 +Accept-Ranges: bytes +Via: HTTP/1.1 GWA +Date: Sat, 21 Jul 2012 21:35:22 GMT +Expires: Thu, 31 Dec 2037 23:55:55 GMT +Etag: W/PSA-GAu26oXbDi + +(icon data) +(connection closed) +``` + +- ❶ 请求的 HTML 文件,包括编、字符集和 cookie 元数据 +- ❷ 原始 HTML 请求的分块响应 +- ❸ 以 ASCII 十六进制数字(256 字节)表示块中的八位元的数量 +- ❹ 分块流响应结束 +- ❺ 在相同的 TCP 连接上请求一个图标文件 +- ❻ 通知服务器不再重用连接 +- ❼ 图标响应后,然后关闭连接 + +哇,这里发生了很多事情!第一个也是最明显的区别是我们有两个对象请求,一个用于 HTML 页面,另一个用于图像,它们都通过一个连接完成。这就是保持连接的实际应用,它允许我们重用现有的 TCP 连接到同一个主机的多个请求,提供一个更快的最终用户体验。参见[TCP 优化][3]。 + +要终止持久连接,注意第二个客户端请求通过 `Connection` 请求头向服务器发送显示的 `close`。类似地,一旦传输响应,服务器就可以通知客户端关闭当前 TCP 连接。从技术上讲,任何一方都可以在没有此类信号的情况下终止 TCP 连接,但客户端和服务器应尽可能提供此类信号,以便双方都启用更好的连接重用策略。 + +> HTTP/1.1 改变了 HTTP 协议的语义,默认情况下使用保持连接。这意味着,除非另有说明(通过 `Connection:close` 头),否则服务器应默认保持连接打开。 + +> 但是,同样的功能也被反向移植到 HTTP/1.0 上,通过 `Connection:keep-Alive` 头启用。因此,如果你使用 HTTP/1.1,从技术上讲,你不需要 `Connection:keep-Alive` 头,但许多客户端仍然选择提供它。 + +此外,HTTP/1.1 协议还添加了内容、编码、字符集,甚至语言协商、传输编码、缓存指令、客户端 cookie,以及可以针对每个请求协商的十几个其他功能。 + +我们不打算详细讨论每个 HTTP/1.1 特性的语义。这个主题可以写一本专门的书了,已经有了很多很棒的书。相反,前面的示例很好地说明了 HTTP 的快速进展和演变,以及每个客户端-服务器交换的错综复杂的过程,里面发生了很多事情! + +> 要了解 HTTP 协议所有内部工作原理,参考 David Gourley 和 Brian Totty 共同撰写的权威指南: The Definitive Guide。 + +### HTTP/2: 提高传输性能 + +RFC 2616 自发布以来,已经成为互联网空前增长的基础:数十亿各种形状和大小的设备,从台式电脑到我们口袋里的小型网络设备,每天都在使用 HTTP 来传送新闻,视频,在我们生活中的数百万的其他网络应用程序都在依靠它。 + +一开始是一个简单的,用于检索超文本的简单协议,很快演变成了一种通用的超媒体传输,现在十年过去了,它几乎可以为你所能想象到的任何用例提供支持。可以使用协议的服务器无处不在,客户端也可以使用协议,这意味着现在许多应用程序都是专门在 HTTP 之上设计和部署的。 + +需要一个协议来控制你的咖啡壶?RFC 2324 已经涵盖了超文本咖啡壶控制协议(HTCPCP/1.0)- 它原本是 IETF 在愚人节开的一个玩笑,但在我们这个超链接的新世界中,它不仅仅意味着一个玩笑。 + +> 超文本传输协议(HTTP)是一个应用程序级的协议,用于分布式、协作、超媒体信息系统。它是一种通用的、无状态的协议,可以通过扩展请求方法、错误码和头,用于超出超文本之外的许多任务,比如名称服务器和分布式对象管理系统。HTTP 的一个特性是数据表示的类型和协商,允许独立于传输的数据构建系统。 +> +> RFC 2616: HTTP/1.1, June 1999 + +HTTP 协议的简单性是它最初被采用和快速增长的原因。事实上,现在使用 HTTP 作为主要控制和数据协议的嵌入式设备(传感器,执行器和咖啡壶)并不罕见。但在其自身成功的重压下,随着我们越来越多地继续将日常互动转移到网络 —— 社交、电子邮件、新闻和视频,以及越来越多的个人和工作空间,它也开始显示出压力的迹象。用户和 Web 开发人员现在都要求 HTTP/1.1 提供近乎实时的响应能力和协议 +性能,如果不进行一些修改,就无法满足这些要求。 + +为了应对这些新挑战,HTTP 必须继续发展,因此 HTTPbis 工作组在 2012 年初宣布了一项针对 HTTP/2 的新计划: + +> 已经有一个协议中出现了新的实现经验和兴趣,该协议保留了 HTTP 的语义,但是没有保留 HTTP/1.x 的消息框架和语法,这些问题已经被确定为妨碍性能和鼓励滥用底层传输。 +> +> 工作组将使用有序的双向流中生成 HTTP 当前语义的新表达式的规范。与 HTTP/1.x 一样,主要传输目标是 TCP,但是应该可以使用其他方式传输。 +> +> HTTP/2 charter, January 2012 + +HTTP/2 的主要重点是提高传输性能并支持更低的延迟和更高的吞吐量。主要的版本增量听起来像是一个很大的步骤,但就性能而言,它将是一个重大的步骤,但重要的是要注意,没有任何高级协议语义收到影响:所有的 HTTP 头,值和用例是相同的。 + +任何现有的网站或应用程序都可以并且将通过 HTTP/2 传送而无需修改。你无需修改应用程序标记来利用 HTTP/2。HTTP 服务器将来一定会使用 HTTP/2,但这对大多数用户来说应该是透明的升级。如果工作组实现目标,唯一的区别应该是我们的应用程序以更低的延迟和更好的网络连接利用率来传送数据。 + +话虽如此,但我们不要走的太远了。在讨论新的 HTTP/2 协议功能之前,有必要回顾一下我们现有的 HTTP/1.1 部署和性能最佳实践。HTTP/2 工作组正在新规范上取得快速的进展,但即使最终标准已经完成并准备就绪,在可预见的未来,我们仍然必须支持旧的 HTTP/1.1 客户端,实际上,这得十年或更长时间。 + +-------------------------------------------------------------------------------- + +via: https://hpbn.co/brief-history-of-http/#http-09-the-one-line-protocol + +作者:[Ilya Grigorik][a] +选题:[lujun9972][b] +译者:[MjSeven](https://github.com/MjSeven) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]: https://www.igvita.com/ +[b]: https://github.com/lujun9972 +[1]: https://hpbn.co/building-blocks-of-tcp/#three-way-handshake +[2]: https://hpbn.co/building-blocks-of-tcp/#slow-start +[3]: https://hpbn.co/building-blocks-of-tcp/#optimizing-for-tcp diff --git a/published/20181216 Schedule a visit with the Emacs psychiatrist.md b/published/20181216 Schedule a visit with the Emacs psychiatrist.md new file mode 100644 index 0000000000..304beda2ff --- /dev/null +++ b/published/20181216 Schedule a visit with the Emacs psychiatrist.md @@ -0,0 +1,63 @@ +[#]: collector: (lujun9972) +[#]: translator: (lujun9972) +[#]: reviewer: (wxy) +[#]: publisher: (wxy) +[#]: url: (https://linux.cn/article-10601-1.html) +[#]: subject: (Schedule a visit with the Emacs psychiatrist) +[#]: via: (https://opensource.com/article/18/12/linux-toy-eliza) +[#]: author: (Jason Baker https://opensource.com/users/jason-baker) + +预约 Emacs 心理医生 +====== + +> Eliza 是一个隐藏于某个 Linux 最流行文本编辑器中的自然语言处理聊天机器人。 + +![](https://opensource.com/sites/default/files/styles/image-full-size/public/uploads/linux-toy-eliza.png?itok=3ioiBik_) + +欢迎你,今天时期 24 天的 Linux 命令行玩具的又一天。如果你是第一次访问本系列,你可能会问什么是命令行玩具呢。我们将会逐步确定这个概念,但一般来说,它可能是一个游戏,或任何能让你在终端玩的开心的其他东西。 + +可能你们已经见过了很多我们之前挑选的那些玩具,但我们依然希望对所有人来说都至少有一件新鲜事物。 + +今天的选择是 Emacs 中的一个彩蛋:Eliza,Rogerian 心理医生,一个准备好倾听你述说一切的终端玩具。 + +旁白:虽然这个玩具很好玩,但你的健康不是用来开玩笑的。请在假期期间照顾好你自己,无论时身体上还是精神上,若假期中的压力和焦虑对你的健康产生负面影响,请考虑找专业人士进行指导。真的有用。 + +要启动 [Eliza][1],首先,你需要启动 Emacs。很有可能 Emacs 已经安装在你的系统中了,但若没有,它基本上也肯定在你默认的软件仓库中。 + +由于我要求本系列的工具一定要时运行在终端内,因此使用 `-nw` 标志来启动 Emacs 让它在你的终端模拟器中运行。 + +``` +$ emacs -nw +``` + +在 Emacs 中,输入 `M-x doctor` 来启动 Eliza。对于像我这样有 Vim 背景的人可能不知道这是什么意思,只需要按下 `escape`,输入 `x` 然后输入 `doctor`。然后,向它倾述所有假日的烦恼吧。 + +Eliza 历史悠久,最早可以追溯到 1960 年代中期的 MIT 人工智能实验室。[维基百科][2] 上有它历史的详细说明。 + +Eliza 并不是 Emacs 中唯一的娱乐工具。查看 [手册][3] 可以看到一整列好玩的玩具。 + +![Linux toy:eliza animated][5] + +你有什么喜欢的命令行玩具值得推荐吗?我们时间不多了,但我还是想听听你的建议。请在下面评论中告诉我,我会查看的。另外也欢迎告诉我你们对本次玩具的想法。 + +请一定要看看昨天的玩具,[带着这个复刻版吃豆人来到 Linux 终端游乐中心][6],然后明天再来看另一个玩具! + +-------------------------------------------------------------------------------- + +via: https://opensource.com/article/18/12/linux-toy-eliza + +作者:[Jason Baker][a] +选题:[lujun9972][b] +译者:[lujun9972](https://github.com/lujun9972) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]: https://opensource.com/users/jason-baker +[b]: https://github.com/lujun9972 +[1]: https://www.emacswiki.org/emacs/EmacsDoctor +[2]: https://en.wikipedia.org/wiki/ELIZA +[3]: https://www.gnu.org/software/emacs/manual/html_node/emacs/Amusements.html +[4]: /file/417326 +[5]: https://opensource.com/sites/default/files/uploads/linux-toy-eliza-animated.gif (Linux toy: eliza animated) +[6]: https://opensource.com/article/18/12/linux-toy-myman diff --git a/published/20181220 7 CI-CD tools for sysadmins.md b/published/20181220 7 CI-CD tools for sysadmins.md new file mode 100644 index 0000000000..64933afa4f --- /dev/null +++ b/published/20181220 7 CI-CD tools for sysadmins.md @@ -0,0 +1,166 @@ +[#]: collector: (lujun9972) +[#]: translator: (jdh8383) +[#]: reviewer: (wxy) +[#]: publisher: (wxy) +[#]: url: (https://linux.cn/article-10578-1.html) +[#]: subject: (7 CI/CD tools for sysadmins) +[#]: via: (https://opensource.com/article/18/12/cicd-tools-sysadmins) +[#]: author: (Dan Barker https://opensource.com/users/barkerd427) + +系统管理员的 7 个 CI/CD 工具 +====== + +> 本文是一篇简单指南:介绍一些顶级的开源的持续集成、持续交付和持续部署(CI/CD)工具。 + +![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/cicd_continuous_delivery_deployment_gears.png?itok=kVlhiEkc) + +虽然持续集成、持续交付和持续部署(CI/CD)在开发者社区里已经存在很多年,一些机构在其运维部门也有实施经验,但大多数公司并没有做这样的尝试。对于很多机构来说,让运维团队能够像他们的开发同行一样熟练操作 CI/CD 工具,已经变得十分必要了。 + +无论是基础设施、第三方应用还是内部开发的应用,都可以开展 CI/CD 实践。尽管你会发现有很多不同的工具,但它们都有着相似的设计模型。而且可能最重要的一点是:通过带领你的公司进行这些实践,会让你在公司内部变得举足轻重,成为他人学习的榜样。 + +一些机构在自己的基础设施上已有多年的 CI/CD 实践经验,常用的工具包括 [Ansible][1]、[Chef][2] 或者 [Puppet][3]。另一些工具,比如 [Test Kitchen][4],允许在最终要部署应用的基础设施上运行测试。事实上,如果使用更高级的配置方法,你甚至可以将应用部署到有真实负载的仿真“生产环境”上,来运行应用级别的测试。然而,单单是能够测试基础设施就是一项了不起的成就了。配置管理工具 Terraform 可以通过 Test Kitchen 来快速创建更[短暂][5]和[冥等的][6]的基础设施配置,这比它的前辈要强不少。再加上 Linux 容器和 Kubernetes,在数小时内,你就可以创建一套类似于生产环境的配置参数和系统资源,来测试整个基础设施和其上部署的应用,这在以前可能需要花费几个月的时间。而且,删除和再次创建整个测试环境也非常容易。 + +当然,作为初学者,你也可以把网络配置和 DDL(数据定义语言data definition language)文件加入版本控制,然后开始尝试一些简单的 CI/CD 流程。虽然只能帮你检查一下语义语法或某些最佳实践,但实际上大多数开发的管道都是这样起步的。只要你把脚手架搭起来,建造就容易得多了。而一旦起步,你就会发现各种管道的使用场景。 + +举个例子,我经常会在公司内部写新闻简报,我使用 [MJML][7] 制作邮件模板,然后把它加入版本控制。我一般会维护一个 web 版本,但是一些同事喜欢 PDF 版,于是我创建了一个[管道][8]。每当我写好一篇新闻稿,就在 Gitlab 上提交一个合并请求。这样做会自动创建一个 index.html 文件,生成这篇新闻稿的 HTML 和 PDF 版链接。HTML 和 PDF 文件也会在该管道里同时生成。除非有人来检查确认,这些文件不会被直接发布出去。使用 GitLab Pages 发布这个网站后,我就可以下载一份 HTML 版,用来发送新闻简报。未来,我会修改这个流程,当合并请求成功或者在某个审核步骤后,自动发出对应的新闻稿。这些处理逻辑并不复杂,但的确为我节省了不少时间。实际上这些工具最核心的用途就是替你节省时间。 + +关键是要在抽象层创建出工具,这样稍加修改就可以处理不同的问题。值得留意的是,我创建的这套流程几乎不需要任何代码,除了一些[轻量级的 HTML 模板][9],一些[把 HTML 文件转换成 PDF 的 nodejs 代码][10],还有一些[生成索引页面的 nodejs 代码][11]。 + +这其中一些东西可能看起来有点复杂,但其中大部分都源自我使用的不同工具的教学文档。而且很多开发人员也会乐意跟你合作,因为他们在完工时会发现这些东西也挺有用。上面我提供的那些代码链接是给 [DevOps KC][12](LCTT 译注:一个地方性 DevOps 组织) 发送新闻简报用的,其中大部分用来创建网站的代码来自我在内部新闻简报项目上所作的工作。 + +下面列出的大多数工具都可以提供这种类型的交互,但是有些工具提供的模型略有不同。这一领域新兴的模型是用声明式的方法例如 YAML 来描述一个管道,其中的每个阶段都是短暂而幂等的。许多系统还会创建[有向无环图(DAG)][13],来确保管道上不同的阶段排序的正确性。 + +这些阶段一般运行在 Linux 容器里,和普通的容器并没有区别。有一些工具,比如 [Spinnaker][14],只关注部署组件,而且提供一些其他工具没有的操作特性。[Jenkins][15] 则通常把管道配置存成 XML 格式,大部分交互都可以在图形界面里完成,但最新的方案是使用[领域专用语言(DSL)][16](如 [Groovy][17])。并且,Jenkins 的任务(job)通常运行在各个节点里,这些节点上会装一个专门的 Java 代理,还有一堆混杂的插件和预装组件。 + +Jenkins 在自己的工具里引入了管道的概念,但使用起来却并不轻松,甚至包含一些禁区。最近,Jenkins 的创始人决定带领社区向新的方向前进,希望能为这个项目注入新的活力,把 CI/CD 真正推广开(LCTT 译注:详见后面的 Jenkins 章节)。我认为其中最有意思的想法是构建一个云原生 Jenkins,能把 Kubernetes 集群转变成 Jenkins CI/CD 平台。 + +当你更多地了解这些工具并把实践带入你的公司和运维部门,你很快就会有追随者,因为你有办法提升自己和别人的工作效率。我们都有多年积累下来的技术债要解决,如果你能给同事们提供足够的时间来处理这些积压的工作,他们该会有多感激呢?不止如此,你的客户也会开始看到应用变得越来越稳定,管理层会把你看作得力干将,你也会在下次谈薪资待遇或参加面试时更有底气。 + +让我们开始深入了解这些工具吧,我们将对每个工具做简短的介绍,并分享一些有用的链接。 + +### GitLab CI + +- [项目主页](https://about.gitlab.com/product/continuous-integration/) +- [源代码](https://gitlab.com/gitlab-org/gitlab-ce/) +- 许可证:MIT + +GitLab 可以说是 CI/CD 领域里新登场的玩家,但它却在权威调研机构 [Forrester 的 CI 集成工具的调查报告][20]中位列第一。在一个高水平、竞争充分的领域里,这是个了不起的成就。是什么让 GitLab CI 这么成功呢?它使用 YAML 文件来描述整个管道。另有一个功能叫做 Auto DevOps,可以为较简单的项目用多种内置的测试单元自动生成管道。这套系统使用 [Herokuish buildpacks][21] 来判断语言的种类以及如何构建应用。有些语言也可以管理数据库,它真正改变了构建新应用程序和从开发的开始将它们部署到生产环境的过程。它原生集成于 Kubernetes,可以根据不同的方案将你的应用自动部署到 Kubernetes 集群,比如灰度发布、蓝绿部署等。 + +除了它的持续集成功能,GitLab 还提供了许多补充特性,比如:将 Prometheus 和你的应用一同部署,以提供操作监控功能;通过 GitLab 提供的 Issues、Epics 和 Milestones 功能来实现项目评估和管理;管道中集成了安全检测功能,多个项目的检测结果会聚合显示;你可以通过 GitLab 提供的网页版 IDE 在线编辑代码,还可以快速查看管道的预览或执行状态。 + +### GoCD + +- [项目主页](https://www.gocd.org/) +- [源代码](https://github.com/gocd/gocd) +- 许可证:Apache 2.0 + +GoCD 是由老牌软件公司 Thoughtworks 出品,这已经足够证明它的能力和效率。对我而言,GoCD 最具亮点的特性是它的[价值流视图(VSM)][22]。实际上,一个管道的输出可以变成下一个管道的输入,从而把管道串联起来。这样做有助于提高不同开发团队在整个开发流程中的独立性。比如在引入 CI/CD 系统时,有些成立较久的机构希望保持他们各个团队相互隔离,这时候 VSM 就很有用了:让每个人都使用相同的工具就很容易在 VSM 中发现工作流程上的瓶颈,然后可以按图索骥调整团队或者想办法提高工作效率。 + +为公司的每个产品配置 VSM 是非常有价值的;GoCD 可以使用 [JSON 或 YAML 格式存储配置][23],还能以可视化的方式展示数据等待时间,这让一个机构能有效减少学习它的成本。刚开始使用 GoCD 创建你自己的流程时,建议使用人工审核的方式。让每个团队也采用人工审核,这样你就可以开始收集数据并且找到可能的瓶颈点。 + +### Travis CI + +- [项目主页](https://docs.travis-ci.com/) +- [源代码](https://github.com/travis-ci/travis-ci) +- 许可证:MIT + +我使用的第一个软件既服务(SaaS)类型的 CI 系统就是 Travis CI,体验很不错。管道配置以源码形式用 YAML 保存,它与 GitHub 等工具无缝整合。我印象中管道从来没有失效过,因为 Travis CI 的在线率很高。除了 SaaS 版之外,你也可以使用自行部署的版本。我还没有自行部署过,它的组件非常多,要全部安装的话,工作量就有点吓人了。我猜更简单的办法是把它部署到 Kubernetes 上,[Travis CI 提供了 Helm charts][26],这些 charts 目前不包含所有要部署的组件,但我相信以后会越来越丰富的。如果你不想处理这些细枝末节的问题,还有一个企业版可以试试。 + +假如你在开发一个开源项目,你就能免费使用 SaaS 版的 Travis CI,享受顶尖团队提供的优质服务!这样能省去很多麻烦,你可以在一个相对通用的平台上(如 GitHub)研发开源项目,而不用找服务器来运行任何东西。 + +### Jenkins + +- [项目主页](https://jenkins.io/) +- [源代码](https://github.com/jenkinsci/jenkins) +- 许可证:MIT + +Jenkins 在 CI/CD 界绝对是元老级的存在,也是事实上的标准。我强烈建议你读一读这篇文章:“[Jenkins: Shifting Gears][27]”,作者 Kohsuke 是 Jenkins 的创始人兼 CloudBees 公司 CTO。这篇文章契合了我在过去十年里对 Jenkins 及其社区的感受。他在文中阐述了一些这几年呼声很高的需求,我很乐意看到 CloudBees 引领这场变革。长期以来,Jenkins 对于非开发人员来说有点难以接受,并且一直是其管理员的重担。还好,这些问题正是他们想要着手解决的。 + +[Jenkins 配置既代码][28](JCasC)应该可以帮助管理员解决困扰了他们多年的配置复杂性问题。与其他 CI/CD 系统类似,只需要修改一个简单的 YAML 文件就可以完成 Jenkins 主节点的配置工作。[Jenkins Evergreen][29] 的出现让配置工作变得更加轻松,它提供了很多预设的使用场景,你只管套用就可以了。这些发行版会比官方的标准版本 Jenkins 更容易维护和升级。 + +Jenkins 2 引入了两种原生的管道功能,我在 LISA(LCTT 译注:一个系统架构和运维大会) 2017 年的研讨会上已经[讨论过了][30]。这两种功能都没有 YAML 简便,但在处理复杂任务时它们很好用。 + +[Jenkins X][31] 是 Jenkins 的一个全新变种,用来实现云端原生 Jenkins(至少在用户看来是这样)。它会使用 JCasC 及 Evergreen,并且和 Kubernetes 整合的更加紧密。对于 Jenkins 来说这是个令人激动的时刻,我很乐意看到它在这一领域的创新,并且继续发挥领袖作用。 + +### Concourse CI + +- [项目主页](https://concourse-ci.org/) +- [源代码](https://github.com/concourse/concourse) +- 许可证:Apache 2.0 + +我第一次知道 Concourse 是通过 Pivotal Labs 的伙计们介绍的,当时它处于早期 beta 版本,而且那时候也很少有类似的工具。这套系统是基于微服务构建的,每个任务运行在一个容器里。它独有的一个优良特性是能够在你本地系统上运行任务,体现你本地的改动。这意味着你完全可以在本地开发(假设你已经连接到了 Concourse 的服务器),像在真实的管道构建流程一样从你本地构建项目。而且,你可以在修改过代码后从本地直接重新运行构建,来检验你的改动结果。 + +Concourse 还有一个简单的扩展系统,它依赖于“资源”这一基础概念。基本上,你想给管道添加的每个新功能都可以用一个 Docker 镜像实现,并作为一个新的资源类型包含在你的配置中。这样可以保证每个功能都被封装在一个不可变的独立工件中,方便对其单独修改和升级,改变其中一个时不会影响其他构建。 + +### Spinnaker + +- [项目主页](https://www.spinnaker.io/) +- [源代码](https://github.com/spinnaker/spinnaker) +- 许可证:Apache 2.0 + +Spinnaker 出自 Netflix,它更关注持续部署而非持续集成。它可以与其他工具整合,比如 Travis 和 Jenkins,来启动测试和部署流程。它也能与 Prometheus、Datadog 这样的监控工具集成,参考它们提供的指标来决定如何部署。例如,在金丝雀发布canary deployment里,我们可以根据收集到的相关监控指标来做出判断:最近的这次发布是否导致了服务降级,应该立刻回滚;还是说看起来一切 OK,应该继续执行部署。 + +谈到持续部署,一些另类但却至关重要的问题往往被忽略掉了,说出来可能有点让人困惑:Spinnaker 可以帮助持续部署不那么“持续”。在整个应用部署流程期间,如果发生了重大问题,它可以让流程停止执行,以阻止可能发生的部署错误。但它也可以在最关键的时刻让人工审核强制通过,发布新版本上线,使整体收益最大化。实际上,CI/CD 的主要目的就是在商业模式需要调整时,能够让待更新的代码立即得到部署。 + +### Screwdriver + +- [项目主页](http://screwdriver.cd/) +- [源代码](https://github.com/screwdriver-cd/screwdriver) +- 许可证:BSD + +Screwdriver 是个简单而又强大的软件。它采用微服务架构,依赖像 Nomad、Kubernetes 和 Docker 这样的工具作为执行引擎。官方有一篇很不错的[部署教学文档][34],介绍了如何将它部署到 AWS 和 Kubernetes 上,但如果正在开发中的 [Helm chart][35] 也完成的话,就更完美了。 + +Screwdriver 也使用 YAML 来描述它的管道,并且有很多合理的默认值,这样可以有效减少各个管道重复的配置项。用配置文件可以组织起高级的工作流,来描述各个任务间复杂的依赖关系。例如,一项任务可以在另一个任务开始前或结束后运行;各个任务可以并行也可以串行执行;更赞的是你可以预先定义一项任务,只在特定的拉取请求时被触发,而且与之有依赖关系的任务并不会被执行,这能让你的管道具有一定的隔离性:什么时候被构造的工件应该被部署到生产环境,什么时候应该被审核。 + +--- + +以上只是我对这些 CI/CD 工具的简单介绍,它们还有许多很酷的特性等待你深入探索。而且它们都是开源软件,可以自由使用,去部署一下看看吧,究竟哪个才是最适合你的那个。 + +-------------------------------------------------------------------------------- + +via: https://opensource.com/article/18/12/cicd-tools-sysadmins + +作者:[Dan Barker][a] +选题:[lujun9972][b] +译者:[jdh8383](https://github.com/jdh8383) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]: https://opensource.com/users/barkerd427 +[b]: https://github.com/lujun9972 +[1]: https://www.ansible.com/ +[2]: https://www.chef.io/ +[3]: https://puppet.com/ +[4]: https://github.com/test-kitchen/test-kitchen +[5]: https://www.merriam-webster.com/dictionary/ephemeral +[6]: https://en.wikipedia.org/wiki/Idempotence +[7]: https://mjml.io/ +[8]: https://gitlab.com/devopskc/newsletter/blob/master/.gitlab-ci.yml +[9]: https://gitlab.com/devopskc/newsletter/blob/master/index/index.html +[10]: https://gitlab.com/devopskc/newsletter/blob/master/html-to-pdf.js +[11]: https://gitlab.com/devopskc/newsletter/blob/master/populate-index.js +[12]: https://devopskc.com/ +[13]: https://en.wikipedia.org/wiki/Directed_acyclic_graph +[14]: https://www.spinnaker.io/ +[15]: https://jenkins.io/ +[16]: https://martinfowler.com/books/dsl.html +[17]: http://groovy-lang.org/ +[18]: https://about.gitlab.com/product/continuous-integration/ +[19]: https://gitlab.com/gitlab-org/gitlab-ce/ +[20]: https://about.gitlab.com/2017/09/27/gitlab-leader-continuous-integration-forrester-wave/ +[21]: https://github.com/gliderlabs/herokuish +[22]: https://www.gocd.org/getting-started/part-3/#value_stream_map +[23]: https://docs.gocd.org/current/advanced_usage/pipelines_as_code.html +[24]: https://docs.travis-ci.com/ +[25]: https://github.com/travis-ci/travis-ci +[26]: https://github.com/travis-ci/kubernetes-config +[27]: https://jenkins.io/blog/2018/08/31/shifting-gears/ +[28]: https://jenkins.io/projects/jcasc/ +[29]: https://github.com/jenkinsci/jep/blob/master/jep/300/README.adoc +[30]: https://danbarker.codes/talk/lisa17-becoming-plumber-building-deployment-pipelines/ +[31]: https://jenkins-x.io/ +[32]: https://concourse-ci.org/ +[33]: https://github.com/concourse/concourse +[34]: https://docs.screwdriver.cd/cluster-management/kubernetes +[35]: https://github.com/screwdriver-cd/screwdriver-chart diff --git a/published/20190104 Midori- A Lightweight Open Source Web Browser.md b/published/20190104 Midori- A Lightweight Open Source Web Browser.md new file mode 100644 index 0000000000..e263fc38ca --- /dev/null +++ b/published/20190104 Midori- A Lightweight Open Source Web Browser.md @@ -0,0 +1,110 @@ +[#]: collector: (lujun9972) +[#]: translator: (geekpi) +[#]: reviewer: (wxy) +[#]: publisher: (wxy) +[#]: url: (https://linux.cn/article-10602-1.html) +[#]: subject: (Midori: A Lightweight Open Source Web Browser) +[#]: via: (https://itsfoss.com/midori-browser) +[#]: author: (Abhishek Prakash https://itsfoss.com/author/abhishek/) + +Midori:轻量级开源 Web 浏览器 +====== + +> 这是一个对再次回归的轻量级、快速、开源的 Web 浏览器 Midori 的快速回顾。 + +如果你正在寻找一款轻量级[网络浏览器替代品][1],请试试 Midori。 + +[Midori][2]是一款开源的网络浏览器,它更注重轻量级而不是提供大量功能。 + +如果你从未听说过 Midori,你可能会认为它是一个新的应用程序,但实际上 Midori 首次发布于 2007 年。 + +因为它专注于速度,所以 Midori 很快就聚集了一群爱好者,并成为了 Bodhi Linux、SilTaz 等轻量级 Linux 发行版的默认浏览器。 + +其他发行版如 [elementary OS][3] 也使用了 Midori 作为其默认浏览器。但 Midori 的开发在 2016 年左右停滞了,它的粉丝开始怀疑 Midori 已经死了。由于这个原因,elementary OS 从最新版本中删除了它。 + +好消息是 Midori 还没有死。经过近两年的不活跃,开发工作在 2018 年的最后一个季度恢复了。在后来的版本中添加了一些包括广告拦截器的扩展。 + +### Midori 网络浏览器的功能 + +![Midori web browser][4] + +以下是 Midori 浏览器的一些主要功能 + + * 使用 Vala 编写,使用 GTK+3 和 WebKit 渲染引擎。 +  * 标签、窗口和会话管理。 +  * 快速拨号。 +  * 默认保存下一个会话的选项卡。 +  * 使用 DuckDuckGo 作为默认搜索引擎。可以更改为 Google 或 Yahoo。 +  * 书签管理。 +  * 可定制和可扩展的界面。 +  * 扩展模块可以用 C 和 Vala 编写。 +  * 支持 HTML5。 +  * 少量的扩展程序包括广告拦截器、彩色标签等。没有第三方扩展程序。 +  * 表单历史。 +  * 隐私浏览。 +  * 可用于 Linux 和 Windows。 + +小知识:Midori 是日语单词,意思是绿色。如果你因此而猜想的话,但 Midori 的开发者实际不是日本人。 + +### 体验 Midori + +![Midori web browser in Ubuntu 18.04][5] + +这几天我一直在使用 Midori。体验基本很好。它支持 HTML5 并能快速渲染网站。广告拦截器也没问题。正如你对任何标准 Web 浏览器所期望的那样,浏览体验挺顺滑。 + +缺少扩展一直是 Midori 的弱点,所以​​我不打算谈论这个。 + +我注意到的是它不支持国际语言。我找不到添加新语言支持的方法。它根本无法渲染印地语字体,我猜对其他非[罗曼语言][6]也是一样。 + +我也在 YouTube 中也遇到了麻烦。有些视频会抛出播放错误而其他视频没问题。 + +Midori 没有像 Chrome 那样吃我的内存,所以这是一个很大的优势。 + +如果你想尝试 Midori,让我们看下你该如何安装。 + +### 在 Linux 上安装 Midori + +在 Ubuntu 18.04 仓库中不再提供 Midori。但是,可以使用 [Snap 包][7]轻松安装较新版本的 Midori。 + +如果你使用的是 Ubuntu,你可以在软件中心找到 Midori(Snap 版)并从那里安装。 + +![Midori browser is available in Ubuntu Software Center][8] + +对于其他 Linux 发行版,请确保你[已启用 Snap 支持][9],然后你可以使用以下命令安装 Midori: + +``` +sudo snap install midori +``` + +你可以选择从源代码编译。你可以从 Midori 的网站下载它的代码。 + +- [下载 Midori](https://www.midori-browser.org/download/) + +如果你喜欢 Midori 并希望帮助这个开源项目,请向他们捐赠或[从他们的商店购买 Midori 商品][10]。 + +你在使用 Midori 还是曾经用过么?你的体验如何?你更喜欢使用哪种其他网络浏览器?请在下面的评论栏分享你的观点。 + +-------------------------------------------------------------------------------- + +via: https://itsfoss.com/midori-browser + +作者:[Abhishek Prakash][a] +选题:[lujun9972][b] +译者:[geekpi](https://github.com/geekpi) +校对:[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/open-source-browsers-linux/ +[2]: https://www.midori-browser.org/ +[3]: https://itsfoss.com/elementary-os-juno-features/ +[4]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2019/01/Midori-web-browser.jpeg?resize=800%2C450&ssl=1 +[5]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2019/01/midori-browser-linux.jpeg?resize=800%2C491&ssl=1 +[6]: https://en.wikipedia.org/wiki/Romance_languages +[7]: https://itsfoss.com/use-snap-packages-ubuntu-16-04/ +[8]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2019/01/midori-ubuntu-software-center.jpeg?ssl=1 +[9]: https://itsfoss.com/install-snap-linux/ +[10]: https://www.midori-browser.org/shop +[11]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2019/01/Midori-web-browser.jpeg?fit=800%2C450&ssl=1 diff --git a/published/20190108 How ASLR protects Linux systems from buffer overflow attacks.md b/published/20190108 How ASLR protects Linux systems from buffer overflow attacks.md new file mode 100644 index 0000000000..08e41d60ee --- /dev/null +++ b/published/20190108 How ASLR protects Linux systems from buffer overflow attacks.md @@ -0,0 +1,127 @@ +[#]: collector: (lujun9972) +[#]: translator: (leommxj) +[#]: reviewer: (wxy) +[#]: publisher: (wxy) +[#]: url: (https://linux.cn/article-10592-1.html) +[#]: subject: (How ASLR protects Linux systems from buffer overflow attacks) +[#]: via: (https://www.networkworld.com/article/3331199/linux/what-does-aslr-do-for-linux.html) +[#]: author: (Sandra Henry-Stocker https://www.networkworld.com/author/Sandra-Henry_Stocker/) + +ASLR 是如何保护 Linux 系统免受缓冲区溢出攻击的 +====== + +> 地址空间随机化(ASLR)是一种内存攻击缓解技术,可以用于 Linux 和 Windows 系统。了解一下如何运行它、启用/禁用它,以及它是如何工作的。 + +![](https://images.idgesg.net/images/article/2019/01/shuffling-cards-100784640-large.jpg) + +地址空间随机化Address Space Layout Randomization(ASLR)是一种操作系统用来抵御缓冲区溢出攻击的内存保护机制。这种技术使得系统上运行的进程的内存地址无法被预测,使得与这些进程有关的漏洞变得更加难以利用。 + +ASLR 目前在 Linux、Windows 以及 MacOS 系统上都有使用。其最早出现在 2005 的 Linux 系统上。2007 年,这项技术被 Windows 和 MacOS 部署使用。尽管 ASLR 在各个系统上都提供相同的功能,却有着不同的实现。 + +ASLR 的有效性依赖于整个地址空间布局是否对于攻击者保持未知。此外,只有编译时作为位置无关可执行文件Position Independent Executable(PIE)的可执行程序才能得到 ASLR 技术的最大保护,因为只有这样,可执行文件的所有代码节区才会被加载在随机地址。PIE 机器码不管绝对地址是多少都可以正确执行。 + +### ASLR 的局限性 + +尽管 ASLR 使得对系统漏洞的利用更加困难了,但其保护系统的能力是有限的。理解关于 ASLR 的以下几点是很重要的: + + * 它不能*解决*漏洞,而是增加利用漏洞的难度 + * 并不追踪或报告漏洞 + * 不能对编译时没有开启 ASLR 支持的二进制文件提供保护 + * 不能避免被绕过 + +### ASLR 是如何工作的 + +通过对攻击者在进行缓冲区溢出攻击时所要用到的内存布局中的偏移做了随机化,ASLR 加大了攻击成功的难度,从而增强了系统的控制流完整性。 + +通常认为 ASLR 在 64 位系统上效果更好,因为 64 位系统提供了更大的熵(可随机的地址范围)。 + +### ASLR 是否正在你的 Linux 系统上运行? + +下面展示的两条命令都可以告诉你的系统是否启用了 ASLR 功能: + +``` +$ cat /proc/sys/kernel/randomize_va_space +2 +$ sysctl -a --pattern randomize +kernel.randomize_va_space = 2 +``` + +上方指令结果中的数值(`2`)表示 ASLR 工作在全随机化模式。其可能为下面的几个数值之一: + +``` +0 = Disabled +1 = Conservative Randomization +2 = Full Randomization +``` + +如果你关闭了 ASLR 并且执行下面的指令,你将会注意到前后两条 `ldd` 的输出是完全一样的。`ldd` 命令会加载共享对象并显示它们在内存中的地址。 + +``` +$ sudo sysctl -w kernel.randomize_va_space=0 <== disable +[sudo] password for shs: +kernel.randomize_va_space = 0 +$ ldd /bin/bash + linux-vdso.so.1 (0x00007ffff7fd1000) <== same addresses + libtinfo.so.6 => /lib/x86_64-linux-gnu/libtinfo.so.6 (0x00007ffff7c69000) + libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007ffff7c63000) + libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007ffff7a79000) + /lib64/ld-linux-x86-64.so.2 (0x00007ffff7fd3000) +$ ldd /bin/bash + linux-vdso.so.1 (0x00007ffff7fd1000) <== same addresses + libtinfo.so.6 => /lib/x86_64-linux-gnu/libtinfo.so.6 (0x00007ffff7c69000) + libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007ffff7c63000) + libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007ffff7a79000) + /lib64/ld-linux-x86-64.so.2 (0x00007ffff7fd3000) +``` + +如果将其重新设置为 `2` 来启用 ASLR,你将会看到每次运行 `ldd`,得到的内存地址都不相同。 + +``` +$ sudo sysctl -w kernel.randomize_va_space=2 <== enable +[sudo] password for shs: +kernel.randomize_va_space = 2 +$ ldd /bin/bash + linux-vdso.so.1 (0x00007fff47d0e000) <== first set of addresses + libtinfo.so.6 => /lib/x86_64-linux-gnu/libtinfo.so.6 (0x00007f1cb7ce0000) + libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f1cb7cda000) + libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f1cb7af0000) + /lib64/ld-linux-x86-64.so.2 (0x00007f1cb8045000) +$ ldd /bin/bash + linux-vdso.so.1 (0x00007ffe1cbd7000) <== second set of addresses + libtinfo.so.6 => /lib/x86_64-linux-gnu/libtinfo.so.6 (0x00007fed59742000) + libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fed5973c000) + libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fed59552000) + /lib64/ld-linux-x86-64.so.2 (0x00007fed59aa7000) +``` + +### 尝试绕过 ASLR + +尽管这项技术有很多优点,但绕过 ASLR 的攻击并不罕见,主要有以下几类: + + * 利用地址泄露 + * 访问与特定地址关联的数据 + * 针对 ASLR 实现的缺陷来猜测地址,常见于系统熵过低或 ASLR 实现不完善。 + * 利用侧信道攻击 + +### 总结 + +ASLR 有很大的价值,尤其是在 64 位系统上运行并被正确实现时。虽然不能避免被绕过,但这项技术的确使得利用系统漏洞变得更加困难了。这份参考资料可以提供 [在 64 位 Linux 系统上的完全 ASLR 的有效性][2] 的更多有关细节,这篇论文介绍了一种利用分支预测 [绕过 ASLR][3] 的技术。 + +-------------------------------------------------------------------------------- + +via: https://www.networkworld.com/article/3331199/linux/what-does-aslr-do-for-linux.html + +作者:[Sandra Henry-Stocker][a] +选题:[lujun9972][b] +译者:[leommxj](https://github.com/leommxj) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]: https://www.networkworld.com/author/Sandra-Henry_Stocker/ +[b]: https://github.com/lujun9972 +[1]: https://www.networkworld.com/article/3242170/linux/invaluable-tips-and-tricks-for-troubleshooting-linux.html +[2]: https://cybersecurity.upv.es/attacks/offset2lib/offset2lib-paper.pdf +[3]: http://www.cs.ucr.edu/~nael/pubs/micro16.pdf +[4]: https://www.facebook.com/NetworkWorld/ +[5]: https://www.linkedin.com/company/network-world diff --git a/published/20190109 Configure Anaconda on Emacs - iD.md b/published/20190109 Configure Anaconda on Emacs - iD.md new file mode 100644 index 0000000000..5c6125e2e9 --- /dev/null +++ b/published/20190109 Configure Anaconda on Emacs - iD.md @@ -0,0 +1,116 @@ +[#]: collector: (lujun9972) +[#]: translator: (lujun9972) +[#]: reviewer: (wxy) +[#]: publisher: (wxy) +[#]: url: (https://linux.cn/article-10604-1.html) +[#]: subject: (Configure Anaconda on Emacs – iD) +[#]: via: (https://idevji.com/configure-anaconda-on-emacs/) +[#]: author: (Devji Chhanga https://idevji.com/author/admin/) + +在 Emacs 上配置 Anaconda +====== + +也许我所追求的究极 IDE 就是 [Emacs][1] 了。我的目标是使 Emacs 成为一款全能的 Python IDE。本文描述了如何在 Emacs 上配置 Anaconda。(LCTT 译注:Anaconda 自称“世界上最流行的 Python/R 的数据分析平台”) + +我的配置信息: + +- OS:Trisquel 8.0 +- Emacs:GNU Emacs 25.3.2 + +快捷键说明([参见完全指南][2]): + +``` +C-x = Ctrl + x +M-x = Alt + x +RET = ENTER +``` + +### 1、下载并安装 Anaconda + +#### 1.1 下载 + +[从这儿][3] 下载 Anaconda。你应该下载 Python 3.x 的版本,因为 Python 2 在 2020 年就不再支持了。你无需预先安装 Python 3.x。这个安装脚本会自动安装它。 + +#### 1.2 安装 + +``` +cd ~/Downloads +bash Anaconda3-2018.12-Linux-x86.sh +``` + +### 2、将 Anaconda 添加到 Emacs + +#### 2.1 将 MELPA 添加到 Emacs + +我们需要用到 `anaconda-mode` 这个 Emacs 包。该包位于 MELPA 仓库中。Emacs25 需要手工添加该仓库。 + +- [注意:点击本文查看如何将 MELPA 添加到 Emacs][4] + +#### 2.2 为 Emacs 安装 anaconda-mode 包 + +``` +M-x package-install RET +anaconda-mode RET +``` + +#### 2.3 为 Emacs 配置 anaconda-mode + +``` +echo "(add-hook 'python-mode-hook 'anaconda-mode)" > ~/.emacs.d/init.el +``` + +### 3、在 Emacs 上通过 Anaconda 运行你第一个脚本 + +#### 3.1 创建新 .py 文件 + +``` +C-x C-f +HelloWorld.py RET +``` + +#### 3.2 输入下面代码 + +``` +print ("Hello World from Emacs") +``` + +#### 3.3 运行之 + +``` +C-c C-p +C-c C-c +``` + +输出为: + +``` +Python 3.7.1 (default, Dec 14 2018, 19:46:24) +[GCC 7.3.0] :: Anaconda, Inc. on linux +Type "help", "copyright", "credits" or "license" for more information. +>>> python.el: native completion setup loaded +>>> Hello World from Emacs +>>> +``` + +我是受到 [Codingquark][5] 的影响才开始使用 Emacs 的。 + +有任何错误和遗漏请在评论中写下。干杯! + +-------------------------------------------------------------------------------- + +via: https://idevji.com/configure-anaconda-on-emacs/ + +作者:[Devji Chhanga][a] +选题:[lujun9972][b] +译者:[lujun9972](https://github.com/lujun9972) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]: https://idevji.com/author/admin/ +[b]: https://github.com/lujun9972 +[1]: https://www.gnu.org/software/emacs/ +[2]: https://www.math.uh.edu/~bgb/emacs_keys.html +[3]: https://www.anaconda.com/download/#linux +[4]: https://melpa.org/#/getting-started +[5]: https://codingquark.com diff --git a/published/20190116 Get started with Cypht, an open source email client.md b/published/20190116 Get started with Cypht, an open source email client.md new file mode 100644 index 0000000000..b14eabca16 --- /dev/null +++ b/published/20190116 Get started with Cypht, an open source email client.md @@ -0,0 +1,59 @@ +[#]: collector: (lujun9972) +[#]: translator: (geekpi) +[#]: reviewer: (wxy) +[#]: publisher: (wxy) +[#]: url: (https://linux.cn/article-10642-1.html) +[#]: subject: (Get started with Cypht, an open source email client) +[#]: via: (https://opensource.com/article/19/1/productivity-tool-cypht-email) +[#]: author: (Kevin Sonney https://opensource.com/users/ksonney (Kevin Sonney)) + +开始使用 Cypht 吧,一个开源的电子邮件客户端 +====== + +> 使用 Cypht 将你的电子邮件和新闻源集成到一个界面中,这是我们 19 个开源工具系列中的第 4 个,它将使你在 2019 年更高效。 + +![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/email_mail_box_envelope_send_blue.jpg?itok=6Epj47H6) + +每年年初似乎都有疯狂的冲动想提高工作效率。新年的决心,渴望开启新的一年,当然,“抛弃旧的,拥抱新的”的态度促成了这一切。通常这时的建议严重偏向闭源和专有软件,但事实上并不用这样。 + +这是我挑选出的 19 个新的(或者对你而言新的)开源工具中的第 4 个工具来帮助你在 2019 年更有效率。 + +### Cypht + +我们花了很多时间来处理电子邮件,有效地[管理你的电子邮件][1]可以对你的工作效率产生巨大影响。像 Thunderbird、Kontact/KMail 和 Evolution 这样的程序似乎都有一个共同点:它们试图复制 Microsoft Outlook 的功能,这在过去 10 年左右并没有真正改变。在过去十年中,甚至像 Mutt 和 Cone 这样的[著名控制台程序][2]也没有太大变化。 + +![](https://opensource.com/sites/default/files/uploads/cypht-1.png) + +[Cypht][3] 是一个简单、轻量级和现代的 Webmail 客户端,它将多个帐户聚合到一个界面中。除了电子邮件帐户,它还包括 Atom/RSS 源。在 “Everything” 中,不仅可以显示收件箱中的邮件,还可以显示新闻源中的最新文章,从而使得阅读不同来源的内容变得简单。 + +![](https://opensource.com/sites/default/files/uploads/cypht-2.png) + +它使用简化的 HTML 消息来显示邮件,或者你也可以将其设置为查看纯文本版本。由于 Cypht 不会加载远程图像(以帮助维护安全性),HTML 渲染可能有点粗糙,但它足以完成工作。你将看到包含大量富文本邮件的纯文本视图 —— 这意味着很多链接并且难以阅读。我不会说是 Cypht 的问题,因为这确实是发件人所做的,但它确实降低了阅读体验。阅读新闻源大致相同,但它们与你的电子邮件帐户集成,这意味着可以轻松获取最新的(我有时会遇到问题)。 + +![](https://opensource.com/sites/default/files/uploads/cypht-3.png) + +用户可以使用预配置的邮件服务器并添加他们使用的任何其他服务器。Cypht 的自定义选项包括纯文本与 HTML 邮件显示,它支持多个配置文件以及更改主题(并自行创建)。你要记得单击左侧导航栏上的“保存”按钮,否则你的自定义设置将在该会话后消失。如果你在不保存的情况下注销并重新登录,那么所有更改都将丢失,你将获得开始时的设置。因此可以轻松地实验,如果你需要重置,只需在不保存的情况下注销,那么在再次登录时就会看到之前的配置。 + +![](https://opensource.com/sites/default/files/pictures/cypht-4.png) + +本地[安装 Cypht][4] 非常容易。虽然它不使用容器或类似技术,但安装说明非常清晰且易于遵循,并且不需要我做任何更改。在我的笔记本上,从安装开始到首次登录大约需要 10 分钟。服务器上的共享安装使用相同的步骤,因此它应该大致相同。 + +最后,Cypht 是桌面和基于 Web 的电子邮件客户端的绝佳替代方案,它有简单的界面,可帮助你快速有效地处理电子邮件。 + +-------------------------------------------------------------------------------- + +via: https://opensource.com/article/19/1/productivity-tool-cypht-email + +作者:[Kevin Sonney][a] +选题:[lujun9972][b] +译者:[geekpi](https://github.com/geekpi) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]: https://opensource.com/users/ksonney (Kevin Sonney) +[b]: https://github.com/lujun9972 +[1]: https://opensource.com/article/17/7/email-alternatives-thunderbird +[2]: https://opensource.com/life/15/8/top-4-open-source-command-line-email-clients +[3]: https://cypht.org/ +[4]: https://cypht.org/install.html diff --git a/published/20190117 Get started with CryptPad, an open source collaborative document editor.md b/published/20190117 Get started with CryptPad, an open source collaborative document editor.md new file mode 100644 index 0000000000..74430b642d --- /dev/null +++ b/published/20190117 Get started with CryptPad, an open source collaborative document editor.md @@ -0,0 +1,60 @@ +[#]: collector: (lujun9972) +[#]: translator: (geekpi) +[#]: reviewer: (wxy) +[#]: publisher: (wxy) +[#]: url: (https://linux.cn/article-10636-1.html) +[#]: subject: (Get started with CryptPad, an open source collaborative document editor) +[#]: via: (https://opensource.com/article/19/1/productivity-tool-cryptpad) +[#]: author: (Kevin Sonney https://opensource.com/users/ksonney (Kevin Sonney)) + +开始使用 CryptPad 吧,一个开源的协作文档编辑器 +====== + +> 使用 CryptPad 安全地共享你的笔记、文档、看板等,这是我们在开源工具系列中的第 5 个工具,它将使你在 2019 年更高效。 + +![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/web_browser_desktop_devlopment_design_system_computer.jpg?itok=pfqRrJgh) + +每年年初似乎都有疯狂的冲动想提高工作效率。新年的决心,渴望开启新的一年,当然,“抛弃旧的,拥抱新的”的态度促成了这一切。通常这时的建议严重偏向闭源和专有软件,但事实上并不用这样。 + +这是我挑选出的 19 个新的(或者对你而言新的)开源工具中的第 5 个工具来帮助你在 2019 年更有效率。 + +### CryptPad + +我们已经介绍过 [Joplin][1],它能很好地保存自己的笔记,但是,你可能已经注意到,它没有任何共享或协作功能。 + +[CryptPad][2] 是一个安全、可共享的笔记应用和文档编辑器,它能够安全地协作编辑。与 Joplin 不同,它是一个 NodeJS 应用,这意味着你可以在桌面或其他服务器上运行它,并使用任何现代 Web 浏览器访问。它开箱即用,它支持富文本、Markdown、投票、白板,看板和 PPT。 + +![](https://opensource.com/sites/default/files/uploads/cryptpad-1.png) + +它支持不同的文档类型且功能齐全。它的富文本编辑器涵盖了你所期望的所有基础功能,并允许你将文件导出为 HTML。它的 Markdown 的编辑能与 Joplin 相提并论,它的看板虽然不像 [Wekan][3] 那样功能齐全,但也做得不错。其他支持的文档类型和编辑器也很不错,并且有你希望在类似应用中看到的功能,尽管投票功能显得有些粗糙。 + +![](https://opensource.com/sites/default/files/uploads/cryptpad-2.png) + +然而,CryptPad 的真正强大之处在于它的共享和协作功能。共享文档只需在“共享”选项中获取可共享 URL,CryptPad 支持使用 `