Merge pull request #1 from LCTT/master

Update from LCTT
This commit is contained in:
hj24 2019-12-05 13:25:57 +08:00 committed by GitHub
commit b7d49d722c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 1402 additions and 567 deletions

View File

@ -1,8 +1,8 @@
[#]: collector: (lujun9972)
[#]: translator: (geekpi)
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
[#]: reviewer: (wxy)
[#]: publisher: (wxy)
[#]: url: (https://linux.cn/article-11643-1.html)
[#]: subject: (Using multitail on Linux)
[#]: via: (https://www.networkworld.com/article/3445228/using-multitail-on-linux.html)
[#]: author: (Sandra Henry-Stocker https://www.networkworld.com/author/Sandra-Henry_Stocker/)
@ -10,14 +10,13 @@
在 Linux 上使用 Multitail
======
[Glen Bowman][1] [(CC BY-SA 2.0)][2]
当你想同时查看多个文件(尤其是日志文件)的活动时,**multitail** 命令会非常有用。它的工作方式类似于多窗口形式的 **tail -f** 命令。也就是说,它显示文件底部和添加的新行。虽然通常使用简单,但是 **multitail** 提供了一些命令行和交互式选项,在开始使用它之前,你应该了解它们。
![](https://img.linux.net.cn/data/attachment/album/201912/05/053423mpnrn95hqqknzheq.jpg)
当你想同时查看多个文件(尤其是日志文件)的活动时,`multitail` 命令会非常有用。它的工作方式类似于多窗口形式的 `tail -f` 命令。也就是说,它显示这些文件的底部和添加的新行。虽然通常使用简单,但是 `multitail` 提供了一些命令行和交互式选项,在开始使用它之前,你应该了解它们。
### 基本 multitail 使用
**multitail** 的最简单用法是在命令行中列出你要查看的文件名称。此命令水平分割屏幕(即顶部和底部),并显示每个文件的底部以及更新。
`multitail` 的最简单用法是在命令行中列出你要查看的文件名称。此命令水平分割屏幕(即顶部和底部),并显示每个文件的底部以及更新。
```
$ multitail /var/log/syslog /var/log/dmesg
@ -50,7 +49,7 @@ more lines
01] my2.log 120KB - 2019/10/14 14:22:29
```
请注意,如果你要求 **multitail** 显示非文本文件或者你无权查看的文件,它不会报错。你只是看不到内容。
请注意,如果你要求 `multitail` 显示非文本文件或者你无权查看的文件,它不会报错。你只是看不到内容。
你还可以使用通配符指定要查看的文件:
@ -58,13 +57,13 @@ more lines
$ multitail my*.log
```
要记住的一件事是,**multitail** 将平均分割屏幕。如果指定的文件太多,那么除非你采取额外的步骤查看之后的文件(参考下面的滚动选项),否则你将只会看到前面 7 个文件的前面几行。确切的结果取决于终端窗口中有多少行可用。
要记住的一件事是,`multitail` 将平均分割屏幕。如果指定的文件太多,那么除非你采取额外的步骤查看之后的文件(参考下面的滚动选项),否则你将只会看到前面 7 个文件的前面几行。确切的结果取决于终端窗口中有多少行可用。
**q** 退出 **multitail** 并返回到正常的屏幕视图。
`q` 退出 `multitail` 并返回到正常的屏幕视图。
### 分割屏幕
如果你愿意,**multitail** 将垂直分割你的终端窗口(即,左和右)。为此,请使用 **-s** 选项。如果指定了三个文件,那么屏幕右侧的窗口将会水平分隔。四个文件的话,你将拥有四个大小相等的窗口。
如果你愿意,`multitail` 也可以垂直分割你的终端窗口(即,左和右)。为此,请使用 `-s` 选项。如果指定了三个文件,那么屏幕右侧的窗口将会水平分隔。四个文件的话,你将拥有四个大小相等的窗口。
```
+-----------+-----------+ +-----------+-----------+ +-----------+-----------+
@ -77,7 +76,7 @@ $ multitail my*.log
2 个文件 3 个文件 4 个文件
```
如果要将屏幕分为三列,请使用 **multitail -s 3 file1 file2 file3**
如果要将屏幕分为三列,请使用 `multitail -s 3 file1 file2 file3`
```
+-------+-------+-------+
@ -92,15 +91,13 @@ $ multitail my*.log
### 滚动
你可以上下滚动文件,但是需要按下 **b** 弹出选择菜单,然后使用向上和向下箭头按钮选择要滚动浏览的文件。然后按下回车键。然后,你可以再次使用向上和向下箭头在放大的区域中滚动浏览各行。完成后按下 **q** 返回正常视图。
你可以上下滚动文件,但是需要按下 `b` 弹出选择菜单,然后使用向上和向下箭头按钮选择要滚动浏览的文件。然后按下回车键。然后,你可以再次使用向上和向下箭头在放大的区域中滚动浏览各行。完成后按下 `q` 返回正常视图。
### 获得帮助
**multitail** 中按下 **h** 将打开一个帮助菜单,其中描述了一些基本操作,但是手册页提供了更多信息,如果莫想了解更多有关使用此工具的信息,请仔细阅读。
`multitail` 中按下 `h` 将打开一个帮助菜单,其中描述了一些基本操作,但是手册页提供了更多信息,如果莫想了解更多有关使用此工具的信息,请仔细阅读。
默认情况下,你的系统商不会安装 **multitail**,但是使用 **apt-get****yum** 可以使你轻松安装。该工具提供了许多功能,但是通过基于字符的显示,窗口边框将只是 **q****x** 的字符串。 当你需要关注文件更新时,它非常方便。
加入 [Facebook][5] 和 [LinkedIn][6] 上的 Network World 社区,评论热门主题。
默认情况下,你的系统上不会安装 `multitail`,但是使用 `apt-get``yum` 可以使你轻松安装。该工具提供了许多功能,不过它是基于字符显示的,窗口边框只是 `q``x` 的字符串组成的。当你需要关注文件更新时,它非常方便。
--------------------------------------------------------------------------------
@ -109,7 +106,7 @@ via: https://www.networkworld.com/article/3445228/using-multitail-on-linux.html
作者:[Sandra Henry-Stocker][a]
选题:[lujun9972][b]
译者:[geekpi](https://github.com/geekpi)
校对:[校对者ID](https://github.com/校对者ID)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出

View File

@ -0,0 +1,138 @@
[#]: collector: "lujun9972"
[#]: translator: "hello-wn"
[#]: reviewer: "wxy"
[#]: publisher: "wxy"
[#]: url: "https://linux.cn/article-11644-1.html"
[#]: subject: "Top 10 Vim plugins for programming in multiple languages"
[#]: via: "https://opensource.com/article/19/11/vim-plugins"
[#]: author: "Maxim Burgerhout https://opensource.com/users/wzzrd"
多语言编程必备的十大 Vim 插件
======
> 使用这 10 个 Vim 插件,可以让你在写代码或运维时,感觉更棒。
![](https://img.linux.net.cn/data/attachment/album/201912/05/062256bnauidfsf7155d1n.jpeg)
我使用 [Vim][2] 文本编辑器大约 20 年了。有一段时间,我一直在定制我的 Vim 配置,但在只有在最近两年我才会使用插件。
最近,当我重新安装系统时(就像我经常做的那样),我觉得这是一次好的机会,我想找出多种编程语言环境下的最佳 Vim 插件,以及如何将这些插件和每种语言结合起来。
有时,我会为特定的语言和配置使用特定的插件(例如,我只在 Ansible 配置中安装 Rocannon在此不细讲了。不过下面介绍的 10 个 Vim 插件都是我的最爱,无论使用哪种编程语言,我几乎都会使用它们。
### 1、Volt
我的首选并不是一个插件,但是它可以替换类似于 [Vundle][3] 的插件,所以在此介绍。
[Volt][4] 是一个不依存于 Vim 的 Vim 插件管理器。你可以用它安装插件并创建名为“profile”的插件组合。你可以使用一个简单的命令 `volt profile set myprofile` 启用新的配置。这样我可以做到这样的事情,如为 Python 配置单独启用 [indentpython][5] 插件。Volt 还提供了一种针对每个插件配置的简单方法这些配置会在“profile”之间共享因此只需要安装一次插件就可以在多个“profile”之间使用。
Volt 还是相对较新且不够完美比如不管你想要使用多少个“profile”每个插件只能有一个配置文件但除此之外我发现它非常方便、快速和简单。
![Volt plugin][6]
### 2、Vim-Rainbow
除了 Python几乎所有的主流编程语言都使用括号小括号、方括号和大括号。通常它们会嵌套使用多对括号因此很难搞清楚某个括号的开闭区间。我发现自己经常要数小括号尤其是在复杂的 Bash 脚本中,以确保无误。
这时候就需要 [vim-rainbow][7] 插件!它为每对括号设置不同的颜色,因此很容易识别出哪些括号是一对括号。它非常有用而且五彩斑斓。
![vim-rainbow plugin][8]
### 3、lightline
Vim 有很多这种插件,例如 [Powerline][9],它会在底部栏显示你正在处理的文件、光标所在的文件位置以及文件类型等信息。这些插件各有利弊,在简单比较后,我选择了 [lightline][10]。它相对较小,便于安装和扩展,并且不依赖于其他工具或插件。
![Lightline plugin][11]
### 4、NERDTree
[NERDTree][12] 是一个很经典的插件。在大型项目中,你可能很难找到想要编辑的内容所在文件的确切名称和路径。使用快捷键(我使用的是 `F7`,因为我在 `.vimrc` 中配置了这个快捷键),搜索窗会以垂直分屏的方式打开,就可以轻松找到所需文件并打开它。对于大型项目,这是必备插件。对于那些经常忘记文件名的人也很有用,比如我。
![NERDTree vim plugin][13]
### 5、NERD Commenter
程序员们在写代码时,有时会遇到一些难以调试的问题,导致他们想要注释或不执行某段代码。这时候就需要 [NERD Commenter][14] 出场了。选择代码段,按 `Leader 键 + cc`,代码就会被注释掉。(标准的 Vim Leader 键 是 `/` 字符。)按 `Leader 键 + cn`取消注释。对于大多数文件类型NERD Commenter 会自动使用正确的注释符。例如,如果你正在编辑 [BIND 区域文件][15],并将文件类型设置为 BIND 区域文件Vim 会正确地使用 `;`(分号)字符进行注释。
![NERD Commenter][16]
### 6、Solarized
我喜欢我的 Vim 主题配色。我也喜欢终端的主题色。我一直在 Vim 上使用 [Solarized][17] 配色,并且将我的终端、文件夹配色和 Vim 设为一致。
但是,有时我会根据周边环境、屏幕亮度以及是否需要分享投屏,来切换明暗模式。
显然,你可以选择自己喜欢的任何配色方案,但我喜欢 `Solarized`,因为它有明暗模式功能,它可以简单快捷地切换两种模式。我的第二个选择是 [Monokai][18]。Volt 插件管理器让我可以轻松地在两者之间切换,因此我在 Python 编程时,使用 MonokaiBash 编程时,使用 Solarized。
我没有给 Solarized 找相应的图片,因为本文中的所有其他图片都使用了 Solarized 中的浅色或深色效果,可以确认一下这些图片。
### 7、fzf
当寻找一个文件时,有时你想要一个文件浏览器,有时你只想在键盘上敲打出与文件名模糊匹配的内容,对吗?
[fzf][19](全称 “模糊查找器”)插件提供了这一功能。打出 `:FZF` 并输入文件名内容。不断缩短的列表将显示出与你输入的文件名内容相匹配的一些文件。我经常使用它,最近使用它的频率估计比使用 NERDTree 还多。缺点是这个插件依赖于 `fzf binary`,因此也必须安装这个依赖包。它适用于 Fedora、Debian 和 Arch据我所知并不在 EPEL 中。
![fzf Vim plugin][20]
### 8、ack
有时,你需要搜索包含特定行或特定单词的文件。我真的很喜欢使用 [ack][21] 插件,最好与 `ag` 结合使用,它俩的组合又被称为 “[silver searcher][22]”。这一组合的速度非常快,覆盖了 `grep``vimgrep` 的绝大多数使用场景。缺点是你需要安装 `ack``ag` 才能正常运行。好消息是 Fedora 和 EPEL7 都可以使用 `ag``ack`
![ack vim plugin][23]
### 9、gitgutter
大多数 IT 人员都使用 [Git][24] 和 Git 仓库中的文件进行工作。[gitgutter][25] 插件在行号附近添加了一列,通过符号显示该行的状态为:已更改(`~`)、已添加(`+`)或者已删除(`-`)。这有利于跟踪你所做的更改,并且可以使你专注于手头的任务,例如编写补丁来修复一个关键错误。
![gitgutter vim plugin][26]
### 10、Tag List
如果你在一个很大的文件中编写代码,会很容易忘记当前所在的位置,你可能需要上下滚动来查找某个功能。使用 [Tag List][27] 插件,只需要输入 `:Tlist`,就能垂直分屏显示出包含变量、类型、类和函数的代码,你可以轻松跳转到这些变量、类型、类和函数。这个功能对于多语言同样适用,例如 Java、Python 以及任何能够使用 `ctags` 功能的文件类型。
![Tag List vim plugin][28]
以上介绍的 10 个 Vim 插件使我作为系统管理员和兼职程序员的生活变得更轻松。你正在使用哪些 Vim 插件?请在评论中分享你最爱的插件。
--------------------------------------------------------------------------------
via: https://opensource.com/article/19/11/vim-plugins
作者:[Maxim Burgerhout][a]
选题:[lujun9972][b]
译者:[hello-wn][c]
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://opensource.com/users/wzzrd
[b]: https://github.com/lujun9972
[c]: https://github.com/hello-wn
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/openstack_python_vim_1.jpg?itok=lHQK5zpm "OpenStack source code (Python) in VIM"
[2]: https://www.vim.org/
[3]: https://github.com/VundleVim/Vundle.vim
[4]: https://github.com/vim-volt/volt
[5]: https://github.com/vim-scripts/indentpython.vim
[6]: https://opensource.com/sites/default/files/uploads/vim-volt.gif "Volt plugin"
[7]: http://github.com/frazrepo/vim-rainbow
[8]: https://opensource.com/sites/default/files/uploads/vim-rainbox.png "vim-rainbow plugin"
[9]: https://github.com/powerline/powerline
[10]: http://github.com/itchyny/lightline.vim
[11]: https://opensource.com/sites/default/files/uploads/lightline.png "Lightline plugin"
[12]: http://github.com/scrooloose/nerdtree
[13]: https://opensource.com/sites/default/files/uploads/nerdtree.gif "NERDTree vim plugin"
[14]: http://github.com/scrooloose/nerdcommenter
[15]: https://en.wikipedia.org/wiki/Zone_file#File_format
[16]: https://opensource.com/sites/default/files/uploads/nerdcommenter.gif "NERD Commenter"
[17]: https://github.com/altercation/vim-colors-solarized
[18]: https://github.com/sickill/vim-monokai
[19]: https://github.com/junegunn/fzf.vim
[20]: https://opensource.com/sites/default/files/uploads/fzf.gif "fzf Vim plugin"
[21]: https://github.com/mileszs/ack.vim
[22]: https://github.com/ggreer/the_silver_searcher
[23]: https://opensource.com/sites/default/files/uploads/ack.gif "ack vim plugin"
[24]: https://opensource.com/resources/what-is-git
[25]: https://github.com/airblade/vim-gitgutter
[26]: https://opensource.com/sites/default/files/uploads/gitgutter.png "gitgutter vim plugin"
[27]: https://github.com/vim-scripts/taglist.vim
[28]: https://opensource.com/sites/default/files/uploads/taglist.gif "Tag List vim plugin) ) ) "

View File

@ -1,8 +1,8 @@
[#]: collector: "lujun9972"
[#]: translator: "lxbwolf"
[#]: reviewer: " "
[#]: publisher: " "
[#]: url: " "
[#]: reviewer: "wxy"
[#]: publisher: "wxy"
[#]: url: "https://linux.cn/article-11645-1.html"
[#]: subject: "Bash Script to View System Information on Linux Every Time You Log into Shell"
[#]: via: "https://www.2daygeek.com/bash-shell-script-view-linux-system-information/"
[#]: author: "Magesh Maruthamuthu https://www.2daygeek.com/author/magesh/"
@ -10,11 +10,7 @@
Bash 脚本实现每次登录到 Shell 时可以查看 Linux 系统信息
======
Linux 中有很多可以查看系统信息如处理器信息,生产商名字,序列号等的命令。
你可能需要执行多个命令来收集这些信息。
同时,记住所有的命令和他们的选项也是有难度。
Linux 中有很多可以查看系统信息如处理器信息、生产商名字、序列号等的命令。你可能需要执行多个命令来收集这些信息。同时,记住所有的命令和他们的选项也是有难度。
你可以写一个 [shell 脚本](https://www.2daygeek.com/category/shell-script/) 基于你的需求来自定义显示的信息。
@ -24,14 +20,12 @@ Linux 中有很多可以查看系统信息如处理器信息,生产商名字
这个j脚本有 6 部分,细节如下:
* **Part-1:** 通用系统信息
* **Part-2:** CPU/内存当前使用情况
* **Part-3:** 硬盘使用率超过 80%
* **Part-4:** 列出系统 WWN 详情
* **Part-5:** Oracle DB 实例
* **Part-6:** 可更新的包
1. 通用系统信息
2. CPU/内存当前使用情况
3. 硬盘使用率超过 80%
4. 列出系统 WWN 详情
5. Oracle DB 实例
6. 可更新的包
我们已经基于我们的需求把可能需要到的信息加到了每个部分。之后你可以基于自己的意愿修改这个脚本。
@ -39,21 +33,19 @@ Linux 中有很多可以查看系统信息如处理器信息,生产商名字
你可以参照以前文章,了解工具详情。
* **[inxi A Great Tool to Check Hardware Information on Linux][3]**
* **[Dmidecode Easy Way To Get Linux System Hardware Information][3]**
* **[LSHW (Hardware Lister) A Nifty Tool To Get A Hardware Information On Linux][3]**
* **[hwinfo (Hardware Info) A Nifty Tool To Detect System Hardware Information On Linux][3]**
* **[python-hwinfo : Display Summary Of Hardware Information Using Standard Linux Utilities][3]**
* **[How To Use lspci, lsscsi, lsusb, And lsblk To Get Linux System Devices Information][3]**
* **[How To Check System Hardware Manufacturer, Model And Serial Number In Linux][3]**
* **[How To Find WWN, WWNN and WWPN Number Of HBA Card In Linux][3]**
* **[How to check HP iLO Firmware version from Linux command line][3]**
* **[How to check Wireless network card and WiFi information from Linux Command Line][3]**
* **[How to check CPU & Hard Disk temperature on Linux][3]**
* **[Hegemon A modular System & Hardware monitoring tool for Linux][3]**
* **[How to Check System Configuration and Hardware Information on Linux][3]**
* [inxi 在 Linux 上检查硬件信息的绝佳工具][3]
* [Dmidecode 获取 Linux 系统硬件信息的简便方法][4]
* [LSHW硬件列表程序 在 Linux 上获取硬件信息的漂亮工具][5]
* [hwinfo硬件信息 在 Linux 上检测系统硬件信息的漂亮工具][6]
* [python-hwinfo使用标准 Linux 实用工具显示硬件信息摘要][7]
* [如何使用 lspci、lsscsi、lsusb 和 lsblk 获取 Linux 系统设备信息][8]
* [如何在 Linux 中检查系统硬件制造商、型号和序列号][9]
* [如何在 Linux 中查找 HBA 卡的 WWN、WWNN 和 WWPN 号][10]
* [如何从 Linux 命令行检查 HP iLO 固件版本][11]
* [如何从 Linux 命令行检查无线网卡和 WiFi 信息][12]
* [如何在 Linux 上检查 CPU 和硬盘温度][13]
* [Hegemon Linux 的模块化系统和硬件监视工具][14]
* [如何在 Linux 上检查系统配置和硬件信息][15]
如果你想为这个脚本增加其他的信息,请在评论去留下你的需求,以便我们帮助你。
@ -62,8 +54,10 @@ Linux 中有很多可以查看系统信息如处理器信息,生产商名字
这个脚本会在你每次登录 shell 时把系统信息打印到 terminal。
```
#vi /opt/scripts/system-info.sh
# vi /opt/scripts/system-info.sh
```
```
#!/bin/bash
echo -e "-------------------------------System Information----------------------------"
echo -e "Hostname:\t\t"`hostname`
@ -90,12 +84,12 @@ df -Ph | sed s/%//g | awk '{ if($5 > 80) print $0;}'
echo ""
echo -e "-------------------------------For WWN Details-------------------------------"
vserver=$(lscpu | grep vendor | wc -l)
vserver=$(lscpu | grep Hypervisor | wc -l)
if [ $vserver -gt 0 ]
then
echo "$(hostname) is a VM"
else
systool -c fc_host -v | egrep "(Class Device path | port_name |port_state)" > systool.out
cat /sys/class/fc_host/host?/port_name
fi
echo ""
@ -120,37 +114,37 @@ echo -e "-----------------------------------------------------------------------
fi
```
把上面脚本内容保存到一个文件 "system-info.sh",之后添加可执行权限
把上面脚本内容保存到一个文件 `system-info.sh`,之后添加可执行权限:
```
# chmod +x ~root/system-info.sh
```
当脚本准备好后,把脚本文件的路径加到 ".bash_profile" 文件末尾红帽系列的系统CentOSOracle Linux 和 Fedora
当脚本准备好后,把脚本文件的路径加到 `.bash_profile` 文件末尾红帽系列的系统CentOS、Oracle Linux 和 Fedora
```
# echo "/root/system-info.sh" >> ~root/.bash_profile
```
执行以下命令,来让修改的内容生效
执行以下命令,来让修改的内容生效
```
# source ~root/.bash_profile
```
对于 Debian 系统的系统,你可能需要把文件路径加到 ".profile" 文件中。
对于 Debian 系统的系统,你可能需要把文件路径加到 `.profile` 文件中:
```
# echo "/root/system-info.sh" >> ~root/.profile
```
运行以下命令使修改生效
运行以下命令使修改生效
```
# source ~root/.profile
```
你以前运行上面 "source" 命令时可能见过类似下面的输出。从下次开始,你在每次登录 shell 时会看到这些信息。当然,如果有必要你也可以随时手动执行这个脚本。
你以前运行上面 `source` 命令时可能见过类似下面的输出。从下次开始,你在每次登录 shell 时会看到这些信息。当然,如果有必要你也可以随时手动执行这个脚本。
```
-------------------------------System Information---------------------------
@ -203,7 +197,7 @@ via: https://www.2daygeek.com/bash-shell-script-view-linux-system-information/
作者:[Magesh Maruthamuthu][a]
选题:[lujun9972][b]
译者:[lxbwolf](https://github.com/lxbwolf)
校对:[校对者ID](https://github.com/校对者ID)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
@ -212,3 +206,15 @@ via: https://www.2daygeek.com/bash-shell-script-view-linux-system-information/
[1]: https://www.2daygeek.com/category/shell-script/
[2]: https://www.2daygeek.com/category/bash-script/
[3]: https://www.2daygeek.com/inxi-system-hardware-information-on-linux/
[4]: https://www.2daygeek.com/dmidecode-get-print-display-check-linux-system-hardware-information/
[5]: https://www.2daygeek.com/lshw-find-check-system-hardware-information-details-linux/
[6]: https://www.2daygeek.com/hwinfo-check-display-detect-system-hardware-information-linux/
[7]: https://www.2daygeek.com/python-hwinfo-check-display-system-hardware-configuration-information-linux/
[8]: https://www.2daygeek.com/check-system-hardware-devices-bus-information-lspci-lsscsi-lsusb-lsblk-linux/
[9]: https://www.2daygeek.com/how-to-check-system-hardware-manufacturer-model-and-serial-number-in-linux/
[10]: https://www.2daygeek.com/how-to-find-wwn-wwnn-and-wwpn-number-of-hba-card-in-linux/
[11]: https://www.2daygeek.com/how-to-check-hp-ilo-firmware-version-from-linux-command-line/
[12]: https://www.2daygeek.com/linux-find-out-wireless-network-wifi-speed-signal-strength-quality/
[13]: https://www.2daygeek.com/view-check-cpu-hard-disk-temperature-linux/
[14]: https://www.2daygeek.com/hegemon-a-modular-system-and-hardware-monitoring-tool-for-linux/
[15]: https://www.2daygeek.com/check-linux-hardware-information-system-configuration/

View File

@ -0,0 +1,62 @@
[#]: collector: (lujun9972)
[#]: translator: ( )
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
[#]: subject: (Amazon joins the quantum computing crowd with Braket testbed)
[#]: via: (https://www.networkworld.com/article/3487421/amazon-joins-the-quantum-computing-crowd-with-braket-testbed.html)
[#]: author: (Jon Gold https://www.networkworld.com/author/Jon-Gold/)
Amazon joins the quantum computing crowd with Braket testbed
======
The newest part of AWS huge public-cloud ecosystem is Braket, a way for companies to experiment with quantum computing without having to own quantum computers.
Vizio
Amazons initial foray into the heavily hyped world of [quantum computing][1] is a virtual sandbox in which companies can test potential quantum-enabled applications and generally get to grips with the new technology, the company announced Monday.
The product is named Braket, after a system of notation used in quantum physics. The idea, according to Amazon, is to democratize access to quantum computing in a small way. Most organizations arent going to own their own quantum computers for the foreseeable future; theyre impractically expensive and require a huge amount of infrastructure even for the limited proof-of-concept models at the current cutting-edge.
[10 of the world's fastest supercomputers][2]
Hence, providing cloud-based access to three of those proofs-of-concept the D-Wave 2000Q, Rigetti 16Q , Aspen-4 and IonQ linear ion trap offers businesses the opportunity to learn firsthand about the way qubits work and how the basic building blocks of quantum programming might look. Braket will let users work remotely with those quantum computers or try out quantum algorithms in a classically driven simulated environment.
[][3]
BrandPost Sponsored by HPE
[Take the Intelligent Route with Consumption-Based Storage][3]
Combine the agility and economics of HPE storage with HPE GreenLake and run your IT department with efficiency.
“Our goal is to make sure you know enough about quantum computing to start looking for some appropriate use cases and conducting some tests and experiments,” said chief AWS evangelist Jeff Barr in [a blog post][4].
To help guide those efforts, Amazon also announced that it would form the AWS Center for Quantum Computing in partnership with Cal Tech. The idea here seems to be to create a center of excellence for research into both how quantum computers can be put to use and how they can be manufactured on a slightly larger scale. Furthermore, the new Amazon Quantum Solutions Lab would allow for a collaborative space in which companies can partner to share newfound expertise in quantum computing, as well as workshops and brainstorming sessions for education on quantum topics.
“Quantum computing is rapidly evolving, but the limited scale of the quantum hardware available today, fragmented development tools, and general shortage of quantum expertise, make it difficult to build near-term quantum applications,” said Amazon in a statement.
Quantum computing technology is still in the very early stages of development something like classical computing in the days of the Bletchley Park codebreaking machines, or ENIAC at the latest. Yet major tech companies have been eager to grab headlines in the field. Google boasted in October of [having achieved quantum supremacy][5], the ability to solve a problem with a quantum computer more quickly than with a classical one.
This sort of cloud-based quantum testbed isnt a wholly new idea. IBM has offered its Q Experience platform since 2016, and the company recently announced that more than 10 million experiments have been run there to date. And Amazons cloud rival Microsoft announced its Azure Quantum service just last month, offering a similar combination of cloud access, quantum programming tools, and remote access to prototype quantum computers.
Join the Network World communities on [Facebook][6] and [LinkedIn][7] to comment on topics that are top of mind.
--------------------------------------------------------------------------------
via: https://www.networkworld.com/article/3487421/amazon-joins-the-quantum-computing-crowd-with-braket-testbed.html
作者:[Jon Gold][a]
选题:[lujun9972][b]
译者:[译者ID](https://github.com/译者ID)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://www.networkworld.com/author/Jon-Gold/
[b]: https://github.com/lujun9972
[1]: https://www.networkworld.com/article/3275367/what-s-quantum-computing-and-why-enterprises-need-to-care.html
[2]: https://www.networkworld.com/article/3236875/embargo-10-of-the-worlds-fastest-supercomputers.html
[3]: https://www.networkworld.com/article/3440100/take-the-intelligent-route-with-consumption-based-storage.html?utm_source=IDG&utm_medium=promotions&utm_campaign=HPE20773&utm_content=sidebar ( Take the Intelligent Route with Consumption-Based Storage)
[4]: https://aws.amazon.com/blogs/aws/amazon-braket-get-started-with-quantum-computing/
[5]: https://www.networkworld.com/article/3447743/google-claims-quantum-supremacy-over-supercomputers.html
[6]: https://www.facebook.com/NetworkWorld/
[7]: https://www.linkedin.com/company/network-world

View File

@ -0,0 +1,157 @@
[#]: collector: (lujun9972)
[#]: translator: ( )
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
[#]: subject: (Java vs. Python: Which should you choose?)
[#]: via: (https://opensource.com/article/19/12/java-vs-python)
[#]: author: (Archit Modi https://opensource.com/users/architmodi)
Java vs. Python: Which should you choose?
======
Compare the two most popular programming languages in the world, and let
us know which one you prefer in our poll.
![Developing code.][1]
Let's compare the two most popular and powerful programming languages in the world: Java and Python! Both languages have huge community support and libraries to perform almost any programming task, although selecting a programming language usually depends on the developer's use case. After you compare and contrast, please make sure to answer our poll to [share your opinion][2] on which is best.
### What is it?
* **Java** is a general-purpose object-oriented programming language used mostly for developing a wide range of applications from mobile to web to enterprise apps.
* **Python** is a high-level object-oriented programming language used mostly for web development, artificial intelligence, machine learning, automation, and other data science applications.
### Creator
* **Java** was created by James Gosling (Sun Microsystems).
* **Python** was created by Guido van Rossum.
### Open source status
* **Java** is free and (mostly) open source except for corporate use.
* **Python** is free and open source for all use cases.
### Platform dependencies
* **Java** is platform-independent (although JVM isn't) per its WORA ("write once, run anywhere") philosophy.
* **Python** is platform-dependent.
### Compiled or interpreted
* **Java** is a compiled language. Java programs are translated to byte code at compile time and not runtime.
* **Python** is an interpreted language. Python programs are translated at runtime.
### File creation
* **Java**: After compilation, **<filename>.class** is generated.
* **Python**: During runtime, **<filename>.pyc** is created.
### Errors types
* **Java** has ****2 ****types of errors: compile and runtime errors.
* **Python** has 1 error type: traceback (or runtime) error.
### Statically or dynamically typed
* **Java** is statically typed. When initiating variables, their types need to be specified in the program because type checking is done at compile time.
* **Python** is dynamically typed. Variables don't need to have a type specified when initiated because type checking is done at runtime.
### Syntax
* **Java**: Every statement needs to end with a semicolon ( **;** ), and blocks of code are separated by curly braces ( **{}** ).
* **Python**: Blocks of code are separated by indentation (the user can choose how many white spaces to use, but it should be consistent throughout the block).
### Number of classes
* **Java**: Only one public top-level class can exist in a single file in Java.
* **Python**: Any number of classes can exist in a single file in Python.
### More or less code?
* **Java** generally involves writing more lines of code compared to Python.
* **Python** involves writing fewer lines of code compared to Java.
### Multiple inheritance
* **Java** does not support multiple inheritance (inheriting from two or more base classes)
* **Python** supports multiple inheritance although it is rarely implemented due to various issues like inheritance complexity, hierarchy, dependency issues, etc.
### Multi-threading
* **Java** multi-threading can support two or more concurrent threads running at the same time.
* **Python** uses a global interpreter lock (GIL), allowing only a single thread (CPU core) to run at a time.
### Execution speed
* **Java** is usually faster in execution time than Python.
* **Python** is usually slower in execution time than Java.
### Hello world in Java
```
public class Hello {
   public static void main([String][3][] args) {
      [System][4].out.println("Hello Opensource.com from Java!");
   }
}
```
### Hello world in Python
```
`print("Hello Opensource.com from Java!")`
```
### Run the programs
![Java vs. Python][5]
To run the java program "Hello.java" you need to compile it first which creates a "Hello.class" file. To run just the class name, use "java Hello." For Python, you would just run the file "python3 helloworld.py."
--------------------------------------------------------------------------------
via: https://opensource.com/article/19/12/java-vs-python
作者:[Archit Modi][a]
选题:[lujun9972][b]
译者:[译者ID](https://github.com/译者ID)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://opensource.com/users/architmodi
[b]: https://github.com/lujun9972
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/code_development_programming.png?itok=M_QDcgz5 (Developing code.)
[2]: tmp.Bpi8QYfp8j#poll
[3]: http://www.google.com/search?hl=en&q=allinurl%3Adocs.oracle.com+javase+docs+api+string
[4]: http://www.google.com/search?hl=en&q=allinurl%3Adocs.oracle.com+javase+docs+api+system
[5]: https://opensource.com/sites/default/files/uploads/python-java-hello-world_0.png (Java vs. Python)

View File

@ -1,347 +0,0 @@
[#]: collector: (lujun9972)
[#]: translator: (hanwckf)
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
[#]: subject: (Debugging Software Deployments with strace)
[#]: via: (https://theartofmachinery.com/2019/11/14/deployment_debugging_strace.html)
[#]: author: (Simon Arneaud https://theartofmachinery.com)
Debugging Software Deployments with strace
======
Most of my paid work involves deploying software systems, which means I spend a lot of time trying to answer the following questions:
* This software works on the original developers machine, so why doesnt it work on mine?
* This software worked on my machine yesterday, so why doesnt it work today?
Thats a kind of debugging, but its a different kind of debugging from normal software debugging. Normal debugging is usually about the logic of the code, but deployment debugging is usually about the interaction between the code and its environment. Even when the root cause is a logic bug, the fact that the software apparently worked on another machine means that the environment is usually involved somehow.
So, instead of using normal debugging tools like `gdb`, I have another toolset for debugging deployments. My favourite tool for “Why isnt this software working on this machine?” is `strace`.
### What is `strace`?
[`strace`][1] is a tool for “system call tracing”. Its primarily a Linux tool, but you can do the same kind of debugging tricks with tools for other systems (such as [DTrace][2] and [ktrace][3]).
The basic usage is very simple. Just run it against a command and it dumps all the system calls (youll probably need to install `strace` first):
```
$ strace echo Hello
...Snip lots of stuff...
write(1, "Hello\n", 6) = 6
close(1) = 0
close(2) = 0
exit_group(0) = ?
+++ exited with 0 +++
```
What are these system calls? Theyre like the API for the operating system kernel. Once upon a time, software used to have direct access to the hardware it ran on. If it needed to display something on the screen, for example, it could twiddle with ports and/or memory-mapped registers for the video hardware. That got chaotic when multitasking computer systems became popular because different applications would “fight” over hardware, and bugs in one application could crash other applications, or even bring down the whole system. So CPUs started supporting different privilege modes (or “protection rings”). They let an operating system kernel run in the most privileged mode with full hardware access, while spawning less-privileged software applications that must ask the kernel to interact with the hardware for them using system calls.
At the binary level, making a system call is a bit different from making a simple function call, but most programs use wrappers in a standard library. E.g. the POSIX C standard library contains a `write()` function call that contains all the architecture-dependent code for making the `write` system call.
![][4]
In short, an applications interaction with its environment (the computer system) is all done through system calls. So when software works on one machine but not another, looking at system call traces is a good way to find whats wrong. More specifically, here are the typical things you can analyse using a system call trace:
* Console input and output (IO)
* Network IO
* Filesystem access and file IO
* Process/thread lifetime management
* Raw memory management
* Access to special device drivers
### When can `strace` be used?
In theory, `strace` can be used with any userspace program because all userspace programs have to make system calls. Its more effective with compiled, lower-level programs, but still works with high-level languages like Python if you can wade through the extra noise from the runtime environment and interpreter.
`strace` shines with debugging software that works fine on one machine, but on another machine fails with a vague error message about files or permissions or failure to run some command or something. Unfortunately, its not so great with higher-level problems, like a certificate verification failure. They usually need a combination of `strace`, sometimes [`ltrace`][5], and higher-level tooling (like the `openssl` command line tool for certificate debugging).
The examples in this post are based on a standalone server, but system call tracing can often be done on more complicated deployment platforms, too. Just search for appropriate tooling.
### A simple debugging example
Lets say youre trying to run an awesome server application called foo, but heres what happens:
```
$ foo
Error opening configuration file: No such file or directory
```
Obviously its not finding the configuration file that youve written. This can happen because package managers sometimes customise the expected locations of files when compiling an application, so following an installation guide for one distro leads to files in the wrong place on another distro. You could fix the problem in a few seconds if only the error message told you where the configuration file is expected to be, but it doesnt. How can you find out?
If you have access to the source code, you could read it and work it out. Thats a good fallback plan, but not the fastest solution. You also could use a stepping debugger like `gdb` to see what the program does, but its more efficient to use a tool thats specifically designed to show the interaction with the environment: `strace`.
The output of `strace` can be a bit overwhelming at first, but the good news is that you can ignore most of it. It often helps to use the `-o` switch to save the trace to a separate file:
```
$ strace -o /tmp/trace foo
Error opening configuration file: No such file or directory
$ cat /tmp/trace
execve("foo", ["foo"], 0x7ffce98dc010 /* 16 vars */) = 0
brk(NULL) = 0x56363b3fb000
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=25186, ...}) = 0
mmap(NULL, 25186, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f2f12cf1000
close(3) = 0
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\260A\2\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=1824496, ...}) = 0
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f2f12cef000
mmap(NULL, 1837056, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f2f12b2e000
mprotect(0x7f2f12b50000, 1658880, PROT_NONE) = 0
mmap(0x7f2f12b50000, 1343488, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x22000) = 0x7f2f12b50000
mmap(0x7f2f12c98000, 311296, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x16a000) = 0x7f2f12c98000
mmap(0x7f2f12ce5000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1b6000) = 0x7f2f12ce5000
mmap(0x7f2f12ceb000, 14336, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f2f12ceb000
close(3) = 0
arch_prctl(ARCH_SET_FS, 0x7f2f12cf0500) = 0
mprotect(0x7f2f12ce5000, 16384, PROT_READ) = 0
mprotect(0x56363b08b000, 4096, PROT_READ) = 0
mprotect(0x7f2f12d1f000, 4096, PROT_READ) = 0
munmap(0x7f2f12cf1000, 25186) = 0
openat(AT_FDCWD, "/etc/foo/config.json", O_RDONLY) = -1 ENOENT (No such file or directory)
dup(2) = 3
fcntl(3, F_GETFL) = 0x2 (flags O_RDWR)
brk(NULL) = 0x56363b3fb000
brk(0x56363b41c000) = 0x56363b41c000
fstat(3, {st_mode=S_IFCHR|0620, st_rdev=makedev(0x88, 0x8), ...}) = 0
write(3, "Error opening configuration file"..., 60) = 60
close(3) = 0
exit_group(1) = ?
+++ exited with 1 +++
```
The first page or so of `strace` output is typically low-level process startup. (You can see a lot of `mmap`, `mprotect`, `brk` calls for things like allocating raw memory and mapping dynamic libraries.) Actually, when debugging an error, `strace` output is best read from the bottom up. You can see the `write` call that outputs the error message at the end. If you work up, the first failing system call is the `openat` call that fails with `ENOENT` (“No such file or directory”) trying to open `/etc/foo/config.json`. And now we know where the configuration file is supposed to be.
Thats a simple example, but Id say at least 90% of the time I use `strace`, Im not doing anything more complicated. Heres the complete debugging formula step-by-step:
1. Get frustrated by a vague system-y error message from a program
2. Run the program again with `strace`
3. Find the error message in the trace
4. Work upwards to find the first failing system call
Theres a very good chance the system call in step 4 shows you what went wrong.
### Some tips
Before walking through a more complicated example, here are some useful tips for using `strace` effectively:
#### `man` is your friend
On many *nix systems, you can get a list of all kernel system calls by running `man syscalls`. Youll see things like `brk(2)`, which means you can get more information by running `man 2 brk`.
One little gotcha: `man 2 fork` shows me the man page for the `fork()` wrapper in GNU `libc`, which is actually now implemented using the `clone` system call instead. The semantics of `fork` are the same, but if I write a program using `fork()` and `strace` it, I wont find any `fork` calls in the trace, just `clone` calls. Gotchas like that are only confusing if youre comparing source code to `strace` output.
#### Use `-o` to save output to a file
`strace` can generate a lot of output so its often helpful to store the trace in a separate file (as in the example above). It also avoids mixing up program output with `strace` output in the console.
#### Use `-s` to see more argument data
You might have noticed that the second part of the error message doesnt appear in the example trace above. Thats because `strace` only shows the first 32 bytes of string arguments by default. If you need to capture more, add something like `-s 128` to the `strace` invocation.
#### `-y` makes it easier to track files/sockets/etc
“Everything is a file” means *nix systems do all IO using file descriptors, whether its to an actual file or over networks or through interprocess pipes. Thats convenient for programming, but makes it harder to follow whats really going on when you see generic `read` and `write` in the system call trace.
Adding the `-y` switch makes `strace` annotate every file descriptor in the output with a note about what it points to.
#### Attach to an already-running process with `-p`
As well see in the example later, sometimes you want to trace a program thats already running. If you know its running as process 1337 (say, by looking at the output of `ps`), you can trace it like this:
```
$ strace -p 1337
...system call trace output...
```
You probably need root.
#### Use `-f` to follow child processes
By default, `strace` only traces the one process. If that process spawns a child process, youll see the system call for spawning the process (normally `clone` nowadays), but not any of the calls made by the child process.
If you think the bug is in a child process, youll need to use the `-f` switch to enable tracing it. A downside is that the output can be more confusing. When tracing one process and one thread, `strace` can show you a single stream of call events. When tracing multiple processes, you might see the start of a call cut off with `<unfinished ...>`, then a bunch of calls for other threads of execution, before seeing the end of the original call with `<... foocall resumed>`. Alternatively, you can separate all the traces into different files by using the `-ff` switch as well (see [the `strace` manual][6] for details).
#### You can filter the trace with `-e`
As youve seen, the default trace output is a firehose of all system calls. You can filter which calls get traced using the `-e` flag (see [the `strace` manual][6]). The main advantage is that its faster to run the program under a filtered `strace` than to trace everything and `grep` the results later. Honestly, I dont bother most of the time.
#### Not all errors are bad
A simple and common example is a program searching for a file in multiple places, like a shell searching for which `bin/` directory has an executable:
```
$ strace sh -c uname
...
stat("/home/user/bin/uname", 0x7ffceb817820) = -1 ENOENT (No such file or directory)
stat("/usr/local/bin/uname", 0x7ffceb817820) = -1 ENOENT (No such file or directory)
stat("/usr/bin/uname", {st_mode=S_IFREG|0755, st_size=39584, ...}) = 0
...
```
The “last failed call before the error message” heuristic is pretty good at finding relevent errors. In any case, working from the bottom up makes sense.
#### C programming guides are good for understanding system calls
Standard C library calls arent system calls, but theyre only thin layers on top. So if you understand (even just roughly) how to do something in C, its easier to read a system call trace. For example, if youre having trouble debugging networking system calls, you could try skimming through [Beejs classic Guide to Network Programming][7].
### A more complicated debugging example
As I said, that simple debugging example is representative of most of my `strace` usage. However, sometimes a little more detective work is required, so heres a slightly more complicated (and real) example.
[`bcron`][8] is a job scheduler thats yet another implementation of the classic *nix `cron` daemon. Its been installed on a server, but heres what happens when someone tries to edit a job schedule:
```
# crontab -e -u logs
bcrontab: Fatal: Could not create temporary file
```
Okay, so bcron tried to write some file, but it couldnt, and isnt telling us why. This is a debugging job for `strace`:
```
# strace -o /tmp/trace crontab -e -u logs
bcrontab: Fatal: Could not create temporary file
# cat /tmp/trace
...
openat(AT_FDCWD, "bcrontab.14779.1573691864.847933", O_RDONLY) = 3
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f82049b4000
read(3, "#Ansible: logsagg\n20 14 * * * lo"..., 8192) = 150
read(3, "", 8192) = 0
munmap(0x7f82049b4000, 8192) = 0
close(3) = 0
socket(AF_UNIX, SOCK_STREAM, 0) = 3
connect(3, {sa_family=AF_UNIX, sun_path="/var/run/bcron-spool"}, 110) = 0
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f82049b4000
write(3, "156:Slogs\0#Ansible: logsagg\n20 1"..., 161) = 161
read(3, "32:ZCould not create temporary f"..., 8192) = 36
munmap(0x7f82049b4000, 8192) = 0
close(3) = 0
write(2, "bcrontab: Fatal: Could not creat"..., 49) = 49
unlink("bcrontab.14779.1573691864.847933") = 0
exit_group(111) = ?
+++ exited with 111 +++
```
Theres the error message `write` near the end, but a couple of things are different this time. First, theres no relevant system call error that happens before it. Second, we see that the error message has just been `read` from somewhere else. It looks like the real problem is happening somewhere else, and `bcrontab` is just replaying the message.
If you look at `man 2 read`, youll see that the first argument (the 3) is a file descriptor, which is what *nix uses for all IO handles. How do you know what file descriptor 3 represents? In this specific case, you could run `strace` with the `-y` switch (as explained above) and it would tell you automatically, but its useful to know how to read and analyse traces to figure things like this out.
A file descriptor can come from one of many system calls (depending on whether its a descriptor for the console, a network socket, an actual file, or something else), but in any case we can search for calls returning 3 (i.e., search for “= 3” in the trace). There are two in this trace: the `openat` at the top, and the `socket` in the middle. `openat` opens a file, but the `close(3)` afterwards shows that it gets closed again. (Gotcha: file descriptors can be reused as theyre opened and closed.) The `socket` call is the relevant one (its the last one before the `read`), which tells us `bcrontab` is talking to something over a network socket. The next line, `connect` shows file descriptor 3 being configured as a Unix domain socket connection to `/var/run/bcron-spool`.
So now we need to figure out whats listening on the other side of the Unix socket. There are a couple of neat tricks for that, both useful for debugging server deployments. One is to use `netstat` or the newer `ss` (“socket status”). Both commands describe active network sockets on the system, and take the `-l` switch for describing listening (server) sockets, and the `-p` switch to get information about what program is using the socket. (There are many more useful options, but those two are enough to get this job done.)
```
# ss -pl | grep /var/run/bcron-spool
u_str LISTEN 0 128 /var/run/bcron-spool 1466637 * 0 users:(("unixserver",pid=20629,fd=3))
```
That tells us that the listener is a command `unixserver` running as process ID 20629. (Its a coincidence that its also using file descriptor 3 for the socket.)
The second really useful tool for finding the same information is `lsof`. It can list all open files (or file descriptors) on the system. Alternatively, we can get information about a specific file:
```
# lsof /var/run/bcron-spool
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
unixserve 20629 cron 3u unix 0x000000005ac4bd83 0t0 1466637 /var/run/bcron-spool type=STREAM
```
Process 20629 is a long-running server, so we can attach `strace` to it using something like `strace -o /tmp/trace -p 20629`. If we then try to edit the cron schedule in another terminal, we can capture a trace while the error is happening. Heres the result:
```
accept(3, NULL, NULL) = 4
clone(child_stack=NULL, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7faa47c44810) = 21181
close(4) = 0
accept(3, NULL, NULL) = ? ERESTARTSYS (To be restarted if SA_RESTART is set)
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=21181, si_uid=998, si_status=0, si_utime=0, si_stime=0} ---
wait4(0, [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], WNOHANG|WSTOPPED, NULL) = 21181
wait4(0, 0x7ffe6bc36764, WNOHANG|WSTOPPED, NULL) = -1 ECHILD (No child processes)
rt_sigaction(SIGCHLD, {sa_handler=0x55d244bdb690, sa_mask=[CHLD], sa_flags=SA_RESTORER|SA_RESTART, sa_restorer=0x7faa47ab9840}, {sa_handler=0x55d244bdb690, sa_mask=[CHLD], sa_flags=SA_RESTORER|SA_RESTART, sa_restorer=0x7faa47ab9840}, 8) = 0
rt_sigreturn({mask=[]}) = 43
accept(3, NULL, NULL) = 4
clone(child_stack=NULL, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7faa47c44810) = 21200
close(4) = 0
accept(3, NULL, NULL) = ? ERESTARTSYS (To be restarted if SA_RESTART is set)
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=21200, si_uid=998, si_status=111, si_utime=0, si_stime=0} ---
wait4(0, [{WIFEXITED(s) && WEXITSTATUS(s) == 111}], WNOHANG|WSTOPPED, NULL) = 21200
wait4(0, 0x7ffe6bc36764, WNOHANG|WSTOPPED, NULL) = -1 ECHILD (No child processes)
rt_sigaction(SIGCHLD, {sa_handler=0x55d244bdb690, sa_mask=[CHLD], sa_flags=SA_RESTORER|SA_RESTART, sa_restorer=0x7faa47ab9840}, {sa_handler=0x55d244bdb690, sa_mask=[CHLD], sa_flags=SA_RESTORER|SA_RESTART, sa_restorer=0x7faa47ab9840}, 8) = 0
rt_sigreturn({mask=[]}) = 43
accept(3, NULL, NULL
```
(The last `accept` doesnt complete during the trace period.) Unfortunately, once again, this trace doesnt contain the error were after. We dont see any of the messages that we saw `bcrontab` sending to and receiving from the socket. Instead, we see a lot of process management (`clone`, `wait4`, `SIGCHLD`, etc.). This process is spawning a child process, which we can guess is doing the real work. If we want to catch a trace of that, we have to add `-f` to the `strace` invocation. Heres what we find if we search for the error message after getting a new trace with `strace -f -o /tmp/trace -p 20629`:
```
21470 openat(AT_FDCWD, "tmp/spool.21470.1573692319.854640", O_RDWR|O_CREAT|O_EXCL, 0600) = -1 EACCES (Permission denied)
21470 write(1, "32:ZCould not create temporary f"..., 36) = 36
21470 write(2, "bcron-spool[21470]: Fatal: logs:"..., 84) = 84
21470 unlink("tmp/spool.21470.1573692319.854640") = -1 ENOENT (No such file or directory)
21470 exit_group(111) = ?
21470 +++ exited with 111 +++
```
Now were getting somewhere. Process ID 21470 is getting a permission denied error trying to create a file at the path `tmp/spool.21470.1573692319.854640` (relative to the current working directory). If we just knew the current working directory, we would know the full path and could figure out why the process cant create create its temporary file there. Unfortunately, the process has already exited, so we cant just use `lsof -p 21470` to find out the current directory, but we can work backwards looking for PID 21470 system calls that change directory. (If there arent any, PID 21470 must have inherited it from its parent, and we can `lsof -p` that.) That system call is `chdir` (which is easy to find out using todays web search engines). Heres the result of working backwards through the trace, all the way to the server PID 20629:
```
20629 clone(child_stack=NULL, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7faa47c44810) = 21470
...
21470 execve("/usr/sbin/bcron-spool", ["bcron-spool"], 0x55d2460807e0 /* 27 vars */) = 0
...
21470 chdir("/var/spool/cron") = 0
...
21470 openat(AT_FDCWD, "tmp/spool.21470.1573692319.854640", O_RDWR|O_CREAT|O_EXCL, 0600) = -1 EACCES (Permission denied)
21470 write(1, "32:ZCould not create temporary f"..., 36) = 36
21470 write(2, "bcron-spool[21470]: Fatal: logs:"..., 84) = 84
21470 unlink("tmp/spool.21470.1573692319.854640") = -1 ENOENT (No such file or directory)
21470 exit_group(111) = ?
21470 +++ exited with 111 +++
```
(If youre getting lost here, you might want to read [my previous post about *nix process management and shells][9].) Okay, so the server PID 20629 doesnt have permission to create a file at `/var/spool/cron/tmp/spool.21470.1573692319.854640`. The most likely reason would be classic *nix filesystem permission settings. Lets check:
```
# ls -ld /var/spool/cron/tmp/
drwxr-xr-x 2 root root 4096 Nov 6 05:33 /var/spool/cron/tmp/
# ps u -p 20629
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
cron 20629 0.0 0.0 2276 752 ? Ss Nov14 0:00 unixserver -U /var/run/bcron-spool -- bcron-spool
```
Theres the problem! The server is running as user `cron`, but only `root` has permissions to write to that `/var/spool/cron/tmp/` directory. A simple `chown cron /var/spool/cron/tmp/` makes `bcron` work properly. (If that werent the problem, the next most likely suspect would be a kernel security module like SELinux or AppArmor, so Id check the kernel logs with `dmesg`.)
### Summary
System call traces can be overwhelming at first, but I hope Ive shown that theyre a fast way to debug a whole class of common deployment problems. Imagine trying to debug that multi-process `bcron` problem using a stepping debugger.
Working back through a chain of system calls takes practice, but as I said, most of the time I use `strace` I just get a trace and look for errors, working from the bottom up. In any case, `strace` has saved me hours and hours of debugging time. I hope its useful for you, too.
--------------------------------------------------------------------------------
via: https://theartofmachinery.com/2019/11/14/deployment_debugging_strace.html
作者:[Simon Arneaud][a]
选题:[lujun9972][b]
译者:[译者ID](https://github.com/译者ID)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://theartofmachinery.com
[b]: https://github.com/lujun9972
[1]: https://strace.io/
[2]: http://dtrace.org/blogs/about/
[3]: https://man.openbsd.org/ktrace
[4]: https://theartofmachinery.com/images/strace/system_calls.svg
[5]: https://linux.die.net/man/1/ltrace
[6]: https://linux.die.net/man/1/strace
[7]: https://beej.us/guide/bgnet/html/index.html
[8]: https://untroubled.org/bcron/
[9]: https://theartofmachinery.com/2018/11/07/writing_a_nix_shell.html

View File

@ -1,5 +1,5 @@
[#]: collector: (lujun9972)
[#]: translator: ( )
[#]: translator: (lxbwolf)
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )

View File

@ -4,7 +4,7 @@
[#]: publisher: ( )
[#]: url: ( )
[#]: subject: (How to write a security integration module for Ansible)
[#]: via: (https://opensource.com/article/19/12/how-write-security-integration-module-ansible)
[#]: via: (https://opensource.com/article/19/12/security-ansible-module)
[#]: author: (Adam Miller https://opensource.com/users/maxamillion)
How to write a security integration module for Ansible
@ -149,7 +149,7 @@ If you have questions about Ansible module development models, feel free to reac
--------------------------------------------------------------------------------
via: https://opensource.com/article/19/12/how-write-security-integration-module-ansible
via: https://opensource.com/article/19/12/security-ansible-module
作者:[Adam Miller][a]
选题:[lujun9972][b]

View File

@ -0,0 +1,131 @@
[#]: collector: (lujun9972)
[#]: translator: ( )
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
[#]: subject: (Solutions to the tiny window manager challenge)
[#]: via: (https://jvns.ca/blog/2019/12/03/solutions-to-the-tiny-window-manager-challenge/)
[#]: author: (Julia Evans https://jvns.ca/)
Solutions to the tiny window manager challenge
======
Hello! Last week I posted a small [programming challenge to write a tiny window manager that bounces windows around the screen][1].
![][2]
Ill write a bit about my experience of solving the challenge, or you can just skip to the end to see the solutions.
### whats a window manager?
An X window manager is a program that sends messages to the X server (which is in charge of drawing your windows) to tell it which windows to display and where.
I found out that you can trace those events with `xtrace`. Heres some example output from xtrace (for the toy window manager which is just moving windows about)
```
000:<:02d8: 20: Request(12): ConfigureWindow window=0x004158e5 values={x=560 y=8}
000:<:02da: 20: Request(12): ConfigureWindow window=0x004158e5 values={x=554 y=12}
000:<:02dc: 20: Request(12): ConfigureWindow window=0x004158e5 values={x=548 y=16}
000:<:02de: 20: Request(12): ConfigureWindow window=0x004158e5 values={x=542 y=20}
000:<:02e0: 20: Request(12): ConfigureWindow window=0x004158e5 values={x=536 y=24}
000:<:02e2: 20: Request(12): ConfigureWindow window=0x004158e5 values={x=530 y=28}
000:<:02e4: 20: Request(12): ConfigureWindow window=0x004158e5 values={x=524 y=32}
```
### you can run programs without a window manager
You technically dont _need_ a window manager to run graphical programs if you want to start an xterm in a window-manager-less X session you can just run
```
xterm -display :1
```
and itll start the xterm. Heres a screenshot of an X session with no window manager open. I even have 2 windows open! (chrome and an xterm). It has some major usability problems, for example I dont think you can resize or move or switch between windows. Which is where the window manager comes in!
<https://jvns.ca/images/no-wm.png>
### move a window with XMoveWindow
The challenge was to make the window bounce around the screen.
In the [tinywm source][3] they use `XMoveResizeWindow` to move and resize windows, but I found in the [docs][4] that theres also a function called `XMoveWindow`. Perfect!
Heres what it looks like. What could be simpler, right? And it works just the way Id expect!
```
XMoveWindow(display, windowID, x, y)
```
Except…
### problem: multiple `XMoveWindow`s dont work
I ran into a problem (which I got stuck on for a couple of hours) where when I ran XMoveWindow twice, it would only apply the last move.
```
XMoveWindow(display, windowID, 100, 200)
usleep(2000 * 1000); # sleep for 2 seconds
XMoveWindow(display, windowID, 300, 400)
```
Id expect this to move the window once, wait 2 seconds, and them move it again. But that was not what happened! Instead, it would pause for 2 seconds and then move the window once (to the second location).
### use xtrace to trace window manager events
I used xtrace to trace the events and found out that my `ConfigureWindow` events that `XMoveWindow` was sending were all being sent at the same time. So it seemed like X was batching the events. But why?
### XSync forces X to process events
I didnt know why this was happening, but I emailed Julian about it and he pointed me in the direction of [XSync][5], which forces X to process all the events youve sent it. Sure enough, I used XSync and everything worked beautifully.
### solutions
I asked people to email me if they completed the challenge, and 4 people did! Here are their solutions. All the solutions I got implemented more features than I did, so Id encourage you to look at all the solutions if youre interested in how to solve this problem!
* [Kacper Słomińskis solution][6] (which uses `XQueryTree` to find the windows to bounce, which is nice)
* [@whichxyjs solution][7]
* [Alexsey Lagoshins stressfulwm][8], which allows bouncing multiple windows:
* [Aldrin Martoq Ahumadas bouncywm-ruby][9], which is the only solution in a language other than C I got! It uses an Xlib Ruby library that looks pretty straightforward to use.
* one really nice one with fancier bouncing effects which Ill post here later if the person sends me the source
* [my solution][10]
Heres a gif of Alexseys solution. Apparently `XQuartz` on a Mac performs better than Xephyr!
![][11]
And Aldrins solution, with a great use of `xeyes`:
![][12]
### thanks!
Thanks to everyone who emailed me a solution, and if you write your own implementation Id love to post it here too, especially if you write one that isnt in C or Ruby! Im [[email protected]][13]
--------------------------------------------------------------------------------
via: https://jvns.ca/blog/2019/12/03/solutions-to-the-tiny-window-manager-challenge/
作者:[Julia Evans][a]
选题:[lujun9972][b]
译者:[译者ID](https://github.com/译者ID)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://jvns.ca/
[b]: https://github.com/lujun9972
[1]: https://jvns.ca/blog/2019/11/25/challenge--make-a-bouncy-window-manager/
[2]: https://jvns.ca/images/bouncewm.gif
[3]: http://incise.org/tinywm.html
[4]: https://tronche.com/gui/x/xlib/window/XMoveWindow.html
[5]: https://tronche.com/gui/x/xlib/event-handling/XSync.html
[6]: https://gist.github.com/jvns/d5a0a4daf300f3dd7fa76d13b5aa2d53
[7]: https://github.com/whichxjy/bounce-wm/blob/master/bounce-wm.c
[8]: https://github.com/ayzenquwe/stressfulwm
[9]: https://github.com/aldrinmartoq/bouncywm-ruby
[10]: https://gist.github.com/jvns/c7a297fc4e17e797fd7b76b68860e55c
[11]: https://raw.githubusercontent.com/ayzenquwe/stressfulwm/d06531d286a5f00424bf12f7c77b18e11437ff20/gif/example.gif
[12]: https://raw.githubusercontent.com/aldrinmartoq/bouncywm-ruby/f6d424b6107c1349c8ee338b6a46c7116c6d1ea7/demo/demo.gif
[13]: https://jvns.ca/cdn-cgi/l/email-protection

View File

@ -1,5 +1,5 @@
[#]: collector: (lujun9972)
[#]: translator: ( )
[#]: translator: (geekpi)
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )

View File

@ -0,0 +1,273 @@
[#]: collector: (lujun9972)
[#]: translator: ( )
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
[#]: subject: (4 ways to control the flow of your awk script)
[#]: via: (https://opensource.com/article/19/12/control-awk-script)
[#]: author: (Seth Kenlon https://opensource.com/users/seth)
4 ways to control the flow of your awk script
======
Learn to use switch statements and the break, continue, and next
commands to control awk scripts.
![JavaScript in Vim][1]
There are many ways to control the flow of an awk script, including [loops][2], **switch** statements and the **break**, **continue**, and **next** commands.
### Sample data
Create a sample data set called **colours.txt** and copy this content into it:
```
name       color  amount
apple      red    4
banana     yellow 6
strawberry red    3
raspberry  red    99
grape      purple 10
apple      green  8
plum       purple 2
kiwi       brown  4
potato     brown  9
pineapple  yellow 5
```
### Switch statements
The **switch** statement is a feature specific to GNU awk, so you can only use it with **gawk**. If your system or your target system doesn't have **gawk**, then you should not use a switch statement.
The **switch** statement in **gawk** is similar to the one in C and many other languages. The syntax is:
```
switch (expression) {
        case VALUE:
                &lt;do something here&gt;
        [...]
        default:
                &lt;do something here&gt;
}
```
The **expression** part can be any awk expression that returns a numeric or string result. The **VALUE** part (after the word **case**) is a numeric or string constant or a regular expression.
When a **switch** statement runs, the _expression_ is evaluated, and the result is matched against each case value. If there's a match, then the code contained within a case definition is executed. If there's no match in any case definition, then the default statement is executed.
The keyword **break** is at the end of the code in each case definition to break the loop. Without **break**, awk would continue to search for matching case values.
Here's an example **switch** statement:
```
#!/usr/bin/awk -f
#
# Example of the use of 'switch' in GNU Awk.
NR &gt; 1 {
    printf "The %s is classified as: ",$1
    switch ($1) {
        case "apple":
            print "a fruit, pome"
            break
        case "banana":
        case "grape":
        case "kiwi":
            print "a fruit, berry"
            break
                case "raspberry":
                        print "a computer, pi"
                        break
        case "plum":
            print "a fruit, drupe"
            break
        case "pineapple":
            print "a fruit, fused berries (syncarp)"
            break
        case "potato":
            print "a vegetable, tuber"
            break
        default:
            print "[unclassified]"
    }
}
```
This script notably ignores the first line of the file, which in the case of the sample data is just a header. It does this by operating only on records with an index number greater than 1. On all other records, this script compares the contents of the first field (**$1**, as you know from previous articles) to the value of each **case** definition. If there's a match, the **print** function is used to print the botanical classification of the entry. If there are no matches, then the **default** instance prints **"[unclassified]"**.
The banana, grape, and kiwi are all botanically classified as a berry, so there are three **case** definitions associated with one **print** result.
Run the script on the **colours.txt** sample file, and you should get this:
```
The apple is classified as: a fruit, pome
The banana is classified as: a fruit, berry
The strawberry is classified as: [unclassified]
The raspberry is classified as: a computer, pi
The grape is classified as: a fruit, berry
The apple is classified as: a fruit, pome
The plum is classified as: a fruit, drupe
The kiwi is classified as: a fruit, berry
The potato is classified as: a vegetable, tuber
The pineapple is classified as: a fruit, fused berries (syncarp)
```
### Break
The **break** statement is mainly used for the early termination of a **for**, **while**, or **do-while** loop or a **switch** statement. In a loop, **break** is often used where it's not possible to determine the number of iterations of the loop beforehand. Invoking **break** terminates the enclosing loop (which is relevant when there are nested loops or loops within loops).
This example, straight out of the [GNU awk manual][3], shows a method of finding the smallest divisor. Read the additional comments for a clear understanding of how the code works:
```
#!/usr/bin/awk -f
{
    num = $1
    # Make an infinite FOR loop
    for (divisor = 2; ; divisor++) {
        # If num is divisible by divisor, then break
        if (num % divisor == 0) {
            printf "Smallest divisor of %d is %d\n", num, divisor
            break
        }
        # If divisor has gotten too large, the number has no
        # divisor, so is a prime
        if (divisor * divisor &gt; num) {
            printf "%d is prime\n", num
            break
        }
    }
}
```
Try running the script to see its results:
```
    $ echo 67 | ./divisor.awk
    67 is prime
    $ echo 69 | ./divisor.awk
    Smallest divisor of 69 is 3
```
As you can see, even though the script starts out with an explicit _infinite_ loop with no end condition, the **break** function ensures that the script eventually terminates.
### Continue
The **continue** function is similar to **break**. It can be used in a **for**, **while**, or **do-while** loop (it's not relevant to a **switch** statements, though). Invoking **continue** skips the rest of the enclosing loop and begins the next cycle.
Here's another good example from the GNU awk manual to demonstrate a possible use of **continue**:
```
#!/usr/bin/awk -f
# Loop, printing numbers 0-20, except 5
BEGIN {
    for (x = 0; x &lt;= 20; x++) {
        if (x == 5)
            continue
        printf "%d ", x
    }
    print ""
}
```
This script analyzes the value of **x** before printing anything. If the value is exactly 5, then **continue** is invoked, causing the **printf** line to be skipped, but leaves the loop unbroken. Try the same code but with **break** instead to see the difference.
### Next
This statement is not related to loops like **break** and **continue** are. Instead, **next** applies to the main record processing cycle of awk: the functions you place between the BEGIN and END functions. The **next** statement causes awk to stop processing the _current input record_ and to move to the next one.
As you know from the earlier articles in this series, awk reads records from its input stream and applies rules to them. The **next** statement stops the execution of rules for the current record and moves to the next one.
Here's an example of **next** being used to "hold" information upon a specific condition:
```
#!/usr/bin/awk -f
# Ignore the header
NR == 1 { next }
# If field 2 (colour) is less than 6
# characters, then save it with its
#  line number and skip it
length($2) &lt; 6 {
    skip[NR] = $0
    next
}
# It's not the header and
# the colour name is &gt; 6 characters,
# so print the line
{
    print
}
# At the end, show what was skipped
END {
    printf "\nSkipped:\n"
    for (n in skip)
        print n": "skip[n]
}
```
This sample uses **next** in the first rule to avoid the first line of the file, which is a header row. The second rule skips lines when the color name is less than six characters long, but it also saves that line in an array called **skip**, using the line number as the key (also known as the _index_).
The third rule prints anything it sees, but it is not invoked if either rule 1 or rule 2 causes it to be skipped.
Finally, at the end of all the processing, the **END** rule prints the contents of the array.
Run the sample script on the **colours.txt** file from above (and previous articles):
```
$ ./next.awk colours.txt
banana     yellow 6
grape      purple 10
plum       purple 2
pineapple  yellow 5
Skipped:
2: apple      red    4
4: strawberry red    3
6: apple      green  8
8: kiwi       brown  4
9: potato     brown  9
```
### Control freak
In summary, **switch**, **continue**, **next**, and **break** are important preemptive exceptions to awk rules that provide greater control of your script. You don't have to use them directly; often, you can gain the same logic through other means, but they're great convenience functions that make the coder's life a lot easier. The next article in this series covers the **printf** statement.
* * *
Would you rather listen to this article? It was adapted from an episode of [Hacker Public Radio][4], a community technology podcast by hackers, for hackers.
--------------------------------------------------------------------------------
via: https://opensource.com/article/19/12/control-awk-script
作者:[Seth Kenlon][a]
选题:[lujun9972][b]
译者:[译者ID](https://github.com/译者ID)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://opensource.com/users/seth
[b]: https://github.com/lujun9972
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/javascript_vim.jpg?itok=mqkAeakO (JavaScript in Vim)
[2]: https://opensource.com/article/19/11/loops-awk
[3]: https://www.gnu.org/software/gawk/manual/
[4]: http://hackerpublicradio.org/eps.php?id=2438

View File

@ -0,0 +1,61 @@
[#]: collector: (lujun9972)
[#]: translator: ( )
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
[#]: subject: (Complementary engineering indicators)
[#]: via: (https://dave.cheney.net/2019/12/04/complementary-engineering-indicators)
[#]: author: (Dave Cheney https://dave.cheney.net/author/davecheney)
Complementary engineering indicators
======
Last year I had the opportunity to watch Cat Swetels presentation _[The Development Metrics You Should Use (but Dont)][1]_. The information that could be gleaned from just tracking the start and finish date of work items was eye opening. If youre using an issue tracker this information is probably already (perhaps with some light data munging) available — no need for TPS reports. Additionally, statistics obtained by data mining your projects issue tracker are, perhaps, less likely to be juked.
Around the time I saw Cats presentation I finished reading Andy Groves _High Output Management_. The hidden gem in this book (assuming becoming a meeting powerhouse isnt your bag) was Groves notion of indicator pairs. An example of a paired indicator might be the number of sales deals closed paired with the customer retention rate. The underling principle being optimising for one indicator will have an adverse impact on the other. In the example, overly aggressive or deceptive tactics could superficially raise the number of sales made, but would be reflected in a dip in the retention rate as customers returned the product or terminated their service prematurely.
These ideas lead me to thinking about indicators you could use for a team delivering a software product. Could those indicators be derived cheaply from the hand to hand combat of software delivery? Could they be structured in a way that aggressively pursuing one metric would be reflected negatively in another? I think so.
These are the three metrics that Ive been using to track the health of the project that I lead.
* Date; was the software done when we said it would be done. If you prefer this indicator as a scalar, how many days difference is there between the ship date agreed on at the start of the sprint/milestone/whatever and what was the actual date that you considered it done.
* Completeness; when the software is done, how many of the things we said were going to do actually got delivered in that release.
* Defects reported; once the software is in the field, what is the rate of bugs reported.
It is relatively easy, for example, to hit a delivery date if you aggressively descope anything risky or simply dont do it. But in doing so this lack of promised functionality would impact the completeness metric.
Conversely, its straight forward to hit your milestones completeness target if you let the release date slip and slip. Bringing both the metics into line requires good estimation skills to judge how much can be attempted in milestone and provide direct feedback if your estimation skills needed work.
The third indicator, defects reported in the field, acts as a check on the other two. It would be easy to consistent hit your delivery date with 100% feature completion if your team does a shoddy job. The high fives and 🎉 emojis will be short lived if each release brings with it a swathe of high priority bug reports. This indicator also tends to have a second order effect, rushed features to meet a deadline tend to generate remedial work in the following milestones, crowding out promised work or blowing later deadlines.
I consider these to be complementary metrics, they should be considered together, as a group, rather than individually. Ideally your team should be delivering what you promised, when you promised it, with a low defect rate. But more importantly, if that isnt the case, if one of the indicators is unhealthy, addressing it shouldnt result in the problem moving to another.
### Related posts:
1. [Never edit a method, always rewrite it][2]
2. [The Mythical Man-Month selection bias][3]
3. [The office coffee model of concurrent garbage collection][4]
4. [Sydney High Performance Go workshop][5]
--------------------------------------------------------------------------------
via: https://dave.cheney.net/2019/12/04/complementary-engineering-indicators
作者:[Dave Cheney][a]
选题:[lujun9972][b]
译者:[译者ID](https://github.com/译者ID)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://dave.cheney.net/author/davecheney
[b]: https://github.com/lujun9972
[1]: https://www.youtube.com/watch?v=cW3yM-K2M08
[2]: https://dave.cheney.net/2017/11/30/never-edit-a-method-always-rewrite-it (Never edit a method, always rewrite it)
[3]: https://dave.cheney.net/2013/12/04/the-mythical-man-month-selection-bias (The Mythical Man-Month selection bias)
[4]: https://dave.cheney.net/2018/12/28/the-office-coffee-model-of-concurrent-garbage-collection (The office coffee model of concurrent garbage collection)
[5]: https://dave.cheney.net/2019/07/05/sydney-high-performance-go-workshop (Sydney High Performance Go workshop)

View File

@ -0,0 +1,82 @@
[#]: collector: (lujun9972)
[#]: translator: ( )
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
[#]: subject: (Fedora Desktops Memory Footprints)
[#]: via: (https://fedoramagazine.org/fedora-desktops-memory-footprints/)
[#]: author: (Troy Dawson https://fedoramagazine.org/author/tdawson/)
Fedora Desktops Memory Footprints
======
![][1]
There are over 40 desktops in Fedora. Each desktop has its own strengths and weaknesses. Usually picking a desktop is a very personal preference based on features, looks, and other qualities. Sometimes, what you pick for a desktop is limited by hardware constraints.
This article is to help people compare Fedora desktops based on the desktop baseline memory. To narrow the scope, we are only looking at the desktops that have an official Fedora Live image.
### Installation and Setup
Each of the desktops was installed on its own KVM virtual machine. Each virtual machine had 1 CPU, 4GB of memory, 15 GB virtio solid state disk, and everything else that comes standard on RHEL 8.0 kvm.
The images for installation were the standard Fedora 31 Live images. For GNOME, that image was the Fedora Workstation. For the other desktops, the corresponding Spin was used. Sugar On A Stick (SOAS) was not tested because it does not install easily onto a local drive.
The virtual machine booted into the Live CD. “Install to Hard Disk” was selected. During the install, only the defaults were used. A root user, and a regular users were created. After installation and reboot, the Live image was verified to not be in the virtual CDROM.
The settings for each desktop was not touched. They each ran whatever settings came default from the Live CD installation. Each desktop was logged into via the regular user. A terminal was opened. Using sudo each machine ran “dnf -y update”. After update, in that sudo terminal, each machine ran “/sbin/shutdown -h now” to shut down.
### Testing
Each machine was started up. The desktop was logged into via the regular user. Three of the desktop terminals were opened. xterm was never used, it was always the terminal for that desktop, such as konsole.
In one terminal, top was started and M pressed, showing the processes sorted by memory. In another terminal, a simple while loop showed “free -m” every 30 seconds. The third terminal was idle.
I then waited 5 minutes. This allowed any startup services to finish. I recorded the final free result, as well as the final top three memory consumers from top.
### Results
* Cinnamon
* 624 MB Memory used
* cinnamon 4.8% / Xorg 2.2% / dnfdragora 1.8%
* GNOME
* 612 MB Memory used
* gnome-shell 6.9% / gnome-software 1.8% / ibus-x11 1.5%
* KDE
* 733 MB Memory used
* plasmashell 6.2% / kwin_x11 3.6% / akonadi_mailfil 2.9%
* LXDE
* 318 MB Memory used
* Xorg 1.9% / nm-applet 1.8% / dnfdragora 1.8%
* LXQt
* 391 MB Memory used
* lxqt-panel 2.2% / pcmanfm-qt 2.1% / Xorg 2.1%
* MATE
* 465 MB Memory used
* Xorg 2.5% / dnfdragora 1.8% / caja 1.5%
* XFCE
* 448 MB Memory used
* Xorg 2.3% / xfwm4 2.0% / dnfdragora 1.8%
### Conclusion
I will let the numbers speak for themselves.
Remember that these numbers are from a default Live install. If you remove, or add services and features, your memory usage will change. But this is a good baseline to look at if you are determining your desktop based on memory consumption.
--------------------------------------------------------------------------------
via: https://fedoramagazine.org/fedora-desktops-memory-footprints/
作者:[Troy Dawson][a]
选题:[lujun9972][b]
译者:[译者ID](https://github.com/译者ID)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://fedoramagazine.org/author/tdawson/
[b]: https://github.com/lujun9972
[1]: https://fedoramagazine.org/wp-content/uploads/2019/11/desktop-memory-footprint-816x346.jpg

View File

@ -0,0 +1,68 @@
[#]: collector: (lujun9972)
[#]: translator: ( )
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
[#]: subject: (Spice up your Linux desktop with Cinnamon)
[#]: via: (https://opensource.com/article/19/12/cinnamon-linux-desktop)
[#]: author: (Seth Kenlon https://opensource.com/users/seth)
Spice up your Linux desktop with Cinnamon
======
This article is part of a special series of 24 days of Linux desktops.
Just like its namesake, the Cinnamon Linux desktop is warm and inviting
and cozy.
![Cinnamon][1]
When GNOME 3 was released, some GNOME users were not ready to give up GNOME 2. The [Linux Mint][2] project was so dissatisfied with GNOME 3 that it started its own desktop as an alternative, and thus the [Cinnamon][3] desktop was born.
Cinnamon originally sought to "remix" GNOME 3 so that it looked and acted like the GNOME 2 so many users knew and loved, but eventually, it diverged enough to be a true fork. Today, Cinnamon uses GTK3 libraries and forked versions of key GNOME 3 applications to create a classic GNOME experience.
You may find Cinnamon in your distribution's software repository, or you can download and install a distribution that ships with Cinnamon as its default desktop. Before you do, though, be aware that it is meant to provide a full desktop experience, so many Cinnamon apps are installed along with the desktop. If you're already running a different desktop, you may find yourself with redundant applications (two PDF readers, two media players, two file managers, and so on).
If you just want to try the Cinnamon desktop, you can install a Cinnamon-based distribution in a virtual machine, such as [GNOME Boxes][4].
### Cinnamon desktop tour
The Cinnamon desktop layout has a classic look, although—in spite of being inspired by GNOME 2—that look is not at all like GNOME 2. In fact, it shares more with KDE's Plasma desktop than with GNOME 2, with an application menu in the lower-left corner, a taskbar for pinned and active applications, and a system tray in the lower-right corner. There's no top menu bar with Applications and Places and System menus, and the taskbar uses icons with no text, so if it's a clone of GNOME 2 you're looking for, Cinnamon doesn't provide that.
![Cinnamon desktop on Linux Mint][5]
What Cinnamon does provide, however, is the opportunity for Linux Mint developers to control the environment they maintain. The Mint desktop is very much a Linux Mint creation, so much so that it's almost a part of the Mint brand. And yet it's appealing enough for enough users that it's available on [other distributions][6], even ones traditionally seen as "rivals" (at least, insofar as there are rivalries in open source). Here's the Cinnamon desktop environment fitting in nicely with a Fedora install:
![Cinnamon desktop on Fedora][7]
The desktop experience, aside from its panel layout, is a simple and classic one. There are icons on the desktop serving as shortcuts to common locations, there's an application for most file-management tasks, and there are applets in the systems tray for common administrative tasks. It's a familiar user experience. Just like its name, it's warm and inviting and cozy.
### Customizing the desktop
Cinnamon isn't as flexible as something like Fluxbox or KDE, but it's not as rigid as GNOME 3 or Pantheon. The System Settings application provides customization for all the usual small details, such as keyboard layout, keyboard shortcuts, workspace behavior, a firewall, and so on. A right-click on any element usually brings up a useful contextual menu with settings or information about what you've clicked.
There are definitely some expectations about what your workflow ought to be when using Cinnamon, but these assumptions are all generic and safe. It may not be the most efficient desktop environment, but it's soundly a generic, all-purpose one. Both power users and new users feel at home in Cinnamon. You can customize the experience within certain parameters, and if you hit the ceiling when you try to make drastic changes, then you can fall back on the fact that this is open source, and you have plenty of other options.
You may never hit that ceiling, though. Cinnamon's an attractive and responsive interface. It's a pleasure to use because it's simple and intuitive, with no surprises or puzzling user-interface choices to slow you down. With a few custom keyboard shortcuts and a little time to settle into a new environment, you can do amazing things with Cinnamon, and you'll love every moment of it because it's a beautiful thing to witness. Cinnamon is restrained with animations and effects, and the ones it uses are appealing and even informative.
### Spice of life
It's fun to try new desktops, and Cinnamon is worth trying. Install or download it today and see what you think. It's one of those desktops that you already know how to use, even if you've never used it before.
--------------------------------------------------------------------------------
via: https://opensource.com/article/19/12/cinnamon-linux-desktop
作者:[Seth Kenlon][a]
选题:[lujun9972][b]
译者:[译者ID](https://github.com/译者ID)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://opensource.com/users/seth
[b]: https://github.com/lujun9972
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/cinnamon.jpg?itok=4GV-boum (Cinnamon)
[2]: https://www.linuxmint.com/
[3]: https://github.com/linuxmint/Cinnamon
[4]: https://opensource.com/article/19/5/getting-started-gnome-boxes-virtualization
[5]: https://opensource.com/sites/default/files/uploads/advent-cinnamon.jpg (Cinnamon desktop on Linux Mint)
[6]: https://en.wikipedia.org/wiki/Cinnamon_(desktop_environment)#Adoption
[7]: https://opensource.com/sites/default/files/uploads/advent-cinnamon-fedora.jpg (Cinnamon desktop on Fedora)

View File

@ -0,0 +1,347 @@
[#]: collector: (lujun9972)
[#]: translator: (hanwckf)
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
[#]: subject: (Debugging Software Deployments with strace)
[#]: via: (https://theartofmachinery.com/2019/11/14/deployment_debugging_strace.html)
[#]: author: (Simon Arneaud https://theartofmachinery.com)
在软件部署中使用 strace 进行调试
======
我的大部分工作都包括部署软件系统,这意味着我需要花费很多时间来解决以下问题:
* 这个软件可以在原始开发者的机器上工作,但是为什么不能在我这里运行?
* 这个软件昨天可以在我的机器上工作,但是为什么今天就不行?
这是调试的一种类型,但是与传统的软件调试有所不同。传统的调试通常只关心代码的逻辑,但是在软件部署中的调试关注的是程序的代码和它所在的运行环境之间的相互影响。即便问题的根源是代码的逻辑错误,但软件显然可以在别的机器上运行的事实意味着这类问题与运行环境密切相关。
所以,在软件部署过程中,我没有使用传统的调试工具(例如 `gdb`),而是选择了其它工具进行调试。我最喜欢的用来解决“为什么这个软件无法在这台机器上运行?”这类问题的工具就是 `strace`
### 什么是 `strace`
[`strace`][1] 是一个用来“追踪系统调用”的工具。它主要是一个 Linux 工具,但是你也可以在其它系统上使用类似的工具(例如 [DTrace][2] 和 [ktrace][3])。
它的基本用法非常简单。只需要在 `strace` 后面跟上你需要运行的命令,它就会显示出该命令触发的所有系统调用(你可能需要先安装好 `strace`
```
$ strace echo Hello
...Snip lots of stuff...
write(1, "Hello\n", 6) = 6
close(1) = 0
close(2) = 0
exit_group(0) = ?
+++ exited with 0 +++
```
这些系统调用都是什么?他们就像是操作系统提供的 API。很久以前软件拥有直接访问硬件的权限。如果软件需要在屏幕上显示一些东西它将会与视频硬件的端口和内存映射寄存器纠缠不清。当多任务操作系统变得流行以后这就导致了混乱的局面因为不同的应用程序将“争夺”硬件并且一个应用程序的错误可能致使其它应用程序崩溃甚至导致整个系统崩溃。所以 CPUs 开始支持多种不同的特权模式 (或者称为“保护环”)。它们让操作系统内核在具有完全硬件访问权限的最高特权模式下运行,于此同时,其它在低特权模式下运行的应用程序必须通过向内核发起系统调用才能够与硬件进行交互。
在二进制级别上发起系统调用相比简单的函数调用有一些区别但是大部分程序都使用标准库提供的封装函数。例如POSIX C 标准库包含一个 `write()` 函数,该函数包含用于进行 `write` 系统调用的所有与硬件体系结构相关的代码。
![][4]
简单来说,一个应用程序与其环境(计算机系统)的相互影响都是通过系统调用来作用的。所以当软件在一台机器上可以工作但是在另一台机器无法工作的时候,追踪系统调用是一个很好的查错方法。具体地说,你可以通过追踪系统调用分析以下典型操作:
* 控制台输入与输出 (IO)
* 网络 IO
* 文件系统访问以及文件 IO
* 进程/线程 生命周期管理
* 原始内存管理
* 访问特定的设备驱动
### 什么时候可以使用 `strace`
理论上,`strace` 适用于任何用户空间程序,因为所有的用户空间程序都需要进行系统调用。`strace` 对于已编译的低级程序最有效果,但如果你可以避免运行时环境和解释器带来的大量额外输出,则仍然可以与 Python 等高级语言程序一起使用。
当软件在一台机器上正常工作,但在另一台机器上却不能正常工作,同时抛出有关文件、权限或者不能运行某某命令等模糊的错误信息时,`strace` 往往能大显身手。不幸的是,它不能诊断高等级的问题,例如数字证书验证错误等。这些问题通常需要结合 `strace`(有时候是 [`ltrace`][5]),以及其它高级工具(例如使用 `openssl` 命令行工具调试数字证书错误)。
本文中的示例基于独立的服务器,但是对系统调用的追踪通常也可以在更复杂的部署平台上完成,仅需要找到合适的工具。
### 一个简单的例子
假设你正在尝试运行一个叫做 foo 的服务器应用程序,但是发生了以下情况:
```
$ foo
Error opening configuration file: No such file or directory
```
显然,它没有找到你已经写好的配置文件。之所以会发生这种情况,是因为包管理工具有时候在编译应用程序时指定了自定义的路径,所以你应当遵循特定发行版提供的安装指南。如果错误信息告诉你正确的配置文件应该在什么地方,你就可以在几秒钟内解决这个问题,但事实并非如此。你该如何找到正确的路径?
如果你有权访问源代码,则可以通过阅读源代码来解决问题。这是一个好的备用计划,但不是最快的解决方案。你还可以使用类似 `gdb` 的单步调试器来观察程序的行为,但使用专门用于展示程序与系统环境交互作用的工具 `strace` 更加有效。
一开始, `strace` 产生的大量输出可能会让你不知所措,幸好你可以忽略其中大部分的无用信息。我经常使用 `-o` 参数把输出的追踪结果保存到单独的文件里:
```
$ strace -o /tmp/trace foo
Error opening configuration file: No such file or directory
$ cat /tmp/trace
execve("foo", ["foo"], 0x7ffce98dc010 /* 16 vars */) = 0
brk(NULL) = 0x56363b3fb000
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=25186, ...}) = 0
mmap(NULL, 25186, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f2f12cf1000
close(3) = 0
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\260A\2\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=1824496, ...}) = 0
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f2f12cef000
mmap(NULL, 1837056, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f2f12b2e000
mprotect(0x7f2f12b50000, 1658880, PROT_NONE) = 0
mmap(0x7f2f12b50000, 1343488, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x22000) = 0x7f2f12b50000
mmap(0x7f2f12c98000, 311296, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x16a000) = 0x7f2f12c98000
mmap(0x7f2f12ce5000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1b6000) = 0x7f2f12ce5000
mmap(0x7f2f12ceb000, 14336, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f2f12ceb000
close(3) = 0
arch_prctl(ARCH_SET_FS, 0x7f2f12cf0500) = 0
mprotect(0x7f2f12ce5000, 16384, PROT_READ) = 0
mprotect(0x56363b08b000, 4096, PROT_READ) = 0
mprotect(0x7f2f12d1f000, 4096, PROT_READ) = 0
munmap(0x7f2f12cf1000, 25186) = 0
openat(AT_FDCWD, "/etc/foo/config.json", O_RDONLY) = -1 ENOENT (No such file or directory)
dup(2) = 3
fcntl(3, F_GETFL) = 0x2 (flags O_RDWR)
brk(NULL) = 0x56363b3fb000
brk(0x56363b41c000) = 0x56363b41c000
fstat(3, {st_mode=S_IFCHR|0620, st_rdev=makedev(0x88, 0x8), ...}) = 0
write(3, "Error opening configuration file"..., 60) = 60
close(3) = 0
exit_group(1) = ?
+++ exited with 1 +++
```
`strace` 输出的第一页通常是低级的进程启动过程。(你可以看到很多 `mmap``mprotect``brk` 调用,这是用来分配原始内存和映射动态链接库的。)实际上,在查找错误时,最好从下往上阅读 `strace` 的输出。你可以看到 `write` 调用在最后返回了错误信息。如果你努力了,你将会看到第一个失败的系统调用是 `openat`,它在尝试打开 `/etc/foo/config.json` 时抛出了 `ENOENT` (“No such file or directory”)的错误。现在我们已经知道了配置文件应该放在哪里。
这是一个简单的例子,但我敢说在 90% 的情况下,使用 `strace` 进行调试不需要更多复杂的工作。以下是完整的调试步骤:
1. 从程序中获得含糊不清的错误信息
2. 使用 `strace` 运行程序
3. 在输出中找到错误信息
4. 往前追溯并找到第一个失败的系统调用
第四步中的系统调用很可能向你显示出问题所在。
### 小技巧
在开始更加复杂的调试之前,这里有一些有用的调试技巧帮助你高效使用 `strace`
#### `man` 是你的朋友
在很多 *nix 操作系统中,你可以通过 `man syscalls` 查看系统调用的列表。你将会看到类似于 `brk(2)` 之类的东西,这意味着你可以通过运行 `man 2 brk` 得到与此相关的更多信息。
一个小问题:`man 2 fork` 会显示出在 GNU `libc` 里封装的 `fork()` 手册页,而 `fork()` 现在实际上是由 `clone` 系统调用实现的。`fork` 的语义与 `clone` 相同,但是如果我写了一个含有 `fork()` 的程序并使用 `strace` 去调试它,我将找不到任何关于 `fork` 调用的信息,只能看到 `clone` 调用。只有在将源代码与 `strace` 的输出进行比较的时候,这种问题才会让人感到困惑。
#### 使用 `-o` 将输出保存到文件
`strace` 可以生成很多输出,所以将输出保存到单独的文件是很有帮助的 (就像上面的例子一样)。它还能够在控制台中避免程序自身的输出与 `strace` 的输出发生混淆。
#### 使用 `-s` 查看更多的参数
你可能已经注意到,错误信息的第二部分没有出现在上面的例子中。这是因为 `strace` 默认仅显示字符串参数的前 32 个字节。如果你需要捕获更多参数,请向 `strace` 追加类似于 `-s 128` 之类的参数。
#### `-y` 使得追踪文件或套接字更加容易
“一切皆文件”意味着 *nix 系统通过文件描述符进行所有 IO 操作,不管是真实的文件还是通过网络或者进程间管道。这对于编程而言是很方便的,但是在追踪系统调用时,你将很难分辨出 `read``write` 的真实行为。
`-y` 参数使 `strace` 在注释中注明每个文件描述符的具体指向。
#### 使用 `-p` 附加到正在运行的进程中
正如我们将在后面的例子中看到的,有时候你想追踪一个正在运行的程序。如果你知道这个程序的进程号为 1337 (可以通过 `ps` 查询),则可以这样操作:
```
$ strace -p 1337
...system call trace output...
```
你可能需要 root 权限才能运行。
#### 使用 `-f` 追踪子进程
`strace` 默认只追踪一个进程。如果这个进程产生了一个子进程,你将会看到创建子进程的系统调用(一般是 `clone`),但是你看不到子进程内触发的任何调用。
如果你认为在子进程中存在 bug则需要使用 `-f` 参数启用子进程追踪功能。这样做的缺点是输出的内容会让人更加困惑。当追踪一个进程时,`strace` 显示的是单个调用事件流。当追踪多个进程的时候,你将会看到以 `<unfinished ...>` 开始的初始调用,接着是一系列针对其它线程的调用,最后才出现以 `<... foocall resumed>` 结束的初始调用。此外,你可以使用 `-ff` 参数将所有的调用分离到不同的文件中(查看 [the `strace` manual][6] 获取更多信息)。
#### 使用 `-e` 进行过滤
正如你所看到的,默认的追踪输出是所有的系统调用。你可以使用 `-e` 参数过滤你需要追踪的调用(查看 [the `strace` manual][6])。这样做的好处是运行过滤后的 `strace` 比起使用 `grep` 进行二次过滤要更快。老实说,我大部分时间都不会被打扰。
#### 并非所有的错误都是不好的
一个简单而常用的例子是一个程序在多个位置搜索文件,例如 shell 搜索哪个 `bin/` 目录包含可执行文件:
```
$ strace sh -c uname
...
stat("/home/user/bin/uname", 0x7ffceb817820) = -1 ENOENT (No such file or directory)
stat("/usr/local/bin/uname", 0x7ffceb817820) = -1 ENOENT (No such file or directory)
stat("/usr/bin/uname", {st_mode=S_IFREG|0755, st_size=39584, ...}) = 0
...
```
“错误信息之前的最后一次失败调用”这种启发式方法非常适合于查找错误。无论如何,自下而上地工作是有道理的。
#### C编程指南非常有助于理解系统调用
标准 C 库函数调用不属于系统调用,但它们仅是系统调用之上的唯一一个薄层。所以如果你了解(甚至只是略知一二)如何使用 C 语言,那么阅读系统调用追踪信息就非常容易。例如,如果你在调试网络系统调用,你可以尝试略读 [Beejs classic Guide to Network Programming][7]。
### 一个更复杂的调试例子
就像我说的那样,简单的调试例子代表我在大部分情况下如何使用 `strace` 。然而,有时候需要一些更加细致的工作,所以这里有一个稍微复杂(且真实)的例子。
[`bcron`][8] 是一个任务调度器,它是经典 *nix `cron` 守护程序的一种实现。它已经被安装到一台服务器上,但是当有人尝试编辑作业时间表时,发生了以下情况:
```
# crontab -e -u logs
bcrontab: Fatal: Could not create temporary file
```
好的,现在 bcron 尝试写入一些文件,但是它失败了,也没有告诉我们原因。以下是 `strace` 的输出:
```
# strace -o /tmp/trace crontab -e -u logs
bcrontab: Fatal: Could not create temporary file
# cat /tmp/trace
...
openat(AT_FDCWD, "bcrontab.14779.1573691864.847933", O_RDONLY) = 3
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f82049b4000
read(3, "#Ansible: logsagg\n20 14 * * * lo"..., 8192) = 150
read(3, "", 8192) = 0
munmap(0x7f82049b4000, 8192) = 0
close(3) = 0
socket(AF_UNIX, SOCK_STREAM, 0) = 3
connect(3, {sa_family=AF_UNIX, sun_path="/var/run/bcron-spool"}, 110) = 0
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f82049b4000
write(3, "156:Slogs\0#Ansible: logsagg\n20 1"..., 161) = 161
read(3, "32:ZCould not create temporary f"..., 8192) = 36
munmap(0x7f82049b4000, 8192) = 0
close(3) = 0
write(2, "bcrontab: Fatal: Could not creat"..., 49) = 49
unlink("bcrontab.14779.1573691864.847933") = 0
exit_group(111) = ?
+++ exited with 111 +++
```
在程序结束之前有一个 `write` 的错误信息,但是这次有些不同。首先,在此之前没有任何相关的失败系统调用。其次,我们看到这个错误信息是由 `read` 从别的地方读取而来的。这看起来像是真正的错误发生在别的地方,而 `bcrontab` 只是在转播这些信息。
如果你查阅了 `man 2 read`,你将会看到 `read` 的第三个参数 (3) 代表文件描述符,这是 *nix 操作系统用于所有 IO 操作的句柄。你该如何知道文件描述符 3 代表什么?在这种情况下,你可以使用 `-y` 参数运行 `strace`(如上文所述),它将会在注释里告诉你文件描述符的具体指向,但是了解如何从上面这种输出中分析追踪结果是很有用的。
一个文件描述符可以来自于许多系统调用之一(这取决于它是用于控制台、网络套接字还是真实文件等的描述符),但不论如何,我们都可以搜索返回值为 3 的系统调用(例如,在 `strace` 的输出中查找 “=3”。在这次 `strace` 中可以看到有两个这样的调用:最上面的 `openat` 以及中间的 `socket`。`openat` 打开一个文件,但是紧接着的 `close(3)` 表明其已经被关闭。(注意:文件描述符可以在打开并关闭后重复使用。)所以 `socket` 调用才是与此相关的(它是在 `read` 之前的最后一次),这告诉我们 `brcontab` 正在与一个网络套接字通信。在下一行,`connect` 表明文件描述符 3 是一个连接到 `/var/run/bcron-spool` 的 Unix 域套接字。
因此,我们需要弄清楚 Unix 套接字的另一侧是哪个进程在监听。有两个巧妙的技巧适用于在服务器部署中调试。一个是使用 `netstat` 或者较新的 `ss`。这两个命令都描述了当前系统中活跃的网络套接字,使用 `-l` 参数可以显示出处于监听状态的套接字,而使用 `-p` 参数可以得到正在使用该套接字的程序信息。(它们还有更多有用的选项,但是这两个已经足够完成工作了。)
```
# ss -pl | grep /var/run/bcron-spool
u_str LISTEN 0 128 /var/run/bcron-spool 1466637 * 0 users:(("unixserver",pid=20629,fd=3))
```
这告诉我们 `/var/run/bcron-spool` 套接字的监听程序是 `unixserver` 这个命令,它的进程 ID 为 20629。巧合的是这个程序也使用文件描述符 3 去连接这个套接字。)
第二个常用的工具就是使用 `lsof` 查找相同的信息。它可以列出当前系统中打开的所有文件(或文件描述符)。或者,我们可以得到一个具体文件的信息:
```
# lsof /var/run/bcron-spool
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
unixserve 20629 cron 3u unix 0x000000005ac4bd83 0t0 1466637 /var/run/bcron-spool type=STREAM
```
进程 20629 是一个常驻进程,所以我们可以使用 `strace -o /tmp/trace -p 20629` 去查看该进程的系统调用。如果我们在另一个终端尝试编辑 cron 的计划任务表,就可以在错误发生时捕获到以下信息:
```
accept(3, NULL, NULL) = 4
clone(child_stack=NULL, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7faa47c44810) = 21181
close(4) = 0
accept(3, NULL, NULL) = ? ERESTARTSYS (To be restarted if SA_RESTART is set)
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=21181, si_uid=998, si_status=0, si_utime=0, si_stime=0} ---
wait4(0, [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], WNOHANG|WSTOPPED, NULL) = 21181
wait4(0, 0x7ffe6bc36764, WNOHANG|WSTOPPED, NULL) = -1 ECHILD (No child processes)
rt_sigaction(SIGCHLD, {sa_handler=0x55d244bdb690, sa_mask=[CHLD], sa_flags=SA_RESTORER|SA_RESTART, sa_restorer=0x7faa47ab9840}, {sa_handler=0x55d244bdb690, sa_mask=[CHLD], sa_flags=SA_RESTORER|SA_RESTART, sa_restorer=0x7faa47ab9840}, 8) = 0
rt_sigreturn({mask=[]}) = 43
accept(3, NULL, NULL) = 4
clone(child_stack=NULL, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7faa47c44810) = 21200
close(4) = 0
accept(3, NULL, NULL) = ? ERESTARTSYS (To be restarted if SA_RESTART is set)
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=21200, si_uid=998, si_status=111, si_utime=0, si_stime=0} ---
wait4(0, [{WIFEXITED(s) && WEXITSTATUS(s) == 111}], WNOHANG|WSTOPPED, NULL) = 21200
wait4(0, 0x7ffe6bc36764, WNOHANG|WSTOPPED, NULL) = -1 ECHILD (No child processes)
rt_sigaction(SIGCHLD, {sa_handler=0x55d244bdb690, sa_mask=[CHLD], sa_flags=SA_RESTORER|SA_RESTART, sa_restorer=0x7faa47ab9840}, {sa_handler=0x55d244bdb690, sa_mask=[CHLD], sa_flags=SA_RESTORER|SA_RESTART, sa_restorer=0x7faa47ab9840}, 8) = 0
rt_sigreturn({mask=[]}) = 43
accept(3, NULL, NULL
```
(最后一个 `accept` 调用没有在追踪周期里完成。)不幸的是,这次追踪没有包含我们想要的错误信息。我们没有观察到 `bcrontan` 往套接字发送或接受的任何信息。然而,我们看到了很多进程管理操作(`clone``wait4``SIGCHLD`,等等)。这个进程产生了子进程,我们猜测真实的工作是由子进程完成的。如果我们想捕获子进程的追踪信息,就必须往 `strace` 追加 `-f` 参数。以下是我们最终使用 `strace -f -o /tmp/trace -p 20629` 找到的错误信息:
```
21470 openat(AT_FDCWD, "tmp/spool.21470.1573692319.854640", O_RDWR|O_CREAT|O_EXCL, 0600) = -1 EACCES (Permission denied)
21470 write(1, "32:ZCould not create temporary f"..., 36) = 36
21470 write(2, "bcron-spool[21470]: Fatal: logs:"..., 84) = 84
21470 unlink("tmp/spool.21470.1573692319.854640") = -1 ENOENT (No such file or directory)
21470 exit_group(111) = ?
21470 +++ exited with 111 +++
```
现在我们知道了进程 ID 21470 在尝试创建文件 `tmp/spool.21470.1573692319.854640` (相对于当前的工作目录)时得到了一个没有权限的错误。如果我们知道当前的工作目录,就可以得到完整路径并能指出为什么该进程无法在此处创建临时文件。不幸的是,这个进程已经退出了,所以我们不能使用 `lsof -p 21470` 去找出当前的工作目录,但是我们可以往前追溯,查找进程 ID 21470 使用哪个系统调用改变了它的工作目录。这个系统调用是 `chdir`(可以在搜索引擎很轻松地找到)。以下是一直往前追溯到服务器进程 ID 20629 的结果:
```
20629 clone(child_stack=NULL, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7faa47c44810) = 21470
...
21470 execve("/usr/sbin/bcron-spool", ["bcron-spool"], 0x55d2460807e0 /* 27 vars */) = 0
...
21470 chdir("/var/spool/cron") = 0
...
21470 openat(AT_FDCWD, "tmp/spool.21470.1573692319.854640", O_RDWR|O_CREAT|O_EXCL, 0600) = -1 EACCES (Permission denied)
21470 write(1, "32:ZCould not create temporary f"..., 36) = 36
21470 write(2, "bcron-spool[21470]: Fatal: logs:"..., 84) = 84
21470 unlink("tmp/spool.21470.1573692319.854640") = -1 ENOENT (No such file or directory)
21470 exit_group(111) = ?
21470 +++ exited with 111 +++
```
(如果你在这里失败了,你可能需要阅读 [我之前有关 *nix 进程管理和 shell 的文章][9])好的,现在 PID 为 20629 的服务器进程没有权限在 `/var/spool/cron/tmp/spool.21470.1573692319.854640` 创建文件。最可能的原因就是典型的 *nix 文件系统权限设置。让我们检查一下:
```
# ls -ld /var/spool/cron/tmp/
drwxr-xr-x 2 root root 4096 Nov 6 05:33 /var/spool/cron/tmp/
# ps u -p 20629
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
cron 20629 0.0 0.0 2276 752 ? Ss Nov14 0:00 unixserver -U /var/run/bcron-spool -- bcron-spool
```
这就是问题所在!这个服务进程以 `cron` 用户运行,但是只有 `root` 用户才有向 `/var/spool/cron/tmp/` 目录写入的权限。一个简单 `chown cron /var/spool/cron/tmp/` 命令就能让 `bcron` 正常工作。(如果不是这个问题,那么下一个最有可能的怀疑对象是诸如 SELinux 或者 AppArmor 之类的内核安全模块,因此我将会使用 `dmesg` 检查内核日志。)
### 总结
最初,系统调用追踪可能会让人不知所措,但是我希望我已经证明它们是调试一整套常见部署问题的快速方法。你可以设想一下尝试用单步调试器去调试多进程的 `bcron` 问题。
通过一连串的系统调用解决问题是需要练习的,但正如我说的那样,在大多数情况下,我只需要使用 `strace` 从下往上追踪并查找错误。不管怎样,`strace` 节省了我很多的调试时间。我希望这也对你有所帮助。
--------------------------------------------------------------------------------
via: https://theartofmachinery.com/2019/11/14/deployment_debugging_strace.html
作者:[Simon Arneaud][a]
选题:[lujun9972][b]
译者:[hanwckf](https://github.com/hanwckf)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://theartofmachinery.com
[b]: https://github.com/lujun9972
[1]: https://strace.io/
[2]: http://dtrace.org/blogs/about/
[3]: https://man.openbsd.org/ktrace
[4]: https://theartofmachinery.com/images/strace/system_calls.svg
[5]: https://linux.die.net/man/1/ltrace
[6]: https://linux.die.net/man/1/strace
[7]: https://beej.us/guide/bgnet/html/index.html
[8]: https://untroubled.org/bcron/
[9]: https://theartofmachinery.com/2018/11/07/writing_a_nix_shell.html

View File

@ -1,139 +0,0 @@
[#]: collector: "lujun9972"
[#]: translator: "hello-wn"
[#]: reviewer: " "
[#]: publisher: " "
[#]: url: " "
[#]: subject: "Top 10 Vim plugins for programming in multiple languages"
[#]: via: "https://opensource.com/article/19/11/vim-plugins"
[#]: author: "Maxim Burgerhout https://opensource.com/users/wzzrd"
多语言编程必备的十大Vim插件
======
使用这 10 个 Vim 插件,可以让你在写代码或运维时,感觉更棒。
![OpenStack source code \(Python\) in VIM][1]
我使用 [Vim][2] 文本编辑器大约20年了。有一段时间我一直在定制我的Vim配置但在过去几年我会使用插件。
最近,当我重新安装 Vim 时(就像我经常做的那样),我决定把这次安装作为一次尝试,找到多种编程语言环境下的最佳 Vim 插件,以及如何将这些插件和每种语言结合起来。
有时,我会为特定的语言和配置使用特定的插件(例如,我只在 Ansible 配置中安装 Rocannon ),在此不细讲了。但是下面介绍的 10 个 Vim 插件是我的最爱,无论使用哪种编程语言,我几乎都会使用它们。
### 1\. Volt
我的首选并不是一个插件, 但是它可以替换类似于 [Vundle][3] 的插件,所以在此介绍。
[Volt][4] 是一个不依存于 Vim 的 Vim 插件管理器。 你可以用它安装插件,通过 `profiles` 组合使用不同的插件。你可以使用一个简单的命令 ```volt profile set myprofile``` 使得新 `profiles` 生效。 这样可以 因制宜地使用插件,比如,我在 Python 配置中单独使用 [indentpython][5] 插件。 Volt 还可以更方便地配置每个插件,这些配置会在 `profiles` 之间共享,因此只需要安装一次插件,就可以在多个 `profiles` 之间使用。
Volt 还是相对较新且不完美的(比如,无论使用多少 `profiles` ,每个插件只能有一个配置文件),但除此之外,我发现它非常方便、快速和简单。
![Volt plugin][6]
### 2\. Vim-Rainbow
除了 Python几乎所有的主流编程语言都使用括号 小括号,方括号和大括号)。 通常,它们会嵌套使用多对括号,因此很难搞清楚某个括号的开闭区间。我发现自己经常要数小括号,尤其是在复杂的 Bash 脚本中,以确保无误。
这时候就需要 [vim-rainbow][7] 插件! 它为每对括号设置不同的颜色,因此很容易识别出哪些括号是一对括号。 它非常有用而且五彩斑斓。
![vim-rainbow plugin][8]
### 3\. lightline
Vim 有很多插件,例如 [Powerline][9] ,它会在底部栏显示你正在处理的文件,光标所在的文件位置以及文件类型等信息。 这些插件各有利弊,在简单比较后,我选择了 [lightline][10]。 它相对较小,便于安装和扩展,并且不依赖于其他工具或插件。
![Lightline plugin][11]
### 4\. NERDTree
[NERDTree][12] 是一个很经典的插件。在大型项目中,你可能很难找到想要编辑的内容所在文件的确切名称和路径。使用快捷键(我使用的是 **F7** ,因为我在 `.vimrc` 中配置了这个快捷键),搜索窗会以垂直分屏的方式打开,就可以轻松找到所需文件并打开它。 对于大型项目,这是必备插件。 对于那些经常忘记文件名的人也很有用,比如我。
![NERDTree vim plugin][13]
### 5\. NERD Commenter
程序员们在写代码时,有时会遇到一些难以调试的问题,导致他们想要注释或不执行某段代码。 这时候就需要 [NERD Commenter][14] 出场了。选择代码段,按 **Leader键 + cc**,代码就会被注释掉。 (标准的 Vim Leader 键 是 **/** 字符。)按 **Leader键 + cn**,取消注释。 对于大多数文件类型NERD Commenter 会自动使用正确的注释符。 例如,如果你正在编辑 [BIND区域文件][15]并将文件类型设置为绑定区域Vim 会正确地使用 **;** (分号)字符进行注释。
![NERD Commenter][16]
### 6\. Solarized
我喜欢我的 Vim 主题配色。我也喜欢终端的主题色。我一直在 Vim 上使用 [Solarized][17] 配色,并且将我的终端、文件夹配色和 Vim 设为一致。
但是,有时我会根据周边环境,屏幕亮度以及是否需要分享投屏,切换明暗模式。
显然,你可以选择自己喜欢的任何配色方案,但我喜欢 `Solarized`,因为它有明暗模式功能,他可以简单快捷地切换两种模式。我的第二个选择是 [Monokai][18]。 Volt 插件管理器让我可以轻松地在两者之间切换因此我在Python编程时使用 Monokai Bash 编程时,使用 Solarized。
我没有给 Solarized 找相应的图片,因为本文中的所有其他图片都使用了 Solarized 中的浅色或深色效果,可以确认一下这些图片。
### 7\. fzf
当寻找一个文件时,有时你想要一个文件浏览器,有时你只想在键盘上敲打出与文件名类似的内容,对吗?
[fzf][19](全称 “模糊查找器”)插件提供了这一功能。打出 **:FZF** 并输入文件名内容。 不断缩短的列表将显示出与你输入的文件名内容相匹配的一些文件。我经常使用它,最近使用它的频率估计比使用 NERDTree 还多。缺点是这个插件依赖于 `fzf binary` ,因此也必须安装这个依赖包。它适用于 FedoraDebian 和 Arch据我所知并不适用于 EPEL。
![fzf Vim plugin][20]
### 8\. ack
有时,你需要搜索包含特定行或特定单词的文件。我真的很喜欢使用 [ack][21] 插件,最好与 **ag** 结合使用,他俩的组合又被称为 “[silver searcher][22]”。 这一组合的速度非常快,覆盖了 **grep****vimgrep** 的绝大多数使用场景。 缺点是您需要安装 ack 或 ag 才能正常运行。 好消息是 Fedora 和 EPEL7 都可以使用 ag 和 ack 。
![ack vim plugin][23]
### 9\. gitgutter
大多数 IT 人员都使用 [Git][24] 和 Git 仓库中的文件进行工作。[gitgutter][25] 插件在行号附近添加了一列,通过符号显示该行的状态为,已更改(**~**),已添加(**+**)或者已删除(**-**)。这有利于跟踪你所做的更改,并且可以使你专注于手头的任务,例如编写补丁来修复一个关键 bug。
![gitgutter vim plugin][26]
### 10\. Tag List
如果你在一个很大的文件中编写代码,会很容易忘记当前所在的位置,你可能需要上下滚动来查找某个功能。使用 [Tag List][27] 插件,只需要输入 **:Tlist** ,就能垂直分屏显示出 包含变量、类型、类和函数的代码,你可以轻松跳转到这些变量、类型、类和函数。这个功能对于多语言同样适用,例如 Java 、Python 以及任何能够使用 **ctags** 功能的文件类型。
![Tag List vim plugin][28]
以上介绍的 10 个 Vim 插件使我作为系统管理员和兼职程序员的生活变得更轻松。你正在使用哪些Vim插件请在评论中分享你最爱的插件。
Vim 为写作者提供了很多便利,无论他们是否了解技术。
--------------------------------------------------------------------------------
via: https://opensource.com/article/19/11/vim-plugins
作者:[Maxim Burgerhout][a]
选题:[lujun9972][b]
译者:[hello-wn][c]
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://opensource.com/users/wzzrd
[b]: https://github.com/lujun9972
[c]: https://github.com/hello-wn
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/openstack_python_vim_1.jpg?itok=lHQK5zpm "OpenStack source code (Python) in VIM"
[2]: https://www.vim.org/
[3]: https://github.com/VundleVim/Vundle.vim
[4]: https://github.com/vim-volt/volt
[5]: https://github.com/vim-scripts/indentpython.vim
[6]: https://opensource.com/sites/default/files/uploads/vim-volt.gif "Volt plugin"
[7]: http://github.com/frazrepo/vim-rainbow
[8]: https://opensource.com/sites/default/files/uploads/vim-rainbox.png "vim-rainbow plugin"
[9]: https://github.com/powerline/powerline
[10]: http://github.com/itchyny/lightline.vim
[11]: https://opensource.com/sites/default/files/uploads/lightline.png "Lightline plugin"
[12]: http://github.com/scrooloose/nerdtree
[13]: https://opensource.com/sites/default/files/uploads/nerdtree.gif "NERDTree vim plugin"
[14]: http://github.com/scrooloose/nerdcommenter
[15]: https://en.wikipedia.org/wiki/Zone_file#File_format
[16]: https://opensource.com/sites/default/files/uploads/nerdcommenter.gif "NERD Commenter"
[17]: https://github.com/altercation/vim-colors-solarized
[18]: https://github.com/sickill/vim-monokai
[19]: https://github.com/junegunn/fzf.vim
[20]: https://opensource.com/sites/default/files/uploads/fzf.gif "fzf Vim plugin"
[21]: https://github.com/mileszs/ack.vim
[22]: https://github.com/ggreer/the_silver_searcher
[23]: https://opensource.com/sites/default/files/uploads/ack.gif "ack vim plugin"
[24]: https://opensource.com/resources/what-is-git
[25]: https://github.com/airblade/vim-gitgutter
[26]: https://opensource.com/sites/default/files/uploads/gitgutter.png "gitgutter vim plugin"
[27]: https://github.com/vim-scripts/taglist.vim
[28]: https://opensource.com/sites/default/files/uploads/taglist.gif "Tag List vim plugin) ) ) "

View File

@ -7,20 +7,20 @@
[#]: via: (https://fedoramagazine.org/a-quick-introduction-to-toolbox-on-fedora/)
[#]: author: (Ryan Walter https://fedoramagazine.org/author/rwaltr/)
A quick introduction to Toolbox on Fedora
快速介绍 Fedora 中的 Toolbox
======
![][1]
Toolbox allows you to [sort and manage your development environments in containers][2] without requiring root privileges or manually attaching volumes. It creates a container where you can install your own CLI tools, without installing them on the base system itself. You can also utilize it when you do not have root access or cannot install programs directly. This article gives you an introduction to toolbox and what it does.
Toolbox 使你可以[在容器中分类和管理开发环境][2],而无需 root 权限或手动添加卷。它创建一个容器你可以在其中安装自己的命令行工具而无需在基础系统中安装它们。当你没有root 权限或无法直接安装程序时,也可以使用它。本文会介绍 Toolbox 及其功能。
### Installing Toolbox
### 安装 Toolbox
[Silverblue][3] includes Toolbox by default. For the Workstation and Server editions, you can grab it from the default repositories using _dnf install toolbox_.
[Silverblue][3] 默认包含 Toolbox。对于 Workstation 和 Server 版本,你可以使用 _dnf install toolbox_ 从默认仓库中获取它。
### Creating Toolboxes
### 创建 Toolbox
Open your terminal and run _toolbox enter_. The utility will automatically request permission to download the latest image, create your first container, and place your shell inside this container.
打开终端并运行 _toolbox enter_。程序将自动请求许可来下载最新的镜像,创建第一个容器并将你的 shell 放在该容器中。
```
$ toolbox enter
@ -29,7 +29,7 @@ Image required to create toolbox container.
Download registry.fedoraproject.org/f30/fedora-toolbox:30 (500MB)? [y/N]: y
```
Currently there is no difference between the toolbox and your base system. Your filesystems and packages appear unchanged. Here is an example using a repository that contains documentation source for a resume under a _~/src/resume_ folder. The resume is built using the _pandoc_ tool.
当前toolbox 和你的基本系统之间没有区别。你的文件系统和软件包未更改。这是一个使用仓库的示例,它包含 _~/src/resume_ 文件夹下的简历的文档源。简历是使用 _pandoc_ 工具构建的。
```
$ pwd
@ -47,7 +47,7 @@ $ pandoc -v
bash: pandoc: command not found
```
This toolbox does not have the programs required to build the resume. You can remedy this by installing the tools with _dnf_. You will not be prompted for the root password, because you are running in a container.
这个 toolbox 没有构建简历所需的程序。你可以通过使用 _dnf_ 安装工具来解决此问题。由于正在容器中运行,因此不会提示你输入 root 密码。
```
$ sudo dnf groupinstall "Authoring and Publishing" -y && sudo dnf install pandoc make -y
@ -63,7 +63,7 @@ $ ls BUILDS/
resume.docx resume.html resume.pdf resume.rtf resume.txt
```
Run _exit_ at any time to exit the toolbox.
运行 _exit_ 退出 toolbox。
```
$ cd BUILDS/
@ -80,21 +80,20 @@ bash: pandoc: command not found...
resume.docx resume.html resume.pdf resume.rtf resume.txt
```
You retain the files created by your toolbox in your home directory. None of the programs installed in your toolbox will be available outside of it.
你会在主目录中得到由 toolbox 创建的文件。toolbox 中安装的程序无法在外部访问。
### Tips and tricks
### 提示和技巧
This introduction to toolbox only scratches the surface. Here are some additional tips, but you can also check out [the official documentation][2].
* _Toolbox help_ will show you the man page for Toolbox
* You can have multiple toolboxes at once. Use _toolbox create -c Toolboxname_ and _toolbox enter -c Toolboxname_
* Toolbox uses [Podman][4] to do the heavy lifting. Use _toolbox list_ to find the IDs of the containers Toolbox creates. Podman can use these IDs to perform actions such as _rm_ and _stop_. (You can also read more about Podman [in this Magazine article][5].)
本介绍仅涉及 toolbox 的表明。还有一些其他提示,但是你也可以查看[官方文档][2]。
* _Toolbox help_ 会显示 Toolbox 的手册页
* 你可以一次有多个 toolbox。使用 _toolbox create -c Toolboxname__toolbox enter -c Toolboxname_
* Toolbox 使用 [Podman][4] 来完成繁重的工作。使用 _toolbox list_ 查找 Toolbox 创建的容器的 ID。Podman 可以使用这些 ID 来执行 _rm__stop_ 之类的操作。 (你也可以在[此文章][5]中阅读有关 Podman 的更多信息。)
* * *
_Photo courtesy of [Florian Richter][6] from [Flickr][7]._
_照片出自 [Flickr][7] 的 [Florian Richter][6]。_
--------------------------------------------------------------------------------
@ -102,7 +101,7 @@ via: https://fedoramagazine.org/a-quick-introduction-to-toolbox-on-fedora/
作者:[Ryan Walter][a]
选题:[lujun9972][b]
译者:[译者ID](https://github.com/译者ID)
译者:[geekpi](https://github.com/geekpi)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出