如何在 Linux 中找出内存消耗最大的进程

# 如何在 Linux 中找出内存消耗最大的进程

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

很多次，你可能遇见过系统消耗了过多的内存。如果是这种情况，那么最好的办法是识别出 Linux 机器上消耗过多内存的进程。我相信，你可能已经运行了下文中的命令以进行检查。如果没有，那你尝试过哪些其他的命令？我希望你可以在评论中更新这篇文章，它可能会帮助其他用户。

使用 [top 命令](https://www.2daygeek.com/linux-top-command-linux-system-performance-monitoring-tool/) 和 [ps 命令](https://www.2daygeek.com/linux-ps-command-find-running-process-monitoring/) 可以轻松的识别这种情况。我过去经常同时使用这两个命令，两个命令得到的结果是相同的。所以我建议你从中选择一个喜欢的使用就可以。

### 1) 如何使用 ps 命令在 Linux 中查找内存消耗最大的进程

`ps` 命令用于报告当前进程的快照。`ps` 命令的意思是“进程状态”。这是一个标准的 Linux 应用程序，用于查找有关在 Linux 系统上运行进程的信息。

它用于列出当前正在运行的进程及其进程 ID（PID）、进程所有者名称、进程优先级（PR）以及正在运行的命令的绝对路径等。

下面的 `ps` 命令格式为你提供有关内存消耗最大进程的更多信息。

```
# ps aux --sort -rss | head

USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
mysql     1064  3.2  5.4 886076 209988 ?       Ssl  Oct25  62:40 /usr/sbin/mysqld
varnish  23396  0.0  2.9 286492 115616 ?       SLl  Oct25   0:42 /usr/sbin/varnishd -P /var/run/varnish.pid -f /etc/varnish/default.vcl -a :82 -T 127.0.0.1:6082 -S /etc/varnish/secret -s malloc,256M
named     1105  0.0  2.7 311712 108204 ?       Ssl  Oct25   0:16 /usr/sbin/named -u named -c /etc/named.conf
nobody   23377  0.2  2.3 153096 89432 ?        S    Oct25   4:35 nginx: worker process
nobody   23376  0.1  2.1 147096 83316 ?        S    Oct25   2:18 nginx: worker process
root     23375  0.0  1.7 131028 66764 ?        Ss   Oct25   0:01 nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf
nobody   23378  0.0  1.6 130988 64592 ?        S    Oct25   0:00 nginx: cache manager process
root      1135  0.0  0.9  86708 37572 ?        S    05:37   0:20 cwpsrv: worker process
root      1133  0.0  0.9  86708 37544 ?        S    05:37   0:05 cwpsrv: worker process
```

使用以下 `ps` 命令格式可在输出中仅展示有关内存消耗过程的特定信息。

```
# ps -eo pid,ppid,%mem,%cpu,cmd --sort=-%mem | head

  PID  PPID %MEM %CPU CMD
 1064     1  5.4  3.2 /usr/sbin/mysqld
23396 23386  2.9  0.0 /usr/sbin/varnishd -P /var/run/varnish.pid -f /etc/varnish/default.vcl -a :82 -T 127.0.0.1:6082 -S /etc/varnish/secret -s malloc,256M
 1105     1  2.7  0.0 /usr/sbin/named -u named -c /etc/named.conf
23377 23375  2.3  0.2 nginx: worker process
23376 23375  2.1  0.1 nginx: worker process
 3625   977  1.9  0.0 /usr/local/bin/php-cgi /home/daygeekc/public_html/index.php
23375     1  1.7  0.0 nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf
23378 23375  1.6  0.0 nginx: cache manager process
 1135  3034  0.9  0.0 cwpsrv: worker process
```

如果你只想查看命令名称而不是命令的绝对路径，请使用下面的 `ps` 命令格式。

```
# ps -eo pid,ppid,%mem,%cpu,comm --sort=-%mem | head

  PID  PPID %MEM %CPU COMMAND
 1064     1  5.4  3.2 mysqld
23396 23386  2.9  0.0 cache-main
 1105     1  2.7  0.0 named
23377 23375  2.3  0.2 nginx
23376 23375  2.1  0.1 nginx
23375     1  1.7  0.0 nginx
23378 23375  1.6  0.0 nginx
 1135  3034  0.9  0.0 cwpsrv
 1133  3034  0.9  0.0 cwpsrv
```

### 2) 如何使用 top 命令在 Linux 中查找内存消耗最大的进程

Linux 的 `top` 命令是用来监视 Linux 系统性能的最好和最知名的命令。它在交互界面上显示运行的系统进程的实时视图。但是，如果要查找内存消耗最大的进程，请 [在批处理模式下使用 top 命令](/article-11491-1.html)。

你应该正确地 [了解 top 命令输出](https://www.2daygeek.com/understanding-linux-top-command-output-usage/) 以解决系统中的性能问题。

```
# top -c -b -o +%MEM | head -n 20 | tail -15

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND
 1064 mysql     20   0  886076 209740   8388 S   0.0  5.4  62:41.20 /usr/sbin/mysqld
23396 varnish   20   0  286492 115616  83572 S   0.0  3.0   0:42.24 /usr/sbin/varnishd -P /var/run/varnish.pid -f /etc/varnish/default.vcl -a :82 -T 127.0.0.1:6082 -S /etc/varnish/secret -s malloc,256M
 1105 named     20   0  311712 108204   2424 S   0.0  2.8   0:16.41 /usr/sbin/named -u named -c /etc/named.conf
23377 nobody    20   0  153240  89432   2432 S   0.0  2.3   4:35.74 nginx: worker process
23376 nobody    20   0  147096  83316   2416 S   0.0  2.1   2:18.09 nginx: worker process
23375 root      20   0  131028  66764   1616 S   0.0  1.7   0:01.07 nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf
23378 nobody    20   0  130988  64592    592 S   0.0  1.7   0:00.51 nginx: cache manager process
 1135 root      20   0   86708  37572   2252 S   0.0  1.0   0:20.18 cwpsrv: worker process
 1133 root      20   0   86708  37544   2212 S   0.0  1.0   0:05.94 cwpsrv: worker process
 3034 root      20   0   86704  36740   1452 S   0.0  0.9   0:00.09 cwpsrv: master process /usr/local/cwpsrv/bin/cwpsrv
 1067 nobody    20   0 1356200  31588   2352 S   0.0  0.8   0:56.06 /usr/local/apache/bin/httpd -k start
  977 nobody    20   0 1356088  31268   2372 S   0.0  0.8   0:30.44 /usr/local/apache/bin/httpd -k start
  968 nobody    20   0 1356216  30544   2348 S   0.0  0.8   0:19.95 /usr/local/apache/bin/httpd -k start
```

如果你只想查看命令名称而不是命令的绝对路径，请使用下面的 `top` 命令格式。

```
# top -b -o +%MEM | head -n 20 | tail -15

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND
 1064 mysql     20   0  886076 210340   8388 S   6.7  5.4  62:40.93 mysqld
23396 varnish   20   0  286492 115616  83572 S   0.0  3.0   0:42.24 cache-main
 1105 named     20   0  311712 108204   2424 S   0.0  2.8   0:16.41 named
23377 nobody    20   0  153240  89432   2432 S  13.3  2.3   4:35.74 nginx
23376 nobody    20   0  147096  83316   2416 S   0.0  2.1   2:18.09 nginx
23375 root      20   0  131028  66764   1616 S   0.0  1.7   0:01.07 nginx
23378 nobody    20   0  130988  64592    592 S   0.0  1.7   0:00.51 nginx
 1135 root      20   0   86708  37572   2252 S   0.0  1.0   0:20.18 cwpsrv
 1133 root      20   0   86708  37544   2212 S   0.0  1.0   0:05.94 cwpsrv
 3034 root      20   0   86704  36740   1452 S   0.0  0.9   0:00.09 cwpsrv
 1067 nobody    20   0 1356200  31588   2352 S   0.0  0.8   0:56.04 httpd
  977 nobody    20   0 1356088  31268   2372 S   0.0  0.8   0:30.44 httpd
  968 nobody    20   0 1356216  30544   2348 S   0.0  0.8   0:19.95 httpd
```

### 3) 奖励技巧：如何使用 ps\_mem 命令在 Linux 中查找内存消耗最大的进程

[ps\_mem 程序](https://www.2daygeek.com/ps_mem-report-core-memory-usage-accurately-in-linux/) 用于显示每个程序（而不是每个进程）使用的核心内存。该程序允许你检查每个程序使用了多少内存。它根据程序计算私有和共享内存的数量，并以最合适的方式返回已使用的总内存。

它使用以下逻辑来计算内存使用量。总内存使用量 = sum(用于程序进程的专用内存使用量) + sum(用于程序进程的共享内存使用量)。

```
# ps_mem

 Private  +   Shared  =  RAM used    Program
128.0 KiB +  27.5 KiB = 155.5 KiB    agetty
228.0 KiB +  47.0 KiB = 275.0 KiB    atd
284.0 KiB +  53.0 KiB = 337.0 KiB    irqbalance
380.0 KiB +  81.5 KiB = 461.5 KiB    dovecot
364.0 KiB + 121.5 KiB = 485.5 KiB    log
520.0 KiB +  65.5 KiB = 585.5 KiB    auditd
556.0 KiB +  60.5 KiB = 616.5 KiB    systemd-udevd
732.0 KiB +  48.0 KiB = 780.0 KiB    crond
296.0 KiB + 524.0 KiB = 820.0 KiB    avahi-daemon (2)
772.0 KiB +  51.5 KiB = 823.5 KiB    systemd-logind
940.0 KiB + 162.5 KiB =   1.1 MiB    dbus-daemon
  1.1 MiB +  99.0 KiB =   1.2 MiB    pure-ftpd
  1.2 MiB + 100.5 KiB =   1.3 MiB    master
  1.3 MiB + 198.5 KiB =   1.5 MiB    pickup
  1.3 MiB + 198.5 KiB =   1.5 MiB    bounce
  1.3 MiB + 198.5 KiB =   1.5 MiB    pipe
  1.3 MiB + 207.5 KiB =   1.5 MiB    qmgr
  1.4 MiB + 198.5 KiB =   1.6 MiB    cleanup
  1.3 MiB + 299.5 KiB =   1.6 MiB    trivial-rewrite
  1.5 MiB + 145.0 KiB =   1.6 MiB    config
  1.4 MiB + 291.5 KiB =   1.6 MiB    tlsmgr
  1.4 MiB + 308.5 KiB =   1.7 MiB    local
  1.4 MiB + 323.0 KiB =   1.8 MiB    anvil (2)
  1.3 MiB + 559.0 KiB =   1.9 MiB    systemd-journald
  1.8 MiB + 240.5 KiB =   2.1 MiB    proxymap
  1.9 MiB + 322.5 KiB =   2.2 MiB    auth
  2.4 MiB +  88.5 KiB =   2.5 MiB    systemd
  2.8 MiB + 458.5 KiB =   3.2 MiB    smtpd
  2.9 MiB + 892.0 KiB =   3.8 MiB    bash (2)
  3.3 MiB + 555.5 KiB =   3.8 MiB    NetworkManager
  4.1 MiB + 233.5 KiB =   4.3 MiB    varnishd
  4.0 MiB + 662.0 KiB =   4.7 MiB    dhclient (2)
  4.3 MiB + 623.5 KiB =   4.9 MiB    rsyslogd
  3.6 MiB +   1.8 MiB =   5.5 MiB    sshd (3)
  5.6 MiB + 431.0 KiB =   6.0 MiB    polkitd
 13.0 MiB + 546.5 KiB =  13.6 MiB    tuned
 22.5 MiB +  76.0 KiB =  22.6 MiB    lfd - sleeping
 30.0 MiB +   6.2 MiB =  36.2 MiB    php-fpm (6)
  5.7 MiB +  33.5 MiB =  39.2 MiB    cwpsrv (3)
 20.1 MiB +  25.3 MiB =  45.4 MiB    httpd (5)
104.7 MiB + 156.0 KiB = 104.9 MiB    named
112.2 MiB + 479.5 KiB = 112.7 MiB    cache-main
 69.4 MiB +  58.6 MiB = 128.0 MiB    nginx (4)
203.4 MiB + 309.5 KiB = 203.7 MiB    mysqld
---------------------------------
                        775.8 MiB
=================================
```

---

via: <https://www.2daygeek.com/linux-find-top-memory-consuming-processes/>

作者：[Magesh Maruthamuthu](https://www.2daygeek.com/author/magesh/) 选题：[lujun9972](https://github.com/lujun9972) 译者：[lnrCoder](https://github.com/lnrCoder) 校对：[wxy](https://github.com/wxy)

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


awk 入门 —— 强大的文本分析工具

Summary: 让我们开始使用它。

awk '$3&gt;5 {print $1, $2}' colours.txt

应该为

awk '$3 gt 5 {print $1, $2}'  colours.txt

谢谢！

ZHAPING

来自湖南常德的 Internet Explorer 11.0|Windows 7 用户

# awk 入门 —— 强大的文本分析工具

>
> 让我们开始使用它。
>
>
>

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

`awk` 是用于 Unix 和类 Unix 系统的强大文本解析工具，但是由于它有可编程函数，因此你可以用它来执行常规解析任务，因此它也被视为一种编程语言。你可能不会使用 `awk` 开发下一个 GUI 应用，并且它可能不会代替你的默认脚本语言，但是它是用于特定任务的强大程序。

这些任务或许是惊人的多样化。了解 `awk` 可以解决你的哪些问题的最好方法是学习 `awk`。你会惊讶于 `awk` 如何帮助你完成更多工作，却花费更少的精力。

`awk` 的基本语法是：

```
awk [options] 'pattern {action}' file
```

首先，创建此示例文件并将其保存为 `colours.txt`。

```
name       color  amount
apple      red    4
banana     yellow 6
strawberry red    3
grape      purple 10
apple      green  8
plum       purple 2
kiwi       brown  4
potato     brown  9
pineapple  yellow 5
```

数据被一个或多个空格分隔为列。以某种方式组织要分析的数据是很常见的。它不一定总是由空格分隔的列，甚至可以不是逗号或分号，但尤其是在日志文件或数据转储中，通常有一个可预测的格式。你可以使用数据格式来帮助 `awk` 提取和处理你关注的数据。

### 打印列

在 `awk` 中，`print` 函数显示你指定的内容。你可以使用许多预定义的变量，但是最常见的是文本文件中以整数命名的列。试试看：

```
$ awk '{print $2;}' colours.txt
color
red
yellow
red
purple
green
purple
brown
brown
yellow
```

在这里，`awk` 显示第二列，用 `$2` 表示。这是相对直观的，因此你可能会猜测 `print $1` 显示第一列，而 `print $3` 显示第三列，依此类推。

要显示*全部*列，请使用 `$0`。

美元符号（`$`）后的数字是*表达式*，因此 `$2` 和 `$(1+1)` 是同一意思。

### 有条件地选择列

你使用的示例文件非常结构化。它有一行充当标题，并且各列直接相互关联。通过定义*条件*，你可以限定 `awk` 在找到此数据时返回的内容。例如，要查看第二列中与 `yellow` 匹配的项并打印第一列的内容：

```
awk '$2=="yellow"{print $1}' file1.txt
banana
pineapple
```

正则表达式也可以工作。此表达式近似匹配 `$2` 中以 `p` 开头跟上任意数量（一个或多个）字符后继续跟上 `p` 的值：

```
$ awk '$2 ~ /p.+p/ {print $0}' colours.txt
grape   purple  10
plum    purple  2
```

数字能被 `awk` 自然解释。例如，要打印第三列包含大于 5 的整数的行：

```
awk '$3>5 {print $1, $2}' colours.txt
name    color
banana  yellow
grape   purple
apple   green
potato  brown
```

### 字段分隔符

默认情况下，`awk` 使用空格作为字段分隔符。但是，并非所有文本文件都使用空格来定义字段。例如，用以下内容创建一个名为 `colours.csv` 的文件：

```
name,color,amount
apple,red,4
banana,yellow,6
strawberry,red,3
grape,purple,10
apple,green,8
plum,purple,2
kiwi,brown,4
potato,brown,9
pineapple,yellow,5
```

只要你指定将哪个字符用作命令中的字段分隔符，`awk` 就能以完全相同的方式处理数据。使用 `--field-separator`（或简称为 `-F`）选项来定义分隔符：

```
$ awk -F"," '$2=="yellow" {print $1}' file1.csv
banana
pineapple
```

### 保存输出

使用输出重定向，你可以将结果写入文件。例如：

```
$ awk -F, '$3>5 {print $1, $2} colours.csv > output.txt
```

这将创建一个包含 `awk` 查询内容的文件。

你还可以将文件拆分为按列数据分组的多个文件。例如，如果要根据每行显示的颜色将 `colours.txt` 拆分为多个文件，你可以在 `awk` 中包含重定向语句来重定向*每条查询*：

```
$ awk '{print > $2".txt"}' colours.txt
```

这将生成名为 `yellow.txt`、`red.txt` 等文件。

在下一篇文章中，你将了解有关字段，记录和一些强大的 awk 变量的更多信息。

本文改编自社区技术播客 [Hacker Public Radio](http://hackerpublicradio.org/eps.php?id=2114)。

---

via: <https://opensource.com/article/19/10/intro-awk>

作者：[Seth Kenlon](https://opensource.com/users/seth) 选题：[lujun9972](https://github.com/lujun9972) 译者：[geekpi](https://github.com/geekpi) 校对：[wxy](https://github.com/wxy)

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


在 Linux 上用 strace 来理解系统调用

Summary: 使用 strace 跟踪用户进程和 Linux 内核之间的交互。

有用，赞

非常详细，感谢！

使用 strace 跟踪用户进程和 Linux 内核之间的交互。

# 在 Linux 上用 strace 来理解系统调用

>
> 使用 strace 跟踪用户进程和 Linux 内核之间的交互。
>
>
>

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

<ruby> 系统调用 <rt>  system call </rt></ruby>是程序从内核请求服务的一种编程方式，而 `strace` 是一个功能强大的工具，可让你跟踪用户进程与 Linux 内核之间的交互。

要了解操作系统的工作原理，首先需要了解系统调用的工作原理。操作系统的主要功能之一是为用户程序提供抽象机制。

操作系统可以大致分为两种模式：

* 内核模式：操作系统内核使用的一种强大的特权模式
* 用户模式：大多数用户应用程序运行的地方 用户大多使用命令行实用程序和图形用户界面（GUI）来执行日常任务。系统调用在后台静默运行，与内核交互以完成工作。

系统调用与函数调用非常相似，这意味着它们都接受并处理参数然后返回值。唯一的区别是系统调用进入内核，而函数调用不进入。从用户空间切换到内核空间是使用特殊的 [trap](https://en.wikipedia.org/wiki/Trap_(computing)) 机制完成的。

通过使用系统库（在 Linux 系统上又称为 glibc），大部分系统调用对用户隐藏了。尽管系统调用本质上是通用的，但是发出系统调用的机制在很大程度上取决于机器（架构）。

本文通过使用一些常规命令并使用 `strace` 分析每个命令进行的系统调用来探索一些实际示例。这些示例使用 Red Hat Enterprise Linux，但是这些命令运行在其他 Linux 发行版上应该也是相同的：

```
[root@sandbox ~]# cat /etc/redhat-release
Red Hat Enterprise Linux Server release 7.7 (Maipo)
[root@sandbox ~]#
[root@sandbox ~]# uname -r
3.10.0-1062.el7.x86_64
[root@sandbox ~]#
```

首先，确保在系统上安装了必需的工具。你可以使用下面的 `rpm` 命令来验证是否安装了 `strace`。如果安装了，则可以使用 `-V` 选项检查 `strace` 实用程序的版本号：

```
[root@sandbox ~]# rpm -qa | grep -i strace
strace-4.12-9.el7.x86_64
[root@sandbox ~]#
[root@sandbox ~]# strace -V
strace -- version 4.12
[root@sandbox ~]#
```

如果没有安装，运行命令安装：

```
yum install strace
```

出于本示例的目的，在 `/tmp` 中创建一个测试目录，并使用 `touch` 命令创建两个文件：

```
[root@sandbox ~]# cd /tmp/
[root@sandbox tmp]#
[root@sandbox tmp]# mkdir testdir
[root@sandbox tmp]#
[root@sandbox tmp]# touch testdir/file1
[root@sandbox tmp]# touch testdir/file2
[root@sandbox tmp]#
```

（我使用 `/tmp` 目录是因为每个人都可以访问它，但是你可以根据需要选择另一个目录。）

在 `testdir` 目录下使用 `ls` 命令验证该文件已经创建：

```
[root@sandbox tmp]# ls testdir/
file1  file2
[root@sandbox tmp]#
```

你可能每天都在使用 `ls` 命令，而没有意识到系统调用在其下面发挥的作用。抽象地来说，该命令的工作方式如下：

>
> 命令行工具 -> 从系统库（glibc）调用函数 -> 调用系统调用
>
>
>

`ls` 命令内部从 Linux 上的系统库（即 glibc）调用函数。这些库去调用完成大部分工作的系统调用。

如果你想知道从 glibc 库中调用了哪些函数，请使用 `ltrace` 命令，然后跟上常规的 `ls testdir/`命令：

```
ltrace ls testdir/
```

如果没有安装 `ltrace`，键入如下命令安装：

```
yum install ltrace
```

大量的输出会被堆到屏幕上；不必担心，只需继续就行。`ltrace` 命令输出中与该示例有关的一些重要库函数包括：

```
opendir("testdir/")                                  = { 3 }
readdir({ 3 })                                       = { 101879119, "." }
readdir({ 3 })                                       = { 134, ".." }
readdir({ 3 })                                       = { 101879120, "file1" }
strlen("file1")                                      = 5
memcpy(0x1665be0, "file1\0", 6)                      = 0x1665be0
readdir({ 3 })                                       = { 101879122, "file2" }
strlen("file2")                                      = 5
memcpy(0x166dcb0, "file2\0", 6)                      = 0x166dcb0
readdir({ 3 })                                       = nil
closedir({ 3 })
```

通过查看上面的输出，你或许可以了解正在发生的事情。`opendir` 库函数打开一个名为 `testdir` 的目录，然后调用 `readdir` 函数，该函数读取目录的内容。最后，有一个对 `closedir` 函数的调用，该函数将关闭先前打开的目录。现在请先忽略其他 `strlen` 和 `memcpy` 功能。

你可以看到正在调用哪些库函数，但是本文将重点介绍由系统库函数调用的系统调用。

与上述类似，要了解调用了哪些系统调用，只需将 `strace` 放在 `ls testdir` 命令之前，如下所示。 再次，一堆乱码丢到了你的屏幕上，你可以按照以下步骤进行操作：

```
[root@sandbox tmp]# strace ls testdir/
execve("/usr/bin/ls", ["ls", "testdir/"], [/* 40 vars */]) = 0
brk(NULL)                               = 0x1f12000
<<< truncated strace output >>>
write(1, "file1  file2\n", 13file1  file2
)          = 13
close(1)                                = 0
munmap(0x7fd002c8d000, 4096)            = 0
close(2)                                = 0
exit_group(0)                           = ?
+++ exited with 0 +++
[root@sandbox tmp]#
```

运行 `strace` 命令后屏幕上的输出就是运行 `ls` 命令的系统调用。每个系统调用都为操作系统提供了特定的用途，可以将它们大致分为以下几个部分：

* 进程管理系统调用
* 文件管理系统调用
* 目录和文件系统管理系统调用
* 其他系统调用

分析显示到屏幕上的信息的一种更简单的方法是使用 `strace` 方便的 `-o` 标志将输出记录到文件中。在 `-o` 标志后添加一个合适的文件名，然后再次运行命令：

```
[root@sandbox tmp]# strace -o trace.log ls testdir/
file1  file2
[root@sandbox tmp]#
```

这次，没有任何输出干扰屏幕显示，`ls` 命令如预期般工作，显示了文件名并将所有输出记录到文件 `trace.log` 中。仅仅是一个简单的 `ls` 命令，该文件就有近 100 行内容：

```
[root@sandbox tmp]# ls -l trace.log
-rw-r--r--. 1 root root 7809 Oct 12 13:52 trace.log
[root@sandbox tmp]#
[root@sandbox tmp]# wc -l trace.log
114 trace.log
[root@sandbox tmp]#
```

让我们看一下这个示例的 `trace.log` 文件的第一行:

```
execve("/usr/bin/ls", ["ls", "testdir/"], [/* 40 vars */]) = 0
```

* 该行的第一个单词 `execve` 是正在执行的系统调用的名称。
* 括号内的文本是提供给该系统调用的参数。
* 符号 `=` 后的数字（在这种情况下为 `0`）是 `execve` 系统调用的返回值。

现在的输出似乎还不太吓人，对吧。你可以应用相同的逻辑来理解其他行。

现在，将关注点集中在你调用的单个命令上，即 `ls testdir`。你知道命令 `ls` 使用的目录名称，那么为什么不在 `trace.log` 文件中使用 `grep` 查找 `testdir` 并查看得到的结果呢？让我们详细查看一下结果的每一行：

```
[root@sandbox tmp]# grep testdir trace.log
execve("/usr/bin/ls", ["ls", "testdir/"], [/* 40 vars */]) = 0
stat("testdir/", {st_mode=S_IFDIR|0755, st_size=32, ...}) = 0
openat(AT_FDCWD, "testdir/", O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC) = 3
[root@sandbox tmp]#
```

回顾一下上面对 `execve` 的分析，你能说一下这个系统调用的作用吗？

```
execve("/usr/bin/ls", ["ls", "testdir/"], [/* 40 vars */]) = 0
```

你无需记住所有系统调用或它们所做的事情，因为你可以在需要时参考文档。手册页可以解救你！在运行 `man` 命令之前，请确保已安装以下软件包：

```
[root@sandbox tmp]# rpm -qa | grep -i man-pages
man-pages-3.53-5.el7.noarch
[root@sandbox tmp]#
```

请记住，你需要在 `man` 命令和系统调用名称之间添加 `2`。如果使用 `man man` 阅读 `man` 命令的手册页，你会看到第 2 节是为系统调用保留的。同样，如果你需要有关库函数的信息，则需要在 `man` 和库函数名称之间添加一个 `3`。

以下是手册的章节编号及其包含的页面类型：

* `1`：可执行的程序或 shell 命令
* `2`：系统调用（由内核提供的函数）
* `3`：库调用（在程序的库内的函数）
* `4`：特殊文件（通常出现在 `/dev`）

使用系统调用名称运行以下 `man` 命令以查看该系统调用的文档：

```
man 2 execve
```

按照 `execve` 手册页，这将执行在参数中传递的程序（在本例中为 `ls`）。可以为 `ls` 提供其他参数，例如本例中的 `testdir`。因此，此系统调用仅以 `testdir` 作为参数运行 `ls`：

```
execve - execute program

DESCRIPTION
       execve()  executes  the  program  pointed to by filename
```

下一个系统调用，名为 `stat`，它使用 `testdir` 参数：

```
stat("testdir/", {st_mode=S_IFDIR|0755, st_size=32, ...}) = 0
```

使用 `man 2 stat` 访问该文档。`stat` 是获取文件状态的系统调用，请记住，Linux 中的一切都是文件，包括目录。

接下来，`openat` 系统调用将打开 `testdir`。密切注意返回的 `3`。这是一个文件描述符，将在以后的系统调用中使用：

```
openat(AT_FDCWD, "testdir/", O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC) = 3
```

到现在为止一切都挺好。现在，打开 `trace.log` 文件，并转到 `openat` 系统调用之后的行。你会看到 `getdents` 系统调用被调用，该调用完成了执行 `ls testdir` 命令所需的大部分操作。现在，从 `trace.log` 文件中用 `grep` 获取 `getdents`：

```
[root@sandbox tmp]# grep getdents trace.log
getdents(3, /* 4 entries */, 32768)     = 112
getdents(3, /* 0 entries */, 32768)     = 0
[root@sandbox tmp]#
```

`getdents` 的手册页将其描述为 “获取目录项”，这就是你要执行的操作。注意，`getdents` 的参数是 `3`，这是来自上面 `openat` 系统调用的文件描述符。

现在有了目录列表，你需要一种在终端中显示它的方法。因此，在日志中用 `grep` 搜索另一个用于写入终端的系统调用 `write`：

```
[root@sandbox tmp]# grep write trace.log
write(1, "file1  file2\n", 13)          = 13
[root@sandbox tmp]#
```

在这些参数中，你可以看到将要显示的文件名：`file1` 和 `file2`。关于第一个参数（`1`），请记住在 Linux 中，当运行任何进程时，默认情况下会为其打开三个文件描述符。以下是默认的文件描述符：

* `0`：标准输入
* `1`：标准输出
* `2`：标准错误

因此，`write` 系统调用将在标准显示（就是这个终端，由 `1` 所标识的）上显示 `file1` 和 `file2`。

现在你知道哪个系统调用完成了 `ls testdir/` 命令的大部分工作。但是在 `trace.log` 文件中其它的 100 多个系统调用呢？操作系统必须做很多内务处理才能运行一个进程，因此，你在该日志文件中看到的很多内容都是进程初始化和清理。阅读整个 `trace.log` 文件，并尝试了解 `ls` 命令是怎么工作起来的。

既然你知道了如何分析给定命令的系统调用，那么就可以将该知识用于其他命令来了解正在执行哪些系统调用。`strace` 提供了许多有用的命令行标志，使你更容易使用，下面将对其中一些进行描述。

默认情况下，`strace` 并不包含所有系统调用信息。但是，它有一个方便的 `-v` 冗余选项，可以在每个系统调用中提供附加信息：

```
strace -v ls testdir
```

在运行 `strace` 命令时始终使用 `-f` 选项是一种好的作法。它允许 `strace` 对当前正在跟踪的进程创建的任何子进程进行跟踪：

```
strace -f ls testdir
```

假设你只需要系统调用的名称、运行的次数以及每个系统调用花费的时间百分比。你可以使用 `-c` 标志来获取这些统计信息：

```
strace -c ls testdir/
```

假设你想专注于特定的系统调用，例如专注于 `open` 系统调用，而忽略其余部分。你可以使用`-e` 标志跟上系统调用的名称：

```
[root@sandbox tmp]# strace -e open ls testdir
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
open("/lib64/libselinux.so.1", O_RDONLY|O_CLOEXEC) = 3
open("/lib64/libcap.so.2", O_RDONLY|O_CLOEXEC) = 3
open("/lib64/libacl.so.1", O_RDONLY|O_CLOEXEC) = 3
open("/lib64/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
open("/lib64/libpcre.so.1", O_RDONLY|O_CLOEXEC) = 3
open("/lib64/libdl.so.2", O_RDONLY|O_CLOEXEC) = 3
open("/lib64/libattr.so.1", O_RDONLY|O_CLOEXEC) = 3
open("/lib64/libpthread.so.0", O_RDONLY|O_CLOEXEC) = 3
open("/usr/lib/locale/locale-archive", O_RDONLY|O_CLOEXEC) = 3
file1  file2
+++ exited with 0 +++
[root@sandbox tmp]#
```

如果你想关注多个系统调用怎么办？不用担心，你同样可以使用 `-e` 命令行标志，并用逗号分隔开两个系统调用的名称。例如，要查看 `write` 和 `getdents` 系统调用：

```
[root@sandbox tmp]# strace -e write,getdents ls testdir
getdents(3, /* 4 entries */, 32768)     = 112
getdents(3, /* 0 entries */, 32768)     = 0
write(1, "file1  file2\n", 13file1  file2
)          = 13
+++ exited with 0 +++
[root@sandbox tmp]#
```

到目前为止，这些示例是明确地运行的命令进行了跟踪。但是，要跟踪已经运行并正在执行的命令又怎么办呢？例如，如果要跟踪用来长时间运行进程的守护程序，该怎么办？为此，`strace` 提供了一个特殊的 `-p` 标志，你可以向其提供进程 ID。

我们的示例不在守护程序上运行 `strace`，而是以 `cat` 命令为例，如果你将文件名作为参数，通常 `cat` 会显示文件的内容。如果没有给出参数，`cat` 命令会在终端上等待用户输入文本。输入文本后，它将重复给定的文本，直到用户按下 `Ctrl + C` 退出为止。

从一个终端运行 `cat` 命令；它会向你显示一个提示，并等待在那里（记住 `cat` 仍在运行且尚未退出）：

```
[root@sandbox tmp]# cat
```

在另一个终端上，使用 `ps` 命令找到进程标识符（PID）：

```
[root@sandbox ~]# ps -ef | grep cat
root      22443  20164  0 14:19 pts/0    00:00:00 cat
root      22482  20300  0 14:20 pts/1    00:00:00 grep --color=auto cat
[root@sandbox ~]#
```

现在，使用 `-p` 标志和 PID（在上面使用 `ps` 找到）对运行中的进程运行 `strace`。运行 `strace` 之后，其输出说明了所接驳的进程的内容及其 PID。现在，`strace` 正在跟踪 `cat` 命令进行的系统调用。看到的第一个系统调用是 `read`，它正在等待文件描述符 `0`（标准输入，这是运行 `cat` 命令的终端）的输入：

```
[root@sandbox ~]# strace -p 22443
strace: Process 22443 attached
read(0,
```

现在，返回到你运行 `cat` 命令的终端，并输入一些文本。我出于演示目的输入了 `x0x0`。注意 `cat` 是如何简单地重复我输入的内容的。因此，`x0x0` 出现了两次。我输入了第一个，第二个是 `cat` 命令重复的输出：

```
[root@sandbox tmp]# cat
x0x0
x0x0
```

返回到将 `strace` 接驳到 `cat` 进程的终端。现在你会看到两个额外的系统调用：较早的 `read` 系统调用，现在在终端中读取 `x0x0`，另一个为 `write`，它将 `x0x0` 写回到终端，然后是再一个新的 `read`，正在等待从终端读取。请注意，标准输入（`0`）和标准输出（`1`）都在同一终端中：

```
[root@sandbox ~]# strace -p 22443
strace: Process 22443 attached
read(0, "x0x0\n", 65536)                = 5
write(1, "x0x0\n", 5)                   = 5
read(0,
```

想象一下，对守护进程运行 `strace` 以查看其在后台执行的所有操作时这有多大帮助。按下 `Ctrl + C` 杀死 `cat` 命令；由于该进程不再运行，因此这也会终止你的 `strace` 会话。

如果要查看所有的系统调用的时间戳，只需将 `-t` 选项与 `strace` 一起使用：

```
[root@sandbox ~]#strace -t ls testdir/

14:24:47 execve("/usr/bin/ls", ["ls", "testdir/"], [/* 40 vars */]) = 0
14:24:47 brk(NULL)                      = 0x1f07000
14:24:47 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f2530bc8000
14:24:47 access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
14:24:47 open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
```

如果你想知道两次系统调用之间所花费的时间怎么办？`strace` 有一个方便的 `-r` 命令，该命令显示执行每个系统调用所花费的时间。非常有用，不是吗？

```
[root@sandbox ~]#strace -r ls testdir/

0.000000 execve("/usr/bin/ls", ["ls", "testdir/"], [/* 40 vars */]) = 0
0.000368 brk(NULL)                 = 0x1966000
0.000073 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fb6b1155000
0.000047 access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
0.000119 open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
```

### 总结

`strace` 实用程序非常有助于理解 Linux 上的系统调用。要了解它的其它命令行标志，请参考手册页和在线文档。

---

via: <https://opensource.com/article/19/10/strace>

作者：[Gaurav Kamathe](https://opensource.com/users/gkamathe) 选题：[lujun9972](https://github.com/lujun9972) 译者：[wxy](https://github.com/wxy) 校对：[wxy](https://github.com/wxy)

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


用 Jenkins 构建 CI/CD 流水线

# 用 Jenkins 构建 CI/CD 流水线

>
> 通过这份 Jenkins 分步教程，构建持续集成和持续交付（CI/CD）流水线。
>
>
>

在我的文章《[使用开源工具构建 DevOps 流水线的初学者指南](/article-11307-1.html)》中，我分享了一个从头开始构建 DevOps 流水线的故事。推动该计划的核心技术是 [Jenkins](https://jenkins.io/)，这是一个用于建立持续集成和持续交付（CI/CD）流水线的开源工具。

在花旗，有一个单独的团队为专用的 Jenkins 流水线提供稳定的主从节点环境，但是该环境仅用于质量保证（QA）、构建阶段和生产环境。开发环境仍然是非常手动的，我们的团队需要对其进行自动化以在加快开发工作的同时获得尽可能多的灵活性。这就是我们决定为 DevOps 建立 CI/CD 流水线的原因。Jenkins 的开源版本由于其灵活性、开放性、强大的插件功能和易用性而成为显而易见的选择。

在本文中，我将分步演示如何使用 Jenkins 构建 CI/CD 流水线。

### 什么是流水线？

在进入本教程之前，了解有关 CI/CD <ruby> 流水线 <rt>  pipeline </rt></ruby>的知识会很有帮助。

首先，了解 Jenkins 本身并不是流水线这一点很有帮助。只是创建一个新的 Jenkins 作业并不能构建一条流水线。可以把 Jenkins 看做一个遥控器，在这里点击按钮即可。当你点击按钮时会发生什么取决于遥控器要控制的内容。Jenkins 为其他应用程序 API、软件库、构建工具等提供了一种插入 Jenkins 的方法，它可以执行并自动化任务。Jenkins 本身不执行任何功能，但是随着其它工具的插入而变得越来越强大。

流水线是一个单独的概念，指的是按顺序连接在一起的事件或作业组：

>
> “<ruby> 流水线 <rt>  pipeline </rt></ruby>”是可以执行的一系列事件或作业。
>
>
>

理解流水线的最简单方法是可视化一系列阶段，如下所示：

在这里，你应该看到两个熟悉的概念：<ruby> 阶段 <rt>  Stage </rt></ruby>和<ruby> 步骤 <rt>  Step </rt></ruby>。

* 阶段：一个包含一系列步骤的块。阶段块可以命名为任何名称；它用于可视化流水线过程。
* 步骤：表明要做什么的任务。步骤定义在阶段块内。

在上面的示例图中，阶段 1 可以命名为 “构建”、“收集信息”或其它名称，其它阶段块也可以采用类似的思路。“步骤”只是简单地说放上要执行的内容，它可以是简单的打印命令（例如，`echo "Hello, World"`）、程序执行命令（例如，`java HelloWorld`）、shell 执行命令（ 例如，`chmod 755 Hello`）或任何其他命令，只要通过 Jenkins 环境将其识别为可执行命令即可。

Jenkins 流水线以**编码脚本**的形式提供，通常称为 “Jenkinsfile”，尽管可以用不同的文件名。下面这是一个简单的 Jenkins 流水线文件的示例：

```
// Example of Jenkins pipeline script

pipeline {
  stages {
    stage("Build") {
      steps {
          // Just print a Hello, Pipeline to the console
          echo "Hello, Pipeline!"
          // Compile a Java file. This requires JDKconfiguration from Jenkins
          javac HelloWorld.java
          // Execute the compiled Java binary called HelloWorld. This requires JDK configuration from Jenkins
          java HelloWorld
          // Executes the Apache Maven commands, clean then package. This requires Apache Maven configuration from Jenkins
          mvn clean package ./HelloPackage
          // List the files in current directory path by executing a default shell command
          sh "ls -ltr"
      }
    }
   // And next stages if you want to define further...
  } // End of stages
} // End of pipeline
```

从此示例脚本很容易看到 Jenkins 流水线的结构。请注意，默认情况下某些命令（如 `java`、`javac`和 `mvn`）不可用，需要通过 Jenkins 进行安装和配置。 因此：

>
> Jenkins 流水线是一种以定义的方式依次执行 Jenkins 作业的方法，方法是将其编码并在多个块中进行结构化，这些块可以包含多个任务的步骤。
>
>
>

好。既然你已经了解了 Jenkins 流水线是什么，我将向你展示如何创建和执行 Jenkins 流水线。在本教程的最后，你将建立一个 Jenkins 流水线，如下所示：

### 如何构建 Jenkins 流水线

为了便于遵循本教程的步骤，我创建了一个示例 [GitHub 存储库](https://github.com/bryantson/CICDPractice)和一个视频教程。

开始本教程之前，你需要：

* Java 开发工具包（JDK）：如果尚未安装，请安装 JDK 并将其添加到环境路径中，以便可以通过终端执行 Java 命令（如 `java jar`）。这是利用本教程中使用的 Java Web Archive（WAR）版本的 Jenkins 所必需的（尽管你可以使用任何其他发行版）。
* 基本计算机操作能力：你应该知道如何键入一些代码、通过 shell 执行基本的 Linux 命令以及打开浏览器。

让我们开始吧。

#### 步骤一：下载 Jenkins

导航到 [Jenkins 下载页面](https://jenkins.io/download/)。向下滚动到 “Generic Java package (.war)”，然后单击下载文件；将其保存在易于找到的位置。（如果你选择其他 Jenkins 发行版，除了步骤二之外，本教程的其余步骤应该几乎相同。）使用 WAR 文件的原因是它是个一次性可执行文件，可以轻松地执行和删除。

#### 步骤二：以 Java 二进制方式执行 Jenkins

打开一个终端窗口，并使用 `cd <your path>` 进入下载 Jenkins 的目录。（在继续之前，请确保已安装 JDK 并将其添加到环境路径。）执行以下命令，该命令将 WAR 文件作为可执行二进制文件运行：

```
java -jar ./jenkins.war
```

如果一切顺利，Jenkins 应该在默认端口 8080 上启动并运行。

#### 步骤三：创建一个新的 Jenkins 作业

打开一个 Web 浏览器并导航到 `localhost:8080`。除非你有以前安装的 Jenkins，否则应直接转到 Jenkins 仪表板。点击 “Create New Jobs”。你也可以点击左侧的 “New Item”。

#### 步骤四：创建一个流水线作业

在此步骤中，你可以选择并定义要创建的 Jenkins 作业类型。选择 “Pipeline” 并为其命名（例如，“TestPipeline”）。单击 “OK” 创建流水线作业。

你将看到一个 Jenkins 作业配置页面。向下滚动以找到 “Pipeline” 部分。有两种执行 Jenkins 流水线的方法。一种方法是在 Jenkins 上直接编写流水线脚本，另一种方法是从 SCM（源代码管理）中检索 Jenkins 文件。在接下来的两个步骤中，我们将体验这两种方式。

#### 步骤五：通过直接脚本配置并执行流水线作业

要使用直接脚本执行流水线，请首先从 GitHub 复制该 [Jenkinsfile 示例](https://github.com/bryantson/CICDPractice)的内容。选择 “Pipeline script” 作为 “Destination”，然后将该 Jenkinsfile 的内容粘贴到 “Script” 中。花一些时间研究一下 Jenkins 文件的结构。注意，共有三个阶段：Build、Test 和 Deploy，它们是任意的，可以是任何一个。每个阶段中都有一些步骤；在此示例中，它们只是打印一些随机消息。

单击 “Save” 以保留更改，这将自动将你带回到 “Job Overview” 页面。

要开始构建流水线的过程，请单击 “Build Now”。如果一切正常，你将看到第一个流水线（如下面的这个）。

要查看流水线脚本构建的输出，请单击任何阶段，然后单击 “Log”。你会看到这样的消息。

#### 步骤六：通过 SCM 配置并执行流水线作业

现在，换个方式：在此步骤中，你将通过从源代码控制的 GitHub 中复制 Jenkinsfile 来部署相同的 Jenkins 作业。在同一个 [GitHub 存储库](https://github.com/bryantson/CICDPractice)中，通过单击 “Clone or download” 并复制其 URL 来找到其存储库 URL。

单击 “Configure” 以修改现有作业。滚动到 “Advanced Project Options” 设置，但这一次，从 “Destination” 下拉列表中选择 “Pipeline script from SCM” 选项。将 GitHub 存储库的 URL 粘贴到 “Repository URL” 中，然后在 “Script Path” 中键入 “Jenkinsfile”。 单击 “Save” 按钮保存。

要构建流水线，回到 “Task Overview” 页面后，单击 “Build Now” 以再次执行作业。结果与之前相同，除了多了一个称为 “Declaration: Checkout SCM” 的阶段。

要查看来自 SCM 构建的流水线的输出，请单击该阶段并查看 “Log” 以检查源代码控制克隆过程的进行情况。

### 除了打印消息，还能做更多

恭喜你！你已经建立了第一个 Jenkins 流水线！

“但是等等”，你说，“这太有限了。除了打印无用的消息外，我什么都做不了。”那没问题。到目前为止，本教程仅简要介绍了 Jenkins 流水线可以做什么，但是你可以通过将其与其他工具集成来扩展其功能。以下是给你的下一个项目的一些思路：

* 建立一个多阶段的 Java 构建流水线，从以下阶段开始：从 Nexus 或 Artifactory 之类的 JAR 存储库中拉取依赖项、编译 Java 代码、运行单元测试、打包为 JAR/WAR 文件，然后部署到云服务器。
* 实现一个高级代码测试仪表板，该仪表板将基于 Selenium 的单元测试、负载测试和自动用户界面测试，报告项目的运行状况。
* 构建多流水线或多用户流水线，以自动化执行 Ansible 剧本的任务，同时允许授权用户响应正在进行的任务。
* 设计完整的端到端 DevOps 流水线，该流水线可提取存储在 SCM 中的基础设施资源文件和配置文件（例如 GitHub），并通过各种运行时程序执行该脚本。

学习本文结尾处的任何教程，以了解这些更高级的案例。

#### 管理 Jenkins

在 Jenkins 主面板，点击 “Manage Jenkins”。

#### 全局工具配置

有许多可用工具，包括管理插件、查看系统日志等。单击 “Global Tool Configuration”。

#### 增加附加能力

在这里，你可以添加 JDK 路径、Git、Gradle 等。配置工具后，只需将该命令添加到 Jenkinsfile 中或通过 Jenkins 脚本执行即可。

### 后继

本文为你介绍了使用酷炫的开源工具 Jenkins 创建 CI/CD 流水线的方法。要了解你可以使用 Jenkins 完成的许多其他操作，请在 Opensource.com 上查看以下其他文章：

* [Jenkins X 入门](https://opensource.com/article/18/11/getting-started-jenkins-x)
* [使用 Jenkins 安装 OpenStack 云](https://opensource.com/article/18/4/install-OpenStack-cloud-Jenkins)
* [在容器中运行 Jenkins](/article-9741-1.html)
* [Jenkins 流水线入门](https://opensource.com/article/18/4/jenkins-pipelines-with-cucumber)
* [如何与 Jenkins 一起运行 JMeter](https://opensource.com/life/16/7/running-jmeter-jenkins-continuous-delivery-101)
* [将 OpenStack 集成到你的 Jenkins 工作流中](https://opensource.com/business/15/5/interview-maish-saidel-keesing-cisco)

你可能对我为你的开源之旅而写的其他一些文章感兴趣：

* [9 个用于构建容错系统的开源工具](https://opensource.com/article/19/3/tools-fault-tolerant-system)
* [了解软件设计模式](https://opensource.com/article/19/7/understanding-software-design-patterns)
* [使用开源工具构建 DevOps 流水线的初学者指南](/article-11307-1.html)

---

via: <https://opensource.com/article/19/9/intro-building-cicd-pipelines-jenkins>

作者：[Bryant Son](https://opensource.com/users/brson) 选题：[lujun9972](https://github.com/lujun9972) 译者：[wxy](https://github.com/wxy) 校对：[wxy](https://github.com/wxy)

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


用 bmon 查看网络带宽使用情况

# 用 bmon 查看网络带宽使用情况

>
> 介绍一下 bmon，这是一个监视和调试工具，可捕获网络统计信息并使它们易于理解。
>
>
>

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

`bmon` 是一种监视和调试工具，可在终端窗口中捕获网络统计信息，并提供了如何以易于理解的形式显示以及显示多少数据的选项。

要检查系统上是否安装了 `bmon`，请使用 `which` 命令：

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

### 获取 bmon

在 Debian 系统上，使用 `sudo apt-get install bmon` 安装该工具。

对于 Red Hat 和相关发行版，你可以使用 `yum install bmon` 或 `sudo dnf install bmon` 进行安装。或者，你可能必须使用更复杂的安装方式，例如使用以下命令，这些命令首先使用 root 帐户或 sudo 来设置所需的 `libconfuse`：

```
# wget https://github.com/martinh/libconfuse/releases/download/v3.2.2/confuse-3.2.2.zip
# unzip confuse-3.2.2.zip && cd confuse-3.2.2
# sudo PATH=/usr/local/opt/gettext/bin:$PATH ./configure
# make
# make install
# git clone https://github.com/tgraf/bmon.git &&ammp; cd bmon
# ./autogen.sh
# ./configure
# make
# sudo make install
```

前面五行会安装 `libconfuse`，而后面五行会获取并安装 `bmon` 本身。

### 使用 bmon

启动 `bmon` 的最简单方法是在命令行中键入 `bmon`。根据你正在使用的窗口的大小，你能够查看并显示各种数据。

显示区域的顶部将显示你的网络接口的统计信息：环回接口（lo）和可通过网络访问的接口（例如 eth0）。如果你的终端窗口只有区区几行高，下面这就是你可能会看到的所有内容，它将看起来像这样：

```
lo bmon 4.0
Interfaces                     x RX bps pps     %x TX bps pps     %
 >lo                           x      4B0      x0     0 0     4B        0
    qdisc none (noqueue) x      0 0      x      0 0
  enp0s25                      x    244B0      x1     0 0   470B        2
    qdisc none (fq_codel)      x      0 0      x      0 0   462B        2
q Increase screen height to see graphical statistics qq

q Press d to enable detailed statistics qq
q Press i to enable additional information qq
 Wed Oct 23 14:36:27 2019 Press ? for help
```

在此示例中，网络接口是 enp0s25。请注意列出的接口下方的有用的 “Increase screen height” 提示。拉伸屏幕以增加足够的行（无需重新启动 bmon），你将看到一些图形：

```
Interfaces                     x RX bps       pps     %x TX bps       pps     %
 >lo                           x      0         0      x      0         0
    qdisc none (noqueue)       x      0         0      x      0         0
  enp0s25                      x    253B        3      x   2.65KiB      6
    qdisc none (fq_codel)      x      0         0      x   2.62KiB      6
qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqvqqqqqqqqqqqqqqqqqqqqqqqvqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq
                              (RX Bytes/second)
    0.00 ............................................................
    0.00 ............................................................
    0.00 ............................................................
    0.00 ............................................................
    0.00 ............................................................
    0.00 ............................................................
         1   5   10   15   20   25   30   35   40   45   50   55   60
                              (TX Bytes/second)
    0.00 ............................................................
    0.00 ............................................................
    0.00 ............................................................
    0.00 ............................................................
    0.00 ............................................................
    0.00 ............................................................
         1   5   10   15   20   25   30   35   40   45   50   55   60
```

但是请注意，该图形未显示值。这是因为它正在显示环回 “>lo” 接口。按下箭头键指向公共网络接口，你将看到一些流量。

```
Interfaces                     x RX bps       pps     %x TX bps       pps     %
  lo                           x      0         0      x      0         0
    qdisc none (noqueue)       x      0         0      x      0         0
 >enp0s25                      x    151B        2      x   1.61KiB      3
    qdisc none (fq_codel)      x      0         0      x   1.60KiB      3
qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqvqqqqqqqqqqqqqqqqqqqqqqqvqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq
       B                      (RX Bytes/second)
  635.00 ...............................|............................
  529.17 .....|.........................|....|.......................
  423.33 .....|................|..|..|..|..|.|.......................
  317.50 .|..||.|..||.|..|..|..|..|..|..||.||||......................
  211.67 .|..||.|..||.|..||||.||.|||.||||||||||......................
  105.83 ||||||||||||||||||||||||||||||||||||||......................
         1   5   10   15   20   25   30   35   40   45   50   55   60
     KiB                      (TX Bytes/second)
    4.59 .....................................|......................
    3.83 .....................................|......................
    3.06 ....................................||......................
    2.30 ....................................||......................
    1.53 |||..............|..|||.|...|.|||.||||......................
    0.77 ||||||||||||||||||||||||||||||||||||||......................
         1   5   10   15   20   25   30   35   40   45   50   55   60

q Press d to enable detailed statistics qq
q Press i to enable additional information qq
 Wed Oct 23 16:42:06 2019 Press ? for help
```

通过更改接口，你可以查看显示了网络流量的图表。但是请注意，默认值是按每秒字节数显示的。要按每秒位数来显示，你可以使用 `bmon -b` 启动该工具。

如果你的窗口足够大并按下 `d` 键，则可以显示有关网络流量的详细统计信息。你看到的统计信息示例如下所示。由于其宽度太宽，该显示分为左右两部分。

左侧：

```
RX        TX   │                  RX      TX   │
 Bytes          11.26MiB  11.26MiB│ Packets       25.91K  25.91K  │
 Collisions         -         0   │ Compressed        0       0   │
 Errors             0         0   │ FIFO Error        0       0   │
 ICMPv6             2         2   │ ICMPv6 Checksu    0       -   │
 Ip6 Broadcast      0         0   │ Ip6 Broadcast     0       0   │
 Ip6 Delivers       8         -   │ Ip6 ECT(0) Pac    0       -   │
 Ip6 Header Err     0         -   │ Ip6 Multicast     0     152B  │
 Ip6 Non-ECT Pa     8         -   │ Ip6 Reasm/Frag    0       0   │
 Ip6 Reassembly     0         -   │ Ip6 Too Big Er    0       -   │
 Ip6Discards        0         0   │ Ip6Octets       530B    530B  │
 Missed Error       0         -   │ Multicast         -       0   │
 Window Error       -         0   │                               │
```

右侧：

```
│                  RX      TX   │                  RX      TX
│ Abort Error       -       0   │ Carrier Error     -       0
│ CRC Error         0       -   │ Dropped           0       0
│ Frame Error       0       -   │ Heartbeat Erro    -
│ ICMPv6 Errors     0       0   │ Ip6 Address Er    0       -
│ Ip6 CE Packets    0       -   │ Ip6 Checksum E    0       -
│ Ip6 ECT(1) Pac    0       -   │ Ip6 Forwarded     -       0
│ Ip6 Multicast     0       2   │ Ip6 No Route      0       0
│ Ip6 Reasm/Frag    0       0   │ Ip6 Reasm/Frag    0       0
│ Ip6 Truncated     0       -   │ Ip6 Unknown Pr    0       -
│ Ip6Pkts           8       8   │ Length Error      0
│ No Handler        0       -   │ Over Error        0       -
```

如果按下 `i` 键，将显示网络接口上的其他信息。

左侧：

```
MTU                        1500 | Flags    broadcast,multicast,up |
Address       00:1d:09:77:9d:08 | Broadcast ff:ff:ff:ff:ff:ff     |
Family                   unspec | Alias                           |
```

右侧：

```
| Operstate                 up | IfIndex                   2 |
| Mode                 default | TXQlen                 1000 |
| Qdisc               fq_codel |
```

如果你按下 `?` 键，将会出现一个帮助菜单，其中简要介绍了如何在屏幕上移动光标、选择要显示的数据以及控制图形如何显示。

要退出 `bmon`，输入 `q`，然后输入 `y` 以响应提示来确认退出。

需要注意的一些重要事项是：

* `bmon` 会将其显示调整为终端窗口的大小
* 显示区域底部显示的某些选项仅在窗口足够大可以容纳数据时才起作用
* 除非你使用 `-R`（例如 `bmon -R 5`）来减慢显示速度，否则每秒更新一次显示

---

via: <https://www.networkworld.com/article/3447936/viewing-network-bandwidth-usage-with-bmon.html>

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

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


在 Linux 中加速工作的键盘快捷键

Summary: 学习键盘快捷键将使生产率提高 3.3％

这计算略简单了，省下来的时间全去折腾显卡了

学习键盘快捷键将使生产率提高 3.3％

# 在 Linux 中加速工作的键盘快捷键

>
> 操作鼠标、键盘和菜单会占用我们很多时间，这些可以使用键盘快捷键来节省时间。这不仅节省时间，还可以使用户更高效。
>
>
>

你是否意识到每次在打字时从键盘切换到鼠标需要多达两秒钟？如果一个人每天工作八小时，每分钟从键盘切换到鼠标一次，并且一年中大约有 240 个工作日，那么所浪费的时间（根据 Brainscape 的计算）为： [每分钟浪费 2 秒] x [每天 480 分钟] x 每年 240 个工作日 = 每年浪费 64 小时 这相当于损失了八个工作日，因此学习键盘快捷键将使生产率提高 3.3％（<https://www.brainscape.com/blog/2011/08/keyboard-shortcuts-economy/>）。

键盘快捷键提供了一种更快的方式来执行任务，不然就需要使用鼠标和/或菜单分多个步骤来完成。图 1 列出了 Ubuntu 18.04 Linux 和 Web 浏览器中一些最常用的快捷方式。我省略了非常有名的快捷方式，例如复制、粘贴等，以及不经常使用的快捷方式。读者可以参考在线资源以获得完整的快捷方式列表。请注意，Windows 键在 Linux 中被重命名为 Super 键。

### 常规快捷方式

下面列出了常规快捷方式。

### 打印屏幕和屏幕录像

以下快捷方式可用于打印屏幕或录制屏幕视频。

### 在应用之间切换

此处列出的快捷键可用于在应用之间切换。

### 平铺窗口

可以使用下面提供的快捷方式以不同方式将窗口平铺。

### 浏览器快捷方式

此处列出了浏览器最常用的快捷方式。大多数快捷键对于 Chrome/Firefox 浏览器是通用的。

| **组合键** | **行为** |
| --- | --- |
| `Ctrl + T` | 打开一个新标签。 |
| `Ctrl + Shift + T` | 打开最近关闭的标签。 |
| `Ctrl + D` | 添加一个新书签。 |
| `Ctrl + W` | 关闭浏览器标签。 |
| `Alt + D` | 将光标置于浏览器的地址栏中。 |
| `F5 或 Ctrl-R` | 刷新页面。 |
| `Ctrl + Shift + Del` | 清除私人数据和历史记录。 |
| `Ctrl + N` | 打开一个新窗口。 |
| `Home` | 滚动到页面顶部。 |
| `End` | 滚动到页面底部。 |
| `Ctrl + J` | 打开下载文件夹（在 Chrome 中） |
| `F11` | 全屏视图（切换效果） |

### 终端快捷方式

这是终端快捷方式的列表。

你还可以在 Ubuntu 中配置自己的自定义快捷方式，如下所示：

* 在 Ubuntu Dash 中单击设置。
* 在“设置”窗口的左侧菜单中选择“设备”选项卡。
* 在设备菜单中选择键盘标签。
* 右面板的底部有个 “+” 按钮。点击 “+” 号打开自定义快捷方式对话框并配置新的快捷方式。

学习本文提到的三个快捷方式可以节省大量时间，并使你的工作效率更高。

### 引用

[Cohen, Andrew. How keyboard shortcuts could revive America’s economy; www.brainscape.com. [Online] Brainscape, 26 May 2017;](https://www.brainscape.com/blog/2011/08/keyboard-shortcuts-economy/)

---

via: <https://opensourceforu.com/2019/11/keyboard-shortcuts-to-speed-up-your-work-in-linux/>

作者：[S Sathyanarayanan](https://opensourceforu.com/author/s-sathyanarayanan/) 选题：[lujun9972](https://github.com/lujun9972) 译者：[geekpi](https://github.com/geekpi) 校对：[wxy](https://github.com/wxy)

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


初级：如何更新 Fedora Linux 系统

Summary: 本快速教程介绍了更新 Fedora Linux 安装的多种方法。

文章的营养有点……<br />
还是谢谢编辑

本快速教程介绍了更新 Fedora Linux 安装的多种方法。

# 初级：如何更新 Fedora Linux 系统

>
> 本快速教程介绍了更新 Fedora Linux 安装的多种方法。
>
>
>

前几天，我安装了[新发布的 Fedora 31](https://itsfoss.com/fedora-31-release/)。老实说，这是我第一次使用[非 Ubuntu 发行版](https://itsfoss.com/non-ubuntu-beginner-linux/)。

安装 Fedora 之后，我做的第一件事就是尝试安装一些软件。我打开软件中心，发现该软件中心已“损坏”。 我无法从中安装任何应用程序。

我不确定我的系统出了什么问题。在团队内部讨论时，Abhishek 建议我先更新系统。我更新了，更新后一切恢复正常。更新 [Fedora](https://getfedora.org/) 系统后，软件中心也能正常工作了。

有时我们一直尝试解决我们所面临的问题，而忽略了对系统的更新。不管问题有多大或多小，为了避免它们，你都应该保持系统更新。

在本文中，我将向你展示更新 Fedora Linux 系统的多种方法。

* 使用软件中心更新 Fedora
* 使用命令行更新 Fedora
* 从系统设置更新 Fedora

请记住，更新 Fedora 意味着安装安全补丁、更新内核和软件。如果要从 Fedora 的一个版本更新到另一个版本，这称为版本升级，你可以[在此处阅读有关 Fedora 版本升级过程的信息](https://itsfoss.com/upgrade-fedora-version/)。

### 从软件中心更新 Fedora

你很可能会收到通知，通知你有一些系统更新需要查看，你应该在单击该通知时启动软件中心。

你所要做的就是 —— 点击“更新”，并验证 root 密码开始更新。

如果你没有收到更新的通知，则只需启动软件中心并转到“更新”选项卡即可。现在，你只需要继续更新。

### 使用终端更新 Fedora

如果由于某种原因无法加载软件中心，则可以使用 `dnf` 软件包管理命令轻松地更新系统。

只需启动终端并输入以下命令即可开始更新（系统将提示你确认 root 密码）：

```
sudo dnf upgrade
```

>
> \*\*dnf 更新 vs dnf 升级 \*\*
>
>
> 你会发现有两个可用的 dnf 命令：`dnf update` 和 `dnf upgrade`。这两个命令执行相同的工作，即安装 Fedora 提供的所有更新。那么，为什么要会有这两个呢，你应该使用哪一个？`dnf update` 基本上是 `dnf upgrade` 的别名。尽管 `dnf update` 可能仍然有效，但最好使用 `dnf upgrade`，因为这是真正的命令。
>
>
>

### 从系统设置中更新 Fedora

如果其它方法都不行（或者由于某种原因已经进入“系统设置”），请导航至“设置”底部的“详细信息”选项。

如上图所示，该选项中显示操作系统和硬件的详细信息以及一个“检查更新”按钮。你只需要单击它并提供 root 密码即可继续安装可用的更新。

### 总结

如上所述，更新 Fedora 系统非常容易。有三种方法供你选择，因此无需担心。

如果你按上述说明操作时发现任何问题，请随时在下面的评论部分告诉我。

---

via: <https://itsfoss.com/update-fedora/>

作者：[Ankush Das](https://itsfoss.com/author/ankush/) 选题：[lujun9972](https://github.com/lujun9972) 译者：[Morisun029](https://github.com/Morisun029) 校对：[wxy](https://github.com/wxy)

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


怎样用 Bash 编程：语法和工具

# 怎样用 Bash 编程：语法和工具

>
> 让我们通过本系列文章来学习基本的 Bash 编程语法和工具，以及如何使用变量和控制运算符，这是三篇中的第一篇。
>
>
>

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

Shell 是操作系统的命令解释器，其中 Bash 是我最喜欢的。每当用户或者系统管理员将命令输入系统的时候，Linux 的 shell 解释器就会把这些命令转换成操作系统可以理解的形式。而执行结果返回 shell 程序后，它会将结果输出到 STDOUT（标准输出），默认情况下，这些结果会[显示在你的终端](https://opensource.com/article/18/10/linux-data-streams)。所有我熟悉的 shell 同时也是一门编程语言。

Bash 是个功能强大的 shell，包含众多便捷特性，比如：tab 补全、命令回溯和再编辑、别名等。它的命令行默认编辑模式是 Emacs，但是我最喜欢的 Bash 特性之一是我可以将其更改为 Vi 模式，以使用那些储存在我肌肉记忆中的的编辑命令。

然而，如果你把 Bash 当作单纯的 shell 来用，则无法体验它的真实能力。我在设计一套包含三卷的 [Linux 自学课程](http://www.both.org/?page_id=1183)时（这个系列的文章正是基于此课程），了解到许多 Bash 的知识，这些是我在过去 20 年的 Linux 工作经验中所没有掌握的，其中的一些知识就是关于 Bash 的编程用法。不得不说，Bash 是一门强大的编程语言，是一个能够同时用于命令行和 shell 脚本的完美设计。

本系列文章将要探讨如何使用 Bash 作为命令行界面（CLI）编程语言。第一篇文章简单介绍 Bash 命令行编程、变量以及控制运算符。其他文章会讨论诸如：Bash 文件的类型；字符串、数字和一些逻辑运算符，它们能够提供代码执行流程中的逻辑控制；不同类型的 shell 扩展；通过 `for`、`while` 和 `until` 来控制循环操作。

### Shell

Bash 是 Bourne Again Shell 的缩写，因为 Bash shell 是 [基于](https://opensource.com/19/9/command-line-heroes-bash) 更早的 Bourne shell，后者是 Steven Bourne 在 1977 年开发的。另外还有很多[其他的 shell](https://en.wikipedia.org/wiki/Comparison_of_command_shells) 可以使用，但下面四个是我经常见到的：

* `csh`：C shell 适合那些习惯了 C 语言语法的开发者。
* `ksh`：Korn shell，由 David Korn 开发，在 Unix 用户中更流行。
* `tcsh`：一个 csh 的变种，增加了一些易用性。
* `zsh`：Z shell，集成了许多其他流行 shell 的特性。

所有 shell 都有内置命令，用以补充或替代核心工具集。打开 shell 的 man 说明页，找到“BUILT-INS”那一段，可以查看都有哪些内置命令。

每种 shell 都有它自己的特性和语法风格。我用过 csh、ksh 和 zsh，但我还是更喜欢 Bash。你可以多试几个，寻找更适合你的 shell，尽管这可能需要花些功夫。但幸运的是，切换不同 shell 很简单。

所有这些 shell 既是编程语言又是命令解释器。下面我们来快速浏览一下 Bash 中集成的编程结构和工具。

### 作为编程语言的 Bash

大多数场景下，系统管理员都会使用 Bash 来发送简单明了的命令。但 Bash 不仅可以输入单条命令，很多系统管理员可以编写简单的命令行程序来执行一系列任务，这些程序可以作为通用工具，能节省时间和精力。

编写 CLI 程序的目的是要提高效率（做一个“懒惰的”系统管理员）。在 CLI 程序中，你可以用特定顺序列出若干命令，逐条执行。这样你就不用盯着显示屏，等待一条命令执行完，再输入另一条，省下来的时间就可以去做其他事情了。

### 什么是“程序”？

自由在线计算机词典（[FOLDOC](http://foldoc.org/program)）对于程序的定义是：“由计算机执行的指令，而不是运行它们的物理硬件。”普林斯顿大学的 [WordNet](https://wordnet.princeton.edu/) 将程序定义为：“……计算机可以理解并执行的一系列指令……”[维基百科](https://en.wikipedia.org/wiki/Computer_program)上也有一条不错的关于计算机程序的条目。

总结下，程序由一条或多条指令组成，目的是完成一个具体的相关任务。对于系统管理员而言，一段程序通常由一系列的 shell 命令构成。Linux 下所有的 shell （至少我所熟知的）都有基本的编程功能，Bash 作为大多数 linux 发行版的默认 shell，也不例外。

本系列用 Bash 举例（因为它无处不在），假如你使用一个不同的 shell 也没关系，尽管结构和语法有所不同，但编程思想是相通的。有些 shell 支持某种特性而其他 shell 则不支持，但它们都提供编程功能。Shell 程序可以被存在一个文件中被反复使用，或者在需要的时候才创建它们。

### 简单 CLI 程序

最简单的命令行程序只有一或两条语句，它们可能相关，也可能无关，在按回车键之前被输入到命令行。程序中的第二条语句（如果有的话）可能取决于第一条语句的操作，但也不是必须的。

这里需要特别讲解一个标点符号。当你在命令行输入一条命令，按下回车键的时候，其实在命令的末尾有一个隐含的分号（`;`）。当一段 CLI shell 程序在命令行中被串起来作为单行指令使用时，必须使用分号来终结每个语句并将其与下一条语句分开。但 CLI shell 程序中的最后一条语句可以使用显式或隐式的分号。

### 一些基本语法

下面的例子会阐明这一语法规则。这段程序由单条命令组成，还有一个显式的终止符：

```
[student@studentvm1 ~]$ echo "Hello world." ;
Hello world.
```

看起来不像一个程序，但它确是我学习每个新编程语言时写下的第一个程序。不同语言可能语法不同，但输出结果是一样的。

让我们扩展一下这段微不足道却又无所不在的代码。你的结果可能与我的有所不同，因为我的家目录有点乱，而你可能是在 GUI 桌面中第一次登录账号。

```
[student@studentvm1 ~]$ echo "My home directory." ; ls ;
My home directory.
chapter25   TestFile1.Linux  dmesg2.txt  Downloads  newfile.txt  softlink1  testdir6
chapter26   TestFile1.mac    dmesg3.txt  file005    Pictures     Templates  testdir
TestFile1      Desktop       dmesg.txt   link3      Public       testdir    Videos
TestFile1.dos  dmesg1.txt    Documents   Music      random.txt   testdir1
```

现在是不是更明显了。结果是相关的，但是两条语句彼此独立。你可能注意到我喜欢在分号前后多输入一个空格，这样会让代码的可读性更好。让我们再运行一遍这段程序，这次不要带结尾的分号：

```
[student@studentvm1 ~]$ echo "My home directory." ; ls
```

输出结果没有区别。

### 关于变量

像所有其他编程语言一样，Bash 支持变量。变量是个象征性的名字，它指向内存中的某个位置，那里存着对应的值。变量的值是可以改变的，所以它叫“变~量”。

Bash 不像 C 之类的语言，需要强制指定变量类型，比如：整型、浮点型或字符型。在 Bash 中，所有变量都是字符串。整数型的变量可以被用于整数运算，这是 Bash 唯一能够处理的数学类型。更复杂的运算则需要借助 [bc](https://www.gnu.org/software/bc/manual/html_mono/bc.html) 这样的命令，可以被用在命令行编程或者脚本中。

变量的值是被预先分配好的，这些值可以用在命令行编程或者脚本中。可以通过变量名字给其赋值，但是不能使用 `$` 符开头。比如，`VAR=10` 这样会把 `VAR` 的值设为 `10`。要打印变量的值，你可以使用语句 `echo $VAR`。变量名必须以文本（即非数字）开始。

Bash 会保存已经定义好的变量，直到它们被取消掉。

下面这个例子，在变量被赋值前，它的值是空（`null`）。然后给它赋值并打印出来，检验一下。你可以在同一行 CLI 程序里完成它：

```
[student@studentvm1 ~]$ echo $MyVar ; MyVar="Hello World" ; echo $MyVar ;

Hello World
[student@studentvm1 ~]$
```

*注意：变量赋值的语法非常严格，等号（`=`）两边不能有空格。*

那个空行表明了 `MyVar` 的初始值为空。变量的赋值和改值方法都一样，这个例子展示了原始值和新的值。

正如之前说的，Bash 支持整数运算，当你想计算一个数组中的某个元素的位置，或者做些简单的算术运算，这还是挺有帮助的。然而，这种方法并不适合科学计算，或是某些需要小数运算的场景，比如财务统计。这些场景有其它更好的工具可以应对。

下面是个简单的算术题：

```
[student@studentvm1 ~]$ Var1="7" ; Var2="9" ; echo "Result = $((Var1*Var2))"
Result = 63
```

好像没啥问题，但如果运算结果是浮点数会发生什么呢？

```
[student@studentvm1 ~]$ Var1="7" ; Var2="9" ; echo "Result = $((Var1/Var2))"
Result = 0
[student@studentvm1 ~]$ Var1="7" ; Var2="9" ; echo "Result = $((Var2/Var1))"
Result = 1
[student@studentvm1 ~]$
```

结果会被取整。请注意运算被包含在 `echo` 语句之中，其实计算在 echo 命令结束前就已经完成了，原因是 Bash 的内部优先级。想要了解详情的话，可以在 Bash 的 man 页面中搜索 “precedence”。

### 控制运算符

Shell 的控制运算符是一种语法运算符，可以轻松地创建一些有趣的命令行程序。在命令行上按顺序将几个命令串在一起，就变成了最简单的 CLI 程序：

```
command1 ; command2 ; command3 ; command4 ; . . . ; etc. ;
```

只要不出错，这些命令都能顺利执行。但假如出错了怎么办？你可以预设好应对出错的办法，这就要用到 Bash 内置的控制运算符， `&&` 和 `||`。这两种运算符提供了流程控制功能，使你能改变代码执行的顺序。分号也可以被看做是一种 Bash 运算符，预示着新一行的开始。

`&&` 运算符提供了如下简单逻辑，“如果 command1 执行成功，那么接着执行 command2。如果 command1 失败，就跳过 command2。”语法如下：

```
command1 && command2
```

现在，让我们用命令来创建一个新的目录，如果成功的话，就把它切换为当前目录。确保你的家目录（`~`）是当前目录，先尝试在 `/root` 目录下创建，你应该没有权限：

```
[student@studentvm1 ~]$ Dir=/root/testdir ; mkdir $Dir/ && cd $Dir
mkdir: cannot create directory '/root/testdir/': Permission denied
[student@studentvm1 ~]$
```

上面的报错信息是由 `mkdir` 命令抛出的，因为创建目录失败了。`&&` 运算符收到了非零的返回码，所以 `cd` 命令就被跳过，前者阻止后者继续运行，因为创建目录失败了。这种控制流程可以阻止后面的错误累积，避免引发更严重的问题。是时候讲点更复杂的逻辑了。

当一段程序的返回码大于零时，使用 `||` 运算符可以让你在后面接着执行另一段程序。简单语法如下：

```
command1 || command2
```

解读一下，“假如 command1 失败，执行 command2”。隐藏的逻辑是，如果 command1 成功，跳过 command2。下面实践一下，仍然是创建新目录：

```
[student@studentvm1 ~]$ Dir=/root/testdir ; mkdir $Dir || echo "$Dir was not created."
mkdir: cannot create directory '/root/testdir': Permission denied
/root/testdir was not created.
[student@studentvm1 ~]$
```

正如预期，因为目录无法创建，第一条命令失败了，于是第二条命令被执行。

把 `&&` 和 `||` 两种运算符结合起来才能发挥它们的最大功效。请看下面例子中的流程控制方法：

```
前置 commands ; command1 && command2 || command3 ; 跟随 commands
```

语法解释：“假如 command1 退出时返回码为零，就执行 command2，否则执行 command3。”用具体代码试试：

```
[student@studentvm1 ~]$ Dir=/root/testdir ; mkdir $Dir && cd $Dir || echo "$Dir was not created."
mkdir: cannot create directory '/root/testdir': Permission denied
/root/testdir was not created.
[student@studentvm1 ~]$
```

现在我们再试一次，用你的家目录替换 `/root` 目录，你将会有权限创建这个目录了：

```
[student@studentvm1 ~]$ Dir=~/testdir ; mkdir $Dir && cd $Dir || echo "$Dir was not created."
[student@studentvm1 testdir]$
```

像 `command1 && command2` 这样的控制语句能够运行的原因是，每条命令执行完毕时都会给 shell 发送一个返回码，用来表示它执行成功与否。默认情况下，返回码为 `0` 表示成功，其他任何正值表示失败。一些系统管理员使用的工具用值为 `1` 的返回码来表示失败，但其他很多程序使用别的数字来表示失败。

Bash 的内置变量 `$?` 可以显示上一条命令的返回码，可以在脚本或者命令行中非常方便地检查它。要查看返回码，让我们从运行一条简单的命令开始，返回码的结果总是上一条命令给出的。

```
[student@studentvm1 testdir]$ ll ; echo "RC = $?"
total 1264
drwxrwxr-x  2 student student   4096 Mar  2 08:21 chapter25
drwxrwxr-x  2 student student   4096 Mar 21 15:27 chapter26
-rwxr-xr-x  1 student student     92 Mar 20 15:53 TestFile1
drwxrwxr-x. 2 student student 663552 Feb 21 14:12 testdir
drwxr-xr-x. 2 student student   4096 Dec 22 13:15 Videos
RC = 0
[student@studentvm1 testdir]$
```

在这个例子中，返回码为零，意味着命令执行成功了。现在对 root 的家目录测试一下，你应该没有权限：

```
[student@studentvm1 testdir]$ ll /root ; echo "RC = $?"
ls: cannot open directory '/root': Permission denied
RC = 2
[student@studentvm1 testdir]$
```

本例中返回码是 `2`，表明非 root 用户没有权限进入这个目录。你可以利用这些返回码，用控制运算符来改变程序执行的顺序。

### 总结

本文将 Bash 看作一门编程语言，并从这个视角介绍了它的简单语法和基础工具。我们学习了如何将数据输出到 STDOUT，怎样使用变量和控制运算符。在本系列的下一篇文章中，将会重点介绍能够控制指令执行流程的逻辑运算符。

---

via: <https://opensource.com/article/19/10/programming-bash-part-1>

作者：[David Both](https://opensource.com/users/dboth) 选题：[lujun9972](https://github.com/lujun9972) 译者：[jdh8383](https://github.com/jdh8383) 校对：[wxy](https://github.com/wxy)

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


全面介绍 Linux 权限

Summary: 知道如何控制用户对文件的访问是一项基本的系统管理技能。

知道如何控制用户对文件的访问是一项基本的系统管理技能。

# 全面介绍 Linux 权限

>
> 知道如何控制用户对文件的访问是一项基本的系统管理技能。
>
>
>

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

了解 Linux 权限以及如何控制哪些用户可以访问文件是系统管理的一项基本技能。

本文将介绍标准 Linux 文件系统权限，并进一步研究特殊权限，以及使用 `umask` 来解释默认权限作为文章的结束。

### 理解 ls 命令的输出

在讨论如何修改权限之前，我们需要知道如何查看权限。通过 `ls` 命令的长列表参数（`-l`）为我们提供了有关文件的许多信息。

```
$ ls -lAh
total 20K
-rwxr-xr--+ 1 root root    0 Mar  4 19:39 file1
-rw-rw-rw-. 1 root root    0 Mar  4 19:39 file10
-rwxrwxr--+ 1 root root    0 Mar  4 19:39 file2
-rw-rw-rw-. 1 root root    0 Mar  4 19:39 file8
-rw-rw-rw-. 1 root root    0 Mar  4 19:39 file9
drwxrwxrwx. 2 root root 4.0K Mar  4 20:04 testdir
```

为了理解这些是什么意思，让我们将关于权限的输出分解为各个部分。单独理解每个部分会更容易。

让我们看看在上面的输出中的最后一行的每个组件：

```
drwxrwxrwx. 2 root root 4.0K Mar  4 20:04 testdir
```

| 第 1 节 | 第 2 节 | 第 3 节 | 第 4 节 | 第 5 节 | 第 6 节 | 第 7 节 |
| --- | --- | --- | --- | --- | --- | --- |
| `d` | `rwx` | `rwx` | `rwx` | `.` | `root` | `root` |

第 1 节（左侧）显示文件的类型。

| 符号 | 类型 |
| --- | --- |
| `d` | 目录 |
| `-` | 常规文件 |
| `l` | 软链接 |

`ls` 的 [info 页面](https://www.gnu.org/software/texinfo/manual/info-stnd/info-stnd.html)完整列出了不同的文件类型。

每个文件都有三种访问方式：

* 属主
* 组
* 所有其他人 第 2、3 和 4 节涉及用户（属主）、组和“其他用户”权限。每个部分都可以包含 `r`（读取）、`w`（写入）和 `x`（执行）权限的组合。

每个权限还分配了一个数值，这在以八进制表示形式讨论权限时很重要。

| 权限 | 八进制值 |
| --- | --- |
| `r` | 4 |
| `w` | 2 |
| `x` | 1 |

第 5 节描述了其他替代访问方法，例如 SELinux 或文件访问控制列表（FACL）。

| 访问方法 | 字符 |
| --- | --- |
| 没有其它访问方法 | `-` |
| SELinux | `.` |
| FACL | `+` |
| 各种方法的组合 | `+` |

第 6 节和第 7 节分别是属主和组的名称。

### 使用 chown 和 chmod

#### chown 命令

`chown`（更改所有权）命令用于更改文件的用户和组的所有权。

要将文件 `foo` 的用户和组的所有权更改为 `root`，我们可以使用以下命令：

```
$ chown root:root foo
$ chown root: foo
```

在用户名后跟冒号（`:`）运行该命令将同时设置用户和组所有权。

要仅将文件 `foo` 的用户所有权设置为 `root` 用户，请输入：

```
$ chown root foo
```

要仅更改文件 `foo` 的组所有权，请在组之前加冒号：

```
$ chown :root foo
```

#### chmod 命令

`chmod`（更改模式）命令控制属主、组以及既不是属主也不属于与文件关联的组的所有其他用户的文件许可权。

`chmod` 命令可以以八进制（例如 `755`、`644` 等）和符号（例如 `u+rwx`、`g-rwx`、`o=rw`）格式设置权限。

八进制表示法将 4 个“点”分配给“读取”，将 2 个“点”分配给“写入”，将 1 个点分配给“执行”。如果要给用户（属主）分配“读取”权限，则将 4 分配给第一个插槽，但是如果要添加“写入”权限，则必须添加 2。如果要添加“执行”，则要添加 1。我们对每种权限类型执行此操作：属主、组和其他。

例如，如果我们想将“读取”、“写入”和“执行”分配给文件的属主，但仅将“读取”和“执行”分配给组成员和所有其他用户，则我们应使用 `755`（八进制格式）。这是属主的所有权限位（`4+2+1`），但组和其他权限的所有权限位只有 `4` 和 `1`（`4+1`）。

>
> 细分为：4+2+1=7，4+1=5 和 4+1=5。
>
>
>

如果我们想将“读取”和“写入”分配给文件的属主，而只将“读取”分配给组的成员和所有其他用户，则可以如下使用 `chmod`：

```
$ chmod 644 foo_file
```

在下面的示例中，我们在不同的分组中使用符号表示法。注意字母 `u`、`g` 和 `o` 分别代表“用户”（属主）、“组”和“其他”。我们将 `u`、`g` 和 `o` 与 `+`、`-` 或 `=` 结合使用来添加、删除或设置权限位。

要将“执行”位添加到所有权权限集中：

```
$ chmod u+x foo_file
```

要从组成员中删除“读取”、“写入”和“执行”：

```
$ chmod g-rwx foo_file
```

要将所有其他用户的所有权设置为“读取”和“写入”：

```
$ chmod o=rw
```

### 特殊位：设置 UID、设置 GID 和粘滞位

除了标准权限外，还有一些特殊的权限位，它们具有一些别的用处。

#### 设置用户 ID（suid）

当在文件上设置 `suid` 时，将以文件的属主的身份而不是运行该文件的用户身份执行操作。一个[好的例子](https://www.theurbanpenguin.com/using-a-simple-c-program-to-explain-the-suid-permission/)是 `passwd` 命令。它需要设置 `suid` 位，以便更改密码的操作具有 root 权限。

```
$ ls -l /bin/passwd
-rwsr-xr-x. 1 root root 27832 Jun 10  2014 /bin/passwd
```

设置 `suid` 位的示例：

```
$ chmod u+s /bin/foo_file_name
```

#### 设置组 ID（sgid）

`sgid` 位与 `suid` 位类似，操作是在目录的组所有权下完成的，而不是以运行命令的用户身份。

一个使用 `sgid` 的例子是，如果多个用户正在同一个目录中工作，并且目录中创建的每个文件都需要具有相同的组权限。下面的示例创建一个名为 `collab_dir` 的目录，设置 `sgid` 位，并将组所有权更改为 `webdev`。

```
$ mkdir collab_dir
$ chmod g+s collab_dir
$ chown :webdev collab_dir
```

现在，在该目录中创建的任何文件都将具有 `webdev` 的组所有权，而不是创建该文件的用户的组。

```
$ cd collab_dir
$ touch file-sgid
$ ls -lah file-sgid
-rw-r--r--. 1 root webdev 0 Jun 12 06:04 file-sgid
```

#### “粘滞”位

粘滞位表示，只有文件所有者才能删除该文件，即使组权限允许该文件可以删除。通常，在 `/tmp` 这样的通用或协作目录上，此设置最有意义。在下面的示例中，“所有其他人”权限集的“执行”列中的 `t` 表示已应用粘滞位。

```
$ ls -ld /tmp
drwxrwxrwt. 8 root root 4096 Jun 12 06:07 /tmp/
```

请记住，这不会阻止某个人编辑该文件，它只是阻止他们删除该目录的内容（LCTT 译注：即删除目录下文件）。

我们将粘滞位设置为：

```
$ chmod o+t foo_dir
```

你可以自己尝试在目录上设置粘滞位并赋予其完整的组权限，以便多个属于同一组的用户可以在目录上进行读取、写入和执行。

接着，以每个用户的身份创建文件，然后尝试以另一个用户的身份删除它们。

如果一切配置正确，则一个用户应该不能从另一用户那里删除文件。

请注意，这些位中的每个位也可以用八进制格式设置：SUID = 4、SGID = 2 和 粘滞位 = 1。（LCTT 译注：这里是四位八进制数字）

```
$ chmod 4744
$ chmod 2644
$ chmod 1755
```

#### 大写还是小写？

如果要设置特殊位时看到大写的 `S` 或 `T` 而不是小写的字符（如我们之前所见），那是因为不存在（对应的）底层的执行位。为了说明这一点，下面的示例创建一个设置了粘滞位的文件。然后，我们可以添加和删除执行位以演示大小写更改。

```
$ touch file cap-ST-demo
$ chmod 1755 cap-ST-demo
$ ls -l cap-ST-demo
-rwxr-xr-t. 1 root root 0 Jun 12 06:16 cap-ST-demo

$ chmod o-x cap-X-demo
$ ls -l cap-X-demo
-rwxr-xr-T. 1 root root 0 Jun 12 06:16 cap-ST-demo
```

#### 有条件地设置执行位

至此，我们使用小写的 `x` 设置了执行位，而无需询问任何问题即可对其进行设置。我们还有另一种选择：使用大写的 `X` 而不是小写的，它将仅在权限组中某个位置已经有执行位时才设置执行位。这可能是一个很难解释的概念，但是下面的演示将帮助说明它。请注意，在尝试将执行位添加到组特权之后，该位没有被设置上。

```
$ touch cap-X-file
$ ls -l cap-X-file
-rw-r--r--. 1 root root 0 Jun 12 06:31 cap-X-file
$ chmod g+X cap-X-file
$ ls -l cap-X-file
-rw-r--r--. 1 root root 0 Jun 12 06:31 cap-X-file
```

在这个类似的例子中，我们首先使用小写的 `x` 将执行位添加到组权限，然后使用大写的 `X` 为所有其他用户添加权限。这次，大写的 `X`设置了该权限。

```
$ touch cap-X-file
$ ls -l cap-X-file
-rw-r--r--. 1 root root 0 Jun 12 06:31 cap-X-file
$ chmod g+x cap-X-file
$ ls -l cap-X-file
-rw-r-xr--. 1 root root 0 Jun 12 06:31 cap-X-file
$ chmod o+X cap-X-file
ls -l cap-X-file
-rw-r-xr-x. 1 root root 0 Jun 12 06:31 cap-X-file
```

### 理解 umask

`umask` 会屏蔽（或“阻止”）默认权限集中的位，以定义文件或目录的权限。例如，`umask`输出中的 `2` 表示它至少在默认情况下阻止了文件的“写入”位。

使用不带任何参数的 `umask` 命令可以使我们看到当前的 `umask` 设置。共有四列：第一列为特殊的`suid`、`sgid` 或粘滞位而保留，其余三列代表属主、组和其他人的权限。

```
$ umask
0022
```

为了理解这意味着什么，我们可以用 `-S` 标志来执行 `umask`（如下所示）以解释屏蔽位的结果。例如，由于第三列中的值为 `2`，因此将“写入”位从组和其他部分中屏蔽掉了；只能为它们分配“读取”和“执行”。

```
$ umask -S
u=rwx,g=rx,o=rx
```

要查看文件和目录的默认权限集是什么，让我们将 `umask` 设置为全零。这意味着我们在创建文件时不会掩盖任何位。

```
$ umask 000
$ umask -S
u=rwx,g=rwx,o=rwx

$ touch file-umask-000
$ ls -l file-umask-000
-rw-rw-rw-. 1 root root 0 Jul 17 22:03 file-umask-000
```

现在，当我们创建文件时，我们看到所有部分的默认权限分别为“读取”（`4`）和“写入”（`2`），相当于八进制表示 `666`。

我们可以对目录执行相同的操作，并看到其默认权限为 `777`。我们需要在目录上使用“执行”位，以便可以遍历它们。

```
$ mkdir dir-umask-000
$ ls -ld dir-umask-000
drwxrwxrwx. 2 root root 4096 Jul 17 22:03 dir-umask-000/
```

### 总结

管理员还有许多其他方法可以控制对系统文件的访问。这些权限是 Linux 的基本权限，我们可以在这些基础上进行构建。如果你的工作为你引入了 FACL 或 SELinux，你会发现它们也建立在这些文件访问的首要规则之上。

---

via: <https://opensource.com/article/19/8/linux-permissions-101>

作者：[Alex Juarez](https://opensource.com/users/mralexjuarezhttps://opensource.com/users/marcobravohttps://opensource.com/users/greg-p) 选题：[lujun9972](https://github.com/lujun9972) 译者：[wxy](https://github.com/wxy) 校对：[wxy](https://github.com/wxy)

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


6 款面向 Linux 用户的开源绘图应用程序

Summary: 既然你是一名 Linux 用户，为什么不关注一下开源绘图应用程序呢？

既然你是一名 Linux 用户，为什么不关注一下开源绘图应用程序呢？

# 6 款面向 Linux 用户的开源绘图应用程序

小时候，当我开始使用计算机（在 Windows XP 中）时，我最喜欢的应用程序是微软的“画图”。我能在它上面涂鸦数个小时。出乎意料，孩子们仍然喜欢这个“画图”应用程序。不仅仅是孩子们，这个简单的“画图”应用程序，在很多情况下都能派上用场。

你可以找到一堆可以让你绘制/绘图或操作图片的应用程序。然而，其中一些是专有软件。既然你是一名 Linux 用户，为什么不关注一下开源绘图应用程序呢？

在这篇文章中，我们将列出一些最好的开源绘图应用程序，它们可以替代可用于 Linux 的专有绘画软件。

### 开源绘图 & 绘制应用程序

**注意:** 该列表没有特别的排名顺序。

#### 1、Pinta

主要亮点：

* Paint.NET / 微软“画图”的极好替代品
* 支持附加组件（有对 WebP 图像的支持）
* 支持图层

[Pinta](https://pinta-project.com/pintaproject/pinta/) 是一款令人赞叹的开源绘图应用程序，非常适合绘图和简单的图片编辑。换句话说，它是一款具有精美功能的简单绘图应用程序。

你可以将 [Pinta](https://itsfoss.com/pinta-1-6-ubuntu-linux-mint/) 视为 Linux 上的“画图”的一个替代品，但是带有图层支持等等。不仅仅是“画图”，它也可以替代 Windows 上的 Paint.NET。尽管 Paint.NET 更好一些，但 Pinta 似乎是个不错的选择。

几个附加组件可以用于增强功能，例如[在 Linux 上支持 WebP 图像](https://itsfoss.com/webp-ubuntu-linux/)。除了图层支持之外，你还可以轻松地调整图片大小、添加特效、进行调整（亮度、对比度等等），以及在导出图片时调整其质量。

##### 如何安装 Pinta ？

你应该能够在软件中心/应用程序中心/软件包管理器中简单地找到它。只需要输入 “Pinta”，并开始安装它。要么也可以尝试 [Flatpak](https://www.flathub.org/apps/details/com.github.PintaProject.Pinta) 软件包。

或者，你可以在终端中输入下面的命令（Ubuntu/Debian）：

```
sudo apt install pinta
```

下载软件包和安装指南的更多信息，参考[官方下载页面](https://pinta-project.com/pintaproject/pinta/releases)。

#### 2、Krita

主要亮点：

* HDR 绘图
* 支持 PSD
* 支持图层
* 笔刷稳定器
* 二维动画

Krita 是 Linux 上最高级的开源绘图应用程序之一。当然，对于本文而言，它可以帮助你绘制草图和在画布上胡写乱画。除此之外，它还提供很多功能。

例如，如果你的手有点颤抖，它可以帮助你稳定笔刷的笔划。你可以使用内置的矢量工具来创建漫画画板和其它有趣的东西。如果你正在寻找具有全面的颜色管理支持、绘图助理和图层管理的软件，Krita 应该是你最好的选择。

##### 如何安装 Krita ？

类似于 pinta，你可以在软件中心/应用程序中心或软件包管理器的列表中找到它。它也可以 [Flatpak 存储库](https://www.flathub.org/apps/details/org.kde.krita)中找到。

考虑通过终端安装它？输入下面的命令：

```
sudo apt install krita
```

要么你也可以前往它们的[官方下载页面](https://krita.org/en/download/krita-desktop/)来获取 AppImage 文件并运行它。

如果你对 AppImage 文件一无所知，查看我们的指南 —— [如何使用 AppImage](https://itsfoss.com/use-appimage-linux/)。

#### 3、Tux Paint

主要亮点：

* 给儿童用的一个简单直接的绘图应用程序

我不是开玩笑，对于 3-12 岁儿童来说，Tux Paint 是最好的开源绘图应用程序之一。当然，当你只想乱画时，那无需选择，所以，在这种情况下，Tux Paint 似乎是最好的选择（即使是成年人！）。

##### 如何安装 Tuxpaint ？

Tuxpaint 可以从软件中心或软件包管理器下载。无论哪种情况，在 Ubuntu/Debian 上安装它，在终端中输入下面的命令：

```
sudo apt install tuxpaint
```

关于它的更多信息，前往[官方站点](http://www.tuxpaint.org/)。

#### 4、Drawpile

主要亮点：

* 协同绘制
* 内置聊天功能，可与其他用户互动
* 图层支持
* 记录绘制会话

Drawpile 是一个有趣的开源绘图应用程序，在该程序中，你可以与其他用户实时协作。确切地说，你们可以单个画布中同时绘制。除了这个独特的功能，它还有图层支持、记录绘制会话的能力，甚至还有与协作用户进行交互的聊天功能。

你可以主持或加入一个公共会话，或通过一个密码与你的朋友建立私有会话。默认情况下，服务器将是你的计算机，但是如果你需要远程服务器那也可以。

注意，你将需要[注册一个 Drawpile 账户](https://drawpile.net/accounts/signup/) 才能进行协作。

##### 如何安装 Drawpile ？

据我所知，你只能在 [Flatpak 存储库](https://flathub.org/apps/details/net.drawpile.drawpile)的列表中找到它。

#### 5、MyPaint

主要亮点：

* 易用的数码画家工具
* 支持图层管理
* 很多微调你的画笔和绘制的选项

对于数码画家来说，[MyPaint](https://mypaint.org/) 是一个简单而强大的工具。它具有许多选项，可以调整以制作出完美的数字画笔笔触。我不是一个数字艺术家（但我是一个涂鸦者），但是我注意到有很多调整笔刷、颜色的选项，和一个添加中间结果暂存器面板的选项。

它也支持图层管理，也许你需要它。最新的稳定版本已经有几年没有更新了，但是当前的 alpha 构建版本（我测试过）运行良好。如果你正在 Linux 上寻找一个开源绘图应用程序 —— 试试这个。

##### 如何安装 MyPaint ？

MyPaint 可在官方存储库中获得。然而，这是老旧的版本。如果你仍然想继续，你可以在软件中心搜索它，或在终端中输入下面的命令：

```
sudo apt install mypaint
```

你可以前往它的官方 [GitHub 发布页面](https://github.com/mypaint/mypaint/releases)获取最新的 alpha 构建版本，获取 [AppImage 文件](https://itsfoss.com/use-appimage-linux/)（任意版本）并使它可执行并启动应用程序。

#### 6、KolourPaint

主要亮点：

* 一个 Linux 上的“画图”的简单替代品
* 不支持图层管理

如果你不需要任何图层管理的支持，而只是想要一个开源绘图应用程序来绘制东西 —— 那就是它了。

[KolourPaint](http://kolourpaint.org/) 最初是为 KDE 桌面环境定制的，但是它在其它的桌面环境中也能完美地工作。

##### 如何安装 KolourPaint ？

你可以从软件中心安装 KolourPaint，或通过终端使用下面的命令：

```
sudo apt install kolourpaint4
```

你总可以试试 [Flathub](https://flathub.org/apps/details/org.kde.kolourpaint)。

### 总结

如果你在考虑如 GIMP/Inkscape 这样的应用程序，我们在另一篇关于[给数码艺术家的最好 Linux 工具](https://itsfoss.com/best-linux-graphic-design-software/)的文章中列出。如果你对更多的选择好奇，我建议你去查看它。

在这里，我们尝试编写一份 Linux 可用的最佳开源绘图应用程序列表。如果你认为我们错过一些东西，请在下面的评论区告诉我们！

---

via: <https://itsfoss.com/open-source-paint-apps/>

作者：[Ankush Das](https://itsfoss.com/author/ankush/) 选题：[lujun9972](https://github.com/lujun9972) 译者：[robsean](https://github.com/robsean) 校对：[wxy](https://github.com/wxy)

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


Chrome/Chromium 用户必知必会的 11 个基本快捷键

# Chrome/Chromium 用户必知必会的 11 个基本快捷键

>
> 掌握这些 Google Chrome 键盘快捷键，以获得更好、更流畅、更高效的 Web 浏览体验。还包括可下载的备忘单。
>
>
>

无可否认，Google Chrome 是[最受欢迎的网络浏览器](https://en.wikipedia.org/wiki/Usage_share_of_web_browsers)。它的开源版本 [Chromium](https://www.chromium.org/Home) 也越来越受欢迎，现在一些 Linux 发行版将其作为默认的网络浏览器。

如果你经常在台式机上使用它，则可以使用 Google Chrome 键盘快捷键来改善浏览体验。没有必要用你的鼠标移来移去、点来点去。只要掌握这些快捷方式，你可以节省一些时间并提高工作效率。

我这里使用的名称是 Google Chrome，但是这些快捷方式同样适用于 Chromium 浏览器。

### 你应该使用的 11 个酷炫的 Chrome 键盘快捷键

如果你是专业人士，可能已经知道其中一些 Chrome 快捷方式，但是有可能你仍然可以在这里找到一些隐藏的宝石。让我们来看看。

| **键盘快捷键** | **动作** |
| --- | --- |
| `Ctrl+T` | 打开一个新标签页 |
| `Ctrl+N` | 打开一个新窗口 |
| `Ctrl+Shift+N` | 打开一个新无痕式窗口 |
| `Ctrl+W` | 关闭当前标签页 |
| `Ctrl+Shift+T` | 重新打开上一个关闭的标签页 |
| `Ctrl+Shift+W` | 关闭窗口 |
| `Ctrl+Tab` 和 `Ctrl+Shift+Tab` | 切换到右侧或左侧的标签页 |
| `Ctrl+L` | 访问搜索/地址栏 |
| `Ctrl+D` | 将网址放入书签 |
| `Ctrl+H` | 访问浏览历史 |
| `Ctrl+J` | 访问下载历史 |
| `Shift+Esc` | 打开 Chrome 任务管理器 |

你可以[下载这份有用的 Chrome 键盘快捷键列表来作为快速参考](tmp.3qZNXSy2FC#download-cheatsheet)。

#### 1、用 `Ctrl+T` 打开一个新标签页

需要打开一个新标签页吗？只需同时按 `Ctrl` 和 `T` 键，你就会打开一个新标签。

#### 2、使用 `Ctrl+N` 打开一个新窗口

已经打开太多标签页？是时候打开一个新的窗口。使用 `Ctrl` 和 `N` 键打开一个新的浏览器窗口。

#### 3、使用 `Ctrl+Shift+N` 隐身

在线查询航班或酒店价格？隐身可能会有所帮助。使用 `Ctrl+Shift+N` 在 Chrome 中打开一个隐身窗口。

#### 4、使用 `Ctrl+W` 关闭标签页

使用 `Ctrl` 和 `W` 键关闭当前标签页。无需将鼠标移到顶部并寻找 `x` 按钮。

#### 5、不小心关闭了标签页？用 `Ctrl+Shift+T` 重新打开

这是我最喜欢的 Google Chrome 浏览器快捷方式。当你关闭了原本不想关的标签页时，就不用再懊悔了。使用 `Ctrl+Shift+T`，它将打开最后一个关闭的选项卡。继续按此组合键，它把关闭的选项卡再次打开。

#### 6、使用 `Ctrl+Shift+W` 关闭整个浏览器窗口

完成工作了吗？是时候关闭带有所有标签页的整个浏览器窗口了。使用 `Ctrl+Shift+W` 键，浏览器窗口将消失，就像以前不存在一样。

#### 7、使用 `Ctrl+Tab` 在标签之间切换

打开的标签页太多了吗？你可以使用 `Ctrl+Tab` 移至右侧标签页。想左移吗？使用 `Ctrl+Shift+Tab`。重复按这些键，你可以在当前浏览器窗口的所有打开的标签页之间移动。

你也可以使用 `Ctrl+0` 直到 `Ctrl+9` 转到前 10 个标签页之一。但是此 Chrome 键盘快捷键不适用于第 11 个及更多标签页。

#### 8、使用 `Ctrl+L` 转到搜索/地址栏

想要输入新的 URL 或快速搜索一些内容。你可以使用 `Ctrl+L`，它将在顶部突出显示地址栏。

#### 9、用 `Ctrl+D` 收藏当前网站

找到了有趣的东西？使用 `Ctrl+D` 组合键将其保存在书签中。

#### 10、使用 `Ctrl+H` 返回历史记录

你可以使用 `Ctrl+H` 键打开浏览器历史记录。如果你正在寻找前一段时间访问过的页面，或者删除你不想再看到的页面，可以搜索历史记录。

#### 11、使用 `Ctrl+J` 查看下载

在 Chrome 中按 `Ctrl+J` 键将带你进入下载页面。此页面将显示你执行的所有下载操作。

#### 意外惊喜：使用 `Shift+Esc` 打开 Chrome 任务管理器

很多人甚至都不知道 Chrome 浏览器中有一个任务管理器。Chrome 以消耗系统内存而臭名昭著。而且，当你打开大量标签时，找到罪魁祸首并不容易。

使用 Chrome 任务管理器，你可以查看所有打开的标签页及其系统利用率统计信息。你还可以看到各种隐藏的进程，例如 Chrome 扩展程序和其他服务。

### 下载 Chrome 快捷键备忘单

我知道掌握键盘快捷键取决于习惯，你可以通过反复使用使其习惯。为了帮助你完成此任务，我创建了此 Google Chrome 键盘快捷键备忘单。

你可以[下载以下 PDF 格式的图像](https://drive.google.com/open?id=1lZ4JgRuFbXrnEXoDQqOt7PQH6femIe3t)，进行打印并将其放在办公桌上。这样，你可以一直练习快捷方式。

如果你对掌握快捷方式感兴趣，还可以查看 [Ubuntu 键盘快捷键](https://itsfoss.com/ubuntu-shortcuts/)。

顺便问一下，你最喜欢的 Chrome 快捷方式是什么？

---

via: <https://itsfoss.com/google-chrome-shortcuts/>

作者：[Abhishek Prakash](https://itsfoss.com/author/abhishek/) 选题：[lujun9972](https://github.com/lujun9972) 译者：[wxy](https://github.com/wxy) 校对：[wxy](https://github.com/wxy)

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


如何拥有一个 Windows 10 和 Debian 10 的双系统

Summary: 在无数次劝说自己后，你终于做出了一个大胆的决定，试试 Linux。

是否要将 grub 的引导装载程序安装到主引导记录表（MBR）上？<br />
win10都是用UEFI的，还来MBR这套？

win10 的ubuntu子系统就挺好

win10 的ubuntu子系统就挺好

在无数次劝说自己后，你终于做出了一个大胆的决定，试试 Linux。

# 如何拥有一个 Windows 10 和 Debian 10 的双系统

在无数次劝说自己后，你终于做出了一个大胆的决定，试试 Linux。不过，在完全熟悉 Linux 之前，你依旧需要使用 Windows 10 系统。幸运的是，通过一个双系统引导设置，能让你在启动时，选择自己想要进入的系统。在这个指南中，你会看到如何 如何双重引导 Windows 10 和 Debian 10。

### 前提条件

在开始之前，确保你满足下列条件:

* 一个 Debian 10 的可引导 USB 或 DVD
* 一个快速且稳定的网络（为了安装更新以及第三方软件）

另外，记得注意你系统的引导策略（UEFI 或 Legacy），需要确保两个系统使用同一种引导模式。

### 第一步：在硬盘上创建一个空余分区

第一步，你需要在你的硬盘上创建一个空余分区。之后，这将是我们安装 Debian 系统的地方。为了实现这一目的，需要使用下图所示的磁盘管理器：

同时按下 `Windows + R` 键，启动“运行程序”。接下来，输入 `diskmgmt.msc`，按回车键。

这会启动“磁盘管理”窗口，它会显示你 Windows 上所有已有磁盘。

接下来，你需要为安装的 Debian 系统创建空余空间。为此，你需要缩小其中一个磁盘（卷）上的分区，从而创建一个未分配的新分区。在这个例子里，我会从 D 盘中创建一个 30 GB 的新分区。

为了缩小一个卷，右键点击它，然后选中选项 “<ruby> 缩小 <rt>  Shrink volume… </rt></ruby>”。

在弹出窗口中，定义你想缩小的空间大小。记住，这是将来要安装 Debian 10 的磁盘空间。我选择了 30000MB（大约 30 GB）。压缩完成后，点击“<ruby> 缩小 <rt>  Shrink </rt></ruby>”。

在缩小操作结束后，你会看到一个如下图所示的未分配分区：

完美！现在可以准备开始安装了。

### 第二步：开始安装 Debian 10

空余分区已经创建好了，将你的可引导 USB 或安装 DVD 插入电脑，重新启动系统。记得更改 BIOS 中的引导顺序，需要在启动时按住功能键（通常，根据品牌不同，是 `F9`、`F10` 或 `F12` 中的某一个）。 这一步骤，对系统是否能进入安装媒体来说，至关重要。保存 BIOS 设置，并重启电脑。

如下图所示，界面会显示一个新的引导菜单：点击 “Graphical install”。

下一步，选择你的偏好语言，然后点击 “<ruby> 继续 <rt>  Continue </rt></ruby>”。

接着，选择你的地区，点击“<ruby> 继续 <rt>  Continue </rt></ruby>”。 根据地区，系统会自动选择当地对应的时区。如果你无法找到你所对应的地区，将界面往下拉， 点击“<ruby> 其他 <rt>  Other </rt></ruby>”后，选择相对应位置。

而后，选择你的键盘布局。

接下来，设置系统的主机名，点击 “<ruby> 继续 <rt>  Continue </rt></ruby>”。

下一步，确定域名。如果你的电脑不在域中，直接点击 “<ruby> 继续 <rt>  Continue </rt></ruby>”按钮。

然后，如图所示，设置 root 密码，点击 “<ruby> 继续 <rt>  Continue </rt></ruby>”。

下一步骤，设置账户的用户全名，点击 “<ruby> 继续 <rt>  Continue </rt></ruby>”。

接着，设置与此账户相关联的用户名。

下一步，设置用户密码，点击“<ruby> 继续 <rt>  Continue </rt></ruby>”。

然后，设置时区。

这时，你要为 Debian10 安装创建分区。如果你是新手用户，点击菜单中的第一个选项，“<ruby> 使用最大的连续空余空间 <rt>  Use the largest continuous free space </rt></ruby>”，点击“<ruby> 继续 <rt>  Continue </rt></ruby>”。

不过，如果你对创建分区有所了解的话，选择“<ruby> 手动 <rt>  Manual </rt></ruby>” 选项，点击 “<ruby> 继续 <rt>  Continue </rt></ruby>”。

接着，选择被标记为 “<ruby> 空余空间 <rt>  FREE SPACE </rt></ruby>” 的磁盘，点击 “<ruby> 继续 <rt>  Continue </rt></ruby>” 。接下来，点击“<ruby> 创建新分区 <rt>  Create a new partition </rt></ruby>”。

下一界面，首先确定交换空间大小。我的交换空间大小为 2GB，点击 “<ruby> 继续 <rt>  Continue </rt></ruby>”。

点击下一界面的 “<ruby> 主分区 <rt>  Primary </rt></ruby>”，点击“<ruby> 继续 <rt>  Continue </rt></ruby>”。

选择在磁盘 “<ruby> 初始位置 <rt>  beginning </rt></ruby>” 创建新分区后，点击继续。

选择 “<ruby> Ext 4 日志文件系统 <rt>  Ext 4 journaling file system </rt></ruby>”，点击 “<ruby> 继续 <rt>  Continue </rt></ruby>”。

下个界面选择“<ruby> 交换空间 <rt>  swap space </rt></ruby>” ，点击 “<ruby> 继续 <rt>  Continue </rt></ruby>”。

选中 “<ruby> 完成此分区设置 <rt>  done setting the partition </rt></ruby>”，点击 “<ruby> 继续 <rt>  Continue </rt></ruby>”。

返回磁盘分区界面，点击 “<ruby> 空余空间 <rt>  FREE SPACE </rt></ruby>”，点击 “<ruby> 继续 <rt>  Continue </rt></ruby>”。

为了让自己能轻松一点，选中 “<ruby> 自动为空余空间分区 <rt>  Automatically partition the free space </rt></ruby>”后，点击 “<ruby> 继续 <rt>  Continue </rt></ruby>”。

接着点击 “<ruby> 将所有文件存储在同一分区（新手用户推荐） <rt>  All files in one partition (recommended for new users) </rt></ruby>”。

最后， 点击 “<ruby> 完成分区设置，并将改动写入磁盘 <rt>  Finish partitioning and write changes to disk </rt></ruby>” ，点击 “<ruby> 继续 <rt>  Continue </rt></ruby>”。

确定你要将改动写入磁盘，点击 “<ruby> 是 <rt>  Yes </rt></ruby>”。

而后，安装程序会开始安装所有必要的软件包。

当系统询问是否要扫描其他 CD 时，选择 “<ruby> 否 <rt>  No </rt></ruby>” ，并点击 “<ruby> 继续 <rt>  Continue </rt></ruby>”。

接着，选择离你最近的镜像站点地区，点击 “<ruby> 继续 <rt>  Continue </rt></ruby>”。

然后，选择最适合你的镜像站点，点击“<ruby> 继续 <rt>  Continue </rt></ruby>”。

如果你打算使用代理服务器，在下面输入具体信息，没有的话就留空，点击 “<ruby> 继续 <rt>  Continue </rt></ruby>”。

随着安装进程的继续， 你会被问到，是否想参加一个软件包用途调查。你可以选择任意一个选项，之后点击“<ruby> 继续 <rt>  Continue </rt></ruby>”，我选择了“<ruby> 否 <rt>  No </rt></ruby>”。

在软件选择窗口选中你想安装的软件包，点击“<ruby> 继续 <rt>  Continue </rt></ruby>”。

安装程序会将选中的软件一一安装，在这期间，你可以去喝杯咖啡休息一下。

系统将会询问你，是否要将 grub 的引导装载程序安装到主引导记录表（MBR）上。点击 “<ruby> 是 <rt>  Yes </rt></ruby>”，而后点击 “<ruby> 继续 <rt>  Continue </rt></ruby>”。

接着，选中你想安装 grub 的硬盘，点击“<ruby> 继续 <rt>  Continue </rt></ruby>”。

最后，安装完成，直接点击 “<ruby> 继续 <rt>  Continue </rt></ruby>”。

你现在应该会有一个列出 Windows 和 Debian 的 grub 菜单。为了引导 Debian 系统，往下选择 Debian。之后，你就能看见登录界面。输入密码之后，按回车键。

这就完成了！这样，你就拥有了一个全新的 Debian 10 和 Windows 10 双系统。

---

via: <https://www.linuxtechi.com/dual-boot-windows-10-debian-10/>

作者：[James Kiarie](https://www.linuxtechi.com/author/james/) 选题：[lujun9972](https://github.com/lujun9972) 译者：[wenwensnow](https://github.com/wenwensnow) 校对：[wxy](https://github.com/wxy)

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


低价 Linux 智能手机 PinePhone 即将接受预订

Summary: 好消息是 PinePhone 将从 11 月 15 日开始接受预订。

昨天晚上在Ubuntu touch 那看了下，新支持的手机型号，linux.cn就碰到这篇文章，鼓励我换个gnu/linux的手机吗！~?  haha:):)

用安卓就是 支持 linux 手机了，是不是  gnu 应该是RMS该关心的事

来自湖北武汉的 Chrome Mobile 62.0|Android 7.1 用户

好消息是 PinePhone 将从 11 月 15 日开始接受预订。

# 低价 Linux 智能手机 PinePhone 即将接受预订

你还记得[在 2017 年首次披露](https://itsfoss.com/pinebook-kde-smartphone/)的 Pine64 正在开发一个基于 Linux（可以运行 KDE Plasma 及其他发行版）的智能手机的事情吗？从那以后已经有一段时间了，但是好消息是 PinePhone 将从 11 月 15 日开始接受预订。

让我来为你提供有关 PinePhone 的更多详细信息，例如其规格、价格和发布日期。

### PinePhone：基于 Linux 的廉价智能手机

PinePhone 开发者套件已经经过了一些开发人员的测试，更多此类套件将于 11 月 15 日发货。你可以查看下面的照片：

开发者套件是由 PINE A64 基板 + SOPine 模块 + 7 英寸触摸屏显示器 + 摄像头 + Wifi / BT + 外壳 + 锂离子电池盒 + LTE cat 4 USB 软件狗组成的组合套件。

这些组合套件可以使开发人员快速开始 PinePhone 开发。由于 PINE64 社区和 [KDE neon](https://neon.kde.org/) 的支持，主线 Linux 操作系统已经可以在 PINE A64 平台上构建。

#### PinePhone 规格

* Allwinner A64 四核 SoC，带有 Mali 400 MP2 GPU
* 2GB 的 LPDDR3 RAM
* 5.95 英寸 LCD 1440×720，长宽比 18：9（钢化玻璃）
* 可启动的 Micro SD
* 16GB eMMC
* 高清数字视频输出
* USB Type-C（电源、数据和视频输出）
* Quectel EG-25G 全球波段
* WiFi：802.11 b/g/n，单频，支持热点
* 蓝牙：4.0，A2DP
* GNSS：GPS，GPS-A，GLONASS
* 振动器
* RGB 状态 LED
* 自拍和主摄像头（分别为 2/5 Mpx）
* 主摄像头：单颗 OV6540、5MP，1/4 英寸，LED 闪光灯
* 自拍相机：单 GC2035、2MP，f/2.8、1/5 英寸
* 传感器：加速器、陀螺仪、距离感应器、罗盘、气压计、环境光感
* 3 个外部开关：上、下和电源
* 硬件开关：LTE/GNSS、WiFi、麦克风、扬声器、USB
* 三星 J7 外形尺寸 3000mAh 电池
* 外壳是磨砂黑色成品塑料
* 耳机插孔

#### 产品、价格和交付时间

PinePhone 的价格约为 150 美元。尝鲜版命名为“勇敢的心”，将于 2019 年 11 月 15 日开始销售。如上图所示，[Pine64 的主页](https://www.pine64.org/)包含了用于首次预订 PinePhone 的计时器。

预期“勇敢的心”尝鲜版在 2019 年 12 月或 2020 年 1 月之前发货。

大规模生产将在中国的农历新年后开始，也就是说在 2020 年第二季度早期或最早 2020 年 3 月开始。

该电话尚未在 Pine Store 中列出，因此，如果你想成为尝鲜者之一，请务必查看 [Pine64 在线商店](https://store.pine64.org/)以预订“勇敢的心”版本。

#### 你对 PinePhone 如何看？

Pine64 已经开发了一款名为 [Pinebook](https://itsfoss.com/pinebook-linux-notebook/) 的廉价笔记本电脑和一款功能相对强大的 [Pinebook Pro](https://itsfoss.com/pinebook-pro/) 笔记本电脑。因此，PinePhone 至少在 DIY 爱好者和 Linux 忠实拥护者的狭窄市场中绝对有希望获得成功。与其他价格超过 600 美元的 [Linux 智能手机 Librem5](https://itsfoss.com/librem-linux-phone/) 相比，低廉的价格绝对是一个巨大的优势。

PinePhone 的另一个优点是，你可以通过安装 Ubuntu Touch、Plasma Mobile 或 Aurora OS/Sailfish OS 来试验操作系统。

这些基于 Linux 的智能手机尚不具备取代 Android 或 iOS 的功能。如果你正在寻找功能全面的智能手机来替代你的 Android 智能手机，那么 PinePhone 当然不适合你。但对于喜欢尝试并且不害怕排除故障的人来说，它的优势更大。

如果你想购买 PinePhone，请记住这个日期并设置提醒。供应应该是限量的，到目前为止，我所了解的，Pine 设备很快就会脱销。

你要预订 PinePhone 吗？在评论部分将你的意见告知我们。

---

via: <https://itsfoss.com/pinephone/>

作者：[Ankush Das](https://itsfoss.com/author/ankush/) 选题：[lujun9972](https://github.com/lujun9972) 译者：[wxy](https://github.com/wxy) 校对：[wxy](https://github.com/wxy)

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


在 Fedora 上优化 bash 或 zsh

# 在 Fedora 上优化 bash 或 zsh

本文将向你展示如何在 Fedora 的命令行解释器（CLI）Shell 中设置一些强大的工具。如果使用bash（默认）或zsh，Fedora 可让你轻松设置这些工具。

### 前置需求

这需要一些已安装的软件包。在 Fedora 工作站上，运行以下命令：

```
sudo dnf install git wget curl ruby ruby-devel zsh util-linux-user redhat-rpm-config gcc gcc-c++ make
```

在 Silverblue 上运行：

```
sudo rpm-ostree install git wget curl ruby ruby-devel zsh util-linux-user redhat-rpm-config gcc gcc-c++ make
```

注意：在 Silverblue 上，你需要重新启动才能继续。

### 字体

你可以通过安装新字体使终端焕然一新。为什么不使用可以同时显示字符和图标的字体呢？

#### Nerd-Fonts

打开一个新终端，然后键入以下命令：

```
git clone https://github.com/ryanoasis/nerd-fonts ~/.nerd-fonts
cd .nerd-fonts
sudo ./install.sh
```

#### Awesome-Fonts

在工作站上，使用以下命令进行安装：

```
sudo dnf fontawesome-fonts
```

在 Silverblue 上键入：

```
sudo rpm-ostree install fontawesome-fonts
```

### Powerline

Powerline 是 vim 的状态行插件，并为其他几个应用程序也提供了状态行和提示符，包括 bash、zsh、tmus、i3、Awesome、IPython 和 Qtile。你也可以在官方[文档站点](https://powerline.readthedocs.io/en/latest/)上找到更多信息。

#### 安装

要在 Fedora 工作站上安装 Powerline 实用程序，请打开一个新终端并运行：

```
sudo dnf install powerline vim-powerline tmux-powerline powerline-fonts
```

在 Silverblue 上，命令更改为：

```
sudo rpm-ostree install powerline vim-powerline tmux-powerline powerline-fonts
```

注意：在 Silverblue 上，你需要重新启动才能继续。

#### 激活 Powerline

要使 Powerline 默认处于活动状态，请将下面的代码放在 `~/.bashrc` 文件的末尾：

```
if [ -f `which powerline-daemon` ]; then
  powerline-daemon -q
  POWERLINE_BASH_CONTINUATION=1
  POWERLINE_BASH_SELECT=1
  . /usr/share/powerline/bash/powerline.sh
fi
```

最后，关闭终端并打开一个新终端。它看起来像这样：

### Oh-My-Zsh

[Oh-My-Zsh](https://ohmyz.sh) 是用于管理 Zsh 配置的框架。它捆绑了有用的功能、插件和主题。要了解如何将 Zsh 设置为默认外壳程序，请参见[这篇文章](https://fedoramagazine.org/set-zsh-fedora-system/)。

#### 安装

在终端中输入：

```
sh -c "$(curl -fsSL https://raw.github.com/robbyrussell/oh-my-zsh/master/tools/install.sh)"
```

或者，你也可以输入以下内容：

```
sh -c "$(wget https://raw.github.com/robbyrussell/oh-my-zsh/master/tools/install.sh -O -)"
```

最后，你将看到如下所示的终端：

恭喜，Oh-my-zsh 已安装成功。

#### 主题

安装后，你可以选择主题。我喜欢使用 powerlevel10k。优点之一是它比 powerlevel9k 主题快 100 倍。要安装它，请运行以下命令行：

```
git clone https://github.com/romkatv/powerlevel10k.git ~/.oh-my-zsh/themes/powerlevel10k
```

并在你的 `~/.zshrc` 文件设置 `ZSH_THEME`：

```
ZSH_THEME=powerlevel10k/powerlevel10k
```

关闭终端。再次打开终端时，powerlevel10k 配置向导将询问你几个问题以正确配置提示符。

完成 powerline10k 配置向导后，你的提示符将如下所示：

如果你不喜欢它。你可以随时使用 `p10k configure` 命令来运行 powerline10k 向导。

#### 启用插件

插件存储在 `.oh-my-zsh/plugins` 文件夹中。要激活插件，你需要编辑 `~/.zshrc` 文件。安装插件意味着你创建了一系列执行特定功能的别名或快捷方式。

例如，要启用 firewalld 和 git 插件，请首先编辑 `~/.zshrc`：

```
plugins=(firewalld git)
```

注意：使用空格分隔插件名称列表。

然后重新加载配置：

```
source ~/.zshrc
```

要查看创建的别名，请使用以下命令：

```
alias | grep firewall
```

#### 更多配置

我建议安装语法高亮和语法自动建议插件。

```
git clone https://github.com/zsh-users/zsh-syntax-highlighting.git ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-syntax-highlighting
git clone https://github.com/zsh-users/zsh-autosuggestions ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-autosuggestions
```

将它们添加到文件 `~/.zshrc` 的插件列表中。

```
plugins=( [plugins...] zsh-syntax-highlighting zsh-autosuggestions)
```

重新加载配置。

```
source ~/.zshrc
```

查看结果：

### 彩色的文件夹和图标

`colorls` 是一个 ruby gem，可使用颜色和超棒的字体图标美化终端的 `ls` 命令。你可以访问官方[网站](https://github.com/athityakumar/colorls)以获取更多信息。

因为它是个 ruby gem，所以请按照以下简单步骤操作：

```
sudo gem install colorls
```

要保持最新状态，只需执行以下操作：

```
sudo gem update colorls
```

为防止每次输入 `colorls`，你可以在 `~/.bashrc` 或 `~/.zshrc` 中创建别名。

```
alias ll='colorls -lA --sd --gs --group-directories-first'
alias ls='colorls --group-directories-first'
```

另外，你可以为 `colorls` 的选项启用制表符补完功能，只需在 shell 配置末尾输入以下行：

```
source $(dirname ($gem which colorls))/tab_complete.sh
```

重新加载并查看会发生什么：

---

via: <https://fedoramagazine.org/tuning-your-bash-or-zsh-shell-in-workstation-and-silverblue/>

作者：[George Luiz Maluf](https://fedoramagazine.org/author/georgelmaluf/) 选题：[lujun9972](https://github.com/lujun9972) 译者：[wxy](https://github.com/wxy) 校对：[wxy](https://github.com/wxy)

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


确认了！微软 Edge 浏览器将发布 Linux 版

Summary: 微软正在全面重制其 Edge Web 浏览器，它将基于开源 Chromium 浏览器。微软还要将新的 Edge 浏览器带到 Linux 桌面上，但是 Linux 版本可能会有所延迟。

# 确认了！微软 Edge 浏览器将发布 Linux 版

>
> 微软正在全面重制其 Edge Web 浏览器，它将基于开源 [Chromium](https://itsfoss.com/install-chromium-ubuntu/) 浏览器。微软还要将新的 Edge 浏览器带到 Linux 桌面上，但是 Linux 版本可能会有所延迟。
>
>
>

微软的 Internet Explorer 曾经一度统治了浏览器市场，但在过去的十年中，它将统治地位丢给了谷歌的 Chrome。

微软试图通过创造 Edge 浏览器来找回失去的位置，Edge 是一种使用 EdgeHTML 和 [Chakra 引擎](https://itsfoss.com/microsoft-chakra-core/)构建的全新 Web 浏览器。它与 Microsoft 的数字助手 [Cortana](https://www.microsoft.com/en-in/windows/cortana) 和 Windows 10 紧密集成。

但是，它仍然无法夺回冠军位置，截至目前，它处于[桌面浏览器使用份额的第四位](https://en.wikipedia.org/wiki/Usage_share_of_web_browsers)。

最近，微软决定通过基于[开源 Chromium 项目](https://www.chromium.org/Home)重新对 Edge 进行大修。谷歌的 Chrome 浏览器也是基于 Chromium 的。[Chromium 还可以作为独立的 Web 浏览器使用](https://itsfoss.com/install-chromium-ubuntu/)，某些 Linux 发行版将其用作默认的 Web 浏览器。

### Linux 上新的微软 Edge Web 浏览器

经过最初的犹豫和不确定性之后，微软似乎最终决定把新的 Edge 浏览器引入到 Linux。

在其年度开发商大会 [Microsoft Ignite](https://www.microsoft.com/en-us/ignite) 中，[关于 Edge 浏览器的演讲](https://myignite.techcommunity.microsoft.com/sessions/79341?source=sessions)中提到了它未来将进入 Linux 中。

新的 Edge 浏览器将于 2020 年 1 月 15 日发布，但我认为 Linux 版本会推迟。

### 微软 Edge 进入 Linux 真的重要吗？

微软 Edge 进入 Linux 有什么大不了的吗？我们又不是没有很多[可用于 Linux 的 Web 浏览器](https://itsfoss.com/open-source-browsers-linux/)？

我认为这与 “微软 Linux 竞争”（如果有这样的事情）有关。微软为 Linux（特别是 Linux 桌面）做的任何事情，都会成为新闻。

我还认为 Linux 上的 Edge 对于微软和 Linux 用户都有好处。这就是为什么。

#### 对于微软有什么用？

当谷歌在 2008 年推出其 Chrome 浏览器时，没有人想到它会在短短几年内占领市场。但是，为什么作为一个搜索引擎会在一个“免费的 Web 浏览器”后面投入如此多的精力呢？

答案是谷歌是一家搜索引擎，它希望有更多的人使用其搜索引擎和其他服务，以便它可以从广告服务中获得收入。使用 Chrome，Google 是默认的搜索引擎。在 Firefox 和 Safari 等其他浏览器上，谷歌支付了数亿美元作为默认 Web 浏览器的费用。如果没有 Chrome，则谷歌必须完全依赖其他浏览器。

微软也有一个名为 Bing 的搜索引擎。Internet Explorer 和 Edge 使用 Bing 作为默认搜索引擎。如果更多用户使用 Edge，它可以增加将更多用户带到 Bing 的机会。而微软显然希望拥有更多的 Bing 用户。

#### 对 Linux 用户有什么用？

对于 Linux 桌面用户，我看到有两个好处。借助 Edge，你可以在 Linux 上使用某些微软特定的产品。 例如，微软的流式游戏服务 [xCloud](https://www.pocket-lint.com/games/news/147429-what-is-xbox-project-xcloud-cloud-gaming-service-price-release-date-devices) 可能仅能在 Edge 浏览器上使用。另一个好处是提升了 [Linux 上的 Netflix 体验](https://itsfoss.com/watch-netflix-in-ubuntu-linux/)。当然，你可以在 Linux 上使用 Chrome 或 [Firefox 观看 Netflix](https://itsfoss.com/netflix-firefox-linux/)，但可能无法获得全高清或超高清流。

据我所知，[全高清和超高清 Netflix 流仅在微软 Edge 上可用](https://help.netflix.com/en/node/23742)。这意味着你可以使用 Linux 上的 Edge 以高清格式享受 Netflix。

### 你怎么看？

你对微软 Edge 进入 Linux 有什么感觉？当 Linux 版本可用时，你会使用吗？请在下面的评论部分中分享你的观点。

---

via: <https://itsfoss.com/microsoft-edge-linux/>

作者：[Abhishek Prakash](https://itsfoss.com/author/abhishek/) 选题：[lujun9972](https://github.com/lujun9972) 译者：[wxy](https://github.com/wxy) 校对：[wxy](https://github.com/wxy)

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


酌一杯云之酒，以开源佐之 ——专访灵雀云陈恺

# 酌一杯云之酒，以开源佐之 ——专访灵雀云陈恺

>
> 在云原生技术实践峰会召开前夕，匆匆奔赴北京的我，见到了刚刚从美国飞回来，却毫无时差之扰的陈恺——灵雀云的 CTO。
>
>
>

虽然我早就和灵雀云有了联系，也有好几位朋友在灵雀云任职，不过作为国内新锐云原生厂商灵雀云的创始人之一的陈恺，我之前并没有直接接触过。虽然我们是初次相识，但是在聊到了开源，聊到云技术，我们以云做老酒，以开源为佐酒菜，很快就俨然如同老友般进入了旁若无人的状态——旁边的朋友被我们暂时性忽视了，虽然这张合影就是她帮我们照的。 :D

滥觞始于云计算。

### 缘起

陈恺和左玥等人在创立灵雀云之前，他们都曾在微软 Azure 从事云计算领域的专业研究。回忆起那时候，陈恺说，那时他们也在想象云里面的应用应该长什么样子，设计最早版本的“云服务模型”、“云服务运行时”，而现在回过头看，其实云计算的发展已经千差万别。

2013 年 Docker 出现以后，左玥和陈恺他们第一时间就意识到容器技术会很有影响力，它重新了定义云技术之后发展的路径，这恍然在他们面前掀开了一个新的时代，于是灵雀云诞生了。

云技术领域发展演变的非常快，事实上，在云计算早期并不能预见到如今的云计算格局。“早期我们尝试过很多东西，总的想法是觉得容器就像是一种轻量级虚拟机，一种新的虚拟化技术。就像虚拟机需要虚拟机平台去作为它的管理平台一样，容器也需要一个容器云平台，所以我们早期想做的就是容器云平台，这一点一直没变，现在也是在做企业级的容器平台。”陈恺说，“我们最早的技术选型是 Mesos 技术栈，经历了几次大的改变，包括从 Mesos 转到支持当时的三种主流的调度系统，然后开始倾向于Kubernetes，到最后全面转向 Kubernetes，以及最近在架构上和 Kubernetes全面对齐，把我们的平台做成一个 Kubernetes 原生的平台，技术上一直在做升级。”

### 云原生吞噬一切，Kubernetes 编排一切

不知不觉之间，云原生已经吞噬了整个世界，如今，云原生已经是技术界最时髦的词汇之一。而应运而生并推动了这一切发生的云原生计算基金会（CNCF）也在不同的时期、不同的场所，对云原生做了不同角度的解读。那么作为一家很早就涉入云计算领域的新锐力量，陈恺对云原生的理解是什么呢？

陈恺说，“CNCF 旗下涵盖这么多云计算的技术、产品和服务，所以它对‘云原生’的定义必然会比较宽泛，但的确，‘云原生’不是一个特定的技术或者一种方法，很难把它精确的定义，也不应该把它和具体的技术对等，比如说把它直接跟 Kubernetes 挂钩，跟 Kubernetes 没关系就不是云原生？跟 Kubernetes 有关系就叫云原生？这两者都是不对的。”

他接着补充说，“我对云原生定义的观点也是比较宽泛的，（云原生）就是**让应用能够最大化的释放云计算生产力的一系列的思维方式、最佳实践和技术体系**，这里的关键词是**让应用去释放云计算最大的生产力**。这是关键。所有的云原生我觉得都是首先应该围绕应用的。什么叫‘云原生’？主要是以应用为中心的。‘原生’这个名字看起来起的不是很好，听上去似乎是只有在云上生出来的才叫‘云原生’，或者只有在公有云上才叫‘云原生’，并不是。关键不是说你在哪里跑你的应用，而是你是不是能够释放云的生产力——广义的云的生产力。”

在容器编排市场尚三分天下的时候，很多容器服务商都同时支持三种主流的编排系统，当时有一些观点认为这种三分格局会持续比较久，然而 Kubernetes 迅速崛起，很快就一家独大地统治了容器编排市场。

陈恺说，“我觉得当时 Kubernetes 可以很快的从编排之争当中胜出，并没有那么让人吃惊。为什么我们比较早的时候就开始往 Kubernetes 发力？其实第一个触发的点比较偶然。那时经常会有人问起三种容器编排系统各自的优势是什么？我们做了一些研究，业界有一些对比，当时我印象比较深的是一个细节，我觉得这才是关键——有一项对比的是基于这三种技术有哪些商业版？基于 Docker Swarm 的有一个商业版 Docker EE；Mesos 有一个商业版 MesosPhere；基于 Kubernetes 有**好多**商业版——这是本质的区别。这一点对它们的社区的发展速度和后续影响很广，因为它是开放式的治理。Kubernetes 虽然是谷歌发明的，但是它是开放式治理，背后有很多商业版。如果从开源软件本身社区发展角度看，很关键一点是上面有多少商业版，商业版越多说明从开源软件里面可以获利的公司越多，这样就有了正向的良性循环，会有更多资源投进来，社区里面参与的人就会更多，最后的发展会更好，生态会很繁荣。当时从这一点我们就觉得这个生态肯定会赢。”

Kubernetes 一统容器编排市场的今天，业界一些专家对此有所忧虑，担心这种垄断会形成市场压制。从长期来看，如果 Kubernetes 的发展会形成类似 Android 一样的巨头化，那么作为下游厂商，灵雀云是如何看待和应对这种发展变化的呢？

陈恺说，“回到垄断这个问题，如果是商业软件的话会有垄断这个问题，如果是开源软件的话，它的治理模式有可能是封闭式的，也有可能是开放式的，而 Kubernetes 是一个开放式的治理模式，会有一些厂商有更大的影响力，但不是被一家完全控制，所以我觉得从这个角度来说，谈不上垄断，更多的是一个标准。它可能更多像 Linux 而不像是 Android。从标准的角度来说，肯定是利大于弊，而且是远大于弊。因为有了标准，大家都围绕着标准做投入，风险就大大降低，可以放心去投入，也就会有越来越多的技术厂商会向它靠拢。”

### 灵雀云的 Kubernetes 生态

灵雀云在围绕 Kubernetes 生态方面也做了自己的发行版，他们是如何在符合 Kubernetes 标准的基础上形成差异化的服务和产品的呢？

“Kubernetes 发行版首先必须是跟 Kubernetes 兼容的。在 Kubernetes 上可以增加各种各样的能力，但它本身的第一属性一定是一个真正的 Kubernetes。如果为了做差异性，把它做得不像 Kubernetes，不兼容会是个很大的问题。”陈恺说，“我们走的比这个更深一步，我们的 ACP 2.0 是把整个平台都做成 Kubernetes 原生的，因为 Kubernetes 本质上是声明式 API 加上基于控制器模型的架构设计范式，容器编排相当于它的一个副产品，是它基于这个架构的一种应用，当然也可以把这种架构应用到对任意资源的编排。前一段时间有一篇很多人转发的《[Kubernetes 编排一切](/article-11565-1.html)》的文章，讲的就是这个事情，它不光可以用来编排容器，可以做各种各样的事情。我很赞同这个观点。”

灵雀云是从 2017 年底的时候决定这样做的，当时的做法是一些新的产品开始在新的架构上做一些实践，比如 DevOps 平台、基于 Istio 的 Service Mesh 等产品，完全基于新的架构来做。今年年初，灵雀云认为所有方面都成熟了：第一，方向肯定没问题，Kubernetes 编排一切；第二，对如何基于 Kubernetes 的架构构建上层产品有了更多的经验和体会。灵雀云于是把以前产品上的所有功能都逐渐迁移到 Kubernetes 原生架构上，重新融合到统一的架构里面，这就是 ACP 2.0。在此之上灵雀云还做了一些差异化。

灵雀云在这里的技术栈分为三层：

最底层的产品是一个 Kubernetes 发行版，Kubernetes 是一个开源的技术，并不是一个平台，大多数企业做不到直接把它当一个平台用。灵雀云的做法是将 Kubernetes 技术变成一个企业就绪的 Kubernetes 发行版。

再往上是 ACP 层，定位是云原生应用赋能平台。包含有三个子产品：容器平台、DevOps 平台和基于 Istio 的 Service Mesh 产品。容器平台和发行版最接近，但对发行版进行了大量扩展，比如在发行版之上增加了多集群管理和企业级多租户。ACP 把单一的 Kubernetes 集群变成企业平台级的产品，经过了三年多 100+ 企业客户生产环境的考验，而且考虑到更多开发者的场景。DevOps 也基于 Kubernetes 原生，用 Kubernetes 去编排所有的工具，定位是一个开放式 DevOps 工具链集成和编排的平台。

在此之上还有一层是灵雀云新的 ACE 3.0，它的定位是一个企业级的 PaaS 平台，或者用现在更时髦的说法，可以称之为企业技术中台，集成了更多企业需要的其他服务，比如第三方的中间件、开发框架等。它是个完整的技术中台，以容器平台为底座，以云原生黄金三角为核心，其他服务在上面做成一个个插件。这部分主要是和生态合作伙伴合作，国内外的一些最优秀的 PaaS 类服务都可以放在里面，为企业提供完整的解决方案。

### 云原生之于微服务和 DevOps

我们知道微服务、DevOps 等模式在云原生概念发展起来之前就已经存在，但是随着云原生的发展，似乎给它们注入了更多的活力。

陈恺认为云原生显著地推动了 DevOps、微服务的发展，对于这一现象他还专门用了一个词汇来形容：**后 Kubernetes**。这是在容器和 Kubernetes 出现之后开始对 DevOps 侧的微服务反过来的助推。

他认为，微服务架构的本质是用运维复杂度为代价去换取敏捷性。企业至少要考虑两件事：第一是否真的有这么高的敏捷性需求，值得用那么大的运维代价去替换，第二，假设你有着敏捷性需求，那么多出来的复杂度怎么办？早期微服务落地会很痛苦，因为大家没有准备好怎么去应付这个复杂度，而且会低估它。这复杂度是未知的，用未知的复杂度去替代已知的复杂度，这通常都是不好的，所以才会有各种各样的治理框架出来。其实它需要底下有一个好的基础设施来支撑它。

容器和微服务天生一对，容器 Kubernetes 的出现，对微服务有非常明显地推动。Kubernetes 作为底层的应用管理平台非常合适，而且很多微服务里面要考虑的与业务无关的能力也可以慢慢推到 Kubernetes 里面去。而进一步，Service Mesh 等其上的技术栈就重新定义了微服务技术栈，微服务治理方式发生了变化，反过来作用到微服务上，形成了新的最佳实践。

因此，要做微服务应该先容器化，才能解决运维复杂度的问题，容器化的服务应该跑在 Kubernetes 之上；如果进一步做服务治理，应该往 Service Mesh 方向走，Service Mesh 是基于 Kubernetes 平台的微服务治理的最佳实践。

云原生之于 DevOps 也是如此。早期大家很多的精力在持续集成上面，比如 Jenkins 最初是作为 CI 工具出现的，而有了容器和 Kubernetes 之后，持续集成变得简化了，最终生成 Docker 镜像就好。重心开始转到部署，转到 CD 上。而且，现在的 DevOps 实践或 CI/CD 通常会把 Kubernetes 作为最重要的部署目标。也就是说CI会围绕容器镜像，CD 会围绕 Kubernetes。这是容器和 Kubernetes 带给 DevOps 的影响，基础设施越强大，对 DevOps、微服务就越有帮助。以 Kubernetes 为核心的基础设施变成新的标准，DevOps 和微服务的一些最佳实践都会围绕它去改变。

### 源于开源，茁壮于开源

云计算构筑在开源之上，灵雀云的基础设施和服务也构建在开源之上，那么灵雀云是如何拥抱开源和贡献开源的？

陈恺说，“有几个开源社区跟我们是非常相关的，最早的时候是 Docker 社区，现在 Kubernetes 则是跟我们关系最大的开源社区。我们核心的产品是容器、DevOps 和微服务三部分。Jenkins、Istio 等相关开源项目是我们的重点，我们非常重视在开源社区的投入。我们的许多工程师会参与其中，对社区进行贡献，也会开源一些项目，我们在一步一步持续地做这件事情。我们首先会选择一些偏底层的技术或者机制，选择那些有足够亮点，真的被需要的项目和技术开源出来。”

目前灵雀云已经开源了的项目，包括基于 OVN 的网络插件 Kube-OVN，它是把 OVN 的网络和 Kubernetes 所集成的网络插件。现在该项目在国内外都受到关注，也有来自外部贡献者参与。另外一个开源的项目叫 Captain，是一个基于 Helm v3 标准的 Kubernetes 控制器，对 Helm 应用分发进行改进。

后续灵雀云还计划将更完整的东西放出来，比如灵雀云的 Kubernetes 发行版，供社区用户用来管理自己的 Kubernetes 平台，可以达到和使用灵雀云产品接近的体验。另外灵雀云也计划将其 ACP 释放社区版或者开源版本出来。陈恺说，“我们很乐意把它开源出来，因为这是一个标准的产品，我们让它较早期的接触更多用户，也能得到更多反馈，甚至吸收一些外部的贡献者参与进来。”

### 尾声

我采访过很多技术领袖和技术专家，不过陈恺的这场采访让我有一点不同的感受。一场对话下来，陈恺给我的感觉如同多年的老友一样言无不尽，而他对于我提到的每个话题，都非常认真、仔细的做了阐述，让人感到浓浓的专业技术风格。我想，这就是陈恺的技术初心，也是灵雀云一直以来的风格吧。

---

>
>
>
>
> “穿山甲专访”栏目是 Linux 中国社区推出的面向开源界、互联网技术圈的重要领军人物的系列采访，将为大家介绍中国开源领域中一些积极推动开源，谙熟开源思想的技术人，并辨析其思考、挖掘其动因，揭示其背后所发生的事情，为关注开源、有志于开源的企业和技术人标出一条路径。
>
>
> 取名为“穿山甲”寓意有二：取穿山甲挖掘、深入之意来象征技术进步和表征技术领袖的作用；穿山甲是珍稀保护动物，宣传公益。
>
>
>


克隆 MAC 地址来绕过强制门户

# 克隆 MAC 地址来绕过强制门户

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

如果你曾经在家和办公室之外连接到 WiFi，那么通常会看到一个门户页面。它可能会要求你接受服务条款或其他协议才能访问。但是，当你无法通过这类门户进行连接时会发生什么？本文向你展示了如何在 Fedora 上使用 NetworkManager 在某些故障情况下让你仍然可以访问互联网。

### 强制门户如何工作

强制门户是新设备连接到网络时显示的网页。当用户首次访问互联网时，门户网站会捕获所有网页请求并将其重定向到单个门户页面。

然后，页面要求用户采取一些措施，通常是同意使用政策。用户同意后，他们可以向 RADIUS 或其他类型的身份验证系统进行身份验证。简而言之，强制门户根据设备的 MAC 地址和终端用户接受条款来注册和授权设备。（MAC 地址是附加到任何网络接口的[基于硬件的值](https://en.wikipedia.org/wiki/MAC_address)，例如 WiFi 芯片或卡。）

有时设备无法加载强制门户来进行身份验证和授权以使用 WiFI 接入。这种情况的例子包括移动设备和游戏机（Switch、Playstation 等）。当连接到互联网时，它们通常不会打开强制门户页面。连接到酒店或公共 WiFi 接入点时，你可能会看到这种情况。

不过，你可以在 Fedora 上使用 NetworkManager 来解决这些问题。Fedora 可以使你临时克隆要连接的设备的 MAC 地址，并代表该设备通过强制门户进行身份验证。你需要得到连接设备的 MAC 地址。通常，它被打印在设备上的某个地方并贴上标签。它是一个六字节的十六进制值，因此看起来类似 `4A:1A:4C:B0:38:1F`。通常，你也可以通过设备的内置菜单找到它。

### 使用 NetworkManager 克隆

首先，打开 `nm-connection-editor`，或通过“设置”打开 WiFi 设置。然后，你可以使用 NetworkManager 进行克隆：

* 对于以太网：选择已连接的以太网连接。然后选择 “Ethernet” 选项卡。记录或复制当前的 MAC 地址。在 “<ruby> 克隆 MAC 地址 <rt>  Cloned MAC address </rt></ruby>” 字段中输入游戏机或其他设备的 MAC 地址。
* 对于 WiFi：选择 WiFi 配置名。然后选择 “WiFi” 选项卡。记录或复制当前的 MAC 地址。在 “<ruby> 克隆 MAC 地址 <rt>  Cloned MAC address </rt></ruby>” 字段中输入游戏机或其他设备的 MAC 地址。

### 启动所需的设备

当 Fedora 系统与以太网或 WiFi 配置连接，克隆的 MAC 地址将用于请求 IP 地址，并加载强制门户。输入所需的凭据和/或选择用户协议。该 MAC 地址将获得授权。

现在，断开 WiF i或以太网配置连接，然后将 Fedora 系统的 MAC 地址更改回其原始值。然后启动游戏机或其他设备。该设备现在应该可以访问互联网了，因为它的网络接口已通过你的 Fedora 系统进行了授权。

不过，这不是 NetworkManager 全部能做的。例如，请参阅[随机化系统硬件地址](/article-10028-1.html)，来获得更好的隐私保护。

---

via: <https://fedoramagazine.org/cloning-a-mac-address-to-bypass-a-captive-portal/>

作者：[Esteban Wilson](https://fedoramagazine.org/author/swilson/) 选题：[lujun9972](https://github.com/lujun9972) 译者：[geekpi](https://github.com/geekpi) 校对：[wxy](https://github.com/wxy)

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


为什么容器和 Kubernetes 有潜力运行一切

# 为什么容器和 Kubernetes 有潜力运行一切

>
> 不仅可以部署简单的应用程序，还可以用 Kubernetes 运维器应对第 2 天运营。
>
>
>

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

在我的第一篇文章 [为什么说 Kubernetes 是一辆翻斗车](https://opensource.com/article/19/6/kubernetes-dump-truck) 中，我谈到了 Kubernetes 如何在定义、分享和运行应用程序方面很出色，类似于翻斗车在移动垃圾方面很出色。在第二篇中，[如何跨越 Kubernetes 学习曲线](https://opensource.com/article/19/6/kubernetes-learning-curve)，我解释了 Kubernetes 的学习曲线实际上与运行任何生产环境中的应用程序的学习曲线相同，这确实比学习所有传统组件要容易（如负载均衡器、路由器、防火墙、交换机、集群软件、集群文件系统等）。这是 DevOps，是开发人员和运维人员之间的合作，用于指定事物在生产环境中的运行方式，这意味着双方都需要学习。在第三篇 [Kubernetes 基础：首先学习如何使用](https://opensource.com/article/19/6/kubernetes-basics) 中，我重新设计了 Kubernetes 的学习框架，重点是驾驶翻斗车而不是制造或装备翻斗车。在第四篇文章 [帮助你驾驭 Kubernetes 的 4 个工具](https://opensource.com/article/19/6/tools-drive-kubernetes) 中，我分享了我喜爱的工具，这些工具可帮助你在 Kubernetes 中构建应用程序（驾驶翻斗车）。

在这最后一篇文章中，我会分享我为什么对在 Kubernetes 上运行应用程序的未来如此兴奋的原因。

从一开始，Kubernetes 就能够很好地运行基于 Web 的工作负载（容器化的）。Web 服务器、Java 和相关的应用程序服务器（PHP、Python等）之类的工作负载都可以正常工作。该平台处理诸如 DNS、负载平衡和 SSH（由 `kubectl exec` 取代）之类的支持服务。在我的职业生涯的大部分时间里，这些都是我在生产环境中运行的工作负载，因此，我立即意识到，除了 DevOps 之外，除了敏捷之外，使用 Kubernetes 运行生产环境工作负载的强大功能。即使是我们几乎不改变我们的文化习惯，也可以提高效率。调试和退役变得非常容易，而这对于传统 IT 来说是极为困难的。因此，从早期开始，Kubernetes 就用一种单一的配置语言（Kube YAML/Json）为我提供了对生产环境工作负载进行建模所需的所有基本原语。

但是，如果你需要运行具有复制功能的多主 MySQL，会发生什么情况？使用 Galera 的冗余数据呢？你如何进行快照和备份？那么像 SAP 这样复杂的工作呢？使用 Kubernetes，简单的应用程序（Web 服务器等）的第 0 天（部署）相当简单，但是没有解决第 2 天的运营和工作负载。这并不是说，具有复杂工作负载的第 2 天运营要比传统 IT 难解决，而是使用 Kubernetes 并没有使它们变得更容易。每个用户都要设计自己的天才想法来解决这些问题，这基本上是当今的现状。在过去的五年中，我遇到的第一类问题是复杂工作负载的第 2 天操作。（LCTT 译注：在软件生命周期中，第 0 天是指软件的设计阶段；第 1 天是指软件的开发和部署阶段；第 2 天是指生产环境中的软件运维阶段。）

值得庆幸的是，随着 Kubernetes <ruby> 运维器 <rt>  Operator </rt></ruby>的出现，这种情况正在改变。随着运维器的出现，我们现在有了一个框架，可以将第 2 天的运维知识汇总到平台中。现在，我们可以应用我在 [Kubernetes 基础：首先学习如何使用](https://opensource.com/article/19/6/kubernetes-basics) 中描述的相同的定义状态、实际状态的方法，现在我们可以定义、自动化和维护各种各样的系统管理任务。

（LCTT 译注： Operator 是 Kubernetes 中的一种可以完成运维工程师的特定工作的组件，业界大多没有翻译这个名词，此处仿运维工程师例首倡翻译为“运维器”。）

我经常将运维器称为“系统管理机器人”，因为它们实质上是在第 2 天的工作中整理出一堆运维知识，该知识涉及<ruby> 主题专家 <rt>  Subject Matter Expert </rt></ruby>（SME、例如数据库管理员或系统管理员）针对的工作负载类型（数据库、Web 服务器等），通常会记录在 Wiki 中的某个地方。这些知识放在 Wiki 中的问题是，为了将该知识应用于解决问题，我们需要：

1. 生成事件，通常监控系统会发现故障，然后我们创建故障单
2. SME 人员必须对此问题进行调查，即使这是我们之前见过几百万次的问题
3. SME 人员必须执行该知识（执行备份/还原、配置 Galera 或事务复制等）

通过运维器，所有这些 SME 知识都可以嵌入到单独的容器镜像中，该镜像在有实际工作负荷之前就已部署。 我们部署运维器容器，然后运维器部署和管理一个或多个工作负载实例。然后，我们使用“运维器生命周期管理器”（Katacoda 教程）之类的方法来管理运维器。

因此，随着我们进一步使用 Kubernetes，我们不仅简化了应用程序的部署，而且简化了整个生命周期的管理。运维器还为我们提供了工具，可以管理具有深层配置要求（群集、复制、修复、备份/还原）的非常复杂的有状态应用程序。而且，最好的地方是，构建容器的人员可能是做第 2 天运维的主题专家，因此现在他们可以将这些知识嵌入到操作环境中。

### 本系列的总结

Kubernetes 的未来是光明的，就像之前的虚拟化一样，工作负载的扩展是不可避免的。学习如何驾驭 Kubernetes 可能是开发人员或系统管理员可以对自己的职业发展做出的最大投资。随着工作负载的增多，职业机会也将增加。因此，这是驾驶一辆令人惊叹的 [在移动垃圾时非常优雅的翻斗车](https://opensource.com/article/19/6/kubernetes-dump-truck)……

你可能想在 Twitter 上关注我，我在 [@fatherlinux](https://twitter.com/fatherlinux) 上分享有关此主题的很多内容。

---

via: <https://opensource.com/article/19/6/kubernetes-potential-run-anything>

作者：[Scott McCarty](https://opensource.com/users/fatherlinux) 选题：[lujun9972](https://github.com/lujun9972) 译者：[wxy](https://github.com/wxy) 校对：[wxy](https://github.com/wxy)

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


第 0 天/第 1 天/第 2 天：云时代的软件生命周期

# 第 0 天/第 1 天/第 2 天：云时代的软件生命周期

在当今的专业 IT 媒体中有一个非常突出的话题，那就是在软件生命周期中的“第 0 天/第 1 天/第 2 天”。在演讲和会议讲话当中，通常着重于使软件开发过程有效且易于管理，为此，有必要明确定义所使用的概念。通常，如果直观地理解基本术语“<ruby> 第 0 天 <rp>  （ </rp> <rt>  Day 0 </rt> <rp>  ） </rp></ruby>/<ruby> 第 1 天 <rp>  （ </rp> <rt>  Day 1 </rt> <rp>  ） </rp></ruby>/<ruby> 第 2 天 <rp>  （ </rp> <rt>  Day 2 </rt> <rp>  ） </rp></ruby>”，这在谈论软件生命周期时可能会引起一些歧义。因此，我决定更准确地定义它们，以展示软件开发的整个过程以及它们在实际项目中的使用方式。这篇简短的博客文章提供了“天”的定义，这些“天”被理解为软件生命周期的各个阶段。它还描述了云如何改变了有关软件开发和维护过程的传统思维方式。毕竟，正如《[RightScale 2019 云状态报告](https://www.flexera.com/about-us/press-center/rightscale-2019-state-of-the-cloud-report-from-flexera-identifies-cloud-adoption-trends.html)》所确认的那样，我们正处于“云时代”。该报告解释说，有 94％ 的调查受访者正在使用云（私有云或公有云）。因此，闲话少说，让我们探讨一下“天”和云如何结合在一起。

### “天”究竟是什么？

在 IT 中，术语“第 0 天/第 1 天/第 2 天”指的是软件生命周期的不同阶段。用军事术语来说，“第 0 天”是训练的第一天，新兵进入训练阶段。在软件开发中，它代表设计阶段，在此阶段中指定项目需求并确定解决方案的体系结构。

“第 1 天”涉及开发和部署在“第 0 天”阶段设计的软件。在此阶段，我们不仅创建应用程序本身，还创建应用程序的基础设施、网络、外部服务，并实现所有部分的初始配置。

“第 2 天”是产品出厂或交付给客户的时间。在这里，大部分工作都集中在维护、监控和优化系统上。分析系统的行为并做出正确的反应至关重要，因为所产生的反馈循环将一直持续到应用程序生命周期结束为止。

在云时代之前的日子里，这些阶段是分别处理的，彼此之间没有重叠。今天，情况已不再如此。让我们看一下所有这些如何应用于现代应用程序的生命周期。

#### 第 0 天：无聊但必不可少

第 0 天经常被忽略，因为它可能很无聊，但这并不会降低其重要性。成功的软件产品是经过全面规划和设计过程的结果。必须仔细计划系统或应用程序的体系结构以及启动和运行所需的资源（CPU、存储空间、RAM）。其次，你应该定义可衡量的里程碑，以实现项目目标。每个里程碑应有一个准确的日期。这有助于衡量项目的进度，并确定你是否延迟了计划运行。所有项目时间估算都应基于概率，而不仅仅是按最佳情况预估。进行计划时，最好添加缓冲余量，因为意外事件甚至可能使精心策划的计划陷入困境。测试阶段也起着重要的作用，也应该包括在初始项目计划中。这些是基本要求，它们在“云时代”中同以往一样重要。

尽管如此，在计算资源的第 0 天计划中，云还是改变了两件事。由于云可以在项目的任何地方获得不同的资源或新资源（CPU、存储空间、RAM），因此比本地基础设施要容易得多。因此，可以避免在计划阶段犯下的一些错误。另一方面，在计划阶段对特定云供应商的承诺可能会在以后导致供应商锁定。这可能会花费你的金钱，并且需要时间来进行更改，因此选择云供应商时要明智一些。

其次，正如我们当前在向云的迁移中观察到的那样，与运维相关的工作依旧保持不变，但不再专注于基础设施。现在，正是软件在推动着自动化和价值。

#### 第 1 天：实现创意的阶段

对于开发人员和项目负责人而言，第 1 天绝对是最有趣的阶段。最初的设计得以实现，并根据项目的规范创建了基础设施。为了成为真正的云原生，必须遵守最佳实践。可以遵循诸如<ruby>   十二要素应用程序方法  <rp>  （ </rp> <rt>  Twelve-Factor Apps methodology </rt> <rp>  ） </rp></ruby>之类的准则。此外，使用云端意味着你应该遵循重要的 DevOps 惯例：持续集成/持续交付（如果你想了解有关 CI/CD 的更多信息，请参阅我们的[博客文章](https://codilime.com/what-is-ci-cd-all-you-need-to-know/)）。

云为我们带来了从传统方法到软件开发的重要变化：将第一行代码拼凑在一起以进行概念验证后，应用程序即开始运行。你可以从持续集成实践开始，以测试你的应用程序的健全性，但是你很快会让企业迈入到持续交付。在开发应用程序时，我们开始引入一些运维元素，尤其是在使用多个环境的情况下。注意这些运维要素将使维护团队在维护阶段（第 2 天）的工作更加轻松。

在第 1 天期间可以使用几种工具。可以将它们按解决的问题分组。这个列表的顶部应提及“<ruby> 基础设施即代码 <rp>  （ </rp> <rt>  Infrastructure-as-a-code </rt> <rp>  ） </rp></ruby>”（IaaC）。 IaaC 就像应用程序或代码一样管理运维环境。这种方法允许将 DevOps 最佳实践（包括版本控制、虚拟化测试和持续监视）应用于驱动基础设施的代码。这里有很多工具可供我们使用，例如 Terraform、Ansible 或 Puppet 等。第二类工具与容器的自动化部署和管理的容器编排系统有关。Kubernetes 及其实现（例如 Google Kubernetes Engine 和亚马逊的 Elastic Kubernetes Service）至关重要。最后，还有诸如 Jenkins、Zuul 和 CircleCI 之类的 CI/CD 系统，可帮助工程师自动化软件的构建、测试以及交付或部署。

### 第 2 天：日常运维环节

一旦软件准备就绪，它就会上线，客户开始使用它。第 2 天始于此，并引入了包括软件维护和客户支持在内的各个元素。该软件本身将不断发展，以适应不断变化的需求和客户需求。在第 2 天期间，主要重点是建立反馈循环。我们监控该应用程序的工作方式，收集用户反馈并将其发送给开发团队，该团队将在产品中实施该应用程序并发布新版本。军事术语“<ruby> 观察-导向-决定-行动 <rp>  （ </rp> <rt>  Observe-Orient-Decide-Act </rt> <rp>  ） </rp></ruby>”（OODA）恰当地抓住了这一阶段发生的事情。

* 观察：从监视系统获取信息（资源使用情况和指标，应用程序性能监控）。
* 导向：执行问题的根本原因分析。
* 决定：找到解决问题的方法。
* 行动：实施解决方案。

与战斗中一样，该循环不断重复。

监控程序基于<ruby> 服务水平协议 <rp>  （ </rp> <rt>  Service Level Agreement </rt> <rp>  ） </rp></ruby>（SLA）中定义的要求。 SLA 基于<ruby> 服务水平目标 <rp>  （ </rp> <rt>  Service Level Objectives </rt> <rp>  ） </rp></ruby>（SLO），代表我们的<ruby> 服务水平指标 <rp>  （ </rp> <rt>  Service Level Indicators </rt> <rp>  ） </rp></ruby>（SLI）的状态。自动化和监控是解决第 2 天职责的关键。

有几种工具可帮助完成第 2 天的工作。 <ruby> 应用程序性能监控 <rp>  （ </rp> <rt>  Application Performance Monitoring </rt> <rp>  ） </rp></ruby>（APM）类软件可以帮助 IT 管理员监控应用程序性能，从而提供高质量的用户体验。在这里，我们可以点名 Datadog、Dynatrace、SignalFX 或 Nutanix Xi Epoch。 还有一些自动化和编排工具，例如 Ansible 或 Kubernetes，可帮助管理应用程序环境。你可能已经注意到，这些工具的应用与第 1 天的工作重叠。最后，工单系统（例如 Servicedesk 或 Zendesk）可以处理客户服务，使用户可以报告故障以及与他们正在运行的应用程序有关的问题。

### 云将改变游戏规则

在前云时代，这些阶段之间的分隔清晰可见，但是今天，随着云的日常运行，事物在不断变化。使用云和现代软件开发实践，可以更轻松地处理软件生命周期中不断变化的要求。持续集成/持续开发方法使我们能够动态响应客户反馈并实时改进应用程序，而无需等待主要版本进行改进。

基于云和原生云的软件中的 DevOps 实践有助于实现<ruby> 向左移动 <rp>  （ </rp> <rt>  shift left </rt> <rp>  ） </rp></ruby>（LCTT 译注：环节前置的意思），这意味着传统上一直保留到最后的步骤现在可以更快地执行。除此以外，这导致第 1 天和第 2 天现在相互重叠。此外，传统软件开发的最大痛点在于从第 1 天到第 2 天的过渡：从开发人员到运维人员的过渡。现在，DevOps 展示了如何解决此问题：及早启动流程，并使流程一直运行到应用程序生命周期结束。最后但同样重要的是，工具链正在完善，这使得执行第 1 天的任务和适应第 2 天的更改成为可能。 可以根据我们的需求对所使用的工具进行建模，并且过程中涉及的每个人都可以使用同一套工具。


如何使用 cron 任务在 Linux 中计划和自动化任务

# 如何使用 cron 任务在 Linux 中计划和自动化任务

有时，你可能需要定期或以预定的时间间隔执行任务。这些任务包括备份数据库、更新系统、执行定期重新引导等。这些任务称为 “cron 任务”。cron 任务用于“自动执行的任务”，它有助于简化重复的、有时是乏味的任务的执行。cron 是一个守护进程，可让你安排这些任务，然后按指定的时间间隔执行这些任务。在本教程中，你将学习如何使用 cron 来安排任务。

### crontab 文件

crontab 即 “cron table”，是一个简单的文本文件，其中包含指定任务执行时间间隔的规则和命令。 crontab 文件分为两类：

1）系统范围的 crontab 文件

这些通常由需要 root 特权的 Linux 服务及关键应用程序使用。系统 crontab 文件位于 `/etc/crontab` 中，并且只能由 root 用户访问和编辑。通常用于配置系统范围的守护进程。`crontab` 文件的看起来类似如下所示：

2）用户创建的 crontab 文件

Linux 用户还可以在 `crontab` 命令的帮助下创建自己的 cron 任务。创建的 cron 任务将以创建它们的用户身份运行。

所有 cron 任务都存储在 `/var/spool/cron`（对于 RHEL 和 CentOS 发行版）和 `/var/spool/cron/crontabs`（对于 Debian 和 Ubuntu 发行版）中，cron 任务使用创建该文件的用户的用户名列出。

cron 守护进程在后台静默地检查 `/etc/crontab` 文件和 `/var/spool/cron` 及 `/etc/cron.d*/` 目录。

`crontab` 命令用于编辑 cron 文件。让我们看一下 crontab 文件的结构。

### crontab 文件剖析

在继续之前，我们要首先探索 crontab 文件的格式。crontab 文件的基本语法包括 5 列，由星号表示，后跟要执行的命令。

```
*    *    *    *    *    command
```

此格式也可以表示如下：

```
m h d moy dow command
```

或

```
m h d moy dow /path/to/script
```

让我们来解释一下每个条目

* `m`：代表分钟。范围是 0 到 59
* `h`：表示小时，范围是 0 到 23
* `d`：代表一个月中的某天，范围是 1 到 31
* `moy`：这是一年中的月份。范围是 1 到 12
* `dow`：这是星期几。范围是 0 到 6，其中 0 代表星期日
* `command`：这是要执行的命令，例如备份命令、重新启动和复制命令等

### 管理 cron 任务

看完 crontab 文件的结构之后，让我们看看如何创建、编辑和删除 cron 任务。

#### 创建 cron 任务

要以 root 用户身份创建或编辑 cron 任务，请运行以下命令：

```
# crontab -e
```

要为另一个用户创建或安排 cron 任务，请使用以下语法：

```
# crontab -u username -e
```

例如，要以 Pradeep 用户身份运行 cron 任务，请发出以下命令：

```
# crontab -u Pradeep -e
```

如果该 crontab 文件尚不存在，那么你将打开一个空白文本文件。如果该 crontab 文件已经存在，则 `-e` 选项会让你编辑该文件，

#### 列出 crontab 文件

要查看已创建的 cron 任务，只需传递 `-l` 选项：

```
# crontab -l
```

#### 删除 crontab 文件

要删除 cron 任务，只需运行 `crontab -e` 并删除所需的 cron 任务行，然后保存该文件。

要删除所有的 cron 任务，请运行以下命令：

```
# crontab -r
```

然后，让我们看一下安排任务的不同方式。

### 使用 crontab 安排任务示例

如图所示，所有 cron 任务文件都带有<ruby> 释伴 <rt>  shebang </rt></ruby>标头。

```
#!/bin/bash
```

这表示你正在使用的 shell，在这种情况下，即 bash shell。

接下来，使用我们之前指定的 cron 任务条目指定要安排任务的时间间隔。

要每天下午 12:30 重启系统，请使用以下语法：

```
30  12 *  *  * /sbin/reboot
```

要安排在凌晨 4:00 重启，请使用以下语法：

```
0  4  *  *  *  /sbin/reboot
```

注：星号 `*` 用于匹配所有记录。

要每天两次运行脚本（例如，凌晨 4:00 和下午 4:00），请使用以下语法：

```
0  4,16  *  *  *  /path/to/script
```

要安排 cron 任务在每个星期五下午 5:00 运行，请使用以下语法：

```
0  17  *  *  Fri  /path/to/script
```

或

```
0 17  *  *  *  5  /path/to/script
```

如果你希望每 30 分钟运行一次 cron 任务，请使用：

```
*/30  *  *  *  * /path/to/script
```

要安排 cron 任务每 5 小时运行一次，请运行：

```
*  */5  *  *  *  /path/to/script
```

要在选定的日期（例如，星期三和星期五的下午 6:00）运行脚本，请执行以下操作：

```
0  18  *  *  wed,fri  /path/to/script
```

要使用单个 cron 任务运行多个命令，请使用分号分隔任务，例如：

```
*  *  *  *  *  /path/to/script1 ; /path/to/script2
```

### 使用特殊字符串节省编写 cron 任务的时间

某些 cron 任务可以使用对应于特定时间间隔的特殊字符串轻松配置。例如，

1）`@hourly` 时间戳等效于 `0 * * * *`

它将在每小时的第一分钟执行一次任务。

```
@hourly /path/to/script
```

2）`@daily` 时间戳等效于 `0 0 * * *`

它在每天的第一分钟（午夜）执行任务。它可以在执行日常工作时派上用场。

```
@daily /path/to/script
```

3）`@weekly` 时间戳等效于 `0 0 * * 0`

它在每周的第一分钟执行 cron 任务，一周第一天是从星期日开始的。

```
@weekly /path/to/script
```

3）`@monthly` 时间戳等效于 `0 0 1 * *`

它在每月第一天的第一分钟执行任务。

```
@monthly /path/to/script
```

4）`@yearly` 时间戳等效于 `0 0 1 1 *`

它在每年的第一分钟执行任务，可以用于发送新年问候。

```
@yearly /path/to/script
```

### 限制 crontab

作为 Linux 用户，你可以控制谁有权使用 `crontab` 命令。可以使用 `/etc/cron.deny` 和 `/etc/cron.allow` 文件来控制。默认情况下，只有一个 `/etc/cron.deny` 文件，并且不包含任何条目。要限制用户使用 `crontab` 实用程序，只需将用户的用户名添加到该文件中即可。当用户添加到该文件中，并且该用户尝试运行 `crontab` 命令时，他/她将遇到以下错误。

要允许用户继续使用 `crontab` 实用程序，只需从 `/etc/cron.deny` 文件中删除用户名即可。

如果存在 `/etc/cron.allow` 文件，则仅文件中列出的用户可以访问和使用 `crontab` 实用程序。

如果两个文件都不存在，则只有 root 用户具有使用 `crontab` 命令的特权。

### 备份 crontab 条目

始终建议你备份 crontab 条目。为此，请使用语法：

```
# crontab -l > /path/to/file.txt
```

例如：

```
# crontab -l > /home/james/backup.txt
```

### 检查 cron 日志

cron 日志存储在 `/var/log/cron` 文件中。要查看 cron 日志，请运行以下命令：

```
# cat /var/log/cron
```

要实时查看日志，请使用 `tail` 命令，如下所示：

```
# tail -f /var/log/cron
```

### 总结

在本指南中，你学习了如何创建 cron 任务以自动执行重复性任务，如何备份和查看 cron 日志。我们希望本文提供有关 cron 作业的有用见解。请随时分享你的反馈和意见。

---

via: <https://www.linuxtechi.com/schedule-automate-tasks-linux-cron-jobs/>

作者：[Pradeep Kumar](https://www.linuxtechi.com/author/pradeep/) 选题：[lujun9972](https://github.com/lujun9972) 译者：[wxy](https://github.com/wxy) 校对：[wxy](https://github.com/wxy)

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