“Exit Trap” 让你的 Bash 脚本更稳固可靠

Summary: 要做到这一点，秘诀就是 bash 提供的一个叫做 EXIT 的伪信号，你可以 trap 它，当脚本因为任何原因退出时，相应的命令或函数就会执行。

# “Exit Trap” 让你的 Bash 脚本更稳固可靠

有个简单实用的技巧可以让你的 bash 脚本更稳健 -- 确保总是执行必要的收尾工作，哪怕是在发生异常的时候。要做到这一点，秘诀就是 bash 提供的一个叫做 EXIT 的伪信号，你可以 [trap](http://www.gnu.org/software/bash/manual/bashref.html#index-trap) 它，当脚本因为任何原因退出时，相应的命令或函数就会执行。我们来看看它是如何工作的。

基本的代码结构看起来像这样：

```
#!/bin/bash
function finish {
  # 你的收尾代码
}
trap finish EXIT

```

你可以把任何你觉得务必要运行的代码放在这个 `finish` 函数里。一个很好的例子是：创建一个临时目录，事后再删除它。

```
#!/bin/bash
scratch=$(mktemp -d -t tmp.XXXXXXXXXX)
function finish {
  rm -rf "$scratch"
}
trap finish EXIT

```

这样，在你的核心代码中，你就可以在这个 `$scratch` 目录里下载、生成、操作中间或临时数据了。   注1

```
# 下载所有版本的 linux 内核…… 为了科学研究！
for major in {1..4}; do
  for minor in {0..99}; do
    for patchlevel in {0..99}; do
      tarball="linux-${major}-${minor}-${patchlevel}.tar.bz2"
      curl -q "http://kernel.org/path/to/$tarball" -o "$scratch/$tarball" || true
      if [ -f "$scratch/$tarball" ]; then
        tar jxf "$scratch/$tarball"
      fi
    done
  done
done
# 整合成单个文件
# 复制到目标位置
cp "$scratch/frankenstein-linux.tar.bz2" "$1"
# 脚本结束， scratch 目录自动被删除

```

比较一下如果不用 `trap` ，你是怎么删除 `scratch` 目录的：

```
#!/bin/bash
# 别这样做！

scratch=$(mktemp -d -t tmp.XXXXXXXXXX)

# 在这里插入你的几十上百行代码

# 都搞定了，退出之前把目录删除
rm -rf "$scratch"

```

这有什么问题么？很多：

* 如果运行出错导致脚本提前退出， `scratch` 目录及里面的内容不会被删除。这会导致资料泄漏，可能引发安全问题。
* 如果这个脚本的设计初衷就是在脚本末尾以前退出，那么你必须手动复制粘贴 `rm` 命令到每一个出口。
* 这也给维护带来了麻烦。如果今后在脚本某处添加了一个 `exit` ，你很可能就忘了加上删除操作 -- 从而制造潜在的安全漏洞。

### 无论如何，服务要在线

另外一个场景： 想象一下你正在运行一些自动化系统运维任务，要临时关闭一项服务，最后这项服务需要重启，而且要万无一失，即使脚本运行出错。那么你可以这样做：

```
function finish {
    # 重启服务
    sudo /etc/init.d/something start
}
trap finish EXIT
sudo /etc/init.d/something stop
# 主要任务代码

# 脚本结束，执行 finish 函数重启服务

```

一个具体的实例：比如 Ubuntu 服务器上运行着 MongoDB ，你要为 crond 写一个脚本来临时关闭服务并做一些日常维护工作。你应该这样写：

```
function finish {
    # 重启服务
    sudo service mongdb start
}
trap finish EXIT
# 关闭 mongod 服务
sudo service mongdb stop
# （如果 mongod 配置了 fork ，比如 replica set ，你可能需要执行 “sudo killall --wait /usr/bin/mongod”）

```

### 控制开销

有一种情况特别能体现 EXIT `trap` 的价值：如果你的脚本运行过程中需要初始化一下成本高昂的资源，结束时要确保把它们释放掉。比如你在 AWS (Amazon Web Services) 上工作，要在脚本中创建一个镜像。

（名词解释: 在亚马逊云上的运行的服务器叫“[实例](http://aws.amazon.com/ec2/)”。实例从<ruby> 亚马逊机器镜像 <rt>  Amazon Machine Image </rt></ruby>创建而来，通常被称为 “AMI” 或 “镜像” 。AMI 相当于某个特殊时间点的服务器快照。）

我们可以这样创建一个自定义的 AMI ：

1. 基于一个基准 AMI 运行一个实例（例如，启动一个服务器）。
2. 在实例中手动或运行脚本来做一些修改。
3. 用修改后的实例创建一个镜像。
4. 如果不再需要这个实例，可以将其删除。

最后一步**相当重要**。如果你的脚本没有把实例删除掉，它会一直运行并计费。（到月底你的账单让你大跌眼镜时，恐怕哭都来不及了！）

如果把 AMI 的创建封装在脚本里，我们就可以利用 `trap` EXIT 来删除实例了。我们还可以用上 EC2 的命令行工具：

```
#!/bin/bash
# 定义基准 AMI 的 ID
ami=$1
# 保存临时实例的 ID
instance=''
# 作为 IT 人，让我们看看 scratch 目录的另类用法
scratch=$(mktemp -d -t tmp.XXXXXXXXXX)
function finish {
    if [ -n "$instance" ]; then
        ec2-terminate-instances "$instance"
    fi
    rm -rf "$scratch"
}
trap finish EXIT
# 创建实例，将输出(包含实例 ID )保存到 scratch 目录下的文件里
ec2-run-instances "$ami" > "$scratch/run-instance"
# 提取实例 ID
instance=$(grep '^INSTANCE' "$scratch/run-instance" | cut -f 2)

```

脚本执行到这里，实例（EC2 服务器）已经开始运行    注2  。接下来你可以做任何事情：在实例中安装软件，修改配置文件等，然后为最终版本创建一个镜像。实例会在脚本结束时被删除 -- 即使脚本因错误而提前退出。（请确保实例创建成功后再运行业务代码。）

### 更多应用

这篇文章只讲了些皮毛。我已经使用这个 bash 技巧很多年了，现在还能不时发现一些有趣的用法。你也可以把这个方法应用到你自己的场景中，从而提升你的 bash 脚本的可靠性。

### 尾注

* 注1. `mktemp` 的选项 `-t` 在 Linux 上是可选的，在 OS X 上是必需的。带上此选项可以让你的脚本有更好的可移植性。
* 注2. 如果只是为了获取实例 ID ，我们不用创建文件，直接写成 `instance=$(ec2-run-instances "$ami" | grep '^INSTANCE' | cut -f 2)` 就可以。但把输出写入文件可以记录更多有用信息，便于调试 ，代码可读性也更强。

作者简介：美国加利福尼亚旧金山的作家，软件工程师，企业家。[Powerful Python](https://www.amazon.com/d/0692878971) 的作者，他的 [blog](https://powerfulpython.com/blog/)。

---

via: <http://redsymbol.net/articles/bash-exit-traps/>

作者：[aaron maxwell](http://redsymbol.net/) 译者：[Dotcra](https://github.com/Dotcra) 校对：[wxy](https://github.com/wxy)

本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译，[Linux中国](https://linux.cn/) 荣誉推出


Linux 命令行下的数学运算

Summary: 有几个有趣的命令可以在 Linux 系统下做数学运算： expr、factor、jot 和 bc 命令。

# Linux 命令行下的数学运算

>
> 有几个有趣的命令可以在 Linux 系统下做数学运算： `expr`、`factor`、`jot` 和 `bc` 命令。
>
>
>

<img src="content_image/album_201805_14_190605btc11bot16tiv2u8.jpg" alt="" title="">

可以在 Linux 命令行下做数学运算吗？当然可以！事实上，有不少命令可以轻松完成这些操作，其中一些甚至让你大吃一惊。让我们来学习这些有用的数学运算命令或命令语法吧。

### expr

首先，对于在命令行使用命令进行数学运算，可能最容易想到、最常用的命令就是 `expr` （<ruby> 表达式 <rt>  expression </rt></ruby>。它可以完成四则运算，也可以用于比较大小。下面是几个例子：

#### 变量递增

```
$ count=0
$ count=`expr $count + 1`
$ echo $count
1

```

#### 完成简单运算

```
$ expr 11 + 123
134
$ expr 134 / 11
12
$ expr 134 - 11
123
$ expr 11 * 123
expr: syntax error      <== oops!
$ expr 11 \* 123
1353
$ expr 20 % 3
2

```

注意，你需要在 `*` 运算符之前增加 `\` 符号，避免语法错误（注：`*` 是 bash 的通配符，因此需要用 `\` 转义，下面的 `>` 也是由于是 bash 的管道符而需要转义）。`%` 运算符用于取余运算。

下面是一个稍微复杂的例子：

```
participants=11
total=156
share=`expr $total / $participants`
remaining=`expr $total - $participants \* $share`
echo $share
14
echo $remaining
2

```

假设某个活动中有 11 位参与者，需要颁发的奖项总数为 156，那么平均每个参与者获得 14 项奖项，额外剩余 2 个奖项。

#### 比较

下面让我们看一下比较的操作。从第一印象来看，语句看似有些怪异；这里并不是**设置**数值，而是进行数字比较。在本例中 `expr` 判断表达式是否为真：如果结果是 1，那么表达式为真；反之，表达式为假。

```
$ expr 11 = 11
1
$ expr 11 = 12
0

```

请读作“11 是否等于 11？”及“11 是否等于 12？”，你很快就会习惯这种写法。当然，我们不会在命令行上执行上述比较，可能的比较是 `$age` 是否等于 `11`。

```
$ age=11
$ expr $age = 11
1

```

在本例中，我们判断 10 是否大于 5，以及是否大于 99。

```
$ expr 10 \> 5
1
$ expr 10 \> 99
0

```

的确，返回 1 和 0 分别代表比较的结果为真和假，我们一般预期在 Linux 上得到这个结果。在下面的例子中，按照上述逻辑使用 `expr` 并不正确，因为 `if` 的工作原理刚好相反，即 0 代表真。

```
#!/bin/bash

echo -n "Cost to us> "
read cost
echo -n "Price we're asking> "
read price

if [ `expr $price \> $cost` ]; then
 echo "We make money"
else
 echo "Don't sell it"
fi

```

下面，我们运行这个脚本：

```
$ ./checkPrice
Cost to us> 11.50
Price we're asking> 6
We make money

```

这显然与我们预期不符！我们稍微修改一下，以便使其按我们预期工作：

```
#!/bin/bash

echo -n "Cost to us> "
read cost
echo -n "Price we're asking> "
read price

if [ `expr $price \> $cost` == 1 ]; then
 echo "We make money"
else
 echo "Don't sell it"
fi

```

### factor

`factor` 命令的功能基本与你预期相符。你给出一个数字，该命令会给出对应数字的因子。

```
$ factor 111
111: 3 37
$ factor 134
134: 2 67
$ factor 17894
17894: 2 23 389
$ factor 1987
1987: 1987

```

注：`factor` 命令对于最后一个数字没有返回更多因子，这是因为 1987 是一个**质数**。

### jot

`jot` 命令可以创建一系列数字。给定数字总数及起始数字即可。

```
$ jot 8 10
10
11
12
13
14
15
16
17

```

你也可以用如下方式使用 `jot`，这里我们要求递减至数字 2。

```
$ jot 8 10 2
10
9
8
7
5
4
3
2

```

`jot` 可以帮你构造一系列数字组成的列表，该列表可以用于其它任务。

```
$ for i in `jot 7 17`; do echo April $i; done
April 17
April 18
April 19
April 20
April 21
April 22
April 23

```

### bc

`bc` 基本上是命令行数学运算最佳工具之一。输入你想执行的运算，使用管道发送至该命令即可：

```
$ echo "123.4+5/6-(7.89*1.234)" | bc
113.664

```

可见 `bc` 并没有忽略精度，而且输入的字符串也相当直截了当。它还可以进行大小比较、处理布尔值、计算平方根、正弦、余弦和正切等。

```
$ echo "sqrt(256)" | bc
16
$ echo "s(90)" | bc -l
.89399666360055789051

```

事实上，`bc` 甚至可以计算 pi。你需要指定需要的精度。

```
$ echo "scale=5; 4*a(1)" | bc -l
3.14156
$ echo "scale=10; 4*a(1)" | bc -l
3.1415926532
$ echo "scale=20; 4*a(1)" | bc -l
3.14159265358979323844
$ echo "scale=40; 4*a(1)" | bc -l
3.1415926535897932384626433832795028841968

```

除了通过管道接收数据并返回结果，`bc`还可以交互式运行，输入你想执行的运算即可。本例中提到的 `scale` 设置可以指定有效数字的个数。

```
$ bc
bc 1.06.95
Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006 Free Software Foundation, Inc.
This is free software with ABSOLUTELY NO WARRANTY.
For details type `warranty'.
scale=2
3/4
.75
2/3
.66
quit

```

你还可以使用 `bc` 完成数字进制转换。`obase` 用于设置输出的数字进制。

```
$ bc
bc 1.06.95
Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006 Free Software Foundation, Inc.
This is free software with ABSOLUTELY NO WARRANTY.
For details type `warranty'.
obase=16
16      <=== entered
10      <=== response
256     <=== entered
100     <=== response
quit

```

按如下方式使用 `bc` 也是完成十六进制与十进制转换的最简单方式之一：

```
$ echo "ibase=16; F2" | bc
242
$ echo "obase=16; 242" | bc
F2

```

在上面第一个例子中，我们将输入进制（`ibase`）设置为十六进制（`hex`），完成十六进制到为十进制的转换。在第二个例子中，我们执行相反的操作，即将输出进制（`obase`）设置为十六进制。

### 简单的 bash 数学运算

通过使用双括号，我们可以在 bash 中完成简单的数学运算。在下面的例子中，我们创建一个变量，为变量赋值，然后依次执行加法、自减和平方。

```
$ (( e = 11 ))
$ (( e = e + 7 ))
$ echo $e
18

$ (( e-- ))
$ echo $e
17

$ (( e = e ** 2 ))
$ echo $e
289

```

允许使用的运算符包括：

```
+ -     加法及减法
++ --   自增与自减
* / %   乘法、除法及求余数
**      指数运算（bash 中）
^       指数运算（bc 中）
```

你还可以使用逻辑运算符和布尔运算符：

```
$ ((x=11)); ((y=7))
$ if (( x > y )); then
> echo "x > y"
> fi
x > y

$ ((x=11)); ((y=7)); ((z=3))
$ if (( x > y )) >> (( y > z )); then
> echo "letters roll downhill"
> fi
letters roll downhill

```

或者如下方式：

```
$ if [ x > y ] << [ y > z ]; then echo "letters roll downhill"; fi
letters roll downhill

```

下面计算 2 的 3 次幂：

```
$ echo "2 ^ 3"
2 ^ 3
$ echo "2 ^ 3" | bc
8

```

### 总结

在 Linux 系统中，有很多不同的命令行工具可以完成数字运算。希望你在读完本文之后，能掌握一两个新工具。

感谢 @[no1xsyzy](https://github.com/no1xsyzy) [提出的修改意见](https://github.com/LCTT/TranslateProject/issues/8841)。

---

via: <https://www.networkworld.com/article/3268964/linux/how-to-do-math-on-the-linux-command-line.html>

作者：[Sandra Henry-Stocker](https://www.networkworld.com/author/Sandra-Henry_Stocker/) 选题：[lujun9972](https://github.com/lujun9972) 译者：[pinewall](https://github.com/pinewall) 校对：[wxy](https://github.com/wxy)

本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译，[Linux中国](https://linux.cn/) 荣誉推出


两款 Linux 桌面端可用的科学计算器

Summary: 如果你想找个高级的桌面计算器的话，你可以看看开源软件，以及一些其它有趣的工具。

如果你想找个高级的桌面计算器的话，你可以看看开源软件，以及一些其它有趣的工具。

# 两款 Linux 桌面端可用的科学计算器

>
> 如果你想找个高级的桌面计算器的话，你可以看看开源软件，以及一些其它有趣的工具。
>
>
>

每个 Linux 桌面环境都至少带有一个功能简单的桌面计算器，但大多数计算器只能进行一些简单的计算。

幸运的是，还是有例外的：不仅可以做得比开平方根和一些三角函数还多，而且还很简单。这里将介绍两款强大的计算器，外加一大堆额外的功能。

### SpeedCrunch

[SpeedCrunch](http://speedcrunch.org/index.html) 是一款高精度科学计算器，有着简明的 Qt5 图像界面，并且强烈依赖键盘。

*SpeedCrunch 运行中*

它支持单位，并且可用在所有函数中。

例如，

```
2 * 10^6 newton / (meter^2)

```

你可以得到：

```
= 2000000 pascal

```

SpeedCrunch 会默认地将结果转化为国际标准单位，但还是可以用 `in` 命令转换：

例如：

```
3*10^8 meter / second in kilo meter / hour

```

结果是：

```
= 1080000000 kilo meter / hour

```

`F5` 键可以将所有结果转为科学计数法（`1.08e9 kilo meter / hour`），`F2` 键可以只将那些很大的数或很小的数转为科学计数法。更多选项可以在配置页面找到。

可用的函数的列表看上去非常壮观。它可以用在 Linux 、 Windows、macOS。许可证是 GPLv2，你可以在 [Bitbucket](https://bitbucket.org/heldercorreia/speedcrunch) 上得到它的源码。

### Qalculate!

[Qalculate!](https://qalculate.github.io/)（有感叹号）有一段长而复杂的历史。

这个项目给了我们一个强大的库，而这个库可以被其它程序使用（在 Plasma 桌面中，krunner 可以用它来计算），以及一个用 GTK3 搭建的图形界面。它允许你转换单位，处理物理常量，创建图像，使用复数，矩阵以及向量，选择任意精度，等等。

*在 Qalculate! 中查看物理常量*

在单位的使用方面，Qalculate! 会比 SppedCrunch 更加直观，而且可以识别一些常用前缀。你有听说过 exapascal 压力吗？反正我没有（太阳的中心大概在 `~26 PPa`），但 Qalculate! ，可以准确 `1 EPa` 的意思。同时，Qalculate! 可以更加灵活地处理语法错误，所以你不需要担心打括号：如果没有歧义，Qalculate! 会直接给出正确答案。

一段时间之后这个项目看上去被遗弃了。但在 2016 年，它又变得强大了，在一年里更新了 10 个版本。它的许可证是 GPLv2 （源码在 [GitHub](https://github.com/Qalculate) 上），提供Linux 、Windows 、macOS的版本。

### 更多计算器

#### ConvertAll

好吧，这不是“计算器”，但这个程序非常好用。

大部分单位转换器只是一个大的基本单位列表以及一大堆基本组合，但 [ConvertAll](http://convertall.bellz.org/) 与它们不一样。有试过把“天文单位每年”转换为“英尺每秒”吗？不管它们说不说得通，只要你想转换任何种类的单位，ConvertAll 就是你要的工具。

只需要在相应的输入框内输入转换前和转换后的单位：如果单位相容，你会直接得到答案。

主程序是在 PyQt5 上搭建的，但也有 [JavaScript 的在线版本](http://convertall.bellz.org/js/)。

#### 带有单位包的 (wx)Maxima

有时候（好吧，很多时候）一款桌面计算器时候不够你用的，然后你需要更多的原力。

[Maxima](http://maxima.sourceforge.net/) 是一款计算机代数系统（LCTT 译注：进行符号运算的软件。这种系统的要件是数学表示式的符号运算），你可以用它计算导数、积分、方程、特征值和特征向量、泰勒级数、拉普拉斯变换与傅立叶变换，以及任意精度的数字计算、二维或三维图像··· ···列出这些都够我们写几页纸的了。

[wxMaxima](https://andrejv.github.io/wxmaxima/) 是一个设计精湛的 Maxima 的图形前端，它简化了许多 Maxima 的选项，但并不会影响其它。在 Maxima 的基础上，wxMaxima 还允许你创建 “笔记本”，你可以在上面写一些笔记，保存你的图像等。其中一项 (wx)Maxima 最惊艳的功能是它可以处理尺寸单位。

在提示符只需要输入：

```
load("unit")

```

按 `Shift+Enter`，等几秒钟的时间，然后你就可以开始了。

默认地，单位包可以用基本的 MKS 单位，但如果你喜欢，例如，你可以用 `N` 为单位而不是 `kg*m/s2`，你只需要输入：`setunits(N)`。

Maxima 的帮助（也可以在 wxMaxima 的帮助菜单中找到）会给你更多信息。

你使用这些程序吗？你知道还有其它好的科学、工程用途的桌面计算器或者其它相关的计算器吗？在评论区里告诉我们吧！

---

via: <https://opensource.com/article/18/1/scientific-calculators-linux>

作者：[Ricardo Berlasso](https://opensource.com/users/rgb-es) 译者：[zyk2290](https://github.com/zyk2290) 校对：[wxy](https://github.com/wxy)

本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译，[Linux中国](https://linux.cn/) 荣誉推出


基于命令行的任务管理器 Taskwarrior

# 基于命令行的任务管理器 Taskwarrior

<img src="content_image/album_201805_15_104609d5en8uesea8gepn8.jpg" alt="" title="">

Taskwarrior 是一个灵活的[命令行任务管理程序](https://taskwarrior.org/)，用他们[自己的话说](https://taskwarrior.org/docs/start.html)：

>
> Taskwarrior 在命令行里管理你的 TODO 列表。它灵活，快速，高效，不显眼，它默默做自己的事情让你避免自己管理。
>
>
>

Taskwarrior 是高度可定制的，但也可以“立即使用”。在本文中，我们将向你展示添加和完成任务的基本命令，然后我们将介绍几个更高级的命令。最后，我们将向你展示一些基本的配置设置，以开始自定义你的设置。

### 安装 Taskwarrior

Taskwarrior 在 Fedora 仓库中是可用的，所有安装它很容易：

```
sudo dnf install task

```

一旦完成安装，运行 `task` 命令。第一次运行将会创建一个 `~/.taskrc` 文件。

```
$ task
A configuration file could not be found in ~

Would you like a sample /home/link/.taskrc created, so Taskwarrior can proceed? (yes/no) yes
[task next]
No matches.

```

### 添加任务

添加任务快速而不显眼。

```
$ task add Plant the wheat
Created task 1.

```

运行 `task` 或者 `task list` 来显示即将来临的任务。

```
$ task list

ID Age Description Urg
 1 8s Plant the wheat 0

1 task

```

让我们添加一些任务来完成这个示例。

```
$ task add Tend the wheat
Created task 2.
$ task add Cut the wheat
Created task 3.
$ task add Take the wheat to the mill to be ground into flour
Created task 4.
$ task add Bake a cake
Created task 5.

```

再次运行 `task` 来查看列表。

```
[task next]

ID Age Description Urg
 1 3min Plant the wheat 0
 2 22s Tend the wheat 0
 3 16s Cut the wheat 0
 4 8s Take the wheat to the mill to be ground into flour 0
 5 2s Bake a cake 0

5 tasks

```

### 完成任务

将一个任务标记为完成， 查找其 ID 并运行：

```
$ task 1 done
Completed task 1 'Plant the wheat'.
Completed 1 task.

```

你也可以用它的描述来标记一个任务已完成。

```
$ task 'Tend the wheat' done
Completed task 1 'Tend the wheat'.
Completed 1 task.

```

通过使用 `add`、`list` 和 `done`，你可以说已经入门了。

### 设定截止日期

很多任务不需要一个截止日期：

```
task add Finish the article on Taskwarrior

```

但是有时候，设定一个截止日期正是你需要提高效率的动力。在添加任务时使用 `due` 修饰符来设置特定的截止日期。

```
task add Finish the article on Taskwarrior due:tomorrow

```

`due` 非常灵活。它接受特定日期 (`2017-02-02`) 或 ISO-8601 (`2017-02-02T20:53:00Z`)，甚至相对时间 (`8hrs`)。可以查看所有示例的 [Date & Time](https://taskwarrior.org/docs/dates.html) 文档。

日期也不只有截止日期，Taskwarrior 有 `scheduled`, `wait` 和 `until` 选项。

```
task add Proof the article on Taskwarrior scheduled:thurs

```

一旦日期（本例中的星期四）通过，该任务就会被标记为 `READY` 虚拟标记。它会显示在 `ready` 报告中。

```
$ task ready

ID Age S Description Urg
 1 2s 1d Proof the article on Taskwarrior 5

```

要移除一个日期，使用空白值来 `modify` 任务：

```
$ task 1 modify scheduled:

```

### 查找任务

如果没有使用正则表达式搜索的能力，任务列表是不完整的，对吧？

```
$ task '/.* the wheat/' list

ID Age Project Description Urg
 2 42min Take the wheat to the mill to be ground into flour 0
 1 42min Home Cut the wheat 1

2 tasks

```

### 自定义 Taskwarrior

记得我们在开头创建的文件 (`~/.taskrc`)吗？让我们来看看默认设置：

```
# [Created by task 2.5.1 2/9/2017 16:39:14]
# Taskwarrior program configuration file.
# For more documentation, see http://taskwarrior.org or try 'man task', 'man task-color',
# 'man task-sync' or 'man taskrc'

# Here is an example of entries that use the default, override and blank values
# variable=foo -- By specifying a value, this overrides the default
# variable= -- By specifying no value, this means no default
# #variable=foo -- By commenting out the line, or deleting it, this uses the default

# Use the command 'task show' to see all defaults and overrides

# Files
data.location=~/.task

# Color theme (uncomment one to use)
#include /usr//usr/share/task/light-16.theme
#include /usr//usr/share/task/light-256.theme
#include /usr//usr/share/task/dark-16.theme
#include /usr//usr/share/task/dark-256.theme
#include /usr//usr/share/task/dark-red-256.theme
#include /usr//usr/share/task/dark-green-256.theme
#include /usr//usr/share/task/dark-blue-256.theme
#include /usr//usr/share/task/dark-violets-256.theme
#include /usr//usr/share/task/dark-yellow-green.theme
#include /usr//usr/share/task/dark-gray-256.theme
#include /usr//usr/share/task/dark-gray-blue-256.theme
#include /usr//usr/share/task/solarized-dark-256.theme
#include /usr//usr/share/task/solarized-light-256.theme
#include /usr//usr/share/task/no-color.theme

```

现在唯一生效的选项是 `data.location=~/.task`。要查看活动配置设置（包括内置的默认设置），运行 `show`。

```
task show

```

要改变设置，使用 `config`。

```
$ task config displayweeknumber no
Are you sure you want to add 'displayweeknumber' with a value of 'no'? (yes/no) yes
Config file /home/link/.taskrc modified.

```

### 示例

这些只是你可以用 Taskwarrior 做的一部分事情。

将你的任务分配到一个项目：

```
task 'Fix leak in the roof' modify project:Home

```

使用 `start` 来标记你正在做的事情，这可以帮助你回忆起你周末后在做什么：

```
task 'Fix bug #141291' start

```

使用相关的标签：

```
task add 'Clean gutters' +weekend +house

```

务必阅读[完整文档](https://taskwarrior.org/docs/)以了解你可以编目和组织任务的所有方式。

---

via: <https://fedoramagazine.org/getting-started-taskwarrior/>

作者：[Link Dupont](https://fedoramagazine.org/author/linkdupont/) 译者：[MjSeven](https://github.com/MjSeven) 校对：[wxy](https://github.com/wxy)

本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译，[Linux中国](https://linux.cn/) 荣誉推出


探秘“栈”之旅

Summary: 栈非常重要，因为它追踪着一个程序中运行的函数，而函数又是一个软件的重要组成部分。

# 探秘“栈”之旅

早些时候，我们探索了 [“内存中的程序之秘”](/article-9255-1.html)，我们欣赏了在一台电脑中是如何运行我们的程序的。今天，我们去探索*栈的调用*，它在大多数编程语言和虚拟机中都默默地存在。在此过程中，我们将接触到一些平时很难见到的东西，像<ruby> 闭包 <rt>  closure </rt></ruby>、递归、以及缓冲溢出等等。但是，我们首先要作的事情是，描绘出栈是如何运作的。

栈非常重要，因为它追踪着一个程序中运行的*函数*，而函数又是一个软件的重要组成部分。事实上，程序的内部操作都是非常简单的。它大部分是由函数向栈中推入数据或者从栈中弹出数据的相互调用组成的，而在堆上为数据分配内存才能在跨函数的调用中保持数据。不论是低级的 C 软件还是像 JavaScript 和 C# 这样的基于虚拟机的语言，它们都是这样的。而对这些行为的深刻理解，对排错、性能调优以及大概了解究竟发生了什么是非常重要的。

当一个函数被调用时，将会创建一个<ruby> 栈帧 <rt>  stack frame </rt></ruby>去支持函数的运行。这个栈帧包含函数的*局部变量*和调用者传递给它的*参数*。这个栈帧也包含了允许被调用的函数（*callee*）安全返回给其调用者的内部事务信息。栈帧的精确内容和结构因处理器架构和函数调用规则而不同。在本文中我们以 Intel x86 架构和使用 C 风格的函数调用（`cdecl`）的栈为例。下图是一个处于栈顶部的一个单个栈帧：

在图上的场景中，有三个 CPU 寄存器进入栈。<ruby> 栈指针 <rt>  stack pointer </rt></ruby> `esp`（LCTT 译注：扩展栈指针寄存器） 指向到栈的顶部。栈的顶部总是被最*后一个推入到栈且还没有弹出*的东西所占据，就像现实世界中堆在一起的一叠盘子或者 100 美元大钞一样。

保存在 `esp` 中的地址始终在变化着，因为栈中的东西不停被推入和弹出，而它总是指向栈中的最后一个推入的东西。许多 CPU 指令的一个副作用就是自动更新 `esp`，离开寄存器而使用栈是行不通的。

在 Intel 的架构中，绝大多数情况下，栈的增长是向着*低位内存地址*的方向。因此，这个“顶部” 在包含数据的栈中是处于低位的内存地址（在这种情况下，包含的数据是 `local_buffer`）。注意，关于从 `esp` 到 `local_buffer` 的箭头不是随意连接的。这个箭头代表着事务：它*专门*指向到由 `local_buffer` 所拥有的*第一个字节*，因为，那是一个保存在 `esp` 中的精确地址。

第二个寄存器跟踪的栈是 `ebp`（LCTT 译注：扩展基址指针寄存器），它包含一个<ruby> 基指针 <rt>  base pointer </rt></ruby>或者称为<ruby> 帧指针 <rt>  frame pointer </rt></ruby>。它指向到一个*当前运行*的函数的栈帧内的固定位置，并且它为参数和局部变量的访问提供一个稳定的参考点（基址）。仅当开始或者结束调用一个函数时，`ebp` 的内容才会发生变化。因此，我们可以很容易地处理在栈中的从 `ebp` 开始偏移后的每个东西。如图所示。

不像 `esp`， `ebp` 大多数情况下是在程序代码中通过花费很少的 CPU 来进行维护的。有时候，完成抛弃 `ebp` 有一些性能优势，可以通过 [编译标志](http://stackoverflow.com/questions/14666665/trying-to-understand-gcc-option-fomit-frame-pointer) 来做到这一点。Linux 内核就是一个这样做的示例。

最后，`eax`（LCTT 译注：扩展的 32 位通用数据寄存器）寄存器惯例被用来转换大多数 C 数据类型返回值给调用者。

现在，我们来看一下在我们的栈帧中的数据。下图清晰地按字节展示了字节的内容，就像你在一个调试器中所看到的内容一样，内存是从左到右、从顶部至底部增长的，如下图所示：

局部变量 `local_buffer` 是一个字节数组，包含一个由 null 终止的 ASCII 字符串，这是 C 程序中的一个基本元素。这个字符串可以读取自任意地方，例如，从键盘输入或者来自一个文件，它只有 7 个字节的长度。因为，`local_buffer` 只能保存 8 字节，所以还剩下 1 个未使用的字节。*这个字节的内容是未知的*，因为栈不断地推入和弹出，*除了你写入的之外*，你根本不会知道内存中保存了什么。这是因为 C 编译器并不为栈帧初始化内存，所以它的内容是未知的并且是随机的 —— 除非是你自己写入。这使得一些人对此很困惑。

再往上走，`local1` 是一个 4 字节的整数，并且你可以看到每个字节的内容。它似乎是一个很大的数字，在8 后面跟着的都是零，在这里可能会误导你。

Intel 处理器是<ruby> 小端 <rt>  little endian </rt></ruby>机器，这表示在内存中的数字也是首先从小的一端开始的。因此，在一个多字节数字中，较小的部分在内存中处于最低端的地址。因为一般情况下是从左边开始显示的，这背离了我们通常的数字表示方式。我们讨论的这种从小到大的机制，使我想起《格里佛游记》：就像小人国的人们吃鸡蛋是从小头开始的一样，Intel 处理器处理它们的数字也是从字节的小端开始的。

因此，`local1` 事实上只保存了一个数字 8，和章鱼的腿数量一样。然而，`param1` 在第二个字节的位置有一个值 2，因此，它的数学上的值是 `2 * 256 = 512`（我们与 256 相乘是因为，每个位置值的范围都是从 0 到 255）。同时，`param2` 承载的数量是 `1 * 256 * 256 = 65536`。

这个栈帧的内部数据是由两个重要的部分组成：*前一个*栈帧的地址（保存的 `ebp` 值）和函数退出才会运行的指令的地址（返回地址）。它们一起确保了函数能够正常返回，从而使程序可以继续正常运行。

现在，我们来看一下栈帧是如何产生的，以及去建立一个它们如何共同工作的内部蓝图。首先，栈的增长是非常令人困惑的，因为它与你你预期的方式相反。例如，在栈上分配一个 8 字节，就要从 `esp` 减去 8，去，而减法是与增长不同的奇怪方式。

我们来看一个简单的 C 程序：

```
Simple Add Program - add.c

int add(int a, int b)
{
    int result = a + b;
    return result;
}

int main(int argc)
{
    int answer;
    answer = add(40, 2);
}

```

*简单的加法程序 - add.c*

假设我们在 Linux 中不使用命令行参数去运行它。当你运行一个 C 程序时，实际运行的第一行代码是在 C 运行时库里，由它来调用我们的 `main` 函数。下图展示了程序运行时每一步都发生了什么。每个图链接的 GDB 输出展示了内存和寄存器的状态。你也可以看到所使用的 [GDB 命令](https://github.com/gduarte/blog/blob/master/code/x86-stack/add-gdb-commands.txt)，以及整个 [GDB 输出](https://github.com/gduarte/blog/blob/master/code/x86-stack/add-gdb-output.txt)。如下：

第 2 步和第 3 步，以及下面的第 4 步，都只是函数的<ruby> 序言 <rt>  prologue </rt></ruby>，几乎所有的函数都是这样的：`ebp` 的当前值被保存到了栈的顶部，然后，将 `esp` 的内容拷贝到 `ebp`，以建立一个新的栈帧。`main` 的序言和其它函数一样，但是，不同之处在于，当程序启动时 `ebp` 被清零。

如果你去检查栈下方（右边）的整形变量（`argc`），你将找到更多的数据，包括指向到程序名和命令行参数（传统的 C 的 `argv`）、以及指向 Unix 环境变量以及它们真实的内容的指针。但是，在这里这些并不是重点，因此，继续向前调用 `add()`：

在 `main` 从 `esp` 减去 12 之后得到它所需的栈空间，它为 `a` 和 `b` 设置值。在内存中的值展示为十六进制，并且是小端格式，与你从调试器中看到的一样。一旦设置了参数值，`main` 将调用 `add`，并且开始运行：

现在，有一点小激动！我们进入了另一个函数序言，但这次你可以明确看到栈帧是如何从 `ebp` 到栈建立一个链表。这就是调试器和高级语言中的 `Exception` 对象如何对它们的栈进行跟踪的。当一个新帧产生时，你也可以看到更多这种典型的从 `ebp` 到 `esp` 的捕获。我们再次从 `esp` 中做减法得到更多的栈空间。

当 `ebp` 寄存器的值拷贝到内存时，这里也有一个稍微有些怪异的字节逆转。在这里发生的奇怪事情是，寄存器其实并没有字节顺序：因为对于内存，没有像寄存器那样的“增长的地址”。因此，惯例上调试器以对人类来说最自然的格式展示了寄存器的值：数位从最重要的到最不重要。因此，这个在小端机器中的副本的结果，与内存中常用的从左到右的标记法正好相反。我想用图去展示你将会看到的东西，因此有了下面的图。

在比较难懂的部分，我们增加了注释：

这是一个临时寄存器，用于帮你做加法，因此没有什么警报或者惊喜。对于加法这样的作业，栈的动作正好相反，我们留到下次再讲。

对于任何读到这里的人都应该有一个小礼物，因此，我做了一个大的图表展示了 [组合到一起的所有步骤](https://manybutfinite.com/img/stack/callSequence.png)。

一旦把它们全部布置好了，看上起似乎很乏味。这些小方框给我们提供了很多帮助。事实上，在计算机科学中，这些小方框是主要的展示工具。我希望这些图片和寄存器的移动能够提供一种更直观的构想图，将栈的增长和内存的内容整合到一起。从软件的底层运作来看，我们的软件与一个简单的图灵机器差不多。

这就是我们栈探秘的第一部分，再讲一些内容之后，我们将看到构建在这个基础上的高级编程的概念。下周见！

---

via:<https://manybutfinite.com/post/journey-to-the-stack/>

作者：[Gustavo Duarte](http://duartes.org/gustavo/blog/about/) 译者：[qhwdw](https://github.com/qhwdw) 校对：[wxy](https://github.com/wxy)

本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译，[Linux中国](https://linux.cn/) 荣誉推出


从专有到开源的十个简单步骤

Summary: 这个共同福利并不适用于专有软件：保持隐藏的东西是不能照亮或丰富这个世界的。

这个共同福利并不适用于专有软件：保持隐藏的东西是不能照亮或丰富这个世界的。

# 从专有到开源的十个简单步骤

>
> 这个共同福利并不适用于专有软件：保持隐藏的东西是不能照亮或丰富这个世界的。
>
>
>

“开源软件肯定不太安全，因为每个人都能看到它的源代码，而且他们能重新编译它，用他们自己写的不好的东西进行替换。”举手示意：谁之前听说过这个说法？ 注1

当我和客户讨论的时候（是的，他们有时候会让我和客户交谈），对于这个领域 注2 的人来说种问题是很常见的。在前一篇文章中，“[许多只眼睛的审查并不一定能防止错误代码]”，我谈论的是开源软件（尤其是安全软件）并不能神奇地比专有软件更安全，但是和专有软件比起来，我每次还是比较青睐开源软件。但我听到“关于开源软件不是很安全”这种问题表明了有时候只是说“开源需要参与”是不够的，我们也需要积极的参与辩护 注3 。

我并不期望能够达到牛顿或者维特根斯坦的逻辑水平，但是我会尽我所能，而且我会在结尾做个总结，如果你感兴趣的话可以去快速的浏览一下。

### 关键因素

首先，我们必须明白没有任何软件是完美的 注6 。无论是专有软件还是开源软件。第二，我们应该承认确实还是存在一些很不错的专有软件的，以及第三，也存在一些糟糕的开源软件。第四，有很多非常聪明的，很有天赋的，专业的架构师、设计师和软件工程师设计开发了专有软件。

但也有些问题：第五，从事专有软件的人员是有限的，而且你不可能总是能够雇佣到最好的员工。即使在政府部门或者公共组织 —— 他们拥有丰富的人才资源池，但在安全应用这块，他们的人才也是有限的。第六，可以查看、测试、改进、拆解、再次改进和发布开源软件的人总是无限的，而且还包含最好的人才。第七（也是我最喜欢的一条），这群人也包含很多编写专有软件的人才。第八，许多政府或者公共组织开发的软件也都逐渐开源了。

第九，如果你在担心你在运行的软件的不被支持或者来源不明，好消息是：有一批组织 注7 会来检查软件代码的来源，提供支持、维护和补丁更新。他们会按照专利软件模式那样去运行开源软件，你也可以确保你从他们那里得到的软件是正确的软件：他们的技术标准就是对软件包进行签名，以便你可以验证你正在运行的开源软件不是来源不明或者是恶意的软件。

第十（也是这篇文章的重点），当你运行开源软件，测试它，对问题进行反馈，发现问题并且报告的时候，你就是在为<ruby> 共同福利 <rt>  commonwealth </rt></ruby>贡献知识、专业技能以及经验，这就是开源，其因为你的所做的这些而变得更好。如果你是通过个人或者提供支持开源软件的商业组织之一 注8 参与的，你已经成为了这个共同福利的一部分了。开源让软件变得越来越好，你可以看到它们的变化。没有什么是隐藏封闭的，它是完全开放的。事情会变坏吗？是的，但是我们能够及时发现问题并且修复。

这个共同福利并不适用于专有软件：保持隐藏的东西是不能照亮或丰富这个世界的。

我知道作为一个英国人在使用<ruby> 共同福利 <rt>  commonwealth </rt></ruby>这个词的时候要小心谨慎的；它和帝国连接着的，但我所表达的不是这个意思。它不是克伦威尔 注9 在对这个词所表述的意思，无论如何，他是一个有争议的历史人物。我所表达的意思是这个词有“共同”和“福利”连接，福利不是指钱而是全人类都能拥有的福利。

我真的很相信这点的。如果i想从这篇文章中得到一些虔诚信息的话，那应该是第十条 注10 ：共同福利是我们的遗产，我们的经验，我们的知识，我们的责任。共同福利是全人类都能拥有的。我们共同拥有它而且它是一笔无法估量的财富。

### 便利贴

1. （几乎）没有一款软件是完美无缺的。
2. 有很好的专有软件。
3. 有不好的专有软件。
4. 有聪明，有才能，专注的人开发专有软件。
5. 从事开发完善专有软件的人是有限的，即使在政府或者公共组织也是如此。
6. 相对来说从事开源软件的人是无限的。
7. …而且包括很多从事专有软件的人才。
8. 政府和公共组织的人经常开源它们的软件。
9. 有商业组织会为你的开源软件提供支持。
10. 贡献--即使是使用--为开源软件贡献。

### 脚注

* 注1： 好的--你现在可以放下手了
* 注2：这应该大写吗？有特定的领域吗？或者它是如何工作的？我不确定。
* 注3：我有一个英国文学和神学的学位--这可能不会惊讶到我的文章的普通读者 注4 。
* 注4： 我希望不是，因为我说的太多神学了 注5 。但是它经常充满了冗余的，无关紧要的人文科学引用。
* 注5： Emacs，每一次。
* 注6： 甚至是 Emacs。而且我知道有技术能够去证明一些软件的正确性。（我怀疑 Emacs 不能全部通过它们...）
* 注7： 注意这里：我被他们其中之一 [Red Hat](https://www.redhat.com/) 所雇佣，去查看一下--它是一个有趣的工作地方，而且[我们经常在招聘](https://www.redhat.com/en/jobs)。
* 注8： 假设他们完全遵守他们正在使用的开源软件许可证。
* 注9： 昔日的“英格兰、苏格兰、爱尔兰的上帝守护者”--比克伦威尔。
* 注10： 很明显，我选择 Emacs 而不是 Vi 变体。

这篇文章原载于 [Alice, Eve, and Bob - a security blog] 而且已经被授权重新发布。

---

via: <https://opensource.com/article/17/11/commonwealth-open-source>

作者：[Mike Bursell](https://opensource.com/users/mikecamel) 译者：[FelixYFZ](https://github.com/FelixYFZ) 校对：[wxy](https://github.com/wxy)

本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译，[Linux中国](https://linux.cn/) 荣誉推出


如何在 Linux 终端下检查笔记本电池状态

# 如何在 Linux 终端下检查笔记本电池状态

在图形界面下查看你的笔记本电池状态是很容易的，只需将鼠标指向任务栏中的电池图标上，你便可以很容易地知道电池的电量。但如果我们想要从命令行中获得这些信息呢？并不是所有人都知道如何做到这点。前几天我的一个朋友询问我如何从他的 Ubuntu 系统里，在终端中查看他的笔记本电池的电量。这便是我写这篇文章的起因。在本文中我概括了三种简单的方法来让你在任何 Linux 发行版本中从终端查看笔记本电池的状态。

### 在终端下检查笔记本电池状态

我们可以使用下面的三种方法来从命令行中查找到笔记本电池状态。

#### 方法一 – 使用 upower 命令

`upower` 命令预装在大多数的 Linux 发行版本中。为了使用 `upower` 命令来展示电池的状态，打开终端并运行如下命令：

```
$ upower -i /org/freedesktop/UPower/devices/battery_BAT0

```

示例输出：

```
native-path: BAT0
vendor: Samsung SDI
model: DELL 7XFJJA2
serial: 4448
power supply: yes
updated: Sat 12 May 2018 06:48:48 PM IST (41 seconds ago)
has history: yes
has statistics: yes
battery
present: yes
rechargeable: yes
state: charging
warning-level: none
energy: 43.3011 Wh
energy-empty: 0 Wh
energy-full: 44.5443 Wh
energy-full-design: 48.84 Wh
energy-rate: 9.8679 W
voltage: 12.548 V
time to full: 7.6 minutes
percentage: 97%
capacity: 91.2045%
technology: lithium-ion
icon-name: 'battery-full-charging-symbolic'
History (charge):
1526131128 97.000 charging
History (rate):
1526131128 9.868 charging

```

正如你所看到的那样，我的电池正处于充电状态，并且它的电量百分比是 97%。

假如上面的命令因为某些未知原因不起作用，可以尝试使用下面的命令：

```
$ upower -i `upower -e | grep 'BAT'`

```

示例输出：

```
native-path: BAT0
vendor: Samsung SDI
model: DELL 7XFJJA2
serial: 4448
power supply: yes
updated: Sat 12 May 2018 06:50:49 PM IST (22 seconds ago)
has history: yes
has statistics: yes
battery
present: yes
rechargeable: yes
state: charging
warning-level: none
energy: 43.6119 Wh
energy-empty: 0 Wh
energy-full: 44.5443 Wh
energy-full-design: 48.84 Wh
energy-rate: 8.88 W
voltage: 12.552 V
time to full: 6.3 minutes
percentage: 97%
capacity: 91.2045%
technology: lithium-ion
icon-name: 'battery-full-charging-symbolic'
History (rate):
1526131249 8.880 charging

```

`upower` 不仅可以显示出电池的状态，它还可以显示出已安装电池的其他完整信息，例如电池型号，供应商名称，电池的序列号，电池的状态，电池的电压等信息。

当然，如果你只想显示电池的状态，你可以可以结合使用 `upower` 命令和[grep](https://www.ostechnix.com/the-grep-command-tutorial-with-examples-for-beginners/) 命令，具体命令如下：

```
$ upower -i $(upower -e | grep BAT) | grep --color=never -E "state|to\ full|to\ empty|percentage"

```

示例输出：

```
state: fully-charged
percentage: 100%

```

从上面的输出中可以看到我的笔记本电池已经完全充满了。

想知晓更多的细节，可以参看 man 页：

```
$ man upower

```

#### 方法二 – 使用 acpi 命令

`acpi` 命令可以用来显示你的 Linux 发行版本中电池的状态以及其他 ACPI 信息。

在某些 Linux 发行版本中，你可能需要安装 `acpi` 命令。

要在 Debian、 Ubuntu 及其衍生版本中安装它，可以使用如下命令：

```
$ sudo apt-get install acpi

```

在 RHEL、 CentOS、 Fedora 等系统中使用：

```
$ sudo yum install acpi

```

或者使用如下命令：

```
$ sudo dnf install acpi

```

在 Arch Linux 及其衍生版本中使用：

```
$ sudo pacman -S acpi

```

一旦 `acpi` 安装好后，运行下面的命令：

```
$ acpi -V

```

注意： 在上面的命令中， `V` 是大写字母。

示例输出：

```
Battery 0: Charging, 99%, 00:02:09 until charged
Battery 0: design capacity 4400 mAh, last full capacity 4013 mAh = 91%
Battery 1: Discharging, 0%, rate information unavailable
Adapter 0: on-line
Thermal 0: ok, 77.5 degrees C
Thermal 0: trip point 0 switches to mode critical at temperature 84.0 degrees C
Cooling 0: Processor 0 of 3
Cooling 1: Processor 0 of 3
Cooling 2: LCD 0 of 15
Cooling 3: Processor 0 of 3
Cooling 4: Processor 0 of 3
Cooling 5: intel_powerclamp no state information available
Cooling 6: x86_pkg_temp no state information available

```

首先让我们来检查电池的电量，可以运行：

```
$ acpi

```

示例输出：

```
Battery 0: Charging, 99%, 00:01:41 until charged
Battery 1: Discharging, 0%, rate information unavailable

```

下面，让我们来查看电池的温度：

```
$ acpi -t

```

示例输出：

```
Thermal 0: ok, 63.5 degrees C

```

如果需要将温度以华氏温标显示，可以使用：

```
$ acpi -t -f

```

示例输出：

```
Thermal 0: ok, 144.5 degrees F

```

如果想看看交流电适配器是否连接上了没有，可以运行：

```
$ acpi -a

```

示例输出：

```
Adapter 0: on-line

```

假如交流电适配器没有连接上，则你将看到如下的输出：

```
Adapter 0: off-line

```

想获取更多的信息，可以查看 man 页：

```
$ man acpi

```

#### 方法三 - 使用 batstat 程序

`batstat` 是一个基于 ncurses 的命令行小工具，使用它可以在类 Unix 系统中展示笔记本电池状态。它可以展示如下具体信息：

* 当前电池电量
* 当前电池所存能量
* 充满时所存能量
* 从程序启动开始经历的时间，它不会追踪记录机器休眠的时间
* 电池电量消耗历史数据

安装 `batstat` 轻而易举。使用下面的命令来克隆该程序的最新版本：

```
$ git clone https://github.com/Juve45/batstat.git

```

上面的命令将拉取 `batstat` 的最新版本并将它的内容保存在一个名为 `batstat` 的文件夹中。

首先将目录切换到 `batstat/bin/` 中：

```
$ cd batstat/bin/

```

接着将 `batstat` 二进制文件复制到 `PATH` 环境变量中的某个目录中，例如 `/usr/local/bin/` 目录：

```
$ sudo cp batstat /usr/local/bin/

```

使用下面的命令来让它可被执行：

```
$ sudo chmod +x /usr/local/bin/batstat

```

最后，使用下面的命令来查看你的电池状态。

```
$ batstat

```

示例输出：

从上面的截图中可以看到我的笔记本电池正处于充电状态。

这个小工具还有某些小的限制。在书写本文之时，`batstat` 仅支持显示一个电池的相关信息。而且它只从 `/sys/class/power_supply/` 目录搜集相关的信息。假如你的电池信息被存放在另外的目录中，则这个小工具就不会起作用了。

想知晓更多信息，可以查看 `batstat` 的 [GitHub 主页](https://github.com/Juve45/batstat)。

上面就是今天我要分享的所有内容。当然，可能还有很多其他的命令或者程序来从 Linux 终端检查笔记本的电池状态。据我所知，上面给出的命令都运行良好。假如你知道其他命令来查看电池的状态，请在下面的评论框中让我们知晓。假如你所给出的方法能够起作用，我将对我的这篇文章进行更新。

最后，上面便是今天的全部内容了。更多的优质内容敬请期待，敬请关注！

欢呼吧!

---

via: <https://www.ostechnix.com/how-to-check-laptop-battery-status-in-terminal-in-linux/>

作者：[SK](https://www.ostechnix.com/author/sk/) 选题：[lujun9972](https://github.com/lujun9972) 译者：[FSSlc](https://github.com/FSSlc) 校对：[wxy](https://github.com/wxy)

本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译，[Linux中国](https://linux.cn/) 荣誉推出


如何在 Linux 中使用 find

Summary: 使用正确的参数，find 命令是在你的系统上找到数据的强大而灵活的方式。

使用正确的参数，find 命令是在你的系统上找到数据的强大而灵活的方式。

# 如何在 Linux 中使用 find

>
> 使用正确的参数，`find` 命令是在你的系统上找到数据的强大而灵活的方式。
>
>
>

<img src="content_image/album_201805_16_083712gelll7esoold7o7l.png" alt="" title="">

在[最近的一篇文章](/article-9585-1.html)中，Lewis Cowles 介绍了 `find` 命令。

`find` 是日常工具箱中功能更强大、更灵活的命令行工具之一，因此值得花费更多的时间。

最简单的，`find` 跟上路径寻找一些东西。例如：

```
find /

```

它将找到（并打印出）系统中的每个文件。而且由于一切都是文件，你会得到很多需要整理的输出。这可能不能帮助你找到你要找的东西。你可以改变路径参数来缩小范围，但它不会比使用 `ls` 命令更有帮助。所以你需要考虑你想要找的东西。

也许你想在主目录中找到所有的 JPEG 文件。 `-name` 参数允许你将结果限制为与给定模式匹配的文件。

```
find ~ -name '*jpg'

```

可是等等！如果它们中的一些是大写的扩展名会怎么样？`-iname` 就像 `-name`，但是不区分大小写。

```
find ~ -iname '*jpg'

```

很好！但是 8.3 名称方案是如此的老。一些图片可能是 .jpeg 扩展名。幸运的是，我们可以将模式用“或”（表示为 `-o`）来组合。

```
find ~ ( -iname 'jpeg' -o -iname 'jpg' )

```

我们正在接近目标。但是如果你有一些以 jpg 结尾的目录呢？ （为什么你要命名一个 `bucketofjpg` 而不是 `pictures` 的目录就超出了本文的范围。）我们使用 `-type` 参数修改我们的命令来查找文件。

```
find ~ \( -iname '*jpeg' -o -iname '*jpg' \) -type f

```

或者，也许你想找到那些命名奇怪的目录，以便稍后重命名它们：

```
find ~ \( -iname '*jpeg' -o -iname '*jpg' \) -type d

```

你最近拍了很多照片，所以让我们把它缩小到上周更改的文件。

```
find ~ \( -iname '*jpeg' -o -iname '*jpg' \) -type f -mtime -7

```

你可以根据文件状态更改时间 （`ctime`）、修改时间 （`mtime`） 或访问时间 （`atime`） 来执行时间过滤。 这些是在几天内，所以如果你想要更细粒度的控制，你可以表示为在几分钟内（分别是 `cmin`、`mmin` 和 `amin`）。 除非你确切地知道你想要的时间，否则你可能会在 `+` （大于）或 `-` （小于）的后面加上数字。

但也许你不关心你的照片。也许你的磁盘空间不够用，所以你想在 `log` 目录下找到所有巨大的（让我们定义为“大于 1GB”）文件：

```
find /var/log -size +1G

```

或者，也许你想在 `/data` 中找到 bcotton 拥有的所有文件：

```
find /data -owner bcotton

```

你还可以根据权限查找文件。也许你想在你的主目录中找到对所有人可读的文件，以确保你不会过度分享。

```
find ~ -perm -o=r

```

这篇文章只说了 `find` 能做什么的表面。将测试条件与布尔逻辑相结合可以为你提供难以置信的灵活性，以便准确找到要查找的文件。并且像 `-exec` 或 `-delete` 这样的参数，你可以让 `find` 对它发现的内容采取行动。你有任何最喜欢的 `find` 表达式么？在评论中分享它们！

---

via: <https://opensource.com/article/18/4/how-use-find-linux>

作者：[Ben Cotton](https://opensource.com/users/bcotton) 选题：[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/) 荣誉推出


在 5 分钟内重置丢失的 root 密码

# 在 5 分钟内重置丢失的 root 密码

>
> 如何快速简单地在 Fedora 、 CentOS 及类似的 Linux 发行版上重置 root 密码。
>
>
>

系统管理员可以轻松地为忘记密码的用户重置密码。但是如果系统管理员忘记 root 密码或他从公司离职了，会发生什么情况？本指南将向你介绍如何在不到 5 分钟的时间内在 Red Hat 兼容系统（包括 Fedora 和 CentOS）上重置丢失或忘记的 root 密码。

请注意，如果整个系统硬盘已用 LUKS 加密，则需要在出现提示时提供 LUKS 密码。此外，此过程适用于运行 systemd 的系统，该系统自 Fedora 15、CentOS 7.14.04 和 Red Hat Enterprise Linux 7.0 以来一直是缺省的初始系统。

首先你需要中断启动的过程，因此你需要启动或者如果已经启动就重启它。第一步可能有点棘手因为 GRUB 菜单会在屏幕上快速地闪烁过去。你可能需要尝试几次，直到你能够做到这一点。

当你看到这个屏幕时，按下键盘上的 `e` 键：

如果你正确地做了这点，你应该看到一个类似于这个的屏幕：

使用箭头键移动到 `Linux16` 这行：

使用你的 `del` 键或你的 `backspace` 键，删除 `rhgb quiet` 并替换为以下内容：

```
rd.break enforcing=0

```

设置 `enforcing=0` 可以避免执行完整的系统 SELinux 重标记。一旦系统重新启动，你只需要为 `/etc/shadow` 恢复正确的 SELinux 上下文。我会告诉你如何做到这一点。

按下 `Ctrl-x` 启动。

**系统现在将处于紧急模式。**

以读写权限重新挂载硬盘驱动器：

```
# mount –o remount,rw /sysroot

```

运行 `chroot` 来访问系统：

```
# chroot /sysroot

```

你现在可以更改 root 密码：

```
# passwd

```

出现提示时，输入新的 root 密码两次。如果成功，你应该看到一条消息显示 “all authentication tokens updated successfully”。

输入 `exit` 两次以重新启动系统。

以 root 身份登录并恢复 `/etc/shadow` 的 SELinux 标签。

```
# restorecon -v /etc/shadow

```

将 SELinux 回到 enforce 模式：

```
# setenforce 1

```

---

via: <https://opensource.com/article/18/4/reset-lost-root-password>

作者：[Curt Warfield](https://opensource.com/users/rcurtiswarfield) 选题：[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/) 荣誉推出


使用 syslog-ng 可靠地记录物联网事件

Summary: 用增强的日志守护进程 syslog-ng 来监控你的物联网设备。

用增强的日志守护进程 syslog-ng 来监控你的物联网设备。

# 使用 syslog-ng 可靠地记录物联网事件

>
> 用增强的日志守护进程 syslog-ng 来监控你的物联网设备。
>
>
>

<img src="content_image/album_201805_17_094849iinnwxitxxn6tbtw.jpg" alt="" title="">

现在，物联网设备和嵌入式系统越来越多。对于许多连接到因特网或者一个网络的设备来说，记录事件很有必要，因为你需要知道这些设备都做了些什么事情，这样你才能够解决可能出现的问题。

可以考虑去使用的一个监视工具是开源的 [syslog-ng](https://syslog-ng.com/open-source-log-management) 应用程序，它是一个强化的、致力于可移植的、中心化的日志收集守护程序。它可以从许多不同种类的来源、进程来收集日志，并且可以对这些日志进行处理和过滤，也可以存储或者路由它们，以便于做进一步的分析。syslog-ng 的大多数代码是用高效率的、高可移植的 C 代码写成的。它能够适用于各种场景，无论你是将它运行在一个处理能力很弱的设备上做一些简单的事情，还是运行在数据中心从成千上万的机器中收集日志的强大应用，它都能够胜任。

你可能注意到在这个段落中，我使用了大量的溢美词汇。为了让你更清晰地了解它，我们来复习一下，但这将花费更多的时间，也了解的更深入一些。

### 日志

首先解释一下日志。<ruby> 日志 <rt>  logging </rt></ruby>是记录一台计算机上事件的东西。在一个典型的 Linux 机器上，你可以在 `/var/log` 目录中找到这些信息。例如，如果你通过 SSH 登录到机器中，你将可以在其中一个日志文件中找到类似于如下内容的信息：

```
Jan 14 11:38:48 linux-0jbu sshd[7716]: Accepted publickey for root from 127.0.0.1 port 48806 ssh2

```

日志的内容可能是关于你的 CPU 过热、通过 HTTP 下载了一个文档，或者你的应用程序认为重要的任何东西。

### syslog-ng

正如我在上面所写的那样，syslog-ng 应用程序是一个强化的、致力于可移植性、和中心化的日志收集守护程序。守护程序的意思是，syslog-ng 是一个持续运行在后台的应用程序，在这里，它用于收集日志信息。

虽然现在大多数应用程序的 Linux 测试是限制在 x86\_64 的机器上，但是，syslog-ng 也可以运行在大多数 BSD 和商业 UNIX 变种版本上的。从嵌入式/物联网的角度来看，这种能够运行在不同的 CPU 架构（包括 32 位和 64 位的 ARM、PowerPC、MIPS 等等）的能力甚至更为重要。（有时候，我通过阅读关于 syslog-ng 是如何使用它们的来学习新架构）

为什么中心化的日志收集如此重要？其中一个很重要的原因是易于使用，因为它放在一个地方，不用到成百上千的机器上挨个去检查它们的日志。另一个原因是可用性 —— 即使一个设备不论是什么原因导致了它不可用，你都可以检查这个设备的日志信息。第三个原因是安全性；当你的设备被黑，检查设备日志可以发现攻击的踪迹。

### syslog-ng 的四种用法

syslog-ng 有四种主要的用法：收集、处理、过滤、和保存日志信息。

**收集信息：** syslog-ng 能够从各种各样的 [特定平台源](https://syslog-ng.com/documents/html/syslog-ng-ose-latest-guides/en/syslog-ng-ose-guide-admin/html/sources.html) 上收集信息，比如 `/dev/log`，`journal`，或者 `sun-streams`。作为一个中心化的日志收集器，传统的（`rfc3164`）和最新的（`rfc5424`）系统日志协议、以及它们基于 UDP、TCP 和加密连接的各种变种，它都是支持的。你也可以从管道、套接字、文件、甚至应用程序输出来收集日志信息（或者各种文本数据）。

**处理日志信息：** 它的处理能力几乎是无限的。你可以用它内置的解析器来分类、规范，以及结构化日志信息。如果它没有为你提供在你的应用场景中所需要的解析器，你甚至可以用 Python 来自己写一个解析器。你也可以使用地理数据来丰富信息，或者基于信息内容来附加一些字段。日志信息可以按处理它的应用程序所要求的格式进行重新格式化。你也可以重写日志信息 —— 当然了，不是篡改日志内容 —— 比如在某些情况下，需要满足匿名要求的信息。

**过滤日志：** 过滤日志的用法主要有两种：丢弃不需要保存的日志信息 —— 像调试级别的信息；和路由日志信息—— 确保正确的日志到达正确的目的地。后一种用法的一个例子是，转发所有的认证相关的信息到一个安全信息与事件管理系统（SIEM）。

**保存信息：** 传统的做法是，将文件保存在本地或者发送到中心化日志服务器；不论是哪种方式，它们都被发送到一个[普通文件](https://en.wikipedia.org/wiki/Flat_file_database)。经过这些年的改进，syslog-ng 已经开始支持 SQL 数据库，并且在过去的几年里，包括 HDFS、Kafka、MongoDB、和 Elasticsearch 在内的大数据存储，都被加入到 syslog-ng 的支持中。

### 消息格式

当在你的 `/var/log` 目录中查看消息时，你将看到（如上面的 SSH 信息）大量的消息都是如下格式的内容：

```
日期 + 主机名 + 应用名 + 一句几乎完整的英文信息

```

在这里的每个应用程序事件都是用不同的语法描述的，基于这些数据去创建一个报告是个痛苦的任务。

解决这种混乱信息的一个方案是使用结构化日志。在这种情况下，事件被表示为键-值对，而不是随意的日志信息。比如，一个 SSH 日志能够按应用程序名字、源 IP 地址、用户名、认证方法等等来描述。

你可以从一开始就对你的日志信息按合适的格式进行结构化处理。当处理传统的日志信息时，你可以在 syslog-ng 中使用不同的解析器，转换非结构化（和部分结构化）的信息为键-值对格式。一旦你的日志信息表示为键-值对，那么，报告、报警、以及简单查找信息将变得很容易。

### 物联网日志

我们从一个棘手的问题开始：哪个版本的 syslog-ng 最流行？在你回答之前，想想如下这些事实：这个项目启动于 20 年以前，Red Hat 企业版 Linux EPEL 已经有了 3.5 版，而当前版本是 3.14。当我在我的演讲中问到这个问题时，观众通常回答是他们用的 Linux 发行版中自带的那个。你们绝对想不到的是，正确答案竟然是 1.6 版最流行，这个版本已经有 15 年的历史的。这什么这个版本是最为流行的，因为它是包含在亚马逊 Kindle 阅读器中的版本，它是电子书阅读器，因为它运行在全球范围内超过 1 亿台的设备上。另外一个在消费类设备上运行 syslog-ng 的例子是 BMW i3 电动汽车。

Kindle 使用 syslog-ng 去收集关于用户在这台设备上都做了些什么事情等所有可能的信息。在 BMW 电动汽车上，syslog-ng 所做的事情更复杂，基于内容过滤日志信息，并且在大多数情况下，只记录最重要的日志。

使用 syslog-ng 的其它类别设备还有网络和存储。一些比较知名的例子有，Turris Omnia 开源 Linux 路由器和群晖 NAS 设备。在大多数案例中，syslog-ng 是在设备上作为一个日志客户端来运行，但是在有些案例中，它运行为一个有丰富 Web 界面的中心日志服务器。

你还可以在一些行业服务中找到 syslog-ng 的身影。它运行在来自美国国家仪器有限公司（NI）的实时 Linux 设备上，执行测量和自动化任务。它也被用于从定制开发的应用程序中收集日志。从命令行就可以做配置，但是一个漂亮的 GUI 可用于浏览日志。

最后，还有大量的项目，比如，汽车和飞机，syslog-ng 在它们上面既可以运行为客户端，也可以运行为服务端。在这种使用案例中，syslog-ng 一般用来收集所有的日志和测量数据，然后发送它们到处理这些日志的中心化服务器集群上，然后保存它们到支持大数据的目的地，以备进一步分析。

### 对物联网的整体益处

在物联网环境中使用 syslog-ng 有几个好处。第一，它的分发性能很高，并且是一个可靠的日志收集器。第二，它的架构也很简单，因此，系统、应用程序日志、以及测量数据可以被一起收集。第三，它使数据易于使用，因为，数据可以被解析和表示为易于使用的格式。最后，通过 syslog-ng 的高效路由和过滤功能，可以显著降低处理程序的负载水平。

---

via: <https://opensource.com/article/18/3/logging-iot-events-syslog-ng>

作者：[Peter Czanik](https://opensource.com/users/czanik) 选题：[lujun9972](https://github.com/lujun9972) 译者：[qhwdw](https://github.com/qhwdw) 校对：[wxy](https://github.com/wxy)

本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译，[Linux中国](https://linux.cn/) 荣誉推出


在 KVM 中测试 IPv6 网络：第 2 部分

# 在 KVM 中测试 IPv6 网络：第 2 部分

我们又见面了，在上一篇 [在 KVM 中测试 IPv6 网络：第 1 部分](/article-9594-1.html) 中，我们学习了有关 IPv6 私有地址的内容。今天，我们将使用 KVM 创建一个网络，去测试上一星期学习的 IPv6 的内容。

如果你想重新温习如何使用 KVM，可以查看 [在 KVM 中创建虚拟机：第 1 部分](https://www.linux.com/learn/intro-to-linux/2017/5/creating-virtual-machines-kvm-part-1) 和 [在 KVM 中创建虚拟机：第 2 部分— 网络](https://www.linux.com/learn/intro-to-linux/2017/5/creating-virtual-machines-kvm-part-2-networking)。

### 在 KVM 中创建网络

在 KVM 中你至少需要两个虚拟机。当然了，如果你愿意，也可以创建更多的虚拟机。在我的系统中有 Fedora、Ubuntu、以及 openSUSE。去创建一个新的 IPv6 网络，在主虚拟机管理窗口中打开 “Edit > Connection Details > Virtual Networks”。点击左下角的绿色十字按钮去创建一个新的网络（图 1）。

*图 1：创建一个网络*

给新网络输入一个名字，然后，点击 “Forward” 按钮。如果你愿意，也可以不创建 IPv4 网络。当你创建一个新的 IPv4 网络时，虚拟机管理器将不让你创建重复网络，或者是使用了一个无效地址。在我的宿主机 Ubuntu 系统上，有效的地址是以绿色高亮显示的，而无效地址是使用高亮的玫瑰红色调。在我的 openSUSE 机器上没有高亮颜色。启用或不启用 DHCP，以及创建或不创建一个静态路由，然后进入下一个窗口。

选中 “Enable IPv6 network address space definition”，然后输入你的私有地址范围。你可以使用任何你希望的 IPv6 地址类，但是要注意，不能将你的实验网络泄漏到公网上去。我们将使用非常好用的 IPv6 唯一本地地址（ULA），并且使用在 [Simple DNS Plus](http://simpledns.com/private-ipv6.aspx) 上的在线地址生成器，去创建我们的网络地址。拷贝 “Combined/CID” 地址到网络框中（图 2）。

*图 2：拷贝 "Combined/CID" 地址到网络框中*

虚拟机认为我的地址是无效的，因为，它显示了高亮的玫瑰红色。它做的对吗？我们使用 `ipv6calc` 去验证一下：

```
$ ipv6calc -qi fd7d:844d:3e17:f3ae::/64
Address type: unicast, unique-local-unicast, iid, iid-local
Registry for address: reserved(RFC4193#3.1)
Address type has SLA: f3ae
Interface identifier: 0000:0000:0000:0000
Interface identifier is probably manual set

```

`ipv6calc` 认为没有问题。如果感兴趣，你可以改变其中一个数字为无效的东西，比如字母 `g`，然后再试一次。（问 “如果…？”，试验和错误是最好的学习方法）。

我们继续进行，启用 DHCPv6（图 3）。你可以接受缺省值，或者输入一个你自己的设置值。

*图 3： 启用 DHCPv6*

我们将跳过缺省路由定义这一步，继续进入下一屏，在那里我们将启用 “Isolated Virtual Network” 和 “Enable IPv6 internal routing/networking”。

### 虚拟机网络选择

现在，你可以配置你的虚拟机去使用新的网络。打开你的虚拟机，然后点击顶部左侧的 “i” 按钮去打开 “Show virtual hardware details” 屏幕。在 “Add Hardware” 列点击 “NIC” 按钮去打开网络选择器，然后选择你喜欢的新的 IPv6 网络。点击 “Apply”，然后重新启动。（或者使用你喜欢的方法去重新启动网络，或者更新你的 DHCP 租期。）

### 测试

`ifconfig` 告诉我们它做了什么？

```
$ ifconfig
ens3: flags=4163 UP,BROADCAST,RUNNING,MULTICAST  mtu 1500
 inet 192.168.30.207  netmask 255.255.255.0
   broadcast 192.168.30.255
 inet6 fd7d:844d:3e17:f3ae::6314
   prefixlen 128  scopeid 0x0
 inet6 fe80::4821:5ecb:e4b4:d5fc
   prefixlen 64  scopeid 0x20

```

这是我们新的 ULA，`fd7d:844d:3e17:f3ae::6314`，它是自动生成的本地链路地址。如果你有兴趣，可以 ping 一下，ping 网络上的其它虚拟机：

```
vm1 ~$ ping6 -c2 fd7d:844d:3e17:f3ae::2c9f
PING fd7d:844d:3e17:f3ae::2c9f(fd7d:844d:3e17:f3ae::2c9f) 56 data bytes
64 bytes from fd7d:844d:3e17:f3ae::2c9f: icmp_seq=1 ttl=64 time=0.635 ms
64 bytes from fd7d:844d:3e17:f3ae::2c9f: icmp_seq=2 ttl=64 time=0.365 ms

vm2 ~$ ping6 -c2 fd7d:844d:3e17:f3ae:a:b:c:6314
PING fd7d:844d:3e17:f3ae:a:b:c:6314(fd7d:844d:3e17:f3ae:a:b:c:6314) 56 data bytes
64 bytes from fd7d:844d:3e17:f3ae:a:b:c:6314: icmp_seq=1 ttl=64 time=0.744 ms
64 bytes from fd7d:844d:3e17:f3ae:a:b:c:6314: icmp_seq=2 ttl=64 time=0.364 ms

```

当你努力去理解子网时，这是一个可以让你尝试不同地址是否可以正常工作的快速易用的方法。你可以给单个接口分配多个 IP 地址，然后 ping 它们去看一下会发生什么。在一个 ULA 中，接口，或者主机是 IP 地址的最后四部分，因此，你可以在那里做任何事情，只要它们在同一个子网中即可，在那个例子中是 `f3ae`。在我的其中一个虚拟机上，我只改变了这个示例的接口 ID，以展示使用这四个部分，你可以做任何你想做的事情：

```
vm1 ~$ sudo /sbin/ip -6 addr add fd7d:844d:3e17:f3ae:a:b:c:6314 dev ens3

vm2 ~$ ping6 -c2 fd7d:844d:3e17:f3ae:a:b:c:6314
PING fd7d:844d:3e17:f3ae:a:b:c:6314(fd7d:844d:3e17:f3ae:a:b:c:6314) 56 data bytes
64 bytes from fd7d:844d:3e17:f3ae:a:b:c:6314: icmp_seq=1 ttl=64 time=0.744 ms
64 bytes from fd7d:844d:3e17:f3ae:a:b:c:6314: icmp_seq=2 ttl=64 time=0.364 ms

```

现在，尝试使用不同的子网，在下面的示例中使用了 `f4ae` 代替 `f3ae`：

```
$ ping6 -c2 fd7d:844d:3e17:f4ae:a:b:c:6314
PING fd7d:844d:3e17:f4ae:a:b:c:6314(fd7d:844d:3e17:f4ae:a:b:c:6314) 56 data bytes
From fd7d:844d:3e17:f3ae::1 icmp_seq=1 Destination unreachable: No route
From fd7d:844d:3e17:f3ae::1 icmp_seq=2 Destination unreachable: No route

```

这也是练习路由的好机会，以后，我们将专门做一期，如何在不使用 DHCP 情况下实现自动寻址。

---

via: <https://www.linux.com/learn/intro-to-linux/2017/11/testing-ipv6-networking-kvm-part-2>

作者：[CARLA SCHRODER](https://www.linux.com/users/cschroder) 选题：[lujun9972](https://github.com/lujun9972) 译者：[qhwdw](https://github.com/qhwdw) 校对：[wxy](https://github.com/wxy)

本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译，[Linux中国](https://linux.cn/) 荣誉推出


成为你所在社区的美好力量

Summary: 明白如何传递美好，了解积极意愿的力量，以及更多。

明白如何传递美好，了解积极意愿的力量，以及更多。

# 成为你所在社区的美好力量

>
> 明白如何传递美好，了解积极意愿的力量，以及更多。
>
>
>

<img src="content_image/album_201805_17_224122lcp16v5ipkgfuvs1.png" alt="Be a force for good in your community" title="Be a force for good in your community">

激烈的争论是开源社区和开放组织的标志特征之一。在好的时候，这些争论充满活力和建设性。他们面红耳赤的背后其实是幽默和善意。各方实事求是，共同解决问题，推动持续改进。对我们中的许多人来说，他们只是单纯的喜欢而已。

然而在那些不好的日子里，这些争论演变成了对旧话题的反复争吵。或者我们用各种方式来传递伤害和相互攻击，或是使用卑劣的手段，而这些侵蚀着我们社区的激情、信任和生产力。

我们茫然四顾，束手无策，因为社区的对话开始变得有毒。然而，正如 [DeLisa Alexander 最近的分享](https://opensource.com/business/15/5/5-ways-promote-inclusive-environment)，我们每个人都有很多方法可以成为我们社区的一种力量。

在这个“开源文化”系列的第一篇文章中，我将分享一些策略，教你如何在这个关键时刻进行干预，引导每个人走向更积极、更有效率的方向。

### 不要将人推开，而是将人推向前方

最近，我和我的朋友和同事 [Mark Rumbles](https://twitter.com/leadership_365) 一起吃午饭。多年来，我们在许多支持开源文化和引领 Red Hat 的项目中合作。在这一天，Mark 问我，他看到我最近介入了一个邮件列表的对话，当其中的辩论越来越过分时我是怎么坚持的。

幸运的是，这事早已尘埃落定，事实上我几乎忘记了谈话的内容。然而，它让我们开始讨论如何在一个拥有数千名成员的社区里，公开和坦率的辩论。

Mark 说了一些让我印象深刻的话。他说:“你知道，作为一个社区，我们真的很擅长将人推开。但我想看到的是，我们更多的是互相扶持 *向前* 。”

Mark 是绝对正确的。在我们的社区里，我们成为一种美好力量的最好的方法之一就是：以一种迫使每个人提升他们的行为的方式回应冲突，而不是使冲突升级的方式。

### 积极意愿假想

我们可以从一个简单的假想开始，当我们在一个激烈的对话中观察到不良行为时：完全有可能该不良行为其实有着积极意愿。

诚然，这不是一件容易的事情。当我看到一场辩论正在变得肮脏的迹象时，我停下来问自己，史蒂芬·科维（Steven Covey）所说的人性化问题是什么：

>
> “为什么一个理性、正直的人会做这样的事情？”
>
>
>

现在，如果他是你的一个“普通的观察对象”—— 一个有消极行为倾向的社区成员——也许你的第一个想法是，“嗯，也许这个人是个不靠谱，不理智的人”

回过头来说。我并不是说你让你自欺欺人。这其实就是人性化的问题，不仅是因为它让你理解别人的立场，它还让你变得人性化。

而这反过来又能帮助你做出反应，或者从最有效率的地方进行干预。

### 寻求了解社区异议的原因

当我再一次问自己为什么一个理性的、正直的人可能会做这样的事情时，归结为几个原因:

* 他认为没人聆听他
* 他认为没人尊重他
* 他认为没人理解他

一个简单的积极意愿假想，我们可以适用于几乎所有的不良行为，其实就是那个人想要被聆听，被尊重，或被理解。我想这是相当合理的。

通过站在这个更客观、更有同情心的角度，我们可以看到他们的行为几乎肯定 ***不会*** 帮助他们得到他们想要的东西，而社区也会因此而受到影响。如果没有我们的帮助的话。

对我来说，这激发了一个愿望：帮助每个人从我们所处的这个丑陋的地方“摆脱困境”。

在我介入之前，我问自己一个后续的问题：是否有其他积极的意图可能会驱使这种行为

容易想到的例子包括:

* 他们担心我们错过了一些重要的东西，或者我们犯了一个错误，没有人能看到它。
* 他们想感受到自己的贡献的价值。
* 他们精疲力竭，因为在社区里工作过度或者在他们的个人生活中发生了一些事情。
* 他们讨厌一些东西被破坏，并感到沮丧，因为没有人能看到造成的伤害或不便。
* ……诸如此类。

有了这些，我就有了丰富的积极的意图假想，我可以为他们的行为找到原因。我准备伸出援助之手，向他们提供一些帮助。

### 传递美好，挣脱泥潭

什么是 an out？（LCTT 译注：类似与佛家“解脱法门”的意思）把它想象成一个逃跑的门。这是一种退出对话的方式，或者放弃不良的行为，恢复表现得像一个体面的人，而不是丢面子。是叫某人振作向上，而不是叫他走开。

你可能经历过这样的事情，在你的生活中，当 *你* 在一次谈话中表现不佳时，咆哮着，大喊大叫，对某事大惊小怪，而有人慷慨地给 *你* 提供了一个台阶下。也许他们选择不去和你“抬杠”，相反，他们说了一些表明他们相信你是一个理性、正直的人，他们采用积极意愿假想，比如:

>
> 所以，嗯，我听到的是你真的很担心，你很沮丧，因为似乎没有人在听。或者你担心我们忽略了它的重要性。是这样对吧？
>
>
>

于是乎：即使这不是完全正确的（也许你的意图不那么高尚），在那一刻，你可能抓住了他们提供给你的台阶，并欣然接受了重新定义你的不良行为的机会。你几乎可以肯定地转向一个更富有成效的角度，甚至你自己可能都没有意识到。

也许你这样说，“哦，虽然不完全是这样，但我只是担心，我们这样会走向歧途，我明白你说的，作为社区，我们不能同时解决所有问题，但如果我们不尽快解决这个问题，会有更多不好的事情要发生……”

最后，谈话几乎可以肯定地开始转移到一个更有效率的方向。

我们都有机会让一个沮丧的人挣脱泥潭，而这就是方法。

### 坏行为还是坏人？

如果这个人特别激动，他们可能不会听到或者接受你给出的第一个台阶。没关系。最可能的是，他们迟钝的大脑已经被史前曾经对人类生存至关重要的杏仁体接管了，他们需要更多的时间来认识到你并不是一个威胁。只是需要你保持温和的态度，坚定地对待他们，就好像他们 *曾经是* 一个理性、正直的人，看看会发生什么。

根据我的经验，这些社区干预以三种方式结束:

大多数情况下，这个人实际上 *是* 一个理性的人，很快，他们就感激地接受了这个事实。在这个过程中，每个人都跳出了“黑与白”，“赢或输”的心态。人们开始思考创造性的选择和“双赢”的结果，每个人都将受益。

>
> 为什么一个理性、正直的人会做这样的事呢？
>
>
>

有时候，这个人天生不是特别理性或正直的，但当他被你以如此一致的、不知疲倦的、耐心的慷慨和善良的对待的时候，他们就会羞愧地从谈话中撤退。这听起来像是，“嗯，我想我已经说了所有要说的了。谢谢你听我的意见”。或者，对于不那么开明的人来说，“嗯，我厌倦了这种谈话。让我们结束吧。”（好的，谢谢）。

更少的情况是，这个人是一个“*坏人*”，或者在社区管理圈子里，是一个“搅屎棍”。这些人确实存在，而且他们在演戏方面很有发展。你猜怎么着？通过持续地以一种友善、慷慨、以社区为中心的方式，完全无视所有试图使局势升级的尝试，你有效地将谈话变成了一个对他们没有兴趣的领域。他们别无选择，只能放弃它。你成为赢家。

这就是积极意愿假想的力量。通过对愤怒和充满敌意的言辞做出回应，优雅而有尊严地回应，你就能化解一场战争，理清混乱，解决棘手的问题，而且在这个过程中很有可能会交到一个新朋友。

我每次应用这个原则都成功吗？见鬼，不会。但我从不后悔选择了积极意愿。但是我能生动的回想起，当我采用消极意愿假想时，将问题变得更糟糕的场景。

现在轮到你了。我很乐意听到你提出的一些策略和原则，当你的社区里的对话变得激烈的时候，要成为一股好力量。在下面的评论中分享你的想法。

下次，我们将探索更多的方法，在你的社区里成为一个美好力量，我将分享一些处理“坏脾气先生”的技巧。

---

作者简介：

<ruby> 丽贝卡·费尔南德斯 <rp>  （ </rp> <rt>  Rebecca Fernandez </rt> <rp>  ） </rp></ruby>是红帽公司的首席就业品牌 + 通讯专家，是《开放组织》书籍的贡献者，也是开源决策框架的维护者。她的兴趣是开源和业务管理模型的开源方式。Twitter：@ruhbehka

---

via: <https://opensource.com/open-organization/17/1/force-for-good-community>

作者：[Rebecca Fernandez](https://opensource.com/users/rebecca) 译者：[chao-zhi](https://github.com/chao-zhi) 校对：[wxy](https://github.com/wxy)

本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译，[Linux中国](https://linux.cn/) 荣誉推出


使用树莓派和 projectx/os 托管你自己的电子邮件

Summary: 这个开源项目可以通过低成本的服务器设施帮助你保护你的数据隐私和所有权。

这个开源项目可以通过低成本的服务器设施帮助你保护你的数据隐私和所有权。

# 使用树莓派和 projectx/os 托管你自己的电子邮件

>
> 这个开源项目可以通过低成本的服务器设施帮助你保护你的数据隐私和所有权。
>
>
>

<img src="content_image/album_201805_18_120617zeoe2re6jo8eozt2.jpg" alt="" title="">

现在有大量的理由，不能再将存储你的数据的任务委以他人之手，也不能在第三方公司运行你的服务；隐私、所有权，以及防范任何人拿你的数据去“赚钱”。但是对于大多数人来说，自己去运行一个服务器，是件即费时间又需要太多的专业知识的事情。不得已，我们只能妥协。抛开这些顾虑，使用某些公司的云服务，随之而来的就是广告、数据挖掘和售卖、以及其它可能的任何东西。

[projectx/os](https://git.sigbus.net/projectx/os) 项目就是要去除这种顾虑，它可以在家里毫不费力地做服务托管，并且可以很容易地创建一个类似于 Gmail 的帐户。实现上述目标，你只需一个 $35 的树莓派 3 和一个基于 Debian 的操作系统镜像 —— 并且不需要很多的专业知识。仅需要四步就可以实现：

1. 解压缩一个 ZIP 文件到 SD 存储卡中。
2. 编辑 SD 卡上的一个文本文件以便于它连接你的 WiFi（如果你不使用有线网络的话）。
3. 将这个 SD 卡插到树莓派 3 中。
4. 使用你的智能手机在树莓派 3 上安装 “email 服务器” 应用并选择一个二级域。

服务器应用程序（比如电子邮件服务器）被分解到多个容器中，它们中的每个都只能够使用指定的方式与外界通讯，它们使用了管理粒度非常细的隔离措施以提高安全性。例如，入站 SMTP、[SpamAssassin](http://spamassassin.apache.org/)（反垃圾邮件平台）、[Dovecot](https://www.dovecot.org/) （安全的 IMAP 服务器），以及 webmail 都使用了独立的容器，它们之间相互不能看到对方的数据，因此，单个守护进程出现问题不会波及其它的进程。

另外，它们都是无状态容器，比如 SpamAssassin 和入站 SMTP，每次收到电子邮件之后，它们的容器都会被销毁并重建，因此，即便是有人找到了 bug 并利用了它，他们也不能访问以前的电子邮件或者接下来的电子邮件；他们只能访问他们自己挖掘出漏洞的那封电子邮件。幸运的是，大多数对外发布的、最容易受到攻击的服务都是隔离的和无状态的。

所有存储的数据都使用 [dm-crypt](https://gitlab.com/cryptsetup/cryptsetup/wikis/DMCrypt) 进行加密。非公开的服务，比如 Dovecot（IMAP）或者 webmail，都是在内部监听，并使用 [ZeroTier One](https://www.zerotier.com/download.shtml) 所提供的私有的加密层叠网络，因此只有你的设备（智能手机、笔记本电脑、平板等等）才能访问它们。

虽然电子邮件并不是端到端加密的（除非你使用了 [PGP](https://en.wikipedia.org/wiki/Pretty_Good_Privacy)），但是非加密的电子邮件绝不会跨越网络，并且也不会存储在磁盘上。现在明文的电子邮件只存在于双方的私有邮件服务器上，它们都在他们的家中受到很好的安全保护并且只能通过他们的客户端访问（智能手机、笔记本电脑、平板等等）。

另一个好处就是，个人设备都使用一个密码保护（不是指纹或者其它生物识别技术），而且在你家中的设备都受到美国的 [第四宪法修正案](https://simple.wikipedia.org/wiki/Fourth_Amendment_to_the_United_States_Constitution) 的保护，比起由公司所有的第三方数据中心，它们受到更强的法律保护。当然，如果你的电子邮件使用的是 Gmail，Google 还保存着你的电子邮件的拷贝。

### 展望

电子邮件是我使用 project/os 项目打包的第一个应用程序。想像一下，一个应用程序商店有全部的服务器软件，打包起来易于安装和使用。想要一个博客？添加一个 WordPress 应用程序！想替换安全的 Dropbox ？添加一个 [Seafile](https://www.seafile.com/en/home/) 应用程序或者一个 [Syncthing](https://syncthing.net/) 后端应用程序。 [IPFS](https://ipfs.io/) 节点？ [Mastodon](https://github.com/tootsuite/mastodon) 实例？GitLab 服务器？各种家庭自动化/物联网后端服务？这里有大量的非常好的开源服务器软件 ，它们都非常易于安装，并且可以使用它们来替换那些有专利的云服务。

---

via: <https://opensource.com/article/18/3/host-your-own-email>

作者：[Nolan Leake](https://opensource.com/users/nolan) 译者：[qhwdw](https://github.com/qhwdw) 校对：[wxy](https://github.com/wxy)

本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译，[Linux中国](https://linux.cn/) 荣誉推出


使用 AppImageLauncher 轻松运行和集成 AppImage 文件

# 使用 AppImageLauncher 轻松运行和集成 AppImage 文件

你有没有下载过 AppImage 文件，而你不知道如何使用它？或许你可能知道如何使用它，但是你每次要运行它时必须要进入到下载了该 .AppImage 的文件夹中来运行它，或者手动为其创建启动程序。

使用 AppImageLauncher，这些就都是过去的问题。该程序可让你轻松运行 AppImage 文件，而无需使其可执行。但它最有趣的特点是可以轻松地将 AppImage 与你的系统进行整合：AppImageLauncher 可以自动将 AppImage 程序快捷方式添加到桌面环境的程序启动器/菜单（包括程序图标和合适的说明）中。

这 里有个例子，我想在 Ubuntu 上使用 [Kdenlive](https://kdenlive.org/download/)，但我不想从仓库中安装它，因为它有大量的 KDE 依赖，我不想把它们弄到我的 Gnome 系统中。因为没有它的 Flatpak 或 Snap 镜像，我只能去下载了 Kdenlive 的 AppImage。

在没有把下载的 [Kdenline](https://kdenlive.org/download/) AppImage 变成可执行的情况下，我第一次双击它时（安装好了 AppImageLauncher），AppImageLauncher 提供了两个选项：

“Run once”或者“Integrate and run”。

点击 “Integrate and run”，这个 AppImage 就被复制到 `~/.bin/` （家目录中的隐藏文件夹）并添加到菜单中，然后启动该程序。

要删除它也很简单，只要您使用的桌面环境支持桌面动作就行。例如，在 Gnome Shell 中，只需右键单击“活动概览”中的应用程序图标，然后选择“Remove from system”：

更新：该应用只初步为 Ubuntu 和 Mint 做了开发，但它最近会提供 Debian、 Netrunner 和 openSUSE 支持。本文首次发布后添加的另一个功能是支持 AppImage 的更新；你在启动器中可以找到 “Update AppImage”。

### 下载 AppImageLauncher

AppImageLauncher 支持 Ubuntu、 Debian、Netrunner 和 openSUSE。如果你使用 Ubuntu 18.04，请确保你下载的 deb 包的名字中有“bionic”，而其它的 deb 是用于旧一些的 Ubuntu 版本的。

* [下载 AppImageLauncher](https://github.com/TheAssassin/AppImageLauncher/releases)

---

via: <https://www.linuxuprising.com/2018/04/easily-run-and-integrate-appimage-files.html>

作者：[Logix](https://plus.google.com/118280394805678839070) 译者：[geekpi](https://github.com/geekpi) 校对：[wxy](https://github.com/wxy) 选题：[lujun9972](https://github.com/lujun9972)

本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译，[Linux中国](https://linux.cn/) 荣誉推出


如何创建适合移动设备的文档

Summary: 帮助用户在智能手机或平板上快速轻松地找到他们所需的信息。

帮助用户在智能手机或平板上快速轻松地找到他们所需的信息。

# 如何创建适合移动设备的文档

>
> 帮助用户在智能手机或平板上快速轻松地找到他们所需的信息。
>
>
>

我并不是完全相信[移动为先](https://www.uxmatters.com/mt/archives/2012/03/mobile-first-what-does-it-mean.php)的理念，但是我确实发现更多的人使用智能手机和平板电脑等移动设备来获取信息。这包括在线的软件和硬件文档，但它们大部分都是冗长的，不适合小屏幕。通常情况下，它的伸缩性不太好，而且很难导航。

当用户使用移动设备访问文档时，他们通常需要迅速获取信息以了解如何执行任务或解决问题，他们不想通过看似无尽的页面来寻找他们需要的特定信息。幸运的是，解决这个问题并不难。以下是一些技巧，可以帮助你构建文档以满足移动阅读器的需求。

### 简短一点

这意味着简短的句子，简短的段落和简短的流程。你不是在写一部长篇小说或一段长新闻。使你的文档简洁。尽可能使用少量的语言来获得想法和信息。

以广播新闻报道为示范：关注关键要素，用简单直接的语言对其进行解释。不要让你的读者在屏幕上看到冗长的文字。

另外，直接切入重点。关注读者需要的信息。在线发布的文档不应该像以前厚厚的手册一样。不要把所有东西都放在一个页面上，把你的信息分成更小的块。接下来是怎样做到这一点：

### 主题

在技术写作的世界里，主题是独立的，独立的信息块。每个主题都由你网站上的单个页面组成。读者应该能从特定的主题中获取他们需要的信息 -- 并且只是那些信息。要做到这一点，选择哪些主题要包含在文档中并决定如何组织它们：

### DITA

<ruby>   达尔文信息类型化体系结构  <rt>  Darwin Information Typing Architecture </rt></ruby> （DITA） 是用于编写和发布的一个 XML 模型。它[广泛采用](http://dita.xml.org/book/list-of-organizations-using-dita)在技术写作中，特别是作为较长的文档集中。

我并不是建议你将文档转换为 XML（除非你真的想）。相反，考虑将 DITA 的不同类型主题的概念应用到你的文档中：

* 一般：概述信息
* 任务：分步骤的流程
* 概念：背景或概念信息
* 参考：API 参考或数据字典等专用信息
* 术语表：定义术语
* 故障排除：有关用户可能遇到的问题以及如何解决问题的信息

你会得到很多单独的页面。要连接这些页面：

### 链接

许多内容管理系统、维基和发布框架都包含某种形式的导航 —— 通常是目录或[面包屑导航](https://en.wikipedia.org/wiki/Breadcrumb_(navigation))，这是一种在移动设备上逐渐消失的导航。

为了加强导航，在主题之间添加明确的链接。将这些链接放在每个主题末尾的“另请参阅”或“相关主题”的标题处。每个部分应包含两到五个链接，指向与当前主题相关的概述、概念和参考主题。

如果你需要指向文档集之外的信息，请确保链接在浏览器新的选项卡中打开。这将把读者送到另一个网站，同时也将读者继续留你的网站上。

这解决了文本问题，那么图片呢？

### 不使用图片

除少数情况之外，不应该加太多图片到文档中。仔细查看文档中的每个图片，然后问自己：

* 它有用吗？
* 它是否增强了文档？
* 如果删除它，读者会错过这张图片吗？

如果回答否，那么移除图片。

另一方面，如果你绝对不能没有图片，就让它变成[响应式的](https://en.wikipedia.org/wiki/Responsive_web_design)。这样，图片就会自动调整以适应更小的屏幕。

如果你仍然不确定图片是否应该出现，Opensource.com 社区版主 Ben Cotton 提供了一个关于在文档中使用屏幕截图的[极好的解释](https://opensource.com/business/15/9/when-does-your-documentation-need-screenshots)。

### 最后的想法

通过少量努力，你就可以构建适合移动设备用户的文档。此外，这些更改也改进了桌面计算机和笔记本电脑用户的文档体验。

---

via: <https://opensource.com/article/17/12/think-mobile>

作者：[Scott Nesbitt](https://opensource.com/users/chrisshort) 译者：[MjSeven](https://github.com/MjSeven) 校对：[wxy](https://github.com/wxy)

本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译，[Linux中国](https://linux.cn/) 荣誉推出


Linux 局域网路由新手指南：第 1 部分

Summary: 现在我们继续深入学习 Linux 中的 IPv4 路由的基础知识。

现在我们继续深入学习 Linux 中的 IPv4 路由的基础知识。

# Linux 局域网路由新手指南：第 1 部分

<img src="content_image/album_201805_19_104432ydrvfz6cqdr7q28d.jpg" alt="" title="">

前面我们学习了 [IPv6 路由](https://www.linux.com/learn/intro-to-linux/2017/7/practical-networking-linux-admins-ipv6-routing)。现在我们继续深入学习 Linux 中的 IPv4 路由的基础知识。我们从硬件概述、操作系统和 IPv4 地址的基础知识开始，下周我们将继续学习它们如何配置，以及测试路由。

### 局域网路由器硬件

Linux 实际上是一个网络操作系统，一直都是，从一开始它就有内置的网络功能。要将你的局域网连入因特网，构建一个局域网路由器比起构建网关路由器要简单的多。你不要太过于执念安全或者防火墙规则，对于处理网络地址转换（NAT）它还是比较复杂的，NAT是 IPv4 的一个痛点。我们为什么不放弃 IPv4 去转到 IPv6 呢？这样将使网络管理员的工作更加简单。

有点跑题了。从理论上讲，你的 Linux 路由器是一个至少有两个网络接口的小型机器。Linux Gizmos 有一个很大的单板机名单：[98 个开放规格、适于黑客的 SBC 的目录](http://linuxgizmos.com/catalog-of-98-open-spec-hacker-friendly-sbcs/#catalog)。你能够使用一个很老的笔记本电脑或者台式计算机。你也可以使用一个紧凑型计算机，像 ZaReason Zini 或者 System76 Meerkat 一样，虽然这些有点贵，差不多要 $600。但是它们又结实又可靠，并且你不用在 Windows 许可证上浪费钱。

如果对路由器的要求不高，使用树莓派 3 Model B 作为路由器是一个非常好的选择。它有一个 10/100 以太网端口，板载 2.4GHz 的 802.11n 无线网卡，并且它还有四个 USB 端口，因此你可以插入多个 USB 网卡。USB 2.0 和低速板载网卡可能会让树莓派变成你的网络上的瓶颈，但是，你不能对它期望太高（毕竟它只有 $35，既没有存储也没有电源）。它支持很多种风格的 Linux，因此你可以选择使用你喜欢的版本。基于 Debian 的树莓派是我的最爱。

### 操作系统

你可以在你选择的硬件上安装将你喜欢的 Linux 的简化版，因为定制的路由器操作系统，比如 OpenWRT、 Tomato、DD-WRT、Smoothwall、Pfsense 等等，都有它们自己的非标准界面。我的观点是，没有必要这么麻烦，它们对你并没有什么帮助。尽量使用标准的 Linux 工具，因为你只需要学习它们一次就够了。

Debian 的网络安装镜像大约有 300MB 大小，并且支持多种架构，包括 ARM、i386、amd64 和 armhf。Ubuntu 的服务器网络安装镜像也小于 50MB，这样你就可以控制你要安装哪些包。Fedora、Mageia、和 openSUSE 都提供精简的网络安装镜像。如果你需要创意，你可以浏览 [Distrowatch](http://distrowatch.org/)。

### 路由器能做什么

我们需要网络路由器做什么？一个路由器连接不同的网络。如果没有路由，那么每个网络都是相互隔离的，所有的悲伤和孤独都没有人与你分享，所有节点只能孤独终老。假设你有一个 192.168.1.0/24 和一个 192.168.2.0/24 网络。如果没有路由器，你的两个网络之间不能相互沟通。这些都是 C 类的私有地址，它们每个都有 254 个可用网络地址。使用 `ipcalc` 可以非常容易地得到它们的这些信息：

```
$ ipcalc 192.168.1.0/24
Address:   192.168.1.0          11000000.10101000.00000001. 00000000
Netmask:   255.255.255.0 = 24   11111111.11111111.11111111. 00000000
Wildcard:  0.0.0.255            00000000.00000000.00000000. 11111111
=>
Network:   192.168.1.0/24       11000000.10101000.00000001. 00000000
HostMin:   192.168.1.1          11000000.10101000.00000001. 00000001
HostMax:   192.168.1.254        11000000.10101000.00000001. 11111110
Broadcast: 192.168.1.255        11000000.10101000.00000001. 11111111
Hosts/Net: 254                   Class C, Private Internet

```

我喜欢 `ipcalc` 的二进制输出信息，它更加可视地表示了掩码是如何工作的。前三个八位组表示了网络地址，第四个八位组是主机地址，因此，当你分配主机地址时，你将 “掩盖” 掉网络地址部分，只使用剩余的主机部分。你的两个网络有不同的网络地址，而这就是如果两个网络之间没有路由器它们就不能互相通讯的原因。

每个八位组一共有 256 字节，但是它们并不能提供 256 个主机地址，因为第一个和最后一个值 ，也就是 0 和 255，是被保留的。0 是网络标识，而 255 是广播地址，因此，只有 254 个主机地址。`ipcalc` 可以帮助你很容易地计算出这些。

当然，这并不意味着你不能有一个结尾是 0 或者 255 的主机地址。假设你有一个 16 位的前缀：

```
$ ipcalc 192.168.0.0/16
Address:   192.168.0.0          11000000.10101000. 00000000.00000000
Netmask:   255.255.0.0 = 16     11111111.11111111. 00000000.00000000
Wildcard:  0.0.255.255          00000000.00000000. 11111111.11111111
=>
Network:   192.168.0.0/16       11000000.10101000. 00000000.00000000
HostMin:   192.168.0.1          11000000.10101000. 00000000.00000001
HostMax:   192.168.255.254      11000000.10101000. 11111111.11111110
Broadcast: 192.168.255.255      11000000.10101000. 11111111.11111111
Hosts/Net: 65534                 Class C, Private Internet

```

`ipcalc` 列出了你的第一个和最后一个主机地址，它们是 192.168.0.1 和 192.168.255.254。你是可以有以 0 或者 255 结尾的主机地址的，例如，192.168.1.0 和 192.168.0.255，因为它们都在最小主机地址和最大主机地址之间。

不论你的地址块是私有的还是公共的，这个原则同样都是适用的。不要羞于使用 `ipcalc` 来帮你计算地址。

### CIDR

CIDR（无类域间路由）就是通过可变长度的子网掩码来扩展 IPv4 的。CIDR 允许对网络空间进行更精细地分割。我们使用 `ipcalc` 来演示一下：

```
$ ipcalc 192.168.1.0/22
Address:   192.168.1.0          11000000.10101000.000000 01.00000000
Netmask:   255.255.252.0 = 22   11111111.11111111.111111 00.00000000
Wildcard:  0.0.3.255            00000000.00000000.000000 11.11111111
=>
Network:   192.168.0.0/22       11000000.10101000.000000 00.00000000
HostMin:   192.168.0.1          11000000.10101000.000000 00.00000001
HostMax:   192.168.3.254        11000000.10101000.000000 11.11111110
Broadcast: 192.168.3.255        11000000.10101000.000000 11.11111111
Hosts/Net: 1022                  Class C, Private Internet

```

网络掩码并不局限于整个八位组，它可以跨越第三和第四个八位组，并且子网部分的范围可以是从 0 到 3，而不是非得从 0 到 255。可用主机地址的数量并不一定是 8 的倍数，因为它是由整个八位组定义的。

给你留一个家庭作业，复习 CIDR 和 IPv4 地址空间是如何在公共、私有和保留块之间分配的，这个作业有助你更好地理解路由。一旦你掌握了地址的相关知识，配置路由器将不再是件复杂的事情了。

从 [理解 IP 地址和 CIDR 图表](https://www.ripe.net/about-us/press-centre/understanding-ip-addressing)、[IPv4 私有地址空间和过滤](https://www.arin.net/knowledge/address_filters.html)、以及 [IANA IPv4 地址空间注册](https://www.iana.org/assignments/ipv4-address-space/ipv4-address-space.xhtml) 开始。接下来的我们将学习如何创建和管理路由器。

通过来自 Linux 基金会和 edX 的免费课程 [“Linux 入门”](https://training.linuxfoundation.org/linux-courses/system-administration-training/introduction-to-linux)学习更多 Linux 知识。

---

via: <https://www.linux.com/learn/intro-to-linux/2018/2/linux-lan-routing-beginners-part-1>

作者：[Carla Schroder](https://www.linux.com/users/cschroder) 译者：[qhwdw](https://github.com/qhwdw) 校对：[wxy](https://github.com/wxy)

本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译，[Linux中国](https://linux.cn/) 荣誉推出


使用交互式 shell 来增强你的 Python

# 使用交互式 shell 来增强你的 Python

Python 编程语言已经成为 IT 中使用的最流行的语言之一。成功的一个原因是它可以用来解决各种问题。从网站开发到数据科学、机器学习到任务自动化，Python 生态系统有丰富的框架和库。本文将介绍 Fedora 软件包集合中提供的一些有用的 Python shell 来简化开发。

### Python Shell

Python Shell 让你以交互模式使用解释器。这在测试代码或尝试新库时非常有用。在 Fedora 中，你可以通过在终端会话中输入 `python3` 来调用默认的 shell。虽然 Fedora 提供了一些更高级和增强的 shell。

### IPython

IPython 为 Python shell 提供了许多有用的增强功能。例如包括 tab 补全，对象内省，系统 shell 访问和命令历史检索。许多功能也被 [Jupyter Notebook](https://ipython.org/notebook.html) 使用，因为它底层使用 IPython。

#### 安装和运行 IPython

```
dnf install ipython3
ipython3

```

使用 tab 补全会提示你可能的选择。当你使用不熟悉的库时，此功能会派上用场。

如果你需要更多信息，输入 `?` 命令来查看文档。对此的更多详细信息，你可以使用 `??` 命令。

另一个很酷的功能是使用 `!` 字符执行系统 shell 命令的能力。然后可以在 IPython shell 中引用该命令的结果。

IPython 完整的功能列表可在[官方文档](https://ipython.readthedocs.io/en/stable/overview.html#main-features-of-the-interactive-shell)中找到。

### bpython

bpython 并不能像 IPython 做那么多，但它却在一个简单的轻量级包中提供了一系列有用功能。除其他功能之外，bpython 提供：

* 内嵌语法高亮显示
* 在你输入时提供自动补全建议
* 可预期的参数列表
* 能够将代码发送或保存到 pastebin 服务或文件中

#### 安装和运行 bpython

```
dnf install bpython3
bpython3

```

在你输入的时候，`bpython` 为你提供了选择来自动补全你的代码。

当你调用函数或方法时，会自动显示需要的参数和文档字符串。

另一个很好的功能是可以使用功能键 `F7` 在外部编辑器（默认为 Vim）中打开当前的 `bpython` 会话。这在测试更复杂的程序时非常有用。

有关配置和功能的更多细节，请参考 bpython [文档](https://docs.bpython-interpreter.org/)。

### 总结

使用增强的 Python shell 是提高生产力的好方法。它为你提供增强的功能来编写快速原型或尝试新库。你在使用增强的 Python shell 吗？请随意在评论区留言。

图片由 [David Clode](https://unsplash.com/photos/d0CasEMHDQs?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText) 在 [Unsplash](https://unsplash.com/search/photos/python?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText) 上发布

---

via: <https://fedoramagazine.org/enhance-python-interactive-shell/>

作者：[Clément Verna](https://fedoramagazine.org/author/cverna/) 选题：[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/) 荣誉推出


如何使用 Ansible 打补丁以及安装应用

Summary: 使用 Ansible IT 自动化引擎节省更新的时间。

使用 Ansible IT 自动化引擎节省更新的时间。

# 如何使用 Ansible 打补丁以及安装应用

>
> 使用 Ansible IT 自动化引擎节省更新的时间。
>
>
>

<img src="content_image/album_201805_20_035937k1jc6t90wi80je66.jpg" alt="" title="">

你有没有想过，如何打补丁、重启系统，然后继续工作？

如果你的回答是肯定的，那就需要了解一下 [Ansible](https://www.ansible.com/overview/how-ansible-works) 了。它是一个配置管理工具，对于一些复杂的有时候需要几个小时才能完成的系统管理任务，又或者对安全性有比较高要求的时候，使用 Ansible 能够大大简化工作流程。

以我作为系统管理员的经验，打补丁是一项最有难度的工作。每次遇到<ruby> 公共漏洞批露 <rt>  Common Vulnearbilities and Exposure </rt></ruby>（CVE）通知或者<ruby> 信息保障漏洞预警 <rt>  Information Assurance Vulnerability Alert </rt></ruby>（IAVA）时都必须要高度关注安全漏洞，否则安全部门将会严肃追究自己的责任。

使用 Ansible 可以通过运行[封装模块](https://docs.ansible.com/ansible/latest/list_of_packaging_modules.html)以缩短打补丁的时间，下面以 [yum 模块](https://docs.ansible.com/ansible/latest/yum_module.html)更新系统为例，使用 Ansible 可以执行安装、更新、删除、从其它地方安装（例如持续集成/持续开发中的 `rpmbuild`）。以下是系统更新的任务：

```
  - name: update the system
    yum:
      name: "*"
      state: latest

```

在第一行，我们给这个任务命名，这样可以清楚 Ansible 的工作内容。第二行表示使用 `yum` 模块在CentOS虚拟机中执行更新操作。第三行 `name: "*"` 表示更新所有程序。最后一行 `state: latest` 表示更新到最新的 RPM。

系统更新结束之后，需要重新启动并重新连接：

```
  - name: restart system to reboot to newest kernel
    shell: "sleep 5 && reboot"
    async: 1
    poll: 0

  - name: wait for 10 seconds
    pause:
      seconds: 10

  - name: wait for the system to reboot
    wait_for_connection:
      connect_timeout: 20
      sleep: 5
      delay: 5
      timeout: 60

  - name: install epel-release
    yum:
      name: epel-release
      state: latest

```

`shell` 模块中的命令让系统在 5 秒休眠之后重新启动，我们使用 `sleep` 来保持连接不断开，使用 `async` 设定最大等待时长以避免发生超时，`poll` 设置为 0 表示直接执行不需要等待执行结果。暂停 10 秒钟以等待虚拟机恢复，使用 `wait_for_connection` 在虚拟机恢复连接后尽快连接。随后由 `install epel-release` 任务检查 RPM 的安装情况。你可以对这个剧本执行多次来验证它的幂等性，唯一会显示造成影响的是重启操作，因为我们使用了 `shell` 模块。如果不想造成实际的影响，可以在使用 `shell` 模块的时候 `changed_when: False`。

现在我们已经知道如何对系统进行更新、重启虚拟机、重新连接、安装 RPM 包。下面我们通过 [Ansible Lightbulb](https://github.com/ansible/lightbulb/tree/master/examples/nginx-role) 来安装 NGINX:

```
  - name: Ensure nginx packages are present
    yum:
      name: nginx, python-pip, python-devel, devel
      state: present
    notify: restart-nginx-service

  - name: Ensure uwsgi package is present
    pip:
      name: uwsgi
      state: present
    notify: restart-nginx-service

  - name: Ensure latest default.conf is present
    template:
      src: templates/nginx.conf.j2
      dest: /etc/nginx/nginx.conf
      backup: yes
    notify: restart-nginx-service

  - name: Ensure latest index.html is present
    template:
      src: templates/index.html.j2
      dest: /usr/share/nginx/html/index.html

  - name: Ensure nginx service is started and enabled
    service:
      name: nginx
      state: started
      enabled: yes

  - name: Ensure proper response from localhost can be received
    uri:
      url: "http://localhost:80/"
      return_content: yes
    register: response
    until: 'nginx_test_message in response.content'
    retries: 10
    delay: 1

```

以及用来重启 nginx 服务的操作文件：

```
# 安装 nginx 的操作文件
  - name: restart-nginx-service
    service:
      name: nginx
      state: restarted

```

在这个角色里，我们使用 RPM 安装了 `nginx`、`python-pip`、`python-devel`、`devel`，用 PIP 安装了 `uwsgi`，接下来使用 `template` 模块复制 `nginx.conf` 和 `index.html` 以显示页面，并确保服务在系统启动时启动。然后就可以使用 `uri` 模块检查到页面的连接了。

这个是一个系统更新、系统重启、安装 RPM 包的剧本示例，后续可以继续安装 nginx，当然这里可以替换成任何你想要的角色和应用程序。

```
  - hosts: all
    roles:
      - centos-update
      - nginx-simple

```

这只是关于如何更新系统、重启以及后续工作的示例。简单起见，我只添加了不带[变量](https://docs.ansible.com/ansible/latest/playbooks_variables.html)的包，当你在操作大量主机的时候，你就需要修改其中的一些设置了：

* [async & poll](https://docs.ansible.com/ansible/latest/playbooks_async.html)
* [serial](https://docs.ansible.com/ansible/latest/playbooks_delegation.html#rolling-update-batch-size)
* [forks](https://docs.ansible.com/ansible/latest/intro_configuration.html#forks)

这是由于在生产环境中如果你想逐一更新每一台主机的系统，你需要花相当一段时间去等待主机重启才能够继续下去。

---

via: <https://opensource.com/article/18/3/ansible-patch-systems>

作者：[Jonathan Lozada De La Matta](https://opensource.com/users/jlozadad) 译者：[HankChow](https://github.com/HankChow) 校对：[wxy](https://github.com/wxy)

本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译，[Linux中国](https://linux.cn/) 荣誉推出


如何改善应用程序在 Linux 中的启动时间

# 如何改善应用程序在 Linux 中的启动时间

<img src="content_image/album_201805_20_112221y4azq4onand1q4aa.png" alt="" title="">

大多数 Linux 发行版在默认配置下已经足够快了。但是，我们仍然可以借助一些额外的应用程序和方法让它们启动更快一点。其中一个可用的这种应用程序就是 Preload。它监视用户使用频率比较高的应用程序，并将它们添加到内存中，这样就比一般的方式加载更快一点。因为，正如你所知道的，内存的读取速度远远快于硬盘。Preload 以守护进程的方式在后台中运行，并记录用户使用较为频繁的程序的文件使用相关的统计数据。然后，它将这些二进制文件及它们的依赖项加载进内存，以改善应用程序的加载时间。简而言之，一旦安装了 Preload，你使用较为频繁的应用程序将可能加载的更快。

在这篇详细的教程中，我们将去了解如何安装和使用 Preload，以改善应用程序在 Linux 中的启动时间。

### 在 Linux 中使用 Preload 改善应用程序启动时间

Preload 可以在 [AUR](https://aur.archlinux.org/packages/preload/) 上找到。因此，你可以使用 AUR 助理程序在任何基于 Arch 的系统上去安装它，比如，Antergos、Manjaro Linux。

使用 [Pacaur](https://www.ostechnix.com/install-pacaur-arch-linux/)：

```
$ pacaur -S preload

```

使用 [Packer](https://www.ostechnix.com/install-packer-arch-linux-2/)：

```
$ packer -S preload

```

使用 [Trizen](https://www.ostechnix.com/trizen-lightweight-aur-package-manager-arch-based-systems/)：

```
$ trizen -S preload

```

使用 [Yay](https://www.ostechnix.com/yay-found-yet-another-reliable-aur-helper/)：

```
$ yay -S preload

```

使用 [Yaourt](https://www.ostechnix.com/install-yaourt-arch-linux/)：

```
$ yaourt -S preload

```

在 Debian、Ubuntu、Linux Mint 上，Preload 可以在默认仓库中找到。因此，你可以像下面一样，使用 APT 包管理器去安装它。

```
$ sudo apt-get install preload

```

Preload 安装完成后，重新启动你的系统。从现在开始，Preload 将监视频繁使用的应用程序，并将它们的二进制文件和库添加到内存中，以使它的启动速度更快。比如，如果你经常使用 Firefox、Chrome 以及 LibreOffice，Preload 将添加这些二进制文件和库到内存中，因此，这些应用程序将启动的更快。而且更好的是，它不需要做任何配置。它是开箱即用的。但是，如果你想去对它进行微调，你可以通过编辑缺省的配置文件 `/etc/preload.conf` 来实现。

### Preload 并不一定适合每个人！

以下是 Preload 的一些缺点，它并不是对每个人都有帮助，在这个 [跟贴](https://askubuntu.com/questions/110335/drawbacks-of-using-preload-why-isnt-it-included-by-default) 中有讨论到。

1. 我使用的是一个有 8GB 内存的现代系统。因此，我的系统总体上来说很快。我每天只打开狂吃内存的应用程序（比如，Firefox、Chrome、VirtualBox、Gimp 等等）一到两次，并且它们始终处于打开状态，因此，它们的二进制文件和库被预读到内存中，并始终整天在内存中。我一般很少去关闭和打开这些应用程序，因此，内存使用纯属浪费。
2. 如果你使用的是带有 SSD 的现代系统，Preload 是绝对没用的。因为 SSD 的访问时间比起一般的硬盘来要快的多，因此，使用 Preload 是没有意义的。
3. Preload 显著影响启动时间。因为更多的应用程序要被预读到内存中，这将让你的系统启动运行时间更长。

你只有在每天都在大量的重新加载应用程序时，才能看到真正的差别。因此，Preload 最适合开发人员和测试人员，他们每天都打开和关闭应用程序好多次。

关于 Preload 更多的信息和它是如何工作的，请阅读它的作者写的完整版的 [Preload 论文](https://cs.uwaterloo.ca/%7Ebrecht/courses/702/Possible-Readings/prefetching-to-memory/preload-thesis.pdf)。

教程到此为止，希望能帮到你。后面还有更精彩的内容，请继续关注！

再见！

---

via: <https://www.ostechnix.com/how-to-improve-application-startup-time-in-linux/>

作者：[SK](https://www.ostechnix.com/author/sk/) 选题：[lujun9972](https://github.com/lujun9972) 译者：[qhwdw](https://github.com/qhwdw) 校对：[wxy](https://github.com/wxy)

本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译，[Linux中国](https://linux.cn/) 荣誉推出


如何使用 Buildah 构建容器镜像

# 如何使用 Buildah 构建容器镜像

<img src="content_image/album_201805_21_071923ewuygn5g3vggjf3n.png" alt="" title="">

Project Atomic 通过他们在 Open Container Initiative（OCI）上的努力创造了一个名为 [Buildah](https://github.com/projectatomic/buildah) 的伟大工具。Buildah 能帮助创建、构建和更新，它支持 Docker 容器镜像以及 OCI 兼容镜像。

Buildah 处理构建容器镜像时无需安装完整的容器运行时或守护进程。这对建立容器的持续集成和持续交付管道尤其有用。

Buildah 使容器的文件系统可以直接供构建主机使用。这意味着构建工具在主机上可用就行，而不需要在容器镜像中可用，从而使构建更快速，镜像更小，更安全。Buildah 有 CentOS、Fedora 和 Debian 的软件包。

### 安装 Buildah

从 Fedora 26 开始 Buildah 可以使用 `dnf` 进行安装。

```
$ sudo dnf install buildah -y

```

`buildah` 的当前版本为 0.16，可以通过以下命令显示。

```
$ buildah --version

```

### 基本命令

构建容器镜像的第一步是获取基础镜像，这是通过 Dockerfile 中的 `FROM` 语句完成的。Buildah 以类似的方式处理这个。

```
$ sudo buildah from fedora

```

该命令将拉取 Fedora 的基础镜像并存储在主机上。通过执行以下操作可以检查主机上可用的镜像。

```
$ sudo buildah images
IMAGE ID IMAGE NAME CREATED AT SIZE
9110ae7f579f docker.io/library/fedora:latest Mar 7, 2018 20:51 234.7 MB

```

在拉取基础镜像后，有一个该镜像的运行容器实例，这是一个“工作容器”。

以下命令显示正在运行的容器。

```
$ sudo buildah containers
CONTAINER ID BUILDER IMAGE ID IMAGE NAME
CONTAINER NAME
6112db586ab9 * 9110ae7f579f docker.io/library/fedora:latest fedora-working-container

```

Buildah 还提供了一个非常有用的命令来停止和删除当前正在运行的所有容器。

```
$ sudo buildah rm --all

```

完整的命令列表可以使用 `--help` 选项。

```
$ buildah --help

```

### 构建一个 Apache Web 服务器容器镜像

让我们看看如何使用 Buildah 在 Fedora 基础镜像上安装 Apache Web 服务器，然后复制一个可供服务的自定义 `index.html`。

首先让我们创建自定义的 `index.html`。

```
$ echo "Hello Fedora Magazine !!!" > index.html

```

然后在正在运行的容器中安装 httpd 包。

```
$ sudo buildah from fedora
$ sudo buildah run fedora-working-container dnf install httpd -y

```

让我们将 `index.html` 复制到 `/var/www/html/`。

```
$ sudo buildah copy fedora-working-container index.html /var/www/html/index.html

```

然后配置容器入口点以启动 httpd。

```
$ sudo buildah config --entrypoint "/usr/sbin/httpd -DFOREGROUND" fedora-working-container

```

现在为了使“工作容器”可用，`commit` 命令将容器保存到镜像。

```
$ sudo buildah commit fedora-working-container hello-fedora-magazine

```

hello-fedora-magazine 镜像现在可用，并且可以推送到仓库以供使用。

```
$ sudo buildah images
IMAGE ID IMAGE NAME CREATED
AT SIZE
9110ae7f579f docker.io/library/fedora:latest
Mar 7, 2018 22:51 234.7 MB
49bd5ec5be71 docker.io/library/hello-fedora-magazine:latest
Apr 27, 2018 11:01 427.7 MB

```

通过运行以下步骤，还可以使用 Buildah 来测试此镜像。

```
$ sudo buildah from --name=hello-magazine docker.io/library/hello-fedora-magazine
$ sudo buildah run hello-magazine

```

访问 <http://localhost> 将显示 “Hello Fedora Magazine !!!”

---

via: <https://fedoramagazine.org/daemon-less-container-management-buildah/>

作者：[Ashutosh Sudhakar Bhakare](https://fedoramagazine.org/author/ashutoshbhakare/) 选题：[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/) 荣誉推出


有用的资源，献给那些想更多了解 Linux 的人

# 有用的资源，献给那些想更多了解 Linux 的人

<img src="content_image/album_201805_21_073426vdpz8p3xdnjejlrp.png" alt="" title="">

Linux 是最流行和多功能的操作系统之一，它可以用在智能手机，电脑甚至汽车上。自 20 世纪 90 年代以来，Linux 存在至今，并且仍然是最普遍的操作系统之一。

Linux 实际上用于运行大多数网络服务，因为与其他操作系统相比，它被认为是相当稳定的。这是[人们选择 Linux 多于 Windows 的原因](https://www.lifewire.com/windows-vs-linux-mint-2200609)之一。此外，Linux 为用户提供了隐私，根本不收集用户信息，而 Windows 10 及其 Cortana 语音控制系统总是需要更新你的个人信息。

Linux 有很多优点。然而，人们并没有听到太多关于它的消息，因为它已被 Windows 和 Mac 挤出（桌面）场。许多人开始使用 Linux 时会感到困惑，因为它与流行的操作系统有点不同。

为了帮助你，我们为那些想要了解更多关于 Linux 的人收集了 5 个有用的资源。

### 1、[Linux 纯新手](https://www.eduonix.com/courses/system-programming/linux-for-absolute-beginners)

如果你想尽可能多地学习 Linux，你应该考虑 Eduonix 为[初学者提供的 Linux 完整教程](https://www.eduonix.com/courses/system-programming/linux-for-absolute-beginners)。这个课程将向你介绍 Linux 的所有功能，并为你提供所有必要的资料，以帮助你了解更多关于 Linux 工作原理的特性。

如果你是以下情况，你应该选择本课程：

* 你想了解有关 Linux 操作系统的详细信息；
* 你想知道如何安装它；
* 你想了解 Linux 如何与硬件配合使用；
* 你想学习如何操作 Linux 命令行。

### 2、[PC World: Linux 初学者指南](https://www.pcworld.com/article/2918397/operating-systems/how-to-get-started-with-linux-a-beginners-guide.html)

为想要在一个地方学习所有有关 Linux 的人提供[免费资源](https://www.pcworld.com/article/2918397/operating-systems/how-to-get-started-with-linux-a-beginners-guide.html)。PC World 专注于计算机操作系统的各个方面，并为订阅用户提供最准确和最新的信息。在这里，你还可以了解更多关于 [Linux 的好处](https://www.popsci.com/switch-to-linux-operating-system#page-4) 和关于其操作系统的最新消息。

该资源为你提供以下信息：

* 如何安装 Linux；
* 如何使用命令行；
* 如何安装软件；
* 如何操作 Linux 桌面环境。

### 3、[Linux.com：Linux 培训](https://www.linux.com/learn/training)

很多使用计算机的人都需要学习如何操作 Linux，以防 Windows 操作系统突然崩溃。还有什么比使用官方资源来启动你的 [Linux 培训](https://www.linux.com/learn/training)更好呢？

该资源可用让你在线注册 Linux 训练，你可以从官方来源获取最新信息。“一年前，我们的 IT 部门在官方网站上为我们提供了 Linux 培训” [Assignmenthelper.com.au](https://www.assignmenthelper.com.au/) 的开发人员 Martin Gibson 说道。“我们选择了这门课，因为我们需要学习如何将我们的所有文件备份到另一个系统，为我们的客户提供最大的安全性，而且这个资源真的教会了我们所有的东西。”

所以你肯定应该使用这个资源，如果：

* 你想获得有关操作系统的第一手信息；
* 想要了解如何在你的计算机上运行 Linux 的特性；
* 想要与其他 Linux 用户联系并与他们分享你的经验。

### 4、 [Linux 基金会：视频培训](https://training.linuxfoundation.org/free-linux-training/linux-training-videos)

如果你在阅读大量资源时容易感到无聊，那么该网站绝对适合你。Linux 基金会提供了由 IT 专家、软件开发技术人员和技术顾问举办的[视频培训](https://training.linuxfoundation.org/free-linux-training/linux-training-videos)，讲座和在线研讨会。

所有培训视频分为以下类别：

* 开发人员： 使用 Linux 内核来处理 Linux 设备驱动程序、Linux 虚拟化等；
* 系统管理员：在 Linux 上开发虚拟主机，构建防火墙，分析 Linux 性能等；
* 用户：Linux 入门，介绍嵌入式 Linux 等。

### 5、 [LinuxInsider](https://www.linuxinsider.com/)

你知道吗？微软对 Linux 的效率感到惊讶，它[允许用户在微软云计算设备上运行 Linux](https://www.wired.com/2016/08/linux-took-web-now-taking-world/)。如果你想了解更多关于 Linux 操作系统的知识，[Linux Insider](https://www.linuxinsider.com/) 会向用户提供关于 Linux 操作系统的最新消息，以及最新更新和 Linux 特性的信息。

在此资源上，你将有机会：

* 参与 Linux 社区；
* 了解如何在各种设备上运行 Linux；
* 看看评论；
* 参与博客讨论并阅读科技博客。

### 总结一下

Linux 提供了很多好处，包括完全的隐私，稳定的操作甚至恶意软件保护。它绝对值得尝试，学习如何使用会帮助你更好地了解你的计算机如何工作以及它需要如何平稳运行。

### 关于作者

Lucy Benton 是一位数字营销专家，商业顾问，帮助人们将他们的梦想变为有利润的业务。现在她正在为营销和商业资源撰写。Lucy 还有自己的博客 [*Prowritingpartner.com*](https://prowritingpartner.com/)，在那里你可以查看她最近发表的文章。

---

via: <https://linuxaria.com/article/useful-resources-for-those-who-want-to-know-more-about-linux>

作者：[Lucy Benton](https://www.lifewire.com) 选题：[lujun9972](https://github.com/lujun9972) 译者：[MjSeven](https://github.com/MjSeven) 校对：[wxy](https://github.com/wxy)

本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译，[Linux中国](https://linux.cn/) 荣誉推出


一个可以更好地调试的 Perl 模块

# 一个可以更好地调试的 Perl 模块

>
> 这个简单优雅的模块可以让你包含调试或仅用于开发环境的代码，而在产品环境中隐藏它们。
>
>
>

<img src="content_image/album_201805_21_075502mmzlyfwlllbb1ffl.jpg" alt="" title="">

仅用于调试或开发调整时的 Perl 代码块有时会很有用。这很好，但是这样的代码块可能会对性能产生很大的影响, 尤其是在运行时才决定是否执行它。

[Curtis "Ovid" Poe](https://metacpan.org/author/OVID) 最近编写了一个可以帮助解决这个问题的模块：[Keyword::DEVELOPMENT](https://metacpan.org/pod/release/OVID/Keyword-DEVELOPMENT-0.04/lib/Keyword/DEVELOPMENT.pm)。该模块利用 `Keyword::Simple` 和 Perl 5.012 中引入的可插入关键字架构来创建了新的关键字：`DEVELOPMENT`。它使用 `PERL_KEYWORD_DEVELOPMENT` 环境变量的值来确定是否要执行一段代码。

使用它不能更容易了：

```
use Keyword::DEVELOPMENT;

sub doing_my_big_loop {
    my $self = shift;
    DEVELOPMENT {
        # insert expensive debugging code here!
    }
}

```

在编译时，`DEVELOPMENT` 块内的代码已经被优化掉了，根本就不存在。

你看到好处了么？在沙盒中将 `PERL_KEYWORD_DEVELOPMENT` 环境变量设置为 `true`，在生产环境设为 `false`，并且可以将有价值的调试工具提交到你的代码库中，在你需要的时候随时可用。

在缺乏高级配置管理的系统中，你也可以使用此模块来处理生产和开发或测试环境之间的设置差异：

```
sub connect_to_my_database {

    my $dsn = "dbi:mysql:productiondb";
    my $user = "db_user";
    my $pass = "db_pass";

    DEVELOPMENT {
        # Override some of that config information
        $dsn = "dbi:mysql:developmentdb";
    }

    my $db_handle = DBI->connect($dsn, $user, $pass);
}

```

稍后对此代码片段的增强使你能在其他地方，比如 YAML 或 INI 中读取配置信息，但我希望您能在此看到该工具。

我查看了关键字 `Keyword::DEVELOPMENT` 的源码，花了大约半小时研究，“天哪，我为什么没有想到这个？”安装 `Keyword::Simple` 后，Curtis 给我们的模块就非常简单了。这是我长期以来在自己的编码实践中所需要的一个优雅解决方案。

---

via: <https://opensource.com/article/18/4/perl-module-debugging-code>

作者：[Ruth Holloway](https://opensource.com/users/druthb) 选题：[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/) 荣誉推出


Jupyter Notebooks 入门

# Jupyter Notebooks 入门

>
> 通过 Jupyter 使用实时代码、方程式和可视化及文本创建交互式的共享笔记本。
>
>
>

自从有了纸莎草纸以来，出版人们一直在努力以吸引读者的方式来格式化数据。尤其是在数学、科学、和编程领域，设计良好的图表、插图和方程式可以成为帮助人们理解技术信息的关键。

[Jupyter Notebook](http://jupyter.org/) 通过重新构想我们如何制作教学文本来解决这个问题。Jupyter （我在 2017 年 10 月在 [All Things Open](https://allthingsopen.org/) 上首次了解到）是一款开源应用程序，它使用户能够创建包含实时代码、方程式、可视化和文本的交互式共享笔记本。

Jupyter 从 [IPython 项目](http://ipython.org/)发展而来，它是个具有交互式 shell 和基于浏览器的笔记本，支持代码、文本和数学表达式。Jupyter 支持超过 40 种编程语言，包括 Python、R 和 Julia，其代码可以导出为 HTML、LaTeX、PDF、图像和视频，或者作为 [IPyhton](https://en.wikipedia.org/wiki/IPython) 笔记本与其他用户共享。

>
> 一个有趣的事实是：“Jupyter” 是 “Julia、Python 和 R” 的缩写。
>
>
>

根据 Jupyter 项目网站介绍，它的一些用途包括“数据清理和转换，数值模拟，统计建模，数据可视化，机器学习等等”。科学机构正在使用 Jupyter Notebooks 来解释研究结果。代码可以来自实际数据，可以调整和重新调整以可视化成不同的结果和情景。通过这种方式，Jupyter Notebooks 变成了生动的文本和报告。

### 安装并开始 Jupyter

Jupyter 软件是开源的，其授权于[修改过的 BSD 许可证](https://opensource.org/licenses/BSD-3-Clause)，它可以[安装在 Linux、MacOS 或 Windows 上](http://jupyter.org/install.html)。有很多种方法可以安装 Jupyter；我在 Linux 和 MacOS 上试过 PIP 和 [Anaconda](https://www.anaconda.com/download/#linux) 安装方式。PIP 安装要求你的计算机上已经安装了 Python；Jupyter 推荐 Python 3。

由于 Python 3 已经安装在我的电脑上，我通过在终端（在 Linux 或 Mac 上）运行以下命令来安装 Jupyter：

```
$ python3 -m pip install --upgrade pip
$ python3 -m pip install jupyter

```

在终端提示符输入以下命令立即启动应用程序：

```
$ jupyter notebook

```

很快，我的浏览器打开并显示了我在 `http://localhost:8888` 的 Jupyter Notebook 服务器。（支持的浏览器有 Google Chrome、Firefox 和 Safari）

在右上角有一个标有 “New” 的下拉菜单，它使我能够根据自己的指示和代码快速创建新的笔记本。请注意，我的新笔记本默认为 Python 3，这是我目前的环境。

一个带有一些默认值的新笔记本，它可以被改变（包括笔记本的名字），已打开。

笔记本有两种不同的模式：“命令模式”和“编辑模式”。命令模式允许你添加或删除单元格。你可以通过按下 `Escape` 键进入命令模式，按 `Enter` 键或单击单元格进入编辑模式。

单元格周围的绿色高亮显示你处于编辑模式，蓝色高亮显示你处于命令模式。以下笔记本处于命令模式并准备好执行单元中的 Python 代码。注意，我已将笔记本的名称更改为 “First Notebook”。

### 使用 Jupyter

Jupyter Notebooks 的强大之处在于除了能够输入代码之外，你还可以用 Markdown 添加叙述性和解释性文本。我想添加一个标题，所以我在代码上面添加了一个单元格，并以 Markdown 输入了一个标题。当我按下 `Ctrl+Enter` 时，我的标题转换为 HTML。（LCTT 译注：或者可以按下 Run 按钮。）

我可以通过在命令前追加 `!` 来添加 Bash 命令或脚本的输出。

我也可以利用 IPython 的 [line magic 和 cell magic](http://ipython.readthedocs.io/en/stable/interactive/magics.html) 命令。你可以通过在代码单元内附加 `%` 或 `%%` 符号来列出魔术命令。例如，`%lsmagic` 将输出所有可用于 Jupyter notebooks 的魔法命令。

这些魔术命令的例子包括 `%pwd`——它输出当前工作目录（例如 `/Users/YourName`）和 `%ls`——它列出当前工作目录中的所有文件和子目录。另一个神奇命令显示从笔记本中的 `matplotlib` 生成的图表。`%%html` 将该单元格中的任何内容呈现为 HTML，这对嵌入视频和链接很有用，还有 JavaScript 和 Bash 的单元魔术命令。

如果你需要更多关于使用 Jupyter Notebooks 和它的特性的信息，它的帮助部分是非常完整的。

人们用许多有趣的方式使用 Jupyter Notebooks；你可以在这个[展示栏目](https://github.com/jupyter/jupyter/wiki/a-gallery-of-interesting-jupyter-notebooks#mathematics)里找到一些很好的例子。你如何使用 Jupyter 笔记本？请在下面的评论中分享你的想法。

---

via: <https://opensource.com/article/18/3/getting-started-jupyter-notebooks>

作者：[Don Watkins](https://opensource.com/users/don-watkins) 选题：[lujun9972](https://github.com/lujun9972) 译者：[MjSeven](https://github.com/MjSeven) 校对：[wxy](https://github.com/wxy)

本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译，[Linux中国](https://linux.cn/) 荣誉推出


如何编译 Linux 内核

Summary: Jack 将带你在 Ubuntu 16.04 服务器上走过内核编译之旅。

文中出现128GB是个错误，原文是12GB

谢谢！

精辟

sad

Jack 将带你在 Ubuntu 16.04 服务器上走过内核编译之旅。

# 如何编译 Linux 内核

>
> Jack 将带你在 Ubuntu 16.04 服务器上走过内核编译之旅。
>
>
>

曾经有一段时间，升级 Linux 内核让很多用户打心里有所畏惧。在那个时候，升级内核包含了很多步骤，也需要很多时间。现在，内核的安装可以轻易地通过像 `apt` 这样的包管理器来处理。通过添加特定的仓库，你能很轻易地安装实验版本的或者指定版本的内核（比如针对音频产品的实时内核）。

考虑一下，既然升级内核如此容易，为什么你不愿意自行编译一个呢？这里列举一些可能的原因：

* 你想要简单了解编译内核的过程
* 你需要启用或者禁用内核中特定的选项，因为它们没有出现在标准选项里
* 你想要启用标准内核中可能没有添加的硬件支持
* 你使用的发行版需要你编译内核
* 你是一个学生，而编译内核是你的任务

不管出于什么原因，懂得如何编译内核是非常有用的，而且可以被视作一个通行权。当我第一次编译一个新的 Linux 内核（那是很久以前了），然后尝试从它启动，我从中（系统马上就崩溃了，然后不断地尝试和失败）感受到一种特定的兴奋。

既然这样，让我们来实验一下编译内核的过程。我将使用 Ubuntu 16.04 Server 来进行演示。在运行了一次常规的 `sudo apt upgrade` 之后，当前安装的内核版本是 `4.4.0-121`。我想要升级内核版本到 `4.17`， 让我们小心地开始吧。

有一个警告：强烈建议你在虚拟机里实验这个过程。基于虚拟机，你总能创建一个快照，然后轻松地从任何问题中回退出来。不要在产品机器上使用这种方式升级内核，除非你知道你在做什么。

### 下载内核

我们要做的第一件事是下载内核源码。在 [Kernel.org](https://www.kernel.org/) 找到你要下载的所需内核的 URL。找到 URL 之后，使用如下命令（我以 `4.17 RC2` 内核为例） 来下载源码文件:

```
wget https://git.kernel.org/torvalds/t/linux-4.17-rc2.tar.gz

```

在下载期间，有一些事需要去考虑。

### 安装需要的环境

为了编译内核，我们首先得安装一些需要的环境。这可以通过一个命令来完成：

```
sudo apt-get install git fakeroot build-essential ncurses-dev xz-utils libssl-dev bc flex libelf-dev bison

```

务必注意：你将需要至少 12 GB 的本地可用磁盘空间来完成内核的编译过程。因此你必须确保有足够的空间。

### 解压源码

在新下载的内核所在的文件夹下，使用该命令来解压内核：

```
tar xvzf linux-4.17-rc2.tar.gz

```

使用命令 `cd linux-4.17-rc2` 进入新生成的文件夹。

### 配置内核

在正式编译内核之前，我们首先必须配置需要包含哪些模块。实际上，有一些非常简单的方式来配置。使用一个命令，你能拷贝当前内核的配置文件，然后使用可靠的 `menuconfig` 命令来做任何必要的更改。使用如下命令来完成：

```
cp /boot/config-$(uname -r) .config

```

现在你有一个配置文件了，输入命令 `make menuconfig`。该命令将打开一个配置工具（图 1），它可以让你遍历每个可用模块，然后启用或者禁用你需要或者不需要的模块。

*图 1: 运行中的 `make menuconfig`*

很有可能你会禁用掉内核中的一个重要部分，所以在 `menuconfig` 期间小心地一步步进行。如果你对某个选项不确定，不要去管它。或者更好的方法是使用我们拷贝的当前运行的内核的配置文件（因为我们知道它可以工作）。一旦你已经遍历了整个配置列表（它非常长），你就准备好开始编译了。

### 编译和安装

现在是时候去实际地编译内核了。第一步是使用 `make` 命令去编译。调用 `make` 命令然后回答必要的问题（图 2）。这些问题取决于你将升级的现有内核以及升级后的内核。相信我，将会有非常多的问题要回答，因此你得预留大量的时间。

*图 2: 回答 `make` 命令的问题*

回答了长篇累牍的问题之后，你就可以用如下的命令安装那些之前启用的模块：

```
make modules_install

```

又来了，这个命令将耗费一些时间，所以要么坐下来看着编译输出，或者去做些其他事（因为编译期间不需要你的输入）。可能的情况是，你想要去进行别的任务（除非你真的喜欢看着终端界面上飞舞而过的输出）。

现在我们使用这个命令来安装内核：

```
sudo make install

```

又一次，另一个将要耗费大量可观时间的命令。事实上，`make install` 命令将比 `make modules_install` 命令花费更多的时间。去享用午餐，配置一个路由器，将 Linux 安装在一些服务器上，或者小睡一会吧。

### 启用内核作为引导

一旦 `make install` 命令完成了，就是时候将内核启用来作为引导。使用这个命令来实现：

```
sudo update-initramfs -c -k 4.17-rc2

```

当然，你需要将上述内核版本号替换成你编译完的。当命令执行完毕后，使用如下命令来更新 grub：

```
sudo update-grub

```

现在你可以重启系统并且选择新安装的内核了。

### 恭喜!

你已经编译了一个 Linux 内核！它是一项耗费时间的活动；但是，最终你的 Linux 发行版将拥有一个定制的内核，同时你也将拥有一项被许多 Linux 管理员所倾向忽视的重要技能。

从 Linux 基金会和 edX 提供的免费 [“Introduction to Linux”](https://training.linuxfoundation.org/linux-courses/system-administration-training/introduction-to-linux) 课程来学习更多的 Linux 知识。

---

via: <https://www.linux.com/learn/intro-to-linux/2018/4/how-compile-linux-kernel-0>

作者：[Jack Wallen](https://www.linux.com/users/jlwallen) 选题：[lujun9972](https://github.com/lujun9972) 译者：[icecoobe](https://github.com/icecoobe) 校对：[wxy](https://github.com/wxy)

本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译，[Linux中国](https://linux.cn/) 荣誉推出


6 个 Python 的日期时间库

Summary: 在 Python 中有许多库可以很容易地测试、转换和读取日期和时间信息。

在 Python 中有许多库可以很容易地测试、转换和读取日期和时间信息。

# 6 个 Python 的日期时间库

>
> 在 Python 中有许多库可以很容易地测试、转换和读取日期和时间信息。
>
>
>

<img src="content_image/album_201805_22_161301ewwz66h6y8hkngmk.jpg" alt="" title="">

*这篇文章是与 [Jeff Triplett](https://opensource.com/users/jefftriplett) 一起合写的。*

曾几何时，我们中的一个人（Lacey）盯了一个多小时的 [Python 文档](https://docs.python.org/3/library/datetime.html#strftime-strptime-behavior)中描述日期和时间格式化字符串的表格。当我试图编写从 API 中将日期时间字符串转换为 [Python datetime](https://opensource.com/article/17/5/understanding-datetime-python-primer) 对象时，我很难理解其中的特定部分，因此我决定请求帮助。

有人问道：“为什么你不使用 `dateutil` 呢？”

读者，如果你没有从这个月的 Python 专栏中获得任何东西，只是学习到有比 datetime 的 `strptime` 更容易地将 datetime 字符串转换为 datetime 对象的方法，那么我们觉得就已经成功了。

但是，除了将字符串转换为更有用的 Python 对象之外，还有许多库都有一些有用的方法和工具，可以让您更轻松地进行时间测试、将时间转换为不同的时区、以人类可读的格式传递时间信息，等等。如果这是你在 Python 中第一次接触日期和时间，请暂停并阅读 *[如何使用 Python的日期和时间](https://opensource.com/article/17/5/understanding-datetime-python-primer)* 。要理解为什么在编程中处理日期和时间是困难的，请阅读 [愚蠢的程序员相信时间](http://infiniteundo.com/post/25326999628/falsehoods-programmers-believe-about-time)。

这篇文章将会向你介绍以下库：

* [Dateutil](https://opensource.com/#Dateutil)
* [Arrow](https://opensource.com/#Arrow)
* [Moment](https://opensource.com/#Moment)
* [Maya](https://opensource.com/#Maya)
* [Delorean](https://opensource.com/#Delorean)
* [Freezegun](https://opensource.com/#Freezegun)

随意跳过那些你已经熟悉的库，专注于那些对你而言是新的库。

### 内建的 datetime 模块

在跳转到其他库之前，让我们回顾一下如何使用 `datetime` 模块将日期字符串转换为 Python datetime 对象。

假设我们从 API 接受到一个日期字符串，并且需要它作为 Python datetime 对象存在：

```
2018-04-29T17:45:25Z

```

这个字符串包括：

* 日期是 `YYYY-MM-DD` 格式的
* 字母 `T` 表示时间即将到来
* 时间是 `HH:II:SS` 格式的
* 表示此时间的时区指示符 `Z` 采用 UTC （详细了解[日期时间字符格式](https://www.w3.org/TR/NOTE-datetime)）

要使用 `datetime` 模块将此字符串转换为 Python datetime 对象，你应该从 `strptime` 开始。 `datetime.strptime` 接受日期字符串和格式化字符并返回一个 Python datetime 对象。

我们必须手动将日期时间字符串的每个部分转换为 Python 的 `datetime.strptime` 可以理解的合适的格式化字符串。四位数年份由 `%Y` 表示，两位数月份是 `%m`，两位数的日期是 `%d`。在 24 小时制中，小时是 `%H`，分钟是 `%M`，秒是 `%S`。

为了得出这些结论，需要在[Python 文档](https://docs.python.org/3/library/datetime.html#strftime-strptime-behavior)的表格中多加注意。

由于字符串中的 `Z` 表示此日期时间字符串采用 UTC，所以我们可以在格式中忽略此项。（现在，我们不会担心时区。）

转换的代码是这样的：

```
$ from datetime import datetime
$ datetime.strptime('2018-04-29T17:45:25Z', '%Y-%m-%dT%H:%M:%SZ')
datetime.datetime(2018, 4, 29, 17, 45, 25)

```

格式字符串很难阅读和理解。我必须手动计算原始字符串中的字母 `T` 和 “Z”的位置，以及标点符号和格式化字符串，如 `%S` 和 `%m`。有些不太了解 datetime 的人阅读我的代码可能会发现它很难理解，尽管其含义已有文档记载，但它仍然很难阅读。

让我们看看其他库是如何处理这种转换的。

### Dateutil

[dateutil 模块](https://dateutil.readthedocs.io/en/stable/)对 `datetime` 模块做了一些扩展。

继续使用上面的解析示例，使用 `dateutil` 实现相同的结果要简单得多：

```
$ from dateutil.parser import parse
$ parse('2018-04-29T17:45:25Z')
datetime.datetime(2018, 4, 29, 17, 45, 25, tzinfo=tzutc())

```

如果字符串包含时区，那么 `dateutil` 解析器会自动返回字符串的时区。由于我们在 UTC 时区，你可以看到返回来一个 datetime 对象。如果你想解析完全忽略时区信息并返回原生的 datetime 对象，你可以传递 `ignoretz=True` 来解析，如下所示：

```
$ from dateutil.parser import parse
$ parse('2018-04-29T17:45:25Z', ignoretz=True)
datetime.datetime(2018, 4, 29, 17, 45, 25)

```

`dateutil` 还可以解析其他人类可读的日期字符串：

```
$ parse('April 29th, 2018 at 5:45 pm')
datetime.datetime(2018, 4, 29, 17, 45)

```

`dateutil` 还提供了像 [relativedelta](https://dateutil.readthedocs.io/en/stable/relativedelta.html) 的工具，它用于计算两个日期时间之间的时间差或向日期时间添加或删除时间，[rrule](https://dateutil.readthedocs.io/en/stable/rrule.html) 创建重复日期时间，[tz](https://dateutil.readthedocs.io/en/stable/tz.html) 用于解决时区以及其他工具。

### Arrow

[Arrow](https://github.com/crsmithdev/arrow) 是另一个库，其目标是操作、格式化，以及处理对人类更友好的日期和时间。它包含 `dateutil`，根据其[文档](https://pypi.python.org/pypi/arrow-fatisar/0.5.3)，它旨在“帮助你使用更少的包导入和更少的代码来处理日期和时间”。

要返回我们的解析示例，下面介绍如何使用 Arrow 将日期字符串转换为 Arrow 的 datetime 类的实例：

```
$ import arrow
$ arrow.get('2018-04-29T17:45:25Z')
<Arrow [2018-04-29T17:45:25+00:00]>

```

你也可以在 `get()` 的第二个参数中指定格式，就像使用 `strptime` 一样，但是 Arrow 会尽力解析你给出的字符串，`get()` 返回 Arrow 的 `datetime` 类的一个实例。要使用 Arrow 来获取 Python datetime 对象，按照如下所示链式 datetime：

```
$ arrow.get('2018-04-29T17:45:25Z').datetime
datetime.datetime(2018, 4, 29, 17, 45, 25, tzinfo=tzutc())

```

通过 Arrow datetime 类的实例，你可以访问 Arrow 的其他有用方法。例如，它的 `humanize()` 方法将日期时间翻译成人类可读的短语，就像这样：

```
$ import arrow
$ utc = arrow.utcnow()
$ utc.humanize()
'seconds ago'

```

在 Arrow 的[文档](https://arrow.readthedocs.io/en/latest/)中阅读更多关于其有用方法的信息。

### Moment

[Moment](https://github.com/zachwill/moment) 的作者认为它是“内部测试版”，但即使它处于早期阶段，它也是非常受欢迎的，我们想来讨论它。

Moment 的方法将字符转换为其他更有用的东西很简单，类似于我们之前提到的库：

```
$ import moment
$ moment.date('2018-04-29T17:45:25Z')
<Moment(2018-04-29T17:45:25)>

```

就像其他库一样，它最初返回它自己的 datetime 类的实例，要返回 Python datetime 对象，添加额外的 `date()` 调用即可。

```
$ moment.date('2018-04-29T17:45:25Z').date
datetime.datetime(2018, 4, 29, 17, 45, 25, tzinfo=<StaticTzInfo 'Z'>)

```

这将 Moment datetime 类转换为 Python datetime 对象。

Moment 还提供了使用人类可读的语言创建新日期的方法。例如创建一个明天的日期：

```
$ moment.date("tomorrow")
<Moment(2018-04-06T11:24:42)>

```

它的 `add()` 和 `subtract()` 命令使用关键字参数来简化日期的操作。为了获得后天，Moment 会使用下面的代码：

```
$ moment.date("tomorrow").add(days=1)
<Moment(2018-04-07T11:26:48)>

```

### Maya

[Maya](https://github.com/kennethreitz/maya) 包含了 Python 中其他流行处理日期时间的库，包括 Humanize、 pytz 和 pendulum 等等。这个项目旨在让人们更容易处理日期。

Maya 的 README 包含几个有用的实例。以下是如何使用 Maya 来重新处理以前的解析示例：

```
$ import maya
$ maya.parse('2018-04-29T17:45:25Z').datetime()
datetime.datetime(2018, 4, 29, 17, 45, 25, tzinfo=<UTC>)

```

注意我们必须在 `maya.parse()` 之后调用 `datetime()`。如果我们跳过这一步，Maya 将会返回一个 MayaDT 类的示例：`<MayaDT epoch=1525023925.0>`。

由于 Maya 与 datetime 库中很多有用的方法重叠，因此它可以使用 MayaDT 类的实例执行诸如使用 `slang_time()` 方法将时间偏移量转换为纯文本语言，并将日期时间间隔保存在单个类的实例中。以下是如何使用 Maya 将日期时间表示为人类可读的短语：

```
$ import maya
$ maya.parse('2018-04-29T17:45:25Z').slang_time()
'23 days from now

```

显然，`slang_time()` 的输出将根据距离 datetime 对象相对较近或较远的距离而变化。

### Delorean

[Delorean](https://github.com/myusuf3/delorean)，以 《返回未来》 电影中的时间旅行汽车命名，它对于操纵日期时间特别有用，包括将日期时间转换为其他时区并添加或减去时间。

Delorean 需要有效的 Python datetime 对象才能工作，所以如果你需要使用时间字符串，最好将其与上述库中的一个配合使用。例如，将 Maya 与 Delorean 一起使用：

```
$ import maya
$ d_t = maya.parse('2018-04-29T17:45:25Z').datetime()

```

现在，你有了一个 datetime 对象 d\_t，你可以使用 Delorean 来做一些事情，例如将日期时间转换为美国东部时区：

```
$ from delorean import Delorean
$ d = Delorean(d_t)
$ d
Delorean(datetime=datetime.datetime(2018, 4, 29, 17, 45, 25), timezone='UTC')
$ d.shift('US/Eastern')
Delorean(datetime=datetime.datetime(2018, 4, 29, 13, 45, 25), timezone='US/Eastern')

```

看到小时是怎样从 17 变成 13 了吗？

你也可以使用自然语言方法来操作 datetime 对象。获取 2018 年 4 月 29 日之后的下个星期五（我们现在使用的）：

```
$ d.next_friday()
Delorean(datetime=datetime.datetime(2018, 5, 4, 13, 45, 25), timezone='US/Eastern')

```

在 Delorean 的[文档](https://delorean.readthedocs.io/en/latest/)中阅读更多关于其的用法。

### Freezegun

[Freezegun](https://github.com/spulec/freezegun) 是一个可以帮助你在 Python 代码中测试特定日期的库。使用 `@freeze_time` 装饰器，你可以为测试用例设置特定的日期和时间，并且所有对 `datetime.datetime.now()`、 `datetime.datetime.utcnow()` 等的调用都将返回你指定的日期和时间。例如：

```
from freezegun import freeze_time
import datetime

@freeze_time("2017-04-14")
def test():
    assert datetime.datetime.now() == datetime.datetime(2017, 4, 14)

```

要跨时区进行测试，你可以将 `tz_offset` 参数传递给装饰器。`freeze_time` 装饰器也接受更简单的口语化日期，例如 `@freeze_time('April 4, 2017')`。

---

上面提到的每个库都提供了一组不同的特性和功能，也许很难决定哪一个最适合你的需要。[Maya 的作者](https://github.com/kennethreitz/maya), Kenneth Reitz 说到：“所有这些项目相辅相成，它们都是我们的朋友”。

这些库共享一些功能，但不是全部。有些擅长时间操作，有些擅长解析，但它们都有共同的目标，即让你对日期和时间的工作更轻松。下次你发现自己对 Python 的内置 datetime 模块感到沮丧，我们希望你可以选择其中的一个库进行试验。

---

via: <https://opensource.com/article/18/4/python-datetime-libraries>

作者: [Lacey Williams Hensche](https://opensource.com/users/laceynwilliams) 选题: [lujun9972](https://github.com/lujun9972) 译者: [MjSeven](https://github.com/MjSeven) 校对: [wxy](https://github.com/wxy)

本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译，[Linux中国](https://linux.cn/) 荣誉推出


Bootiso ：让你安全地创建 USB 启动设备

# Bootiso ：让你安全地创建 USB 启动设备

<img src="content_image/album_201805_22_163121prqrm82zr67vroom.png" alt="" title="">

你好，新兵！你们有些人经常使用 `dd` 命令做各种各样的事，比如创建 USB 启动盘或者克隆硬盘分区。不过请牢记，`dd` 是一个危险且有毁灭性的命令。如果你是个 Linux 的新手，最好避免使用 `dd` 命令。如果你不知道你在做什么，你可能会在几分钟里把硬盘擦掉。从原理上说，`dd` 只是从 `if` 读取然后写到 `of` 上。它才不管往哪里写呢。它根本不关心那里是否有分区表、引导区、家目录或是其他重要的东西。你叫它做什么它就做什么。可以使用像 [Etcher](https://www.ostechnix.com/etcher-beauitiful-app-create-bootable-sd-cards-usb-drives/) 这样的用户友好的应用来代替它。这样你就可以在创建 USB 引导设备之前知道你将要格式化的是哪块盘。

今天，我发现了另一个可以安全创建 USB 引导设备的工具 Bootiso 。它实际上是一个 BASH 脚本，但真的很智能！它有很多额外的功能来帮我们安全创建 USB 引导盘。如果你想确保你的目标是 USB 设备（而不是内部驱动器），或者如果你想检测 USB 设备，你可以使用 Bootiso。下面是使用此脚本的显著优点:

* 如果只有一个 USB 驱动器，Bootiso 会自动选择它。
* 如果有一个以上的 USB 驱动器存在，它可以让你从列表中选择其中一个。
* 万一你错误地选择一个内部硬盘驱动器，它将退出而不做任何事情。
* 它检查选定的 ISO 是否具有正确的 MIME 类型。如果 MIME 类型不正确，它将退出。
* 它判定所选的项目不是分区，如果判定失败则退出。
* 它将在擦除和对 USB 驱动器分区之前提示用户确认。
* 列出可用的 USB 驱动器。
* 安装 syslinux 引导系统 (可选)。
* 自由且开源。

### 使用 Bootiso 安全地创建 USB 驱动器

安装 Bootiso 非常简单。用这个命令下载最新版本：

```
$ curl -L https://rawgit.com/jsamr/bootiso/latest/bootiso -O

```

把下载的文件加到 `$PATH` 目录中，比如 `/usr/local/bin/`。

```
$ sudo cp bootiso /usr/local/bin/

```

最后，添加运行权限：

```
$ sudo chmod +x /usr/local/bin/bootiso

```

搞定！现在就可以创建 USB 引导设备了。首先，让我们用命令看看现在有哪些 USB 驱动器：

```
$ bootiso -l

```

输出：

```
Listing USB drives available in your system:
NAME HOTPLUG SIZE STATE TYPE
sdb 1 7.5G running disk

```

如你所见，我只有一个 USB 驱动器。让我们继续通过命令用 ISO 文件创建 USB 启动盘：

```
$ bootiso bionic-desktop-amd64.iso

```

这个命令会提示你输入 `sudo` 密码。输入密码并回车来安装缺失的组件（如果有的话），然后创建 USB 启动盘。

输出：

```
[...]
Listing USB drives available in your system:
NAME HOTPLUG SIZE STATE TYPE
sdb 1 7.5G running disk
Autoselecting `sdb' (only USB device candidate)
The selected device `/dev/sdb' is connected through USB.
Created ISO mount point at `/tmp/iso.c5m'
`bootiso' is about to wipe out the content of device `/dev/sdb'.
Are you sure you want to proceed? (y/n)>y
Erasing contents of /dev/sdb...
Creating FAT32 partition on `/dev/sdb1'...
Created USB device mount point at `/tmp/usb.QgV'
Copying files from ISO to USB device with `rsync'
Synchronizing writes on device `/dev/sdb'
`bootiso' took 303 seconds to write ISO to USB device with `rsync' method.
ISO succesfully unmounted.
USB device succesfully unmounted.
USB device succesfully ejected.
You can safely remove it !

```

如果你的 ISO 文件 MIME 类型不对，你会得到下列错误信息：

```
Provided file `bionic-desktop-amd64.iso' doesn't seem to be an iso file (wrong mime type: `application/octet-stream').
Exiting bootiso...

```

当然，你也能像下面那样使用 `–no-mime-check` 选项来跳过 MIME 类型检查。

```
$ bootiso --no-mime-check bionic-desktop-amd64.iso

```

就像我前面提到的，如果系统里只有 1 个 USB 设备 Bootiso 将自动选中它。所以我们不需要告诉它 USB 设备路径。如果你连接了多个设备，你可以像下面这样使用 `-d` 来指明 USB 设备。

```
$ bootiso -d /dev/sdb bionic-desktop-amd64.iso

```

用你自己的设备路径来换掉 `/dev/sdb`。

在多个设备情况下，如果你没有使用 `-d` 来指明要使用的设备，Bootiso 会提示你选择可用的 USB 设备。

Bootiso 在擦除和改写 USB 盘分区前会要求用户确认。使用 `-y` 或 `–assume-yes` 选项可以跳过这一步。

```
$ bootiso -y bionic-desktop-amd64.iso

```

您也可以把自动选择 USB 设备与 `-y` 选项连用，如下所示。

```
$ bootiso -y -a bionic-desktop-amd64.iso

```

或者，

```
$ bootiso?--assume-yes?--autoselect bionic-desktop-amd64.iso

```

请记住，当你只连接一个 USB 驱动器时，它才会起作用。

Bootiso 会默认创建一个 FAT 32 分区，挂载后用 `rsync` 程序把 ISO 的内容拷贝到 USB 盘里。 如果你愿意也可以使用 `dd` 代替 `rsync` 。

```
$ bootiso --dd -d /dev/sdb bionic-desktop-amd64.iso

```

如果你想增加 USB 引导的成功概率，请使用 `-b` 或 `–bootloader` 选项。

```
$ bootiso -b bionic-desktop-amd64.iso

```

上面这条命令会安装 `syslinux` 引导程序（安全模式）。注意，此时 `–dd` 选项不可用。

在创建引导设备后，Bootiso 会自动弹出 USB 设备。如果不想自动弹出，请使用 `-J` 或 `–no-eject` 选项。

```
$ bootiso -J bionic-desktop-amd64.iso

```

现在，USB 设备依然连接中。你可以使用 `umount` 命令随时卸载它。

需要完整帮助信息，请输入：

```
$ bootiso -h

```

好，今天就到这里。希望这个脚本对你有帮助。好货不断，不要走开哦！

---

via: <https://www.ostechnix.com/bootiso-lets-you-safely-create-bootable-usb-drive/>

作者：[SK](https://www.ostechnix.com/author/sk/) 选题：[lujun9972](https://github.com/lujun9972) 译者：[kennethXia](https://github.com/kennethXia) 校对：[wxy](https://github.com/wxy)

本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译，[Linux中国](https://linux.cn/) 荣誉推出


为什么建设一个社区值得额外的努力

# 为什么建设一个社区值得额外的努力

>
> 建立 NethServer 社区是有风险的。但是我们从这些激情的人们所带来的力量当中学习到了很多。
>
>
>

<img src="content_image/album_201805_22_171454x5jfnf8rggfsrgzo.png" alt="" title="">

当我们在 2003 年推出 [Nethesis](http://www.nethesis.it/) 时，我们还只是系统集成商。我们只使用已有的开源项目。我们的业务模式非常明确：为这些项目增加多种形式的价值：实践知识、针对意大利市场的文档、额外模块、专业支持和培训课程。我们还通过向上游贡献代码并参与其社区来回馈上游项目。

那时时代不同。我们不能太张扬地使用“开源”这个词。人们将它与诸如“书呆子”，“没有价值”以及最糟糕的“免费”这些词联系起来。这些不太适合生意。

在 2010 年的一个星期六，Nethesis 的工作人员，他们手中拿着馅饼和浓咖啡，正在讨论如何推进事情发展（嘿，我们喜欢在创新的同时吃喝东西！）。尽管势头对我们不利，但我们决定不改变方向。事实上，我们决定加大力度 —— 去做开源和开放的工作方式，这是一个成功运营企业的模式。

多年来，我们已经证明了该模型的潜力。有一件事是我们成功的关键：社区。

在这个由三部分组成的系列文章中，我将解释社区在开放组织的存在中扮演的重要角色。我将探讨为什么一个组织希望建立一个社区，并讨论如何建立一个社区 —— 因为我确实认为这是如今产生新创新的最佳方式。

### 这个疯狂的想法

与 Nethesis 伙伴一起，我们决定构建自己的开源项目：我们自己的操作系统，它建立在 CentOS 之上（因为我们不想重新发明轮子）。我们假设我们拥有实现它的经验、实践知识和人力。我们感到很勇敢。

我们非常希望构建一个名为 [NethServer](http://www.nethserver.org/) 的操作系统，其使命是：通过开源使系统管理员的生活更轻松。我们知道我们可以为服务器创建一个 Linux 发行版，与当前已有的相比，它更容易使用、更易于部署，并且更易于理解。

不过，最重要的是，我们决定创建一个真正的，100％ 开放的项目，其主要规则有三条：

* 完全免费下载
* 开发公开
* 社区驱动

最后一个很重要。我们是一家公司。我们能够自己开发它。如果我们在内部完成这项工作，我们将会更有效（并且做出更快的决定）。与其他任何意大利公司一样，这将非常简单。

但是我们已经如此深入到开源文化中，所以我们选择了不同的路径。

我们确实希望有尽可能多的人围绕着我们、围绕着产品、围绕着公司周围。我们希望对工作有尽可能多的视角。我们意识到：独自一人，你可以走得快 —— 但是如果你想走很远，你需要一起走。

所以我们决定建立一个社区。

### 下一步是什么？

我们意识到创建社区有很多好处。例如，如果使用产品的人真正参与到项目中，他们将提供反馈和测试用例、编写文档、发现 bug，与其他产品进行比较，建议功能并为开发做出贡献。所有这些都会产生创新，吸引贡献者和客户，并扩展你产品的用户群。

但是很快就出现了这样一个问题：我们如何建立一个社区？我们不知道如何实现这一点。我们参加了很多社区，但我们从未建立过一个社区。

我们擅长编码 —— 而不是人。我们是一家公司，是一个有非常具体优先事项的组织。那么我们如何建立一个社区，并在公司和社区之间建立良好的关系呢？

我们做了你必须做的第一件事：学习。我们从专家、博客和许多书中学到了知识。我们进行了实验。我们失败了多次，从结果中收集数据，并再次进行测试。

最终我们学到了社区管理的黄金法则：**没有社区管理的黄金法则。**

人们太复杂了，社区无法用一条规则来“统治他们”。

然而，我可以说的一件事是，社区和公司之间的健康关系总是一个给予和接受的过程。在我的下一篇文章中，我将讨论你的组织如果想要一个蓬勃发展和创新的社区，应该期望提供什么。

---

via: <https://opensource.com/open-organization/18/1/why-build-community-1>

作者：[Alessio Fattorini](https://opensource.com/users/alefattorini) 译者：[geekpi](https://github.com/geekpi) 校对：[wxy](https://github.com/wxy)

本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译，[Linux中国](https://linux.cn/) 荣誉推出


HeRM's ：一个命令行食谱管理器

Summary: 今天，我介绍 HeRM's，这是一个基于 Haskell 的命令行食谱管理器，能为你的美食食谱做笔记。

# HeRM's ：一个命令行食谱管理器

烹饪让爱变得可见，不是吗？确实！烹饪也许是你的热情或爱好或职业，我相信你会维护一份烹饪日记。保持写烹饪日记是改善烹饪习惯的一种方法。有很多方法可以记录食谱。你可以维护一份小日记/笔记或将配方的笔记存储在智能手机中，或将它们保存在计算机中文档中。这有很多选择。今天，我介绍 **HeRM's**，这是一个基于 Haskell 的命令行食谱管理器，能为你的美食食谱做笔记。使用 Herm's，你可以添加、查看、编辑和删除食物配方，甚至可以制作购物清单。这些全部来自你的终端！它是免费的，是使用 Haskell 语言编写的开源程序。源代码在 GitHub 中免费提供，因此你可以复刻它，添加更多功能或改进它。

### HeRM's - 一个命令食谱管理器

#### 安装 HeRM's

由于它是使用 Haskell 编写的，因此我们需要首先安装 Cabal。 Cabal 是一个用于下载和编译用 Haskell 语言编写的软件的命令行程序。Cabal 存在于大多数 Linux 发行版的核心软件库中，因此你可以使用发行版的默认软件包管理器来安装它。

例如，你可以使用以下命令在 Arch Linux 及其变体（如 Antergos、Manjaro Linux）中安装 cabal：

```
sudo pacman -S cabal-install

```

在 Debian、Ubuntu 上：

```
sudo apt-get install cabal-install

```

安装 Cabal 后，确保你已经添加了 `PATH`。为此，请编辑你的 `~/.bashrc`：

```
vi ~/.bashrc

```

添加下面这行：

```
PATH=$PATH:~/.cabal/bin

```

按 `:wq` 保存并退出文件。然后，运行以下命令更新所做的更改。

```
source ~/.bashrc

```

安装 cabal 后，运行以下命令安装 `herms`：

```
cabal install herms

```

喝一杯咖啡！这将需要一段时间。几分钟后，你会看到一个输出，如下所示。

```
[...]
Linking dist/build/herms/herms ...
Installing executable(s) in /home/sk/.cabal/bin
Installed herms-1.8.1.2

```

恭喜！ Herms 已经安装完成。

#### 添加食谱

让我们添加一个食谱，例如 Dosa。对于那些想知道的，Dosa 是一种受欢迎的南印度食物，配以 sambar（LCTT 译注：扁豆和酸豆炖菜，像咖喱汤） 和**酸辣酱**。这是一种健康的，可以说是最美味的食物。它不含添加的糖或饱和脂肪。制作一个也很容易。有几种不同的 Dosas，在我们家中最常见的是 Plain Dosa。

要添加食谱，请输入：

```
herms add

```

你会看到一个如下所示的屏幕。开始输入食谱的详细信息。

要变换字段，请使用以下键盘快捷键：

* `Tab` / `Shift+Tab` - 下一个/前一个字段
* `Ctrl + <箭头键>` - 导航字段
* `[Meta 或者 Alt] + <h-j-k-l>` - 导航字段
* `Esc` - 保存或取消。

添加完配方的详细信息后，按下 `ESC` 键并点击 `Y` 保存。同样，你可以根据需要添加尽可能多的食谱。

要列出添加的食谱，输入：

```
herms list

```

要查看上面列出的任何食谱的详细信息，请使用下面的相应编号。

```
herms view 1

```

要编辑任何食谱，使用：

```
herms edit 1

```

完成更改后，按下 `ESC` 键。系统会询问你是否要保存。你只需选择适当的选项。

要删除食谱，命令是：

```
herms remove 1

```

要为指定食谱生成购物清单，运行：

```
herms shopping 1

```

要获得帮助，运行：

```
herms -h

```

当你下次听到你的同事、朋友或其他地方谈到好的食谱时，只需打开 Herm's，并快速记下，并将它们分享给你的配偶。她会很高兴！

今天就是这些。还有更好的东西。敬请关注！

干杯！！

---

via: <https://www.ostechnix.com/herms-commandline-food-recipes-manager/>

作者：[SK](https://www.ostechnix.com) 译者：[geekpi](https://github.com/geekpi) 校对：[wxy](https://github.com/wxy)

本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译，[Linux中国](https://linux.cn/) 荣誉推出