为什么车企纷纷招聘计算机安全专家

![](/data/attachment/album/201801/25/133120d8dq9dutg6dava49.jpg)

来自 CloudFlare 公司的网络安全专家 Marc Rogers（左）和来自 Lookout 的 Kevin Mahaffey 能够通过直接连接在汽车上的笔记本电脑控制特斯拉汽车进行许多操作。图为他们在 CloudFlare 的大厅里的的熔岩灯前的合影，这些熔岩灯被用来生成密匙。（纽约时报 Credit ，Christie Hemm Klok 拍摄）

大约在七年前，伊朗的几位顶级核科学家经历过一系列形式类似的暗杀：凶手的摩托车接近他们乘坐的汽车，把磁性炸弹吸附在汽车上，然后逃离并引爆炸弹。

安全专家们警告人们，再过 7 年，凶手们不再需要摩托车或磁性炸弹。他们所需要的只是一台笔记本电脑和发送给无人驾驶汽车的一段代码——让汽车坠桥、被货车撞扁或者在高速公路上突然抛锚。

汽车制造商眼中的无人驾驶汽车。在黑客眼中只是一台可以达到时速 100 公里的计算机。

网络安全公司 CloudFlare 的首席安全研究员<ruby> 马克·罗杰斯 <rt>  Marc Rogers </rt></ruby>说：“它们已经不再是汽车了。它们是装在车轮上的数据中心。从外界接收的每一条数据都可以作为黑客的攻击载体。“

两年前，两名“白帽”黑客（寻找系统漏洞并修复它们的研究员，而不是利用漏洞来犯罪的<ruby> 破坏者 <rt>  Cracker </rt></ruby>）成功地在数里之外用电脑获得了一辆 Jeep Cherokee 的控制权。他们控制汽车撞击一个放置在高速公路中央的假人（在场景设定中是一位紧张的记者），直接终止了假人的一生。

黑客 Chris Valasek 和 Charlie Miller（现在是 Uber 和滴滴的安全研究人员）发现了一条 [由 Jeep 娱乐系统通向仪表板的电路](https://bits.blogs.nytimes.com/2015/07/21/security-researchers-find-a-way-to-hack-cars/)。他们利用这条线路控制了车辆转向、刹车和变速——他们在高速公路上撞击假人所需的一切。

Miller 先生上周日在 Twitter 上写道：“汽车被黑客入侵成为头条新闻，但是人们要清楚，没有谁的汽车被坏人入侵过。 这些只是研究人员的测试。”

尽管如此，Miller 和 Valasek 的研究使 Jeep 汽车的制造商<ruby> 菲亚特克莱斯勒 <rt>  Fiat Chrysler </rt></ruby>付出了巨大的代价，因为这个安全漏洞，菲亚特克莱斯勒被迫召回了 140 万辆汽车。

毫无疑问，后来通用汽车首席执行官<ruby> 玛丽·巴拉 <rt>  Mary Barra </rt></ruby>把网络安全作为公司的首要任务。现在，计算机网络安全领域的人才在汽车制造商和高科技公司推进的无人驾驶汽车项目中的需求量很大。

优步 、特斯拉、苹果和中国的滴滴一直在积极招聘像 Miller 先生和 Valasek 先生这样的白帽黑客，传统的网络安全公司和学术界也有这样的趋势。

去年，特斯拉挖走了苹果 iOS 操作系统的安全经理 Aaron Sigel。优步挖走了 Facebook 的白帽黑客 Chris Gates。Miller 先生在发现 Jeep 的漏洞后就职于优步，然后被滴滴挖走。计算机安全领域已经有数十名优秀的工程师加入无人驾驶汽车项目研究的行列。

Miller 先生说，他离开了优步的一部分原因是滴滴给了他更自由的工作空间。

Miller 星期六在 Twitter 上写道：“汽车制造商对待网络攻击的威胁似乎更加严肃，但我仍然希望有更大的透明度。”

像许多大型科技公司一样，特斯拉和菲亚特克莱斯勒也开始给那些发现并提交漏洞的黑客们提供奖励。通用汽车公司也做了类似的事情，但批评人士认为通用汽车公司的计划与科技公司们提供的计划相比诚意不足，迄今为止还收效甚微。

在 Miller 和 Valasek 发现 Jeep 漏洞的一年后，他们又向人们演示了所有其他可能危害乘客安全的方式，包括劫持车辆的速度控制系统，猛打方向盘或在高速行驶下拉动手刹——这一切都是由汽车外的电脑操作的。（在测试中使用的汽车最后掉进路边的沟渠，他们只能寻求当地拖车公司的帮助）

虽然他们必须在 Jeep 车上才能做到这一切，但这也证明了入侵的可能性。

在 Jeep 被入侵之前，华盛顿大学和加利福尼亚大学圣地亚哥分校的[安全研究人员](http://www.autosec.org/pubs/cars-usenixsec2011.pdf)第一个通过蓝牙远程控制轿车并控制其刹车。研究人员警告汽车公司：汽车联网程度越高，被入侵的可能性就越大。

2015 年，安全研究人员们发现了入侵高度软件化的特斯拉 Model S 的途径。Rogers 先生和网络安全公司 Lookout 的首席技术官<ruby> 凯文·马哈菲 <rt>  Kevin Mahaffey </rt></ruby>找到了一种通过直接连接在汽车上的笔记本电脑控制特斯拉汽车的方法。

一年后，来自中国腾讯的一支团队做了更进一步的尝试。他们入侵了一辆行驶中的特斯拉 Model S 并控制了其刹车器达12 米远。和 Jeep 不同，特斯拉可以通过远程安装补丁来修复那些可能被黑的安全漏洞。

以上所有的例子中，入侵者都是无恶意的白帽黑客或者安全研究人员，但是给无人驾驶汽车制造商的教训是惨重的。

黑客入侵汽车的动机是无穷的。在得知 Rogers 先生和 Mahaffey 先生对特斯拉 Model S 的研究之后，一位中国 app 开发者和他们联系、询问他们是否愿意分享或者出售他们发现的漏洞。（这位 app 开发者正在寻找后门，试图在特斯拉的仪表盘上偷偷安装 app）

尽管犯罪分子们一直在积极开发、购买、使用能够破解汽车的关键通信数据的工具，但目前还没有证据能够表明犯罪分子们已经找到连接汽车的后门。

但随着越来越多的无人驾驶和半自动驾驶的汽车驶入公路，它们将成为更有价值的目标。安全专家警告道：无人驾驶汽车面临着更复杂、更多面的入侵风险，每一辆新无人驾驶汽车的加入，都使这个系统变得更复杂，而复杂性不可避免地带来脆弱性。

20 年前，平均每辆汽车有 100 万行代码，通用汽车公司的 2010 [雪佛兰 Volt](http://autos.nytimes.com/2011/Chevrolet/Volt/238/4117/329463/researchOverview.aspx?inline=nyt-classifier) 有大约 1000 万行代码——比一架 [F-35 战斗机](http://topics.nytimes.com/top/reference/timestopics/subjects/m/military_aircraft/f35_airplane/index.html?inline=nyt-classifier)的代码还要多。

如今， 平均每辆汽车至少有 1 亿行代码。无人驾驶汽车公司预计不久以后它们将有 2 亿行代码。当你停下来考虑：平均每 1000 行代码有 15 到 50 个缺陷，那么潜在的可利用缺陷就会以很快的速度增加。

“计算机最大的安全威胁仅仅是数据被删除，但无人驾驶汽车一旦出现安全事故，失去的却是乘客的生命。”一家致力于解决汽车安全问题的以色列初创公司 Karamba Security 的联合创始人 David Barzilai 说。

安全专家说道：要想真正保障无人驾驶汽车的安全，汽车制造商必须想办法避免所有可能产生的漏洞——即使漏洞不可避免。其中最大的挑战，是汽车制造商和软件开发商们之间的缺乏合作经验。

网络安全公司 Lookout 的 Mahaffey 先生说：“新的革命已经出现，我们不能固步自封，应该寻求新的思维。我们需要像发明出安全气囊那样的人来解决安全漏洞，但我们现在还没有看到行业内有人做出改变。”

Mahaffey 先生说：“在这场无人驾驶汽车的竞争中，那些最注重软件的公司将会成为最后的赢家。”

---

via: <https://www.nytimes.com/2017/06/07/technology/why-car-companies-are-hiring-computer-security-experts.html>

作者：[NICOLE PERLROTH](https://www.nytimes.com/by/nicole-perlroth)  译者：[XiatianSummer](https://github.com/XiatianSummer) 校对：[wxy](https://github.com/wxy)

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


三步上手 GDB

Summary: 调试 C 程序，曾让我很困扰。然而当我之前在写我的操作系统时，我有很多的 Bug 需要调试。我很幸运的使用上了 qemu 模拟器，它允许我将调试器附加到我的操作系统。这个调试器就是 gdb。

![](/data/attachment/album/201801/25/134655pdy41fvu7f6ln61k.jpg)

调试 C 程序，曾让我很困扰。然而当我之前在写我的[操作系统](https://jvns.ca/blog/categories/kernel)时，我有很多的 Bug 需要调试。我很幸运的使用上了 qemu 模拟器，它允许我将调试器附加到我的操作系统。这个调试器就是 `gdb`。

我得解释一下，你可以使用 `gdb` 先做一些小事情，因为我发现初学它的时候真的很混乱。我们接下来会在一个小程序中，设置断点，查看内存。

### 1、 设断点

如果你曾经使用过调试器，那你可能已经会设置断点了。

下面是一个我们要调试的程序（虽然没有任何 Bug）:

```
#include <stdio.h>
void do_thing() {
    printf("Hi!\n");
}
int main() {
    do_thing();
}

```

另存为 `hello.c`. 我们可以使用 `dbg` 调试它，像这样：

```
bork@kiwi ~> gcc -g hello.c -o hello
bork@kiwi ~> gdb ./hello

```

以上是带调试信息编译 `hello.c`（为了 `gdb` 可以更好工作），并且它会给我们醒目的提示符，就像这样：

```
(gdb)

```

我们可以使用 `break` 命令设置断点，然后使用 `run` 开始调试程序。

```
(gdb) break do_thing
Breakpoint 1 at 0x4004f8
(gdb) run
Starting program: /home/bork/hello

Breakpoint 1, 0x00000000004004f8 in do_thing ()

```

程序暂停在了 `do_thing` 开始的地方。

我们可以通过 `where` 查看我们所在的调用栈。

```
(gdb) where
#0  do_thing () at hello.c:3
#1  0x08050cdb in main () at hello.c:6
(gdb)

```

### 2、 阅读汇编代码

使用 `disassemble` 命令，我们可以看到这个函数的汇编代码。棒级了，这是 x86 汇编代码。虽然我不是很懂它，但是 `callq` 这一行是 `printf` 函数调用。

```
(gdb) disassemble do_thing
Dump of assembler code for function do_thing:
   0x00000000004004f4 <+0>:     push   %rbp
   0x00000000004004f5 <+1>:     mov    %rsp,%rbp
=> 0x00000000004004f8 <+4>:     mov    $0x40060c,%edi
   0x00000000004004fd <+9>:     callq  0x4003f0
   0x0000000000400502 <+14>:    pop    %rbp
   0x0000000000400503 <+15>:    retq

```

你也可以使用 `disassemble` 的缩写 `disas`。

### 3、 查看内存

当调试我的内核时，我使用 `gdb` 的主要原因是，以确保内存布局是如我所想的那样。检查内存的命令是 `examine`，或者使用缩写 `x`。我们将使用`x`。

通过阅读上面的汇编代码，似乎 `0x40060c` 可能是我们所要打印的字符串地址。我们来试一下。

```
(gdb) x/s 0x40060c
0x40060c:        "Hi!"

```

的确是这样。`x/s` 中 `/s` 部分，意思是“把它作为字符串展示”。我也可以“展示 10 个字符”，像这样：

```
(gdb) x/10c 0x40060c
0x40060c:       72 'H'  105 'i' 33 '!'  0 '\000'        1 '\001'        27 '\033'       3 '\003'        59 ';'
0x400614:       52 '4'  0 '\000'

```

你可以看到前四个字符是 `H`、`i`、`!` 和 `\0`，并且它们之后的是一些不相关的东西。

我知道 `gdb` 很多其他的东西，但是我仍然不是很了解它，其中 `x` 和 `break` 让我获得很多。你还可以阅读 [do umentation for examining memory](https://ftp.gnu.org/old-gnu/Manuals/gdb-5.1.1/html_chapter/gdb_9.html#SEC56)。

---

via: <https://jvns.ca/blog/2014/02/10/three-steps-to-learning-gdb/>

作者：[Julia Evans](https://jvns.ca) 译者：[Torival](https://github.com/Torival) 校对：[wxy](https://github.com/wxy)

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


如何在 Linux 中从 PDF 创建视频

![](/data/attachment/album/201801/25/191109w3d0trt5n540xicv.jpg)

我在我的平板电脑中收集了大量的 PDF 文件，其中主要是 Linux 教程。有时候我懒得在平板电脑上看。我认为如果我能够从 PDF 创建视频，并在大屏幕设备（如电视机或计算机）中观看会更好。虽然我对 [FFMpeg](https://www.ostechnix.com/20-ffmpeg-commands-beginners/) 有一些经验，但我不知道如何使用它来创建视频。经过一番 Google 搜索，我想出了一个很好的解决方案。对于那些想从一组 PDF 文件制作视频文件的人，请继续阅读。这并不困难。

### 在 Linux 中从 PDF 创建视频

为此，你需要在系统中安装 “FFMpeg” 和 “ImageMagick”。

要安装 FFMpeg，请参考以下链接。

* [在 Linux 上安装 FFMpeg](https://www.ostechnix.com/install-ffmpeg-linux/)

Imagemagick 可在大多数 Linux 发行版的官方仓库中找到。

在 Arch Linux 以及 Antergos、Manjaro Linux 等衍生产品上，运行以下命令进行安装。

```
sudo pacman -S imagemagick

```

Debian、Ubuntu、Linux Mint：

```
sudo apt-get install imagemagick

```

Fedora：

```
sudo dnf install imagemagick

```

RHEL、CentOS、Scientific Linux：

```
sudo yum install imagemagick

```

SUSE、 openSUSE：

```
sudo zypper install imagemagick

```

在安装 ffmpeg 和 imagemagick 之后，将你的 PDF 文件转换成图像格式，如 PNG 或 JPG，如下所示。

```
convert -density 400 input.pdf picture.png

```

这里，`-density 400` 指定输出图像的水平分辨率。

上面的命令会将指定 PDF 的所有页面转换为 PNG 格式。PDF 中的每个页面都将被转换成 PNG 文件，并保存在当前目录中，文件名为： `picture-1.png`、 `picture-2.png` 等。根据选择的 PDF 的页数，这将需要一些时间。

将 PDF 中的所有页面转换为 PNG 格式后，运行以下命令以从 PNG 创建视频文件。

```
ffmpeg -r 1/10 -i picture-%01d.png -c:v libx264 -r 30 -pix_fmt yuv420p video.mp4

```

这里：

* `-r 1/10` ：每张图像显示 10 秒。
* `-i picture-%01d.png` ：读取以 `picture-` 开头，接着是一位数字（`％01d`），最后以 `.png` 结尾的所有图片。如果图片名称带有 2 位数字（也就是 `picture-10.png`、`picture11.png` 等），在上面的命令中使用（`％02d`）。
* `-c:v libx264`：输出的视频编码器（即 h264）。
* `-r 30` ：输出视频的帧率
* `-pix_fmt yuv420p`：输出的视频分辨率
* `video.mp4`：以 .mp4 格式输出视频文件。

好了，视频文件完成了！你可以在任何支持 .mp4 格式的设备上播放它。接下来，我需要找到一种方法来为我的视频插入一个很酷的音乐。我希望这也不难。

如果你想要更高的分辨率，你不必重新开始。只要将输出的视频文件转换为你选择的任何其他更高/更低的分辨率，比如说 720p，如下所示。

```
ffmpeg -i video.mp4 -vf scale=-1:720 video_720p.mp4

```

请注意，使用 ffmpeg 创建视频需要一台配置好的 PC。在转换视频时，ffmpeg 会消耗大量系统资源。我建议在高端系统中这样做。

就是这些了。希望你觉得这个有帮助。还会有更好的东西。敬请关注！

---

via: <https://www.ostechnix.com/create-video-pdf-files-linux/>

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

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


python-hwinfo：使用 Linux 系统工具展示硬件信息概况

Summary: 这是一个通过解析系统工具（例如 lspci 和 dmidecode）的输出，来检查硬件和设备的 Python 库。

![](/data/attachment/album/201801/25/193747izu851ummun555wu.jpg)

到目前为止，我们已经介绍了大部分获取 Linux 系统硬件信息和配置的工具，不过也有许多命令可用于相同目的。

而且，一些工具会显示所有硬件组件的详细信息，或只显示特定设备的信息。

在这个系列中, 今天我们讨论一下关于 [python-hwinfo](https://github.com/rdobson/python-hwinfo)， 它是一个展示硬件信息概况的工具之一，并且其配置简洁。

### 什么是 python-hwinfo

这是一个通过解析系统工具（例如 `lspci` 和 `dmidecode`）的输出，来检查硬件和设备的 Python 库。

它提供了一个简单的命令行工具，可以用来检查本地、远程的主机和记录的信息。用 `sudo` 运行该命令以获得最大的信息。

另外，你可以提供服务器 IP 或者主机名、用户名和密码，在远程的服务器上执行它。当然你也可以使用这个工具查看其它工具捕获的输出（例如 `demidecode` 输出的 `dmidecode.out`，`/proc/cpuinfo` 输出的 `cpuinfo`，`lspci -nnm` 输出的 `lspci-nnm.out`）。

建议阅读：

* [Inxi：一个功能强大的获取 Linux 系统信息的命令行工具](/article-8424-1.html)
* [Dmidecode：获取 Linux 系统硬件信息的简易方式](https://www.2daygeek.com/dmidecode-get-print-display-check-linux-system-hardware-information/)
* [LSHW (Hardware Lister)： 一个在 Linux 上获取硬件信息的漂亮工具](https://www.2daygeek.com/lshw-find-check-system-hardware-information-details-linux/)
* [hwinfo (Hardware Info)：一个在 Linux 上检测系统硬件信息的漂亮工具](https://www.2daygeek.com/hwinfo-check-display-detect-system-hardware-information-linux/)
* [如何使用 lspci、lsscsi、lsusb 和 lsblk 获取 Linux 系统设备信息](https://www.2daygeek.com/check-system-hardware-devices-bus-information-lspci-lsscsi-lsusb-lsblk-linux/)

### Linux 上如何安装 python-hwinfo

在绝大多数 Linux 发行版，都可以通过 pip 包安装。为了安装 python-hwinfo， 确保你的系统已经有 Python 和python-pip 包作为先决条件。

`pip` 是 Python 附带的一个包管理工具，在 Linux 上安装 Python 包的推荐工具之一。

在 Debian/Ubuntu 平台，使用 [APT-GET 命令](https://www.2daygeek.com/apt-get-apt-cache-command-examples-manage-packages-debian-ubuntu-systems/) 或者 [APT 命令](https://www.2daygeek.com/apt-command-examples-manage-packages-debian-ubuntu-systems/) 安装 `pip`。

```
$ sudo apt install python-pip

```

在 RHEL/CentOS 平台，使用 [YUM 命令](https://www.2daygeek.com/yum-command-examples-manage-packages-rhel-centos-systems/)安装 `pip`。

```
$ sudo yum install python-pip python-devel

```

在 Fedora 平台，使用 [DNF 命令](https://www.2daygeek.com/dnf-command-examples-manage-packages-fedora-system/)安装 `pip`。

```
$ sudo dnf install python-pip

```

在 Arch Linux 平台，使用 [Pacman 命令](https://www.2daygeek.com/pacman-command-examples-manage-packages-arch-linux-system/)安装 `pip`。

```
$ sudo pacman -S python-pip

```

在 openSUSE 平台，使用 [Zypper 命令](https://www.2daygeek.com/zypper-command-examples-manage-packages-opensuse-system/)安装 `pip`。

```
$ sudo zypper python-pip

```

最后，执行下面的 `pip` 命令安装 python-hwinfo。

```
$ sudo pip install python-hwinfo

```

### 怎么在本地机器使用 python-hwinfo

执行下面的命令，检查本地机器现有的硬件。输出很清楚和整洁，这是我在其他命令中没有看到的。

它的输出分为了五类：

* Bios Info（BIOS 信息）： BIOS 供应商名称、系统产品名称、系统序列号、系统唯一标识符、系统制造商、BIOS 发布日期和BIOS 版本。
* CPU Info（CPU 信息）：处理器编号、供应商 ID，CPU 系列代号、型号、步进编号、型号名称、CPU 主频。
* Ethernet Controller Info（网卡信息）： 供应商名称、供应商 ID、设备名称、设备 ID、子供应商名称、子供应商 ID，子设备名称、子设备 ID。
* Storage Controller Info（存储设备信息）： 供应商名称、供应商 ID、设备名称、设备 ID、子供应商名称，子供应商 ID、子设备名称、子设备 ID。
* GPU Info（GPU 信息）： 供应商名称、供应商 ID、设备名称、设备 ID、子供应商名称、子供应商 ID、子设备名称、子设备 ID。

```
$ sudo hwinfo

Bios Info:

+----------------------+--------------------------------------+
| Key                  | Value                                |
+----------------------+--------------------------------------+
| bios_vendor_name     | IBM                                  |
| system_product_name  | System x3550 M3: -[6102AF1]-         |
| system_serial_number | RS2IY21                              |
| chassis_type         | Rack Mount Chassis                   |
| system_uuid          | 4C4C4544-0051-3210-8052-B2C04F323132 |
| system_manufacturer  | IBM                                  |
| socket_count         | 2                                    |
| bios_release_date    | 10/21/2014                           |
| bios_version         | -[VLS211TSU-2.51]-                   |
| socket_designation   | Socket 1, Socket 2                   |
+----------------------+--------------------------------------+

CPU Info:

+-----------+--------------+------------+-------+----------+------------------------------------------+----------+
| processor |  vendor_id   | cpu_family | model | stepping |                model_name                | cpu_mhz  |
+-----------+--------------+------------+-------+----------+------------------------------------------+----------+
|     0     | GenuineIntel |     6      |   45  |    7     | Intel(R) Xeon(R) CPU E5-1607 0 @ 3.00GHz | 1200.000 |
|     1     | GenuineIntel |     6      |   45  |    7     | Intel(R) Xeon(R) CPU E5-1607 0 @ 3.00GHz | 1200.000 |
|     2     | GenuineIntel |     6      |   45  |    7     | Intel(R) Xeon(R) CPU E5-1607 0 @ 3.00GHz | 1200.000 |
|     3     | GenuineIntel |     6      |   45  |    7     | Intel(R) Xeon(R) CPU E5-1607 0 @ 3.00GHz | 1200.000 |
|     4     | GenuineIntel |     6      |   45  |    7     | Intel(R) Xeon(R) CPU E5-2650 0 @ 2.00GHz | 1200.000 |
+-----------+--------------+------------+-------+----------+------------------------------------------+----------+

Ethernet Controller Info:

+-------------------+-----------+---------------------------------+-----------+-------------------+--------------+---------------------------------+--------------+
|    vendor_name    | vendor_id |           device_name           | device_id |   subvendor_name  | subvendor_id |          subdevice_name         | subdevice_id |
+-------------------+-----------+---------------------------------+-----------+-------------------+--------------+---------------------------------+--------------+
| Intel Corporation |    8086   | I350 Gigabit Network Connection |    1521   | Intel Corporation |     8086     | I350 Gigabit Network Connection |     1521     |
+-------------------+-----------+---------------------------------+-----------+-------------------+--------------+---------------------------------+--------------+

Storage Controller Info:

+-------------------+-----------+----------------------------------------------+-----------+----------------+--------------+----------------+--------------+
|    vendor_name    | vendor_id |                 device_name                  | device_id | subvendor_name | subvendor_id | subdevice_name | subdevice_id |
+-------------------+-----------+----------------------------------------------+-----------+----------------+--------------+----------------+--------------+
| Intel Corporation |    8086   |   C600/X79 series chipset IDE-r Controller   |    1d3c   |      Dell      |     1028     | [Device 05d2]  |     05d2     |
| Intel Corporation |    8086   | C600/X79 series chipset SATA RAID Controller |    2826   |      Dell      |     1028     | [Device 05d2]  |     05d2     |
+-------------------+-----------+----------------------------------------------+-----------+----------------+--------------+----------------+--------------+

GPU Info:

+--------------------+-----------+-----------------------+-----------+--------------------+--------------+----------------+--------------+
|    vendor_name     | vendor_id |      device_name      | device_id |   subvendor_name   | subvendor_id | subdevice_name | subdevice_id |
+--------------------+-----------+-----------------------+-----------+--------------------+--------------+----------------+--------------+
| NVIDIA Corporation |    10de   | GK107GL [Quadro K600] |    0ffa   | NVIDIA Corporation |     10de     | [Device 094b]  |     094b     |
+--------------------+-----------+-----------------------+-----------+--------------------+--------------+----------------+--------------+

```

### 怎么在远处机器上使用 python-hwinfo

执行下面的命令检查远程机器现有的硬件，需要远程机器 IP，用户名和密码：

```
$ hwinfo -m x.x.x.x -u root -p password

```

### 如何使用 python-hwinfo 读取记录的输出

执行下面的命令，检查本地机器现有的硬件。输出很清楚和整洁，这是我在其他命令中没有看到的。

```
$ hwinfo -f [Path to file]

```

---

via: <https://www.2daygeek.com/python-hwinfo-check-display-system-hardware-configuration-information-linux/>

作者：[2DAYGEEK](https://www.2daygeek.com/author/2daygeek/) 译者：[Torival](https://github.com/Torival) 校对：[wxy](https://github.com/wxy)

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


如何根据文件权限查找文件

Summary: 今天，在基于 Unix 的操作系统中，我们将见识如何通过权限查找文件。

今天，在基于 Unix 的操作系统中，我们将见识如何通过权限查找文件。

![](/data/attachment/album/201801/26/040931rssgce0zzmklsul5.png)

在 Linux 中查找文件并不是什么大问题。市面上也有很多可靠的自由开源的可视化查找工具。但对我而言，查找文件，用命令行的方式会更快更简单。我们已经知道 [如何根据访问和修改文件的时间寻找或整理文件](https://www.ostechnix.com/find-sort-files-based-access-modification-date-time-linux/)。今天，在基于 Unix 的操作系统中，我们将见识如何通过权限查找文件。

本段教程中，我将创建三个文件名为 `file1`，`file2` 和 `file3` 分别赋予 `777`，`766` 和 `655` 文件权限，并分别置于名为 `ostechnix` 的文件夹中。

```
mkdir ostechnix && cd ostechnix/
install -b -m 777 /dev/null file1
install -b -m 766 /dev/null file2
install -b -m 655 /dev/null file3

```

![](/data/attachment/album/201801/26/040932u3z3tqy36q4exd3j.png)

现在，让我们通过权限来查找一下文件。

### 根据权限查找文件

根据权限查找文件最具代表性的语法：

```
find -perm mode

```

mode 可以是代表权限的八进制数字（777、666 …）也可以是权限符号（u=x，a=r+x）。

在深入之前，我们就以下三点详细说明 mode 参数。

1. 如果我们不指定任何参数前缀，它将会寻找**具体**权限的文件。
2. 如果我们使用 `-` 参数前缀， 寻找到的文件至少拥有 mode 所述的权限，而不是具体的权限（大于或等于此权限的文件都会被查找出来）。
3. 如果我们使用 `/` 参数前缀，那么所有者、组或者其他人任意一个应当享有此文件的权限。

为了让你更好的理解，让我举些例子。

首先，我们将要看到基于数字权限查找文件。

### 基于数字（八进制）权限查找文件

让我们运行下列命令：

```
find -perm 777

```

这条命令将会查找到当前目录权限为**确切为 777** 权限的文件。

![1](/data/attachment/album/201801/26/040932u6qowqindhfxoifg.png)

如你看见的屏幕输出，file1 是唯一一个拥有**确切为 777 权限**的文件。

现在，让我们使用 `-` 参数前缀，看看会发生什么。

```
find -perm -766

```

![](/data/attachment/album/201801/26/040932rwwb9wd0r99rxxh0.png)

如你所见，命令行上显示两个文件。我们给 file2 设置了 766 权限，但是命令行显示两个文件，什么鬼？因为，我们设置了 `-` 参数前缀。它意味着这条命令将在所有文件中查找文件所有者的“读/写/执行”权限，文件用户组的“读/写”权限和其他用户的“读/写”权限。本例中，file1 和 file2 都符合要求。换句话说，文件并不一样要求时确切的 766 权限。它将会显示任何属于（高于）此权限的文件 。

然后，让我们使用 `/` 参数前置，看看会发生什么。

```
find -perm /222

```

![](/data/attachment/album/201801/26/040932i22qreglurqgzldd.png)

上述命令将会查找某些人（要么是所有者、用户组，要么是其他人）拥有写权限的文件。这里有另外一个例子：

```
find -perm /220

```

这条命令会查找所有者或用户组中拥有写权限的文件。这意味着匹配所有者和用户组任一可写的文件，而其他人的权限随意。

如果你使用 `-` 前缀运行相同的命令，你只会看到所有者和用户组都拥有写权限的文件。

```
find -perm -220

```

下面的截图会告诉你这两个参数前缀的不同。

![](/data/attachment/album/201801/26/040933jgkgjgl6ku1pmzgb.png)

如我之前说过的一样，我们也可以使用符号表示文件权限。

请阅读：

* [如何在 Linux 中找到最大和最小的目录和文件](https://www.ostechnix.com/how-to-find-largest-and-smallest-directories-and-files-in-linux/)
* [如何在 Linux 的目录树中找到最老的文件](https://www.ostechnix.com/find-oldest-file-directory-tree-linux/)
* [如何在 Linux 中找到超过或小于某个大小的文件](https://www.ostechnix.com/find-files-bigger-smaller-x-size-linux/)

### 基于符号的文件权限查找文件

在下面的例子中，我们使用例如 `u`（所有者）、`g`（用户组） 和 `o`（其他） 的符号表示法。我们也可以使用字母 `a` 代表上述三种类型。我们可以通过特指的 `r` （读）、 `w` （写）、 `x` （执行）分别代表它们的权限。

例如，寻找用户组中拥有 `写` 权限的文件，执行：

```
find -perm -g=w

```

![](/data/attachment/album/201801/26/040933jihk3i55hu5luwcx.png)

上面的例子中，file1 和 file2 都拥有 `写` 权限。请注意，你可以等效使用 `=` 或 `+` 两种符号标识。例如，下列两行相同效果的代码。

```
find -perm -g=w
find -perm -g+w

```

查找文件所有者中拥有写权限的文件，执行：

```
find -perm -u=w

```

查找所有用户中拥有写权限的文件，执行：

```
find -perm -a=w

```

查找所有者和用户组中同时拥有写权限的文件，执行：

```
find -perm -g+w,u+w

```

上述命令等效与 `find -perm -220`。

查找所有者或用户组中拥有写权限的文件，执行：

```
find -perm /u+w,g+w

```

或者,

```
find -perm /u=w,g=w

```

上述命令等效于 `find -perm /220`。

更多详情，参照 man 手册。

```
man find

```

了解更多简化案例或其他 Linux 命令，查看[man 手册](https://www.ostechnix.com/3-good-alternatives-man-pages-every-linux-user-know/)。

然后，这就是所有的内容。希望这个教程有用。更多干货，敬请关注。

干杯！

---

via: <https://www.ostechnix.com/find-files-based-permissions/>

作者：[SK](https://www.ostechnix.com/author/sk/) 译者：[CYLeft](https://github.com/CYLeft) 校对：[校对者ID](https://github.com/%E6%A0%A1%E5%AF%B9%E8%80%85ID)

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


2018 年 4 个需要关注的人工智能趋势

Summary: 今年人工智能决策将变得更加透明吗？

今年人工智能决策将变得更加透明吗？

>
> 今年人工智能决策将变得更加透明？
>
>
>

![](/data/attachment/album/201801/26/043645wxtyp3r32vef2xj2.png)

无论你的 IT 业务现在使用了多少[人工智能](https://enterprisersproject.com/tags/artificial-intelligence)，预计你将会在 2018 年使用更多。即便你从来没有涉猎过 AI 项目，这也可能是将谈论转变为行动的一年，德勤董事总经理 David Schatsky 说。他说：“与 AI 开展合作的公司数量正在上升。”

看看他对未来一年的AI预测：

### 1、预期更多的企业 AI 试点项目

如今我们经常使用的许多现成的应用程序和平台都将 AI 结合在一起。 Schatsky 说：“除此之外，越来越多的公司正在试验机器学习或自然语言处理来解决特定的问题，或者帮助理解他们的数据，或者使内部流程自动化，或者改进他们自己的产品和服务。

“除此之外，公司与人工智能的合作强度将会上升。”他说，“早期采纳它的公司已经有五个或略少的项目正在进行中，但是我们认为这个数字会上升到十个或有更多正在进行的计划。” 他说，这个预测的一个原因是人工智能技术正在变得越来越好，也越来越容易使用。

### 2、人工智能将缓解数据科学人才紧缺的现状

人才是数据科学中的一个大问题，大多数大公司都在努力聘用他们所需要的数据科学家。 Schatsky 说，AI 可以承担一些负担。他说：“数据科学的实践，逐渐成为由创业公司和大型成熟的技术供应商提供的自动化的工具。”他解释说，大量的数据科学工作是重复的、乏味的，自动化的时机已经成熟。 “数据科学家不会消亡，但他们将会获得更高的生产力，所以一家只能做一些数据科学项目而没有自动化的公司将能够使用自动化来做更多的事情，虽然它不能雇用更多的数据科学家”。

### 3、合成数据模型将缓解瓶颈

Schatsky 指出，在你训练机器学习模型之前，你必须得到数据来训练它。 这并不容易，他说：“这通常是一个商业瓶颈，而不是生产瓶颈。 在某些情况下，由于有关健康记录和财务信息的规定，你无法获取数据。”

他说，合成数据模型可以采集一小部分数据，并用它来生成可能需要的较大集合。 “如果你以前需要 10000 个数据点来训练一个模型，但是只能得到 2000 个，那么现在就可以产生缺少的 8000 个数据点，然后继续训练你的模型。”

### 4、人工智能决策将变得更加透明

AI 的业务问题之一就是它经常作为一个黑匣子来操作。也就是说，一旦你训练了一个模型，它就会吐出你不能解释的答案。 Schatsky 说：“机器学习可以自动发现人类无法看到的数据模式，因为数据太多或太复杂。 “发现了这些模式后，它可以预测未见的新数据。”

问题是，有时你确实需要知道 AI 发现或预测背后的原因。 “以医学图像为例子来说，模型说根据你给我的数据，这个图像中有 90％ 的可能性是肿瘤。 “Schatsky 说，“你说，‘你为什么这么认为？’ 模型说：‘我不知道，这是数据给的建议。’”

Schatsky 说，如果你遵循这些数据，你将不得不对患者进行探查手术。 当你无法解释为什么时，这是一个艰难的请求。 “但在很多情况下，即使模型产生了非常准确的结果，如果不能解释为什么，也没有人愿意相信它。”

还有一些情况是由于规定，你确实不能使用你无法解释的数据。 Schatsky 说：“如果一家银行拒绝贷款申请，就需要能够解释为什么。 这是一个法规，至少在美国是这样。传统上来说，人类分销商会打个电话做回访。一个机器学习模式可能会更准确，但如果不能解释它的答案，就不能使用。”

大多数算法不是为了解释他们的推理而设计的。 他说：“所以研究人员正在找到聪明的方法来让 AI 泄漏秘密，并解释哪些变量使得这个病人更可能患有肿瘤。 一旦他们这样做，人们可以发现答案，看看为什么会有这样的结论。”

他说，这意味着人工智能的发现和决定可以用在许多今天不可能的领域。 “这将使这些模型更加值得信赖，在商业世界中更具可用性。”

---

via: <https://enterprisersproject.com/article/2018/1/4-ai-trends-watch>

作者：[Minda Zetlin](https://enterprisersproject.com/user/minda-zetlin) 译者：[Wuod3n](https://github.com/Wuod3n) 校对：[wxy](https://github.com/wxy)

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


创建一个简易 APT 仓库

![](/data/attachment/album/201801/27/103014y5f5jtxx6krvj76r.jpg)

作为我工作的一部分，我所维护的 [PATHspider](https://pathspider.net) 依赖于 [cURL](http://curl.haxx.se/) 和 [PycURL](http://pycurl.io/)中的一些[刚刚](https://github.com/pycurl/pycurl/pull/456)[被](https://github.com/pycurl/pycurl/pull/458)合并或仍在[等待](https://github.com/curl/curl/pull/1847)被合并的功能。我需要构建一个包含这些 Debian 包的 Docker 容器，所以我需要快速构建一个 APT 仓库。

Debian 仓库本质上可以看作是一个静态的网站，而且内容是经过 GPG 签名的，所以它不一定需要托管在某个可信任的地方（除非可用性对你的程序来说是至关重要的）。我在 [Netlify](http://netlify.com/)（一个静态的网站主机）上托管我的博客，我认为它很合适这种情况。他们也[支持开源项目](https://www.netlify.com/open-source/)。

你可以用下面的命令安装 netlify 的 CLI 工具：

```
sudo apt install npm
sudo npm install -g netlify-cli

```

设置仓库的基本步骤是：

```
mkdir repository
cp /path/to/*.deb repository/
cd repository
apt-ftparchive packages . > Packages
apt-ftparchive release . > Release
gpg --clearsign -o InRelease Release
netlify deploy

```

当你完成这些步骤后，并在 Netlify 上创建了一个新的网站，你也可以通过 Web 界面来管理这个网站。你可能想要做的一些事情是为你的仓库设置自定义域名，或者使用 Let's Encrypt 启用 HTTPS。（如果你打算启用 HTTPS，请确保命令中有 `apt-transport-https`。）

要将这个仓库添加到你的 apt 源：

```
gpg --export -a YOURKEYID | sudo apt-key add -
echo "deb https://SUBDOMAIN.netlify.com/ /" | sudo tee -a /etc/apt/sources.list
sudo apt update

```

你会发现这些软件包是可以安装的。注意下 [APT pinnng](https://wiki.debian.org/AptPreferences)，因为你可能会发现，根据你的策略，仓库上的较新版本实际上并不是首选版本。

**更新**：如果你想要一个更适合平时使用的解决方案，请参考 [repropro](https://mirrorer.alioth.debian.org/)。如果你想让最终用户将你的 apt 仓库作为第三方仓库添加到他们的系统中，请查看 [Debian wiki 上的这个页面](https://wiki.debian.org/DebianRepository/UseThirdParty)，其中包含关于如何指导用户使用你的仓库。

**更新 2**：有一位评论者指出用 [aptly](https://www.aptly.info/)，它提供了更多的功能，并消除了 repropro 的一些限制。我从来没有用过 aptly，所以不能评论具体细节，但从网站看来，这是一个很好的工具。

---

via: <https://iain.learmonth.me/blog/2017/2017w383/>

作者：[Iain R. Learmonth](https://iain.learmonth.me) 译者：[geekpi](https://github.com/geekpi) 校对：[wxy](https://github.com/wxy)

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


启动开源项目：免费指导！

![](/data/attachment/album/201801/27/113922v59x9hx61pdhkgch.jpg)

启动项目、组建社区支持可能会比较复杂，但是这个全新的指南可以帮助你开启开源项目。

各种规模的组织、技术人员和 DecOps 工作者选择使用开源项目，甚至去开发自己的开源项目，开源程序变得越来越普遍。从 Google 到 Netflix 再到 Facebook ，这些公司都在将它们的开源创作发布到开源社区。经常见到起于内部的开源项目，然后受惠于外部开发人员的合作开发。

然而，开启一个开源项目、组建社区支持比你想的还要复杂。一些前期准备可以帮助事情开展变得顺利，这就是这个全新的“[启动开源项目指南](https://www.linuxfoundation.org/resources/open-source-guides/starting-open-source-project/)”所能为你做的。

这个免费指南是为了帮助那些深谙开源的组织启动自己的开源项目而诞生。在本文的开始，介绍包括了决定开源什么项目，预计项目费用，考虑开源协议和一些其他方面。开源项目这种方式可能源自国外，但是从 Google 到 Facebook 这样一些主要的开源公司都已经开放提供了开源项目指导资源。事实上，Google 拥有的[丰富的在线资源](https://www.linux.com/blog/learn/chapter/open-source-management/2017/5/googles-new-home-all-things-open-source-runs-deep)对开源项目实践和启动开源项目上做出了贡献。

Capital One 开源社区经理 Jared Smith 指出，“无论公司在内雇佣了多少聪明人，总还是有聪明人在公司之外”， “我们发现开放我们的源代码给外面世界的专业且愿意分享的人士交流经验是非常值得的，我们能从中获取一些非常好的建议”。

在这个新指南中，开源专家 Ibrahim Haddad 提供了五条关于一个组织为什么要开源新项目的原因：

1. 促成开放式问题解决方案；为标准提供参照实现；分担战略功能的开发开销。
2. 商品化市场；减少非战略的软件成本费用。
3. 通过建立产品生态来驱动需求。
4. 协同合作；吸引客户；深化共同目标间的关系。
5. 提供用户自我支持的能力：无需等待即可调整代码

本文指出：“做出发布或创建一个新的开源项目的决定和自身境况相关。你的公司应该在使用或贡献既有的开源项目上拥有一定程度的熟练度。这是因为消费能够指导你，通过外部工程使开发者对自己的产品构建变得省力（参见我们的指南[使用开源代码](https://www.linuxfoundation.org/using-open-source-code/)和[加入开源社区](https://www.linuxfoundation.org/participating-open-source-communities/)  上）。但是当一旦你顺利的参与过开源，那这将是启动你自己的开源项目的最佳时机。”

该指南还指出, 规划可以使您和您的组织摆脱法律麻烦。如果您希望您的项目蓬勃发展, 则与许可、分发、支持选项甚至品牌相关的问题都需要提前考虑。

“我认为, 对于一家公司来说, 至关重要的是要考虑他们希望通过新的开源项目实现的目标，” Linux 基金会的项目管理主任 John Mertic 说。"他们必须考虑它对社区和开发者的价值，以及他们希望从中得到什么结果。然后, 他们必须了解所有的部分，以正确的方式去完成，包括法律、治理、基础设施和一个启动社区。当你把一个开源项目放在那里时，我总是最强调这些。”

这个“启动开源项目指南”可以帮助您了解从许可证问题到最佳开发实践的所有内容，并探讨如何无缝地将现有的开放组件编织到您的开源项目中。它是来自 Linux 基金会和 TODO 组的免费指南的新集合之一，对于任何运作开源程序的组织来说都非常有价值。现在可以使用该指南来帮助您运行开源计划办公室，以支持、分享和利用开源。有了这样一个办公室， 组织就可以有效地建立并执行其开放源码战略，并有明确的条款。

这些免费的教程是基于开源领导人的经验而来。[在这里可以查看所有指南](https://github.com/todogroup/guides)，然后关注我们的后续文章。

也别错过了本系列早些的文章：

* [如何创建开源计划](https://github.com/todogroup/guides/blob/master/creating-an-open-source-program.md)
* [开源计划管理工具](https://www.linuxfoundation.org/blog/managing-open-source-programs-free-guide/)
* [衡量你的开源项目成功性](https://www.linuxfoundation.org/measuring-your-open-source-program-success/)
* [吸引开源开发者的高效策略](https://www.linuxfoundation.org/blog/effective-strategies-recruiting-open-source-developers/)
* [加入开源社区](https://www.linuxfoundation.org/participating-open-source-communities/)
* [使用开源代码](https://www.linuxfoundation.org/using-open-source-code/)

---

via: <https://www.linuxfoundation.org/blog/launching-open-source-project-free-guide/>

作者：[Sam Dean](https://www.linuxfoundation.org/author/sdean/) 译者：[CYLeft](https://github.com/CYLeft) 校对：[wxy](https://github.com/wxy)

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


如何解决 check_mk 出现 “Cannot fetch deployment URL via curl” 的错误

本文解释了 “ERROR Cannot fetch deployment URL via curl：Couldn't resolve host。The given remote host was not resolved。” 的原因及其解决方案。

![ERROR Cannot fetch deployment URL via curl：Couldn't resolve host。The given remote host was not resolved。](/data/attachment/album/201801/27/115331ohoqitxjxjhsijkt.png)

`check_mk` 是一个帮你配置 [nagios](https://www.nagios.org/) 监控服务器的工具。然后在配置其中一台机器时，我遇到了下面的错误：

```
ERROR Cannot fetch deployment URL via curl：Couldn't resolve host。The given remote host was not resolved。

```

该错误是在我使用下面命令尝试将该机器注册到监控服务器时发生的：

```
root@kerneltalks# /usr/bin/cmk-update-agent register -s monitor.kerneltalks.com -i master -H `hostname` -p http -U omdadmin -S ASFKWEFUNSHEFKG -v

```

其中：

* `-s` 指明监控服务器
* `-i` 指定服务器上 Check\_MK 站点的名称
* `-H` 指定 agent 所在的主机名
* `-p` 为协议，可以是 http 或 https （默认为 https）
* `-U` 允许下载 agent 的用户 ID
* `-S` 为密码。用户的自动操作密码（当是自动用户时）

从错误中可以看出，命令无法解析监控服务器的 DNS 名称 `monitor.kerneltalks.com`。

### 解决方案：

超级简单。检查 `/etc/resolv.conf`，确保你的 DNS 配置正确。如果还解决不了这个问题那么你可以直接在 [/etc/hosts](https://kerneltalks.com/linux/understanding-etc-hosts-file/) 中指明它的 IP。

```
root@kerneltalks# cat /etc/hosts
10.0.10.9 monitor.kerneltalks.com

```

这就搞定了。你现在可以成功注册了。

```
root@kerneltalks # /usr/bin/cmk-update-agent register -s monitor.kerneltalks.com -i master -H `hostname` -p http -U omdadmin -S ASFKWEFUNSHEFKG -v
Going to register agent at deployment server
Successfully registered agent for deployment.
You can now update your agent by running 'cmk-update-agent -v'
Saved your registration settings to /etc/cmk-update-agent.state.

```

另外，你也可以为 `-s` 直接指定 IP 地址，就没那么多事了！

---

via: <https://kerneltalks.com/troubleshooting/check_mk-register-cannot-fetch-deployment-url-via-curl-error/>

作者：[kerneltalks](https://kerneltalks.com) 译者：[lujun9972](https://github.com/lujun9972) 校对：[wxy](https://github.com/wxy)

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


三款简单而优秀的 Linux 网络监视工具

Summary: 通过 iftop、 nethogs 和 vnstat 详细了解你的网络连接状态。

![network](/data/attachment/album/201801/27/122518y3s2q22s62j21j6z.png "network")

>
> 通过 `iftop`、 `nethogs` 和 `vnstat` 详细了解你的网络连接状态。
>
>
>

你可以通过这三个 Linux 命令了解当前网络的大量信息。`iftop` 通过进程号跟踪网络连接，`nethogs` 快速告知你哪些进程在占用你的带宽，而 `vnstat` 以一个良好的轻量级守护进程在后台运行，并实时记录你的网络使用情况。

### iftop

令人称赞的 `iftop` 可以监听您指定的网络接口，并以 top 的样式呈现。

这是一个不错的小工具，可以用于找出网络拥塞，测速和维持网络流量总量。看到自己到底在用多少带宽往往是非常惊人的，尤其是对于我们这些仍然记得电话线路、调制解调器，“高速”到令人惊叫的 kb 和实时波特率的老人们。我们在很久之前就不再使用波特率，转而钟情于比特率。波特率用于衡量信号变化，尽管有时候与比特率相同，但大多数情况下并非如此。

如果你只有一个网络接口，直接运行 `iftop` 即可。不过 `iftop` 需要 root 权限：

```
$ sudo iftop

```

如果你有多个网络接口，那就指定你要监控的接口：

```
$ sudo iftop -i wlan0

```

就像 `top` 命令一样，你可以在命令运行时更改显示选项：

* `h` 切换帮助界面。
* `n` 是否解析域名。
* `s` 切换源地址的显示，`d` 则切换目的地址的显示。
* `S` 是否显示端口号。
* `N` 是否解析端口；若关闭解析则显示端口号。
* `t` 切换文本显示界面。默认的显示方式需要 ncurses。我个人认为图 1 的显示方式在组织性和可读性都更加良好。
* `p` 暂停显示更新。
* `q` 退出程序。

![text display](/data/attachment/album/201801/27/122519kjjtdh5fftzwfpzp.png "text display")

*图 1:组织性和可读性良好的文本显示。*

当你切换显示设置的时候，`iftop` 并不会中断监测流量。当然你也可以单独监测一台主机。而这需要该主机的 IP 地址和子网掩码。现在，我很好奇 Pandora（LCTT 译注：一家美国的电台公司）能给我贫瘠的带宽带来多大的负载。因此我首先使用 dig 命令找到他们的 IP 地址：

```
$ dig A pandora.com
[...]
;; ANSWER SECTION:
pandora.com.            267     IN      A       208.85.40.20
pandora.com.            267     IN      A       208.85.40.50

```

那子网掩码呢？[ipcalc](https://www.linux.com/learn/intro-to-linux/2017/8/how-calculate-network-addresses-ipcalc) 会告诉我们：

```
$ ipcalc -b 208.85.40.20
Address:   208.85.40.20
Netmask:   255.255.255.0 = 24
Wildcard:  0.0.0.255
=>
Network:   208.85.40.0/24

```

现在，将 IP 地址和子网掩码提供给 `iftop`：

```
$ sudo iftop -F 208.85.40.20/24 -i wlan0

```

很棒的不是么？而我也很惊奇地发现，Pandora 在我的网络上，每小时大约使用 500kb。并且就像大多数流媒体服务一样，Pandora 的流量在迅速增长，并依靠缓存稳定下来。

你可以使用 `-G` 选项对 IPv6 地址执行相同的操作。查阅友好的 man 可以帮助你了解 `iftop` 的其他功能，包括使用个人配置文件自定义你的默认选项，以及使用自定义过滤（请参阅 [PCAP-FILTER](http://www.tcpdump.org/manpages/pcap-filter.7.html) 来获取过滤指南）。

### nethogs

当你想要快速了解是谁在吸取你的带宽的时候，`nethogs` 是个快速而简单的方法。你需要以 root 身份运行并指定要监听的接口。它会给你显示大量的应用程序及其进程号，所以如果你想的话，你可以借此杀死任一进程。

```
$ sudo nethogs wlan0

nethogs version 0.8.1

PID USER   PROGRAM              DEV    SENT   RECEIVED
7690 carla /usr/lib/firefox     wlan0 12.494 556.580 KB/sec
5648 carla .../chromium-browser wlan0  0.052   0.038 KB/sec
TOTAL                                 12.546 556.618 KB/sec

```

`nethogs` 并没有多少选项：在 kb/s、kb、b、mb之间循环，按接收和发送的数据包排序，调整刷新延迟。具体请看`man nethogs`，或者是运行 `nethogs -h`。

### vnstat

[vnstat](http://humdi.net/vnstat/)是最容易使用的网络数据收集工具。它十分轻量并且不需要 root 权限。它以守护进程在后台运行，因此可以实时地记录你的网络数据。单个 `vnstat` 命令就可以显示所累计的数据。

```
$ vnstat -i wlan0
Database updated: Tue Oct 17 08:36:38 2017

   wlan0 since 10/17/2017

          rx:  45.27 MiB      tx:  3.77 MiB      total:  49.04 MiB

   monthly
                     rx      |     tx      |    total    |   avg. rate
     ------------------------+-------------+-------------+---------------
       Oct '17     45.27 MiB |    3.77 MiB |   49.04 MiB |    0.28 kbit/s
     ------------------------+-------------+-------------+---------------
     estimated        85 MiB |       5 MiB |      90 MiB |

   daily
                     rx      |     tx      |    total    |   avg. rate
     ------------------------+-------------+-------------+---------------
         today     45.27 MiB |    3.77 MiB |   49.04 MiB |   12.96 kbit/s
     ------------------------+-------------+-------------+---------------
     estimated       125 MiB |       8 MiB |     133 MiB |

```

默认情况下它会显示所有的网络接口。使用 `-i` 选项来选择某个接口。也可以像这样合并多个接口的数据：

```
$ vnstat -i wlan0+eth0+eth1

```

你可以通过这几种方式过滤数据显示：

* `-h` 按小时显示统计信息。
* `-d` 按天显示统计信息.
* `-w` 和 `-m` 分别按周和月份来显示统计信息。
* 使用 `-l` 选项查看实时更新。

以下这条命令将会删除 wlan1 的数据库并不再监视它：

```
$ vnstat -i wlan1 --delete

```

而下面这条命令将会为你的一个网络接口创建一个别名。这个例子使用了 Ubuntu 16.04 的一个有线接口名称：

```
$ vnstat -u -i enp0s25 --nick eth0

```

默认情况下，vnstat 会监视 eth0。你可以在 `/etc/vnstat.conf` 对它进行修改，或者在你的家目录下创建你自己的个人配置文件。请参阅 `man vnstat` 以获取完整的指南。

你也可以安装 `vnstati` 来创建简单的彩图（图 2）:

```
$ vnstati -s -i wlx7cdd90a0a1c2 -o vnstat.png

```

![vnstati](/data/attachment/album/201801/27/122520bdn47s4s847n7j4j.png "vnstati")

*图 2:你可以使用vnstati来创建简单的彩图。*

请参阅 `man vnstati` 以获取完整的选项。

*欲了解 Linux 的更多信息，可以通过学习 Linux 基金会和 edX 的免费课程，[“Linux 入门”](https://training.linuxfoundation.org/linux-courses/system-administration-training/introduction-to-linux)。*

---

via: <https://www.linux.com/learn/intro-to-linux/2017/10/3-simple-excellent-linux-network-monitors>

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

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


无需 root 实现在 Android 设备上运行 Linux

![](/data/attachment/album/201801/28/092426b5w9iz45g7z34bgg.jpg)

曾经，我尝试过搜索一种简单的可以在 Android 上运行 Linux 的方法。我当时唯一的意图只是想使用 Linux 以及一些基本的应用程序，比如 SSH，Git，awk 等。要求的并不多！我不想 root 我的 Android 设备。我有一台平板电脑，主要用于阅读电子书、新闻和少数 Linux 博客。除此之外也不怎么用它了。因此我决定用它来实现一些 Linux 的功能。在 Google Play 商店上浏览了几分钟后，一个应用程序瞬间引起了我的注意，勾起了我实验的欲望。如果你也想在 Android 设备上运行 Linux，这个应用可能会有所帮助。

### Termux - 在 Android 和 Chrome OS 上运行的 Android 终端模拟器

**Termux** 是一个 Android 终端模拟器以及提供 Linux 环境的应用程序。跟许多其他应用程序不同，你无需 root 设备也无需进行设置。它是开箱即用的！它会自动安装好一个最基本的 Linux 系统，当然你也可以使用 APT 软件包管理器来安装其他软件包。总之，你可以让你的 Android 设备变成一台袖珍的 Linux 电脑。它不仅适用于 Android，你还能在 Chrome OS 上安装它。

![](/data/attachment/album/201801/28/092427qdfflalzndzdvll2.png)

Termux 提供了许多重要的功能，比您想象的要多。

* 它允许你通过 openSSH 登录远程服务器。
* 你还能够从远程系统 SSH 到 Android 设备中。
* 使用 rsync 和 curl 将您的智能手机通讯录同步到远程系统。
* 支持不同的 shell，比如 BASH、ZSH，以及 FISH 等等。
* 可以选择不同的文本编辑器来编辑/查看文件，支持 Emacs、Nano 和 Vim。
* 使用 APT 软件包管理器在 Android 设备上安装你想要的软件包。支持 Git、Perl、Python、Ruby 和 Node.js 的最新版本。
* 可以将 Android 设备与蓝牙键盘、鼠标和外置显示器连接起来，就像是整合在一起的设备一样。Termux 支持键盘快捷键。
* Termux 支持几乎所有 GNU/Linux 命令。

此外通过安装插件可以启用其他一些功能。例如，**Termux：API** 插件允许你访问 Android 和 Chrome 的硬件功能。其他有用的插件包括：

* Termux：Boot - 设备启动时运行脚本
* Termux：Float - 在浮动窗口中运行 Termux
* Termux：Styling - 提供配色方案和支持 Powerline 的字体来定制 Termux 终端的外观。
* Termux：Task - 提供一种从任务栏类的应用中调用 Termux 可执行文件的简易方法。
* Termux：Widget - 提供一种从主屏幕启动小脚本的建议方法。

要了解更多有关 termux 的信息，请长按终端上的任意位置并选择“帮助”菜单选项来打开内置的帮助部分。它唯一的缺点就是**需要 Android 5.0 及更高版本**。如果它支持 Android 4.x 和旧版本的话，将会更有用的多。你可以在 **Google Play 商店**和 **F-Droid** 中找到并安装 Termux。

要在 Google Play 商店中安装 Termux，点击下面按钮。

[![](/data/attachment/album/201801/28/092427izx6r0xxr12xrx1e.png)](https://play.google.com/store/apps/details?id=com.termux)

若要在 F-Droid 中安装，则点击下面按钮。

[![](/data/attachment/album/201801/28/092428ar1u338drsu3fpsm.png)](https://f-droid.org/packages/com.termux/)

你现在知道如何使用 Termux 在 Android 设备上使用 Linux 了。你有用过其他更好的应用吗？请在下面留言框中留言。我很乐意也去尝试他们！

此致敬礼！

相关资源：

* [Termux 官网](https://termux.com/)

---

via: <https://www.ostechnix.com/termux-run-linux-android-devices-no-rooting-required/>

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

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


3 个可以替代 Emacs 和 Vim 的文本编辑器

![](/data/attachment/album/201801/28/210355ah11eco6vzwbk1h5.png)

>
> Vim 和 Emacs 对于 Linux 桌面上进行文本编辑显然是重量级的，但是它们并非唯一之选。
>
>
>

Emacs 和 Vim 的粉丝们，在你们开始编辑器之争之前，请你们理解，这篇文章并不是为了贬低诸位最喜欢的编辑器。我是一个 Emacs 爱好者，但是也很喜欢 Vim。

就是说，我认为 Emacs 和 Vim 并不适合所有人。也许 [编辑器之争](https://en.wikipedia.org/wiki/Editor_war) 略显幼稚，让很多人失望了。也许他们只是想要有一个不太苛刻的现代化的编辑器。

如果你正寻找可以替代 Emacs 或者 Vim 的编辑器，请继续阅读下去。这里有三个可能会让你感兴趣的编辑器。

### Geany

![用 Geany 编辑一个 LaTeX 文档](/data/attachment/album/201801/28/210408ch76d89g6ybgsdy8.png "Editing a LaTeX document with Geany")

*你可以用 Geany 编辑 LaTeX 文档*

[Geany](https://www.geany.org/) 是一个古老的编辑器，当我还在过时的硬件上运行轻量级 Linux 发行版的时候，[Geany](https://www.geany.org/) 就是一个优秀的的编辑器。Geany 开始用于我的 [LaTeX](https://opensource.com/article/17/6/introduction-latex) 编辑，但是很快就成为我所有的文本编辑的编辑器了。

尽管 Geany 号称是轻量且快速的 [IDE](https://en.wikipedia.org/wiki/Integrated_development_environment)（集成开发环境），但是它绝不仅仅是一个技术人的工具。Geany 轻便快捷，即便是在一个过时的机器或是 [运行 Linux 的 Chromebook](https://opensource.com/article/17/4/linux-chromebook-gallium-os) 也能轻松运行起来。无论是从编辑配置文件到维护任务列表或日志，从写文章或书籍到编写代码和脚本，Geany 都能轻松胜任。

[插件](http://plugins.geany.org/) 给 Geany 带来一些额外的魅力。这些插件拓展了 Geany 的功能，让你编码或是处理一些标记语言变得更高效，帮助你处理文本，甚至做拼写检查。

### Atom

![使用 Atom 编辑网页](/data/attachment/album/201801/28/210410aqgdrruf3nggmxea.png "Editing a webpage with Atom")

*使用 Atom 编辑网页*

在文本编辑器领域，[Atom](https://atom.io) 后来居上。很短的时间内，Atom 就获得了一批忠实的追随者。

Atom 的定制功能让其拥有如此的吸引力。如果有一些技术癖好，你完全可以在这个编辑器上随意设置。如果你不仅仅是沉迷技术，Atom 也有 [一些主题](https://atom.io/themes) ，你可以用来更改编辑器外观。

千万不要低估 Atom 数以千计的 [拓展包](https://atom.io/packages)。它们能在不同功能上拓展 Atom，能根据你的爱好把 Atom 转化成合适的文本编辑器或是开发环境。Atom 不仅为程序员提供服务。它同样是适用于 [作家的文本编辑器](https://opensource.com/article/17/5/atom-text-editor-packages-writers)。

### Xed

![使用 Xed 编辑文章](/data/attachment/album/201801/28/210411bu7e5zve56vsu1vn.png "Writing this article in Xed")

*使用 Xed 编辑文章*

可能对用户体验来说，Atom 和 Geany 略显臃肿。也许你只想要一个轻量级，一个不要太简陋也不要有太多很少使用的特性的编辑器，如此看来，[Xed](https://github.com/linuxmint/xed) 正是你所期待的。

如果 Xed 你看着眼熟，那是因为它是 MATE 桌面环境中 Pluma 编辑器上的分支。我发现相比于 Pluma，Xed 可能速度更快一点，响应更灵敏一点——不过，因人而异吧。

虽然 Xed 没有那么多的功能，但也不至于太糟。它有扎实的语法高亮，略强于一般的搜索替换和拼写检查功能以及单窗口编辑多文件的选项卡式界面。

### 其他值得发掘的编辑器

我不是 KDE 痴，当我工作在 KDE 环境下时， [KDevelop](https://www.kdevelop.org/) 就已经是我深度工作时的首选了。它很强大而且灵活，又没有过大的体积，很像 Genany。

虽然我还没感受过对它的喜爱，但是我认识的几个人都用 [Brackets](http://brackets.io/) 感受到了。它很强大，而且不得不承认它的 [拓展](https://registry.brackets.io/) 真的很实用。

被称为 “开发者的编辑器” 的 [Notepadqq](http://notepadqq.altervista.org/s/) ，总让人联想到 [Notepad++](https://opensource.com/article/16/12/notepad-text-editor)。虽然它的发展仍处于早期阶段，但至少它看起来还是很有前景的。

对于那些只有简单的文本编辑器需求的人来说，[Gedit](https://wiki.gnome.org/Apps/Gedit) 和 [Kate](https://kate-editor.org/) 相比是极好的。它绝不是太过原始的编辑器——它有足够完成大型文本编辑的功能。无论是 Gedit 还是 Kate 都以速度和易上手而称名。

你有其他 Emacs 和 Vim 之外的挚爱编辑器么？方便的话留言分享。

---

via: <https://opensource.com/article/17/9/3-alternatives-emacs-and-vim>

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

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


在 Linux 字符界面中获取天气预报

Summary: http://wttr.in 是一个允许你搜索世界各地天气预报的网站，而且它的是以 ASCII 字符的形式来显示结果的。通过使用 cURL 访问 http://wttr.in，就能直接在终端显示查询结果了。

机器人自动点赞  -.-

zsh下在问好前面加 \ 即可

![](/data/attachment/album/201801/28/212019uf8fs6lz8wbffcli.jpg)

**目标：**使用 Linux 命令行显示天气预报。

**发行版：**所有 Linux 发行版。

**要求：**能连上因特网的 Linux

**难度：**容易

**约定：**

* `#` - 需要使用 root 权限来执行指定命令，可以直接使用 root 用户来执行也可以使用 `sudo` 命令
* `$` - 可以使用普通用户来执行指定命令

### 简介

无需打开网页浏览器就能直接从终端获取最新的天气预报那该多方便啊，对吧？你还能把它写成脚本，或者设置定义定时任务。

`http://wttr.in` 是一个允许你搜索世界各地天气预报的网站，而且它的是以 ASCII 字符的形式来显示结果的。通过使用 `cURL` 访问 `http://wttr.in`，就能直接在终端显示查询结果了。

### 获取所在地的天气

![Local weather from wttr.in](/data/attachment/album/201801/28/212033thhm9ib99n1ihhjm.jpg)

要抓取所在地的天气情况非常简单。`wttr.in` 会自动根据 IP 地址来探测你的所在地。除非你用了 VPN，否则它的精度还不错。

```
$ curl wttr.in

```

### 获取指定城市的天气

![Weather by city from wttr.in](/data/attachment/album/201801/28/212034ukawk4azxv8b7lge.jpg)

你可以通过在 `wttr.in` 后加上斜杠和城市名称的方式来获得其他城市的天气情况。不过要把名字中的空格替换成 `+`。

```
$ curl wttr.in/New+York

```

你也可以以 Unix 时区的形式来填写城市名称。

```
$ curl wttr.in/New_York

```

不要直接使用空格，否则会出现奇怪而不准确的结果。

### 获取机场天气

![Weather by airport from wttr.in](/data/attachment/album/201801/28/212035opdd4pgs4xqrgws7.jpg)

若你对地区的三位机场代号很熟悉，你也可以使用机场代号来查询天气。一般来说使用机场要比使用城市更贴近你，而且更精确一些。

```
$ curl wttr.in/JFK

```

### 猜测所在地

![Weather by landmark from wttr.in](/data/attachment/album/201801/28/212036cxl2ffbm55bfy551.jpg)

通过使用 `~` 字符，你可以让 `wttr.in` 通过地标来猜测天气情况。

```
$ curl wttr.in/~Statue+Of+Liberty

```

### 域名所在地的天气

![Weather by domain name from wttr.in](/data/attachment/album/201801/28/212036c0x3uazx3nbceexe.jpg)

你想不想知道 LinuxConfig 托管地的天气？现在有一个方法可以知道！`wttr.in` 可以通过域名获取天气。是的，这个功能可能不那么实用，但这很有趣啊。

```
$ curl wttr.in/@linuxconfig.org

```

### 更改温度单位

![Change unit system in wttr.in](/data/attachment/album/201801/28/212037tdv1d8vd3hk8ka3v.jpg)

默认情况下，`wttr.in` 会根据你的实际地址来决定显示哪种温度单位（C 还是 F）。基本上，在美国，使用的是华氏度，而其他地方显示的是摄氏度。你可以指定显示的温度单位，在 URL 后添加 `?u` 会显示华氏度，而添加 `?m` 会显示摄氏度。

```
$ curl wttr.in/New_York?m

$ curl wttr.in/Toronto?u

```

在 ZSH 上有一个很奇怪的 bug，会使得这两条语句不能正常工作，如果你需要更换单位，恐怕需要改成使用 Bash 了。

### 总结

你可以很方便地在脚本，定时任务，甚至 MOTD（LCTT 译注：Message Of The Day - 每日消息）中访问 `wttr.in`。当然，你完全没有必要这么做。当你需要查看天气预报的时候只需要访问一下这个超棒的网站就行了。

---

via: <https://linuxconfig.org/get-your-weather-forecast-from-the-linux-cli>

作者：[Nick Congleton](https://linuxconfig.org) 译者：[lujun9972](https://github.com/lujun9972) 校对：[wxy](https://github.com/wxy)

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


如何在 Linux/Unix/Windows 中发现隐藏的进程和端口

Summary: 绝大多数的 Rootkit 工具或者恶意软件借助内核来实现进程隐藏，这些进程只在内核内部可见。你可以使用 unhide 或者诸如 rkhunter 等工具，扫描 rootkit 程序 、后门程序以及一些可能存在的本地漏洞。

`unhide` 是一个小巧的网络取证工具，能够发现那些借助 rootkit、LKM 及其它技术隐藏的进程和 TCP/UDP 端口。这个工具在 Linux、UNIX 类、MS-Windows 等操作系统下都可以工作。根据其 man 页面的说明：

>
> Unhide 通过下述三项技术来发现隐藏的进程。
>
>
> 1. 进程相关的技术，包括将 `/proc` 目录与 [/bin/ps](https://www.cyberciti.biz/faq/show-all-running-processes-in-linux/ "Linux / Unix ps command") 命令的输出进行比较。
> 2. 系统相关的技术，包括将 [/bin/ps](https://www.cyberciti.biz/faq/show-all-running-processes-in-linux/ "Linux / Unix ps command") 命令的输出结果同从系统调用方面得到的信息进行比较。
> 3. 穷举法相关的技术，包括对所有的进程 ID 进行暴力求解，该技术仅限于在基于 Linux2.6 内核的系统中使用。
>
>
>

绝大多数的 Rootkit 工具或者恶意软件借助内核来实现进程隐藏，这些进程只在内核内部可见。你可以使用 `unhide` 或者诸如 [rkhunter 等工具，扫描 rootkit 程序 、后门程序以及一些可能存在的本地漏洞](https://www.cyberciti.biz/faq/howto-check-linux-rootkist-with-detectors-software/)。

![](/data/attachment/album/201801/28/222715iwpb9s492l6bbj5p.jpg)

这篇文章描述了如何安装 unhide 并搜索隐藏的进程和 TCP/UDP 端口。

### 如何安装 unhide

首先建议你在只读介质上运行这个工具。如果使用的是 Ubuntu 或者 Debian 发行版，输入下述的 [apt-get](https://www.cyberciti.biz/tips/linux-debian-package-management-cheat-sheet.html "See Linux/Unix apt-get command examples for more info")/[apt](//www.cyberciti.biz/faq/ubuntu-lts-debian-linux-apt-command-examples/ "See Linux/Unix apt command examples for more info") 命令以安装 Unhide：

```
$ sudo apt-get install unhide

```

一切顺利的话你的命令行会输出以下内容：

```
[sudo] password for vivek:
Reading package lists... Done
Building dependency tree
Reading state information... Done
Suggested packages:
  rkhunter
The following NEW packages will be installed:
  unhide
0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded.
Need to get 46.6 kB of archives.
After this operation, 136 kB of additional disk space will be used.
Get:1 http://in.archive.ubuntu.com/ubuntu artful/universe amd64 unhide amd64 20130526-1 [46.6 kB]
Fetched 46.6 kB in 0s (49.0 kB/s)
Selecting previously unselected package unhide.
(Reading database ... 205367 files and directories currently installed.)
Preparing to unpack .../unhide_20130526-1_amd64.deb ...
Unpacking unhide (20130526-1) ...
Setting up unhide (20130526-1) ...
Processing triggers for man-db (2.7.6.1-2) ...

```

### 如何在 RHEL/CentOS/Oracle/Scientific/Fedora 上安装 unhide

输入下列 yum Type the following yum command (first turn on EPLE repo on a CentOS/RHEL version 6.x or version 7.x):

输入以下的 [yum](https://www.cyberciti.biz/faq/rhel-centos-fedora-linux-yum-command-howto/ "See Linux/Unix yum command examples for more info") 命令（CentOS/RHEL [6.x](https://www.cyberciti.biz/faq/fedora-sl-centos-redhat6-enable-epel-repo/) 或 [7.x](https://www.cyberciti.biz/faq/installing-rhel-epel-repo-on-centos-redhat-7-x/) 上首先打开 EPEL 仓库）：

```
$ sudo yum install unhide

```

在 Fedora 上则使用以下 dnf 命令：

```
$ sudo dnf install unhide

```

### 如何在 Arch 上安装 unhide

键入以下 pacman 命令安装：

```
$ sudo pacman -S unhide

```

### 如何在 FreeBSD 上安装 unhide

可以通过以下的命令使用 port 来安装 unhide：

```
# cd /usr/ports/security/unhide/
# make install clean

```

或者可以通过二进制文件安装 hide，使用 pkg 命令安装：

```
# pkg install unhide

```

### 如何使用 unhide 工具？

unhide 的语法是：

```
unhide [options] test_list

```

`test_list` 参数可以是以下测试列表中的一个或者多个标准测试：

1. brute
2. proc
3. procall
4. procfs
5. quick
6. reverse
7. sys

或基本测试：

1. checkbrute
2. checkchdir
3. checkgetaffinity
4. checkgetparam
5. checkgetpgid
6. checkgetprio
7. checkRRgetinterval
8. checkgetsched
9. checkgetsid
10. checkkill
11. checknoprocps
12. checkopendir
13. checkproc
14. checkquick
15. checkreaddir
16. checkreverse
17. checksysinfo
18. checksysinfo2
19. checksysinfo3

你可以通过以下示例命令使用 `unhide`：

```
# unhide proc
# unhide sys
# unhide quick

```

示例输出：

```
Unhide 20130526
Copyright © 2013 Yago Jesus & Patrick Gouin
License GPLv3+ : GNU GPL version 3 or later
http://www.unhide-forensics.info

NOTE : This version of unhide is for systems using Linux >= 2.6

Used options:
[*]Searching for Hidden processes through  comparison of results of system calls, proc, dir and ps

```

### 如何使用 unhide-tcp 工具辨明 TCP/UDP 端口的身份

以下是来自 man 页面的介绍：

>
> `unhide-tcp` 取证工具通过对所有可用的 TCP/IP 端口进行暴力求解的方式，辨别所有正在监听，却没有列入 [/bin/netstat](https://www.cyberciti.biz/tips/linux-display-open-ports-owner.html "Linux netstat command") 或者 [/bin/ss](https://www.cyberciti.biz/tips/linux-investigate-sockets-network-connections.html) 命令输出的 TCP/IP 端口身份。
>
>
> 注一：对于 FreeBSD、OpenBSD系统，一般使用 netstat 命令取代在这些操作系统上不存在的 iproute2，此外，sockstat 命令也用于替代 fuser。
>
>
> 注二：如果操作系统不支持 iproute2 命令，在使用 `unhide` 时需要在命令上加上 `-n` 或者 `-s` 选项。
>
>
>

```
# unhide-tcp

```

示例输出：

```
Unhide 20100201
http://www.security-projects.com/?Unhide

Starting TCP checking

Starting UDP checking

```

上述操作中，没有发现隐藏的端口。

但在下述示例中，我展示了一些有趣的事。

```
# unhide-tcp

```

示例输出：

```
Unhide 20100201
http://www.security-projects.com/?Unhide

Starting TCP checking

Found Hidden port that not appears in netstat: 1048
Found Hidden port that not appears in netstat: 1049
Found Hidden port that not appears in netstat: 1050
Starting UDP checking

```

可以看到 `netstat -tulpn` 和 `ss` 命令确实没有反映出这三个隐藏的端口：

```
# netstat -tulpn | grep 1048
# ss -lp
# ss -l | grep 1048

```

通过下述的 man 命令可以更多地了解 `unhide`：

```
$ man unhide
$ man unhide-tcp

```

### Windows 用户如何安装使用 unhide

你可以通过这个[页面](http://www.unhide-forensics.info/?Windows:Download)获取 Windows 版本的 unhide。

---

via: <https://www.cyberciti.biz/tips/linux-unix-windows-find-hidden-processes-tcp-udp-ports.html>

作者：[Vivek Gite](https://www.cyberciti.biz) 译者：[ljgibbslf](https://github.com/ljgibbslf) 校对：[wxy](https://github.com/wxy)

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

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


热爱你的 Bug

![](/data/attachment/album/201801/28/235056e16ps197dkaz1aay.jpg)

十月初的时候我在贝洛奥里藏特的[<ruby> 巴西 Python 大会 <rt>  Python Brasil </rt></ruby>](http://2017.pythonbrasil.org.br/#)上做了主题演讲。这是稍加改动过的演讲文稿。你可以在[这里](http://www.youtube.com/watch?v=h4pZZOmv4Qs)观看演讲视频。

### 我爱 bug

我目前是 [Pilot.com](http://www.pilot.com/) 的一位高级工程师，负责给创业公司提供自动记账服务。在此之前，我曾是 [Dropbox](http://www.dropbox.com/) 的桌面客户端组的成员，我今天将分享关于我当时工作的一些故事。更早之前，我是 [Recurse Center](http://www.recurse.com/) 的导师，给身在纽约的程序员提供临时的训练环境。在成为工程师之前，我在大学攻读天体物理学并在金融界工作过几年。

但这些都不重要——关于我你唯一需要知道的是，我爱 bug。我爱 bug 因为它们有趣。它们富有戏剧性。调试一个好的 bug 的过程可以非常迂回曲折。一个好的 bug 像是一个有趣的笑话或者或者谜语——你期望看到某种结果，但却事与愿违。

在这个演讲中我会给你们讲一些我曾经热爱过的 bug，解释为什么我如此爱 bug，然后说服你们也同样去热爱 bug。

### Bug 1 号

好，让我们直接来看第一个 bug。这是我在 Dropbox 工作时遇到的一个 bug。你们或许听说过，Dropbox 是一个将你的文件从一个电脑上同步到云端和其他电脑上的应用。

```
        +--------------+     +---------------+
        |              |     |               |
        |  元数据服务器  |     |     块服务器    |
        |              |     |               |
        +-+--+---------+     +---------+-----+
          ^  |                         ^
          |  |                         |
          |  |     +----------+        |
          |  +---> |          |        |
          |       |   客户端   +--------+
          +--------+          |
                   +----------+

```

这是个极度简化的 Dropbox 架构图。桌面客户端在你的电脑本地运行，监听文件系统的变动。当它检测到文件改动时，它读取改变的文件，并把它的内容 hash 成 4 MB 大小的文件块。这些文件块被存放在后端一个叫做<ruby> 块服务器 <rt>  blockserver </rt></ruby>的巨大的<ruby> 键值对数据库 <rt>  key-value store </rt></ruby>中。

当然，我们想避免多次上传同一个文件块。可以想见，如果你在编写一份文档，你应该大部分时候都在改动文档最底部——我们不想一遍又一遍地上传开头部分。所以在上传文件块到块服务器之前之前，客户端会先和一个负责管理元数据和权限等等的服务器沟通。客户端会询问这个<ruby> 元数据服务器 <rt>  metaserver </rt></ruby>它是需要这个文件块，还是已经见过这个文件块了。元数据服务器会返回每一个文件块是否需要上传。

所以这些请求和响应看上去大概是这样：客户端说“我有一个改动过的文件，分为这些文件块，它们的 hash 是 `'abcd,deef,efgh'`。服务器响应说“我有前两块，但需要你上传第三块”。然后客户端会把那个文件块上传到块服务器。

```
                +--------------+     +---------------+
                |              |     |               |
                |  元数据服务器  |     |     块服务器    |
                |              |     |               |
                +-+--+---------+     +---------+-----+
                  ^  |                         ^
                  |  | '有, 有, 无'             |
'abcd,deef,efgh'  |  |     +----------+        | efgh: [内容]
                  |  +---> |          |        |
                  |        |   客户端   +--------+
                  +--------+          |
                           +----------+

```

这是问题的背景。下面是 bug。

```
                +--------------+
                |              |
                |    块服务器    |
                |              |
                +-+--+---------+
                  ^  |
                  |  |   '???'
'abcdldeef,efgh'  |  |     +----------+
     ^            |  +---> |          |
     ^            |        |   客户端  +
                  +--------+          |
                           +----------+

```

有时候客户端会提交一个奇怪的请求：每个 hash 值应该包含 16 个字母，但它却发送了 33 个字母——所需数量的两倍加一。服务器不知道该怎么处理它，于是会抛出一个异常。我们收到这个异常的报告，于是去查看客户端的记录文件，然后会看到非常奇怪的事情——客户端的本地数据库损坏了，或者 python 抛出 MemoryError，没有一个合乎情理的。

如果你以前没见过这个问题，可能会觉得毫无头绪。但当你见过一次之后，你以后每次看到都能轻松地认出它来。给你一个提示：在那些 33 个字母的字符串中，`l` 经常会代替逗号出现。其他经常出现的字符是：

```
l \x0c < $ ( . -

```

英文逗号的 ASCII 码是 44。`l` 的 ASCII 码是 108。它们的二进制表示如下：

```
bin(ord(',')): 0101100
bin(ord('l')): 1101100

```

你会注意到 `l` 和逗号只差了一位。问题就出在这里：发生了位反转。桌面客户端使用的内存中的一位发生了错误，于是客户端开始向服务器发送错误的请求。

这是其他经常代替逗号出现的字符的 ASCII 码：

```
,    : 0101100
l    : 1101100
\x0c : 0001100
<    : 0111100
$    : 0100100
(    : 0101000
.    : 0101110
-    : 0101101

```

#### 位反转是真的！

我爱这个 bug 因为它证明了位反转是可能真实发生的事情，而不只是一个理论上的问题。实际上，它在某些情况下会比平时更容易发生。其中一种情况是用户使用的是低配或者老旧的硬件，而运行 Dropbox 的电脑很多都是这样。另外一种会造成很多位反转的地方是外太空——在太空中没有大气层来保护你的内存不受高能粒子和辐射的影响，所以位反转会十分常见。

你大概非常在乎在宇宙中运行的程序的正确性——你的代码或许事关国际空间站中宇航员的性命，但即使没有那么重要，也还要考虑到在宇宙中很难进行软件更新。如果你的确需要让你的程序能够处理位反转，有很多硬件和软件措施可供你选择，Katie Betchold 还关于这个问题做过一个[非常有意思的讲座](http://www.youtube.com/watch?v=ETgNLF_XpEM)。

在刚才那种情况下，Dropbox 并不需要处理位反转。出现内存损坏的是用户的电脑，所以即使我们可以检测到逗号字符的位反转，但如果这发生在其他字符上我们就不一定能检测到了，而且如果从硬盘中读取的文件本身发生了位反转，那我们根本无从得知。我们能改进的地方很少，于是我们决定无视这个异常并继续程序的运行。这种 bug 一般都会在客户端重启之后自动解决。

#### 不常见的 bug 并非不可能发生

这是我最喜欢的 bug 之一，有几个原因。第一，它提醒我注意不常见和不可能之间的区别。当规模足够大的时候，不常见的现象会以值得注意的频率发生。

#### 覆盖面广的 bug

这个 bug 第二个让我喜欢的地方是它覆盖面非常广。每当桌面客户端和服务器交流的时候，这个 bug 都可能悄然出现，而这可能会发生在系统里很多不同的端点和组件当中。这意味着许多不同的 Dropbox 工程师会看到这个 bug 的各种版本。你第一次看到它的时候，你 *真的* 会满头雾水，但在那之后诊断这个 bug 就变得很容易了，而调查过程也非常简短：你只需找到中间的字母，看它是不是个 `l`。

#### 文化差异

这个 bug 的一个有趣的副作用是它展示了服务器组和客户端组之间的文化差异。有时候这个 bug 会被服务器组的成员发现并展开调查。如果你的 *服务器* 上发生了位反转，那应该不是个偶然——这很可能是内存损坏，你需要找到受影响的主机并尽快把它从集群中移除，不然就会有损坏大量用户数据的风险。这是个事故，而你必须迅速做出反应。但如果是用户的电脑在破坏数据，你并没有什么可以做的。

#### 分享你的 bug

如果你在调试一个难搞的 bug，特别是在大型系统中，不要忘记跟别人讨论。也许你的同事以前就遇到过类似的 bug。若是如此，你可能会节省很多时间。就算他们没有见过，也不要忘记在你解决了问题之后告诉他们解决方法——写下来或者在组会中分享。这样下次你们组遇到类似的问题时，你们都会早有准备。

### Bug 如何帮助你进步

#### Recurse Center

在加入 Dropbox 之前，我曾在 Recurse Center 工作。它的理念是建立一个社区让正在自学的程序员们聚到一起来提高能力。这就是 Recurse Center 的全部了：我们没有大纲、作业、截止日期等等。唯一的前提条件是我们都想要成为更好的程序员。参与者中有的人有计算机学位但对自己的实际编程能力不够自信，有的人已经写了十年 Java 但想学 Clojure 或者 Haskell，还有各式各样有着其他的背景的参与者。

我在那里是一位导师，帮助人们更好地利用这个自由的环境，并参考我们从以前的参与者那里学到的东西来提供指导。所以我的同事们和我本人都非常热衷于寻找对成年自学者最有帮助的学习方法。

#### 刻意练习

在学习方法这个领域有很多不同的研究，其中我觉得最有意思的研究之一是刻意练习的概念。刻意练习理论意在解释专业人士和业余爱好者的表现的差距。它的基本思想是如果你只看内在的特征——不论先天与否——它们都无法非常好地解释这种差距。于是研究者们，包括最初的 Ericsson、Krampe 和 Tesch-Romer，开始寻找能够解释这种差距的理论。他们最终的答案是在刻意练习上所花的时间。

他们给刻意练习的定义非常精确：不是为了收入而工作，也不是为了乐趣而玩耍。你必须尽自己能力的极限，去做一个和你的水平相称的任务（不能太简单导致你学不到东西，也不能太难导致你无法取得任何进展）。你还需要获得即时的反馈，知道自己是否做得正确。

这非常令人兴奋，因为这是一套能够用来建立专业技能的系统。但难点在于对于程序员来说这些建议非常难以实施。你很难知道你是否处在自己能力的极限。也很少有即时的反馈帮助你改进——有时候你能得到任何反馈都已经算是很幸运了，还有时候你需要等几个月才能得到反馈。对于在 REPL 中做的简单的事情你可以很快地得到反馈，但如果你在做一个设计上的决定或者技术上的选择，你在很长一段时间里都无法得到反馈。

但是在有一类编程工作中刻意练习是非常有用的，它就是 debug。如果你写了一份代码，那么当时你是理解这份代码是如何工作的。但你的代码有 bug，所以你的理解并不完全正确。根据定义来说，你正处在你理解能力的极限上——这很好！你马上要学到新东西了。如果你可以重现这个 bug，那么这是个宝贵的机会，你可以获得即时的反馈，知道自己的修改是否正确。

像这样的 bug 也许能让你学到关于你的程序的一些小知识，但你也可能会学到一些关于运行你的代码的系统的一些更复杂的知识。我接下来要讲一个关于这种 bug 的故事。

### Bug 2 号

这也是我在 Dropbox 工作时遇到的 bug。当时我正在调查为什么有些桌面客户端没有像我们预期的那样持续发送日志。我开始调查客户端的日志系统并且发现了很多有意思的 bug。我会挑一些跟这个故事有关的 bug 来讲。

和之前一样，这是一个非常简化的系统架构。

```
                                   +--------------+
                                   |              |
               +---+  +----------> |   日志服务器   |
               |日志|  |            |              |
               +---+  |            +------+-------+
                      |                   |
                +-----+----+              |  200 ok
                |          |              |
                |  客户端   |  <-----------+
                |          |
                +-----+----+
                      ^
                      +--------+--------+--------+
                      |        ^        ^        |
                   +--+--+  +--+--+  +--+--+  +--+--+
                   | 日志 |  | 日志 |  | 日志 |  | 日志 |
                   |     |  |     |  |     |  |     |
                   |     |  |     |  |     |  |     |
                   +-----+  +-----+  +-----+  +-----+

```

桌面客户端会生成日志。这些日志会被压缩、加密并写入硬盘。然后客户端会间歇性地把它们发送给服务器。客户端从硬盘读取日志并发送给日志服务器。服务器会将它解码并存储，然后返回 200。

如果客户端无法连接到日志服务器，它不会让日志目录无限地增长。超过一定大小之后，它会开始删除日志来让目录大小不超过一个最大值。

最初的两个 bug 本身并不严重。第一个 bug 是桌面客户端向服务器发送日志时会从最早的日志而不是最新的日志开始。这并不是很好——比如服务器会在客户端报告异常的时候让客户端发送日志，所以你可能最在乎的是刚刚生成的日志而不是在硬盘上的最早的日志。

第二个 bug 和第一个相似：如果日志目录的大小达到了上限，客户端会从最新的日志而不是最早的日志开始删除。同理，你总是会丢失一些日志文件，但你大概更不在乎那些较早的日志。

第三个 bug 和加密有关。有时服务器会无法对一个日志文件解码（我们一般不知道为什么——也许发生了位反转）。我们在后端没有正确地处理这个错误，而服务器会返回 500。客户端看到 500 之后会做合理的反应：它会认为服务器停机了。所以它会停止发送日志文件并且不再尝试发送其他的日志。

对于一个损坏的日志文件返回 500 显然不是正确的行为。你可以考虑返回 400，因为问题出在客户端的请求上。但客户端同样无法修复这个问题——如果日志文件现在无法解码，我们后也永远无法将它解码。客户端正确的做法是直接删除日志文件然后继续运行。实际上，这正是客户端在成功上传日志文件并从服务器收到 200 的响应时的默认行为。所以我们说，好——如果日志文件无法解码，就返回 200。

所有这些 bug 都很容易修复。前两个 bug 出在客户端上，所以我们在 alpha 版本修复了它们，但大部分的客户端还没有获得这些改动。我们在服务器代码中修复了第三个 bug 并部署了新版的服务器。

#### 激增

突然日志服务器集群的流量开始激增。客服团队找到我们并问我们是否知道原因。我花了点时间把所有的部分拼到一起。

在修复之前，这四件事情会发生：

1. 日志文件从最早的开始发送
2. 日志文件从最新的开始删除
3. 如果服务器无法解码日志文件，它会返回 500
4. 如果客户端收到 500，它会停止发送日志

一个存有损坏的日志文件的客户端会试着发送这个文件，服务器会返回 500，客户端会放弃发送日志。在下一次运行时，它会尝试再次发送同样的文件，再次失败，并再次放弃。最终日志目录会被填满，然后客户端会开始删除最新的日志文件，而把损坏的文件继续保留在硬盘上。

这三个 bug 导致的结果是：如果客户端在任何时候生成了损坏的日志文件，我们就再也不会收到那个客户端的日志了。

问题是，处于这种状态的客户端比我们想象的要多很多。任何有一个损坏文件的客户端都会像被关在堤坝里一样，无法再发送日志。现在这个堤坝被清除了，所有这些客户端都开始发送它们的日志目录的剩余内容。

#### 我们的选择

好的，现在文件从世界各地的电脑如洪水般涌来。我们能做什么？（当你在一个有 Dropbox 这种规模，尤其是这种桌面客户端的规模的公司工作时，会遇到这种有趣的事情：你可以非常轻易地对自己造成 DDoS 攻击）。

当你部署的新版本发生问题时，第一个选项是回滚。这是非常合理的选择，但对于这个问题，它无法帮助我们。我们改变的不是服务器的状态而是客户端的——我们删除了那些出错文件。将服务器回滚可以防止更多客户端进入这种状态，但它并不能解决根本问题。

那扩大日志集群的规模呢？我们试过了——然后因为处理能力增加了，我们开始收到更多的请求。我们又扩大了一次，但你不可能一直这么下去。为什么不能？因为这个集群并不是独立的。它会向另一个集群发送请求，在这里是为了处理异常。如果你的一个集群正在被 DDoS，而你持续扩大那个集群，你最终会把它依赖的集群也弄坏，然后你就有两个问题了。

我们考虑过的另一个选择是减低负载——你不需要每一个日志文件，所以我们可以直接无视一些请求。一个难点是我们并没有一个很好的方法来区分好的请求和坏的请求。我们无法快速地判断哪些日志文件是旧的，哪些是新的。

我们最终使用的是一个 Dropbox 里许多不同场合都用过的一个解决方法：我们有一个自定义的头字段，`chillout`，全世界所有的客户端都遵守它。如果客户端收到一个有这个头字段的响应，它将在字段所标注的时间内不再发送任何请求。很早以前一个英明的程序员把它加到了 Dropbox 客户端里，在之后这些年中它已经不止一次地起了作用。

#### 了解你的系统

这个 bug 的第一个教训是要了解你的系统。我对于客户端和服务器之间的交互有不错的理解，但我并没有考虑到当服务器和所有这些客户端同时交互的时候会发生什么。这是一个我没有完全搞懂的层面。

#### 了解你的工具

第二个教训是要了解你的工具。如果出了差错，你有哪些选项？你能撤销你做的迁移吗？你如何知道事情出了差错，你又如何发现更多信息？所有这些事情都应该在危机发生之前就了解好——但如果你没有，你会在危机发生时学到它们并不会再忘记。

#### 功能开关 & 服务器端功能控制

第三个教训是专门针对移动端和桌面应用开发者的：*你需要服务器端功能控制和功能开关*。当你发现一个问题时如果你没有服务器端的功能控制，你可能需要几天或几星期来推送新版本或者提交新版本到应用商店中，然后问题才能得到解决。这是个很糟糕的处境。Dropbox 桌面客户端不需要经过应用商店的审查过程，但光是把一个版本推送给上千万的用户就已经要花很多时间。相比之下，如果你能在新功能遇到问题的时候在服务器上翻转一个开关：十分钟之后你的问题就已经解决了。

这个策略也有它的代价。加入很多的功能开关会大幅提高你的代码的复杂度。而你的测试代码更是会成指数地复杂化：要考虑 A 功能和 B 功能都开启，或者仅开启一个，或者都不开启的情况——然后每个功能都要相乘一遍。让工程师们在事后清理他们的功能开关是一件很难的事情（我自己也有这个毛病）。另外，桌面客户端会同时有好几个版本有人使用，也会加大思考难度。

但是它的好处——啊，当你需要它的时候，你真的是很需要它。

### 如何去爱 bug

我讲了几个我爱的 bug，也讲了为什么要爱 bug。现在我想告诉你如何去爱 bug。如果你现在还不爱 bug，我知道唯一一种改变的方法，那就是要有成长型心态。

社会学家 Carol Dweck 做了很多关于人们如何看待智力的研究。她找到两种不同的看待智力的心态。第一种，她叫做固定型心态，认为智力是一个固定的特征，人类无法改变自己智力的多寡。另一种心态叫做成长型心态。在成长型心态下，人们相信智力是可变的而且可以通过努力来增强。

Dweck 发现一个人看待智力的方式——固定型还是成长型心态——可以很大程度地影响他们选择任务的方式、面对挑战的反应、认知能力、甚至是他们的诚信度。

【我在新西兰 Kiwi Pycon 会议所做的主题演讲中也讨论过成长型心态，所以在此只摘录一部分内容。你可以在[这里](http://akaptur.com/blog/2015/10/10/effective-learning-strategies-for-programmers/)找到完整版的演讲稿】

关于诚信的发现：

>
> 在这之后，他们让学生们给笔友写信讲这个实验，信中说“我们在学校做了这个实验，这是我得的分数”。他们发现 *因智力而受到表扬的学生中几乎一半人谎报了自己的分数* ，而因努力而受表扬的学生则几乎没有人不诚实。
>
>
>

关于努力：

>
> 数个研究发现有着固定型心态的人会不愿真正去努力，因为他们认为这意味着他们不擅长做他们正努力去做的这件事情。Dweck 写道，“如果每当一个任务需要努力的时候你就会怀疑自己的智力，那么你会很难对自己的能力保持自信。”
>
>
>

关于面对困惑：

>
> 他们发现有成长型心态的学生大约能理解 70% 的内容，不论里面是否有难懂的段落。在有固定型心态的学生中，那些被分配没有难懂段落的手册的学生同样可以理解大约 70%。但那些看到了难懂段落的持固定型心态的学生的记忆则降到了 30%。有着固定型心态的学生非常不擅长从困惑中恢复。
>
>
>

这些发现表明成长型心态对 debug 至关重要。我们必须从从困惑中重整旗鼓，诚实地面对我们理解上的不足，并时不时地在寻找答案的路上努力奋斗——成长型心态会让这些都变得更简单而且不那么痛苦。

#### 热爱你的 bug

我在 Recurse Center 工作时会直白地欢迎挑战，我就是这样学会热爱我的 bug 的。有时参与者会坐到我身边说“唉，我觉得我遇到了个奇怪的 Python bug”，然后我会说“太棒了，我 *爱* 奇怪的 Python bug！” 首先，这百分之百是真的，但更重要的是，我这样是在对参与者强调，找到让自己觉得困难的事情是一种成就，而他们做到了这一点，这是件好事。

像我之前说过的，在 Recurse Center 没有截止日期也没有作业，所以这种态度没有任何成本。我会说，“你现在可以花一整天去在 Flask 里找出这个奇怪的 bug 了，多令人兴奋啊！”在 Dropbox 和之后的 Pilot，我们有产品需要发布，有截止日期，还有用户，于是我并不总是对在奇怪的 bug 上花一整天而感到兴奋。所以我对有截止日期的现实也是感同身受。但是如果我有 bug 需要解决，我就必须得去解决它，而抱怨它的存在并不会帮助我之后更快地解决它。我觉得就算在截止日期临近的时候，你也依然可以保持这样的心态。

如果你热爱你的 bug，你可以在解决困难问题时获得更多乐趣。你可以担心得更少而更加专注，并且从中学到更多。最后，你可以和你的朋友和同事分享你的 bug，这将会同时帮助你自己和你的队友们。

### 鸣谢！

在此向给我的演讲提出反馈以及给我的演讲提供其他帮助的人士表示感谢：

* Sasha Laundy
* Amy Hanlon
* Julia Evans
* Julian Cooper
* Raphael Passini Diniz 以及其他的 Python Brasil 组织团队成员

---

via: <http://akaptur.com/blog/2017/11/12/love-your-bugs/>

作者：[Allison Kaptur](http://akaptur.com/about/) 译者：[yixunx](https://github.com/yixunx) 校对：[wxy](https://github.com/wxy)

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


在 Linux 上恢复一个损坏的 USB 设备至初始状态

Summary: 无论是上面提及的什么原因，最终的结果是我们无法继续使用这个设备。所以这里有一个恢复 USB 设备或者是 SD 卡到出厂状态的方法。

![](/data/attachment/album/201801/29/220941qr44tpy4tfffz3yl.jpg)

很多时候我们诸如 SD 卡和 U 盘这样的储存器可能会被损坏，并且因此或其他原因不能继续使用。

这可能是因为使用这个设备创建了一个引导媒体或者是通过错误的平台格式化亦或是创建了一个新的分区在这个设备上。

### 恢复损坏的 USB 设备至初始状态

[![Linux 系统磁盘管理器](/data/attachment/album/201801/29/220948jvujujojubxjkrz3.png)](http://www.linuxandubuntu.com/uploads/2/1/1/5/21152474/edited/usb.png)

**警告：接下来的操作会将你设备上的所有数据格式化。**

无论是上面提及的什么原因，最终的结果是我们无法继续使用这个设备。

所以这里有一个恢复 USB 设备或者是 SD 卡到出厂状态的方法。

大多数时候通过文件浏览器进行一次简单格式化可以解决问题，但是在一些极端情况下，比如文件管理器没有作用，而你又需要你的设备可以继续工作时，你可以使用下面的指导：

我们将会使用一个叫做 `mkusb` 的小工具来实现目标，这个工具的安装非常简单。

添加 mkusb 的仓库：

```
sudo apt add repository ppa:mkusb/ppa

```

现在更新你的包列表：

```
sudo apt-get update

```

安装 `mkusb：

```
sudo apt-get install mkusb

```

现在运行 `mkusb` 你将会看到这个提示，点击 ‘Yes’。

[![运行 mkusb dus](/data/attachment/album/201801/29/220952jnnkdndatzzczkcp.png)](http://www.linuxandubuntu.com/uploads/2/1/1/5/21152474/edited/run-mkusb.png)

现在 `mkusb` 将会最后一次询问你是否希望继续格式化你的数据，‘Stop’是被默认选择的，你现在选择 ‘Go’ 并点击 ‘OK’。

[![Linux mkusb](/data/attachment/album/201801/29/220956p2v0qiimpp5h2sbp.png)](http://www.linuxandubuntu.com/uploads/2/1/1/5/21152474/edited/final-checkpoint_1.png)

窗口将会关闭，此时你的终端看起来是这样的。

[![mkusb usb 控制台](/data/attachment/album/201801/29/221008f4tfb63tlz3itzki.png)](http://www.linuxandubuntu.com/uploads/2/1/1/5/21152474/edited/mkusb.png)

在几秒钟之后，整个过程将会完成，并且你将看到一个这样的弹出窗口。

[![恢复损坏的 USB 设备](/data/attachment/album/201801/29/221013n8022t6s5cx4lqfz.png)](http://www.linuxandubuntu.com/uploads/2/1/1/5/21152474/edited/usb_1.png)

你现在需要把你的设备从系统推出，然后再重新插进去。你的设备将被恢复成为一个普通设备而且还能像原来一样的工作。

[![Linux 磁盘管理器](/data/attachment/album/201801/29/221022v3tg1iwwii1tjpie.png)](http://www.linuxandubuntu.com/uploads/2/1/1/5/21152474/edited/usb_2.png)

我们现在所做的操作本可以通过终端命令或是 gparted 或者其他的软件来完成，但是那将会需要一些关于分区管理的知识。

所以有一个像这样可以自动解决专一问题的小工具总是一个好事。

### 结论

`mkusb` 是一个很容易使用的程序，它可以修复你的 USB 储存设备和 SD 卡。`mkusb` 通过 mkusb 的 PPA 来下载。所有在 `mkusb` 上的操作都需要超级管理员的权限，并且你在这个设备上的所有数据将会被格式化。

一旦操作完成，你将会重置这个设备并让它继续工作。

如果你感到任何疑惑，你可以在下面的评论栏里免费发表。

---

via: <http://www.linuxandubuntu.com/home/restore-corrupted-usb-drive-to-original-state-in-linux>

作者：[LINUXANDUBUNTU](http://www.linuxandubuntu.com) 译者：[Drshu](https://github.com/Drshu) 校对：[wxy](https://github.com/wxy)

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


Linux/Unix 桌面盛典：模仿 “黑客帝国” 界面！

![](/data/attachment/album/201801/29/222415ln4gn4nh4m6kznmw.jpg)

《黑客帝国》是 1999 年，由 Wachowki 兄弟编导的科幻动作片。这部电影的荧屏里有无尽的绿色字符降落。数字雨模拟着《黑客帝国》中的虚拟现实活动。现在，Linux 和 Unix 终端上，你也可以通过 CMatrix 模仿出矩阵数字雨。

### 安装 cmatrix

根据你的 Linux/Unix 发行版或操作系统安装并且设置 CMatrix。

#### 如何在 Debian/Ubuntu Linux 发行版中安装 cmatrix

在 Debian/Ubuntu/Mint 系统中键入以下命令 [apt-get 命令](https://www.cyberciti.biz/tips/linux-debian-package-management-cheat-sheet.html "See Linux/Unix apt-get command examples for more info")/[apt 命令](https://www.cyberciti.biz/faq/ubuntu-lts-debian-linux-apt-command-examples/ "See Linux/Unix apt command examples for more info")：

```
$ sudo apt install cmatrix

```

示例输出：

```
[sudo] password for vivek:
Reading package lists... Done
Building dependency tree
Reading state information... Done
Suggested packages:
  cmatrix-xfont
The following NEW packages will be installed:
  cmatrix
0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded.
Need to get 15.8 kB of archives.
After this operation, 50.2 kB of additional disk space will be used.
Get:1 http://in.archive.ubuntu.com/ubuntu artful/universe amd64 cmatrix amd64 1.2a-5build2 [15.8 kB]
Fetched 15.8 kB in 0s (19.7 kB/s)
Selecting previously unselected package cmatrix.
(Reading database ... 205388 files and directories currently installed.)
Preparing to unpack .../cmatrix_1.2a-5build2_amd64.deb ...
Unpacking cmatrix (1.2a-5build2) ...
Setting up cmatrix (1.2a-5build2) ...
Processing triggers for man-db (2.7.6.1-2) ...

```

#### 如何在 Arch Linux 发行版安装 cmatrix

键入 pacman 命令：

```
$ sudo pacman -S cmatrix

```

#### 如何在 FreeBCD 系统中安装 cmatrix

运行如下命令安装 port：

```
# cd /usr/ports/misc/cmatrix/ && make install clean

```

或者使用 pkg 命令添加二进制包：

```
# pkg install cmatrix

```

#### 如何在 macOS Unix 发行版中安装 cmatrix

键入下列命令：

```
$ brew install cmatrix

```

#### 如何在 OpenBSD 系统中安装 cmatrix

键入 pkg\_add 命令：

```
# pkg_add cmatrix

```

### 使用 cmatrix

简单键入命令：

```
$ cmatrix

```

[![cmtarix 运转中](/data/attachment/album/201801/29/222426mrmtjayfitmfiffi.gif)](https://www.cyberciti.biz/media/new/cms/2018/01/small-cmtarix-file.gif)

#### 使用键盘

在执行期间，下列按键有效（`-s` 模式下，按键无效）：

| 按键 | 说明 |
| --- | --- |
| `a` | 切换异步滚动 |
| `b` | 随机字符加粗 |
| `B` | 全部字符加粗 |
| `n` | 关闭字符加粗 |
| `0`-`9` | 调整更新时间 |
| `!` `@` `#` `$` `%` `^` `&` `)` | 改变对应的矩阵颜色: `!` – 红、`@` – 绿、`#` – 黄、`$` – 蓝、`%` – 洋红、`^` – 青、 `&` – 白、 `)` – 黑。 |
| `q` | 退出程序 |

你可以通过以下命令获取 cmatrix 选项：

```
$ cmatrix -h

```

* `-a`： 异步滚动
* `-b`： 开启字符加粗
* `-B`： 所有字符加粗（优先于 -b 选项）
* `-f`： 强制开启 Linux $TERM 模式
* `-l`： Linux 模式（使用 matrix 控制台字体）
* `-o`： 启用旧式滚动
* `-h`： 输出使用说明并退出
* `-n`： 关闭字符加粗 （优先于 -b and -B，默认）
* `-s`： “屏保”模式， 第一次按键时退出
* `-x`： X 窗口模式，如果你使用的时 mtx.pcf 终端
* `-V`： 输出版本信息并且退出
* `-u delay` （0 - 10，默认 4）： 屏幕更新延时
* `-C [color]`： 调整 matrix 颜色（默认绿色）

现在，你拥有了一款最炫酷的终端应用！

---

via: <https://www.cyberciti.biz/open-source/command-line-hacks/matrix-digital-rain-on-linux-macos-unix-terminal/>

作者：[nixCraft](https://www.cyberciti.biz) 译者：[CYLeft](https://github.com/CYLeft) 校对：[校对者ID](https://github.com/%E6%A0%A1%E5%AF%B9%E8%80%85ID)

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


如何在使用 scp 命令时递归地排除文件

![](/data/attachment/album/201801/29/224214p1179wdr9laeriwg.jpg)

Q：我需要将所有包含 \*.c 文件的文件夹从名为 hostA 的本地笔记本复制到 hostB。我使用的是下面的 `scp` 命令，但不知道如何排除特定的文件（如 \*.out）：

```
$ scp -r ~/projects/ user@hostB:/home/delta/projects/

```

如何告诉 `scp` 命令在 Linux/Unix 命令行中排除特定的文件或目录？

人们可以使用 `scp` 命令在网络主机之间安全地复制文件。它使用 ssh 进行数据传输和身份验证。典型的语法是：

```
scp file1 user@host:/path/to/dest/
scp -r /path/to/source/ user@host:/path/to/dest/

```

### scp 排除文件

我不认为你可以在使用 scp 命令时过滤或排除文件。但是，有一个很好的解决方法来排除文件并使用 ssh 安全地复制它。本页面说明如何在使用 `scp` 递归复制目录时过滤或排除文件。

### 如何使用 rsync 命令排除文件

语法是：

```
rsync av -e ssh --exclude='*.out' /path/to/source/ user@hostB:/path/to/dest/

```

这里：

1. `-a` ：递归到目录，即复制所有文件和子目录。另外，打开归档模式和所有其他选项（相当于 `-rlptgoD`）
2. `-v` ：详细输出
3. `-e ssh` ：使用 ssh 作为远程 shell，这样所有的东西都被加密
4. `--exclude='*.out'` ：排除匹配模式的文件，例如 \*.out 或 \*.c 等。

### rsync 命令的例子

在这个例子中，从 `~/virt/` 目录递归地复制所有文件，但排除所有 \*.new 文件：

```
$ rsync -av -e ssh --exclude='*.new' ~/virt/ root@centos7:/tmp

```

示例输出：

[![Scp exclude files but using rsync exclude command](/data/attachment/album/201801/29/224228pk4edf2dzclkh9hf.jpg)](https://www.cyberciti.biz/media/new/faq/2017/12/scp-exclude-files-on-linux-unix-macos-bash-shell-command-line.jpg)

如果远程服务器上找不到 `rsync`，那么 `rsync` 命令将失败。在这种情况下，请尝试使用以下 `scp` 命令，该命令在当前目录中使用 [bash shell 模式匹配](https://www.gnu.org/software/bash/manual/html_node/Pattern-Matching.html#Pattern-Matching) （它不能与 `-r` 选项一起使用）：

```
$ ls

```

示例输出：

```
centos71.log centos71.qcow2 centos71.qcow2.new centos71.v2.qcow2.new meta-data user-data

```

复制除 .new 之外的当前目录中的所有内容：

```
$ shopt -s extglob
$ scp !(*.new) root@centos7:/tmp/

```

示例输出：

```
centos71.log 100 % 4262 1.3MB/s 00:00
centos71.qcow2 100 % 836MB 32.7MB/s 00: 25
meta-data 100 % 47 18.5KB/s 00:00
user-data 100 % 1543 569.7KB/s 00:00

```

有关更多信息，请参阅以下手册页：

```
$ man rsync
$ man bash
$ man scp

```

---

via: <https://www.cyberciti.biz/faq/scp-exclude-files-when-using-command-recursively-on-unix-linux/>

作者：[Vivek Gite](https://www.cyberciti.biz) 译者：[geekpi](https://github.com/geekpi) 校对：[wxy](https://github.com/wxy)

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


迁移到 Linux：图形操作环境

![](/data/attachment/album/201801/29/233159rij9anj6hhiih0ri.jpg)

>
> 这篇文章对 Linux 图形环境做了一番介绍，展示了在不同的 Linux 发行版上的各种选择。
>
>
>

这是我们迁移到 Linux 系统系列的第三篇文章。如果你错过了先前的两篇，这里有两文的链接《[入门介绍](/article-9212-1.html)》 和 《[磁盘、文件、和文件系统](/article-9213-1.html)》。本文中，我们将讨论图形操作环境。在 Linux 系统中，你可以依照喜好选择并且定制一个图形界面，你有很大的选择余地，这也是 Linux 优越的体验之一。

一些主流的 Linux 图形界面包括：Cinnamon、Gnome、KDE Plasma、Xfce 和 MATE，总之这里有很多选择。

有一点经常混淆 Linux 新手，虽然某个 Linux 系统分配了一个缺省的图形环境，但是一般你可以随时更换这个图形界面。这和 Windows 或 Mac OS 的惯用者的定势思维不同。安装图形环境是一件独立的事情，很多时候，Linux 和其图形环境的连接并不紧密。此外，你在一个图形环境构建运行的程序同样适用于另一个图形环境。比如说一个为 KDE Plasma 图形环境编写的应用程序完全适用于 Gnome 桌面图形环境。

由于人们熟悉 Windows 和 MacOS 系统，部分 Linux 操作系统的图形环境在一定程度上尝试着去模仿它们，但另一些 Linux 图形界面则是独特的。

下面，我将就一些不同的 Linux 发行版，展示几个 Linux 图形环境。如果你不确定应该采用那个 Linux 发行版，那我建议你从 [Ubuntu](https://www.evernote.com/OutboundRedirect.action?dest=https%3A%2F%2Fwww.ubuntu.com%2Fdownload%2Fdesktop) 开始，获取其长期支持（LTS）的版本（Ubuntu 16.04.3 LTS 正在开发）。Ubuntu 稳定且真的非常好用。

### 由 Mac 过渡

Elementary OS 发行版提供了和 Mac 系统风格很接近的界面。它的默认图形环境被称作 Pantheon，是一款很适合 Mac 用户过渡使用的图形环境。这款图形界面发行版的屏幕底部有一个停靠栏，专为极简者使用而设计。为了保持简约的风格，很多默认的应用程序甚至都不会有自己的菜单。相反，它们的按钮和控件在应用程序的标题栏上（图 1）。

![Elementary OS](/data/attachment/album/201801/29/233200wv5joc7g4tvtpb4v.png "Elementary OS")

*图 1： Elementary OS Pantheon.*

Ubuntu 发行版提供的一个默认的图形界面，也和 Mac 相似。Ubuntu 17.04 或者更老的版本都使用 Unity 图形环境，Unity 停靠栏的默认位置在屏幕的左边，屏幕顶部有一个全局应用程序共享的菜单栏。

### 由 Windows 过渡

ChaletOS 亦步亦趋模仿 Windows 界面，可以帮助 Windows 用户轻松的过渡到 Linux。ChaletOS 使用的图形环境是 Xfce（图 2）。在屏幕的左下角有一个开始（主）菜单和搜索栏。屏幕的右下角是一个桌面图标和一些通知信息。这看起来和 Windows 非常像，乍一看，可能都会以为桌面跑的是 Windows。

![ChaletOS](/data/attachment/album/201801/29/233202k11pjqyygx6dmhgs.png)

*图 2： ChaletOS with Xfce.*

Zorin OS 发行版同样尝试模仿 Windows。 Zorin OS 使用的 Gnome 的改进桌面，工作起来和 Windows 的图形界面很相似。左下角的开始按钮、右下角的通知栏和信息通知栏。开始按钮会弹出一个和 Windows 无异的应用程序列表和搜索框。

### 独有的图形环境

Gnome 桌面（图 3）是最常用的图形环境之一。许多发行版将 Gnome 作为默认的图形环境。Gnome 并不打算模仿 Windows 或是 MacOS，而是以其自身的优雅和易用为目标。

![](/data/attachment/album/201801/29/233205g5k8rpxaha138ttx.png)

*图 3：openSUSE with Gnome.*

Gnome 桌面环境从版本 2 到 版本 3 发生了巨变，Cinnamon 环境为消除该改变带来的不利影响而创造。尽管 Cinnamon 和前辈 Gnome 2 外观不相似，但是它依旧尝试提供一个简约的界面，而且它的功能和 Windows XP 类似。

MATE 图形环境直接模仿于 Gnome 2，在它的屏幕顶部有一个用作设置和存放应用的菜单栏，底部提供了一个应用程序运行选项卡和一些其他组件。

KDE plasma 围绕组件界面而构建，组件可以安装在桌面或是面板上（图 4）。

![KDE Plasma](/data/attachment/album/201801/29/233208p59qikss9s22ei65.png "KDE Plasma")

*图 4: 安装了 KDE Plasma 的 Kubuntu 操作系统。*

没有那个图形环境比另外一个更好。不同的风格适用不同的用户风格。另外，如果选择太多无从下手，那就从 [Ubuntu](https://www.evernote.com/OutboundRedirect.action?dest=https%3A%2F%2Fwww.ubuntu.com%2Fdownload%2Fdesktop) 开始吧。

### 相似与不同

不同的操作系统处理方式不同，这会给使用者的过渡带来挑战。比如说，菜单栏可能出现在不同的位置，然后设置有可能用不同的选项入口路径。我列举了一些相似或不同地方来帮助减少 Linux 调整。

#### 鼠标

Linux 的鼠标通常和 Windows 与 MacOS 的工作方式有所差异。在 Windows 或 Mac，双击标签，你几乎可以打开任何事物，而这在 Linux 图形界面中很多都被设置为单击。

此外在 Windows 系统中，你通常通过单击窗口获取焦点。在 Linux，很多窗口的焦点获取方式被设置为鼠标悬停，即便鼠标悬停下的窗口并不在屏幕顶端。这种微妙的差异有时候会让人很吃惊。比如说，在 Windows 中，假如有一个后台应用（不在屏幕顶层），你移动鼠标到它的上面，不点击鼠标仅仅转动鼠标滚轮，顶层窗口会滚动。而在 Linux 中，后台窗口（鼠标悬停的那个窗口）会滚动。

#### 菜单

应用菜单是电脑程序的一个主要集中位置，最近似乎可以调整移动菜单栏到不碍事的地方，甚至干脆完全删除。大概，当你迁移到 Linux，你可能找不到你期待的菜单。应用程序菜单会像 MacOS一样出现在全局共享菜单栏内。和很多移动应用程序一样，该菜单可能在“更多选项”的图标里。或者，这个菜单干脆被完全移除被一个按钮取代，正如在 Elementary OS Pantheon 环境里的一些程序一样。

#### 工作空间

很多 Linux 图形环境提供了多个工作空间。一个工作空间包含的正在运行的程序窗口充盈了整个屏幕。切换到不同的工作空间将会改变程序的可见性。这个概念是把当前项目运行使用的全部应用程序分组到一个工作空间，而一些为另一个项目使用的应用程序会被分组到不同的工作空间。

不是每一个人都需要甚至是喜欢工作空间，但是我提到它是因为，作为一个新手，你可能无意间通过一个组合键切换了工作空间，然后，“喂！我的应用程序哪去了?” 如果你看到的还是你熟悉的桌面壁纸，那你可能只是切换了工作空间，你所有的应用程序还在一个工作空间运行，只是现在不可见而已。在很多 Linux 环境中，通过敲击 `Alt+Ctrl` 和一个箭头（上、下、左或右）可以切换工作空间。很有可能发现你的应用程序一直都在另一个工作空间里运行。

当然，如果你刚好喜欢工作空间（很多人都喜欢），然后你就发现了一个 Linux 很有用的默认功能。

#### 设置

许多 Linux 图形环境提供一些类型的设置程序或是面板让你在机器上配置设置。值得注意的是类似 Windows 和 MacOS，Linux 可以配置好很多细节，但不是所有的详细设置都可以在设置程序上找到。但是这些设置项已经足够满足大部分典型的桌面系统，比如选择桌面壁纸，改变熄屏时间，连接打印机等其他一些设置。

和 Windows 或者 MacOS 相比，Linux 的应用程序设置的分组或是命名都有不同的方式。甚至同是 Linux 系统，不同的图形界面也会出现不同的设置，这可能需要时间适应。当然，在你的图形环境中设置配置的问题可以通过在线查询这样不错的方法解决。

#### 应用程序

最后，Linux 的应用程序也可能不同。你可能会发现一些熟悉的应用程序，但是对你来说更多的将会是崭新的应用。比如说，你能在 Linux 上找到 Firefox、Chrome 和 Skype。如果不能找到特定的应用程序，通常你能使用一些替代程序。如果还是不能，那你可以使用 WINE 这样的兼容层来运行 Windows 的应用程序。

在很多 Linux 图形环境中，你可以通过敲击 Windows 的标志键来打开应用程序菜单栏。在其他一些情况中，你不得不点击开始（主）按钮或应用程序菜单。很多图形环境中，你可以通过分类搜索到应用程序而不一定需要它的特定程序名。比如说，你要使用一个你不清楚名字的编辑器程序，这时候，你可以在应用程序菜单栏键的搜索框中键入“editor”字样，它将为你展示一个甚至更多的被认为是编辑器类的应用程序。

为帮你起步，这里列举了一点可能成为 Linux 系统使用的替代程序。

![](/data/attachment/album/201801/29/233211licpwzsy5pcqtwxw.png)

请注意，Linux 提供了大量的满足你需求的选择，这张表里列举的一点也不完整。

---

via: <https://www.linux.com/blog/learn/2017/12/migrating-linux-graphical-environments>

作者：[John Bonesio](https://www.linux.com/users/johnbonesio) 译者：[CYLeft](https://github.com/CYLeft) 校对：[wxy](https://github.com/wxy)

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


Python 版的 Nmon 分析器：让你远离 excel 宏

Summary: nmon 输出的文件很难直接由电子表格应用来处理，因此诞生了 Nmon_Analyzer excel 宏。这个过程很死板而且有点麻烦。现在出现了一个更灵活的工具，我向你们介绍一下 pyNmonAnalyzer。

![pyNmonAnalyzer Graph output](/data/attachment/album/201801/30/121232ke7q2v7f44cj2e3c.png "pyNmonAnalyzer Graph output")

[Nigel's monitor](http://nmon.sourceforge.net/)，也叫做 “Nmon”，是一个很好的监控、记录和分析 Linux/\*nix 系统性能随时间变化的工具。Nmon 最初由 IBM 开发并于 2009 年夏天开源。时至今日 Nmon 已经在所有 Linux 平台和架构上都可用了。它提供了很棒的当前系统统计信息的基于命令行的实时可视化报告，这些统计信息包括 CPU、RAM、网络和磁盘 I/O。然而，Nmon 最棒的特性是可以随着时间的推移记录系统性能快照。

比如：`nmon -f -s 1`。

![nmon CPU and Disk utilization](/data/attachment/album/201801/30/121232vf9yzxc5tco5spai.png)

会创建一个日志文件，该日志文件最开头是一些系统的元数据（AAA - BBBV 部分），后面是所监控的系统属性的定时快照，比如 CPU 和内存的使用情况。这个输出的文件很难直接由电子表格应用来处理，因此诞生了 [Nmon\_Analyzer](http://www.ibm.com/developerworks/wikis/display/WikiPtype/nmonanalyser) excel 宏。如果你用的是 Windows/Mac 并安装了 Microsoft Office，那么这个工具非常不错。如果没有这个环境那也可以使用 Nmon2rrd 工具，这个工具能将日志文件转换 RRD 输入文件，进而生成图形。这个过程很死板而且有点麻烦。现在出现了一个更灵活的工具，我向你们介绍一下 pyNmonAnalyzer，它提供了一个可定制化的解决方案来生成结构化的 CSV 文件和带有用 [matplotlib](http://matplotlib.org/) 生成的图片的简单 HTML 报告。

### 入门介绍

系统需求：

从名字中就能看出我们需要有 python。此外 pyNmonAnalyzer 还依赖于 matplotlib 和 numpy。若你使用的是 debian 衍生的系统，则你需要先安装这些包：

```
$ sudo apt-get install python-numpy python-matplotlib

```

#### 获取 pyNmonAnalyzer：

你可以克隆 git 仓库：

```
$ git clone git@github.com:madmaze/pyNmonAnalyzer.git

```

或者，直接从这里下载：[pyNmonAnalyzer-1.0.zip](https://github.com/madmaze/pyNmonAnalyzer/blob/master/release/pyNmonAnalyzer-1.0.zip) 。(LCTT 译注：这是个 5 年前的项目但是一直在陆陆续续的进行维护）

接下来我们需要一个 Nmon 文件，如果没有的话，可以使用发行版中提供的实例或者自己录制一个样本：`nmon -F test.nmon -s 1 -c 120`，会录制 120 个快照，每秒一个，存储到 test.nmon 文件中。

让我们来看看基本的帮助信息：

```
$ ./pyNmonAnalyzer.py -h
usage: pyNmonAnalyzer.py [-h] [-x] [-d] [-o OUTDIR] [-c] [-b] [-r CONFFNAME]
 input_file

nmonParser converts Nmon monitor files into time-sorted
CSV/Spreadsheets for easier analysis, without the use of the
MS Excel Macro. Also included is an option to build an HTML
report with graphs, which is configured through report.config.

positional arguments:
 input_file Input NMON file

optional arguments:
 -h, --help show this help message and exit
 -x, --overwrite overwrite existing results (Default: False)
 -d, --debug debug? (Default: False)
 -o OUTDIR, --output OUTDIR
 Output dir for CSV (Default: ./data/)
 -c, --csv CSV output? (Default: False)
 -b, --buildReport report output? (Default: False)
 -r CONFFNAME, --reportConfig CONFFNAME
 Report config file, if none exists: we will write the
 default config file out (Default: ./report.config)

```

该工具有两个主要的选项

1. 将 nmon 文件传唤成一系列独立的 CSV 文件
2. 使用 matplotlib 生成带图形的 HTML 报告

下面命令既会生成 CSV 文件，也会生成 HTML 报告：

```
$ ./pyNmonAnalyzer.py -c -b test.nmon

```

这会创建一个 `./data` 目录，其中有一个存放 CSV 文件的目录 (`./data/csv/`)，一个存放 PNG 图片的目录 (`./data/img/`) 以及一个 HTML 报告 (`./data/report.html`)。

默认情况下，HTML 报告中会用图片展示 CPU、磁盘繁忙程度、内存使用情况和网络传输情况。所有这些都定义在一个不言自明的配置文件中 (`report.config`)。目前这个工具还不是特别的灵活，因为 CPU 和 MEM 除了 `on` 和 `off` 外，无法做其他的配置。不过下一步将会改进作图的方法并允许用户灵活地指定针对哪些数据使用哪种作图方法。

目前这些报告还十分的枯燥而且只能打印出基本的几种标记图表，不过它的功能还在不断的完善中。目前在开发的是一个向导来让配置调整变得更容易。如果有任何建议，找到任何 bug 或者有任何功能需求，欢迎与我交流。

---

via: <https://matthiaslee.com/python-nmon-analyzer-moving-away-from-excel-macros/>

作者：[Matthias Lee](https://matthiaslee.com/) 译者：[lujun9972](https://github.com/lujun9972) 校对：[wxy](https://github.com/wxy)

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


精通 Linux 上的文件搜索

Summary: 有很多有用的命令可以搜索文件，find 命令可能是其中最有名的，但它不是唯一的命令，也不一定总是找到目标文件的最快方法。

![](/data/attachment/album/201801/30/223143sx9k09hxykph69ky.jpg)

在 Linux 系统上搜索文件的方法有很多，有的命令很简单，有的很详细。我们的目标是：缩小搜索范围，找到您正在寻找的文件，又不受其他文件的干扰。在今天的文章中，我们将研究一些对文件搜索最有用的命令和选项。我们将涉及：

* 快速搜索
* 更复杂的搜索条件
* 组合条件
* 反转条件
* 简单和详细的回应
* 寻找重复的文件

有很多有用的命令可以搜索文件，`find` 命令可能是其中最有名的，但它不是唯一的命令，也不一定总是找到目标文件的最快方法。

### 快速搜索命令：which 和 locate

搜索文件的最简单的命令可能就是 `which` 和 `locate` 了，但二者都有一些局限性。`which` 命令只会在系统定义的搜索路径中，查找可执行的文件，通常用于识别命令。如果您对输入 `which` 时会运行哪个命令感到好奇，您可以使用命令 `which which`，它会指出对应的可执行文件。

```
$ which which
/usr/bin/which

```

`which` 命令会显示它找到的第一个以相应名称命名的可执行文件（也就是使用该命令时将运行的那个文件），然后停止。

`locate` 命令更大方一点，它可以查找任意数量的文件，但它也有一个限制：仅当文件名被包含在由 `updatedb` 命令构建的数据库时才有效。该文件可能会存储在某个位置，如 `/var/lib/mlocate/mlocate.db`，但不能用 `locate` 以外的任何命令读取。这个文件的更新通常是通过每天通过 cron 运行的 `updatedb` 进行的。

简单的 `find` 命令没有太多限制，不过它需要指定搜索的起点和搜索条件。最简单的 `find` 命令：按文件名搜索文件。如下所示：

```
$ find . -name runme
./bin/runme

```

如上所示，通过文件名搜索文件系统的当前位置将会搜索所有子目录，除非您指定了搜索深度。

### 不仅仅是文件名

`find` 命令允许您搜索除文件名以外的多种条件，包括文件所有者、组、权限、大小、修改时间、缺少所有者或组，和文件类型等。除了查找文件外，您还可以删除文件、对其进行重命名、更改所有者、更改权限和对找到的文件运行几乎任何命令。

下面两条命令会查找：在当前目录中 root 用户拥有的文件，以及不被指定用户（在本例中为 shs）所拥有的文件。在这个例子中，两个输出是一样的，但并不总是如此。

```
$ find . -user root -ls
 396926 0 lrwxrwxrwx 1 root root 21 Sep 21 09:03 ./xyz -> /home/peanut/xyz
$ find . ! -user shs -ls
 396926 0 lrwxrwxrwx 1 root root 21 Sep 21 09:03 ./xyz -> /home/peanut/xyz

```

感叹号 `!` 字符代表“非”：反转跟随其后的条件。

下面的命令将查找具有特定权限的文件：

```
$ find . -perm 750 -ls
 397176 4 -rwxr-x--- 1 shs shs 115 Sep 14 13:52 ./ll
 398209 4 -rwxr-x--- 1 shs shs 117 Sep 21 08:55 ./get-updates
 397145 4 drwxr-x--- 2 shs shs 4096 Sep 14 15:42 ./newdir

```

接下来的命令显示具有 777 权限的非符号链接文件：

```
$ sudo find /home -perm 777 ! -type l -ls
 397132 4 -rwxrwxrwx 1 shs shs 18 Sep 15 16:06 /home/shs/bin/runme
 396949 4 -rwxrwxrwx 1 root root 558 Sep 21 11:21 /home/oops

```

以下命令将查找大小超过千兆字节的文件。请注意，我们找到了一个非常有趣的文件。它以 ELF core 文件格式表示了该系统的物理内存。

```
$ sudo find / -size +1G -ls
 4026531994 0 -r-------- 1 root root 140737477881856 Sep 21 11:23 /proc/kcore
 1444722 15332 -rw-rw-r-- 1 shs shs 1609039872 Sep 13 15:55 /home/shs/Downloads/ubuntu-17.04-desktop-amd64.iso

```

只要您知道 `find` 命令是如何描述文件类型的，就可以通过文件类型来查找文件。

```
b = 块设备文件
c = 字符设备文件
d = 目录
p = 命名管道
f = 常规文件
l = 符号链接
s = 套接字
D = 门（仅限 Solaris）

```

在下面的命令中，我们要寻找符号链接和套接字：

```
$ find . -type l -ls
 396926 0 lrwxrwxrwx 1 root root 21 Sep 21 09:03 ./whatever -> /home/peanut/whatever
$ find . -type s -ls
 395256 0 srwxrwxr-x 1 shs shs 0 Sep 21 08:50 ./.gnupg/S.gpg-agent

```

您还可以根据 inode 号来搜索文件：

```
$ find . -inum 397132 -ls
 397132 4 -rwx------ 1 shs shs 18 Sep 15 16:06 ./bin/runme

```

另一种通过 inode 搜索文件的方法是使用 `debugfs` 命令。在大的文件系统上，这个命令可能比 `find` 快得多，您可能需要安装 icheck。

```
$ sudo debugfs -R 'ncheck 397132' /dev/sda1
debugfs 1.42.13 (17-May-2015)
Inode Pathname
397132 /home/shs/bin/runme

```

在下面的命令中，我们从主目录（`~`）开始，限制搜索的深度（即我们将搜索子目录的层数），并只查看在最近一天内创建或修改的文件（`mtime` 设置）。

```
$ find ~ -maxdepth 2 -mtime -1 -ls
 407928 4 drwxr-xr-x 21 shs shs 4096 Sep 21 12:03 /home/shs
 394006 8 -rw------- 1 shs shs 5909 Sep 21 08:18 /home/shs/.bash_history
 399612 4 -rw------- 1 shs shs 53 Sep 21 08:50 /home/shs/.Xauthority
 399615 4 drwxr-xr-x 2 shs shs 4096 Sep 21 09:32 /home/shs/Downloads

```

### 不仅仅是列出文件

使用 `-exec` 选项，在您使用 `find` 命令找到文件后可以以某种方式更改文件。您只需参照 `-exec` 选项即可运行相应的命令。

```
$ find . -name runme -exec chmod 700 {} \;
$ find . -name runme -ls
 397132 4 -rwx------ 1 shs shs 18 Sep 15 16:06 ./bin/runme

```

在这条命令中，`{}` 代表文件名。此命令将更改当前目录和子目录中任何名为 `runme` 的文件的权限。

把您想运行的任何命令放在 `-exec` 选项之后，并使用类似于上面命令的语法即可。

### 其他搜索条件

如上面的例子所示，您还可以通过其他条件进行搜索：文件的修改时间、所有者、权限等。以下是一些示例。

#### 根据用户查找文件

```
$ sudo find /home -user peanut
/home/peanut
/home/peanut/.bashrc
/home/peanut/.bash_logout
/home/peanut/.profile
/home/peanut/examples.desktop

```

#### 根据权限查找文件

```
$ sudo find /home -perm 777
/home/shs/whatever
/home/oops

```

#### 根据修改时间查找文件

```
$ sudo find /home -mtime +100
/home/shs/.mozilla/firefox/krsw3giq.default/gmp-gmpopenh264/1.6/gmpopenh264.info
/home/shs/.mozilla/firefox/krsw3giq.default/gmp-gmpopenh264/1.6/libgmpopenh264.so

```

#### 通过比较修改时间查找文件

像这样的命令可以让您找到修改时间较近的文件。

```
$ sudo find /var/log -newer /var/log/syslog
/var/log/auth.log

```

### 寻找重复的文件

如果您正在清理磁盘空间，则可能需要删除较大的重复文件。确定文件是否真正重复的最好方法是使用 `fdupes` 命令。此命令使用 md5 校验和来确定文件是否具有相同的内容。使用 `-r`（递归）选项，`fdupes` 将在一个目录下并查找具有相同校验和而被确定为内容相同的文件。

如果以 root 身份运行这样的命令，您可能会发现很多重复的文件，但是很多文件都是创建时被添加到主目录的启动文件。

```
# fdupes -rn /home > /tmp/dups.txt
# more /tmp/dups.txt
/home/jdoe/.profile
/home/tsmith/.profile
/home/peanut/.profile
/home/rocket/.profile

/home/jdoe/.bashrc
/home/tsmith/.bashrc
/home/peanut/.bashrc
/home/rocket/.bashrc

```

同样，您可能会在 `/usr` 中发现很多重复的但不该删除的配置文件。所以，请谨慎利用 `fdupes` 的输出。

`fdupes` 命令并不总是很快，但是要记住，它正在对许多文件运行校验和来做比较，你可能会意识到它是多么有效。

### 总结

有很多方法可以在 Linux 系统上查找文件。如果您可以描述清楚您正在寻找什么，上面的命令将帮助您找到目标。

---

via: <https://www.networkworld.com/article/3227075/linux/mastering-file-searches-on-linux.html>

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

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


从 ISO 和在线仓库创建一个 Yum 仓库

![](/data/attachment/album/201801/30/224540dlqk8tn1sf8lgrgp.jpg)

Yum 是 Centos/RHEL/Fedora 中最重要的工具之一。尽管在 Fedora 的最新版本中，它已经被 DNF 所取代，但这并不意味着它自生自灭了。它仍然被广泛用于安装 rpm 包，我们已经在前面的教程（[**在这里阅读**](http://linuxtechlab.com/using-yum-command-examples/)）中用示例讨论了 Yum。

在本教程中，我们将学习创建一个本地 Yum 仓库，首先使用系统的 ISO 镜像，然后创建一个在线 Yum 仓库的镜像。

### 用 DVD ISO 创建 Yum

我们在本教程中使用 Centos 7 dvd，同样的过程也应该可以用在 RHEL 7 上。

首先在根文件夹中创建一个名为 Yum 的目录

```
$ mkdir /YUM

```

然后挂载 Centos 7 ISO：

```
$ mount -t iso9660 -o loop /home/dan/Centos-7-x86_x64-DVD.iso /mnt/iso/

```

接下来，从挂载的 ISO 中复制软件包到 `/YUM` 中。当所有的软件包都被复制到系统中后，我们将安装创建 Yum 所需的软件包。打开 `/YUM` 并安装以下 RPM 包：

```
$ rpm -ivh deltarpm
$ rpm -ivh python-deltarpm
$ rpm -ivh createrepo

```

安装完成后，我们将在 `/etc/yum.repos.d` 中创建一个名 为 `local.repo` 的文件，其中包含所有的 Yum 信息。

```
$ vi /etc/yum.repos.d/local.repo

```

```
LOCAL REPO]
Name=Local YUM
baseurl=file:///YUM
gpgcheck=0
enabled=1

```

保存并退出文件。接下来，我们将通过运行以下命令来创建仓库数据。

```
$ createrepo -v /YUM

```

创建仓库数据需要一些时间。一切完成后，请运行：

```
$ yum clean all

```

清理缓存，然后运行：

```
$ yum repolist

```

检查所有仓库列表。你应该在列表中看到 `local.repo`。

### 使用在线仓库创建镜像 Yum 仓库

创建在线 Yum 的过程与使用 ISO 镜像创建 Yum 类似，只是我们将从在线仓库而不是 ISO 中获取 rpm 软件包。

首先，我们需要找到一个在线仓库来获取最新的软件包。建议你找一个离你位置最近的在线 Yum 仓库，以优化下载速度。我们将使用下面的镜像，你可以从 [CENTOS 镜像列表](http://mirror.centos.org/centos/)中选择一个离你最近的镜像。

选择镜像之后，我们将使用 `rsync` 将该镜像与我们的系统同步，但在此之前，请确保你服务器上有足够的空间。

```
$ rsync -avz rsync://mirror.fibergrid.in/centos/7.2/os/x86_64/Packages/s/ /YUM

```

同步将需要相当长一段时间（也许一个小时），这取决于你互联网的速度。同步完成后，我们将更新我们的仓库数据。

```
$ createrepo - v /YUM

```

我们的 Yum 已经可以使用了。我们可以创建一个 cron 任务来根据你的需求每天或每周定时地自动更新仓库数据。

要创建一个用于同步仓库的 cron 任务，请运行：

```
$ crontab -e

```

并添加以下行

```
30 12 * * * rsync -avz http://mirror.centos.org/centos/7/os/x86_64/Packages/ /YUM

```

这会在每晚 12:30 同步 Yum。还请记住在 `/etc/yum.repos.d` 中创建仓库配置文件，就像我们上面所做的一样。

就是这样，你现在使用你自己的 Yum 仓库了。如果你喜欢它，请分享这篇文章，并在下面的评论栏留下你的意见/疑问。

---

via: <http://linuxtechlab.com/creating-yum-repository-iso-online-repo/>

作者：[Shusain](http://linuxtechlab.com/author/shsuain/) 译者：[geekpi](https://github.com/geekpi) 校对：[wxy](https://github.com/wxy)

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


用命令行查看比特币等加密货币的价格

Summary: Coinmon 会在终端上检查加密货币的价格。它将从 coinmarketcap.com API 获取所有详细信息。对于那些 加密货币投资者和工程师来说是非常有用的。

![配图](/data/attachment/album/201801/30/231433vbz3szbb77hybasa.jpg)

前段时间，我们发布了一个关于 [Cli-Fyi](https://www.ostechnix.com/cli-fyi-quick-easy-way-fetch-information-ips-emails-domains-lots/) 的指南 - 一个可能有用的命令行查询工具。使用 Cli-Fyi，我们可以很容易地了解加密货币的最新价格和许多其他有用的细节。今天，我们将看到另一个名为 “Coinmon” 的加密货币价格查看工具。不像 Cli.Fyi，Coinmon 只能用来查看不同加密货币的价格。没有其他功能！Coinmon 会在终端上检查加密货币的价格。它将从 [coinmarketcap.com](https://coinmarketcap.com/) API 获取所有详细信息。对于那些 **加密货币投资者**和**工程师**来说是非常有用的。

### 安装 Coinmon

确保你的系统上安装了 Node.js 和 Npm。如果你的机器上没有安装 Node.js 和/或 npm，请参考以下链接进行安装。

安装完 Node.js 和 Npm 后，从终端运行以下命令安装 Coinmon。

```
sudo npm install -g coinmon

```

### 从命令行查看加密货币价格

运行以下命令查看市值排名的前 10 位的加密货币：

```
coinmon

```

示例输出：

![](/data/attachment/album/201801/30/231433tb7rj2g232h52h07.png)

如我所说，如果你不带任何参数运行 Coinmon，它将显示前 10 位加密货币。你还可以使用 `-t` 标志查看最高的 n 位加密货币，例如 20。

```
coinmon -t 20

```

所有价格默认以美元显示。你还可以使用 `-c` 标志将价格从美元转换为另一种货币。

例如，要将价格转换为 INR（印度卢比），运行：

```
coinmon -c inr

```

![](/data/attachment/album/201801/30/231433wup1k1rvx8r1k5rt.png)

目前，Coinmon 支持 AUD、BRL、CAD、CHF、CLP、CNY、CZK、DKK、EUR、GBP、HKD、HUF、IDR、ILS、INR、JPY、KRW、MXN、MYR、NOK、NZD、PHP、PKR、PLN、RUB、SEK、SGD、THB、TRY、TWD、ZAR 这些货币。

也可以使用加密货币的符号来搜索价格。

```
coinmon -f btc

```

这里，`btc` 是比特币的符号。你可以在[**这里**](https://en.wikipedia.org/wiki/List_of_cryptocurrencies)查看所有可用的加密货币的符号。

有关更多详情，请参阅 coinmon 的帮助部分：

```
$ coinmon -h

Usage: coinmon [options]

Options:

 -V, --version output the version number
 -c, --convert [currency] Convert to your fiat currency (default: usd)
 -f, --find [symbol] Find specific coin data with coin symbol (can be a comma seperated list) (default: )
 -t, --top [index] Show the top coins ranked from 1 - [index] according to the market cap (default: null)
 -H, --humanize [enable] Show market cap as a humanized number, default true (default: true)
 -h, --help output usage information

```

希望这个有帮助。会有更好的东西。敬请关注！

干杯!

---

via: <https://www.ostechnix.com/coinmon-check-cryptocurrency-prices-commandline/>

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

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


什么是 .bashrc，为什么要编辑 .bashrc？

Summary: 你的 home 目录下藏着很多隐藏文件。如果你在运行 macOS 或者主流的 Linux 发行版的话，你就会在靠近隐藏文件列表的上方看见一个名为 .bashrc 的文件。那么什么是 .bashrc，编辑 .bashrc 又有什么用呢？

![](/data/attachment/album/201801/31/145506vz6pxrtzqoxtmgou.png)

你的 home 目录下藏着很多隐藏文件。如果你在运行 macOS 或者主流的 Linux 发行版的话，你就会在靠近隐藏文件列表的上方看见一个名为 `.bashrc` 的文件。那么什么是 `.bashrc`，编辑 `.bashrc` 又有什么用呢？

![finder-find-bashrc](/data/attachment/album/201801/31/145506am14t1jmx4tjzq17.png "finder-find-bashrc")

如果你运行一个基于 Unix 或者类 Unix 的操作系统，bash 很有可能是作为默认终端被安装的。虽然存在很多[不同的 shell](https://www.maketecheasier.com/alternative-linux-shells/)，bash 却是最常见或许也是最主流的。如果你不明白那意味着什么，bash 是一个能解释你输入进终端程序的东西，并且基于你的输入来运行命令。它在一定程度上支持使用脚本来定制功能，这时候就要用到 `.bashrc` 了。

为了加载你的配置，bash 在每次启动时都会加载 `.bashrc` 文件的内容。每个用户的 home 目录都有这个 shell 脚本。它用来存储并加载你的终端配置和环境变量。

终端配置可以包含很多不同的东西。最常见的，`.bashrc` 文件包含用户想要用的别名。别名允许用户通过更短的名字或替代的名字来指向命令，对于经常在终端下工作的人来说这可是一个省时利器。

![terminal-edit-bashrc-1](/data/attachment/album/201801/31/145507bxspgcpiizi4nnng.png "terminal-edit-bashrc-1")

你可以在任何终端文本编辑器上编辑 `.bashrc`。在接下来的例子中我们将使用 `nano`。

要使用 `nano` 来编辑 `.bashrc`，在终端中调用以下命令：

```
nano ~/.bashrc

```

如果你之前从没有编辑过 `.bashrc` 的话，你也许会发现它是空的。这没关系！如果不是的话，你可以随意在任一行添加你的配置。

你对 bashrc 所做的任何修改将在下一次启动终端时生效。如果你想立刻生效的话，运行下面的命令：

```
source ~/.bashrc

```

你可以添加到任何 `.bashrc` 的位置，随意使用命令（通过 `#`）来组织你的代码。

编辑 `.bashrc` 需要遵循 [bash 脚本格式](http://tldp.org/HOWTO/Bash-Prog-Intro-HOWTO.html)。如果你不知道如何用 bash 编写脚本的话，有很多在线资料可供查阅。这是一本相当全面的[介绍指南](https://www.digitalocean.com/community/tutorials/an-introduction-to-useful-bash-aliases-and-functions)，包含一些我们没能在这里提及的 bashrc 的方面。

**相关**： [如何在 Linux 启动时以 root 权限运行 bash 脚本](https://www.maketecheasier.com/run-bash-script-as-root-during-startup-linux/ "How to Run Bash Script as Root During Startup on Linux")

有一些有用的小技巧能使你的终端体验将更高效，也更用户友好。

### 为什么我要编辑 bashrc ？

#### Bash 提示符

bash 提示符允许你自定义你的终端，并让它在你运行命令时显示提示。自定义的 bash 提示符着实能提高你在终端的工作效率。

看看这些即[有用](https://www.maketecheasier.com/8-useful-and-interesting-bash-prompts/)又[有趣](https://www.maketecheasier.com/more-useful-and-interesting-bash-prompts/)的 bash 提示符，你可以把它们添加到你的 `.bashrc` 里。

#### 别名

![terminal-edit-bashrc-3](/data/attachment/album/201801/31/145509t7n1tnnqwnnn6tnn.png "terminal-edit-bashrc-3")

别名允许你使用简写的代码来执行你想要的某种格式的某个命令。让我们用 `ls` 命令来举个例子吧。`ls` 命令默认显示你目录里的内容。这挺有用的，不过显示目录的更多信息，或者显示目录下的隐藏内容，往往更加有用。因此，有个常见的别名就是 `ll`，用来运行 `ls -lha` 或者其他类似的命令。这样就能显示文件的大部分信息，找出隐藏的文件，并能以“能被人类阅读”的单位显示文件大小，而不是用“块”作为单位。

你需要按照下面这样的格式书写别名：

```
alias ll = "ls -lha"

```

左边输入你想设置的别名，右边引号里是要执行的命令。你可以用这种方法来创建命令的短版本，防止出现常见的拼写错误，或者让一个命令总是带上你想要的参数来运行。你也可以用你喜欢的缩写来规避讨厌或容易忘记的语法。这是一些[常见的别名的用法](https://www.maketecheasier.com/install-software-in-various-linux-distros/#aliases)，你可以添加到你的 `.bashrc` 里。

#### 函数

![terminal-edit-bashrc-2](/data/attachment/album/201801/31/145509hbz59nzan249fs95.png "terminal-edit-bashrc-2")

除了缩短命令名，你也可以用 bash 函数组合多个命令到一个操作。这些命令可以很复杂，但是它们大多遵循这种语法：

```
function_name () {
 command_1
 command_2
}

```

下面的命令组合了 `mkdir` 和 `cd` 命令。输入 `md folder_name` 可以在你的工作目录创建一个名为“folder\_name”的目录并立刻导航进入。

```
md () {
  mkdir -p $1
  cd $1
}

```

如你所见，函数中的 `$1` 代表第一个参数，就是你在函数名后紧跟着输入的文本。

### 总结

不像某些自定义终端的方法，变动 bashrc 是非常直接且低风险的。即使你一不小心全搞砸了，你也可以随时删掉 bashrc 文件然后重新来一遍。试试看吧，你会惊叹于你提高的生产力的。

---

via: <https://www.maketecheasier.com/what-is-bashrc/>

作者：[Alexander Fox](https://www.maketecheasier.com/author/alexfox/) 译者：[heart4lor](https://github.com/heart4lor) 校对：[wxy](https://github.com/wxy)

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


如何在 Linux 上用 Fail2Ban 保护服务器免受暴力攻击

![](/data/attachment/album/201801/31/151825ej2k38zwwqwhrmkw.jpg)

Linux 管理员的一个重要任务是保护服务器免受非法攻击或访问。 默认情况下，Linux 系统带有配置良好的防火墙，比如iptables、Uncomplicated Firewall（UFW），ConfigServer Security Firewall（CSF）等，可以防止多种攻击。

任何连接到互联网的机器都是恶意攻击的潜在目标。 有一个名为 Fail2Ban 的工具可用来缓解服务器上的非法访问。

### 什么是 Fail2Ban？

[Fail2Ban](https://github.com/fail2ban/fail2ban) 是一款入侵防御软件，可以保护服务器免受暴力攻击。 它是用 Python 编程语言编写的。 Fail2Ban 基于auth 日志文件工作，默认情况下它会扫描所有 auth 日志文件，如 `/var/log/auth.log`、`/var/log/apache/access.log` 等，并禁止带有恶意标志的IP，比如密码失败太多，寻找漏洞等等标志。

通常，Fail2Ban 用于更新防火墙规则，用于在指定的时间内拒绝 IP 地址。 它也会发送邮件通知。 Fail2Ban 为各种服务提供了许多过滤器，如 ssh、apache、nginx、squid、named、mysql、nagios 等。

Fail2Ban 能够降低错误认证尝试的速度，但是它不能消除弱认证带来的风险。 这只是服务器防止暴力攻击的安全手段之一。

### 如何在 Linux 中安装 Fail2Ban

Fail2Ban 已经与大部分 Linux 发行版打包在一起了，所以只需使用你的发行包版的包管理器来安装它。

对于 Debian / Ubuntu，使用 [APT-GET 命令](https://www.2daygeek.com/apt-get-apt-cache-command-examples-manage-packages-debian-ubuntu-systems/)或 [APT 命令](https://www.2daygeek.com/apt-command-examples-manage-packages-debian-ubuntu-systems/)安装。

```
$ sudo apt install fail2ban

```

对于 Fedora，使用 [DNF 命令](https://www.2daygeek.com/dnf-command-examples-manage-packages-fedora-system/)安装。

```
$ sudo dnf install fail2ban

```

对于 CentOS/RHEL，启用 [EPEL 库](https://www.2daygeek.com/install-enable-epel-repository-on-rhel-centos-scientific-linux-oracle-linux/)或 [RPMForge](https://www.2daygeek.com/install-enable-repoforge-rpmforge-repository-on-rhel-centos-sl/) 库，使用 [YUM 命令](https://www.2daygeek.com/yum-command-examples-manage-packages-rhel-centos-systems/)安装。

```
$ sudo yum install fail2ban

```

对于 Arch Linux，使用 [Pacman 命令](https://www.2daygeek.com/pacman-command-examples-manage-packages-arch-linux-system/)安装。

```
$ sudo pacman -S fail2ban

```

对于 openSUSE , 使用 [Zypper命令](https://www.2daygeek.com/zypper-command-examples-manage-packages-opensuse-system/)安装。

```
$ sudo zypper in fail2ban

```

### 如何配置 Fail2Ban

默认情况下，Fail2Ban 将所有配置文件保存在 `/etc/fail2ban/` 目录中。 主配置文件是 `jail.conf`，它包含一组预定义的过滤器。 所以，不要编辑该文件，这是不可取的，因为只要有新的更新，配置就会重置为默认值。

只需在同一目录下创建一个名为 `jail.local` 的新配置文件，并根据您的意愿进行修改。

```
# cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local

```

默认情况下，大多数选项都已经配置的很完美了，如果要启用对任何特定 IP 的访问，则可以将 IP 地址添加到 `ignoreip` 区域，对于多个 IP 的情况，用空格隔开 IP 地址。

配置文件中的 `DEFAULT` 部分包含 Fail2Ban 遵循的基本规则集，您可以根据自己的意愿调整任何参数。

```
# nano /etc/fail2ban/jail.local

[DEFAULT]
ignoreip = 127.0.0.1/8 192.168.1.100/24
bantime = 600
findtime = 600
maxretry = 3
destemail = 2daygeek@gmail.com

```

* `ignoreip`：本部分允许我们列出 IP 地址列表，Fail2Ban 不会禁止与列表中的地址匹配的主机
* `bantime`：主机被禁止的秒数
* `findtime`：如果在最近 `findtime` 秒期间已经发生了 `maxretry` 次重试，则主机会被禁止
* `maxretry`：是主机被禁止之前的失败次数

### 如何配置服务

Fail2Ban 带有一组预定义的过滤器，用于各种服务，如 ssh、apache、nginx、squid、named、mysql、nagios 等。 我们不希望对配置文件进行任何更改，只需在服务区域中添加 `enabled = true` 这一行就可以启用任何服务。 禁用服务时将 `true` 改为 `false` 即可。

```
# SSH servers
[sshd]
enabled = true
port = ssh
logpath = %(sshd_log)s
backend = %(sshd_backend)s

```

* `enabled`： 确定服务是打开还是关闭。
* `port`：指明特定的服务。 如果使用默认端口，则服务名称可以放在这里。 如果使用非传统端口，则应该是端口号。
* `logpath`：提供服务日志的位置
* `backend`：指定用于获取文件修改的后端。

### 重启 Fail2Ban

进行更改后，重新启动 Fail2Ban 才能生效。

```
[For SysVinit Systems]
# service fail2ban restart

[For systemd Systems]
# systemctl restart fail2ban.service

```

### 验证 Fail2Ban iptables 规则

你可以使用下面的命令来确认是否在防火墙中成功添加了Fail2Ban iptables 规则。

```
# iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
f2b-apache-auth tcp -- anywhere anywhere multiport dports http,https
f2b-sshd tcp -- anywhere anywhere multiport dports 1234
ACCEPT tcp -- anywhere anywhere tcp dpt:1234

Chain FORWARD (policy ACCEPT)
target prot opt source destination

Chain OUTPUT (policy ACCEPT)
target prot opt source destination

Chain f2b-apache-auth (1 references)
target prot opt source destination
RETURN all -- anywhere anywhere

Chain f2b-sshd (1 references)
target prot opt source destination
RETURN all -- anywhere anywhere

```

### 如何测试 Fail2Ban

我做了一些失败的尝试来测试这个。 为了证实这一点，我要验证 `/var/log/fail2ban.log` 文件。

```
2017-11-05 14:43:22,901 fail2ban.server [7141]: INFO Changed logging target to /var/log/fail2ban.log for Fail2ban v0.9.6
2017-11-05 14:43:22,987 fail2ban.database [7141]: INFO Connected to fail2ban persistent database '/var/lib/fail2ban/fail2ban.sqlite3'
2017-11-05 14:43:22,996 fail2ban.database [7141]: WARNING New database created. Version '2'
2017-11-05 14:43:22,998 fail2ban.jail [7141]: INFO Creating new jail 'sshd'
2017-11-05 14:43:23,002 fail2ban.jail [7141]: INFO Jail 'sshd' uses poller {}
2017-11-05 14:43:23,019 fail2ban.jail [7141]: INFO Initiated 'polling' backend
2017-11-05 14:43:23,019 fail2ban.filter [7141]: INFO Set maxRetry = 5
2017-11-05 14:43:23,020 fail2ban.filter [7141]: INFO Set jail log file encoding to UTF-8
2017-11-05 14:43:23,020 fail2ban.filter [7141]: INFO Added logfile = /var/log/auth.log
2017-11-05 14:43:23,021 fail2ban.actions [7141]: INFO Set banTime = 600
2017-11-05 14:43:23,021 fail2ban.filter [7141]: INFO Set findtime = 600
2017-11-05 14:43:23,022 fail2ban.filter [7141]: INFO Set maxlines = 10
2017-11-05 14:43:23,070 fail2ban.server [7141]: INFO Jail sshd is not a JournalFilter instance
2017-11-05 14:43:23,081 fail2ban.jail [7141]: INFO Jail 'sshd' started
2017-11-05 14:43:23,763 fail2ban.filter [7141]: INFO [sshd] Found 103.5.134.167
2017-11-05 14:43:23,763 fail2ban.filter [7141]: INFO [sshd] Found 103.5.134.167
2017-11-05 14:43:23,764 fail2ban.filter [7141]: INFO [sshd] Found 181.129.54.170
2017-11-05 14:43:23,764 fail2ban.filter [7141]: INFO [sshd] Found 181.129.54.170
2017-11-05 14:43:23,765 fail2ban.filter [7141]: INFO [sshd] Found 181.129.54.170
2017-11-05 14:43:23,765 fail2ban.filter [7141]: INFO [sshd] Found 181.129.54.170
2017-11-05 15:19:06,192 fail2ban.server [7141]: INFO Stopping all jails
2017-11-05 15:19:06,874 fail2ban.jail [7141]: INFO Jail 'sshd' stopped
2017-11-05 15:19:06,879 fail2ban.server [7141]: INFO Exiting Fail2ban
2017-11-05 15:19:07,123 fail2ban.server [8528]: INFO Changed logging target to /var/log/fail2ban.log for Fail2ban v0.9.6
2017-11-05 15:19:07,123 fail2ban.database [8528]: INFO Connected to fail2ban persistent database '/var/lib/fail2ban/fail2ban.sqlite3'
2017-11-05 15:19:07,126 fail2ban.jail [8528]: INFO Creating new jail 'sshd'
2017-11-05 15:19:07,129 fail2ban.jail [8528]: INFO Jail 'sshd' uses poller {}
2017-11-05 15:19:07,141 fail2ban.jail [8528]: INFO Initiated 'polling' backend
2017-11-05 15:19:07,142 fail2ban.actions [8528]: INFO Set banTime = 60
2017-11-05 15:19:07,142 fail2ban.filter [8528]: INFO Set findtime = 60
2017-11-05 15:19:07,142 fail2ban.filter [8528]: INFO Set jail log file encoding to UTF-8
2017-11-05 15:19:07,143 fail2ban.filter [8528]: INFO Set maxRetry = 3
2017-11-05 15:19:07,144 fail2ban.filter [8528]: INFO Added logfile = /var/log/auth.log
2017-11-05 15:19:07,144 fail2ban.filter [8528]: INFO Set maxlines = 10
2017-11-05 15:19:07,189 fail2ban.server [8528]: INFO Jail sshd is not a JournalFilter instance
2017-11-05 15:19:07,195 fail2ban.jail [8528]: INFO Jail 'sshd' started
2017-11-05 15:20:03,263 fail2ban.filter [8528]: INFO [sshd] Found 103.5.134.167
2017-11-05 15:20:05,267 fail2ban.filter [8528]: INFO [sshd] Found 103.5.134.167
2017-11-05 15:20:12,276 fail2ban.filter [8528]: INFO [sshd] Found 103.5.134.167
2017-11-05 15:20:12,380 fail2ban.actions [8528]: NOTICE [sshd] Ban 103.5.134.167
2017-11-05 15:21:12,659 fail2ban.actions [8528]: NOTICE [sshd] Unban 103.5.134.167

```

要查看启用的监狱列表，请运行以下命令。

```
# fail2ban-client status
Status
|- Number of jail:  2
`- Jail list:   apache-auth, sshd

```

通过运行以下命令来获取禁止的 IP 地址。

```
# fail2ban-client status ssh
Status for the jail: ssh
|- filter
| |- File list: /var/log/auth.log
| |- Currently failed: 1
| `- Total failed: 3
`- action
 |- Currently banned: 1
 | `- IP list: 192.168.1.115
 `- Total banned: 1

```

要从 Fail2Ban 中删除禁止的 IP 地址，请运行以下命令。

```
# fail2ban-client set ssh unbanip 192.168.1.115

```

---

via: <https://www.2daygeek.com/how-to-install-setup-configure-fail2ban-on-linux/>

作者：[Magesh Maruthamuthu](https://www.2daygeek.com/author/magesh/) 译者：[Flowsnow](https://github.com/Flowsnow) 校对：[wxy](https://github.com/wxy)

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