From 730d08333dc0d068abe0d592e81030fdc7d77591 Mon Sep 17 00:00:00 2001 From: Brooke Lau Date: Tue, 10 Dec 2019 01:34:48 +0800 Subject: [PATCH 1/5] translating --- ... Logical operators and shell expansions.md | 116 +++++++++--------- 1 file changed, 60 insertions(+), 56 deletions(-) diff --git a/sources/tech/20191022 How to program with Bash- Logical operators and shell expansions.md b/sources/tech/20191022 How to program with Bash- Logical operators and shell expansions.md index 5cfef23305..a12d370214 100644 --- a/sources/tech/20191022 How to program with Bash- Logical operators and shell expansions.md +++ b/sources/tech/20191022 How to program with Bash- Logical operators and shell expansions.md @@ -1,29 +1,29 @@ -[#]: collector: (lujun9972) -[#]: translator: (lxbwolf) -[#]: reviewer: ( ) -[#]: publisher: ( ) -[#]: url: ( ) -[#]: subject: (How to program with Bash: Logical operators and shell expansions) -[#]: via: (https://opensource.com/article/19/10/programming-bash-logical-operators-shell-expansions) -[#]: author: (David Both https://opensource.com/users/dboth) +[#]: collector: "lujun9972" +[#]: translator: "lxbwolf" +[#]: reviewer: " " +[#]: publisher: " " +[#]: url: " " +[#]: subject: "How to program with Bash: Logical operators and shell expansions" +[#]: via: "https://opensource.com/article/19/10/programming-bash-logical-operators-shell-expansions" +[#]: author: "David Both https://opensource.com/users/dboth" -How to program with Bash: Logical operators and shell expansions +Bash 编程教程:逻辑操作符和 shell 扩展 ====== -Learn about logical operators and shell expansions, in the second -article in this three-part series on programming with Bash. + +学习逻辑操作符和 shell 扩展,本文是Bash 编程系列(三篇文章)的第二篇。 ![Women in computing and open source v5][1] -Bash is a powerful programming language, one perfectly designed for use on the command line and in shell scripts. This three-part series (which is based on my [three-volume Linux self-study course][2]) explores using Bash as a programming language on the command-line interface (CLI). +Bash 是一种强大的编程语言,完美契合命令行和 shell 脚本。本系列(三篇文章,基于我的 [Linux 自学课程三卷][2])讲解如何在 CLI 使用 Bash 编程。 -The [first article][3] explored some simple command-line programming with Bash, including using variables and control operators. This second article looks into the types of file, string, numeric, and miscellaneous logical operators that provide execution-flow control logic and different types of shell expansions in Bash. The third and final article in the series will explore the **for**, **while**, and **until** loops that enable repetitive operations. +[第一篇文章][3] 讲解了 Bash 的一些简单命令行操作,包括如何使用变量和控制操作符。第二篇文章探讨文件、字符串、数字等类型和各种各样在执行流中提供控制逻辑的的逻辑运算符,还有 Bash 中的各类 shell 扩展。本系列第三篇也是最后一篇文章,将会探索能重复执行操作的 **for** 、**while** 和 **until** 循环。 -Logical operators are the basis for making decisions in a program and executing different sets of instructions based on those decisions. This is sometimes called flow control. +逻辑操作符是程序中判断的根本要素,也是执行不同的语句组合的依据。有时这也被称为流控制。 -### Logical operators +### 逻辑操作符 -Bash has a large set of logical operators that can be used in conditional expressions. The most basic form of the **if** control structure tests for a condition and then executes a list of program statements if the condition is true. There are three types of operators: file, numeric, and non-numeric operators. Each operator returns true (0) if the condition is met and false (1) if the condition is not met. +Bash 中有大量的用于不同条件表达式的逻辑操作符。最基本的是 **if** 控制结构,它判断一个条件,如果条件为真,就执行一些了程序语句。操作符共有三类:文件,数字和非数字操作符。如果条件为真,所有的操作符返回 true(0),如果条件为假,返回 false (1)。 -The functional syntax of these comparison operators is one or two arguments with an operator that are placed within square braces, followed by a list of program statements that are executed if the condition is true, and an optional list of program statements if the condition is false: +这些比较操作符的函数语法是,一个操作符加一个或两个参数放在中括号内,后面跟一系列程序语句,如果条件为真,程序语句执行,可能会有另一个程序语句 list,该 list 在条件为假时执行: ``` @@ -32,54 +32,54 @@ or if [ arg1 operator arg2 ] ; then list ; else list ; fi ``` -The spaces in the comparison are required as shown. The single square braces, **[** and **]**, are the traditional Bash symbols that are equivalent to the **test** command: +像例子中那样,在比较表达式中,空格不能省略。中括号的每部分,**[** 和 **]**,是跟 **test** 命令一样的传统的 Bash 符号: ``` `if test arg1 operator arg2 ; then list` ``` -There is also a more recent syntax that offers a few advantages and that some sysadmins prefer. This format is a bit less compatible with different versions of Bash and other shells, such as ksh (the Korn shell). It looks like: +还有一个更新的语法能提供一点点便利,一些系统管理员比较喜欢用。这种格式对于不同版本的 Bash 和一些 shell 如 ksh(the Korn shell)兼容性稍差。格式如下: ``` `if [[ arg1 operator arg2 ]] ; then list` ``` -#### File operators +#### 文件操作符 -File operators are a powerful set of logical operators within Bash. Figure 1 lists more than 20 different operators that Bash can perform on files. I use them quite frequently in my scripts. +文件操作符是 Bash 中一系列强大的逻辑操作符。图表1列出了 20 多种不同的 Bash 处理文件的操作符。在我的脚本中使用频率很高。 Operator | Description ---|--- --a filename | True if the file exists; it can be empty or have some content but, so long as it exists, this will be true --b filename | True if the file exists and is a block special file such as a hard drive like **/dev/sda** or **/dev/sda1** --c filename | True if the file exists and is a character special file such as a TTY device like **/dev/TTY1** --d filename | True if the file exists and is a directory --e filename | True if the file exists; this is the same as **-a** above --f filename | True if the file exists and is a regular file, as opposed to a directory, a device special file, or a link, among others --g filename | True if the file exists and is **set-group-id**, **SETGID** +-a filename | 如果文件存在,返回 true;文件可以为空也可以有内容,但是只要它存在,就返回 true +-b filename | 如果文件存在且是一个块设备如**/dev/sda** or **/dev/sda1**,则返回 true +-c filename | 如果文件存在且是一个字符设备如**/dev/TTY1**,则返回 true +-d filename | 文件存在且是一个目录,返回 true +-e filename | 文件存在,返回 true;与上面的 **-a** 相同 +-f filename | 文件存在且是一个一般文件,不是目录、设备文件或链接等的其他的文件,则返回 true +-g filename | 文件存在且 **SETGID** 标记被设置在其上,返回 true -h filename | True if the file exists and is a symbolic link -k filename | True if the file exists and its "sticky'" bit is set --p filename | True if the file exists and is a named pipe (FIFO) --r filename | True if the file exists and is readable, i.e., has its read bit set --s filename | True if the file exists and has a size greater than zero; a file that exists but that has a size of zero will return false --t fd | True if the file descriptor **fd** is open and refers to a terminal --u filename | True if the file exists and its **set-user-id** bit is set --w filename | True if the file exists and is writable --x filename | True if the file exists and is executable --G filename | True if the file exists and is owned by the effective group ID --L filename | True if the file exists and is a symbolic link --N filename | True if the file exists and has been modified since it was last read --O filename | True if the file exists and is owned by the effective user ID +-p filename | 文件存在且是一个命名的管道(FIFO),返回 true +-r filename | 文件存在且有可读权限,如它的可读位被设置,返回 true +-s filename | 文件存在且大小大于 0,返回 true;如果一个文件存在但大小为 0,则返回 false +-t fd | 文件描述符 **fd** 被打开且被关联到一个终端设备上,返回 true +-u filename | 文件存在且它的**set-user-id** 位被设置,返回 true +-w filename | 文件存在且有可写权限,返回 true +-x filename | 文件存在且有可执行权限,返回 true +-G filename | 文件存在且文件的 group ID 与当前用户相同,返回 true +-L filename | 文件存在且是一个符号链接,返回 true +-N filename | 文件存在且从文件上一次被读取到现在为止, 文件被修改过,返回 true +-O filename | 文件存在且你是文件的拥有者,返回 true -S filename | True if the file exists and is a socket -file1 -ef file2 | True if file1 and file2 refer to the same device and iNode numbers -file1 -nt file2 | True if file1 is newer (according to modification date) than file2, or if file1 exists and file2 does not -file1 -ot file2 | True if file1 is older than file2, or if file2 exists and file1 does not +file1 -ef file2 | 文件`file1`和 文件`file2`是相同文件的硬链接,返回 true +file1 -nt file2 | 文件 file1 比 file2 新(根据修改日期),或 file1 存在而 file2 不存在 +file1 -ot file2 | 文件 file1 比 file2 旧(根据修改日期),或 file1 不存在而 file2 存在 -_**Fig. 1: The Bash file operators**_ +_**Fig.1:Bash 文件操作符**_ -As an example, start by testing for the existence of a file: +以测试一个文件存在与否来举例: ``` @@ -88,14 +88,14 @@ The file TestFile1 does not exist. [student@studentvm1 testdir]$ ``` -Next, create a file for testing named **TestFile1**. For now, it does not need to contain any data: +创建一个用来测试的文件,命名为 **TestFile1**。目前它不需要包含任何数据: ``` `[student@studentvm1 testdir]$ touch TestFile1` ``` -It is easy to change the value of the **$File** variable rather than a text string for the file name in multiple locations in this short CLI program: +在这个简短的 CLI 程序中, 修改 **$File** 变量的值相比于在多个地方修改表示文件名的字符串的值要容易: ``` @@ -104,7 +104,7 @@ The file TestFile1 exists. [student@studentvm1 testdir]$ ``` -Now, run a test to determine whether a file exists and has a non-zero length, which means it contains data. You want to test for three conditions: 1. the file does not exist; 2. the file exists and is empty; and 3. the file exists and contains data. Therefore, you need a more complex set of tests—use the **elif** stanza in the **if-elif-else** construct to test for all of the conditions: +现在,运行一个测试来判断一个文件是否存在且长度不为 0(表示它包含数据)。假设你想判断三种情况:1. 文件不存在;2. 文件存在且为空;3. 文件存在且包含数据。因此,你需要一组更负责的测试代码 — 为了测试所有的情况在 **if-elif-else** 结构中使用 **elif** 语句: ``` @@ -112,16 +112,16 @@ Now, run a test to determine whether a file exists and has a non-zero length, wh [student@studentvm1 testdir]$ ``` -In this case, the file exists but does not contain any data. Add some data and try again: +在本案例中,文件存在但不包含任何数据。向文件添加一些数据再运行一次: ``` -[student@studentvm1 testdir]$ File="TestFile1" ; echo "This is file $File" > $File ; if [ -s $File ] ; then echo "$File exists and contains data." ; fi +[student@studentvm1 testdir]$ File="TestFile1" ; echo "This is file $File" > $File ; if [ -s $File ] ; then echo "$File exists and contains data." ; fi TestFile1 exists and contains data. [student@studentvm1 testdir]$ ``` -That works, but it is only truly accurate for one specific condition out of the three possible ones. Add an **else** stanza so you can be somewhat more accurate, and delete the file so you can fully test this new code: +这组语句能返回正常的结果,但是仅仅是在我们已知三种可能的情况下测试某种确切的条件。添加一段 **else** 语句,这样你就可以更精确地测试。把文件删掉,你就可以完整地测试这段新代码: ``` @@ -129,7 +129,7 @@ That works, but it is only truly accurate for one specific condition out of the TestFile1 does not exist or is empty. ``` -Now create an empty file to test: +现在创建一个空文件用来测试: ``` @@ -137,7 +137,7 @@ Now create an empty file to test: TestFile1 does not exist or is empty. ``` -Add some content to the file and test again: +向文件添加一些内容,然后再测试一次: ``` @@ -145,7 +145,7 @@ Add some content to the file and test again: TestFile1 exists and contains data. ``` -Now, add the **elif** stanza to discriminate between a file that does not exist and one that is empty: +现在加入 **elif** 语句来辨别是文件不存在还是文件为空: ``` @@ -160,6 +160,10 @@ Now you have a Bash CLI program that can test for these three different conditio It is easier to see the logic structure of the more complex compound commands if you arrange the program statements more like you would in a script that you can save in a file. Figure 2 shows how this would look. The indents of the program statements in each stanza of the **if-elif-else** structure help to clarify the logic. +现在你有一个可以测试这三种情况的 Bash CLI 程序,但是可能的情况是无限的。 + +如果你能像保存在文件中的脚本那样书写程序语句,那么对于即使更复杂的命令组合也会很容易看出它们的逻辑结构。图表 2 就是一个示例。 **if-elif-else** 结构中每一部分的程序语句的缩进让逻辑更变得清晰。 + ``` File="TestFile1" @@ -175,9 +179,9 @@ else fi ``` -_**Fig. 2: The command line program rewritten as it would appear in a script**_ +_**Fig. 2: 像在脚本里一样重写书写命令行程序**_ -Logic this complex is too lengthy for most CLI programs. Although any Linux or Bash built-in commands may be used in CLI programs, as the CLI programs get longer and more complex, it makes more sense to create a script that is stored in a file and can be executed at any time, now or in the future. +对于大多数 CLI 程序来说,让这些复杂的命令变得有逻辑需要写很长的代码。虽然 CLI 可能是用 Linux 或 Bash 内置的命令,但是当 CLI 程序很长或很复杂时,创建一个脚本保存在一个文件中将更有效,保存到文件中后,可以随时运行。 #### String comparison operators @@ -493,6 +497,6 @@ via: https://opensource.com/article/19/10/programming-bash-logical-operators-she [a]: https://opensource.com/users/dboth [b]: https://github.com/lujun9972 -[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/OSDC_women_computing_5.png?itok=YHpNs_ss (Women in computing and open source v5) +[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/OSDC_women_computing_5.png?itok=YHpNs_ss "Women in computing and open source v5" [2]: http://www.both.org/?page_id=1183 [3]: https://opensource.com/article/19/10/programming-bash-part-1 From 79ffaa273682448a192a0d722a7b23bde070a539 Mon Sep 17 00:00:00 2001 From: Brooke Lau Date: Wed, 11 Dec 2019 12:12:06 +0800 Subject: [PATCH 2/5] translated --- ... Logical operators and shell expansions.md | 211 +++++++++--------- 1 file changed, 102 insertions(+), 109 deletions(-) diff --git a/sources/tech/20191022 How to program with Bash- Logical operators and shell expansions.md b/sources/tech/20191022 How to program with Bash- Logical operators and shell expansions.md index a12d370214..4e6fd82862 100644 --- a/sources/tech/20191022 How to program with Bash- Logical operators and shell expansions.md +++ b/sources/tech/20191022 How to program with Bash- Logical operators and shell expansions.md @@ -21,7 +21,7 @@ Bash 是一种强大的编程语言,完美契合命令行和 shell 脚本。 ### 逻辑操作符 -Bash 中有大量的用于不同条件表达式的逻辑操作符。最基本的是 **if** 控制结构,它判断一个条件,如果条件为真,就执行一些了程序语句。操作符共有三类:文件,数字和非数字操作符。如果条件为真,所有的操作符返回 true(0),如果条件为假,返回 false (1)。 +Bash 中有大量的用于不同条件表达式的逻辑操作符。最基本的是 **if** 控制结构,它判断一个条件,如果条件为真,就执行一些程序语句。操作符共有三类:文件,数字和非数字操作符。如果条件为真,所有的操作符返回 true(0),如果条件为假,返回 false(1)。 这些比较操作符的函数语法是,一个操作符加一个或两个参数放在中括号内,后面跟一系列程序语句,如果条件为真,程序语句执行,可能会有另一个程序语句 list,该 list 在条件为假时执行: @@ -48,34 +48,34 @@ if [ arg1 operator arg2 ] ; then list ; else list ; fi #### 文件操作符 -文件操作符是 Bash 中一系列强大的逻辑操作符。图表1列出了 20 多种不同的 Bash 处理文件的操作符。在我的脚本中使用频率很高。 +文件操作符是 Bash 中一系列强大的逻辑操作符。图表 1 列出了 20 多种不同的 Bash 处理文件的操作符。在我的脚本中使用频率很高。 Operator | Description ---|--- -a filename | 如果文件存在,返回 true;文件可以为空也可以有内容,但是只要它存在,就返回 true -b filename | 如果文件存在且是一个块设备如**/dev/sda** or **/dev/sda1**,则返回 true -c filename | 如果文件存在且是一个字符设备如**/dev/TTY1**,则返回 true --d filename | 文件存在且是一个目录,返回 true --e filename | 文件存在,返回 true;与上面的 **-a** 相同 --f filename | 文件存在且是一个一般文件,不是目录、设备文件或链接等的其他的文件,则返回 true --g filename | 文件存在且 **SETGID** 标记被设置在其上,返回 true --h filename | True if the file exists and is a symbolic link --k filename | True if the file exists and its "sticky'" bit is set --p filename | 文件存在且是一个命名的管道(FIFO),返回 true --r filename | 文件存在且有可读权限,如它的可读位被设置,返回 true --s filename | 文件存在且大小大于 0,返回 true;如果一个文件存在但大小为 0,则返回 false --t fd | 文件描述符 **fd** 被打开且被关联到一个终端设备上,返回 true --u filename | 文件存在且它的**set-user-id** 位被设置,返回 true --w filename | 文件存在且有可写权限,返回 true --x filename | 文件存在且有可执行权限,返回 true --G filename | 文件存在且文件的 group ID 与当前用户相同,返回 true --L filename | 文件存在且是一个符号链接,返回 true --N filename | 文件存在且从文件上一次被读取到现在为止, 文件被修改过,返回 true --O filename | 文件存在且你是文件的拥有者,返回 true +-d filename | 如果文件存在且是一个目录,返回 true +-e filename | 如果文件存在,返回 true;与上面的 **-a** 相同 +-f filename | 如果文件存在且是一个一般文件,不是目录、设备文件或链接等的其他的文件,则返回 true +-g filename | 如果文件存在且 **SETGID** 标记被设置在其上,返回 true +-h filename | 如果文件存在且是一个符号链接,则返回 true +-k filename | 如果文件存在且粘贴位已设置,则返回 true +-p filename | 如果文件存在且是一个命名的管道(FIFO),返回 true +-r filename | 如果文件存在且有可读权限,如它的可读位被设置,返回 true +-s filename | 如果文件存在且大小大于 0,返回 true;如果一个文件存在但大小为 0,则返回 false +-t fd | 如果文件描述符 **fd** 被打开且被关联到一个终端设备上,返回 true +-u filename | 如果文件存在且它的 **set-user-id** 位被设置,返回 true +-w filename | 如果文件存在且有可写权限,返回 true +-x filename | 如果文件存在且有可执行权限,返回 true +-G filename | 如果文件存在且文件的 group ID 与当前用户相同,返回 true +-L filename | 如果文件存在且是一个符号链接,返回 true +-N filename | 如果文件存在且从文件上一次被读取到现在为止, 文件被修改过,返回 true +-O filename | 如果文件存在且你是文件的拥有者,返回 true -S filename | True if the file exists and is a socket -file1 -ef file2 | 文件`file1`和 文件`file2`是相同文件的硬链接,返回 true -file1 -nt file2 | 文件 file1 比 file2 新(根据修改日期),或 file1 存在而 file2 不存在 -file1 -ot file2 | 文件 file1 比 file2 旧(根据修改日期),或 file1 不存在而 file2 存在 +file1 -ef file2 | 如果文件`file1`和 文件`file2`是相同文件的硬链接,返回 true +file1 -nt file2 | 如果文件 file1 比 file2 新(根据修改日期),或 file1 存在而 file2 不存在 +file1 -ot file2 | 如果文件 file1 比 file2 旧(根据修改日期),或 file1 不存在而 file2 存在 _**Fig.1:Bash 文件操作符**_ @@ -88,14 +88,14 @@ The file TestFile1 does not exist. [student@studentvm1 testdir]$ ``` -创建一个用来测试的文件,命名为 **TestFile1**。目前它不需要包含任何数据: +创建一个用来测试的文件,命名为 **TestFile1**。目前它不需要包含任何数据: ``` `[student@studentvm1 testdir]$ touch TestFile1` ``` -在这个简短的 CLI 程序中, 修改 **$File** 变量的值相比于在多个地方修改表示文件名的字符串的值要容易: +在这个简短的 CLI 程序中,修改 **$File** 变量的值相比于在多个地方修改表示文件名的字符串的值要容易: ``` @@ -104,7 +104,15 @@ The file TestFile1 exists. [student@studentvm1 testdir]$ ``` -现在,运行一个测试来判断一个文件是否存在且长度不为 0(表示它包含数据)。假设你想判断三种情况:1. 文件不存在;2. 文件存在且为空;3. 文件存在且包含数据。因此,你需要一组更负责的测试代码 — 为了测试所有的情况在 **if-elif-else** 结构中使用 **elif** 语句: +现在,运行一个测试来判断一个文件是否存在且长度不为 0(表示它包含数据)。假设你想判断三种情况: + +1. 文件不存在; + +2. 文件存在且为空; + +3. 文件存在且包含数据。 + + 因此,你需要一组更负责的测试代码 — 为了测试所有的情况在 **if-elif-else** 结构中使用 **elif** 语句: ``` @@ -156,10 +164,6 @@ TestFile1 exists and contains data. [student@studentvm1 testdir]$ ``` -Now you have a Bash CLI program that can test for these three different conditions… but the possibilities are endless. - -It is easier to see the logic structure of the more complex compound commands if you arrange the program statements more like you would in a script that you can save in a file. Figure 2 shows how this would look. The indents of the program statements in each stanza of the **if-elif-else** structure help to clarify the logic. - 现在你有一个可以测试这三种情况的 Bash CLI 程序,但是可能的情况是无限的。 如果你能像保存在文件中的脚本那样书写程序语句,那么对于即使更复杂的命令组合也会很容易看出它们的逻辑结构。图表 2 就是一个示例。 **if-elif-else** 结构中每一部分的程序语句的缩进让逻辑更变得清晰。 @@ -183,34 +187,31 @@ _**Fig. 2: 像在脚本里一样重写书写命令行程序**_ 对于大多数 CLI 程序来说,让这些复杂的命令变得有逻辑需要写很长的代码。虽然 CLI 可能是用 Linux 或 Bash 内置的命令,但是当 CLI 程序很长或很复杂时,创建一个脚本保存在一个文件中将更有效,保存到文件中后,可以随时运行。 -#### String comparison operators +#### 字符串比较操作符 -String comparison operators enable the comparison of alphanumeric strings of characters. There are only a few of these operators, which are listed in Figure 3. +字符串比较操作符使我们可以对字符串中的字符按字母顺序进行比较。图表 3 列出了仅有的几个字符串比较操作符。 Operator | Description ---|--- -z string | True if the length of string is zero -n string | True if the length of string is non-zero -string1 == string2 -or -string1 = string2 | True if the strings are equal; a single **=** should be used with the test command for POSIX conformance. When used with the **[[** command, this performs pattern matching as described above (compound commands). -string1 != string2 | True if the strings are not equal -string1 < string2 | True if string1 sorts before string2 lexicographically (refers to locale-specific sorting sequences for all alphanumeric and special characters) -string1 > string2 | True if string1 sorts after string2 lexicographically +string1 == string2
or
string1 = string2 | 如果两个字符串相等,返回 true。为了保持 POSIX 一致性,一个等号 **=** 应与 test 命令一起用。命令 **[[** 支持模式匹配,跟前面描述的一样(复杂命令)。 +string1 != string2 | 两个字符串不相等,返回 true +string1 < string2 | 如果对 string1 和 string2 按字母顺序进行排序,string1 排在 string2 前面(即基于地区设定的对所有字母和特殊字符的排列顺序) +string1 > string2 | 如果对 string1 和 string2 按字母顺序进行排序,string1 排在 string2 后面 +_**Fig. 3: Bash 字符串逻辑操作符**_ -_**Fig. 3: Bash string logical operators**_ - -First, look at string length. The quotes around **$MyVar** in the comparison must be there for the comparison to work. (You should still be working in **~/testdir**.) +首先,检查字符串长度。比较表达式中 **$MyVar** 两边的双引号不能省略(你仍应该在目录 **~/testdir** 下 )。 ``` -[student@studentvm1 testdir]$ MyVar="" ; if [ -z "" ] ; then echo "MyVar is zero length." ; else echo "MyVar contains data" ; fi +[student@studentvm1 testdir]$ MyVar="" ; if [ -z "$MyVar" ] ; then echo "MyVar is zero length." ; else echo "MyVar contains data" ; fi MyVar is zero length. -[student@studentvm1 testdir]$ MyVar="Random text" ; if [ -z "" ] ; then echo "MyVar is zero length." ; else echo "MyVar contains data" ; fi +[student@studentvm1 testdir]$ MyVar="Random text" ; if [ -z "$MyVar" ] ; then echo "MyVar is zero length." ; else echo "MyVar contains data" ; fi MyVar is zero length. ``` -You could also do it this way: +你也可以这样做: ``` @@ -220,7 +221,7 @@ MyVar contains data. MyVar is zero length ``` -Sometimes you may need to know a string's exact length. This is not a comparison, but it is related. Unfortunately, there is no simple way to determine the length of a string. There are a couple of ways to do it, but I think using the **expr** (evaluate expression) command is easiest. Read the man page for **expr** for more about what it can do. Note that quotes are required around the string or variable you're testing. +有时候你需要知道一个字符串确切的长度。这虽然不是比较,但是也与比较相关。不幸的是,计算字符串的长度没有简单的方法。有很多种方法可以计算,但是我认为使用 **expr**(evaluate expression,求值表达式)是相对最简单的一种。阅读 **expr** 的 man 主页可以了解更多相关知识。注意表达式中你检测的字符串或变量两边的引号不要省略。 ``` @@ -232,7 +233,7 @@ Sometimes you may need to know a string's exact length. This is not a comparison 70 ``` -Regarding comparison operators, I use a lot of testing in my scripts to determine whether two strings are equal (i.e., identical). I use the non-POSIX version of this comparison operator: +关于比较操作符,在我们的脚本中使用了大量的检测两个字符串是否相等(例如,两个字符串是否实际上是同一个字符串)的操作。我使用的是非 POSIX 版本的比较表达式: ``` @@ -242,24 +243,24 @@ Var1 matches Var2 Var1 and Var2 do not match. ``` -Experiment some more on your own to try out these operators. +在你自己的脚本中去试一下这些操作符。 -#### Numeric comparison operators +#### 数字比较操作符 -Numeric operators make comparisons between two numeric arguments. Like the other operator classes, most are easy to understand. +数字操作符用于两个数字参数之间的比较。像其他类操作符一样,大部分都很容易理解。 Operator | Description ---|--- arg1 -eq arg2 | True if arg1 equals arg2 -arg1 -ne arg2 | True if arg1 is not equal to arg2 -arg1 -lt arg2 | True if arg1 is less than arg2 -arg1 -le arg2 | True if arg1 is less than or equal to arg2 -arg1 -gt arg2 | True if arg1 is greater than arg2 -arg1 -ge arg2 | True if arg1 is greater than or equal to arg2 +arg1 -ne arg2 | 如果 arg1 不等于 arg2,返回 true +arg1 -lt arg2 | 如果 arg1 小于 arg2,返回 true +arg1 -le arg2 | 如果 arg1 小于或等于 arg2,返回 true +arg1 -gt arg2 | 如果 arg1 大于 arg2,返回 true +arg1 -ge arg2 | 如果 arg1 大于或等于 arg2,返回 true -_**Fig. 4: Bash numeric comparison logical operators**_ +_**Fig. 4: Bash 数字比较逻辑操作符**_ -Here are some simple examples. The first instance sets the variable **$X** to 1, then tests to see if **$X** is equal to 1. In the second instance, **X** is set to 0, so the comparison is not true. +来看几个简单的例子。第一个示例设置变量 **$X** 的值为 1,然后检测 **$X** 是否等于 1.第二个示例中, **$X** 被设置为 0,所以比较表达式返回结果不为 true。 ``` @@ -270,31 +271,31 @@ X does not equal 1 [student@studentvm1 testdir]$ ``` -Try some more experiments on your own. +自己来多尝试一下其他的。 -#### Miscellaneous operators +#### 混杂操作符 -These miscellaneous operators show whether a shell option is set or a shell variable has a value, but it does not discover the value of the variable, just whether it has one. +这些混杂操作符展示一个 shell 选项是否被设置或一个 shell 变量是否有值,但是它不显示变量的值,只显示它是否有值。 Operator | Description ---|--- --o optname | True if the shell option optname is enabled (see the list of options under the description of the **-o** option to the Bash set builtin in the Bash man page) --v varname | True if the shell variable varname is set (has been assigned a value) --R varname | True if the shell variable varname is set and is a name reference +-o optname | 如果一个选项 `optname` 开启了(查看 Bash 内建的 Bash man 页面中 **-o** 选项描述下面的选项列表),则返回 true +-v varname | 如果 shell 变量 varname 被设置了值(被赋予了值),则返回 true +-R varname | 如果一个 shell 变量 varname 被设置了值且是一个名字引用,则返回 true -_**Fig. 5: Miscellaneous Bash logical operators**_ +_**Fig. 5: 混杂 Bash 逻辑操作符**_ -Experiment on your own to try out these operators. +自己来使用这些操作符实践下。 -### Expansions +### 扩展 -Bash supports a number of types of expansions and substitutions that can be quite useful. According to the Bash man page, Bash has seven forms of expansions. This article looks at five of them: tilde expansion, arithmetic expansion, pathname expansion, brace expansion, and command substitution. +Bash 支持一些类型扩展和一些非常有用的命令替换。根据 Bash man 页面,Bash 有多种扩展格式。本文只介绍其中 5 种:`~` 扩展,算术扩展,路径名称扩展,大括号扩展和命令替换。 -#### Brace expansion +#### 大括号扩展 -Brace expansion is a method for generating arbitrary strings. (This tool is used below to create a large number of files for experiments with special pattern characters.) Brace expansion can be used to generate lists of arbitrary strings and insert them into a specific location within an enclosing static string or at either end of a static string. This may be hard to visualize, so it's best to just do it. +大括号扩展是生成任意字符串的一种方法。(下面的例子是用特定模式的字符创建大量的文件。)大括号扩展可以用于生产任意字符串的列表,并把它们插入一个静态字符串的中间特定位置或静态字符串的两端。这可能很难想象,所以还是来实践一下。 -First, here's what a brace expansion does: +首先,看一下大括号扩展的作用: ``` @@ -302,7 +303,7 @@ First, here's what a brace expansion does: string1 string2 string3 ``` -Well, that is not very helpful, is it? But look what happens when you use it just a bit differently: +看起来不是很有用,对吧?但是用其他方式使用它,再来看看: ``` @@ -310,7 +311,7 @@ Well, that is not very helpful, is it? But look what happens when you use it jus Hello David. Hello Jen. Hello Rikki. Hello Jason. ``` -That looks like something useful—it could save a good deal of typing. Now try this: +这看起来貌似有点用了 — 我们可以少打很多字。现在试一下这个: ``` @@ -318,13 +319,13 @@ That looks like something useful—it could save a good deal of typing. Now try beds bolts bars ``` -I could go on, but you get the idea. +我可以继续举例,但是你应该已经理解了它的用处。 -#### Tilde expansion +#### ~ 扩展 -Arguably, the most common expansion is the tilde (**~**) expansion. When you use this in a command like **cd ~/Documents**, the Bash shell expands it as a shortcut to the user's full home directory. +资料显示,使用最多的扩展是波浪字符(~)扩展。当你在命令中使用它(如 **cd ~/Documents**)时,Bash shell 把这个快捷方式展开式完整的 home 目录。 -Use these Bash programs to observe the effects of the tilde expansion: +使用 Bash 程序观察 ~ 扩展的作用: ``` @@ -337,16 +338,14 @@ Use these Bash programs to observe the effects of the tilde expansion: [student@studentvm1 Documents]$ ``` -#### Pathname expansion +#### 路径名称扩展 -Pathname expansion is a fancy term expanding file-globbing patterns, using the characters **?** and *****, into the full names of directories that match the pattern. File globbing refers to special pattern characters that enable significant flexibility in matching file names, directories, and other strings when performing various actions. These special pattern characters allow matching single, multiple, or specific characters in a string. +路径名称扩展是展开文件代换模式到匹配到的完成路径名称的另一种说法,匹配字符使用 **?** 和 **\*** 。文件代换指的是在大量操作中匹配文件名、路径和其他字符串时用特定的模式字符产生极大的灵活性。这些特定的模式字符允许匹配字符串中的一个、多个或特定字符。 - * **?** — Matches only one of any character in the specified location within the string - * ***** — Matches zero or more of any character in the specified location within the string + * **?** — 匹配字符串中特定位置的一个任意字符 + * ***** — 匹配字符串中特定位置的 0 个或多个任意字符 - - -This expansion is applied to matching directory names. To see how this works, ensure that **testdir** is the present working directory (PWD) and start with a plain listing (the contents of my home directory will be different from yours): +这个扩展用于匹配路径名称。为了弄清它的用法,请确保 **testdir** 是当前工作目录(PWD),先执行基本的列出清单命令 `ls`(我 home 目录下的内容跟你的不一样)。 ``` @@ -358,7 +357,7 @@ cpuHog     Desktop       dmesg.txt   link3      random.txt  testdir1 [student@studentvm1 testdir]$ ``` -Now list the directories that start with **Do**, **testdir/Documents**, and **testdir/Downloads**: +现在列出以 **Do**, **testdir/Documents**, 和 **testdir/Downloads** 开头的目录: ``` @@ -376,7 +375,7 @@ Downloads: [student@studentvm1 testdir]$ ``` -Well, that did not do what you wanted. It listed the contents of the directories that begin with **Do**. To list only the directories and not their contents, use the **-d** option. +然而,并没有得到你期望的结果。它列出了以 **Do** 开头的目录下的内容。使用 **-d** 选项,仅列出目录而不列出它们的内容。 ``` @@ -385,7 +384,7 @@ Documents  Downloads [student@studentvm1 testdir]$ ``` -In both cases, the Bash shell expands the **Do*** pattern into the names of the two directories that match the pattern. But what if there are also files that match the pattern? +在两个例子中,Bash shell 都把 **Do*** 模式展开成了匹配该模式的目录名称。但是如果有文件也匹配这个模式,会发生什么? ``` @@ -394,17 +393,17 @@ Documents  Downloads  Downtown [student@studentvm1 testdir]$ ``` -This shows the file, too. So any files that match the pattern are also expanded to their full names. +因此所有匹配这个模式的文件也被展开成了完成名字。 -#### Command substitution +#### 命令替换 -Command substitution is a form of expansion that allows the STDOUT data stream of one command to be used as the argument of another command; for example, as a list of items to be processed in a loop. The Bash man page says: "Command substitution allows the output of a command to replace the command name." I find that to be accurate if a bit obtuse. +命令替换让一个命令的 STDOUT 数据流被当做参数传给另一个命令,例如,在一个循环中作为一系列被处理的项目。Bash man 页面显示:”命令替换用命令的输出替换了命令的名字。“ 可能不太好理解。 -There are two forms of this substitution, **`command`** and **$(command)**. In the older form using back tics (**`**), using a backslash (**\**) in the command retains its literal meaning. However, when it's used in the newer parenthetical form, the backslash takes on its meaning as a special character. Note also that the parenthetical form uses only single parentheses to open and close the command statement. +命令替换有两种格式:**`command`** 和 **$(command)**。在更早的格式中使用反引号(**\`**),在命令中使用反斜杠(`\`)来保持它转义之前的文本含义。然而,当用在新版本的括号格式中时,反斜杠被当做一个特殊字符处理。也请注意带括号的格式打开个关闭命令语句都是用一个括号。 -I frequently use this capability in command-line programs and scripts where the results of one command can be used as an argument for another command. +我经常在命令行程序和脚本中出现一个命令的结果可以被作为参数传给另一个命令时使用命令替换。 -Start with a very simple example that uses both forms of this expansion (again, ensure that **testdir** is the PWD): +来看一个非常简单的示例,这个示例使用了这个扩展的两种格式(再一次提醒,确保 **testdir** 是当前工作目录): ``` @@ -415,9 +414,9 @@ Todays date is Sun Apr  7 14:42:59 EDT 2019 [student@studentvm1 testdir]$ ``` -The **-w** option to the **seq** utility adds leading zeros to the numbers generated so that they are all the same width, i.e., the same number of digits regardless of the value. This makes it easier to sort them in numeric sequence. +**-seq** 工具加上 **-w** 选项后,在生成的数字前面会用 0 补全,这样所有的结果都等宽,例如,忽略数字的值,它们的位数一样。这样在对它们按数字顺序进行排列时很容易。 -The **seq** utility is used to generate a sequence of numbers: +**-seq** 工具用于一个数字序列: ``` @@ -432,22 +431,20 @@ The **seq** utility is used to generate a sequence of numbers: [student@studentvm1 testdir]$ ``` -Now you can do something a bit more useful, like creating a large number of empty files for testing: +现在你可以做一些更有用处的操作,比如创建大量用于测试的空文件。 ``` `[student@studentvm1 testdir]$ for I in $(seq -w 5000) ; do touch file-$I ; done` ``` -In this usage, the statement **seq -w 5000** generates a list of numbers from one to 5,000. By using command substitution as part of the **for** statement, the list of numbers is used by the **for** statement to generate the numerical part of the file names. + **seq -w 5000** 语句生成了1 到 5000 的数字序列。通过把命令替换用于 **for** 语句,**for** 语句就可以使用数字序列来生成文件名的数字部分。 -#### Arithmetic expansion +#### 算术扩展 -Bash can perform integer math, but it is rather cumbersome (as you will soon see). The syntax for arithmetic expansion is **$((arithmetic-expression))**, using double parentheses to open and close the expression. +Bash 可以进行整型的数学计算,但是比较繁琐(你一会儿将看到)。数字扩展的语法是 **$((算术表达式))** ,分别用两个括号来打开和关闭表达式。算术扩展在 shell 程序或脚本中类似命令替换;表达式结算后的结果替换了表达式,用于 shell 后续的计算。 -Arithmetic expansion works like command substitution in a shell program or script; the value calculated from the expression replaces the expression for further evaluation by the shell. - -Once again, start with something simple: +我们再用一个简单的用法来开始: ``` @@ -457,7 +454,7 @@ Once again, start with something simple: Var 3 = 35 ``` -The following division results in zero because the result would be a decimal value of less than one: +下面的除法结果是 0,因为表达式的结果是一个小于 1 的整型数字: ``` @@ -465,7 +462,7 @@ The following division results in zero because the result would be a decimal val Var 3 = 0 ``` -Here is a simple calculation I often do in a script or CLI program that tells me how much total virtual memory I have in a Linux host. The **free** command does not provide that data: +这是一个我经常在脚本或 CLI 程序中使用的一个简单的计算,用来查看在 Linux 主机中使用了多少虚拟内存。 **free** 不提供我需要的数据: ``` @@ -474,15 +471,11 @@ RAM = 4037080 and Swap = 6291452 Total Virtual memory is 10328532 ``` -I used the **`** character to delimit the sections of code used for command substitution. +我使用 **\`** 字符来划定用作命令替换的界限。我用 Bash 算术扩展的场景主要是用脚本检查系统资源用量后基于返回的结果选择一个程序运行的路径。 -I use Bash arithmetic expansion mostly for checking system resource amounts in a script and then choose a program execution path based on the result. +### 总结 -### Summary - -This article, the second in this series on Bash as a programming language, explored the Bash file, string, numeric, and miscellaneous logical operators that provide execution-flow control logic and the different types of shell expansions. - -The third article in this series will explore the use of loops for performing various types of iterative operations. +本文是 Bash 编程语言系列的第二篇,探讨了 Bash 文件,字符串,数字和各种提供流程控制逻辑的逻辑操作符还有不同种类的 shell 扩展。 -------------------------------------------------------------------------------- @@ -490,7 +483,7 @@ via: https://opensource.com/article/19/10/programming-bash-logical-operators-she 作者:[David Both][a] 选题:[lujun9972][b] -译者:[译者ID](https://github.com/译者ID) +译者:[lxbwolf](https://github.com/lxbwolf) 校对:[校对者ID](https://github.com/校对者ID) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 From ffb62101bf06e9e5464cb0fa049f664c5ecb723d Mon Sep 17 00:00:00 2001 From: Brooke Lau Date: Wed, 11 Dec 2019 12:13:27 +0800 Subject: [PATCH 3/5] TSL: 20191022 How to program with Bash- Logical operators and shell expansions --- ...o program with Bash- Logical operators and shell expansions.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename {sources => translated}/tech/20191022 How to program with Bash- Logical operators and shell expansions.md (100%) diff --git a/sources/tech/20191022 How to program with Bash- Logical operators and shell expansions.md b/translated/tech/20191022 How to program with Bash- Logical operators and shell expansions.md similarity index 100% rename from sources/tech/20191022 How to program with Bash- Logical operators and shell expansions.md rename to translated/tech/20191022 How to program with Bash- Logical operators and shell expansions.md From dce05ca93086042420d2936a1c942cdad9ebbbb4 Mon Sep 17 00:00:00 2001 From: Brooke Lau Date: Wed, 11 Dec 2019 12:16:24 +0800 Subject: [PATCH 4/5] TSL: 20191022 How to program with Bash- Logical operators and shell expansions --- ...- Logical operators and shell expansions.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/translated/tech/20191022 How to program with Bash- Logical operators and shell expansions.md b/translated/tech/20191022 How to program with Bash- Logical operators and shell expansions.md index 4e6fd82862..a3adfeb6cf 100644 --- a/translated/tech/20191022 How to program with Bash- Logical operators and shell expansions.md +++ b/translated/tech/20191022 How to program with Bash- Logical operators and shell expansions.md @@ -1,11 +1,11 @@ -[#]: collector: "lujun9972" -[#]: translator: "lxbwolf" -[#]: reviewer: " " -[#]: publisher: " " -[#]: url: " " -[#]: subject: "How to program with Bash: Logical operators and shell expansions" -[#]: via: "https://opensource.com/article/19/10/programming-bash-logical-operators-shell-expansions" -[#]: author: "David Both https://opensource.com/users/dboth" +[#]: collector: (lujun9972) +[#]: translator: (lxbwolf) +[#]: reviewer: ( ) +[#]: publisher: ( ) +[#]: url: ( ) +[#]: subject: (How to program with Bash: Logical operators and shell expansions) +[#]: via: (https://opensource.com/article/19/10/programming-bash-logical-operators-shell-expansions) +[#]: author: (David Both https://opensource.com/users/dboth) Bash 编程教程:逻辑操作符和 shell 扩展 ====== @@ -490,6 +490,6 @@ via: https://opensource.com/article/19/10/programming-bash-logical-operators-she [a]: https://opensource.com/users/dboth [b]: https://github.com/lujun9972 -[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/OSDC_women_computing_5.png?itok=YHpNs_ss "Women in computing and open source v5" +[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/OSDC_women_computing_5.png?itok=YHpNs_ss (Women in computing and open source v5) [2]: http://www.both.org/?page_id=1183 [3]: https://opensource.com/article/19/10/programming-bash-part-1 From 6b6c5660e9e64e83992ae5641fb82db2e29a00c5 Mon Sep 17 00:00:00 2001 From: darksun Date: Wed, 11 Dec 2019 18:59:58 +0800 Subject: [PATCH 5/5] =?UTF-8?q?=E9=80=89=E9=A2=98:=2020191204=20#:acid=20'?= =?UTF-8?q?words:=20Handle=20Chromium=20&=20Firefox=20sessions=20with=20or?= =?UTF-8?q?g-mode?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit sources/tech/20191204 --acid -words- Handle Chromium - Firefox sessions with org-mode.md --- ...romium - Firefox sessions with org-mode.md | 145 ++++++++++++++++++ 1 file changed, 145 insertions(+) create mode 100644 sources/tech/20191204 --acid -words- Handle Chromium - Firefox sessions with org-mode.md diff --git a/sources/tech/20191204 --acid -words- Handle Chromium - Firefox sessions with org-mode.md b/sources/tech/20191204 --acid -words- Handle Chromium - Firefox sessions with org-mode.md new file mode 100644 index 0000000000..7b71e21ff3 --- /dev/null +++ b/sources/tech/20191204 --acid -words- Handle Chromium - Firefox sessions with org-mode.md @@ -0,0 +1,145 @@ +[#]: collector: (lujun9972) +[#]: translator: (lujun9972) +[#]: reviewer: ( ) +[#]: publisher: ( ) +[#]: url: ( ) +[#]: subject: (#:acid 'words: Handle Chromium & Firefox sessions with org-mode) +[#]: via: (https://acidwords.com/posts/2019-12-04-handle-chromium-and-firefox-sessions-with-org-mode.html) +[#]: author: (Sanel Z https://acidwords.com/) + +Handle Chromium & Firefox sessions with org-mode +====== + +I was big fan of [Session Manager][1], small addon for Chrome and Chromium that will save all open tabs, assign the name to session and, when is needed, restore it. + +Very useful, especially if you are like me, switching between multiple "mind sessions" during the day - research, development or maybe news reading. Or simply, you'd like to remember workflow (and tabs) you had few days ago. + +After I decided to ditch all extensions from Chromium except [uBlock Origin][2], it was time to look for alternative. My main goal was it to be browser agnostic and session links had to be stored in text file, so I can enjoy all the goodies of plain text file. What would be better for that than good old [org-mode][3] ;) + +Long time ago I found this trick: [Get the currently open tabs in Google Chrome via the command line][4] and with some elisp sugar and coffee, here is the code: + +``` +(require 'cl-lib) + +(defun save-chromium-session () + "Reads chromium current session and generate org-mode heading with items." + (interactive) + (save-excursion + (let* ((cmd "strings ~/'.config/chromium/Default/Current Session' | 'grep' -E '^https?://' | sort | uniq") + (ret (shell-command-to-string cmd))) + (insert + (concat + "* " + (format-time-string "[%Y-%m-%d %H:%M:%S]") + "\n" + (mapconcat 'identity + (cl-reduce (lambda (lst x) + (if (and x (not (string= "" x))) + (cons (concat " - " x) lst) + lst)) + (split-string ret "\n") + :initial-value (list)) + "\n")))))) + +(defun restore-chromium-session () + "Restore session, by openning each link in list with (browse-url). +Make sure to put cursor on date heading that contains list of urls." + (interactive) + (save-excursion + (beginning-of-line) + (when (looking-at "^\\*") + (forward-line 1) + (while (looking-at "^[ ]+-[ ]+\\(http.?+\\)$") + (let* ((ln (thing-at-point 'line t)) + (ln (replace-regexp-in-string "^[ ]+-[ ]+" "" ln)) + (ln (replace-regexp-in-string "\n" "" ln))) + (browse-url ln)) + (forward-line 1))))) +``` + +So, how does it work? + +Evaluate above code, open new org-mode file and call `M-x save-chromium-session`. It will create something like this: + +``` +* [2019-12-04 12:14:02] + - https://www.reddit.com/r/emacs/comments/... + - https://www.reddit.com/r/Clojure + - https://news.ycombinator.com +``` + +or whatever urls are running in Chromium instance. To restore it back, put cursor on desired date and run `M-x restore-chromium-session`. All tabs should be back. + +Here is how I use it, with randomly generated data for the purpose of this text: + +``` +#+TITLE: Browser sessions + +* [2019-12-01 23:15:00]... +* [2019-12-02 18:10:20]... +* [2019-12-03 19:00:12] + - https://www.reddit.com/r/emacs/comments/... + - https://www.reddit.com/r/Clojure + - https://news.ycombinator.com + +* [2019-12-04 12:14:02] + - https://www.reddit.com/r/emacs/comments/... + - https://www.reddit.com/r/Clojure + - https://news.ycombinator.com +``` + +Note that hack for reading Chromium session isn't perfect: `strings` will read whatever looks like string and url from binary database and sometimes that will yield small artifacts in urls. But, you can easily edit those and keep session file lean and clean. + +To actually open tabs, elisp code will use [browse-url][5] and it can be further customized to run Chromium, Firefox or any other browser with `browse-url-browser-function` variable. Make sure to read documentation for this variable. + +Don't forget to put session file in git, mercurial or svn and enjoy the fact that you will never loose your session history again :) + +### What about Firefox? + +If you are using Firefox (recent versions) and would like to pull session urls, here is how to do it. + +First, download and compile [lz4json][6], small tool that will decompress Mozilla lz4json format, where Firefox stores session data. Session data (at the time of writing this post) is stored in `$HOME/.mozilla/firefox//sessionstore-backups/recovery.jsonlz4`. + +If Firefox is not running, `recovery.jsonlz4` will not be present, but use `previous.jsonlz4` instead. + +To extract urls, try this in terminal: + +``` +$ lz4jsoncat recovery.jsonlz4 | grep -oP '"(http.+?)"' | sed 's/"//g' | sort | uniq +``` + +and update `save-chromium-session` with: + +``` +(defun save-chromium-session () + "Reads chromium current session and converts it to org-mode chunk." + (interactive) + (save-excursion + (let* ((path "~/.mozilla/firefox//sessionstore-backups/recovery.jsonlz4") + (cmd (concat "lz4jsoncat " path " | grep -oP '\"(http.+?)\"' | sed 's/\"//g' | sort | uniq")) + (ret (shell-command-to-string cmd))) +... +;; rest of the code is unchanged +``` + +Updating documentation strings, function name and any further refactoring is left for exercise. + +-------------------------------------------------------------------------------- + +via: https://acidwords.com/posts/2019-12-04-handle-chromium-and-firefox-sessions-with-org-mode.html + +作者:[Sanel Z][a] +选题:[lujun9972][b] +译者:[lujun9972](https://github.com/lujun9972) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]: https://acidwords.com/ +[b]: https://github.com/lujun9972 +[1]: https://chrome.google.com/webstore/detail/session-manager/mghenlmbmjcpehccoangkdpagbcbkdpc?hl=en-US +[2]: https://chrome.google.com/webstore/detail/ublock-origin/cjpalhdlnbpafiamejdnhcphjbkeiagm?hl=en +[3]: https://orgmode.org/ +[4]: https://superuser.com/a/1310873 +[5]: https://www.gnu.org/software/emacs/manual/html_node/emacs/Browse_002dURL.html +[6]: https://github.com/andikleen/lz4json