mirror of
https://github.com/LCTT/TranslateProject.git
synced 2025-03-21 02:10:11 +08:00
commit
d03958a845
@ -0,0 +1,240 @@
|
||||
自动共享和上传文件到兼容的托管站点
|
||||
======
|
||||
|
||||

|
||||
|
||||
前阵子我们写了一个关于 [Transfer.sh][1]的指南,它允许你使用命令行通过互联网来分享文件。今天,我们来看看另一种文件分享实用工具 Anypaste。这是一个基于文件类型自动共享和上传文件到兼容托管站点的简单脚本。你不需要去手动登录到托管站点来上传或分享你的文件。Anypaste 将会根据你想上传的文件的类型来**自动挑选合适的托管站点**。简单地说,照片将被上传到图像托管站点,视频被传到视频站点,代码被传到 pastebin。难道不是很酷的吗?Anypaste 是一个完全开源、免费、轻量的脚本,你可以通过命令行完成所有操作。因此,你不需要依靠那些臃肿的、需要消耗大量内存的 GUI 应用来上传和共享文件。
|
||||
|
||||
### 安装
|
||||
|
||||
正如我所说,这仅仅是一个脚本。所以不存在任何复杂的安装步骤。只需要将脚本下载后放置在你想要运行的位置(例如 `/usr/bin/`),并将其设置为可执行文件后就可以直接使用了。此外,你也可以通过下面的这两条命令来快速安装 Anypaste。
|
||||
|
||||
```
|
||||
sudo curl -o /usr/bin/anypaste https://anypaste.xyz/sh
|
||||
sudo chmod +x /usr/bin/anypaste
|
||||
```
|
||||
|
||||
就是这样简单。如果需要更新老的 Anypaste 版本,只需要用新的可执行文件覆写旧的即可。
|
||||
|
||||
现在,让我们看看一些实例。
|
||||
|
||||
### 配置
|
||||
|
||||
Anypaste 开箱即用,并不需要特别的配置。默认的配置文件是 `~/.config/anypaste.conf`,这个文件在你第一次运行 Anypaste 时会自动创建。
|
||||
|
||||
需要配置的选项只有 `ap_plugins`。Anypaste 使用插件系统上传文件。每个站点(的上传)都由一个特定的插件表示。你可以在 `anypaste.conf` 文件中的 `ap-plugins directive` 位置浏览可用的插件列表。
|
||||
|
||||
```
|
||||
# List of plugins
|
||||
# If there are multiple compatible plugins, precedence is determined
|
||||
# by which one is listed first in this array
|
||||
ap_plugins=(
|
||||
# Videos/Gifs
|
||||
'sendvid' 'streamable' 'gfycat'
|
||||
# Images
|
||||
'tinyimg' 'vgyme'
|
||||
# Audio
|
||||
'instaudio'
|
||||
# Text
|
||||
'hastebin' 'ixio' 'sprunge'
|
||||
# Documents
|
||||
'docdroid'
|
||||
# Any file
|
||||
'jirafeau' 'fileio'
|
||||
)
|
||||
[...]
|
||||
```
|
||||
|
||||
如果你要安装一个新的插件,将它添加进这个列表中就可以了。如果你想禁用一个默认插件,只需要将它从列表中移除即可。如果有多个兼容的插件,排列中的第一个会被选择,因此**顺序很重要**。
|
||||
|
||||
### 用法
|
||||
|
||||
上传一个简单的文件,例如 `test.png`,可以运行以下命令:
|
||||
|
||||
```
|
||||
anypaste test.png
|
||||
```
|
||||
|
||||
输出示例:
|
||||
|
||||
```
|
||||
Current file: test.png
|
||||
Attempting to upload with plugin 'tinyimg'
|
||||
######################################################################## 100.0%
|
||||
|
||||
Direct Link: https://tinyimg.io/i/Sa1zsjj.png
|
||||
|
||||
Upload complete.
|
||||
All files processed. Have a nice day!
|
||||
```
|
||||
|
||||
正如输出结果中所看到的,Anypaste 通过自动匹配图像文件 `test.png` 发现了兼容的托管站点(https://tinyimg.io),并将文件上传到了该站点。此外,Anypaste 也为我们提供了用于直接浏览/下载该文件的链接。
|
||||
|
||||
不仅是 png 格式文件,你还可以上传任何其他图片格式的文件。例如,下面的命令将会上传 gif 格式文件:
|
||||
|
||||
```
|
||||
$ anypaste file.gif
|
||||
Current file: file.gif
|
||||
Plugin 'streamable' is compatible, but missing config parameters: 'streamable_email' 'streamable_password'
|
||||
You can set them in /home/sk/.config/anypaste.conf
|
||||
Attempting to upload with plugin 'gfycat'
|
||||
######################################################################## 100.0%
|
||||
Reminder: Gfycat needs time to encode. Your video will not appear right away.
|
||||
|
||||
Link: https://gfycat.com/MisguidedQuaintBergerpicard
|
||||
Direct(ish) Link: https://thumbs.gfycat.com/MisguidedQuaintBergerpicard-size_restricted.gif
|
||||
|
||||
Upload complete.
|
||||
All files processed. Have a nice day!
|
||||
```
|
||||
|
||||
你可以将链接分享给你的家庭、朋友和同事们。下图是我刚刚将图片上传到 gfycat 网站的截图。
|
||||
|
||||
![][3]
|
||||
|
||||
也可以一次同时上传多个(相同格式或不同格式)文件。
|
||||
|
||||
下面的例子提供参考,这里我会上传两个不同的文件,包含一个图片文件和一个视频文件:
|
||||
|
||||
```
|
||||
anypaste image.png video.mp4
|
||||
```
|
||||
|
||||
输出示例:
|
||||
|
||||
```
|
||||
Current file: image.png
|
||||
Attempting to upload with plugin 'tinyimg'
|
||||
######################################################################## 100.0%
|
||||
|
||||
Direct Link: https://tinyimg.io/i/au1PHpg.png
|
||||
|
||||
Upload complete.
|
||||
Current file: video.mp4
|
||||
Plugin 'streamable' is compatible, but missing config parameters: 'streamable_email' 'streamable_password'
|
||||
You can set them in /home/sk/.config/anypaste.conf
|
||||
Attempting to upload with plugin 'sendvid'
|
||||
######################################################################## 100.0%
|
||||
|
||||
Link: http://sendvid.com/wwy7w96h
|
||||
Delete/Edit: http://sendvid.com/wwy7w96h?secret=39c0af2d-d8bf-4d3d-bad3-ad37432a40a5
|
||||
|
||||
Upload complete.
|
||||
All files processed. Have a nice day!
|
||||
```
|
||||
|
||||
Anypaste 针对两个文件自动发现了与之相兼容的托管站点并成功上传。
|
||||
|
||||
正如你在上述用法介绍部分的例子中注意到的,Anypaste 会自动挑选最佳的插件。此外,你可以指定插件进行文件上传,这里提供一个上传到 gfycat 的案例,运行以下命令:
|
||||
|
||||
```
|
||||
anypaste -p gfycat file.gif
|
||||
```
|
||||
|
||||
输出示例:
|
||||
|
||||
```
|
||||
Current file: file.gif
|
||||
Plugin 'streamable' is compatible, but missing config parameters: 'streamable_email' 'streamable_password'
|
||||
You can set them in /home/sk/.config/anypaste.conf
|
||||
Attempting to upload with plugin 'gfycat'
|
||||
######################################################################## 100.0%
|
||||
Reminder: Gfycat needs time to encode. Your video will not appear right away.
|
||||
|
||||
Link: https://gfycat.com/GrayDifferentCollie
|
||||
Direct(ish) Link: https://thumbs.gfycat.com/GrayDifferentCollie-size_restricted.gif
|
||||
|
||||
Upload complete.
|
||||
All files processed. Have a nice day!
|
||||
```
|
||||
|
||||
如果要使用特定插件进行文件上传,可以通过以下命令绕过兼容性检查:
|
||||
|
||||
```
|
||||
anypaste -fp gfycat file.gif
|
||||
```
|
||||
|
||||
如果你发现在配置文件中忽略了特定的插件,你仍然可以强制 Anypaste 去使用特定的插件,只不过需要加上 `-xp` 参数。
|
||||
|
||||
```
|
||||
anypaste -xp gfycat file.gif
|
||||
```
|
||||
|
||||
如果想要以交互模式上传文件,可以在命令后加上 `-i` 标签:
|
||||
|
||||
```
|
||||
$ anypaste -i file.gif
|
||||
Current file: file.gif
|
||||
Determine compatible plugins automatically? [Y/n] **n**
|
||||
The following plugins were found: 'sendvid' 'streamable' 'gfycat' 'tinyimg' 'vgyme' 'instaudio' 'hastebin' 'ixio' 'sprunge' 'docdroid' 'jirafeau' 'fileio'
|
||||
|
||||
Enter the (partial) name of a plugin, or nothing for automatic selection
|
||||
**gfycat**
|
||||
Attempt to upload with plugin 'gfycat'? [Y/n] **y**
|
||||
Attempting to upload with plugin 'gfycat'
|
||||
######################################################################## 100.0%
|
||||
Reminder: Gfycat needs time to encode. Your video will not appear right away.
|
||||
|
||||
Link: https://gfycat.com/WaryAshamedBlackbear
|
||||
Direct(ish) Link: https://thumbs.gfycat.com/WaryAshamedBlackbear-size_restricted.gif
|
||||
|
||||
Upload complete.
|
||||
All files processed. Have a nice day!
|
||||
```
|
||||
|
||||
正如你所见,Anypaste 首先询问了我是否需要自动确定插件。因为我不想自动寻找插件,所以我回复了 “No”。之后,Anypaste 列出了所有可选择的插件,并要求我从列表中选择一个。同样的,你可以上传和共享不同类型的文件,相关文件会被上传到相兼容的站点。
|
||||
|
||||
无论你何时上传一个视频文件,Anypaste 都会将其上传到以下站点中的一个:
|
||||
|
||||
1. sendvid
|
||||
2. streamable
|
||||
3. gfycat
|
||||
|
||||
这里注意列表顺序,Anypaste 将首先将文件上传到 sendvid 站点,如果没有 sendvid 的插件可供使用,Anypaste 将会尝试顺序中的另外两个站点。当然你也可以通过更改配置文件来修改顺序。
|
||||
|
||||
图像文件上传站点:
|
||||
|
||||
1. tinyimg.io
|
||||
2. vgy.me
|
||||
|
||||
音频文件上传站点:
|
||||
|
||||
1. instaud
|
||||
|
||||
文本文件上传站点:
|
||||
|
||||
1. hastebin
|
||||
2. ix.io
|
||||
3. sprunge.us
|
||||
|
||||
文档上传站点:
|
||||
|
||||
1. docdroid
|
||||
|
||||
其他任意类型的文件上传站点:
|
||||
|
||||
1. jirafeau
|
||||
2. file.io
|
||||
|
||||
上面列出来的部分站点一段特定的时间后会删除上传的内容,所以在上传和分享内容时应先明确这些站点的条款和条件。
|
||||
|
||||
### 结论
|
||||
|
||||
在我看来,识别文件并决定将其上传到何处的想法非常棒,而且开发者也以恰当的方式完美地实现了它。毫无疑问,Anypaste 对那些在互联网上需要频繁分享文件的人们非常有用,我希望你也能这么觉得。
|
||||
|
||||
这就是今天的全部内容,后面会有越来越多的好东西分享给大家。再见啦!
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.ostechnix.com/anypaste-share-upload-files-compatible-hosting-sites-automatically/
|
||||
|
||||
作者:[SK][a]
|
||||
译者:[lixin555](https://github.com/lixin555)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:https://www.ostechnix.com/author/sk/
|
||||
[1]:https://www.ostechnix.com/easy-fast-way-share-files-internet-command-line/
|
||||
[2]:data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7
|
||||
[3]:http://www.ostechnix.com/wp-content/uploads/2017/10/gfycat.png
|
@ -0,0 +1,289 @@
|
||||
23 款开源的声音、视觉生产工具
|
||||
======
|
||||
|
||||
> 无论你是要进行音频、图形、视频、动画还是它们的任意组合,都有一个开源工具可以帮助你产生专业水平的结果。
|
||||
|
||||

|
||||
|
||||
“开源”在云基础设施、网站托管、嵌入式设备和其他领域已经建立的相当完善。很少数人知道开源在生产专业级的声音视觉素材上也是一个不错的选择。
|
||||
|
||||
作为一名产品经理(有时候也是市场支持),我为终端用户提供很多内容:文档、文章、视频教学,甚至是展台物料、白皮书、采访等等。我找到了很多可以帮我制作音频、视频、排版、截屏的开源软件。人们选择开源软件而不是专有软件的[原因][1]有很多,而我也为以下人群编制了一份开源音视频工具清单:
|
||||
|
||||
* 想要入坑 GNU/Linux,但需要在原来的操作系统上慢慢从使用跨平台软件开始
|
||||
* 热爱开源,但对音视频开源软件所知甚少,不知道该如何选择
|
||||
* 想要为创造力充电而探索新的工具,并且不想使用其他人使用过的方法工具
|
||||
* 存在某些其他的原因使用开源音视频解决方案(如果是你,不妨在评论里分享一下)
|
||||
|
||||
幸运的是,存在着很多开源的音视频创作软件,也存在着很多硬件来支持这些应用。本文清单里的所有软件都符合以下标准:
|
||||
|
||||
* 跨平台
|
||||
* 开源(软件和驱动)
|
||||
* 稳定
|
||||
* 积极维护
|
||||
* 良好的文档与技术支持
|
||||
|
||||
我将清单中的解决方案划分为图形、音频、视频和动画。注意,本文中提到的应用程序并不完全等同于一些有名的私有软件,它们需要花时间来学习,并且可能需要改变你的工作流程,但是学习新的工具能够让体验全新的创造方式。
|
||||
|
||||
### 图形
|
||||
|
||||
我制作过很多出版和网站使用的图形,包括徽标、横幅、视频节目、草图。这里是一些我用过的开源应用,也包括一同使用的硬件。
|
||||
|
||||
#### 软件
|
||||
|
||||
**1、[Inkscape][2]**(矢量图)
|
||||
|
||||
Inkscape 是一款不错的矢量图编辑器,用来制作 RGB 颜色空间下的 SVG 和 PDF 文件。(它可以制作 CMYK 图像,但不是主要用途)它是为 web 应用制作 SVG 格式的地图和图表的人的救命稻草。你不仅可以使用集成的 XML 编辑器打开文件,也可以用它查看对象的所有参数。但有一个缺点:它在 Mac 上的优化不是很好。有很多样例,可以看[Inkscape 画廊][3]。
|
||||
|
||||
**2、[GIMP][4]**(图片编辑器)
|
||||
|
||||
GIMP 是我最喜欢的图片编辑程序,它包括了色彩调整、裁剪和拉伸,并且(尤其是)对于网页使用的文件大小进行了优化(很多使用 Photoshop 的同事让我帮他们做这最后一步)。你也可以从头制作并绘制一张图片,但 GIMP 并不是我最喜欢用来做这件事的工具。在 [GIMP Artists on DevianArt][5] 上查看众多的样例。
|
||||
|
||||
**3、[Krita][6]**(数字绘画)
|
||||
|
||||
当你桌子上摆着一个漂亮的 Wacom 数位板,你肯定想试试真正的数字绘画应用。Krita 就是你创作漂亮插画所需要的工具。在 [Krita 画廊][7] 里看看我说的东西吧。
|
||||
|
||||
**4、[Scribus][8]**(桌面印刷系统)
|
||||
|
||||
你可以使用 Scribus 来创建一个完整的文档,或者只是把用 Inkscape 或 Libre Office 制作的 PDF 从 RGB 转换到 CMYK。有一个功能我非常喜欢:你可以试着模拟视觉障碍人士使用 Scribus 时的体验。当我发送 PDF 文件给商业印刷公司时全指望 Scribus。尽管出版社可能使用像 InDesign 这样的私有软件创建文档,但如果你用 Scribus 正确的完成一份文档,那么打印时就不会出现任何问题。免费建议:第一次发送文件给印刷公司时,不要告诉印刷公司创建该文档所使用的软件。你可以在 [Scribus 教程][9]中寻找创建文档的例子。
|
||||
|
||||
**5、[RawTherapee][10]**(RAW 图像开发工具)
|
||||
|
||||
RawTherapee 是我所知道唯一跨平台可替代 Lightroom 的软件。你可以将相机调整到 RAW 模式,然后使用 RawTherapee 来修图。它提供了非常强大的引擎和对图片没有破坏的编辑器。例如,可以见 [Raw Therapee 截图][11]。
|
||||
|
||||
**6、[LibreOffice Draw][12]**(桌面印刷系统)
|
||||
|
||||
尽管你可能认为 LibraOffice Draw 不是一款专业的桌面印刷解决方案,但它仍然能够在很多情况下帮助你。例如,制作其他人(尽管是那些不懂图形软件的人)以后可以修改的白皮书、图表或海报。它不仅方便使用,而且当创建有趣的文档时也是 Impress 或 PowerPoint 的绝佳替代软件。
|
||||
|
||||
#### 图形硬件
|
||||
|
||||
**绘图板**
|
||||
|
||||
[Wacom][13] 数位板(和兼容设备)通常支持所有的操作系统。
|
||||
|
||||
**颜色校正**
|
||||
|
||||
颜色校正产品通常可用于所有操作系统,也包括了 GNU/Linux。Datacolor 生产的 [Spyder][14] 在所有平台上都有应用程序的支持。
|
||||
|
||||
**扫描仪和打印机**
|
||||
|
||||
图形艺术家需要输出(无论是打印还是电子版)的颜色是精确的。但是真正跨平台的设备,以及所有平台都易于安装的驱动,并不像你想的那样普遍。你的最佳选择是兼容 TWAIN 的扫描仪和兼容 Postscript 的打印机。以我的经验,Epson 和 Xerox 的专业级扫描仪和打印机更不容易出现驱动问题,并且它们通常也是开箱即用,拥有漂亮精确的颜色。
|
||||
|
||||
### 音频
|
||||
|
||||
有许多可供音乐家、视频制作者、游戏制作者、音乐出版商等等人群选择的开源音频软件。这里有一些我曾经用来进行内容创作与声音录制时所使用的软件。
|
||||
|
||||
#### 软件
|
||||
|
||||
**7、[Ardour][15]**(数字音频录制)
|
||||
|
||||
对录音与编辑来说,最专业级的工具选择当然是唾手可得的 Ardour。听起来很棒,它的混音部分非常的完整灵活,能够提供给你喜欢的插件,并且易于回放、编辑、对比修改。我经常用它进行声音录制和视频混音。要找出一些使用 Ardour 录制好的音乐并不容易,因为音乐家们很少表明他们使用的软件。然而,你可以查看它的[截图][16]和一些特性来了解它的功能。
|
||||
|
||||
(如果你在寻求一种声音制作方面的“模拟体验”,你可以试试 [Harrison Mixbus][17],它并不是一个开源项目,但是高度基于 Ardour,拥有模拟显示的终端。我非常喜欢用它进行工作,我的客户也喜欢用它制作的声音。Mixbus 也是跨平台的)
|
||||
|
||||
**8、[Audacity][18]** (声音编辑)
|
||||
|
||||
Audacity 属于“瑞士军刀”级的声音制作软件。它并不完美,但你几乎可以用它做所有的事情。加上非常易于使用,任何人都能在几分钟之内上手。像 Ardour 一样,很难找到一份归功于 Audacity 的作品,但你可以从这些[截图][19]中了解如何使用它。
|
||||
|
||||
**9、[LMMS][20]** (音乐制作)
|
||||
|
||||
LMMS,设计作为 FL Studio 的替代品,也许使用并不那么广泛,但它非常完整并易于使用。你可以使用自己最喜欢的插件,使用“钢琴键”编辑乐器,使用<ruby>步定序器<rt>step sequencer</rt></ruby>播放鼓点,混合音轨...几乎能做任何事情。在我没有时间为音乐家录音的时候我就使用它为视频创建声音片段。查看[最好的 LMMS][21] 榜单来看看一些例子。
|
||||
|
||||
**10、[Mixxx][22]** (DJ,音乐混音)
|
||||
|
||||
如果你需要强大的混音和播放 DJ 软件,Mixxx 就可以满足你的需求。它与大多数 MIDI 控制器、唱片、专用声卡所兼容。你可以用它管理音乐库、添加音效,做一些有趣的事情。查看它的[功能][23]来了解它是如何工作的。
|
||||
|
||||
#### 音频接口硬件
|
||||
|
||||
尽管你可以使用任何一个计算机的声卡录制音频,但要录制的很好,就需要一个音频接口——一个录制高质量音频输入的专用的外部声卡。对于跨平台兼容性来说,大多数“兼容 USB”和“兼容 iOS”的音频接口设备应该都能录制 MIDI 或其他音频。下面是一些我用过的一些有名气的跨平台设备。
|
||||
|
||||
**[Behringer U-PHORIA UMC22][24]**
|
||||
|
||||
UMC22 是你可以考虑的最便宜的选择。但它的前置放大器噪音太大,<ruby>音腔<rt>box</rt></ruby>质量也比较低。
|
||||
|
||||
**[Presonus AudioBox USB][25]**
|
||||
|
||||
AudioBox USB 是第一个兼容 USB(因此也跨平台)的录音系统。它非常的耐用,经常在二手市场也能见到。
|
||||
|
||||
**[Focusrite Scarlett][26]**
|
||||
|
||||
Scarlett 在我看来是目前最高质量的跨平台声卡。不同种类的设备可以涵盖 2-18 个输入/输出端口。你可以在二手市场找到它的最初版本,而最新的第二代具有更好的前置放大器与规格。[2i2][27] 型号是我经常使用的那一款。
|
||||
|
||||
**[Arturia AudioFuse][28]**
|
||||
|
||||
AudioFuse 几乎可以让你接入任何设备,从麦克风到黑胶唱片机再到各种数字输入设备。它具有优质的声音与良好的设计,也是我目前用的最多的一款设备。它是跨平台的,但目前配置软件还不能在 GUN/Linux 上使用。即使我把它从 Windows 电脑上断开,它仍然保留着我的配置。但是讲真,Arturia,劳烦认真考虑做一个 Linux 的软件。
|
||||
|
||||
#### MIDI 控制器
|
||||
|
||||
MIDI 控制器是一种乐器——例如电子琴、鼓垫等等。可以让你控制音乐软件或者硬件。现有的大多数 USB MIDI 控制器都跨平台并兼容主流的录音编辑软件。基于网页的教程可以帮你对不同的软件进行配置。尽管找到有关在 GNU/Linux 上配置的信息可能比较困难,但它们仍然是可以使用的。我用过许多 Akai 和 M-Audio 设备,没有任何问题。在买乐器之前最好先试一下,至少去听一下它们的音质或体验一下按键触感。
|
||||
|
||||
#### 音频编解码器
|
||||
|
||||
音频编解码器压缩或解压数字音频,用尽可能小的文件大小获得最佳质量的声音。幸运的是,用于收听或流媒体播放的编解码器恰好是开源的:[FLAC][29]。[Ogg Vorbis][30] 是另一个值得了解的开源音频编解码器;在相同的比特率下比 MP3 好的多。如果你需要输出不同的音频格式,我建议通常存档最好质量的音频,然后再压缩成特定的版本。
|
||||
|
||||
### 视频
|
||||
|
||||
视频对于品牌的传播是影响巨大的。即使你不是一个视频专家,学习一些基础的东西也是非常明智的。
|
||||
|
||||
#### 软件
|
||||
|
||||
**11、[VLC][31]** (视频播放器与转换器)
|
||||
|
||||
最初是为流媒体而开发的,VLC 现在因能够在所有设备上读取所有的视频格式被人们熟知。它非常的实用,例如,你可以使用它将视频转换成其他编解码格式或容器,也可以用来恢复破损的视频。
|
||||
|
||||
**12、[OpenShot][32]** (视频编辑)
|
||||
|
||||
OpenShot 是一个简单的软件,但它却可以制作出很好的效果,尤其是在短视频上。(在编辑或改善音质方面有一定的限制,但它也能够完成)我非常喜欢它的移动、拉伸、裁剪工具;用它创建视频的开头或结尾,导出之后使用更复杂的编辑器进行编辑,非常的完美。你可以在 OpenShot 的网站上看这些[例子][33](并获取更多信息)。
|
||||
|
||||
**13、[Shotcut][34]** (视频编辑)
|
||||
|
||||
我认为 Shotcut 是比 OpenShot 更完整一些的工具——它在你的操作系统上比起其他较为基础的编辑器更具有竞争力,并且它支持 4K 分辨率,具有专业的解码器。尝试一下,我相信你会爱上它的。你可以在这些[视频教程][35]里看一些范例。
|
||||
|
||||
**14、[Blender Velvets][36]** (视频编辑、合成、特效)
|
||||
|
||||
尽管这一章节不是本文的学习重点,但 Blender Velvets 是你能找到的最强大的解决方案之一。它是由一些视频创作者所制作的一系列扩展工具和脚本的合集,是通过 Blender 3D 制作软件转换成的 2D 视频编辑器。尽管它的复杂度意味着不是我的首选视频编辑器,但你仍可以在 YouTube 和其他网站上找到它的教程,并且一旦你学习了它,你就能通过它做任何事情。观看这个[视频教程][37]来了解它的功能与运作方式。
|
||||
|
||||
**15、[Natron][38]**(合成)
|
||||
|
||||
我不使用 Natron,但我听说它广受好评。它是 Adobe After Effects 的替代品,但运作方式并不同。想了解更多可以观看一些视频教程,比如这些 Natron 的 [YouTube 频道][39]。
|
||||
|
||||
**16、[OBS][40]** (实时编辑、录制、流媒体)
|
||||
|
||||
Open Broadcaster Software(OBS)是一个领先的在 YouTube 或 Twitch 上进行现场录制或现场直播电子竞技、电视游戏的解决方案。我经常使用它记录用户的屏幕、会议和聚会。要获取更多信息,查看我曾经在 Opensource.com 上写的关于录制现场汇报的教程,[第一部分:选择你的设备][42]和[第二部分:软件安装][43]。
|
||||
|
||||
#### 视频硬件
|
||||
|
||||
结论先行:你需要一个强大的工作站以及快速的硬盘和更新的软件和驱动。
|
||||
|
||||
**图形处理单元(GPU)**
|
||||
|
||||
一部分包含在清单里的软件比如 Blender 和 Shotcut 使用 OpenGL 和硬件加速,这些都高度依赖 GPU。我建议你使用可以负担起的最强大的 GPU。我所使用过的 AMD 和 Nvidia 都有着良好的体验,这取决于使用的平台。不要忘记安装最新的驱动。
|
||||
|
||||
**硬盘**
|
||||
|
||||
大体上来说,越快越大的硬盘,对视频越好。不要忘记在软件里配置好正确的路径。
|
||||
|
||||
**视频录制硬件**
|
||||
|
||||
* [Blackmagic Design][44]: Blackmagic 提供了非常好的、专业级的视频录制和回放硬件。驱动支持 Mac、Windows 和 GNU/Linux(但不是所有的发行版)
|
||||
* [Epiphan][45]: 在 Epiphan 的专业级 USB 视频录制设备中有一款新型产品,它适用于 HDMI 和高分辨率的屏幕。然而,你也可以在二手市场找到旧的 VGA 设备,因为他们还在继续为 GNU/Linux 和 Windows 上提供专用的驱动程序。
|
||||
|
||||
#### 视频编解码
|
||||
|
||||
不幸的是,使用开源的编解码器仍然很困难。例如,许多相机使用专有的编解码器录制 H.264 的视频和 AC3 的音频,组成称为 AVCHD 的格式。因此,我们必须务实,尽可能利用现有资源。
|
||||
|
||||
好消息是内容产业正在步向开源的编解码器来避免一些费用,并使用开源标准。对于出版和流媒体,[谷歌][46]的 [WebM][46] 便是一款优秀的开源编解码器,并且大多数视频编辑器可以导入这种格式。同样地, [GoPro][47]的超高分辨率和 360° 视频编解码器 [Cineform][47] 现在也进行了开源。希望更多的设备和供应商将会在不久之后使用它。
|
||||
|
||||
### 2D 和 3D 动画
|
||||
|
||||
动画不是我的专业领域,因此我问了从事于动画内容生产的朋友一些建议并加入到清单中,他的工作包含儿童电影和连续剧。
|
||||
|
||||
#### 软件
|
||||
|
||||
**17、[Blender][48]** (3D 模型和渲染)
|
||||
|
||||
Blender 是顶级的开源跨平台 3D 建模和渲染软件。你可以直接在 Blender 中完成整个项目的工作,或者使用它为电影或视频创建 3D 效果。你能够在网上找到许多视频教程,因此即使它不是一个简单的软件,但也非常容易上手。Blender 是一个非常活跃的项目,经常还会制作一些微电影来展示他们的技术。你可以在 [Blender Open Movies][49] 上观看。
|
||||
|
||||
**18、[Synfig Studio][50]** (2D 动画)
|
||||
|
||||
第一次用 Synfig 时,它让我想起了那个不错的 Macromedia 老式 Flash 编辑器。在那之后,它已经发展成一个全功能的 2D 动画工作室。你可以使用它制作宣传故事、商业广告、演示、开场或结尾动画以及视频中的转场,或者甚至用它制作全动画的电影。见 [Synfig 作品集][51]。
|
||||
|
||||
**19、[TupiTube][52]** (定格 2D 动画)
|
||||
|
||||
使用 TupiTube 是一个学习基本 2D 动画的极好方法。你可以将一系列绘画或其他图片转换成一个视频或者创建一个 GIF 循环动画。它是一个相当简单的软件,但非常完整。查看 [TupiTude 的 YouTube][53] 频道获取一些教程和范例。
|
||||
|
||||
#### 硬件
|
||||
|
||||
动画制作使用与图形设计相同的硬件,因此查看第一小结中的硬件清单获取一些建议。
|
||||
|
||||
有一点需要注意:你要用一个强大的 GPU 来进行 3D 建模和渲染。选择可能有些限制,因为这取决于你使用的平台或电脑制造商,但是不要忘记安装最新的驱动。谨慎选择你的显卡:它们非常昂贵,并且在大型的 3D 项目中至关重要,尤其是在渲染步骤中。
|
||||
|
||||
### Linux 上的选择
|
||||
|
||||
如果你是 GUN/Linux 用户,那么我为你提供了更多不错的选择。它们并不是完全跨平台的,但部分拥有 Windows 版本,还有一些可以在 Mac 上使用 Macports 安装。
|
||||
|
||||
**20、[Kdenlive][54]** (视频编辑)
|
||||
|
||||
伴随着最新版本的发布(几个月之前),Kdenlive 成为了我最喜欢的视频编辑器,尤其是当我在 Linux 机器上处理一些长视频的时候。如果你经常使用流行的非线性视频编辑器,Kdenlive(全称是 <ruby>KDE 非线性视频编辑器<rt>KDE Non-Linear Video Editor</rt></ruby>)对你来说将非常简单。它拥有很棒的视频和音频特效,强大的细节处理能力。并且在 BSD 和 MacOS(尽管它对准的是 GNU/Linux)都能使用,还有望移植到 Windows 上。
|
||||
|
||||
**21、[Darktable][55]** (RAW 图像开发)
|
||||
|
||||
Darktable 是一款由摄影师制作的非常完整的 DxO PhotoLab 替代品。一些研究型项目使用它当做开发平台并测试一些图像处理算法。它是一个非常活跃的项目,我已经等不及的见到它的跨平台版本了。
|
||||
|
||||
**22、[MyPaint][56]** (digital painting数字绘画)
|
||||
|
||||
MyPaint 就像数字绘画领域的 light table(LCTT 译注:集成开发环境)。它在 Wacom 设备上表现良好,并且它的笔刷引擎尤其值得赞赏,因此 GIMP 开发人员正在密切的关注它。
|
||||
|
||||
**23、[Shutter][57]** (桌面截图)
|
||||
|
||||
当我写这篇教程的时候,我使用了许多截图来进行展示。我最喜欢的 GNU/Linux 截图工具就是 Shutter。事实上,我都找不到在 Windows 或 Mac 上能与之抗衡的一些功能。有一点小遗憾:我很期待 Shutter 在将来能够增加新的功能来创建几秒动态的 GIF 截图。
|
||||
|
||||
我希望这些足以说服你开源软件是一种非常卓越且可行的音视频内容生产解决方案。如果你正在使用其他开源软件,或者对于使用跨平台软件和硬件进行音视频项目有好的建议,请在评论中分享你的观点。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/18/2/open-source-audio-visual-production-tools
|
||||
|
||||
作者:[Antoine Thomas][a]
|
||||
译者:[LuuMing](https://github.com/LuuMing)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:https://opensource.com/users/ttoine
|
||||
[1]:https://opensource.com/resources/what-open-source
|
||||
[2]:https://inkscape.org/
|
||||
[3]:https://inkscape.org/en/gallery/
|
||||
[4]:https://www.gimp.org/
|
||||
[5]:https://gimp-artists.deviantart.com/gallery/
|
||||
[6]:https://krita.org/
|
||||
[7]:https://krita.org/en/features/gallery/
|
||||
[8]:https://www.scribus.net/
|
||||
[9]:https://www.scribus.net/category/made-with-scribus/
|
||||
[10]:http://rawtherapee.com/
|
||||
[11]:http://rawtherapee.com/blog/screenshots
|
||||
[12]:https://www.libreoffice.org/discover/draw/
|
||||
[13]:http://www.wacom.com/en-us
|
||||
[14]:http://www.datacolor.com/photography-design/product-overview/#workflow_2
|
||||
[15]:https://www.ardour.org/
|
||||
[16]:http://ardour.org/features.html
|
||||
[17]:http://harrisonconsoles.com/site/mixbus.html
|
||||
[18]:http://www.audacityteam.org/
|
||||
[19]:http://www.audacityteam.org/about/screenshots/
|
||||
[20]:https://lmms.io/
|
||||
[21]:https://lmms.io/showcase/
|
||||
[22]:https://www.mixxx.org/
|
||||
[23]:https://www.mixxx.org/features/
|
||||
[24]:http://www.musictri.be/Categories/Behringer/Computer-Audio/Interfaces/UMC22/p/P0AUX
|
||||
[25]:https://www.presonus.com/products/audiobox-usb
|
||||
[26]:https://us.focusrite.com/scarlett-range
|
||||
[27]:https://us.focusrite.com/usb-audio-interfaces/scarlett-2i2
|
||||
[28]:https://www.arturia.com/products/audio/audiofuse/overview
|
||||
[29]:https://en.wikipedia.org/wiki/FLAC
|
||||
[30]:https://xiph.org/vorbis/
|
||||
[31]:https://www.videolan.org/
|
||||
[32]:https://www.openshot.org/
|
||||
[33]:https://www.openshot.org/videos/
|
||||
[34]:https://shotcut.com/
|
||||
[35]:https://shotcut.org/tutorials/
|
||||
[36]:http://blendervelvets.org/
|
||||
[37]:http://blendervelvets.org/video-tutorial-new-functions-for-the-blender-velvets/
|
||||
[38]:https://natron.fr/
|
||||
[39]:https://www.youtube.com/playlist?list=PL2n8LbT_b5IeMwi3AIzqG4Rbg8y7d6Amk
|
||||
[40]:https://obsproject.com/
|
||||
[41]:https://opensource.com/article/17/7/obs-studio-pro-level-streaming
|
||||
[42]:https://opensource.com/article/17/9/equipment-recording-presentations
|
||||
[43]:https://opensource.com/article/17/9/equipment-setup-live-presentations
|
||||
[44]:https://www.blackmagicdesign.com/
|
||||
[45]:https://www.epiphan.com/
|
||||
[46]:https://www.webmproject.org/
|
||||
[47]:https://fr.gopro.com/news/gopro-open-sources-the-cineform-codec
|
||||
[48]:https://www.blender.org/
|
||||
[49]:https://www.blender.org/about/projects/
|
||||
[50]:https://www.synfig.org/
|
||||
[51]:https://www.synfig.org/#portfolio
|
||||
[52]:https://maefloresta.com/
|
||||
[53]:https://www.youtube.com/channel/UCBavSfmoZDnqZalr52QZRDw
|
||||
[54]:https://kdenlive.org/
|
||||
[55]:https://www.darktable.org/
|
||||
[56]:http://mypaint.org/
|
||||
[57]:http://shutter-project.org/
|
@ -0,0 +1,247 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (wxy)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11691-1.html)
|
||||
[#]: subject: (Easily Upload Text Snippets To Pastebin-like Services From Commandline)
|
||||
[#]: via: (https://www.ostechnix.com/how-to-easily-upload-text-snippets-to-pastebin-like-services-from-commandline/)
|
||||
[#]: author: (SK https://www.ostechnix.com/author/sk/)
|
||||
|
||||
从命令行轻松将文本片段上传到类似 Pastebin 的服务中
|
||||
======
|
||||
|
||||

|
||||
|
||||
每当需要在线共享代码片段时,我们想到的第一个便是 Pastebin.com,这是 Paul Dixon 于 2002 年推出的在线文本共享网站。现在,有几种可供选择的文本共享服务可以上传和共享文本片段、错误日志、配置文件、命令输出或任何类型的文本文件。如果你碰巧经常使用各种类似于 Pastebin 的服务来共享代码,那么这对你来说确实是个好消息。向 Wgetpaste 打个招呼吧,它是一个命令行 BASH 实用程序,可轻松地将文本摘要上传到类似 Pastebin 的服务中。使用 Wgetpaste 脚本,任何人都可以与自己的朋友、同事或想在类似 Unix 的系统中的命令行中查看/使用/审查代码的人快速共享文本片段。
|
||||
|
||||
### 安装 Wgetpaste
|
||||
|
||||
Wgetpaste 在 Arch Linux [Community] 存储库中可用。要将其安装在 Arch Linux 及其变体(如 Antergos 和 Manjaro Linux)上,只需运行以下命令:
|
||||
|
||||
```
|
||||
$ sudo pacman -S wgetpaste
|
||||
```
|
||||
|
||||
对于其他发行版,请从 [Wgetpaste 网站][1] 获取源代码,并按如下所述手动安装。
|
||||
|
||||
首先下载最新的 Wgetpaste tar 文件:
|
||||
|
||||
```
|
||||
$ wget http://wgetpaste.zlin.dk/wgetpaste-2.28.tar.bz2
|
||||
```
|
||||
|
||||
提取它:
|
||||
|
||||
```
|
||||
$ tar -xvjf wgetpaste-2.28.tar.bz2
|
||||
```
|
||||
|
||||
它将 tar 文件的内容提取到名为 `wgetpaste-2.28` 的文件夹中。
|
||||
|
||||
转到该目录:
|
||||
|
||||
```
|
||||
$ cd wgetpaste-2.28/
|
||||
```
|
||||
|
||||
将 `wgetpaste` 二进制文件复制到 `$PATH` 中,例如 `/usr/local/bin/`。
|
||||
|
||||
```
|
||||
$ sudo cp wgetpaste /usr/local/bin/
|
||||
```
|
||||
|
||||
最后,使用命令使其可执行:
|
||||
|
||||
```
|
||||
$ sudo chmod +x /usr/local/bin/wgetpaste
|
||||
```
|
||||
|
||||
### 将文本片段上传到类似 Pastebin 的服务中
|
||||
|
||||
使用 Wgetpaste 上传文本片段很简单。让我向你展示一些示例。
|
||||
|
||||
#### 1、上传文本文件
|
||||
|
||||
要使用 Wgetpaste 上传任何文本文件,只需运行:
|
||||
|
||||
```
|
||||
$ wgetpaste mytext.txt
|
||||
```
|
||||
|
||||
此命令将上传 `mytext.txt` 文件的内容。
|
||||
|
||||
示例输出:
|
||||
|
||||
```
|
||||
Your paste can be seen here: https://paste.pound-python.org/show/eO0aQjTgExP0wT5uWyX7/
|
||||
```
|
||||
|
||||

|
||||
|
||||
你可以通过邮件、短信、whatsapp 或 IRC 等任何媒体共享 pastebin 的 URL。拥有此 URL 的人都可以访问它,并在他们选择的 Web 浏览器中查看文本文件的内容。
|
||||
|
||||
这是 Web 浏览器中 `mytext.txt` 文件的内容:
|
||||
|
||||

|
||||
|
||||
你也可以使用 `tee` 命令显示粘贴的内容,而不是盲目地上传它们。
|
||||
|
||||
为此,请使用如下的 `-t` 选项。
|
||||
|
||||
```
|
||||
$ wgetpaste -t mytext.txt
|
||||
```
|
||||
|
||||
![][3]
|
||||
|
||||
#### 2、将文字片段上传到其他服务
|
||||
|
||||
默认情况下,Wgetpaste 会将文本片段上传到 poundpython(<https://paste.pound-python.org/>)服务。
|
||||
|
||||
要查看支持的服务列表,请运行:
|
||||
|
||||
```
|
||||
$ wgetpaste -S
|
||||
```
|
||||
|
||||
示例输出:
|
||||
|
||||
```
|
||||
Services supported: (case sensitive):
|
||||
Name: | Url:
|
||||
=============|=================
|
||||
bpaste | https://bpaste.net/
|
||||
codepad | http://codepad.org/
|
||||
dpaste | http://dpaste.com/
|
||||
gists | https://api.github.com/gists
|
||||
*poundpython | https://paste.pound-python.org/
|
||||
```
|
||||
|
||||
在这里,`*` 表示默认服务。
|
||||
|
||||
如你所见,Wgetpaste 当前支持五种文本共享服务。我并没有全部尝试,但是我相信所有服务都可以使用。
|
||||
|
||||
要将内容上传到其他服务,例如 bpaste.net,请使用如下所示的 `-s` 选项。
|
||||
|
||||
```
|
||||
$ wgetpaste -s bpaste mytext.txt
|
||||
Your paste can be seen here: https://bpaste.net/show/5199e127e733
|
||||
```
|
||||
|
||||
#### 3、从标准输入读取输入
|
||||
|
||||
Wgetpaste 也可以从标准输入读取。
|
||||
|
||||
```
|
||||
$ uname -a | wgetpaste
|
||||
```
|
||||
|
||||
此命令将上传 `uname -a` 命令的输出。
|
||||
|
||||
#### 4、上传命令及命令的输出
|
||||
|
||||
有时,你可能需要粘贴命令及其输出。为此,请在如下所示的引号内指定命令的内容。
|
||||
|
||||
```
|
||||
$ wgetpaste -c 'ls -l'
|
||||
```
|
||||
|
||||
这会将命令 `ls -l` 及其输出上传到 pastebin 服务。
|
||||
|
||||
当你想让其他人清楚地知道你刚运行的确切命令及其输出时,此功能很有用。
|
||||
|
||||
![][4]
|
||||
|
||||
如你在输出中看到的,我运行了 `ls -l` 命令。
|
||||
|
||||
#### 5、上载系统日志文件、配置文件
|
||||
|
||||
就像我已经说过的,我们可以上载你的系统中任何类型的文本文件,而不仅仅是普通的文本文件,例如日志文件、特定命令的输出等。例如,你刚刚更新了 Arch Linux 机器,最后系统损坏了。你问你的同事该如何解决此问题,他(她)想阅读 `pacman.log` 文件。 这是上传 `pacman.log` 文件内容的命令:
|
||||
|
||||
```
|
||||
$ wgetpaste /var/log/pacman.log
|
||||
```
|
||||
|
||||
与你的同事共享 pastebin URL,以便他/她可以查看 `pacman.log`,并通过查看日志文件来帮助你解决问题。
|
||||
|
||||
通常,日志文件的内容可能太长,你不希望全部共享它们。在这种情况下,只需使用 `cat` 命令读取输出,然后使用 `tail -n` 命令定义要共享的行数,最后将输出通过管道传递到 Wgetpaste,如下所示。
|
||||
|
||||
```
|
||||
$ cat /var/log/pacman.log | tail -n 50 | wgetpaste
|
||||
```
|
||||
|
||||
上面的命令将仅上传 `pacman.log` 文件的“最后 50 行”。
|
||||
|
||||
#### 6、将输入网址转换为短链接
|
||||
|
||||
默认情况下,Wgetpaste 将在输出中显示完整的 pastebin URL。如果要将输入 URL 转换为短链接,只需使用 `-u` 选项。
|
||||
|
||||
```
|
||||
$ wgetpaste -u mytext.txt
|
||||
Your paste can be seen here: http://tinyurl.com/y85d8gtz
|
||||
```
|
||||
|
||||
#### 7、设定语言
|
||||
|
||||
默认情况下,Wgetpaste 将上传“纯文本”中的文本片段。
|
||||
|
||||
要列出指定服务支持的语言,请使用 `-L` 选项。
|
||||
|
||||
```
|
||||
$ wgetpaste -L
|
||||
```
|
||||
|
||||
该命令将列出默认服务(poundpython <https://paste.pound-python.org/>)支持的所有语言。
|
||||
|
||||
我们可以使用 `-l` 选项来改变它。
|
||||
|
||||
```
|
||||
$ wgetpaste -l Bash mytext.txt
|
||||
```
|
||||
|
||||
#### 8、在输出中禁用语法突出显示或 html
|
||||
|
||||
如上所述,文本片段将以特定的语言格式(纯文本、Bash 等)显示。
|
||||
|
||||
但是,你可以更改此行为,以使用 `-r` 选项显示原始文本摘要。
|
||||
|
||||
```
|
||||
$ wgetpaste -r mytext.txt
|
||||
Your raw paste can be seen here: https://paste.pound-python.org/raw/CUJhQ3jEmr2UvfmD2xCL/
|
||||
```
|
||||
|
||||

|
||||
|
||||
如你在上面的输出中看到的,没有语法突出显示,没有 html 格式。只是原始输出。
|
||||
|
||||
#### 9、更改 Wgetpaste 默认值
|
||||
|
||||
所有默认值(`DEFAULT_{NICK,LANGUAGE,EXPIRATION}[_${SERVICE}]` 和 `DEFAULT_SERVICE`)都可以在 `/etc/wgetpaste.conf` 中全局更改,也可以在 `~/.wgetpaste.conf` 文件中针对每个用户更改。但是,这些文件在我的系统中默认情况下并不存在。我想我们需要手动创建它们。开发人员已经在[这里][5]和[这里][6]为这两个文件提供了示例内容。只需使用给定的样本内容手动创建这些文件,并相应地修改参数即可更改 Wgetpaste 的默认设置。
|
||||
|
||||
#### 10、获得帮助
|
||||
|
||||
要显示帮助部分,请运行:
|
||||
|
||||
```
|
||||
$ wgetpaste -h
|
||||
```
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.ostechnix.com/how-to-easily-upload-text-snippets-to-pastebin-like-services-from-commandline/
|
||||
|
||||
作者:[SK][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[wxy](https://github.com/wxy)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://www.ostechnix.com/author/sk/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: http://wgetpaste.zlin.dk/
|
||||
[2]: data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7
|
||||
[3]: http://www.ostechnix.com/wp-content/uploads/2018/12/wgetpaste-3.png
|
||||
[4]: http://www.ostechnix.com/wp-content/uploads/2018/12/wgetpaste-4.png
|
||||
[5]: http://wgetpaste.zlin.dk/zlin.conf
|
||||
[6]: http://wgetpaste.zlin.dk/wgetpaste.example
|
79
published/20190322 Easy means easy to debug.md
Normal file
79
published/20190322 Easy means easy to debug.md
Normal file
@ -0,0 +1,79 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (LuuMing)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11693-1.html)
|
||||
[#]: subject: (Easy means easy to debug)
|
||||
[#]: via: (https://arp242.net/weblog/easy.html)
|
||||
[#]: author: (Martin Tournoij https://arp242.net/)
|
||||
|
||||
简单就是易于调试
|
||||
======
|
||||
|
||||
对于框架、库或者工具来说,怎样做才算是“简单”?也许有很多的定义,但我的理解通常是**易于调试**。我经常见到人们宣传某个特定的程序、框架、库、文件格式或者其它什么东西是简单的,因为他们会说“看,我只需要这么一点工作量就能够完成某项工作,这太简单了”。非常好,但并不完善。
|
||||
|
||||
你可能只编写一次软件,但几乎总要经历好几个调试周期。注意我说的调试周期并不意味着“代码里面有 bug 你需要修复”,而是说“我需要再看一下这份代码来修复 bug”。为了调试代码,你需要理解它,因此“易于调试”延伸来讲就是“易于理解”。
|
||||
|
||||
抽象使得程序易于编写,但往往是以难以理解为代价。有时候这是一个很好的折中,但通常不是。大体上,如果能使程序在日后易于理解和调试,我很乐意花更多的时间来写一些东西,因为这样实际上更省时间。
|
||||
|
||||
简洁并不是让程序易于调试的**唯一**方法,但它也许是最重要的。良好的文档也是,但不幸的是好的文档太少了。(注意,质量并**不**取决于字数!)
|
||||
|
||||
这种影响是真是存在的。难以调试的程序会有更多的 bug,即使最初的 bug 数量与易于调试的程序完全相同,而是因为修复 bug 更加困难、更花时间。
|
||||
|
||||
在公司的环境中,把时间花在难以修复的 bug 上通常被认为是不划算的投资。而在开源的环境下,人们花的时间会更少。(大多数项目都有一个或多个定期的维护者,但成百上千的贡献者提交的仅只是几个补丁)
|
||||
|
||||
---
|
||||
|
||||
这并不全是 1974 年由 Brian W. Kernighan 和 P. J. Plauger 合著的《<ruby>编程风格的元素<rt>The Elements of Programming Style</rt></ruby>》中的观点:
|
||||
|
||||
> 每个人都知道调试比起编写程序困难两倍。当你写程序的时候耍小聪明,那么将来应该怎么去调试?
|
||||
|
||||
我见过许多看起来写起来“极尽精妙”,但却导致难以调试的代码。我会在下面列出几种样例。争论这些东西本身有多坏并不是我的本意,我仅想强调对于“易于使用”和“易于调试”之间的折中。
|
||||
|
||||
* <ruby>ORM<rt>对象关系映射</rt></ruby> 库可以让数据库查询变得简单,代价是一旦你想解决某个问题,事情就变得难以理解。
|
||||
* 许多测试框架让调试变得困难。Ruby 的 rspec 就是一个很好的例子。有一次我不小心使用错了,结果花了很长时间搞清楚**究竟**哪里出了问题(因为它给出错误提示非常含糊)。
|
||||
|
||||
我在《[测试并非万能][1]》这篇文章中写了更多关于以上的例子。
|
||||
* 我用过的许多 JavaScript 框架都很难完全理解。Clever(LCTT 译注:一种 JS 框架)的语句一向很有逻辑,直到某条语句不能如你预期的工作,这时你就只能指望 Stack Overflow 上的某篇文章或 GitHub 上的某个回帖来帮助你了。
|
||||
|
||||
这些函数库**确实**让任务变得非常简单,使用它们也没有什么错。但通常人们都过于关注“易于使用”而忽视了“易于调试”这一点。
|
||||
* Docker 非常棒,并且让许多事情变得非常简单,直到你看到了这条提示:
|
||||
|
||||
```
|
||||
ERROR: for elasticsearch Cannot start service elasticsearch:
|
||||
oci runtime error: container_linux.go:247: starting container process caused "process_linux.go:258:
|
||||
applying cgroup configuration for process caused \"failed to write 898 to cgroup.procs: write
|
||||
/sys/fs/cgroup/cpu,cpuacct/docker/b13312efc203e518e3864fc3f9d00b4561168ebd4d9aad590cc56da610b8dd0e/cgroup.procs:
|
||||
invalid argument\""
|
||||
```
|
||||
|
||||
或者这条:
|
||||
|
||||
```
|
||||
ERROR: for elasticsearch Cannot start service elasticsearch: EOF
|
||||
```
|
||||
|
||||
那么...你怎么看?
|
||||
* `Systemd` 比起 `SysV`、`init.d` 脚本更加简单,因为编写 `systemd` 单元文件比起编写 `shell` 脚本更加方便。这也是 Lennart Poetterin 在他的 [systemd 神话][2] 中解释 `systemd` 为何简单时使用的论点。
|
||||
|
||||
我非常赞同 Poettering 的观点——也可以看 [shell 脚本陷阱][3] 这篇文章。但是这种角度并不全面。单元文件简单的背后意味着 `systemd` 作为一个整体要复杂的多,并且用户确实会受到它的影响。看看我遇到的这个[问题][4]和为它所做的[修复][5]。看起来很简单吗?
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://arp242.net/weblog/easy.html
|
||||
|
||||
作者:[Martin Tournoij][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[LuuMing](https://github.com/LuuMing)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://arp242.net/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://www.arp242.net/testing.html
|
||||
[2]: http://0pointer.de/blog/projects/the-biggest-myths.html
|
||||
[3]:https://www.arp242.net/shell-scripting-trap.html
|
||||
[4]:https://unix.stackexchange.com/q/185495/33645
|
||||
[5]:https://cgit.freedesktop.org/systemd/systemd/commit/?id=6e392c9c45643d106673c6643ac8bf4e65da13c1
|
@ -0,0 +1,196 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (robsean)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11631-1.html)
|
||||
[#]: subject: (How to Install LEMP (Linux, Nginx, MariaDB, PHP) on Fedora 30 Server)
|
||||
[#]: via: (https://www.linuxtechi.com/install-lemp-stack-fedora-30-server/)
|
||||
[#]: author: (Pradeep Kumar https://www.linuxtechi.com/author/pradeep/)
|
||||
|
||||
如何在 Fedora 30 Server 上安装 LEMP(Linux、Nginx、MariaDB、PHP)
|
||||
======
|
||||
|
||||
在这篇文章中,我们将看看如何在 Fedora 30 Server 上安装 **LEMP** 。LEMP 代表:
|
||||
|
||||
* L -> Linux
|
||||
* E -> Nginx
|
||||
* M -> Maria DB
|
||||
* P -> PHP
|
||||
|
||||
我假设 [Fedora 30][1] 已经安装在你的电脑系统上。
|
||||
|
||||

|
||||
|
||||
LEMP 是一组强大的软件设置集合,它安装在一个 Linux 服务器上以帮助使用流行的开发平台来构建网站,LEMP 是 LAMP 的一个变种,在其中不是 Apache ,而是使用 EngineX(Nginx),此外,使用 MariaDB 代替 MySQL。这篇入门指南是一个安装 Nginx、Maria DB 和 PHP 的独立指南的作品集合。
|
||||
|
||||
### 在 Fedora 30 Server 上安装 Nginx、PHP 7.3 和 PHP-FPM
|
||||
|
||||
让我们看看如何在 Fedora 30 Server 上安装 Nginx 和 PHP 以及 PHP FPM。
|
||||
|
||||
#### 步骤 1) 切换到 root 用户
|
||||
|
||||
在系统上安装 Nginx 的第一步是切换到 root 用户。使用下面的命令:
|
||||
|
||||
```
|
||||
root@linuxtechi ~]$ sudo -i
|
||||
[sudo] password for pkumar:
|
||||
[root@linuxtechi ~]#
|
||||
```
|
||||
|
||||
#### 步骤 2) 使用 dnf 命令安装 Nginx、PHP 7.3 和 PHP FPM
|
||||
|
||||
使用下面的 `dnf` 命令安装 Nginx:
|
||||
|
||||
```
|
||||
[root@linuxtechi ~]# dnf install nginx php php-fpm php-common -y
|
||||
```
|
||||
|
||||
#### 步骤 3) 安装额外的 PHP 模块
|
||||
|
||||
PHP 的默认安装仅自带基本模块和最需要的模块,如果你需要额外的模块,像 PHP 支持的 GD、XML、命令行接口、Zend OPCache 功能等等,你总是能够选择你的软件包,并一次性安装所有的东西。查看下面的示例命令:
|
||||
|
||||
```
|
||||
[root@linuxtechi ~]# sudo dnf install php-opcache php-pecl-apcu php-cli php-pear php-pdo php-pecl-mongodb php-pecl-redis php-pecl-memcache php-pecl-memcached php-gd php-mbstring php-mcrypt php-xml -y
|
||||
```
|
||||
|
||||
#### 步骤 4) 开始 & 启用 Nginx 和 PHP-fpm 服务
|
||||
|
||||
使用下面的命令来开始并启用 Nginx 服务:
|
||||
|
||||
```
|
||||
[root@linuxtechi ~]# systemctl start nginx && systemctl enable nginx
|
||||
Created symlink /etc/systemd/system/multi-user.target.wants/nginx.service → /usr/lib/systemd/system/nginx.service.
|
||||
[root@linuxtechi ~]#
|
||||
```
|
||||
|
||||
使用下面的命令来开始并启用 PHP-FPM 服务:
|
||||
|
||||
```
|
||||
[root@linuxtechi ~]# systemctl start php-fpm && systemctl enable php-fpm
|
||||
Created symlink /etc/systemd/system/multi-user.target.wants/php-fpm.service → /usr/lib/systemd/system/php-fpm.service.
|
||||
[root@linuxtechi ~]#
|
||||
```
|
||||
|
||||
#### 步骤 5) 核实 Nginx (Web 服务) 和 PHP 安装
|
||||
|
||||
注意:假使操作系统防火墙是启用的,并运行在你的 Fedora 30 系统上,那么使用下面的命令来准许 80 和 443 端口:
|
||||
|
||||
```
|
||||
[root@linuxtechi ~]# firewall-cmd --permanent --add-service=http
|
||||
success
|
||||
[root@linuxtechi ~]#
|
||||
[root@linuxtechi ~]# firewall-cmd --permanent --add-service=https
|
||||
success
|
||||
[root@linuxtechi ~]# firewall-cmd --reload
|
||||
success
|
||||
[root@linuxtechi ~]#
|
||||
```
|
||||
|
||||
打开网页浏览器,输入下面的 URL: http://<Your-Server-IP> 。
|
||||
|
||||
![Test-Page-HTTP-Server-Fedora-30][4]
|
||||
|
||||
上面的屏幕证实 Nginx 已经成功地安装。
|
||||
|
||||
现在,让我们核实 PHP 安装,使用下面的命令创建一个测试 php 页(`info.php`):
|
||||
|
||||
```
|
||||
[root@linuxtechi ~]# echo "<?php phpinfo(); ?>" > /usr/share/nginx/html/info.php
|
||||
[root@linuxtechi ~]#
|
||||
```
|
||||
|
||||
在网页浏览器中输入下面的 URL, http://<Your-Server-IP>/info.php
|
||||
|
||||
![Php-info-page-fedora30][6]
|
||||
|
||||
上面的页面验证 PHP 7.3.5 已经被成功地安装。现在,让我们安装 MariaDB 数据库服务器。
|
||||
|
||||
### 在 Fedora 30 上安装 MariaDB
|
||||
|
||||
MariaDB 是 MySQL 数据库的一个极好的替代品,因为它的工作方式与 MySQL 非常类似,并且兼容性也与 MySQL 一致。让我们看看在 Fedora 30 Server 上安装 MariaDB 的步骤。
|
||||
|
||||
#### 步骤 1) 切换到 root 用户
|
||||
|
||||
在系统上安装 MariaDB 的第一步是切换到 root 用户,或者你可以使用有 root 权限的本地用户。使用下面的命令:
|
||||
|
||||
```
|
||||
[root@linuxtechi ~]# sudo -i
|
||||
[root@linuxtechi ~]#
|
||||
```
|
||||
|
||||
#### 步骤 2) 使用 dnf 命令安装 MariaDB(10.3)的最新版本
|
||||
|
||||
在 Fedora 30 Server 上使用下面的命令来安装 MariaDB:
|
||||
|
||||
```
|
||||
[root@linuxtechi ~]# dnf install mariadb-server -y
|
||||
```
|
||||
|
||||
#### 步骤 3) 开启并启用 MariaDB 服务
|
||||
|
||||
在步骤 2 中成功地安装 MariaDB 后,接下来的步骤是开启 MariaDB 服务。使用下面的命令:
|
||||
|
||||
```
|
||||
[root@linuxtechi ~]# systemctl start mariadb.service ; systemctl enable mariadb.service
|
||||
```
|
||||
|
||||
#### 步骤 4) 保护安装好的 MariaDB
|
||||
|
||||
当我们安装 MariaDB 服务器时,因为默认情况下没有 root 密码,在数据库中也会创建匿名用户。因此,要保护安装好的 MariaDB,运行下面的 `mysql_secure_installation` 命令:
|
||||
|
||||
```
|
||||
[root@linuxtechi ~]# mysql_secure_installation
|
||||
```
|
||||
|
||||
接下来你将被提示一些问题,仅回答下面展示的问题:
|
||||
|
||||
![Secure-MariaDB-Installation-Part1][7]
|
||||
|
||||
![Secure-MariaDB-Installation-Part2][8]
|
||||
|
||||
#### 步骤 5) 测试 MariaDB 安装
|
||||
|
||||
在你安装后,你总是能够测试是否 MariaDB 被成功地安装在 Fedora 30 Server 上。使用下面的命令:
|
||||
|
||||
```
|
||||
[root@linuxtechi ~]# mysql -u root -p
|
||||
Enter password:
|
||||
```
|
||||
|
||||
接下来,你将被提示一个密码。输入在保护安装好的 MariaDB 期间你设置的密码,接下来你可以看到 MariaDB 欢迎屏幕。
|
||||
|
||||
```
|
||||
Welcome to the MariaDB monitor. Commands end with ; or \g.
|
||||
Your MariaDB connection id is 17
|
||||
Server version: 10.3.12-MariaDB MariaDB Server
|
||||
|
||||
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
|
||||
|
||||
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
|
||||
|
||||
MariaDB [(none)]>
|
||||
```
|
||||
|
||||
最后,我们已经在你的 Fedora 30 Server 上成功地完成安装 LEMP(Linux、Nginx、MariaDB 和 PHP)的所有工作。请在下面的反馈部分发布你的评论和建议,我们将尽快在后面回应。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.linuxtechi.com/install-lemp-stack-fedora-30-server/
|
||||
|
||||
作者:[Pradeep Kumar][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[robsean](https://github.com/robsean)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://www.linuxtechi.com/author/pradeep/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://www.linuxtechi.com/fedora-30-workstation-installation-guide/
|
||||
[2]: https://www.linuxtechi.com/wp-content/uploads/2019/06/LEMP-Stack-Fedora30.jpg
|
||||
[3]: https://www.linuxtechi.com/wp-content/uploads/2019/06/Test-Page-HTTP-Server-Fedora-30-1024x732.jpg
|
||||
[4]: https://www.linuxtechi.com/wp-content/uploads/2019/06/Test-Page-HTTP-Server-Fedora-30.jpg
|
||||
[5]: https://www.linuxtechi.com/wp-content/uploads/2019/06/Php-info-page-fedora30-1024x732.jpg
|
||||
[6]: https://www.linuxtechi.com/wp-content/uploads/2019/06/Php-info-page-fedora30.jpg
|
||||
[7]: https://www.linuxtechi.com/wp-content/uploads/2019/06/Secure-MariaDB-Installation-Part1.jpg
|
||||
[8]: https://www.linuxtechi.com/wp-content/uploads/2019/06/Secure-MariaDB-Installation-Part2.jpg
|
@ -0,0 +1,235 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (wxy)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11673-1.html)
|
||||
[#]: subject: (24 sysadmin job interview questions you should know)
|
||||
[#]: via: (https://opensource.com/article/19/7/sysadmin-job-interview-questions)
|
||||
[#]: author: (DirectedSoul https://opensource.com/users/directedsoul)
|
||||
|
||||
24 个必知必会的系统管理员面试问题
|
||||
======
|
||||
|
||||
> 即将进行系统管理员工作面试吗?阅读本文,了解你可能会遇到的一些问题以及可能的答案。
|
||||
|
||||

|
||||
|
||||
作为一个经常与计算机打交道的极客,在硕士毕业后在 IT 行业选择我的职业是很自然的选择。因此,我认为走上系统管理员之路是正确的路径。在我的职业生涯中,我对求职面试过程非常熟悉。现在来看一下对该职位的预期、职业发展道路,以及一系列常见面试问题及我的回答。
|
||||
|
||||
### 系统管理员的典型任务和职责
|
||||
|
||||
组织需要了解系统工作原理的人员,以确保数据安全并保持服务平稳运行。你可能会问:“等等,是不是系统管理员还能做更多的事情?”
|
||||
|
||||
你是对的。现在,一般来说,让我们看一下典型的系统管理员的日常任务。根据公司的需求和人员的技能水平,系统管理员的任务从管理台式机、笔记本电脑、网络和服务器到设计组织的 IT 策略不等。有时,系统管理员甚至负责购买和订购新的 IT 设备。
|
||||
|
||||
那些寻求系统管理工作以作为其职业发展道路的人可能会发现,由于 IT 领域的快速变化是不可避免的,因此难以保持其技能和知识的最新状态。所有人都会想到的下一个自然而然的问题是 IT 专业人员如何掌握最新的更新和技能。
|
||||
|
||||
### 简单的问题
|
||||
|
||||
这是你将遇到的一些最基本的问题,以及我的答案:
|
||||
|
||||
**1、你在 \*nix 服务器上登录后键入的前五个命令是什么?**
|
||||
|
||||
> * `lsblk` 以查看所有的块设备信息
|
||||
> * `who` 查看谁登录到服务器
|
||||
> * `top`,以了解服务器上正在运行的进程
|
||||
> * `df -khT` 以查看服务器上可用的磁盘容量
|
||||
> * `netstat` 以查看哪些 TCP 网络连接处于活动状态
|
||||
|
||||
**2、如何使进程在后台运行,这样做的好处是什么?**
|
||||
|
||||
> 你可以通过在命令末尾添加特殊字符 `&` 来使进程在后台运行。通常,执行时间太长并且不需要用户交互的应用程序可以放到后台,以便我们可以在终端中继续工作。([引文][2])
|
||||
|
||||
**3、以 root 用户身份运行这些命令是好事还是坏事?**
|
||||
|
||||
> 由于两个主要问题,以 root 身份运行(任何命令)是不好的。第一个是*风险*。当你以 **root** 身份登录时,无法避免你由于粗心大意而犯错。如果你尝试以带有潜在危害的方式更改系统,则需要使用 `sudo`,它会引入一个暂停(在你输入密码时),以确保你不会犯错。
|
||||
>
|
||||
> 第二个原因是*安全*。如果你不知道管理员用户的登录信息,则系统更难被攻击。拥有 root 的访问权限意味着你已经能够进行管理员身份下的一半工作任务。
|
||||
|
||||
**4、`rm` 和 `rm -rf` 有什么区别?**
|
||||
|
||||
> `rm` 命令本身仅删除指明的文件(而不删除目录)。使用 `-rf` 标志,你添加了两个附加功能:`-r`(或等价的 `-R`、`--recursive`)标志可以递归删除目录的内容,包括隐藏的文件和子目录;而 `-f`(或 `--force`)标志使 `rm` 忽略不存在的文件,并且从不提示你进行确认。
|
||||
|
||||
**5、有一个大小约为 15GB 的 `Compress.tgz` 文件。你如何列出其内容,以及如何仅提取出特定文件?**
|
||||
|
||||
> 要列出文件的内容:
|
||||
>
|
||||
> `tar tf archive.tgz`
|
||||
>
|
||||
> 要提取特定文件:
|
||||
>
|
||||
> `tar xf archive.tgz filename`
|
||||
|
||||
### 有点难度的问题
|
||||
|
||||
这是你可能会遇到的一些较难的问题,以及我的答案:
|
||||
|
||||
**6、什么是 RAID?什么是 RAID 0、RAID 1、RAID 5、RAID 6 和 RAID 10?**
|
||||
|
||||
> RAID(<ruby>廉价磁盘冗余阵列<rt>Redundant Array of Inexpensive Disks</rt></ruby>)是一种用于提高数据存储性能和/或可靠性的技术。RAID 级别为:
|
||||
>
|
||||
> * RAID 0:也称为磁盘条带化,这是一种分解文件并将数据分布在 RAID 组中所有磁盘驱动器上的技术。它没有防止磁盘失败的保障。([引文][3])
|
||||
> * RAID 1:一种流行的磁盘子系统,通过在两个驱动器上写入相同的数据来提高安全性。RAID 1 被称为*镜像*,它不会提高写入性能,但读取性能可能会提高到每个磁盘性能的总和。另外,如果一个驱动器发生故障,则会使用第二个驱动器,发生故障的驱动器需要手动更换。更换后,RAID 控制器会将可工作的驱动器的内容复制到新驱动器上。
|
||||
> * RAID 5:一种磁盘子系统,可通过计算奇偶校验数据来提高安全性和提高速度。RAID 5 通过跨三个或更多驱动器交错数据(条带化)来实现此目的。在单个驱动器发生故障时,后续读取可以从分布式奇偶校验计算出,从而不会丢失任何数据。
|
||||
> * RAID 6:通过添加另一个奇偶校验块来扩展 RAID 5。此级别至少需要四个磁盘,并且可以在任何两个并发磁盘故障的情况下继续执行读/写操作。RAID 6 不会对读取操作造成性能损失,但由于与奇偶校验计算相关的开销,因此确实会对写入操作造成性能损失。
|
||||
> * RAID 10:RAID 10 也称为 RAID 1 + 0,它结合了磁盘镜像和磁盘条带化功能来保护数据。它至少需要四个磁盘,并且跨镜像对对数据进行条带化。只要每个镜像对中的一个磁盘起作用,就可以检索数据。如果同一镜像对中的两个磁盘发生故障,则所有数据将丢失,因为带区集中没有奇偶校验。([引文][4])
|
||||
|
||||
**7、`ping` 命令使用哪个端口?**
|
||||
|
||||
> `ping` 命令使用 ICMP。具体来说,它使用 ICMP 回显请求和应答包。
|
||||
>
|
||||
> ICMP 不使用 UDP 或 TCP 通信服务:相反,它使用原始的 IP 通信服务。这意味着,ICMP 消息直接承载在 IP 数据报数据字段中。
|
||||
|
||||
**8、路由器和网关之间有什么区别?什么是默认网关?**
|
||||
|
||||
> *路由器*描述的是一种通用技术功能(第 3 层转发)或用于该目的的硬件设备,而*网关*描述的是本地网段的功能(提供到其他地方的连接性)。你还可以说“将路由器设置为网关”。另一个术语是“跳”,它描述了子网之间的转发。
|
||||
>
|
||||
> 术语*默认网关*表示局域网上的路由器,它的责任是作为对局域网外部的计算机通信的第一个联系点。
|
||||
|
||||
**9、解释一下 Linux 的引导过程。**
|
||||
|
||||
> BIOS -> 主引导记录(MBR) -> GRUB -> 内核 -> 初始化 -> 运行级
|
||||
|
||||
**10、服务器启动时如何检查错误消息?**
|
||||
|
||||
> 内核消息始终存储在 kmsg 缓冲区中,可通过 `dmesg` 命令查看。
|
||||
>
|
||||
> 引导出现的问题和错误要求系统管理员结合某些特定命令来查看某些重要文件,这些文件不同版本的 Linux 处理方式不同:
|
||||
>
|
||||
> * `/var/log/boot.log` 是系统引导日志,其中包含系统引导过程中展开的所有内容。
|
||||
> * `/var/log/messages` 存储全局系统消息,包括系统引导期间记录的消息。
|
||||
> * `/var/log/dmesg` 包含内核环形缓冲区信息。
|
||||
|
||||
**11、符号链接和硬链接有什么区别?**
|
||||
|
||||
> *符号链接*(*软链接*)实际是到原始文件的链接,而*硬链接*是原始文件的镜像副本。如果删除原始文件,则该软链接就没有用了,因为它指向的文件不存在了。如果是硬链接,则完全相反。如果删除原始文件,则硬链接仍然包含原始文件中的数据。([引文][5])
|
||||
|
||||
**12、如何更改内核参数?你可能需要调整哪些内核选项?**
|
||||
|
||||
> 要在类 Unix 系统中设置内核参数,请首先编辑文件 `/etc/sysctl.conf`。进行更改后,保存文件并运行 `sysctl -p` 命令。此命令使更改永久生效,而无需重新启动计算机
|
||||
|
||||
**13、解释一下 `/proc` 文件系统。**
|
||||
|
||||
> `/proc` 文件系统是虚拟的,并提供有关内核、硬件和正在运行的进程的详细信息。由于 `/proc` 包含虚拟文件,因此称为“虚拟文件系统”。这些虚拟文件具有独特性。其中大多数显示为零字节。
|
||||
>
|
||||
> 虚拟文件,例如 `/proc/interrupts`、`/proc/meminfo`、`/proc/mounts` 和 `/proc/partitions`,提供了系统硬件的最新信息。其他诸如 `/proc/filesystems` 和 `/proc/sys` 目录提供系统配置信息和接口。
|
||||
|
||||
**14、如何在没有密码的情况下以其他用户身份运行脚本?**
|
||||
|
||||
> 例如,如果你可以编辑 sudoers 文件(例如 `/private/etc/sudoers`),则可以使用 `visudo` 添加以下[内容][2]:
|
||||
>
|
||||
> `user1 ALL =(user2)NOPASSWD:/opt/scripts/bin/generate.sh`
|
||||
|
||||
**15、什么是 UID 0 toor 帐户?是被入侵了么?**
|
||||
|
||||
> `toor` 用户是备用的超级用户帐户,其中 `toor` 是 `root` 反向拼写。它预期与非标准 shell 一起使用,因此 `root` 的默认 shell 不需要更改。
|
||||
>
|
||||
> 此用途很重要。这些 shell 不是基本发行版的一部分,而是从 ports 或软件包安装的,它们安装在 `/usr/local/bin` 中,默认情况下,位于其他文件系统上。如果 root 的 shell 位于 `/usr/local/bin` 中,并且未挂载包含 `/usr/local/bin` 的文件系统,则 root 无法登录以解决问题,并且系统管理员必须重新启动进入单用户模式来输入 shell 程序的路径。
|
||||
|
||||
### 更难的问题
|
||||
|
||||
这是你可能会遇到的甚至更困难的问题:
|
||||
|
||||
**16、`tracert` 如何工作,使用什么协议?**
|
||||
|
||||
> 命令 `tracert`(或 `traceroute`,具体取决于操作系统)使你可以准确地看到在连接到最终目的地的连接链条中所触及的路由器。如果你遇到无法连接或无法 `ping` 通最终目的地的问题,则可以使用 `tracert` 来帮助你确定连接链在何处停止。([引文][6])
|
||||
>
|
||||
> 通过此信息,你可以联系正确的人;无论是你自己的防火墙、ISP、目的地的 ISP 还是中间的某个位置。 `tracert` 命令像 `ping` 一样使用 ICMP 协议,但也可以使用 TCP 三步握手的第一步来发送 SYN 请求以进行响应。
|
||||
|
||||
**17、使用 `chroot` 的主要优点是什么?我们何时以及为什么使用它?在 chroot 环境中,`mount /dev`、`mount /proc` 和 `mount /sys` 命令的作用是什么?**
|
||||
|
||||
> chroot 环境的优点是文件系统与物理主机是隔离的,因为 chroot 在文件系统内部有一个单独的文件系统。区别在于 `chroot` 使用新创建的根目录(`/`)作为其根目录。
|
||||
>
|
||||
> chroot 监狱可让你将进程及其子进程与系统其余部分隔离。它仅应用于不以 root 身份运行的进程,因为 root 用户可以轻松地脱离监狱。
|
||||
>
|
||||
> 该思路是创建一个目录树,在其中复制或链接运行该进程所需的所有系统文件。然后,你可以使用 `chroot()` 系统调用来告诉它根目录现在位于此新树的基点上,然后启动在该 chroot 环境中运行的进程。由于该命令因此而无法引用修改后的根目录之外的路径,因此它无法在这些位置上执行恶意操作(读取、写入等)。([引文][7])
|
||||
|
||||
**18、如何保护你的系统免遭黑客攻击?**
|
||||
|
||||
> 遵循最低特权原则和这些做法:
|
||||
>
|
||||
> * 使用公钥加密,它可提供出色的安全性。
|
||||
> * 增强密码复杂性。
|
||||
> * 了解为什么要对上述规则设置例外。
|
||||
> * 定期检查你的例外情况。
|
||||
> * 让具体的人对失败负责。(它使你保持警惕。)([引文][8])
|
||||
|
||||
**19、什么是 LVM,使用 LVM 有什么好处?**
|
||||
|
||||
> LVM(逻辑卷管理)是一种存储设备管理技术,该技术使用户能够合并和抽象化组件存储设备的物理布局,从而可以更轻松、灵活地进行管理。使用设备映射器的 Linux 内核框架,当前迭代(LVM2)可用于将现有存储设备收集到组中,并根据需要从组合的空间分配逻辑单元。
|
||||
|
||||
**20、什么是粘性端口?**
|
||||
|
||||
> 粘性端口是网络管理员最好的朋友,也是最头痛的事情之一。它们允许你设置网络,以便通过将交换机上的每个端口锁定到特定的 MAC 地址,仅允许一台(或你指定的数字)计算机在该端口上进行连接。
|
||||
|
||||
**21、解释一下端口转发?**
|
||||
|
||||
> 尝试与安全的网络内部的系统进行通信时,从外部进行通信可能非常困难,这是很显然的。因此,在路由器本身或其他连接管理设备中使用端口转发表可以使特定流量自动转发到特定目的地。例如,如果你的网络上运行着一台 Web 服务器,并且想从外部授予对该服务器的访问权限,则可以将端口转发设置为该服务器上的端口 80。这意味着在 Web 浏览器中输入你的(外网)IP 地址的任何人都将立即连接到该服务器的网站。
|
||||
>
|
||||
> 请注意,通常不建议允许从你的网络外部直接访问服务器。
|
||||
|
||||
**22、对于 IDS,误报和漏报是什么?**
|
||||
|
||||
> 当入侵检测系统(IDS)设备为实际上没有发生的入侵生成警报时,这是<ruby>误报(假阳性)<rt>false positive</rt></ruby>。如果设备未生成任何警报,而入侵实际上已发生,则为<ruby>漏报(假阴性)</rt></ruby>。
|
||||
|
||||
**23、解释一下 `:(){ :|:& };:`,如果已经登录系统,如何停止此代码?**
|
||||
|
||||
> 这是一枚复刻炸弹。它分解如下:
|
||||
>
|
||||
> * `:()` 定义了函数,以 `:` 作为函数名,并且空括号表示它不接受任何参数。
|
||||
> * `{}` 是函数定义的开始和结束。
|
||||
> * `:|:` 将函数 `:` 的副本加载到内存中,并将其输出通过管道传递给函数 `:` 的另一个副本,该副本也必须加载到内存中。
|
||||
> * `&` 使前一个命令行成为后台进程,因此即使父进程被自动杀死,子进程也不会被杀死。
|
||||
> * `:` 执行该函数,因此连锁反应开始。
|
||||
>
|
||||
> 保护多用户系统的最佳方法是使用特权访问管理(PAM)来限制用户可以使用的进程数。
|
||||
>
|
||||
> 复刻炸弹的最大问题是它发起了太多进程。因此,如果你已经登录系统,我们有两种尝试解决此问题的方法。一种选择是执行一个 `SIGSTOP` 命令来停止进程,例如:
|
||||
>
|
||||
> `killall -STOP -u user1`
|
||||
>
|
||||
> 如果由于占用了所有进程而无法使用命令行,则必须使用 `exec` 强制其运行:
|
||||
>
|
||||
> `exec killall -STOP -u user1`
|
||||
>
|
||||
> 对于复刻炸弹,最好的选择是防患于未然。
|
||||
|
||||
**24、什么是 OOM 杀手,它如何决定首先杀死哪个进程?**
|
||||
|
||||
> 如果内存被进程彻底耗尽,可能会威胁到系统的稳定性,那么<ruby>内存不足<rt>out of memory</rt></ruby>(OOM)杀手就登场了。
|
||||
>
|
||||
> OOM 杀手首先必须选择要杀死的最佳进程。*最佳*在这里指的是在被杀死时将释放最大内存的进程,并且对系统来说最不重要。主要目标是杀死最少数量的进程,以最大程度地减少造成的损害,同时最大化释放的内存量。
|
||||
>
|
||||
> 为了实现此目标,内核为每个进程维护一个 `oom_score`。你可以在 `/proc` 文件系统中的 `pid` 目录下的看到每个进程的 `oom_score`:
|
||||
>
|
||||
> `$ cat /proc/10292/oom_score`
|
||||
>
|
||||
> 任何进程的 `oom_score` 值越高,在内存不足的情况下被 OOM 杀手杀死的可能性就越高。([引文][9])
|
||||
|
||||
### 总结
|
||||
|
||||
系统管理人员的薪水[差别很大][10],有些网站上说年薪在 70,000 到 100,000 美元之间,具体取决于地点、组织的规模以及你的教育水平以及多年的工作经验。系统管理的职业道路最终归结为你对使用服务器和解决那些酷问题的兴趣。现在,我要说,继续前进,实现你的梦想之路吧!
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/19/7/sysadmin-job-interview-questions
|
||||
|
||||
作者:[DirectedSoul][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[wxy](https://github.com/wxy)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/directedsoul
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/OSDC_HowToFish_520x292.png?itok=DHbdxv6H (Question and answer.)
|
||||
[2]: https://github.com/trimstray/test-your-sysadmin-skills
|
||||
[3]: https://www.waytoeasylearn.com/2016/05/netapp-filer-tutorial.html
|
||||
[4]: https://searchstorage.techtarget.com/definition/RAID-10-redundant-array-of-independent-disks
|
||||
[5]: https://www.answers.com/Q/What_is_hard_link_and_soft_link_in_Linux
|
||||
[6]: https://www.wisdomjobs.com/e-university/network-administrator-interview-questions.html
|
||||
[7]: https://unix.stackexchange.com/questions/105/chroot-jail-what-is-it-and-how-do-i-use-it
|
||||
[8]: https://serverfault.com/questions/391370/how-to-prevent-zero-day-attacks
|
||||
[9]: https://unix.stackexchange.com/a/153586/8369
|
||||
[10]: https://blog.netwrix.com/2018/07/23/systems-administrator-salary-in-2018-how-much-can-you-earn/
|
82
published/20190827 curl exercises.md
Normal file
82
published/20190827 curl exercises.md
Normal file
@ -0,0 +1,82 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (hanwckf)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11648-1.html)
|
||||
[#]: subject: (curl exercises)
|
||||
[#]: via: (https://jvns.ca/blog/2019/08/27/curl-exercises/)
|
||||
[#]: author: (Julia Evans https://jvns.ca/)
|
||||
|
||||
21 个 curl 命令练习
|
||||
======
|
||||
|
||||
最近,我对人们如何学习新事物感兴趣。我正在读 Kathy Sierra 的好书《[Badass: Making Users Awesome][1]》,它探讨了有关“刻意练习”的想法。这个想法是,你找到一个可以用三节 45 分钟课程内能够学会的小技能,并专注于学习这项小技能。因此,作为一项练习,我尝试考虑一项能够在三节 45 分钟课程内学会的计算机技能。
|
||||
|
||||
我认为使用 `curl` 构造 HTTP 请求也许就是这样的一项技能,所以这里有一些 `curl` 练习作为实验!
|
||||
|
||||
### 什么是 curl ?
|
||||
|
||||
`curl` 是用于构造 HTTP 请求的命令行工具。我喜欢使用 `curl`,因为它能够很轻松地测试服务器或 API 的行为是否符合预期,但是刚开始接触它的时候会让你感到一些困惑!
|
||||
|
||||
下面是一幅解释 `curl` 常用命令行参数的漫画 (在我的 [Bite Size Networking][2] 杂志的第 6 页)。
|
||||
|
||||

|
||||
|
||||
### 熟能生巧
|
||||
|
||||
对于任何命令行工具,我认为熟练使用是很有帮助的,能够做到只输入必要的命令真是太好了。例如,最近我在测试 Gumroad API,我只需要输入:
|
||||
|
||||
```
|
||||
curl https://api.gumroad.com/v2/sales \
|
||||
-d "access_token=<SECRET>" \
|
||||
-X GET -d "before=2016-09-03"
|
||||
```
|
||||
|
||||
就能从命令行中得到想要的结果。
|
||||
|
||||
### 21 个 curl 练习
|
||||
|
||||
这些练习是用来理解如何使用 `curl` 构造不同种类的 HTTP 请求的,它们是故意有点重复的,基本上包含了我需要 `curl` 做的任何事情。
|
||||
|
||||
为了简单起见,我们将对 https://httpbin.org 发起一系列 HTTP 请求,httpbin 接受 HTTP 请求,然后在响应中回显你所发起的 HTTP 请求。
|
||||
|
||||
1. 请求 <https://httpbin.org>
|
||||
2. 请求 <https://httpbin.org/anything>,它将会解析你发起的请求,并且在响应中回显。`curl` 默认发起的是 GET 请求
|
||||
3. 向 <https://httpbin.org/anything> 发起 GET 请求
|
||||
4. 向 <https://httpbin.org/anything> 发起 GET 请求,但是这次需要添加一些查询参数(设置 `value=panda`)
|
||||
5. 请求 Google 的 `robots.txt` 文件 ([www.google.com/robots.txt][3])
|
||||
6. 向 <https://httpbin.org/anything> 发起 GET 请求,并且设置请求头为 `User-Agent: elephant`
|
||||
7. 向 <https://httpbin.org/anything> 发起 DELETE 请求
|
||||
8. 请求 <https://httpbin.org/anything> 并获取响应头信息
|
||||
9. 向 <https://httpbin.com/anything> 发起请求体为 JSON `{"value": "panda"}` 的 POST 请求
|
||||
10. 发起与上一次相同的 POST 请求,但是这次要把请求头中的 `Content-Type` 字段设置成 `application/json`(因为 POST 请求需要一个与请求体相匹配的 `Content-Type` 请求头字段)。查看响应体中的 `json` 字段,对比上一次得到的响应体
|
||||
11. 向 <https://httpbin.org/anything> 发起 GET 请求,并且在请求头中设置 `Accept-Encoding: gzip`(将会发生什么?为什么会这样?)
|
||||
12. 将一些 JSON 放在文件中,然后向 <https://httpbin.org/anything> 发起请求体为该文件的 POST 请求
|
||||
13. 设置请求头为 `Accept: image/png` 并且向 <https://httpbin.org/image> 发起请求,将输出保存为 PNG 文件,然后使用图片浏览器打开。尝试使用不同的 `Accept:` 字段去请求此 URL
|
||||
14. 向 <https://httpbin.org/anything> 发起 PUT 请求
|
||||
15. 请求 <https://httpbin.org/image/jpeg> 并保存为文件,然后使用你的图片编辑器打开这个文件
|
||||
16. 请求 <https://www.twitter.com>,你将会得到空的响应。让 `curl` 显示出响应头信息,并尝试找出响应内容为空的原因
|
||||
17. 向 <https://httpbin.org/anything> 发起任意的请求,同时设置一些无意义的请求头(例如:`panda: elephant`)
|
||||
18. 请求 <https://httpbin.org/status/404> 和 <https://httpbin.org/status/200>,然后再次请求它们并且让 curl 显示响应头信息
|
||||
19. 请求 <https://httpbin.org/anything> 并且设置用户名和密码(使用 `-u username:password`)
|
||||
20. 设置 `Accept-Language: es-ES` 的请求头用以下载 Twitter 的西班牙语主页 (<https://twitter.com>)
|
||||
21. 使用 `curl` 向 Stripe API 发起请求(请查看 <https://stripe.com/docs/development> 了解如何使用,他们会给你一个测试用的 API key)。尝试向 <https://httpbin.org/anything> 发起相同的请求
|
||||
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://jvns.ca/blog/2019/08/27/curl-exercises/
|
||||
|
||||
作者:[Julia Evans][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[hanwckf](https://github.com/hanwckf)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://jvns.ca/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://www.amazon.com/Badass-Making-Awesome-Kathy-Sierra/dp/1491919019
|
||||
[2]: https://wizardzines.com/zines/bite-size-networking
|
||||
[3]: http://www.google.com/robots.txt
|
220
published/20190927 5 tips for GNU Debugger.md
Normal file
220
published/20190927 5 tips for GNU Debugger.md
Normal file
@ -0,0 +1,220 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (wxy)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11647-1.html)
|
||||
[#]: subject: (5 tips for GNU Debugger)
|
||||
[#]: via: (https://opensource.com/article/19/9/tips-gnu-debugger)
|
||||
[#]: author: (Tim Waugh https://opensource.com/users/twaugh)
|
||||
|
||||
5 个鲜为人知 GNU 调试器(GDB)技巧
|
||||
======
|
||||
|
||||
> 了解如何使用 gdb 的一些鲜为人知的功能来检查和修复代码。
|
||||
|
||||

|
||||
|
||||
[GNU 调试器][2](`gdb`)是一种宝贵的工具,可用于在开发程序时检查正在运行的进程并解决问题。
|
||||
|
||||
你可以在特定位置(按函数名称、行号等)设置断点、启用和禁用这些断点、显示和更改变量值,并执行所有调试器希望执行的所有标准操作。但是它还有许多其它你可能没有尝试过的功能。这里有五个你可以尝试一下。
|
||||
|
||||
### 条件断点
|
||||
|
||||
设置断点是学习使用 GNU 调试器的第一步。程序在达到断点时停止,你可以运行 `gdb` 的命令对其进行检查或更改变量,然后再允许该程序继续运行。
|
||||
|
||||
例如,你可能知道一个经常调用的函数有时会崩溃,但仅当它获得某个参数值时才会崩溃。你可以在该函数的开始处设置一个断点并运行程序。每次碰到该断点时都会显示函数参数,并且如果未提供触发崩溃的参数值,则可以继续操作,直到再次调用该函数为止。当这个惹了麻烦的参数触发崩溃时,你可以单步执行代码以查看问题所在。
|
||||
|
||||
|
||||
```
|
||||
(gdb) break sometimes_crashes
|
||||
Breakpoint 1 at 0x40110e: file prog.c, line 5.
|
||||
(gdb) run
|
||||
[...]
|
||||
Breakpoint 1, sometimes_crashes (f=0x7fffffffd1bc) at prog.c:5
|
||||
5 fprintf(stderr,
|
||||
(gdb) continue
|
||||
Breakpoint 1, sometimes_crashes (f=0x7fffffffd1bc) at prog.c:5
|
||||
5 fprintf(stderr,
|
||||
(gdb) continue
|
||||
```
|
||||
|
||||
为了使此方法更具可重复性,你可以在你感兴趣的特定调用之前计算该函数被调用的次数,并在该断点处设置一个计数器(例如,`continue 30` 以使其在接下来的 29 次到达该断点时忽略它)。
|
||||
|
||||
但是断点真正强大的地方在于它们在运行时评估表达式的能力,这使你可以自动化这种测试。
|
||||
|
||||
```
|
||||
break [LOCATION] if CONDITION
|
||||
|
||||
(gdb) break sometimes_crashes if !f
|
||||
Breakpoint 1 at 0x401132: file prog.c, line 5.
|
||||
(gdb) run
|
||||
[...]
|
||||
Breakpoint 1, sometimes_crashes (f=0x0) at prog.c:5
|
||||
5 fprintf(stderr,
|
||||
(gdb)
|
||||
```
|
||||
|
||||
条件断点使你不必让 `gdb` 每次调用该函数时都去问你要做什么,而是让条件断点仅在特定表达式的值为 `true` 时才使 `gdb` 停止在该位置。如果执行到达条件断点的位置,但表达式的计算结果为 `false`,调试器会自动使程序继续运行,而无需询问用户该怎么做。
|
||||
|
||||
### 断点命令
|
||||
|
||||
GNU 调试器中断点的一个甚至更复杂的功能是能够编写对到达断点的响应的脚本。断点命令使你可以编写一系列 GNU 调试器命令,以在到达该断点时运行。
|
||||
|
||||
我们可以使用它来规避在 `sometimes_crashes` 函数中我们已知的错误,并在它提供空指针时使其无害地从该函数返回。
|
||||
|
||||
我们可以使用 `silent` 作为第一行,以更好地控制输出。否则,每次命中断点时,即使在运行断点命令之前,也会显示堆栈帧。
|
||||
|
||||
```
|
||||
(gdb) break sometimes_crashes
|
||||
Breakpoint 1 at 0x401132: file prog.c, line 5.
|
||||
(gdb) commands 1
|
||||
Type commands for breakpoint(s) 1, one per line.
|
||||
End with a line saying just "end".
|
||||
>silent
|
||||
>if !f
|
||||
>frame
|
||||
>printf "Skipping call\n"
|
||||
>return 0
|
||||
>continue
|
||||
>end
|
||||
>printf "Continuing\n"
|
||||
>continue
|
||||
>end
|
||||
(gdb) run
|
||||
Starting program: /home/twaugh/Documents/GDB/prog
|
||||
warning: Loadable section ".note.gnu.property" outside of ELF segments
|
||||
Continuing
|
||||
Continuing
|
||||
Continuing
|
||||
#0 sometimes_crashes (f=0x0) at prog.c:5
|
||||
5 fprintf(stderr,
|
||||
Skipping call
|
||||
[Inferior 1 (process 9373) exited normally]
|
||||
(gdb)
|
||||
```
|
||||
|
||||
### 转储二进制内存
|
||||
|
||||
GNU 调试器内置支持使用 `x` 命令以各种格式检查内存,包括八进制、十六进制等。但是我喜欢并排看到两种格式:左侧为十六进制字节,右侧为相同字节表示的 ASCII 字符。
|
||||
|
||||
当我想逐字节查看文件的内容时,经常使用 `hexdump -C`(`hexdump` 来自 [util-linux][3] 软件包)。这是 `gdb` 的 `x` 命令显示的十六进制字节:
|
||||
|
||||
```
|
||||
(gdb) x/33xb mydata
|
||||
0x404040 <mydata> : 0x02 0x01 0x00 0x02 0x00 0x00 0x00 0x01
|
||||
0x404048 <mydata+8> : 0x01 0x47 0x00 0x12 0x61 0x74 0x74 0x72
|
||||
0x404050 <mydata+16>: 0x69 0x62 0x75 0x74 0x65 0x73 0x2d 0x63
|
||||
0x404058 <mydata+24>: 0x68 0x61 0x72 0x73 0x65 0x75 0x00 0x05
|
||||
0x404060 <mydata+32>: 0x00
|
||||
```
|
||||
|
||||
如果你想让 `gdb` 像 `hexdump` 一样显示内存怎么办?这是可以的,实际上,你可以将这种方法用于你喜欢的任何格式。
|
||||
|
||||
通过使用 `dump` 命令以将字节存储在文件中,结合 `shell` 命令以在文件上运行 `hexdump` 以及`define` 命令,我们可以创建自己的新的 `hexdump` 命令来使用 `hexdump` 显示内存内容。
|
||||
|
||||
```
|
||||
(gdb) define hexdump
|
||||
Type commands for definition of "hexdump".
|
||||
End with a line saying just "end".
|
||||
>dump binary memory /tmp/dump.bin $arg0 $arg0+$arg1
|
||||
>shell hexdump -C /tmp/dump.bin
|
||||
>end
|
||||
```
|
||||
|
||||
这些命令甚至可以放在 `~/.gdbinit` 文件中,以永久定义 `hexdump` 命令。以下是它运行的例子:
|
||||
|
||||
```
|
||||
(gdb) hexdump mydata sizeof(mydata)
|
||||
00000000 02 01 00 02 00 00 00 01 01 47 00 12 61 74 74 72 |.........G..attr|
|
||||
00000010 69 62 75 74 65 73 2d 63 68 61 72 73 65 75 00 05 |ibutes-charseu..|
|
||||
00000020 00 |.|
|
||||
00000021
|
||||
```
|
||||
|
||||
### 行内反汇编
|
||||
|
||||
有时你想更多地了解导致崩溃的原因,而源代码还不够。你想查看在 CPU 指令级别发生了什么。
|
||||
|
||||
`disassemble` 命令可让你查看实现函数的 CPU 指令。但是有时输出可能很难跟踪。通常,我想查看与该函数源代码的特定部分相对应的指令。为此,请使用 `/s` 修饰符在反汇编中包括源代码行。
|
||||
|
||||
```
|
||||
(gdb) disassemble/s main
|
||||
Dump of assembler code for function main:
|
||||
prog.c:
|
||||
11 {
|
||||
0x0000000000401158 <+0>: push %rbp
|
||||
0x0000000000401159 <+1>: mov %rsp,%rbp
|
||||
0x000000000040115c <+4>: sub $0x10,%rsp
|
||||
|
||||
12 int n = 0;
|
||||
0x0000000000401160 <+8>: movl $0x0,-0x4(%rbp)
|
||||
|
||||
13 sometimes_crashes(&n);
|
||||
0x0000000000401167 <+15>: lea -0x4(%rbp),%rax
|
||||
0x000000000040116b <+19>: mov %rax,%rdi
|
||||
0x000000000040116e <+22>: callq 0x401126 <sometimes_crashes>
|
||||
[...snipped...]
|
||||
```
|
||||
|
||||
这里,用 `info` 寄存器查看所有 CPU 寄存器的当前值,以及用如 `stepi` 这样命令一次执行一条指令,可以使你对程序有了更详细的了解。
|
||||
|
||||
### 反向调试
|
||||
|
||||
有时,你希望自己可以逆转时间。想象一下,你已经达到了变量的监视点。监视点像是一个断点,但不是在程序中的某个位置设置,而是在表达式上设置(使用 `watch` 命令)。每当表达式的值更改时,执行就会停止,并且调试器将获得控制权。
|
||||
|
||||
想象一下你已经达到了这个监视点,并且由该变量使用的内存已更改了值。事实证明,这可能是由更早发生的事情引起的。例如,内存已释放,现在正在重新使用。但是它是何时何地被释放的呢?
|
||||
|
||||
GNU 调试器甚至可以解决此问题,因为你可以反向运行程序!
|
||||
|
||||
它通过在每个步骤中仔细记录程序的状态来实现此目的,以便可以恢复以前记录的状态,从而产生时间倒流的错觉。
|
||||
|
||||
要启用此状态记录,请使用 `target record-full` 命令。然后,你可以使用一些听起来不太可行的命令,例如:
|
||||
|
||||
* `reverse-step`,倒退到上一个源代码行
|
||||
* `*reverse-next`,它倒退到上一个源代码行,向后跳过函数调用
|
||||
* `reverse-finish`,倒退到当前函数即将被调用的时刻
|
||||
* `reverse-continue`,它返回到程序中的先前状态,该状态将(现在)触发断点(或其他导致断点停止的状态)
|
||||
|
||||
这是运行中的反向调试的示例:
|
||||
|
||||
```
|
||||
(gdb) b main
|
||||
Breakpoint 1 at 0x401160: file prog.c, line 12.
|
||||
(gdb) r
|
||||
Starting program: /home/twaugh/Documents/GDB/prog
|
||||
[...]
|
||||
|
||||
Breakpoint 1, main () at prog.c:12
|
||||
12 int n = 0;
|
||||
(gdb) target record-full
|
||||
(gdb) c
|
||||
Continuing.
|
||||
|
||||
Program received signal SIGSEGV, Segmentation fault.
|
||||
0x0000000000401154 in sometimes_crashes (f=0x0) at prog.c:7
|
||||
7 return *f;
|
||||
(gdb) reverse-finish
|
||||
Run back to call of #0 0x0000000000401154 in sometimes_crashes (f=0x0)
|
||||
at prog.c:7
|
||||
0x0000000000401190 in main () at prog.c:16
|
||||
16 sometimes_crashes(0);
|
||||
```
|
||||
|
||||
这些只是 GNU 调试器可以做的一些有用的事情。还有更多有待发现。你最喜欢 `gdb` 的哪个隐藏的、鲜为人知或令人吃惊的功能?请在评论中分享。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/19/9/tips-gnu-debugger
|
||||
|
||||
作者:[Tim Waugh][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[wxy](https://github.com/wxy)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/twaugh
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/bug_software_issue_tracking_computer_screen.jpg?itok=6qfIHR5y (Bug tracking magnifying glass on computer screen)
|
||||
[2]: https://www.gnu.org/software/gdb/
|
||||
[3]: https://en.wikipedia.org/wiki/Util-linux
|
200
published/20191004 What-s in an open source name.md
Normal file
200
published/20191004 What-s in an open source name.md
Normal file
@ -0,0 +1,200 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (laingke)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11688-1.html)
|
||||
[#]: subject: (What's in an open source name?)
|
||||
[#]: via: (https://opensource.com/article/19/10/open-source-name-origins)
|
||||
[#]: author: (Joshua Allen Holm https://opensource.com/users/holmja)
|
||||
|
||||
开源软件名称中的故事
|
||||
======
|
||||
|
||||
> 有没有想过你喜欢的开源项目或编程语言的名称来自何处?让我们按字母顺序了解一下流行的技术术语背后的起源故事。
|
||||
|
||||

|
||||
|
||||
GNOME、Java、Jupyter、Python……如果你的朋友或家人曾留意过你的工作对话,他们可能会认为你从事文艺复兴时期的民间文学艺术、咖啡烘焙、天文学或动物学工作。这些开源技术的名称从何而来?我们请我们的作者社区提供意见,并汇总了一些我们最喜欢的技术名称的起源故事。
|
||||
|
||||
### Ansible
|
||||
|
||||
“Ansible”这个名称直接来自科幻小说。Ursula Le Guin 的《Rocannon's World》一书中能进行即时(比光速更快)通信的设备被称为 ansibles(显然来自 “answerable” 一词)。Ansibles 开始流行于科幻小说之中,Orson Scott Card 的《Ender's Game》(后来成为受欢迎的电影)中,该设备控制了许多远程太空飞船。对于控制分布式机器的软件来说,这似乎是一个很好的模型,因此 Michael DeHaan(Ansible 的创建者和创始人)借用了这个名称。
|
||||
|
||||
### Apache
|
||||
|
||||
[Apache][2] 是最初于 1995 年发布的开源 Web 服务器。它的名称与著名的美国原住民部落无关;相反,它是指对原始软件代码的重复补丁。因此称之为,“<ruby>一个修补的<rt>A-patchy</rt></ruby>服务器”。
|
||||
|
||||
### awk
|
||||
|
||||
“awk(1) 代表着 Aho、Weinberger、Kernighan(作者)”—— Michael Greenberg
|
||||
|
||||
### Bash
|
||||
|
||||
“最初的 Unix shell,即 Bourne shell,是以其创造者的名字命名的。在开发出来 Bash 时,csh(发音为 ‘seashell’)实际上更受交互登录用户的欢迎。Bash 项目旨在赋予 Bourne shell 新的生命,使其更适合于交互式使用,因此它被命名为 ‘Bourne again shell’,是‘<ruby>重生<rt>born again</rt></ruby>’的双关语。”——Ken Gaillot
|
||||
|
||||
### C
|
||||
|
||||
在早期,AT&T 的 Ken Thompson 和 Dennis Ritchie 发现可以使用更高级的编程语言(而不是低级的、可移植性更低的汇编编程)来编写操作系统和工具。早期有一个叫做 BCPL(<ruby>基本组合编程语言<rt>Basic Combined programming Language</rt></ruby>)的编程系统,Thompson 创建了一个名为 B 的简化版 BCPL,但 B 的灵活性和速度都不高。然后,Ritchie 把 B 的思想扩展成一种叫做 C 的编译语言。”——Jim Hall
|
||||
|
||||
### dd
|
||||
|
||||
“我想你发表这样一篇文章不能不提到 dd。我的外号叫 Didi。发音正确的话听起来像 ‘dd’。我开始学的是 Unix,然后是 Linux,那是在 1993 年,当时我还是个学生。然后我去了军队,来到了我的部队中少数几个使用 Unix(Ultrix)的部门之一(其它部门主要是 VMS),那里的一个人说:‘这么说,你是一个黑客,对吗?你以为你了解 Unix 吗?好的,那么 dd 这个名字的是怎么来的呢?’我不知道,试着猜道:‘<ruby>数据复印机<rt>Data duplicator</rt></ruby>?’所以他说,‘我要告诉你 dd 的故事。dd 是<ruby>转换<rt>convert</rt></ruby>和<ruby>复制<rt>copy</rt></ruby>的缩写(如今人们仍然可以在手册页中看到),但由于 cc 这个缩写已经被 C 编译器占用,所以它被命名为 dd。’就在几年后,我听闻了关于 JCL 的数据定义和 Unix dd 命令不统一的、半开玩笑的语法的真实故事,某种程度是基于此的。”——Yedidyah Bar David
|
||||
|
||||
### Emacs
|
||||
|
||||
经典的<ruby>反 vi<rt>anti-vi</rt></ruby>编辑器,其名称的真正词源并不明显,因为它源自“<ruby>编辑宏<rt>Editing MACroS</rt></ruby>”。但是,它作为一个伟大的宗教亵渎和崇拜的对象,吸引了许多恶作剧般的缩写,例如“Escape Meta Alt Control Shift”(以调侃其对键盘的大量依赖),“<ruby>8MB 并经常发生内存交换<rt>Eight Megabytes And Constantly Swapping</rt></ruby>”(从那时起就很吃内存了),“<ruby>最终分配了所有的计算机存储空间<rt>Eventually malloc()s All Computer Storage</rt></ruby>”和 “<ruby>EMACS 使一台计算机慢<rt>EMACS Makes A Computer Slow</rt></ruby>”——改编自 Jargon File/Hacker's Dictionary
|
||||
|
||||
### Enarx
|
||||
|
||||
[Enarx][3] 是机密计算领域的一个新项目。该项目的设计原则之一是它应该是“可替代的”。因此最初的名字是“psilocybin”(著名的魔术蘑菇)。一般情况下,经理级别的人可能会对这个名称有所抵触,因此考虑使用新名称。该项目的两位创始人 Mike Bursell 和 Nathaniel McCallum 都是古老语言极客,因此他们考虑了许多不同的想法,包括 тайна(Tayna——俄语中代表秘密或神秘——虽然俄语并不是一门古老的语言,但你就不要在乎这些细节了),crypticon(希腊语的意思是完全私生的),cryptidion(希腊中表示小密室),arconus(拉丁语中表示秘密的褒义形容词),arcanum(拉丁语中表示秘密的中性形容词)和 ærn(盎格鲁撒克逊人表示地方、秘密的地方、壁橱、住所、房子,或小屋的词汇)。最后,由于各种原因,包括域名和 GitHub 项目名称的可用性,他们选择了 enarx,这是两个拉丁词根的组合:en-(表示内部)和 -arx(表示城堡、要塞或堡垒)。
|
||||
|
||||
### GIMP
|
||||
|
||||
没有 [GIMP][4] 我们会怎么样?<ruby>GNU 图像处理项目<rt>GNU Image Manipulation Project</rt></ruby>多年来一直是开源的重要基础。[维基百科][5]指出,“1995 年,[Spencer Kimball][6] 和 [Peter Mattis][7] 在加州大学伯克利分校开始为<ruby>实验计算设施<rt>eXperimental Computing Facility</rt></ruby>开发 GIMP,这是一个为期一个学期的项目。”
|
||||
|
||||
### GNOME
|
||||
|
||||
你有没有想过为什么 GNOME 被称为 GNOME?根据[维基百科][8],GNOME 最初是一个表示“<ruby>GNU 网络对象模型环境<rt>GNU Network Object Model Environment</rt></ruby>”的缩写词。现在,该名称不再表示该项目,并且该项目已被放弃,但这个名称仍然保留了下来。[GNOME 3][9] 是 Fedora、红帽企业版、Ubuntu、Debian、SUSE Linux 企业版等发行版的默认桌面环境。
|
||||
|
||||
### Java
|
||||
|
||||
你能想象这种编程语言还有其它名称吗?Java 最初被称为 Oak,但是遗憾的是,Sun Microsystems 的法律团队由于已有该商标而否决了它。所以开发团队又重新给它命名。[据说][10]该语言的工作组在 1995 年 1 月举行了一次大规模的头脑风暴。许多其它名称也被扔掉了,包括 Silk、DNA、WebDancer 等。该团队不希望新名称与过度使用的术语“web”或“net”有任何关系。取而代之的是,他们在寻找更有活力、更有趣、更容易记住的东西。Java 满足了这些要求,并且奇迹般地,团队同意通过了!
|
||||
|
||||
### Jupyter
|
||||
|
||||
现在许多数据科学家和学生在工作中使用 [Jupyter][11] 笔记本。“Jupyter”这个名字是三种开源计算机语言的融合,这三种语言在这个笔记本中都有使用,在数据科学中也很突出:[Julia][12]、[Python][13] 和 [R][14]。
|
||||
|
||||
### Kubernetes
|
||||
|
||||
Kubernetes 源自希腊语中的舵手。Kubernetes 项目创始人 Craig McLuckie 在 [2015 Hacker News][15] 回应中证实了这种词源。他坚持航海主题,解释说,这项技术可以驱动集装箱,就像舵手或驾驶员驾驶集装箱船一样,因此,他选择了 Kubernetes 这个名字。我们中的许多人仍然在尝试正确的发音(koo-bur-NET-eez),因此 替代使用 K8s 也是可以接受的。有趣的是,它与英语单词“<ruby>行政长官<rt>governor</rt></ruby>”具有相同的词源,也与蒸汽机上的机械负反馈装置相同。
|
||||
|
||||
### KDE
|
||||
|
||||
那 K 桌面呢?KDE 最初代表“<ruby>酷桌面环境<rt>Kool Desktop Environment</rt></ruby>”。 它由 [Matthias Ettrich][16] 于 1996 年创立。根据[维基百科][17]上的说法,该名称是对 Unix 上 <ruby>[通用桌面环境][18]<rt>Common Desktop Environment</rt></ruby>(CDE)一词的调侃。
|
||||
|
||||
### Linux
|
||||
|
||||
[Linux][19] 因其发明者 Linus Torvalds 的名字命名的。Linus 最初想将他的作品命名为“Freax”,因为他认为以他自己的名字命名太自负了。根据[维基百科][19]的说法,“赫尔辛基科技大学 Torvalds 的同事 Ari Lemmke 当时是 FTP 服务器的志愿管理员之一,他并不认为‘Freax’是个好名字。因此,他没有征询 Torvalds 就将服务器上的这个项目命名为‘Linux’。”
|
||||
|
||||
以下是一些最受欢迎的 Linux 发行版。
|
||||
|
||||
#### CentOS
|
||||
|
||||
[CentOS][20] 是<ruby>社区企业操作系统<rt>Community Enterprise Operating System</rt></ruby>的缩写。它包含来自 Red Hat Enterprise Linux 的上游软件包。
|
||||
|
||||
#### Debian
|
||||
|
||||
[Debian][21] Linux 创建于 1993 年 9 月,是其创始人 Ian Murdock 和他当时的女友 Debra Lynn 的名字的混成词。
|
||||
|
||||
#### RHEL
|
||||
|
||||
[Red Hat Linux][22] 得名于它的创始人 Marc Ewing,他戴着一顶祖父送给他的康奈尔大学红色<ruby>软呢帽<rt>fedora</rt></ruby>。红帽公司成立于 1993 年 3 月 26 日。[Fedora Linux][23] 最初是一个志愿者项目,旨在为红帽发行版提供额外的软件,它的名字来自红帽的“Shadowman”徽标。
|
||||
|
||||
#### Ubuntu
|
||||
|
||||
[Ubuntu][24] 旨在广泛分享开源软件,它以非洲哲学“<ruby>人的本质<rt>ubuntu</rt></ruby>”命名,可以翻译为“对他人的人道主义”或“我之所以是我,是因为我们都是这样的人”。
|
||||
|
||||
### Moodle
|
||||
|
||||
开源学习平台 [Moodle][25] 是“<ruby>模块化面向对象动态学习环境<rt>modular object-oriented dynamic learning environment</rt></ruby>”的首字母缩写。Moodle 仍然是领先的线上学习平台。全球有近 10.4 万个注册的 Moodle 网站。
|
||||
|
||||
另外两个流行的开源内容管理系统是 Drupal 和 Joomla。Drupal 的名字来自荷兰语 “druppel”,意思是“掉落”。根据维基百科,Joomla 是斯瓦希里语单词“jumla”的[英式拼写][26],在阿拉伯语、乌尔都语和其他语言中是“在一起”的意思。
|
||||
|
||||
### Mozilla
|
||||
|
||||
[Mozilla][27] 是一个成立于 1998 年的开源软件社区。根据其网站,“Mozilla 项目创建于 1998 年,发布了 Netscape 浏览器套件源代码。其旨在利用互联网上成千上万的程序员的创造力,并推动浏览器市场上前所未有的创新水平。” 这个名字是 [Mosaic] [28] 和 Godzilla 的混成词。
|
||||
|
||||
### Nginx
|
||||
|
||||
“许多技术人员都试图装酷,并将它念成‘n’‘g’‘n’‘x’。实际上,很少的一些人做点基本的调查工作,就可以很快发现该名称实际上应该被念成是“EngineX”,指的是功能强大的 web 服务器,像个引擎。”——Jean Sebastien Tougne
|
||||
|
||||
### Perl
|
||||
|
||||
Perl 的创始人 Larry Wall 最初将他的项目命名为“Pearl”。根据维基百科,Wall 想给这种语言起一个有积极含义的简短名字。在 Perl 正式发布之前,Wall 发现了已有 [PEARL][29] 编程语言,于是更改了名称的拼写。
|
||||
|
||||
### Piet 和 Mondrian
|
||||
|
||||
“有两种编程语言以艺术家 Piet Mondrian 命名。一种叫做‘Piet’,另一种叫做‘Mondrian’。(David Morgan-Mar [写道][30]):‘Piet 是一种编程语言,其中的程序看起来像抽象绘画。该语言以几何抽象艺术的开创者 Piet Mondrian 的名字命名。我曾想将这种语言命名为 Mondrian,但是有人告诉我这会让它看起来像一种很普通的脚本语言。哦,好吧,我想我们不能都是深奥的语言作家。’”——Yuval Lifshitz
|
||||
|
||||
### Python
|
||||
|
||||
Python 编程语言的独特名称来自其创建者 Guido Van Rossum,他是英国六人喜剧团体 Monty Python 的粉丝。
|
||||
|
||||
### Raspberry Pi
|
||||
|
||||
Raspberry Pi 以其微小但强大的功能和对低廉的价格而闻名,在开源社区中是最受欢迎的。但是它可爱(和好吃)的名字是从哪里来的呢?在 70 年代和 80 年代,以水果命名的计算机是一种流行的趋势。苹果、橘子、杏……有人饿了吗?根据创始人 Eben Upton 的 [2012 采访] [31],“<ruby>树莓派<rt>Raspberry Pi</rt></ruby>”这个名称是对这种趋势的致敬。树莓也很小,但却很有味道。名称中的“Pi”暗示着这样的事实:最初,该计算机只能运行 Python。
|
||||
|
||||
### Samba
|
||||
|
||||
[Server Message Block][32] 用于在 Linux 上共享 Windows 文件。
|
||||
|
||||
### ScummVM
|
||||
|
||||
[ScummVM][33](《疯狂大楼》虚拟机的脚本创建实用程序)是一个程序,可以在现代计算机上运行一些经典的计算机冒险游戏。最初,它旨在玩用 SCUMM 构建的 LucasArts 的冒险游戏,该游戏最初用于开发《疯狂大楼》,后来又被用来开发 LucasArts 的其它大多数冒险游戏。目前,ScummVM 支持大量游戏引擎,包括 Sierra Online 的 AGI 和 SCI,但仍保留着名称 ScummVM。
|
||||
|
||||
有一个相关的项目 [ResidualVM][34] 之所以得名,是因为它涵盖了 ScummVM 未涵盖的“<ruby>剩余的<rt>residual</rt></ruby>” LucasArts 冒险游戏。 ResidualVM 涵盖的 LucasArts 游戏是使用 GrimE(Grim Engine)开发的,该引擎最初用于开发 Grim Fandango,因此 ResidualVM 的名称是双关语。
|
||||
|
||||
### SQL
|
||||
|
||||
“你可能知道 SQL 代表<ruby>结构化查询语言<rt>Structured Query Language</rt></ruby>,但你知道为什么它经常被读作‘sequel’吗?它是作为原本的‘QUEL’(<ruby>查询语言<rt>QUEry Language</rt></ruby>)的后续(如<ruby>结局<rt>sequel</rt></ruby>)而创建的。”——Ken Gaillot
|
||||
|
||||
### XFCE
|
||||
|
||||
[XFCE][35] 是由 [Olivier Fourdan][36] 创建的一个流行的桌面。它在 1996 年作为 CDE 的替代品出现,最初是 <ruby>XForms 公共环境<rt>XForms Common Environment</rt></ruby>的缩写。
|
||||
|
||||
### Zsh
|
||||
|
||||
Zsh 是一个交互式登录 shell。1990 年,普林斯顿大学的学生 Paul Falstad 写了该 shell 的第一个版本。他在看到当时在普林斯顿大学担任助教的 Zhong Sha 的登录 ID(zsh)后,觉得这个名字听起来像 [shell 的好名字][37],给它起了这个名字。
|
||||
|
||||
还有更多的项目和名称还没有包括在这个列表中。请一定要在评论中分享你的收藏。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/19/10/open-source-name-origins
|
||||
|
||||
作者:[Joshua Allen Holm][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[laingke](https://github.com/laingke)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/holmja
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/rh_003784_02_os.comcareers_resume_rh1x.png?itok=S3HGxi6E (A person writing.)
|
||||
[2]: https://httpd.apache.org/
|
||||
[3]: https://enarx.io
|
||||
[4]: https://www.gimp.org/
|
||||
[5]: https://en.wikipedia.org/wiki/GIMP
|
||||
[6]: https://en.wikipedia.org/wiki/Spencer_Kimball_(computer_programmer)
|
||||
[7]: https://en.wikipedia.org/wiki/Peter_Mattis
|
||||
[8]: https://en.wikipedia.org/wiki/GNOME
|
||||
[9]: https://www.gnome.org/gnome-3/
|
||||
[10]: https://www.javaworld.com/article/2077265/so-why-did-they-decide-to-call-it-java-.html
|
||||
[11]: https://jupyter.org/
|
||||
[12]: https://julialang.org/
|
||||
[13]: https://www.python.org/
|
||||
[14]: https://www.r-project.org/
|
||||
[15]: https://news.ycombinator.com/item?id=9653797
|
||||
[16]: https://en.wikipedia.org/wiki/Matthias_Ettrich
|
||||
[17]: https://en.wikipedia.org/wiki/KDE
|
||||
[18]: https://sourceforge.net/projects/cdesktopenv/
|
||||
[19]: https://en.wikipedia.org/wiki/Linux
|
||||
[20]: https://www.centos.org/
|
||||
[21]: https://www.debian.org/
|
||||
[22]: https://www.redhat.com/en/technologies/linux-platforms/enterprise-linux
|
||||
[23]: https://getfedora.org/
|
||||
[24]: https://ubuntu.com/about
|
||||
[25]: https://moodle.org/
|
||||
[26]: https://en.wikipedia.org/wiki/Joomla#Historical_background
|
||||
[27]: https://www.mozilla.org/en-US/
|
||||
[28]: https://en.wikipedia.org/wiki/Mosaic_(web_browser)
|
||||
[29]: https://en.wikipedia.org/wiki/PEARL_(programming_language)
|
||||
[30]: http://www.dangermouse.net/esoteric/piet.html
|
||||
[31]: https://www.techspot.com/article/531-eben-upton-interview/
|
||||
[32]: https://www.samba.org/
|
||||
[33]: https://www.scummvm.org/
|
||||
[34]: https://www.residualvm.org/
|
||||
[35]: https://www.xfce.org/
|
||||
[36]: https://en.wikipedia.org/wiki/Olivier_Fourdan
|
||||
[37]: http://www.zsh.org/mla/users/2005/msg00951.html
|
118
published/20191017 Using multitail on Linux.md
Normal file
118
published/20191017 Using multitail on Linux.md
Normal file
@ -0,0 +1,118 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: 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/)
|
||||
|
||||
在 Linux 上使用 Multitail
|
||||
======
|
||||
|
||||

|
||||
|
||||
当你想同时查看多个文件(尤其是日志文件)的活动时,`multitail` 命令会非常有用。它的工作方式类似于多窗口形式的 `tail -f` 命令。也就是说,它显示这些文件的底部和添加的新行。虽然通常使用简单,但是 `multitail` 提供了一些命令行和交互式选项,在开始使用它之前,你应该了解它们。
|
||||
|
||||
### 基本 multitail 使用
|
||||
|
||||
`multitail` 的最简单用法是在命令行中列出你要查看的文件名称。此命令水平分割屏幕(即顶部和底部),并显示每个文件的底部以及更新。
|
||||
|
||||
```
|
||||
$ multitail /var/log/syslog /var/log/dmesg
|
||||
```
|
||||
|
||||
显示内容将像这样拆分:
|
||||
|
||||
```
|
||||
+-----------------------+
|
||||
| |
|
||||
| |
|
||||
+-----------------------|
|
||||
| |
|
||||
| |
|
||||
+-----------------------+
|
||||
```
|
||||
|
||||
每个文件都有一行显示该文件的文件编号(从 00 开始)、文件名、文件大小、最新内容的添加日期和时间。每个文件将被分配一半空间,而不论它的大小和活动情况。比如:
|
||||
|
||||
```
|
||||
content lines from my1.log
|
||||
more content
|
||||
more lines
|
||||
|
||||
00] my1.log 59KB - 2019/10/14 12:12:09
|
||||
content lines from my2.log
|
||||
more content
|
||||
more lines
|
||||
|
||||
01] my2.log 120KB - 2019/10/14 14:22:29
|
||||
```
|
||||
|
||||
请注意,如果你要求 `multitail` 显示非文本文件或者你无权查看的文件,它不会报错。你只是看不到内容。
|
||||
|
||||
你还可以使用通配符指定要查看的文件:
|
||||
|
||||
```
|
||||
$ multitail my*.log
|
||||
```
|
||||
|
||||
要记住的一件事是,`multitail` 将平均分割屏幕。如果指定的文件太多,那么除非你采取额外的步骤查看之后的文件(参考下面的滚动选项),否则你将只会看到前面 7 个文件的前面几行。确切的结果取决于终端窗口中有多少行可用。
|
||||
|
||||
按 `q` 退出 `multitail` 并返回到正常的屏幕视图。
|
||||
|
||||
### 分割屏幕
|
||||
|
||||
如果你愿意,`multitail` 也可以垂直分割你的终端窗口(即,左和右)。为此,请使用 `-s` 选项。如果指定了三个文件,那么屏幕右侧的窗口将会水平分隔。四个文件的话,你将拥有四个大小相等的窗口。
|
||||
|
||||
```
|
||||
+-----------+-----------+ +-----------+-----------+ +-----------+-----------+
|
||||
| | | | | | | | |
|
||||
| | | | | | | | |
|
||||
| | | | +-----------+ +-----------+-----------+
|
||||
| | | | | | | | |
|
||||
| | | | | | | | |
|
||||
+-----------+-----------+ +-----------+-----------+ +-----------+-----------+
|
||||
2 个文件 3 个文件 4 个文件
|
||||
```
|
||||
|
||||
如果要将屏幕分为三列,请使用 `multitail -s 3 file1 file2 file3`。
|
||||
|
||||
```
|
||||
+-------+-------+-------+
|
||||
| | | |
|
||||
| | | |
|
||||
| | | |
|
||||
| | | |
|
||||
| | | |
|
||||
+-------+-------+-------+
|
||||
3 个文件带上 -s 3 选项
|
||||
```
|
||||
|
||||
### 滚动
|
||||
|
||||
你可以上下滚动文件,但是需要按下 `b` 弹出选择菜单,然后使用向上和向下箭头按钮选择要滚动浏览的文件。然后按下回车键。然后,你可以再次使用向上和向下箭头在放大的区域中滚动浏览各行。完成后按下 `q` 返回正常视图。
|
||||
|
||||
### 获得帮助
|
||||
|
||||
在 `multitail` 中按下 `h` 将打开一个帮助菜单,其中描述了一些基本操作,但是手册页提供了更多信息,如果莫想了解更多有关使用此工具的信息,请仔细阅读。
|
||||
|
||||
默认情况下,你的系统上不会安装 `multitail`,但是使用 `apt-get` 或 `yum` 可以使你轻松安装。该工具提供了许多功能,不过它是基于字符显示的,窗口边框只是 `q` 和 `x` 的字符串组成的。当你需要关注文件更新时,它非常方便。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.networkworld.com/article/3445228/using-multitail-on-linux.html
|
||||
|
||||
作者:[Sandra Henry-Stocker][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://www.networkworld.com/author/Sandra-Henry_Stocker/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://www.flickr.com/photos/glenbowman/7992498919/in/photolist-dbgDtv-gHfRRz-5uRM4v-gHgFnz-6sPqTZ-5uaP7H-USFPqD-pbtRUe-fiKiYn-nmgWL2-pQNepR-q68p8d-dDsUxw-dbgFKG-nmgE6m-DHyqM-nCKA4L-2d7uFqH-Kbqzk-8EwKg-8Vy72g-2X3NSN-78Bv84-buKWXF-aeM4ok-yhweWf-4vwpyX-9hu8nq-9zCoti-v5nzP5-23fL48r-24y6pGS-JhWDof-6zF75k-24y6nHS-9hr19c-Gueh6G-Guei7u-GuegFy-24y6oX5-26qu5iX-wKrnMW-Gueikf-24y6oYh-27y4wwA-x4z19F-x57yP4-24BY6gc-24y6nPo-QGwbkf
|
||||
[2]: https://creativecommons.org/licenses/by-sa/2.0/legalcode
|
||||
[5]: https://www.facebook.com/NetworkWorld/
|
||||
[6]: https://www.linkedin.com/company/network-world
|
@ -0,0 +1,245 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (wxy)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11669-1.html)
|
||||
[#]: subject: (14 SCP Command Examples to Securely Transfer Files in Linux)
|
||||
[#]: via: (https://www.linuxtechi.com/scp-command-examples-in-linux/)
|
||||
[#]: author: (Pradeep Kumar https://www.linuxtechi.com/author/pradeep/)
|
||||
|
||||
在 Linux 上安全传输文件的 14 SCP 命令示例
|
||||
======
|
||||
|
||||

|
||||
|
||||
SCP(<ruby>安全复制<rt>Secure Copy</rt></ruby>)是 Linux 和 Unix 之类的系统中的命令行工具,用于通过网络安全地跨系统传输文件和目录。当我们使用 `scp` 命令将文件和目录从本地系统复制到远程系统时,则在后端与远程系统建立了 ssh 连接。换句话说,我们可以说 `scp` 在后端使用了相同的 SSH 安全机制,它需要密码或密钥进行身份验证。
|
||||
|
||||
![scp-command-examples-linux][2]
|
||||
|
||||
在本教程中,我们将讨论 14 个有用的 Linux `scp` 命令示例。
|
||||
|
||||
`scp` 命令语法:
|
||||
|
||||
```
|
||||
# scp <选项> <文件或目录> 用户名@目标主机:/<文件夹>
|
||||
|
||||
# scp <选项> 用户名@目标主机:/文件 <本地文件夹>
|
||||
```
|
||||
|
||||
`scp` 命令的第一个语法演示了如何将文件或目录从本地系统复制到特定文件夹下的目标主机。
|
||||
|
||||
`scp` 命令的第二种语法演示了如何将目标主机中的文件复制到本地系统中。
|
||||
|
||||
下面列出了 `scp` 命令中使用最广泛的一些选项,
|
||||
|
||||
* `-C` 启用压缩
|
||||
* `-i` 指定识别文件或私钥
|
||||
* `-l` 复制时限制带宽
|
||||
* `-P` 指定目标主机的 ssh 端口号
|
||||
* `-p` 复制时保留文件的权限、模式和访问时间
|
||||
* `-q` 禁止 SSH 警告消息
|
||||
* `-r` 递归复制文件和目录
|
||||
* `-v` 详细输出
|
||||
|
||||
现在让我们跳入示例!
|
||||
|
||||
### 示例:1)使用 scp 将文件从本地系统复制到远程系统
|
||||
|
||||
假设我们要使用 `scp` 命令将 jdk 的 rpm 软件包从本地 Linux 系统复制到远程系统(172.20.10.8),请使用以下命令,
|
||||
|
||||
```
|
||||
[root@linuxtechi ~]$ scp jdk-linux-x64_bin.rpm root@linuxtechi:/opt
|
||||
root@linuxtechi's password:
|
||||
jdk-linux-x64_bin.rpm 100% 10MB 27.1MB/s 00:00
|
||||
[root@linuxtechi ~]$
|
||||
```
|
||||
|
||||
上面的命令会将 jdk 的 rpm 软件包文件复制到 `/opt` 文件夹下的远程系统。
|
||||
|
||||
### 示例:2)使用 scp 将文件从远程系统复制到本地系统
|
||||
|
||||
假设我们想将文件从远程系统复制到本地系统下的 `/tmp` 文件夹,执行以下 `scp` 命令,
|
||||
|
||||
```
|
||||
[root@linuxtechi ~]$ scp root@linuxtechi:/root/Technical-Doc-RHS.odt /tmp
|
||||
root@linuxtechi's password:
|
||||
Technical-Doc-RHS.odt 100% 1109KB 31.8MB/s 00:00
|
||||
[root@linuxtechi ~]$ ls -l /tmp/Technical-Doc-RHS.odt
|
||||
-rwx------. 1 pkumar pkumar 1135521 Oct 19 11:12 /tmp/Technical-Doc-RHS.odt
|
||||
[root@linuxtechi ~]$
|
||||
```
|
||||
|
||||
### 示例:3)使用 scp 传输文件时的详细输出(-v)
|
||||
|
||||
在 `scp` 命令中,我们可以使用 `-v` 选项启用详细输出。使用详细输出,我们可以轻松地发现后台确切发生了什么。这对于调试连接、认证和配置等问题非常有用。
|
||||
|
||||
```
|
||||
root@linuxtechi ~]$ scp -v jdk-linux-x64_bin.rpm root@linuxtechi:/opt
|
||||
Executing: program /usr/bin/ssh host 172.20.10.8, user root, command scp -v -t /opt
|
||||
OpenSSH_7.8p1, OpenSSL 1.1.1 FIPS 11 Sep 2018
|
||||
debug1: Reading configuration data /etc/ssh/ssh_config
|
||||
debug1: Reading configuration data /etc/ssh/ssh_config.d/05-redhat.conf
|
||||
debug1: Reading configuration data /etc/crypto-policies/back-ends/openssh.config
|
||||
debug1: /etc/ssh/ssh_config.d/05-redhat.conf line 8: Applying options for *
|
||||
debug1: Connecting to 172.20.10.8 [172.20.10.8] port 22.
|
||||
debug1: Connection established.
|
||||
…………
|
||||
debug1: Next authentication method: password
|
||||
root@linuxtechi's password:
|
||||
```
|
||||
|
||||
### 示例:4)将多个文件传输到远程系统
|
||||
|
||||
可以使用 `scp` 命令一次性将多个文件复制/传输到远程系统,在 `scp` 命令中指定多个文件,并用空格隔开,示例如下所示
|
||||
|
||||
```
|
||||
[root@linuxtechi ~]$ scp install.txt index.html jdk-linux-x64_bin.rpm root@linuxtechi:/mnt
|
||||
root@linuxtechi's password:
|
||||
install.txt 100% 0 0.0KB/s 00:00
|
||||
index.html 100% 85KB 7.2MB/s 00:00
|
||||
jdk-linux-x64_bin.rpm 100% 10MB 25.3MB/s 00:00
|
||||
[root@linuxtechi ~]$
|
||||
```
|
||||
|
||||
### 示例:5)在两个远程主机之间传输文件
|
||||
|
||||
使用 `scp` 命令,我们可以在两个远程主机之间复制文件和目录,假设我们有一个可以连接到两个远程 Linux 系统的本地 Linux 系统,因此从我的本地 Linux 系统中,我可以使用 `scp` 命令在这两个系统之间复制文件,
|
||||
|
||||
命令语法:
|
||||
|
||||
```
|
||||
# scp 用户名@远程主机1:/<要传输的文件> 用户名@远程主机2:/<文件夹>
|
||||
```
|
||||
|
||||
示例如下:
|
||||
|
||||
```
|
||||
# scp root@linuxtechi:~/backup-Oct.zip root@linuxtechi:/tmp
|
||||
# ssh root@linuxtechi "ls -l /tmp/backup-Oct.zip"
|
||||
-rwx------. 1 root root 747438080 Oct 19 12:02 /tmp/backup-Oct.zip
|
||||
```
|
||||
|
||||
### 示例:6)递归复制文件和目录(-r)
|
||||
|
||||
在 `scp` 命令中使用 `-r` 选项将整个目录从一个系统递归地复制到另一个系统,示例如下所示:
|
||||
|
||||
```
|
||||
[root@linuxtechi ~]$ scp -r Downloads root@linuxtechi:/opt
|
||||
```
|
||||
|
||||
使用以下命令验证 `Downloads` 文件夹是否已复制到远程系统,
|
||||
|
||||
```
|
||||
[root@linuxtechi ~]$ ssh root@linuxtechi "ls -ld /opt/Downloads"
|
||||
drwxr-xr-x. 2 root root 75 Oct 19 12:10 /opt/Downloads
|
||||
[root@linuxtechi ~]$
|
||||
```
|
||||
|
||||
### 示例:7)通过启用压缩来提高传输速度(-C)
|
||||
|
||||
在 `scp` 命令中,我们可以通过使用 `-C` 选项启用压缩来提高传输速度,它将自动在源主机上启用压缩并在目标主机上解压缩。
|
||||
|
||||
```
|
||||
root@linuxtechi ~]$ scp -r -C Downloads root@linuxtechi:/mnt
|
||||
```
|
||||
|
||||
在以上示例中,我们正在启用压缩的情况下传输下载目录。
|
||||
|
||||
### 示例:8)复制时限制带宽(-l)
|
||||
|
||||
在 `scp` 命令中使用 `-l` 选项设置复制时对带宽使用的限制。带宽以 Kbit/s 为单位指定,示例如下所示:
|
||||
|
||||
```
|
||||
[root@linuxtechi ~]$ scp -l 500 jdk-linux-x64_bin.rpm root@linuxtechi:/var
|
||||
```
|
||||
|
||||
### 示例:9)在 scp 时指定其他 ssh 端口(-P)
|
||||
|
||||
在某些情况下,目标主机上的 ssh 端口会更改,因此在使用 `scp` 命令时,我们可以使用 `-P` 选项指定 ssh 端口号。
|
||||
|
||||
```
|
||||
[root@linuxtechi ~]$ scp -P 2022 jdk-linux-x64_bin.rpm root@linuxtechi:/var
|
||||
```
|
||||
|
||||
在上面的示例中,远程主机的 ssh 端口为 “2022”。
|
||||
|
||||
### 示例:10)复制时保留文件的权限、模式和访问时间(-p)
|
||||
|
||||
从源复制到目标时,在 `scp` 命令中使用 `-p` 选项保留权限、访问时间和模式。
|
||||
|
||||
```
|
||||
[root@linuxtechi ~]$ scp -p jdk-linux-x64_bin.rpm root@linuxtechi:/var/tmp
|
||||
jdk-linux-x64_bin.rpm 100% 10MB 13.5MB/s 00:00
|
||||
[root@linuxtechi ~]$
|
||||
```
|
||||
|
||||
### 示例:11)在 scp 中以安静模式传输文件(-q)
|
||||
|
||||
在 `scp` 命令中使用 `-q` 选项可禁止显示 ssh 的传输进度、警告和诊断消息。示例如下所示:
|
||||
|
||||
```
|
||||
[root@linuxtechi ~]$ scp -q -r Downloads root@linuxtechi:/var/tmp
|
||||
[root@linuxtechi ~]$
|
||||
```
|
||||
|
||||
### 示例:12)在传输时使用 scp 中的识别文件(-i)
|
||||
|
||||
在大多数 Linux 环境中,首选基于密钥的身份验证。在 `scp` 命令中,我们使用 `-i` 选项指定识别文件(私钥文件),示例如下所示:
|
||||
|
||||
```
|
||||
[root@linuxtechi ~]$ scp -i my_key.pem -r Downloads root@linuxtechi:/root
|
||||
```
|
||||
|
||||
在上面的示例中,`my_key.pem` 是识别文件或私钥文件。
|
||||
|
||||
### 示例:13)在 scp 中使用其他 ssh_config 文件(-F)
|
||||
|
||||
在某些情况下,你使用不同的网络连接到 Linux 系统,可能某些网络位于代理服务器后面,因此在这种情况下,我们必须具有不同的 `ssh_config` 文件。
|
||||
|
||||
通过 `-F` 选项在 `scp` 命令中指定了不同的 `ssh_config` 文件,示例如下所示:
|
||||
|
||||
```
|
||||
[root@linuxtechi ~]$ scp -F /home/pkumar/new_ssh_config -r Downloads root@linuxtechi:/root
|
||||
root@linuxtechi's password:
|
||||
jdk-linux-x64_bin.rpm 100% 10MB 16.6MB/s 00:00
|
||||
backup-Oct.zip 100% 713MB 41.9MB/s 00:17
|
||||
index.html 100% 85KB 6.6MB/s 00:00
|
||||
[root@linuxtechi ~]$
|
||||
```
|
||||
|
||||
### 示例:14)在 scp 命令中使用其他加密方式(-c)
|
||||
|
||||
默认情况下,`scp` 使用 AES-128 加密方式来加密文件。如果你想在 `scp` 命令中使用其他加密方式,请使用 `-c` 选项,后接加密方式名称。
|
||||
|
||||
假设我们要在用 `scp` 命令传输文件时使用 3des-cbc 加密方式,请运行以下 `scp` 命令:
|
||||
|
||||
```
|
||||
[root@linuxtechi ~]# scp -c 3des-cbc -r Downloads root@linuxtechi:/root
|
||||
```
|
||||
|
||||
使用以下命令列出 `ssh` 和 `scp` 支持的加密方式:
|
||||
|
||||
```
|
||||
[root@linuxtechi ~]# ssh -Q cipher localhost | paste -d , -s -
|
||||
3des-cbc,aes128-cbc,aes192-cbc,aes256-cbc,root@linuxtechi,aes128-ctr,aes192-ctr,aes256-ctr,root@linuxtechi,root@linuxtechi,root@linuxtechi
|
||||
[root@linuxtechi ~]#
|
||||
```
|
||||
|
||||
以上就是本教程的全部内容,要获取有关 `scp` 命令的更多详细信息,请参考其手册页。请在下面的评论部分中分享你的反馈和评论。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.linuxtechi.com/scp-command-examples-in-linux/
|
||||
|
||||
作者:[Pradeep Kumar][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[wxy](https://github.com/wxy)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://www.linuxtechi.com/author/pradeep/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7
|
||||
[2]: https://www.linuxtechi.com/wp-content/uploads/2019/10/scp-command-examples-linux.jpg
|
||||
[3]: https://www.linuxtechi.com/cdn-cgi/l/email-protection
|
@ -0,0 +1,467 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (lxbwolf)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11687-1.html)
|
||||
[#]: subject: (How to program with Bash: Logical operators and shell expansions)
|
||||
[#]: via: (https://opensource.com/article/19/10/programming-bash-logical-operators-shell-expansions)
|
||||
[#]: author: (David Both https://opensource.com/users/dboth)
|
||||
|
||||
怎样用 Bash 编程:逻辑操作符和 shell 扩展
|
||||
======
|
||||
|
||||
> 学习逻辑操作符和 shell 扩展,本文是三篇 Bash 编程系列的第二篇。
|
||||
|
||||

|
||||
|
||||
Bash 是一种强大的编程语言,完美契合命令行和 shell 脚本。本系列(三篇文章,基于我的 [三集 Linux 自学课程][2])讲解如何在 CLI 使用 Bash 编程。
|
||||
|
||||
[第一篇文章][3] 讲解了 Bash 的一些简单命令行操作,包括如何使用变量和控制操作符。第二篇文章探讨文件、字符串、数字等类型和各种各样在执行流中提供控制逻辑的的逻辑运算符,还有 Bash 中的各类 shell 扩展。本系列第三篇也是最后一篇文章,将会探索能重复执行操作的 `for` 、`while` 和 `until` 循环。
|
||||
|
||||
逻辑操作符是程序中进行判断的根本要素,也是执行不同的语句组合的依据。有时这也被称为流控制。
|
||||
|
||||
### 逻辑操作符
|
||||
|
||||
Bash 中有大量的用于不同条件表达式的逻辑操作符。最基本的是 `if` 控制结构,它判断一个条件,如果条件为真,就执行一些程序语句。操作符共有三类:文件、数字和非数字操作符。如果条件为真,所有的操作符返回真值(`0`),如果条件为假,返回假值(`1`)。
|
||||
|
||||
这些比较操作符的函数语法是,一个操作符加一个或两个参数放在中括号内,后面跟一系列程序语句,如果条件为真,程序语句执行,可能会有另一个程序语句列表,该列表在条件为假时执行:
|
||||
|
||||
|
||||
```
|
||||
if [ arg1 operator arg2 ] ; then list
|
||||
或
|
||||
if [ arg1 operator arg2 ] ; then list ; else list ; fi
|
||||
```
|
||||
|
||||
像例子中那样,在比较表达式中,空格不能省略。中括号的每部分,`[` 和 `]`,是跟 `test` 命令一样的传统的 Bash 符号:
|
||||
|
||||
```
|
||||
if test arg1 operator arg2 ; then list
|
||||
```
|
||||
|
||||
还有一个更新的语法能提供一点点便利,一些系统管理员比较喜欢用。这种格式对于不同版本的 Bash 和一些 shell 如 ksh(Korn shell)兼容性稍差。格式如下:
|
||||
|
||||
```
|
||||
if [[ arg1 operator arg2 ]] ; then list
|
||||
```
|
||||
|
||||
#### 文件操作符
|
||||
|
||||
文件操作符是 Bash 中一系列强大的逻辑操作符。图表 1 列出了 20 多种不同的 Bash 处理文件的操作符。在我的脚本中使用频率很高。
|
||||
|
||||
操作符 | 描述
|
||||
---|---
|
||||
`-a filename` | 如果文件存在,返回真值;文件可以为空也可以有内容,但是只要它存在,就返回真值
|
||||
`-b filename` | 如果文件存在且是一个块设备,如 `/dev/sda` 或 `/dev/sda1`,则返回真值
|
||||
`-c filename` | 如果文件存在且是一个字符设备,如 `/dev/TTY1`,则返回真值
|
||||
`-d filename` | 如果文件存在且是一个目录,返回真值
|
||||
`-e filename` | 如果文件存在,返回真值;与上面的 `-a` 相同
|
||||
`-f filename` | 如果文件存在且是一个一般文件,不是目录、设备文件或链接等的其他的文件,则返回 真值
|
||||
`-g filename` | 如果文件存在且 `SETGID` 标记被设置在其上,返回真值
|
||||
`-h filename` | 如果文件存在且是一个符号链接,则返回真值
|
||||
`-k filename` | 如果文件存在且粘滞位已设置,则返回真值
|
||||
`-p filename` | 如果文件存在且是一个命名的管道(FIFO),返回真值
|
||||
`-r filename` | 如果文件存在且有可读权限(它的可读位被设置),返回真值
|
||||
`-s filename` | 如果文件存在且大小大于 0,返回真值;如果一个文件存在但大小为 0,则返回假值
|
||||
`-t fd` | 如果文件描述符 `fd` 被打开且被关联到一个终端设备上,返回真值
|
||||
`-u filename` | 如果文件存在且它的 `SETUID` 位被设置,返回真值
|
||||
`-w filename` | 如果文件存在且有可写权限,返回真值
|
||||
`-x filename` | 如果文件存在且有可执行权限,返回真值
|
||||
`-G filename` | 如果文件存在且文件的组 ID 与当前用户相同,返回真值
|
||||
`-L filename` | 如果文件存在且是一个符号链接,返回真值(同 `-h`)
|
||||
`-N filename` | 如果文件存在且从文件上一次被读取后文件被修改过,返回真值
|
||||
`-O filename` | 如果文件存在且你是文件的拥有者,返回真值
|
||||
`-S filename` | 如果文件存在且文件是套接字,返回真值
|
||||
`file1 -ef file2` | 如果文件 `file1` 和文件 `file2` 指向同一设备的同一 INODE 号,返回真值(即硬链接)
|
||||
`file1 -nt file2` | 如果文件 `file1` 比 `file2` 新(根据修改日期),或 `file1` 存在而 `file2` 不存在,返回真值
|
||||
`file1 -ot file2` | 如果文件 `file1` 比 `file2` 旧(根据修改日期),或 `file1` 不存在而 `file2` 存在
|
||||
|
||||
*图表 1:Bash 文件操作符*
|
||||
|
||||
以测试一个文件存在与否来举例:
|
||||
|
||||
```
|
||||
[student@studentvm1 testdir]$ File="TestFile1" ; if [ -e $File ] ; then echo "The file $File exists." ; else echo "The file $File does not exist." ; fi
|
||||
The file TestFile1 does not exist.
|
||||
[student@studentvm1 testdir]$
|
||||
```
|
||||
|
||||
创建一个用来测试的文件,命名为 `TestFile1`。目前它不需要包含任何数据:
|
||||
|
||||
```
|
||||
[student@studentvm1 testdir]$ touch TestFile1
|
||||
```
|
||||
|
||||
在这个简短的 CLI 程序中,修改 `$File` 变量的值相比于在多个地方修改表示文件名的字符串的值要容易:
|
||||
|
||||
```
|
||||
[student@studentvm1 testdir]$ File="TestFile1" ; if [ -e $File ] ; then echo "The file $File exists." ; else echo "The file $File does not exist." ; fi
|
||||
The file TestFile1 exists.
|
||||
[student@studentvm1 testdir]$
|
||||
```
|
||||
|
||||
现在,运行一个测试来判断一个文件是否存在且长度不为 0(表示它包含数据)。假设你想判断三种情况:
|
||||
|
||||
1. 文件不存在;
|
||||
2. 文件存在且为空;
|
||||
3. 文件存在且包含数据。
|
||||
|
||||
因此,你需要一组更复杂的测试代码 — 为了测试所有的情况,使用 `if-elif-else` 结构中的 `elif` 语句:
|
||||
|
||||
```
|
||||
[student@studentvm1 testdir]$ File="TestFile1" ; if [ -s $File ] ; then echo "$File exists and contains data." ; fi
|
||||
[student@studentvm1 testdir]$
|
||||
```
|
||||
|
||||
在这个情况中,文件存在但不包含任何数据。向文件添加一些数据再运行一次:
|
||||
|
||||
```
|
||||
[student@studentvm1 testdir]$ File="TestFile1" ; echo "This is file $File" > $File ; if [ -s $File ] ; then echo "$File exists and contains data." ; fi
|
||||
TestFile1 exists and contains data.
|
||||
[student@studentvm1 testdir]$
|
||||
```
|
||||
|
||||
这组语句能返回正常的结果,但是仅仅是在我们已知三种可能的情况下测试某种确切的条件。添加一段 `else` 语句,这样你就可以更精确地测试。把文件删掉,你就可以完整地测试这段新代码:
|
||||
|
||||
```
|
||||
[student@studentvm1 testdir]$ File="TestFile1" ; rm $File ; if [ -s $File ] ; then echo "$File exists and contains data." ; else echo "$File does not exist or is empty." ; fi
|
||||
TestFile1 does not exist or is empty.
|
||||
```
|
||||
|
||||
现在创建一个空文件用来测试:
|
||||
|
||||
```
|
||||
[student@studentvm1 testdir]$ File="TestFile1" ; touch $File ; if [ -s $File ] ; then echo "$File exists and contains data." ; else echo "$File does not exist or is empty." ; fi
|
||||
TestFile1 does not exist or is empty.
|
||||
```
|
||||
|
||||
向文件添加一些内容,然后再测试一次:
|
||||
|
||||
```
|
||||
[student@studentvm1 testdir]$ File="TestFile1" ; echo "This is file $File" > $File ; if [ -s $File ] ; then echo "$File exists and contains data." ; else echo "$File does not exist or is empty." ; fi
|
||||
TestFile1 exists and contains data.
|
||||
```
|
||||
|
||||
现在加入 `elif` 语句来辨别是文件不存在还是文件为空:
|
||||
|
||||
```
|
||||
[student@studentvm1 testdir]$ File="TestFile1" ; touch $File ; if [ -s $File ] ; then echo "$File exists and contains data." ; elif [ -e $File ] ; then echo "$File exists and is empty." ; else echo "$File does not exist." ; fi
|
||||
TestFile1 exists and is empty.
|
||||
[student@studentvm1 testdir]$ File="TestFile1" ; echo "This is $File" > $File ; if [ -s $File ] ; then echo "$File exists and contains data." ; elif [ -e $File ] ; then echo "$File exists and is empty." ; else echo "$File does not exist." ; fi
|
||||
TestFile1 exists and contains data.
|
||||
[student@studentvm1 testdir]$
|
||||
```
|
||||
|
||||
现在你有一个可以测试这三种情况的 Bash CLI 程序,但是可能的情况是无限的。
|
||||
|
||||
如果你能像保存在文件中的脚本那样组织程序语句,那么即使对于更复杂的命令组合也会很容易看出它们的逻辑结构。图表 2 就是一个示例。 `if-elif-else` 结构中每一部分的程序语句的缩进让逻辑更变得清晰。
|
||||
|
||||
|
||||
```
|
||||
File="TestFile1"
|
||||
echo "This is $File" > $File
|
||||
if [ -s $File ]
|
||||
then
|
||||
echo "$File exists and contains data."
|
||||
elif [ -e $File ]
|
||||
then
|
||||
echo "$File exists and is empty."
|
||||
else
|
||||
echo "$File does not exist."
|
||||
fi
|
||||
```
|
||||
|
||||
*图表 2: 像在脚本里一样重写书写命令行程序*
|
||||
|
||||
对于大多数 CLI 程序来说,让这些复杂的命令变得有逻辑需要写很长的代码。虽然 CLI 可能是用 Linux 或 Bash 内置的命令,但是当 CLI 程序很长或很复杂时,创建一个保存在文件中的脚本将更有效,保存到文件中后,可以随时运行。
|
||||
|
||||
#### 字符串比较操作符
|
||||
|
||||
字符串比较操作符使我们可以对字符串中的字符按字母顺序进行比较。图表 3 列出了仅有的几个字符串比较操作符。
|
||||
|
||||
操作符 | 描述
|
||||
---|---
|
||||
`-z string` | 如果字符串的长度为 0 ,返回真值
|
||||
`-n string` |如果字符串的长度不为 0 ,返回真值
|
||||
`string1 == string2` 或 `string1 = string2` | 如果两个字符串相等,返回真值。处于遵从 POSIX 一致性,在测试命令中应使用一个等号 `=`。与命令 `[[` 一起使用时,会进行如上描述的模式匹配(混合命令)。
|
||||
`string1 != string2` | 两个字符串不相等,返回真值
|
||||
`string1 < string2` | 如果对 `string1` 和 `string2` 按字母顺序进行排序,`string1` 排在 `string2` 前面(即基于地区设定的对所有字母和特殊字符的排列顺序)
|
||||
`string1 > string2` | 如果对 `string1` 和 `string2` 按字母顺序进行排序,`string1` 排在 `string2` 后面
|
||||
|
||||
*图表 3: Bash 字符串逻辑操作符*
|
||||
|
||||
首先,检查字符串长度。比较表达式中 `$MyVar` 两边的双引号不能省略(你仍应该在目录 `~/testdir` 下 )。
|
||||
|
||||
```
|
||||
[student@studentvm1 testdir]$ MyVar="" ; if [ -z "" ] ; then echo "MyVar is zero length." ; else echo "MyVar contains data" ; fi
|
||||
MyVar is zero length.
|
||||
[student@studentvm1 testdir]$ MyVar="Random text" ; if [ -z "" ] ; then echo "MyVar is zero length." ; else echo "MyVar contains data" ; fi
|
||||
MyVar is zero length.
|
||||
```
|
||||
|
||||
你也可以这样做:
|
||||
|
||||
```
|
||||
[student@studentvm1 testdir]$ MyVar="Random text" ; if [ -n "$MyVar" ] ; then echo "MyVar contains data." ; else echo "MyVar is zero length" ; fi
|
||||
MyVar contains data.
|
||||
[student@studentvm1 testdir]$ MyVar="" ; if [ -n "$MyVar" ] ; then echo "MyVar contains data." ; else echo "MyVar is zero length" ; fi
|
||||
MyVar is zero length
|
||||
```
|
||||
|
||||
有时候你需要知道一个字符串确切的长度。这虽然不是比较,但是也与比较相关。不幸的是,计算字符串的长度没有简单的方法。有很多种方法可以计算,但是我认为使用 `expr`(求值表达式)命令是相对最简单的一种。阅读 `expr` 的手册页可以了解更多相关知识。注意表达式中你检测的字符串或变量两边的引号不要省略。
|
||||
|
||||
```
|
||||
[student@studentvm1 testdir]$ MyVar="" ; expr length "$MyVar"
|
||||
0
|
||||
[student@studentvm1 testdir]$ MyVar="How long is this?" ; expr length "$MyVar"
|
||||
17
|
||||
[student@studentvm1 testdir]$ expr length "We can also find the length of a literal string as well as a variable."
|
||||
70
|
||||
```
|
||||
|
||||
关于比较操作符,在我们的脚本中使用了大量的检测两个字符串是否相等(例如,两个字符串是否实际上是同一个字符串)的操作。我使用的是非 POSIX 版本的比较表达式:
|
||||
|
||||
```
|
||||
[student@studentvm1 testdir]$ Var1="Hello World" ; Var2="Hello World" ; if [ "$Var1" == "$Var2" ] ; then echo "Var1 matches Var2" ; else echo "Var1 and Var2 do not match." ; fi
|
||||
Var1 matches Var2
|
||||
[student@studentvm1 testdir]$ Var1="Hello World" ; Var2="Hello world" ; if [ "$Var1" == "$Var2" ] ; then echo "Var1 matches Var2" ; else echo "Var1 and Var2 do not match." ; fi
|
||||
Var1 and Var2 do not match.
|
||||
```
|
||||
|
||||
在你自己的脚本中去试一下这些操作符。
|
||||
|
||||
#### 数字比较操作符
|
||||
|
||||
数字操作符用于两个数字参数之间的比较。像其他类操作符一样,大部分都很容易理解。
|
||||
|
||||
操作符 | 描述
|
||||
---|---
|
||||
`arg1 -eq arg2` | 如果 `arg1` 等于 `arg2`,返回真值
|
||||
`arg1 -ne arg2` | 如果 `arg1` 不等于 `arg2`,返回真值
|
||||
`arg1 -lt arg2` | 如果 `arg1` 小于 `arg2`,返回真值
|
||||
`arg1 -le arg2` | 如果 `arg1` 小于或等于 `arg2`,返回真值
|
||||
`arg1 -gt arg2` | 如果 `arg1` 大于 `arg2`,返回真值
|
||||
`arg1 -ge arg2` | 如果 `arg1` 大于或等于 `arg2`,返回真值
|
||||
|
||||
*图表 4: Bash 数字比较逻辑操作符*
|
||||
|
||||
来看几个简单的例子。第一个示例设置变量 `$X` 的值为 1,然后检测 `$X` 是否等于 1。第二个示例中,`$X` 被设置为 0,所以比较表达式返回结果不为真值。
|
||||
|
||||
```
|
||||
[student@studentvm1 testdir]$ X=1 ; if [ $X -eq 1 ] ; then echo "X equals 1" ; else echo "X does not equal 1" ; fi
|
||||
X equals 1
|
||||
[student@studentvm1 testdir]$ X=0 ; if [ $X -eq 1 ] ; then echo "X equals 1" ; else echo "X does not equal 1" ; fi
|
||||
X does not equal 1
|
||||
[student@studentvm1 testdir]$
|
||||
```
|
||||
|
||||
自己来多尝试一下其他的。
|
||||
|
||||
#### 杂项操作符
|
||||
|
||||
这些杂项操作符展示一个 shell 选项是否被设置,或一个 shell 变量是否有值,但是它不显示变量的值,只显示它是否有值。
|
||||
|
||||
操作符 | 描述
|
||||
---|---
|
||||
`-o optname` | 如果一个 shell 选项 `optname` 是启用的(查看内建在 Bash 手册页中的 set `-o` 选项描述下面的选项列表),则返回真值
|
||||
`-v varname` | 如果 shell 变量 `varname` 被设置了值(被赋予了值),则返回真值
|
||||
`-R varname` | 如果一个 shell 变量 `varname` 被设置了值且是一个名字引用,则返回真值
|
||||
|
||||
*图表 5: 杂项 Bash 逻辑操作符*
|
||||
|
||||
自己来使用这些操作符实践下。
|
||||
|
||||
### 扩展
|
||||
|
||||
Bash 支持非常有用的几种类型的扩展和命令替换。根据 Bash 手册页,Bash 有七种扩展格式。本文只介绍其中五种:`~` 扩展、算术扩展、路径名称扩展、大括号扩展和命令替换。
|
||||
|
||||
#### 大括号扩展
|
||||
|
||||
大括号扩展是生成任意字符串的一种方法。(下面的例子是用特定模式的字符创建大量的文件。)大括号扩展可以用于产生任意字符串的列表,并把它们插入一个用静态字符串包围的特定位置或静态字符串的两端。这可能不太好想象,所以还是来实践一下。
|
||||
|
||||
首先,看一下大括号扩展的作用:
|
||||
|
||||
```
|
||||
[student@studentvm1 testdir]$ echo {string1,string2,string3}
|
||||
string1 string2 string3
|
||||
```
|
||||
|
||||
看起来不是很有用,对吧?但是用其他方式使用它,再来看看:
|
||||
|
||||
```
|
||||
[student@studentvm1 testdir]$ echo "Hello "{David,Jen,Rikki,Jason}.
|
||||
Hello David. Hello Jen. Hello Rikki. Hello Jason.
|
||||
```
|
||||
|
||||
这看起来貌似有点用了 — 我们可以少打很多字。现在试一下这个:
|
||||
|
||||
```
|
||||
[student@studentvm1 testdir]$ echo b{ed,olt,ar}s
|
||||
beds bolts bars
|
||||
```
|
||||
|
||||
我可以继续举例,但是你应该已经理解了它的用处。
|
||||
|
||||
#### ~ 扩展
|
||||
|
||||
资料显示,使用最多的扩展是波浪字符(`~`)扩展。当你在命令中使用它(如 `cd ~/Documents`)时,Bash shell 把这个快捷方式展开成用户的完整的家目录。
|
||||
|
||||
使用这个 Bash 程序观察 `~` 扩展的作用:
|
||||
|
||||
```
|
||||
[student@studentvm1 testdir]$ echo ~
|
||||
/home/student
|
||||
[student@studentvm1 testdir]$ echo ~/Documents
|
||||
/home/student/Documents
|
||||
[student@studentvm1 testdir]$ Var1=~/Documents ; echo $Var1 ; cd $Var1
|
||||
/home/student/Documents
|
||||
[student@studentvm1 Documents]$
|
||||
```
|
||||
|
||||
#### 路径名称扩展
|
||||
|
||||
路径名称扩展是展开文件通配模式为匹配该模式的完整路径名称的另一种说法,匹配字符使用 `?` 和 `*`。文件通配指的是在大量操作中匹配文件名、路径和其他字符串时用特定的模式字符产生极大的灵活性。这些特定的模式字符允许匹配字符串中的一个、多个或特定字符。
|
||||
|
||||
* `?` — 匹配字符串中特定位置的一个任意字符
|
||||
* `*` — 匹配字符串中特定位置的 0 个或多个任意字符
|
||||
|
||||
这个扩展用于匹配路径名称。为了弄清它的用法,请确保 `testdir` 是当前工作目录(`PWD`),先执行基本的列出清单命令 `ls`(我家目录下的内容跟你的不一样)。
|
||||
|
||||
```
|
||||
[student@studentvm1 testdir]$ ls
|
||||
chapter6 cpuHog.dos dmesg1.txt Documents Music softlink1 testdir6 Videos
|
||||
chapter7 cpuHog.Linux dmesg2.txt Downloads Pictures Templates testdir
|
||||
testdir cpuHog.mac dmesg3.txt file005 Public testdir tmp
|
||||
cpuHog Desktop dmesg.txt link3 random.txt testdir1 umask.test
|
||||
[student@studentvm1 testdir]$
|
||||
```
|
||||
|
||||
现在列出以 `Do`、`testdir/Documents` 和 `testdir/Downloads` 开头的目录:
|
||||
|
||||
```
|
||||
Documents:
|
||||
Directory01 file07 file15 test02 test10 test20 testfile13 TextFiles
|
||||
Directory02 file08 file16 test03 test11 testfile01 testfile14
|
||||
file01 file09 file17 test04 test12 testfile04 testfile15
|
||||
file02 file10 file18 test05 test13 testfile05 testfile16
|
||||
file03 file11 file19 test06 test14 testfile09 testfile17
|
||||
file04 file12 file20 test07 test15 testfile10 testfile18
|
||||
file05 file13 Student1.txt test08 test16 testfile11 testfile19
|
||||
file06 file14 test01 test09 test18 testfile12 testfile20
|
||||
|
||||
Downloads:
|
||||
[student@studentvm1 testdir]$
|
||||
```
|
||||
|
||||
然而,并没有得到你期望的结果。它列出了以 `Do` 开头的目录下的内容。使用 `-d` 选项,仅列出目录而不列出它们的内容。
|
||||
|
||||
```
|
||||
[student@studentvm1 testdir]$ ls -d Do*
|
||||
Documents Downloads
|
||||
[student@studentvm1 testdir]$
|
||||
```
|
||||
|
||||
在两个例子中,Bash shell 都把 `Do*` 模式展开成了匹配该模式的目录名称。但是如果有文件也匹配这个模式,会发生什么?
|
||||
|
||||
```
|
||||
[student@studentvm1 testdir]$ touch Downtown ; ls -d Do*
|
||||
Documents Downloads Downtown
|
||||
[student@studentvm1 testdir]$
|
||||
```
|
||||
|
||||
因此所有匹配这个模式的文件也被展开成了完整名字。
|
||||
|
||||
#### 命令替换
|
||||
|
||||
命令替换是让一个命令的标准输出数据流被当做参数传给另一个命令的扩展形式,例如,在一个循环中作为一系列被处理的项目。Bash 手册页显示:“命令替换可以让你用一个命令的输出替换为命令的名字。”这可能不太好理解。
|
||||
|
||||
命令替换有两种格式:\`command\` 和 `$(command)`。在更早的格式中使用反引号(\`),在命令中使用反斜杠(`\`)来保持它转义之前的文本含义。然而,当用在新版本的括号格式中时,反斜杠被当做一个特殊字符处理。也请注意带括号的格式打开个关闭命令语句都是用一个括号。
|
||||
|
||||
我经常在命令行程序和脚本中使用这种能力,一个命令的结果能被用作另一个命令的参数。
|
||||
|
||||
来看一个非常简单的示例,这个示例使用了这个扩展的两种格式(再一次提醒,确保 `testdir` 是当前工作目录):
|
||||
|
||||
```
|
||||
[student@studentvm1 testdir]$ echo "Todays date is `date`"
|
||||
Todays date is Sun Apr 7 14:42:46 EDT 2019
|
||||
[student@studentvm1 testdir]$ echo "Todays date is $(date)"
|
||||
Todays date is Sun Apr 7 14:42:59 EDT 2019
|
||||
[student@studentvm1 testdir]$
|
||||
```
|
||||
|
||||
`-seq` 工具用于一个数字序列:
|
||||
|
||||
```
|
||||
[student@studentvm1 testdir]$ seq 5
|
||||
1
|
||||
2
|
||||
3
|
||||
4
|
||||
5
|
||||
[student@studentvm1 testdir]$ echo `seq 5`
|
||||
1 2 3 4 5
|
||||
[student@studentvm1 testdir]$
|
||||
```
|
||||
|
||||
现在你可以做一些更有用处的操作,比如创建大量用于测试的空文件。
|
||||
|
||||
```
|
||||
[student@studentvm1 testdir]$ for I in $(seq -w 5000) ; do touch file-$I ; done
|
||||
```
|
||||
|
||||
`seq` 工具加上 `-w` 选项后,在生成的数字前面会用 0 补全,这样所有的结果都等宽,例如,忽略数字的值,它们的位数一样。这样在对它们按数字顺序进行排列时很容易。
|
||||
|
||||
`seq -w 5000` 语句生成了 1 到 5000 的数字序列。通过把命令替换用于 `for` 语句,`for` 语句就可以使用该数字序列来生成文件名的数字部分。
|
||||
|
||||
#### 算术扩展
|
||||
|
||||
Bash 可以进行整型的数学计算,但是比较繁琐(你一会儿将看到)。数字扩展的语法是 `$((arithmetic-expression))` ,分别用两个括号来打开和关闭表达式。算术扩展在 shell 程序或脚本中类似命令替换;表达式结算后的结果替换了表达式,用于 shell 后续的计算。
|
||||
|
||||
我们再用一个简单的用法来开始:
|
||||
|
||||
```
|
||||
[student@studentvm1 testdir]$ echo $((1+1))
|
||||
2
|
||||
[student@studentvm1 testdir]$ Var1=5 ; Var2=7 ; Var3=$((Var1*Var2)) ; echo "Var 3 = $Var3"
|
||||
Var 3 = 35
|
||||
```
|
||||
|
||||
下面的除法结果是 0,因为表达式的结果是一个小于 1 的整型数字:
|
||||
|
||||
```
|
||||
[student@studentvm1 testdir]$ Var1=5 ; Var2=7 ; Var3=$((Var1/Var2)) ; echo "Var 3 = $Var3"
|
||||
Var 3 = 0
|
||||
```
|
||||
|
||||
这是一个我经常在脚本或 CLI 程序中使用的一个简单的计算,用来查看在 Linux 主机中使用了多少虚拟内存。 `free` 不提供我需要的数据:
|
||||
|
||||
```
|
||||
[student@studentvm1 testdir]$ RAM=`free | grep ^Mem | awk '{print $2}'` ; Swap=`free | grep ^Swap | awk '{print $2}'` ; echo "RAM = $RAM and Swap = $Swap" ; echo "Total Virtual memory is $((RAM+Swap))" ;
|
||||
RAM = 4037080 and Swap = 6291452
|
||||
Total Virtual memory is 10328532
|
||||
```
|
||||
|
||||
我使用 \` 字符来划定用作命令替换的界限。
|
||||
|
||||
我用 Bash 算术扩展的场景主要是用脚本检查系统资源用量后基于返回的结果选择一个程序运行的路径。
|
||||
|
||||
### 总结
|
||||
|
||||
本文是 Bash 编程语言系列的第二篇,探讨了 Bash 中文件、字符串、数字和各种提供流程控制逻辑的逻辑操作符还有不同种类的 shell 扩展。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/19/10/programming-bash-logical-operators-shell-expansions
|
||||
|
||||
作者:[David Both][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[lxbwolf](https://github.com/lxbwolf)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/dboth
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/OSDC_women_computing_5.png?itok=YHpNs_ss (Women in computing and open source v5)
|
||||
[2]: http://www.both.org/?page_id=1183
|
||||
[3]: https://linux.cn/article-11552-1.html
|
240
published/20191024 Get sorted with sort at the command line.md
Normal file
240
published/20191024 Get sorted with sort at the command line.md
Normal file
@ -0,0 +1,240 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (lxbwolf)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11657-1.html)
|
||||
[#]: subject: (Get sorted with sort at the command line)
|
||||
[#]: via: (https://opensource.com/article/19/10/get-sorted-sort)
|
||||
[#]: author: (Seth Kenlon https://opensource.com/users/seth)
|
||||
|
||||
在命令行用 sort 进行排序
|
||||
======
|
||||
|
||||
> 在 Linux、BSD 或 Mac 的终端中使用 sort 命令,按自己的需求重新整理数据。
|
||||
|
||||

|
||||
|
||||
如果你曾经用过数据表应用程序,你就会知道可以按列的内容对行进行排序。例如,如果你有一个费用列表,你可能希望对它们进行按日期或价格升序抑或按类别进行排序。如果你熟悉终端的使用,你不会仅为了排序文本数据就去使用庞大的办公软件。这正是 [sort][2] 命令的用处。
|
||||
|
||||
### 安装
|
||||
|
||||
你不必安装 `sort` ,因为它向来都包含在 [POSIX][3] 系统里。在大多数 Linux 系统中,`sort` 命令来自 GNU 组织打包的实用工具集合中。在其他的 POSIX 系统中,像 BSD 和 Mac,默认的 `sort` 命令不是 GNU 提供的,所以有一些选项可能不一样。本文中我尽量对 GNU 和 BSD 两者的实现都进行说明。
|
||||
|
||||
### 按字母顺序排列行
|
||||
|
||||
`sort` 命令默认会读取文件每行的第一个字符并对每行按字母升序排序后输出。两行中的第一个字符相同的情况下,对下一个字符进行对比。例如:
|
||||
|
||||
```
|
||||
$ cat distro.list
|
||||
Slackware
|
||||
Fedora
|
||||
Red Hat Enterprise Linux
|
||||
Ubuntu
|
||||
Arch
|
||||
1337
|
||||
Mint
|
||||
Mageia
|
||||
Debian
|
||||
$ sort distro.list
|
||||
1337
|
||||
Arch
|
||||
Debian
|
||||
Fedora
|
||||
Mageia
|
||||
Mint
|
||||
Red Hat Enterprise Linux
|
||||
Slackware
|
||||
Ubuntu
|
||||
```
|
||||
|
||||
使用 `sort` 不会改变原文件。`sort` 仅起到过滤的作用,所以如果你希望按排序后的格式保存数据,你需要用 `>` 或 `tee` 进行重定向。
|
||||
|
||||
|
||||
```
|
||||
$ sort distro.list | tee distro.sorted
|
||||
1337
|
||||
Arch
|
||||
Debian
|
||||
[...]
|
||||
$ cat distro.sorted
|
||||
1337
|
||||
Arch
|
||||
Debian
|
||||
[...]
|
||||
```
|
||||
|
||||
### 按列排序
|
||||
|
||||
复杂数据集有时候不止需要对每行的第一个字符进行排序。例如,假设有一个动物列表,每个都有其种和属,用可预见的分隔符分隔每一个“字段”(即数据表中的“单元格”)。这类由数据表导出的格式很常见,CSV(<ryby>以逗号分隔的数据<rt>comma-separated values</rt></ruby>)后缀可以标识这些文件(虽然 CSV 文件不一定用逗号分隔,有分隔符的文件也不一定用 CSV 后缀)。以下数据作为示例:
|
||||
|
||||
```
|
||||
Aptenodytes;forsteri;Miller,JF;1778;Emperor
|
||||
Pygoscelis;papua;Wagler;1832;Gentoo
|
||||
Eudyptula;minor;Bonaparte;1867;Little Blue
|
||||
Spheniscus;demersus;Brisson;1760;African
|
||||
Megadyptes;antipodes;Milne-Edwards;1880;Yellow-eyed
|
||||
Eudyptes;chrysocome;Viellot;1816;Southern Rockhopper
|
||||
Torvaldis;linux;Ewing,L;1996;Tux
|
||||
```
|
||||
|
||||
对于这组示例数据,你可以用 `--field-separator` (在 BSD 和 Mac 用 `-t`,在 GNU 上也可以用简写 `-t` )设置分隔符为分号(因为该示例数据中是用分号而不是逗号,理论上分隔符可以是任意字符),用 `--key`(在 BSD 和 Mac 上用 `-k`,在 GNU 上也可以用简写 `-k`)选项指定哪个字段被排序。例如,对每行第二个字段进行排序(计数以 1 开头而不是 0):
|
||||
|
||||
```
|
||||
sort --field-separator=";" --key=2
|
||||
Megadyptes;antipodes;Milne-Edwards;1880;Yellow-eyed
|
||||
Eudyptes;chrysocome;Viellot;1816;Sothern Rockhopper
|
||||
Spheniscus;demersus;Brisson;1760;African
|
||||
Aptenodytes;forsteri;Miller,JF;1778;Emperor
|
||||
Torvaldis;linux;Ewing,L;1996;Tux
|
||||
Eudyptula;minor;Bonaparte;1867;Little Blue
|
||||
Pygoscelis;papua;Wagler;1832;Gentoo
|
||||
```
|
||||
|
||||
结果有点不容易读,但是 Unix 以构造命令的管道方式而闻名,所以你可以使用 `column` 命令美化输出结果。使用 GNU `column`:
|
||||
|
||||
```
|
||||
$ sort --field-separator=";" \
|
||||
\--key=2 penguins.list | column --table --separator ";"
|
||||
Megadyptes antipodes Milne-Edwards 1880 Yellow-eyed
|
||||
Eudyptes chrysocome Viellot 1816 Southern Rockhopper
|
||||
Spheniscus demersus Brisson 1760 African
|
||||
Aptenodytes forsteri Miller,JF 1778 Emperor
|
||||
Torvaldis linux Ewing,L 1996 Tux
|
||||
Eudyptula minor Bonaparte 1867 Little Blue
|
||||
Pygoscelis papua Wagler 1832 Gentoo
|
||||
```
|
||||
|
||||
对于初学者可能有点不好理解(但是写起来简单),BSD 和 Mac 上的命令选项:
|
||||
|
||||
```
|
||||
$ sort -t ";" \
|
||||
-k2 penguins.list | column -t -s ";"
|
||||
Megadyptes antipodes Milne-Edwards 1880 Yellow-eyed
|
||||
Eudyptes chrysocome Viellot 1816 Southern Rockhopper
|
||||
Spheniscus demersus Brisson 1760 African
|
||||
Aptenodytes forsteri Miller,JF 1778 Emperor
|
||||
Torvaldis linux Ewing,L 1996 Tux
|
||||
Eudyptula minor Bonaparte 1867 Little Blue
|
||||
Pygoscelis papua Wagler 1832 Gentoo
|
||||
```
|
||||
|
||||
当然 `-k` 不一定非要设为 `2`。任意存在的字段都可以被设为排序的键。
|
||||
|
||||
### 逆序排列
|
||||
|
||||
你可以用 `--reverse`(BSD/Mac 上用 `-r`,GNU 上也可以用简写 `-r`)选项来颠倒已经排好序的列表。
|
||||
|
||||
```
|
||||
$ sort --reverse alphabet.list
|
||||
z
|
||||
y
|
||||
x
|
||||
w
|
||||
[...]
|
||||
```
|
||||
|
||||
你也可以把输出结果通过管道传给命令 [tac][4] 来实现相同的效果。
|
||||
|
||||
### 按月排序(仅 GNU 支持)
|
||||
|
||||
理想情况下,所有人都按照 ISO 8601 标准来写日期:年、月、日。这是一种合乎逻辑的指定精确日期的方法,也可以很容易地被计算机理解。也有很多情况下,人类用其他的方式标注日期,包括用很名字随意的月份。
|
||||
|
||||
幸运的是,GNU `sort` 命令能识别这种写法,并可以按月份的名称正确排序。使用 `--month-sort`(`-M`)选项:
|
||||
|
||||
```
|
||||
$ cat month.list
|
||||
November
|
||||
October
|
||||
September
|
||||
April
|
||||
[...]
|
||||
$ sort --month-sort month.list
|
||||
January
|
||||
February
|
||||
March
|
||||
April
|
||||
May
|
||||
[...]
|
||||
November
|
||||
December
|
||||
```
|
||||
|
||||
月份的全称和简写都可以被识别。
|
||||
|
||||
### 人类可读的数字排序(仅 GNU 支持)
|
||||
|
||||
另一个人类和计算机的常见混淆点是数字的组合。例如,人类通常把 “1024 kilobytes” 写成 “1KB”,因为人类解析 “1 KB” 比 “1024” 要容易且更快(数字越大,这种差异越明显)。对于计算机来说,一个 9 KB 的字符串要比诸如 1 MB 的字符串大(尽管 9 KB 是 1 MB 很小一部分)。GNU `sort` 命令提供了`--human-numeric-sort`(`-h`)选项来帮助正确解析这些值。
|
||||
|
||||
```
|
||||
$ cat sizes.list
|
||||
2M
|
||||
12MB
|
||||
1k
|
||||
9k
|
||||
900
|
||||
7000
|
||||
$ sort --human-numeric-sort
|
||||
900
|
||||
7000
|
||||
1k
|
||||
9k
|
||||
2M
|
||||
12MB
|
||||
```
|
||||
|
||||
有一些情况例外。例如,“16000 bytes” 比 “1 KB” 大,但是 `sort` 识别不了。
|
||||
|
||||
```
|
||||
$ cat sizes0.list
|
||||
2M
|
||||
12MB
|
||||
16000
|
||||
1k
|
||||
$ sort -h sizes0.list
|
||||
16000
|
||||
1k
|
||||
2M
|
||||
12MB
|
||||
```
|
||||
|
||||
逻辑上来说,这个示例中 16000 应该写成 16 KB,所以也不应该全部归咎于GNU `sort`。只要你确保数字的一致性,`--human-numeric-sort` 可以用一种计算机友好的方式解析成人类可读的数字。
|
||||
|
||||
### 随机排序(仅 GNU 支持)
|
||||
|
||||
有时候工具也提供了一些与设计初衷相悖的选项。某种程度上说,`sort` 命令提供对一个文件进行随机排序的能力没有任何意义。这个命令的工作流让这个特性变得很方便。你*可以*用其他的命令,像 [shuf][5] ,或者你可以用现在的命令添加一个选项。不管你认为它是一个臃肿的还是极具创造力的用户体验设计,GNU `sort` 命令提供了对文件进行随机排序的功能。
|
||||
|
||||
最纯粹的随机排序格式选项是 `--random-sort` 或 `-R`(不要跟 `-r` 混淆,`-r` 是 `--reverse` 的简写)。
|
||||
|
||||
```
|
||||
$ sort --random-sort alphabet.list
|
||||
d
|
||||
m
|
||||
p
|
||||
a
|
||||
[...]
|
||||
```
|
||||
|
||||
每次对文件运行随机排序都会有不同的结果。
|
||||
|
||||
### 结语
|
||||
|
||||
GNU 和 BSD 的 `sort` 命令还有很多功能,所以花点时间去了解这些选项。你会惊异于 `sort` 的灵活性,尤其是当它和其他的 Unix 工具一起使用时。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/19/10/get-sorted-sort
|
||||
|
||||
作者:[Seth Kenlon][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[lxbwolf](https://github.com/lxbwolf)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [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/code_computer_laptop_hack_work.png?itok=aSpcWkcl "Coding on a computer"
|
||||
[2]: https://en.wikipedia.org/wiki/Sort_(Unix)
|
||||
[3]: https://en.wikipedia.org/wiki/POSIX
|
||||
[4]: https://opensource.com/article/19/9/tac-command
|
||||
[5]: https://www.gnu.org/software/coreutils/manual/html_node/shuf-invocation.html
|
153
published/20191028 6 signs you might be a Linux user.md
Normal file
153
published/20191028 6 signs you might be a Linux user.md
Normal file
@ -0,0 +1,153 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (wxy)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11635-1.html)
|
||||
[#]: subject: (6 signs you might be a Linux user)
|
||||
[#]: via: (https://opensource.com/article/19/10/signs-linux-user)
|
||||
[#]: author: (Seth Kenlon https://opensource.com/users/seth)
|
||||
|
||||
Linux 资深用户的 6 大特征
|
||||
======
|
||||
|
||||
> 如果你是 Linux 资深用户,则可能会有这些共同倾向。
|
||||
|
||||

|
||||
|
||||
Linux 用户千差万别,但是我们许多人都有一些相同的习惯。你可能没有本文列出的任何特征,而且如果你是个 Linux 新用户,你可能还不能理解这些特征……
|
||||
|
||||
下面是你可能是 Linux 用户的六个特征。
|
||||
|
||||
### 1、理所当然,纪元始于 1970 年 1 月 1 日
|
||||
|
||||
关于 Unix 计算机时钟为何在重置时总是将其设置回 1970-01-01 的传闻有很多。但有点令人感到乏味的事实是,Unix “纪元”是用于同步的通用且简单的参考点。例如,万圣节在儒略历中是今年的 304 日,但我们通常将该节日称为 “31 号”。我们知道指的是哪个月的 31 号,因为我们有个共同的参考点:我们知道万圣节在 10 月庆祝,而 10 月是一年中的第十个月,并且我们知道前面每一个月包含多少天。没有这些值,虽然我们可以使用传统的计时方法(如月相)来跟踪特殊的季节性事件,但是计算机显然不具备这种能力。
|
||||
|
||||
计算机需要确定且明确定义的值,因此将值 `1970-01-01T00:00:00Z` 选择为 Unix 纪元的开始。每当 [POSIX][2] 计算机的时间不准确时,诸如网络时间协议(NTP)之类的服务就可以向其提供自 `1970-01-01T00:00:00Z` 以来的秒数,计算机可以将其转换为人类易于识别的日期。
|
||||
|
||||
日期和时间是在计算中要追踪的著名的复杂事物,主要是因为几乎所有标准都有例外。一个月并不总是有 30 天,一年也不总是有 365 天,甚至每年有多少秒钟也往往会有所不同。如果你正在寻找一个有趣而令人沮丧的编程练习,那么请尝试编程一个可靠的日历应用程序!
|
||||
|
||||
### 2、输入超过两个字母你就会觉得麻烦
|
||||
|
||||
众所周知,最常见的 Unix 命令都超简短。除了 `cd`、`ls` 和 `mv` 之类的命令外,还有一个命令简直不能再短了:`w`(它根据 `/var/run/utmp` 文件显示当前谁登录了)。
|
||||
|
||||
一方面,极短的命令似乎很不直观。新用户可能不会猜测到键入 `ls` 会<ruby>列出<rt>list</rt></ruby>目录。但是,一旦学习命令,它们肯定是越短越好。如果你整天都在终端上度过,那么你键入的击键次数越少就意味着你可以有更多的时间来完成工作。
|
||||
|
||||
幸运的是,单字母命令并不太多,因此你可以使用大多数字母作为别名。例如,我经常使用 Emacs,以至于我觉得 `emacs` 的输入时间太长,因此通过将下面这行添加到 `.bashrc` 文件中,将其别名为 `e`:
|
||||
|
||||
```
|
||||
alias e='emacs'
|
||||
```
|
||||
|
||||
你也可以临时为命令添加别名。例如,如果你在解决网络问题时发现自己反复运行 [firewall-cmd][3],则可以为当前会话创建别名:
|
||||
|
||||
```
|
||||
$ alias f='firewall-cmd'
|
||||
$ f
|
||||
usage: see firewall-cmd man page
|
||||
No option specified.
|
||||
```
|
||||
|
||||
只要你打开着终端,你的别名就会一直存在。当终端一旦关闭,它便会被遗忘。
|
||||
|
||||
### 3、做任何事都不应该单击两次以上
|
||||
|
||||
Linux 用户喜欢效率。尽管并非每个 Linux 用户都总是急于完成工作,但 Linux 桌面中有一些旨在减少完成任务所需的操作数量的惯例。这里有些例子。
|
||||
|
||||
* 在 KDE 文件管理器 Dolphin 中,单击即可打开文件或目录。假定如果要选择一个文件,则可以单击并拖动,也可以 `Ctrl + 点击`。这可能会使习惯于双击所有内容的用户感到困惑,但是一旦你尝试了单击操作,通常就无法返回费力的双击操作。
|
||||
* 在大多数 Linux 桌面上,单击鼠标中键可粘贴剪贴板的最新内容。
|
||||
* 在许多 Linux 桌面上,可以通过按 `Alt`、`Ctrl` 或 `Shift` 键来修改拖动动作。例如,`Alt + 拖动` 在 KDE 中移动窗口,而 GNOME 中的 `Ctrl + 拖动` 会复制文件而不是移动。
|
||||
|
||||
### 4、任何操作你都不会执行三次以上,因为第三次时你已经将它自动化了
|
||||
|
||||
请原谅我有点夸张,但是许多 Linux 用户期望他们的计算机比他们更努力地工作。虽然学习如何自动执行常见任务需要花费时间,但在 Linux 上它往往比在其它平台上更容易,因为 Linux 终端和 Linux 操作系统是如此紧密地集成在一起。最容易自动化的是你在终端中已经执行的操作,因为命令只是你在解释器中键入的字符串,而该解释器(终端)不会在乎你是手动键入字符串还是将其指向一个脚本。
|
||||
|
||||
例如,如果你发现自己经常将一组文件从一个位置移动到另一个位置,则或许可以将相同的指令序列用作一个脚本,你可以使用单个命令来触发该脚本。假设你每天早上手动执行此操作:
|
||||
|
||||
```
|
||||
$ cd Documents
|
||||
$ trash reports-latest.txt
|
||||
$ wget myserver.local/reports/daily/report-latest.txt
|
||||
$ cp report-latest.txt reports_daily/2019-31-10.log
|
||||
```
|
||||
|
||||
这是一个简单的序列,但是每天重复一次并不是消磨时间的最有效方法。做一点点抽象,你可以使用一个简单的脚本将其自动化:
|
||||
|
||||
```
|
||||
#!/bin/sh
|
||||
|
||||
trash $HOME/Documents/reports-latest.txt
|
||||
|
||||
wget myserver.local/reports/daily/report-latest.txt \
|
||||
-P $HOME/Documents/udpates_daily/`date --iso-8601`.log
|
||||
|
||||
cp $HOME/Documents/udpates_daily/`date --iso-8601`.log \
|
||||
$HOME/Documents/reports-latest.txt
|
||||
```
|
||||
|
||||
你可以把你的脚本叫做 `get-reports.sh` 并在每天早晨手动启动它,或者甚至可以将其输入到 crontab 中,以便计算机可以执行此任务而无需你进行任何干预。
|
||||
|
||||
对于新用户来说,这可能会有点困扰,因为什么和什么是一体的并不总是很明显。例如,如果你经常发现自己打开图像并将其按比例缩小 50%,那么你可能习惯于执行以下操作:
|
||||
|
||||
1. 打开你的照片查看器或编辑器
|
||||
2. 缩放图像
|
||||
3. 将图像导出为修改后的文件
|
||||
4. 关闭应用程序
|
||||
|
||||
如果你一天要做几次,你可能会对这种重复感到厌倦。但是,由于你是在图形用户界面(GUI)中执行这些操作的,因此你需要知道如何对 GUI 编写脚本以使其自动化。某些应用程序,例如 [GIMP][4],具有丰富的脚本接口,但是其过程显然不同于仅修改一堆命令并将其存储到文件中那么简单。
|
||||
|
||||
再说一次,有时在命令行中有与你在 GUI 中所做的等效的操作。将文档从一种文本格式转换为另一种格式可以使用 [Pandoc][5],处理图像可以使用 [Image Magick][6],音乐和视频也可以通过命令行进行编辑和转换,等等。最大的问题是你需要知道要查找什么,通常是学习新的(有时是复杂的)命令。但是,在终端中按比例缩小图像比在 GUI 中显然更简单:
|
||||
|
||||
```
|
||||
#!/bin/sh
|
||||
|
||||
convert "${1}" -scale 50% `basename "${1}" .jpg`_50.jpg
|
||||
```
|
||||
|
||||
这些麻烦、重复的任务值得研究。你永远不知道你的工作让计算机做起来是有多么的简单和快捷!
|
||||
|
||||
### 5、发行版之间跳来跳去
|
||||
|
||||
我在家里是一个热情的 Slackware 用户,而在工作时是一个 RHEL 用户。实际上,这不是事实,我现在在工作时是 Fedora 用户。除了有时候我使用 CentOS,偶尔我还会运行 [Mageia][7]。
|
||||
|
||||
![Debian on a PowerPC64 box, image CC BY SA Claudio Miranda][8]
|
||||
|
||||
*运行在 PowerPC64 机器上的 Debian*
|
||||
|
||||
发行版好不好无关紧要,成为 Linux 用户的极致乐趣之一是可以自由决定运行哪个发行版。乍一看,它们基本相同,令人耳目一新。但是根据你的心情,你可能更喜欢 CentOS 的稳定性而不是 Fedora 的不断更新,或者你可能有一天会真正享受 Mageia 的集中控制中心,然后又对原始的 [Debian][9] 配置文件进行模块化乐在其中,而有时你又会完全转向其他操作系统。
|
||||
|
||||
![OpenBSD, image CC BY SA Claudio Miranda][10]
|
||||
|
||||
*OpenBSD,不是 Linux 发行版*
|
||||
|
||||
关键是,Linux 发行版是激情项目,成为其他人的开源激情的一部分很有趣。
|
||||
|
||||
### 6、你对开源充满热情
|
||||
|
||||
无论你的经验如何,如果你是 Linux 用户,那么你无疑会对开源充满热情。无论你是每天通过[共创艺术品] [11]还是代码来表达你的热情,还是将其升华到只在自由而自在的环境中完成工作,你都生活并构筑于开源之上。因为有了千千万万个你,所以有了开源社区,社区因你而变得更加丰富。
|
||||
|
||||
有太多的东西我没有提到。作为 Linux 用户,还有什么可以出卖你的身份?让我们在评论中知道!
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/19/10/signs-linux-user
|
||||
|
||||
作者:[Seth Kenlon][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[wxy](https://github.com/wxy)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [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/tux_linux_penguin_code_binary.jpg?itok=TxGxW0KY (Tux with binary code background)
|
||||
[2]: https://opensource.com/article/19/7/what-posix-richard-stallman-explains
|
||||
[3]: https://opensource.com/article/19/7/make-linux-stronger-firewalls
|
||||
[4]: https://www.gimp.org/
|
||||
[5]: https://opensource.com/article/19/5/convert-markdown-to-word-pandoc
|
||||
[6]: https://opensource.com/article/17/8/imagemagick
|
||||
[7]: http://mageia.org
|
||||
[8]: https://opensource.com/sites/default/files/uploads/debian.png (Debian on a PowerPC64 box)
|
||||
[9]: http://debian.org
|
||||
[10]: https://opensource.com/sites/default/files/uploads/openbsd.jpg (OpenBSD)
|
||||
[11]: http://freesvg.org
|
@ -0,0 +1,222 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (lxbwolf)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11666-1.html)
|
||||
[#]: subject: (How to remove duplicate lines from files with awk)
|
||||
[#]: via: (https://opensource.com/article/19/10/remove-duplicate-lines-files-awk)
|
||||
[#]: author: (Lazarus Lazaridis https://opensource.com/users/iridakos)
|
||||
|
||||
怎样使用 awk 删掉文件中重复的行
|
||||
======
|
||||
|
||||
> 学习怎样使用 awk 的 `!visited[$0]++` 在不重新排序或改变原排列顺序的前提下删掉重复的行。
|
||||
|
||||

|
||||
|
||||
假设你有一个文本文件,你需要删掉所有重复的行。
|
||||
|
||||
### TL;DR
|
||||
|
||||
*要保持原来的排列顺序*删掉重复行,使用:
|
||||
|
||||
```
|
||||
awk '!visited[$0]++' your_file > deduplicated_file
|
||||
```
|
||||
|
||||
### 工作原理
|
||||
|
||||
这个脚本维护一个关联数组,索引(键)为文件中去重后的行,每个索引对应的值为该行出现的次数。对于文件的每一行,如果这行(之前)出现的次数为 0,则值加 1,并打印这行,否则值加 1,不打印这行。
|
||||
|
||||
我之前不熟悉 `awk`,我想弄清楚这么短小的一个脚本是怎么实现的。我调研了下,下面是调研心得:
|
||||
|
||||
* 这个 awk “脚本” `!visited[$0]++` 对输入文件的*每一行*都执行。
|
||||
* `visited[]` 是一个[关联数组][2](又名[映射][3])类型的变量。`awk` 会在第一次执行时初始化它,因此我们不需要初始化。
|
||||
* `$0` 变量的值是当前正在被处理的行的内容。
|
||||
* `visited[$0]` 通过与 `$0`(正在被处理的行)相等的键来访问该映射中的值,即出现次数(我们在下面设置的)。
|
||||
* `!` 对表示出现次数的值取反:
|
||||
* 在 `awk` 中,[任意非零的数或任意非空的字符串的值是 `true`][4]。
|
||||
* [变量默认的初始值为空字符串][5],如果被转换为数字,则为 0。
|
||||
* 也就是说:
|
||||
* 如果 `visited[$0]` 的值是一个比 0 大的数,取反后被解析成 `false`。
|
||||
* 如果 `visited[$0]` 的值为等于 0 的数字或空字符串,取反后被解析成 `true` 。
|
||||
* `++` 表示变量 `visited[$0]` 的值加 1。
|
||||
* 如果该值为空,`awk` 自动把它转换为 `0`(数字) 后加 1。
|
||||
* 注意:加 1 操作是在我们取到了变量的值之后执行的。
|
||||
|
||||
总的来说,整个表达式的意思是:
|
||||
|
||||
* `true`:如果表示出现次数为 0 或空字符串
|
||||
* `false`:如果出现的次数大于 0
|
||||
|
||||
`awk` 由 [模式或表达式和一个与之关联的动作][6] 组成:
|
||||
|
||||
```
|
||||
<模式/表达式> { <动作> }
|
||||
```
|
||||
|
||||
如果匹配到了模式,就会执行后面的动作。如果省略动作,`awk` 默认会打印(`print`)输入。
|
||||
|
||||
> 省略动作等价于 `{print $0}`。
|
||||
|
||||
我们的脚本由一个 `awk` 表达式语句组成,省略了动作。因此这样写:
|
||||
|
||||
```
|
||||
awk '!visited[$0]++' your_file > deduplicated_file
|
||||
```
|
||||
|
||||
等于这样写:
|
||||
|
||||
```
|
||||
awk '!visited[$0]++ { print $0 }' your_file > deduplicated_file
|
||||
```
|
||||
|
||||
对于文件的每一行,如果表达式匹配到了,这行内容被打印到输出。否则,不执行动作,不打印任何东西。
|
||||
|
||||
### 为什么不用 uniq 命令?
|
||||
|
||||
`uniq` 命令仅能对相邻的行去重。这是一个示例:
|
||||
|
||||
```
|
||||
$ cat test.txt
|
||||
A
|
||||
A
|
||||
A
|
||||
B
|
||||
B
|
||||
B
|
||||
A
|
||||
A
|
||||
C
|
||||
C
|
||||
C
|
||||
B
|
||||
B
|
||||
A
|
||||
$ uniq < test.txt
|
||||
A
|
||||
B
|
||||
A
|
||||
C
|
||||
B
|
||||
A
|
||||
```
|
||||
|
||||
### 其他方法
|
||||
|
||||
#### 使用 sort 命令
|
||||
|
||||
我们也可以用下面的 [sort][7] 命令来去除重复的行,但是*原来的行顺序没有被保留*。
|
||||
|
||||
|
||||
```
|
||||
sort -u your_file > sorted_deduplicated_file
|
||||
```
|
||||
|
||||
#### 使用 cat + sort + cut
|
||||
|
||||
上面的方法会产出一个去重的文件,各行是基于内容进行排序的。[通过管道连接命令][8]可以解决这个问题。
|
||||
|
||||
|
||||
```
|
||||
cat -n your_file | sort -uk2 | sort -nk1 | cut -f2-
|
||||
```
|
||||
|
||||
**工作原理**
|
||||
|
||||
假设我们有下面一个文件:
|
||||
|
||||
```
|
||||
abc
|
||||
ghi
|
||||
abc
|
||||
def
|
||||
xyz
|
||||
def
|
||||
ghi
|
||||
klm
|
||||
```
|
||||
|
||||
`cat -n test.txt` 在每行前面显示序号:
|
||||
|
||||
```
|
||||
1 abc
|
||||
2 ghi
|
||||
3 abc
|
||||
4 def
|
||||
5 xyz
|
||||
6 def
|
||||
7 ghi
|
||||
8 klm
|
||||
```
|
||||
|
||||
`sort -uk2` 基于第二列(`k2` 选项)进行排序,对于第二列相同的值只保留一次(`u` 选项):
|
||||
|
||||
```
|
||||
1 abc
|
||||
4 def
|
||||
2 ghi
|
||||
8 klm
|
||||
5 xyz
|
||||
```
|
||||
|
||||
`sort -nk1` 基于第一列排序(`k1` 选项),把列的值作为数字来处理(`-n` 选项):
|
||||
|
||||
```
|
||||
1 abc
|
||||
2 ghi
|
||||
4 def
|
||||
5 xyz
|
||||
8 klm
|
||||
```
|
||||
|
||||
最后,`cut -f2-` 从第二列开始打印每一行,直到最后的内容(`-f2-` 选项:留意 `-` 后缀,它表示这行后面的内容都包含在内)。
|
||||
|
||||
```
|
||||
abc
|
||||
ghi
|
||||
def
|
||||
xyz
|
||||
klm
|
||||
```
|
||||
|
||||
### 参考
|
||||
|
||||
* [GNU awk 用户手册][9]
|
||||
* [awk 中的数组][2]
|
||||
* [Awk — 真值][4]
|
||||
* [Awk 表达式][5]
|
||||
* [Unix 怎么删除文件中重复的行?][10]
|
||||
* [不用排序去掉重复的行(去重)][11]
|
||||
* ['!a[$0]++' 工作原理][12]
|
||||
|
||||
以上为全文。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/19/10/remove-duplicate-lines-files-awk
|
||||
|
||||
作者:[Lazarus Lazaridis][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[lxbwolf](https://github.com/lxbwolf)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/iridakos
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/code_computer_laptop_hack_work.png?itok=aSpcWkcl (Coding on a computer)
|
||||
[2]: http://kirste.userpage.fu-berlin.de/chemnet/use/info/gawk/gawk_12.html
|
||||
[3]: https://en.wikipedia.org/wiki/Associative_array
|
||||
[4]: https://www.gnu.org/software/gawk/manual/html_node/Truth-Values.html
|
||||
[5]: https://ftp.gnu.org/old-gnu/Manuals/gawk-3.0.3/html_chapter/gawk_8.html
|
||||
[6]: http://kirste.userpage.fu-berlin.de/chemnet/use/info/gawk/gawk_9.html
|
||||
[7]: http://man7.org/linux/man-pages/man1/sort.1.html
|
||||
[8]: https://stackoverflow.com/a/20639730/2292448
|
||||
[9]: https://www.gnu.org/software/gawk/manual/html_node/
|
||||
[10]: https://stackoverflow.com/questions/1444406/how-can-i-delete-duplicate-lines-in-a-file-in-unix
|
||||
[11]: https://stackoverflow.com/questions/11532157/remove-duplicate-lines-without-sorting
|
||||
[12]: https://unix.stackexchange.com/questions/159695/how-does-awk-a0-work/159734#159734
|
||||
[13]: https://opensource.com/sites/default/files/uploads/duplicate-cat.jpg (Duplicate cat)
|
||||
[14]: https://iridakos.com/about/
|
||||
[15]: http://creativecommons.org/licenses/by-nc/4.0/
|
@ -0,0 +1,76 @@
|
||||
用 autoplank 在多个显示器上使用 Plank 扩展坞
|
||||
======
|
||||
|
||||

|
||||
|
||||
[autoplank][1] 是用 Go 语言编写的小型工具,它为 Plank 扩展坞增加了多显示器支持,而无需创建[多个][2]扩展坞。
|
||||
|
||||
当你将鼠标光标移动到显示器的底部时,`autoplank` 会使用 `xdotool` 检测到你的鼠标移动,并且自动将 Plank 扩展坞移动到该显示器。该工具仅在将 Plank 设置为在屏幕底部的情况下工作(至少目前如此)。
|
||||
|
||||
在 Plank 实际出现在鼠标所在的显示器上前会稍有延迟。开发人员说这是有意设计的,以确保你确实要在该显示器上访问 Plank。显示 Plank 之前的时间延迟目前尚不可配置,但将来可能会改变。
|
||||
|
||||
`autoplank` 可以在 elementary OS 以及其它的桌面环境或发行版上使用。
|
||||
|
||||
Plank 是一个简单的扩展坞,它显示了正在运行的应用程序/窗口的图标。它允许将应用程序固定到扩展坞,并带有一些内置的简单“扩展组件”:剪贴板管理器、时钟、CPU 监视器、显示桌面和垃圾桶。要访问其设置,请按住 `Ctrl` 键,同时右键单击 Plank 扩展坞上的任意位置,然后单击 “Preferences”。
|
||||
|
||||
Plank 默认用在 elementary OS 中,但也可以在任何桌面环境或 Linux 发行版中使用。
|
||||
|
||||
### 安装 autoplank
|
||||
|
||||
在其 GitHub 页面上,提到你需要 Go 1.8 或更高版本才能构建 `autoplank`,但我能够在 Ubuntu 16.04(elementary OS 0.4 Loki)中使用 Go 1.6 成功构建它。
|
||||
|
||||
开发者说:
|
||||
|
||||
1、安装所需的依赖项。
|
||||
|
||||
要构建 `autoplank`,你需要 Go(在 Debian、Ubuntu、elementary OS 等中使用 golang-go)。要获取最新的 Git 代码,你还需要 `git`,要在显示器上检测你的鼠标移动,还需要安装 `xdotool`。
|
||||
|
||||
使用以下命令将它们安装在 Ubuntu、Debian、elementary OS 等中:
|
||||
|
||||
```
|
||||
sudo apt install git golang-go xdotool
|
||||
```
|
||||
|
||||
2、从 [Git][1] 获取最新的 `autoplank`,构建并将其安装在 `/usr/local/bin` 中:
|
||||
|
||||
```
|
||||
git clone https://github.com/abiosoft/autoplank
|
||||
cd autoplank
|
||||
go build -o autoplank
|
||||
sudo mv autoplank /usr/local/bin/
|
||||
```
|
||||
|
||||
你现在可以从主目录中删除 `autoplank` 文件夹。
|
||||
|
||||
当你想卸载 `autoplank` 时,只需删除 `/usr/local/bin/autoplank` 二进制文件(`sudo rm /usr/local/bin/autoplank`)。
|
||||
|
||||
3、将 `autoplank` 添加到启动中。
|
||||
|
||||
如果你想在将 `autoplank` 添加到启动项或为其创建 systemd 服务之前尝试使用 `autoplank`,则只需在终端中键入 `/usr/local/bin/autoplank` 即可启动它。
|
||||
|
||||
要使 `autoplank` 在重新启动后起作用,你需要将其添加到启动项中。确切的操作步骤取决于你的桌面环境,因此我不会确切告诉你如何在每个桌面环境中执行此操作,但是请记住在启动项中将 `/usr/local/bin/autoplank` 设置为可执行文件。
|
||||
|
||||
在 elementary OS 中,你可以打开“系统设置”,然后在“应用程序”的“启动”选项卡上,单击窗口左下角的“+”按钮,然后在“键入自定义命令”字段中添加 “/usr/local/bin/autoplank”:
|
||||
|
||||

|
||||
|
||||
如[此处][3]的解释,使用 `autoplank` 的另一种方法是通过为其创建 systemd 服务。将 systemd 服务用于 autoplank 的优点是,无论它出于何种原因而崩溃,都可以重新启动 `autoplank`。可以使用 systemd 服务或将 `autoplank` 添加到启动应用程序中(但不要同时使用两者)。
|
||||
|
||||
4、完成此操作后,注销、登录,`autoplank` 应该已在运行,因此你可以将鼠标移至显示器底部以将 Plank 停靠此处。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.linuxuprising.com/2018/08/use-plank-on-multiple-monitors-without.html
|
||||
|
||||
作者:[Logix][a]
|
||||
选题:[lujun9972](https://github.com/lujun9972)
|
||||
译者:[wxy](https://github.com/wxy)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:https://plus.google.com/118280394805678839070
|
||||
[1]:https://github.com/abiosoft/autoplank
|
||||
[2]:https://answers.launchpad.net/plank/+question/204593
|
||||
[3]:https://github.com/abiosoft/autoplank#optional-create-a-service
|
||||
[4]:https://www.reddit.com/r/elementaryos/comments/95a879/autoplank_use_plank_on_multimonitor_setup/e3r9saq/
|
@ -0,0 +1,101 @@
|
||||
Linux 平台上的写作者必备工具
|
||||
======
|
||||
|
||||

|
||||
|
||||
我从事作家已有 20 多年了。我撰写了数千篇有关各种技术主题的文章和指南,并撰写了 40 多本小说。因此,书面文字不仅对我很重要,还很熟悉,成为了我的第二种自然交流的方式。在过去的二十年中(而且还在继续),我几乎都是在 Linux 平台上完成的所有工作。我必须承认,在早期,这并不总是那么容易。格式并不总是与编辑器所需要的相吻合,在某些情况下,开源平台根本没有完成工作所需的必要工具。
|
||||
|
||||
那时已经过去,现在已经不同了。
|
||||
|
||||
Linux 演进和基于 Web 的工具的相得益彰使得它可以让任何写作者都能在 Linux 上完成工作(并且做得很好)。但是你需要什么工具?你可能会惊讶地发现,在某些情况下,使用 100% 开源的工具无法有效完成这项工作。不过即使如此,工作总是可以完成的。让我们来看看我作为技术作家和小说作者一直使用的工具。我将通过小说和非小说类的写作过程来概述这一点(因为过程不同,需要特定的工具)。
|
||||
|
||||
对认真的 Linux 硬核用户预先做个预警。很久以前,我就放弃了使用 LaTeX 和 DocBook 之类的工具进行写作。为什么?因为对我而言,重点必须放在内容上,而不是过程上。当你面临最后期限时,必须以效率为先。
|
||||
|
||||
### 非小说类
|
||||
|
||||
我们将从非虚构写作入手,因为这是两者中较简单的过程。为了编写技术指南,我与不同的编辑人员合作,并且在某些情况下,必须将内容复制/粘贴到 CMS 中。但是就像我的小说一样,整个过程总是从 Google 云端硬盘开始。在这一点上,许多开源纯粹主义者会转身走开。不用担心,你始终可以选择将所有文件保存在本地,也可以使用更开放友好的云服务(例如 [Zoho][1] 或 [nextCloud][2])。
|
||||
|
||||
为什么要从云端开始?多年来,我发现我需要能够随时随地访问那些内容。最简单的解决方案是迁移到云上。我对丢失工作成果这件事也很偏执。为此,我使用了 [Insync][3] 之类的工具来使我的 Google 云端硬盘与桌面保持同步。有了桌面同步功能,我知道我的工作成果总是有备份,以防万一 Google 云端硬盘出了问题。
|
||||
|
||||
对于那些我必须与之一起将内容输入到内容管理系统(CMS)的客户,该过程到此结束。我可以直接从 Google 文档复制/粘贴到 CMS 中,并完成此操作。当然,对于技术内容,总是涉及到屏幕截图。为此,我使用 [Gimp][4],它使得截取屏幕截图变得简单:
|
||||
|
||||
![screenshot with Gimp][6]
|
||||
|
||||
*图 1:使用 Gimp 截屏。*
|
||||
|
||||
1. 打开 Gimp。
|
||||
2. 单击“文件>创建>屏幕快照”。
|
||||
3. 选择单个窗口、整个屏幕或要抓取的区域(图 1)。
|
||||
4. 单击“抓取”。
|
||||
|
||||
我的大多数客户倾向于使用 Google 文档,因为我可以共享文件夹,以便他们可以可靠地访问该内容。我有一些无法使用 Google 文档的客户,因此我必须将文件下载为可以使用的格式。为此,我要做的是下载 .odt 格式,以 [LibreOffice][8] 打开文档(图 2),根据需要设置格式,保存为客户所需的格式,然后发送文档。
|
||||
|
||||
![Google Doc][10]
|
||||
|
||||
*图 2:在 LibreOffice 中打开我下载的 Google 文档。*
|
||||
|
||||
非小说类作品这样就行了。
|
||||
|
||||
### 小说类
|
||||
|
||||
这里会稍微变得有点复杂。开始的步骤是相同的,因为我总是在 Google 文档中写小说的每个初稿。完成后,我将文件下载到 Linux 桌面,在 LibreOffice 中打开文件,根据需要设置格式,然后另存为编辑器支持的文件类型(不幸的是,这意味着是 .docx)。
|
||||
|
||||
该过程的下一步变得有些琐碎。我的编辑更喜欢使用注释来跟踪更改(因为这使我们俩阅读文档和做出更改一样容易)。因此,一个 60k 的 word 文档可以包含成百上千的注释,这会使 LibreOffice 慢的像爬一样。从前,你可以增加用于文档的内存,但是从 LibreOffice 6 开始,这不再可行。这意味着任何较大的、像小说一样长的、带有大量注释的文档都将无法使用。因此,我不得不采取一些极端的措施,使用 [WPS Office][11](图 3)。尽管这不是开源解决方案,但 WPS Office 在文档中包含大量注释的情况下做得很好,因此无需处理 LibreOffice 所带来的麻烦(当处理带有数百个注释的大型文件时)。
|
||||
|
||||
![comments][13]
|
||||
|
||||
*图 3:WPS 可以轻松处理大量注释。*
|
||||
|
||||
一旦我和我的编辑完成了对书的编辑(所有评论都已删除),我就可以在 LibreOffice 中打开文件进行最终格式化。格式化完成后,我将文件保存为 .html 格式,然后以 [Calibre][14] 打开文件以将文件导出为 .mobi 和 .epub 格式。
|
||||
|
||||
对于希望在 Amazon、Barnes&Noble、Smashwords 或其他平台上出版的任何人,Calibre 都是必备工具。Caliber 比其他类似解决方案更好地方是,它使你可以直接编辑 .epub 文件(图 4)。对于 Smashword 来说,这是绝对必要的(因为导出过程将添加 Smashwords 转换工具上不接受的元素)。
|
||||
|
||||
![Calibre][16]
|
||||
|
||||
*图 4:直接在 Calibre 中编辑 epub 文件。*
|
||||
|
||||
写作过程结束后(或有时在等待编辑完成一校时),我将开始为书制作封面。该任务完全在 Gimp 中处理(图 5)。
|
||||
|
||||
![Using Gimp][19]
|
||||
|
||||
*图 5:在 Gimp 中创建 POTUS 的封面。*
|
||||
|
||||
这样就完成了在 Linux 平台上创建小说的过程。由于文档的篇幅以及某些编辑人员的工作方式,与创建非小说类的过程相比,它可能会变得有些复杂,但这远没有挑战性。实际上,在 Linux 上创建小说与其他平台一样简单(并且更可靠)。
|
||||
|
||||
### 希望这可以帮助你
|
||||
|
||||
我希望这可以帮助有抱负的作家有信心在 Linux 平台上进行写作。还有许多其他工具可供使用,但是多年来我在这里列出的工具很好地服务了我。而且,尽管我确实使用了几个专有的工具,但只要它们在 Linux 上都能正常运行,我觉得是可以的。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.linux.com/learn/2018/11/must-have-tools-writers-linux-platform
|
||||
|
||||
作者:[Jack Wallen][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[wxy](https://github.com/wxy)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://www.linux.com/users/jlwallen
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://www.zoho.com/
|
||||
[2]: https://nextcloud.com/
|
||||
[3]: https://www.insynchq.com
|
||||
[4]: https://www.gimp.org/
|
||||
[5]: /files/images/writingtools1jpg
|
||||
[6]: https://lcom.static.linuxfound.org/sites/lcom/files/writingtools_1.jpg (screenshot with Gimp)
|
||||
[7]: /licenses/category/used-permission
|
||||
[8]: https://www.libreoffice.org/
|
||||
[9]: /files/images/writingtools2jpg
|
||||
[10]: https://lcom.static.linuxfound.org/sites/lcom/files/writingtools_2.jpg (Google Doc)
|
||||
[11]: https://www.wps.com/en-US/
|
||||
[12]: /files/images/writingtools3jpg
|
||||
[13]: https://lcom.static.linuxfound.org/sites/lcom/files/writingtools_3.jpg (comments)
|
||||
[14]: https://calibre-ebook.com/
|
||||
[15]: /files/images/writingtools4jpg
|
||||
[16]: https://lcom.static.linuxfound.org/sites/lcom/files/writingtools_4.jpg (Calibre)
|
||||
[17]: /licenses/category/creative-commons-zero
|
||||
[18]: /files/images/writingtools5jpg
|
||||
[19]: https://lcom.static.linuxfound.org/sites/lcom/files/writingtools_5.jpg (Using Gimp)
|
||||
[20]: https://training.linuxfoundation.org/training/introduction-to-open-source-development-git-and-linux/?utm_source=linux.com&utm_medium=article&utm_campaign=lfd201
|
@ -0,0 +1,77 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (wxy)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11607-1.html)
|
||||
[#]: subject: (Can Better Task Stealing Make Linux Faster?)
|
||||
[#]: via: (https://www.linux.com/blog/can-better-task-stealing-make-linux-faster)
|
||||
[#]: author: (Oracle )
|
||||
|
||||
更好的任务窃取可以使 Linux 更快吗?
|
||||
======
|
||||
|
||||

|
||||
|
||||
> Oracle Linux 内核开发人员 Steve Sistare 参与了这场有关内核调度程序改进的讨论。
|
||||
|
||||
### 通过可扩展的任务窃取进行负载平衡
|
||||
|
||||
Linux 任务调度程序通过将唤醒的任务推送到空闲的 CPU,以及在 CPU 空闲时从繁忙的 CPU 中拉取任务来平衡整个系统的负载。在大型系统上的推送侧和拉取侧,有效的伸缩都是挑战。对于拉取,调度程序搜索连续的更大范围中的所有 CPU,直到找到过载的 CPU,然后从最繁忙的组中拉取任务。这代价非常昂贵,在大型系统上要花费 10 到 100 微秒,因此搜索时间受到平均空闲时间的限制,并且某些范围不会被搜索。并非总能达到平衡,而且闲置的 CPU 依旧闲置。
|
||||
|
||||
我实现了一种备用机制,该机制在 `idle_balance()` 中的现有搜索中自身受限并且没有找到之后被调用。我维护了一个过载的 CPU 的位图,当可运行的 CFS 任务计数超过 1 时,CPU 会设置该位。这个位图是稀疏的,每个高速缓存线的有效位数量有限。当许多线程同时设置、清除和访问元素时,这可以减少缓存争用。每个末级缓存都有一个位图。当 CPU 空闲时,它将搜索该位图以查找第一个具有可迁移任务的过载 CPU,然后将其窃取。这种简单的窃取会比单独的 `idle_balance()` 产生更高的 CPU 利用率,因为该搜索的成本很便宜,花费 1 到 2 微秒,因此每次 CPU 即将空闲时都可以调用它。窃取不会减轻全局最繁忙的队列的负担,但是它比根本不执行任何操作要好得多。
|
||||
|
||||
### 结果
|
||||
|
||||
偷窃仅在调度程序代码中占用少量 CPU 开销即可提高利用率。在以下实验中,以不同数量的组(每个组 40 个任务)运行 hackbench,并对每次运行结果显示 `/proc/schedstat` 中的增量(按 CPU 平均),并增加了这些非标准的统计信息:
|
||||
|
||||
* `%find`:在旧函数和新函数中花费的时间百分比,这些函数用于搜索空闲的 CPU 和任务以窃取并设置过载的 CPU 位图。
|
||||
* `steal`:任务从另一个 CPU 窃取的次数。经过的时间增加了 8% 到 36%,最多增加了 0.4% 的发现时间。
|
||||
|
||||
![load balancing][1]
|
||||
|
||||
如下图的绿色曲线所示,新内核的 CPU 繁忙利用率接近 100%,作为比较的基线内核是橙色曲线:
|
||||
|
||||
![][3]
|
||||
|
||||
根据负载的不同,窃取可将 Oracle 数据库 OLTP 性能提高多达 9%,并且我们已经看到 MySQL、Pgsql、gcc、Java 和网络方面有了一些不错的改进。通常,窃取对上下文切换率高的工作负载最有帮助。
|
||||
|
||||
### 代码
|
||||
|
||||
截至撰写本文时,这项工作尚未完成,但最新的修补程序系列位于 [https://lkml.org/lkml/2018/12/6/1253][4]。如果你的内核是使用 `CONFIG_SCHED_DEBUG=y` 构建的,则可以使用以下命令验证其是否包含窃取优化:
|
||||
|
||||
```
|
||||
# grep -q STEAL /sys/kernel/debug/sched_features && echo Yes
|
||||
Yes
|
||||
```
|
||||
|
||||
如果要尝试使用,请注意,对于具有 2 个以上 NUMA 节点的系统,禁用了窃取功能,因为 hackbench 在此类系统上发生了回归,正如我在 [https://lkml.org/lkml/2018/12/6/1250][5] 中解释的那样。但是,我怀疑这种影响是特定于 hackbench 的,并且窃取将有助于多节点系统上的其他工作负载。要尝试使用它,请用内核参数 `sched_steal_node_limit=8`(或更大)重新启动。
|
||||
|
||||
### 进一步工作
|
||||
|
||||
在将基本盗用算法推向上游之后,我正在考虑以下增强功能:
|
||||
|
||||
* 如果在末级缓存中进行窃取找不到候选者,在 LLC 和 NUMA 节点之间进行窃取。
|
||||
* 维护稀疏位图以标识 RT 调度类中的偷窃候选者。当前 `pull_rt_task()` 搜索所有运行队列。
|
||||
* 从 `idle_balance()` 中删除核心和套接字级别,因为窃取会处理这些级别。当支持跨 LLC 窃取时,完全删除 `idle_balance()`。
|
||||
* 维护位图以标识空闲核心和空闲 CPU,以实现推平衡。
|
||||
|
||||
这篇文章最初发布于 [Oracle Developers Blog][6]。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.linux.com/blog/can-better-task-stealing-make-linux-faster
|
||||
|
||||
作者:[Oracle][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[wxy](https://github.com/wxy)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://www.linux.com/author/oracle/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://lcom.static.linuxfound.org/sites/lcom/files/linux-load-balancing.png (load balancing)
|
||||
[3]: https://cdn.app.compendium.com/uploads/user/e7c690e8-6ff9-102a-ac6d-e4aebca50425/b7a700fe-edc3-4ea0-876a-c91e1850b59b/Image/00c074f4282bcbaf0c10dd153c5dfa76/steal_graph.png
|
||||
[4]: https://lkml.org/lkml/2018/12/6/1253
|
||||
[5]: https://lkml.org/lkml/2018/12/6/1250
|
||||
[6]: https://blogs.oracle.com/linux/can-better-task-stealing-make-linux-faster
|
@ -0,0 +1,73 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (wxy)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11575-1.html)
|
||||
[#]: subject: (Why blockchain (might be) coming to an IoT implementation near you)
|
||||
[#]: via: (https://www.networkworld.com/article/3386881/why-blockchain-might-be-coming-to-an-iot-implementation-near-you.html)
|
||||
[#]: author: (Jon Gold https://www.networkworld.com/author/Jon-Gold/)
|
||||
|
||||
为什么区块链(可能会)来到你身边的物联网
|
||||
======
|
||||
|
||||
![MF3D / Getty Images][1]
|
||||
|
||||
各个公司发现,物联网与最近其他许多流行的企业级计算技术有着良好的合作关系,以支持加密货币而闻名的创新的分布式信任系统的区块链也不例外。然而,在物联网应用中实施区块链可能具有挑战性,并且需要对技术有深入的了解。
|
||||
|
||||
区块链是一个跟踪各种交易的分布式账本。链上的每个“块”都包含要防止篡改的交易记录或其他数据,并通过加密散列链接到前一个,这意味着对块的任何篡改都将使该链接无效。节点(几乎可以是其中装有 CPU 的任何节点)通过分布式的对等网络进行通信,以共享数据并确保链中数据的有效性。
|
||||
|
||||
北卡罗来纳大学格林波若分校的管理学教授 Nir Kshetri 表示,区块链系统之所以有效,是因为所有的块都必须就它们所保护的数据的细节达成一致。如果有人尝试更改给定节点上先前的事务,则存储在网络上的其余数据会回推回来。“数据的旧记录仍然存在,” Kshetri 说。
|
||||
|
||||
这是一项强大的安全技术 —— 如果没有坏人成功控制给定区块链上的所有(LCTT 译注:应为“大部分”)节点([著名的“51% 攻击”][4]),那么该区块链保护的数据就不会被伪造或以其他方式弄乱。因此,对于在物联网世界某些角落的公司来说,使用区块链是一种有吸引力的选择也就不足为奇了。
|
||||
|
||||
物联网安全初创企业 NXMLabs 的首席技术官兼联合创始人 Jay Fallah 认为,除了区块链能够在网络上安全地分发可信信息的能力这一事实之外,部分原因还在于区块链在技术堆栈中的地位。
|
||||
|
||||
“区块链站在一个非常有趣的交叉点。在过去的 15 年中,在存储、CPU 等方面,计算技术一直在加速发展,但是直到最近,网络技术并没有发生太大变化。”他说,“ 区块链不是网络技术、不是数据技术,而是二者兼具。”
|
||||
|
||||
### 区块链和物联网
|
||||
|
||||
区块链作为物联网世界的部分意义取决于你在和谁交谈以及他们在出售什么,但是最接近的概括可能来自企业区块链供应商 Filament 的首席执行官 Allison Clift-Jenning。
|
||||
|
||||
她说:“在任何地方,人们都想互相信任,并且用的是非常古老的方式,这通常是进入场景的好地方。”
|
||||
|
||||
直接从 Filament 自己的客户群中挑选出来的一个例子是二手车销售。Filament 与“一家主要的底特律汽车制造商”合作,创建了一个受信任的车辆历史平台,该平台基于一种设备,该设备可插入二手车的诊断端口,从那里获取信息,并将该数据写入区块链。像这样,二手车的历史记录就是不可变的,包括它的安全气囊是否曾经打开过,是否被水淹过等等。任何不道德的二手车或不诚实的前车主都无法更改数据,甚至拔掉设备也将意味着记录中存在可疑的空白期。
|
||||
|
||||
SAP 物联网高级副总裁兼全球负责人 Elvira Wallis 表示,当今大多数区块链物联网方案都与信任和数据验证有关。
|
||||
|
||||
她说:“我们遇到的大多数用例都在项目的跟踪和溯源领域,”她举例说明了高端食品的农场到餐桌跟踪系统,该系统使用安装在板条箱和卡车上的区块链节点,这样就可以为物品在运输基础设施中创建无懈可击的记录。(例如,该牛排在这样的温度下冷藏了多长时间,今天运输了多长时间,等等。)
|
||||
|
||||
### 将区块链与物联网一起使用是个好主意吗?
|
||||
|
||||
不同的供应商针对不同的用例出售不同的基于区块链的产品,这些产品使用不同的区块链技术实现,其中一些与加密货币中所使用的经典的、线性的、挖矿式交易区块链不太一样。
|
||||
|
||||
这意味着你目前需要从供应商那里购买特定功能。451 Research 高级分析师 Csilla Zsigri 表示,很少有客户组织拥有可以实施区块链安全系统的内部专家。
|
||||
|
||||
她说,区块链技术的任何智能应用的想法都是发挥其优势,为关键信息创建可信赖的平台。
|
||||
|
||||
Zsigri 说:“这就是我真正看到增值的地方,只是增加了一层信任和验证。”
|
||||
|
||||
专家们一致认为,尽管相当了解基于区块链的物联网应用程序的基本概念,但它并不适用于每个物联网用例。 将区块链应用于非交易系统(尽管有例外,包括 NXM Labs 的用于物联网设备的基于区块链配置的产品)通常不是正确的举动。
|
||||
|
||||
如果不需要在两个不同的参与方之间共享数据,而是简单地将数据从传感器移到后端,那么区块链通常就没有意义,因为它实际上并没有为当前大多数物联网实现中的数据分析增加任何关键的增值。
|
||||
|
||||
“今天,我们仍处于区块链的早期拨号时代。”Clift-Jennings 说,“它比典型的数据库要慢,它甚至无法读取,也常常没有查询引擎。从本质上讲,你并没有真正获得隐私。”
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.networkworld.com/article/3386881/why-blockchain-might-be-coming-to-an-iot-implementation-near-you.html
|
||||
|
||||
作者:[Jon Gold][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[wxy](https://github.com/wxy)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [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://images.idgesg.net/images/article/2019/02/chains_binary_data_blockchain_security_by_mf3d_gettyimages-941175690_2400x1600-100788434-large.jpg
|
||||
[2]: https://www.networkworld.com/article/3224893/internet-of-things/what-is-edge-computing-and-how-it-s-changing-the-network.html
|
||||
[3]: https://www.networkworld.com/article/3291790/data-center/how-edge-networking-and-iot-will-reshape-data-centers.html
|
||||
[4]: https://bitcoinist.com/51-percent-attack-hackers-steals-18-million-bitcoin-gold-btg-tokens/
|
||||
[5]: https://www.facebook.com/NetworkWorld/
|
||||
[6]: https://www.linkedin.com/company/network-world
|
@ -0,0 +1,63 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (wxy)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11565-1.html)
|
||||
[#]: subject: (Why containers and Kubernetes have the potential to run almost anything)
|
||||
[#]: via: (https://opensource.com/article/19/6/kubernetes-potential-run-anything)
|
||||
[#]: author: (Scott McCarty https://opensource.com/users/fatherlinux)
|
||||
|
||||
为什么容器和 Kubernetes 有潜力运行一切
|
||||
======
|
||||
|
||||
> 不仅可以部署简单的应用程序,还可以用 Kubernetes 运维器应对第 2 天运营。
|
||||
|
||||

|
||||
|
||||
在我的第一篇文章 [为什么说 Kubernetes 是一辆翻斗车][2] 中,我谈到了 Kubernetes 如何在定义、分享和运行应用程序方面很出色,类似于翻斗车在移动垃圾方面很出色。在第二篇中,[如何跨越 Kubernetes 学习曲线][3],我解释了 Kubernetes 的学习曲线实际上与运行任何生产环境中的应用程序的学习曲线相同,这确实比学习所有传统组件要容易(如负载均衡器、路由器、防火墙、交换机、集群软件、集群文件系统等)。这是 DevOps,是开发人员和运维人员之间的合作,用于指定事物在生产环境中的运行方式,这意味着双方都需要学习。在第三篇 [Kubernetes 基础:首先学习如何使用][4] 中,我重新设计了 Kubernetes 的学习框架,重点是驾驶翻斗车而不是制造或装备翻斗车。在第四篇文章 [帮助你驾驭 Kubernetes 的 4 个工具][5] 中,我分享了我喜爱的工具,这些工具可帮助你在 Kubernetes 中构建应用程序(驾驶翻斗车)。
|
||||
|
||||
在这最后一篇文章中,我会分享我为什么对在 Kubernetes 上运行应用程序的未来如此兴奋的原因。
|
||||
|
||||
从一开始,Kubernetes 就能够很好地运行基于 Web 的工作负载(容器化的)。Web 服务器、Java 和相关的应用程序服务器(PHP、Python等)之类的工作负载都可以正常工作。该平台处理诸如 DNS、负载平衡和 SSH(由 `kubectl exec` 取代)之类的支持服务。在我的职业生涯的大部分时间里,这些都是我在生产环境中运行的工作负载,因此,我立即意识到,除了 DevOps 之外,除了敏捷之外,使用 Kubernetes 运行生产环境工作负载的强大功能。即使是我们几乎不改变我们的文化习惯,也可以提高效率。调试和退役变得非常容易,而这对于传统 IT 来说是极为困难的。因此,从早期开始,Kubernetes 就用一种单一的配置语言(Kube YAML/Json)为我提供了对生产环境工作负载进行建模所需的所有基本原语。
|
||||
|
||||
但是,如果你需要运行具有复制功能的多主 MySQL,会发生什么情况?使用 Galera 的冗余数据呢?你如何进行快照和备份?那么像 SAP 这样复杂的工作呢?使用 Kubernetes,简单的应用程序(Web 服务器等)的第 0 天(部署)相当简单,但是没有解决第 2 天的运营和工作负载。这并不是说,具有复杂工作负载的第 2 天运营要比传统 IT 难解决,而是使用 Kubernetes 并没有使它们变得更容易。每个用户都要设计自己的天才想法来解决这些问题,这基本上是当今的现状。在过去的五年中,我遇到的第一类问题是复杂工作负载的第 2 天操作。(LCTT 译注:在软件生命周期中,第 0 天是指软件的设计阶段;第 1 天是指软件的开发和部署阶段;第 2 天是指生产环境中的软件运维阶段。)
|
||||
|
||||
值得庆幸的是,随着 Kubernetes <ruby>运维器<rt>Operator</rt></ruby>的出现,这种情况正在改变。随着运维器的出现,我们现在有了一个框架,可以将第 2 天的运维知识汇总到平台中。现在,我们可以应用我在 [Kubernetes 基础:首先学习如何使用][4] 中描述的相同的定义状态、实际状态的方法,现在我们可以定义、自动化和维护各种各样的系统管理任务。
|
||||
|
||||
(LCTT 译注: Operator 是 Kubernetes 中的一种可以完成运维工程师的特定工作的组件,业界大多没有翻译这个名词,此处仿运维工程师例首倡翻译为“运维器”。)
|
||||
|
||||
我经常将运维器称为“系统管理机器人”,因为它们实质上是在第 2 天的工作中整理出一堆运维知识,该知识涉及<ruby>主题专家<rt>Subject Matter Expert</rt></ruby>(SME、例如数据库管理员或系统管理员)针对的工作负载类型(数据库、Web 服务器等),通常会记录在 Wiki 中的某个地方。这些知识放在 Wiki 中的问题是,为了将该知识应用于解决问题,我们需要:
|
||||
|
||||
1. 生成事件,通常监控系统会发现故障,然后我们创建故障单
|
||||
2. SME 人员必须对此问题进行调查,即使这是我们之前见过几百万次的问题
|
||||
3. SME 人员必须执行该知识(执行备份/还原、配置 Galera 或事务复制等)
|
||||
|
||||
通过运维器,所有这些 SME 知识都可以嵌入到单独的容器镜像中,该镜像在有实际工作负荷之前就已部署。 我们部署运维器容器,然后运维器部署和管理一个或多个工作负载实例。然后,我们使用“运维器生命周期管理器”(Katacoda 教程)之类的方法来管理运维器。
|
||||
|
||||
因此,随着我们进一步使用 Kubernetes,我们不仅简化了应用程序的部署,而且简化了整个生命周期的管理。运维器还为我们提供了工具,可以管理具有深层配置要求(群集、复制、修复、备份/还原)的非常复杂的有状态应用程序。而且,最好的地方是,构建容器的人员可能是做第 2 天运维的主题专家,因此现在他们可以将这些知识嵌入到操作环境中。
|
||||
|
||||
### 本系列的总结
|
||||
|
||||
Kubernetes 的未来是光明的,就像之前的虚拟化一样,工作负载的扩展是不可避免的。学习如何驾驭 Kubernetes 可能是开发人员或系统管理员可以对自己的职业发展做出的最大投资。随着工作负载的增多,职业机会也将增加。因此,这是驾驶一辆令人惊叹的 [在移动垃圾时非常优雅的翻斗车][2]……
|
||||
|
||||
你可能想在 Twitter 上关注我,我在 [@fatherlinux][6] 上分享有关此主题的很多内容。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/19/6/kubernetes-potential-run-anything
|
||||
|
||||
作者:[Scott McCarty][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[wxy](https://github.com/wxy)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/fatherlinux
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/fail_progress_cycle_momentum_arrow.png?itok=q-ZFa_Eh (arrows cycle symbol for failing faster)
|
||||
[2]: https://opensource.com/article/19/6/kubernetes-dump-truck
|
||||
[3]: https://opensource.com/article/19/6/kubernetes-learning-curve
|
||||
[4]: https://opensource.com/article/19/6/kubernetes-basics
|
||||
[5]: https://opensource.com/article/19/6/tools-drive-kubernetes
|
||||
[6]: https://twitter.com/fatherlinux
|
@ -0,0 +1,122 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (wxy)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11608-1.html)
|
||||
[#]: subject: (What you need to know to be a sysadmin)
|
||||
[#]: via: (https://opensource.com/article/19/7/be-a-sysadmin)
|
||||
[#]: author: (Seth Kenlon https://opensource.com/users/seth)
|
||||
|
||||
你需要知道什么才能成为系统管理员?
|
||||
======
|
||||
|
||||
> 通过获得这些起码的能力,开始你的系统管理员职业。
|
||||
|
||||

|
||||
|
||||
昔日的系统管理员整天都在调教用户和摆弄服务器,一天的时间都奔波在几百米长的电缆之间。随着云计算、容器和虚拟机的复杂性的增加,而今依然如此。
|
||||
|
||||
以外行人来看,很难准确确定系统管理员的确切职能,因为他们在许多地方都扮演着一个不起眼的角色。没人能在培训中知道自己工作中所需要的一切知识,但是每个人其实都需要一个坚实的基础。如果你想走上系统管理的道路,那么这是你个人自学或在正式培训中应重点关注的内容。
|
||||
|
||||
### Bash
|
||||
|
||||
当你学习 Bash Shell 时,你学习的不仅是 Bash Shell,你学习的也是 Linux、BSD、MacOS 甚至Windows(在适当条件下)的通用界面。你将了解语法的重要性,因此可以快速适应思科路由器的命令行或微软 PowerShell 等系统,最终你甚至可以学习更强大的语言,如 Python 或 Go。而且,你还会开始进行程序性思考,以便可以分析复杂的问题并将其分解为单个组件,这很关键,因为这就是系统(例如互联网、组织的内部网、Web 服务器、备份解决方案)是如何设计的。
|
||||
|
||||
不止于此,还有更多。
|
||||
|
||||
由于最近 DevOps 和[容器][2]的发展趋势,了解 Bash shell 变得尤为重要。你的系统管理员职业可能会将你带入一个视基础设施为代码的世界,这通常意味着你必须了解脚本编写的基础知识、[基于 YAML][3]配置的结构,以及如何与[容器][5](运行在[沙盒文件][6]内部的微型 Linux 系统)[交互][4]。你会知道 Bash 是高效管理激动人心的开源技术的门户,因此请进入 [Bash][7] 世界吧。
|
||||
|
||||
#### 资源
|
||||
|
||||
有很多方法可以在 Bash shell 中进行练习。
|
||||
|
||||
尝试一下[便携式 Linux 发行版][8]。你无需安装 Linux 即可使用 Linux,因此,请拿一块闲置的 U 盘,花个晚上或周末的空闲时光,来适应基于文本的界面。
|
||||
|
||||
这里有[几篇很棒的][10] [Bash 文章][9]。
|
||||
|
||||
要注意的是 Bash 练习的关键在于要练习,你必须有要做的练习才行。而且,在你知道如何使用 Bash 之前,你可能不知道该练习什么。如果是这样,请去 Over The Wire 玩一下 [Bandit][11] 游戏。这是一款针对绝对初学者的游戏,具有 34 个级别的交互式基本技巧,可让你熟悉 Linux shell。
|
||||
|
||||
### Web 服务器设置
|
||||
|
||||
一旦你习惯了 Bash,你应该尝试设置一个 Web 服务器。并不是所有的系统管理员都会四处设置 Web 服务器甚至维护 Web 服务器,但是你在安装和启动 HTTP 守护程序、配置 Apache 或 Nginx,设置[正确权限][12]和[配置防火墙][13]时所掌握的技能是你每天都需要使用的技能。经过一些努力,你可能会开始注意到自己的某些工作模式。在尝试管理可用于生产环境的软件和硬件之前,你可能认为某些概念是理所当然的,而你在成为新手的管理员角色时,将不再受到它们的影响。起初这可能会令人沮丧,因为每个人都喜欢在自己做好所做的事情,但这实际上是一件好事。让自己接触新技能,那就是你学习的方式。
|
||||
|
||||
此外,你在第一步中付出的努力越多,最终当你在默认的 index.html 上看到胜利的“it works!”就越甜蜜!
|
||||
|
||||
#### 资源
|
||||
|
||||
David Both 撰写了有关 [Apache Web 服务器][14]配置的出色文章。值得一提的是,请逐步阅读他的后续文章,其中介绍了如何在一台计算机上[托管多个站点][15]。
|
||||
|
||||
### DHCP
|
||||
|
||||
动态主机配置协议(DHCP)是为网络上的设备分配 IP 地址的系统。在家里,ISP(互联网服务提供商)支持的调制解调器或路由器可能内置了 DHCP 服务器,因此可能不在你的权限范围内。如果你曾经登录家用路由器来调整 IP 地址范围或为某些网络设备设置了静态地址,那么你至少对该概念有所了解。你可能会将其理解为对网络上的设备分配了一种 IP 地址形式的电话号码,并且你可能会意识到计算机之间通过广播发送到特定 IP 地址的消息彼此进行通信。消息标头由路径上的路由器读取,每个消息标头都将消息定向到路径上的第二个逻辑路由器,以达到其最终目标。
|
||||
|
||||
即使你了解了这些概念,要从对 DHCP 的基本了解再进一步是架设 DHCP 服务器。安装和配置自己的 DHCP 服务器可能会导致家庭网络中的 DHCP 冲突(如果可以的话,请尽量避免这样做,因为它肯定会干掉你的网络,直到解决为止),要控制地址的分配、创建子网,并监控连接和租赁时间。
|
||||
|
||||
更重要的是,设置 DHCP 并尝试不同的配置有助于你了解网络之间的关系。你会了解网络如何在数据传输中表示“分区”,以及必须采取哪些步骤才能将信息从一个网络传递到另一个。这对于系统管理员来说至关重要,因为网络肯定是工作中最重要的方面之一。
|
||||
|
||||
#### 资源
|
||||
|
||||
在运行自己的 DHCP 服务器之前,请确保家庭路由器(如果有)中的 DHCP 服务器处于非活动状态。一旦启动并运行了 DHCP 服务器,请阅读 Archit Modi 的[网络命令指南][16],以获取有关如何探索网络的提示。
|
||||
|
||||
### 网络电缆
|
||||
|
||||
这听起来很普通,但是熟悉网络电缆的工作方式不仅使你的周末变得非常有趣,而且还使你对数据是如何通过缆线的得到了全新的了解。最好的学习方法是去当地的业余爱好商店并购买五类线剥线钳和压线钳以及一些五类线水晶头。然后回家,拿一根备用的以太网电缆,切断水晶头,花一些时间重新制作网线接头,将电缆重新投入使用。
|
||||
|
||||
解决了这个难题后,请再做一次,这次创建一条有效的[交叉电缆][17]。
|
||||
|
||||
你现在应该还在沉迷于有关电缆管理。如果你有些强迫症,喜欢沿着地板线或桌子的边缘整齐地排列电缆,或者将电缆绑在一起以保持它们的整齐有序,那么就可以使自己免受永久混乱的电缆困扰。你一开始可能不会理解这样做的必要性,但是当你第一次走进服务器机房时,你会马上知道原因。
|
||||
|
||||
### Ansible
|
||||
|
||||
[Ansible][18] 是配置管理软件,它在系统管理员和 DevOps 之间架起了一座桥梁。系统管理员使用 Ansible 来配置全新安装的操作系统并在计算机上维护特定的状态。DevOps 使用 Ansible 减少了在工具上花费的时间和精力,从而在开发上可以花费更多的时间和精力。作为系统管理员培训的一部分,你应该学习 Ansible,并着眼于 DevOps 实践,因为 DevOps 现在开创的大多数功能将最终成为将来系统管理中工作流的一部分。
|
||||
|
||||
Ansible 的好处是你可以立即开始使用它。它是跨平台的,并且可以向上和向下缩放。对于单用户计算机, Ansible 可能是小题大做,但是话又说回来,Ansible 可能会改变你启动虚拟机的方式,或者可以帮助你同步家庭或[家庭实验室][19]中所有计算机的状态。
|
||||
|
||||
|
||||
#### 资源
|
||||
|
||||
阅读 Jay LaCroix 的[如何使用 Ansible 管理工作站配置][20]中的典型介绍,以轻松地在日常之中开始使用 Ansible。
|
||||
|
||||
### 破坏
|
||||
|
||||
由于用户的错误、软件的错误、管理员(就是你!)的错误以及许多其他因素,计算机上会出现问题。无法预测将要失败的原因,因此你的个人系统管理员培训制度的一部分应该是破坏你设置的系统,直到它们失败为止。你自己的实验室基础设施越是脆弱,发现弱点的可能性就越大。而且,你越是经常修复这些弱点,你对解决问题的能力就越有信心。
|
||||
|
||||
除了严格设置所有常见的软件和硬件之外,作为系统管理员的主要工作是查找解决方案。有时候,你可能会遇到职位描述之外的问题,甚至可能无法解决,但这完全取决于你的解决方法。
|
||||
|
||||
现在,你越多地折腾并努力加以解决,则以系统管理员的身份进行的准备就越充分。
|
||||
|
||||
你是系统管理员吗?你是否希望自己为更好的任务做好准备?在下面的评论中写下它们!
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/19/7/be-a-sysadmin
|
||||
|
||||
作者:[Seth Kenlon][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[wxy](https://github.com/wxy)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [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/rh_003499_01_linux11x_cc.png?itok=XMDOouJR (People work on a computer server with devices)
|
||||
[2]: https://opensource.com/article/19/6/kubernetes-dump-truck
|
||||
[3]: https://www.redhat.com/sysadmin/yaml-tips
|
||||
[4]: https://opensource.com/article/19/6/how-ssh-running-container
|
||||
[5]: https://opensource.com/resources/what-are-linux-containers
|
||||
[6]: https://opensource.com/article/18/11/behind-scenes-linux-containers
|
||||
[7]: https://opensource.com/article/18/7/admin-guide-bash
|
||||
[8]: https://opensource.com/article/19/6/linux-distros-to-try
|
||||
[9]: https://opensource.com/tags/bash
|
||||
[10]: https://www.redhat.com/sysadmin/managing-files-linux-terminal
|
||||
[11]: http://overthewire.org/wargames/bandit
|
||||
[12]: https://opensource.com/article/19/6/understanding-linux-permissions
|
||||
[13]: https://www.redhat.com/sysadmin/secure-linux-network-firewall-cmd
|
||||
[14]: https://opensource.com/article/18/2/how-configure-apache-web-server
|
||||
[15]: https://opensource.com/article/18/3/configuring-multiple-web-sites-apache
|
||||
[16]: https://opensource.com/article/18/7/sysadmin-guide-networking-commands
|
||||
[17]: https://en.wikipedia.org/wiki/Ethernet_crossover_cable
|
||||
[18]: https://opensource.com/sitewide-search?search_api_views_fulltext=ansible
|
||||
[19]: https://opensource.com/article/19/6/create-centos-homelab-hour
|
||||
[20]: https://opensource.com/article/18/3/manage-workstation-ansible
|
@ -1,8 +1,8 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (wxy)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11553-1.html)
|
||||
[#]: subject: (Linux permissions 101)
|
||||
[#]: via: (https://opensource.com/article/19/8/linux-permissions-101)
|
||||
[#]: author: (Alex Juarez https://opensource.com/users/mralexjuarezhttps://opensource.com/users/marcobravohttps://opensource.com/users/greg-p)
|
||||
@ -12,11 +12,11 @@
|
||||
|
||||
> 知道如何控制用户对文件的访问是一项基本的系统管理技能。
|
||||
|
||||
![Penguins][1]
|
||||

|
||||
|
||||
了解 Linux 权限以及如何控制哪些用户可以访问文件是系统管理的一项基本技能。
|
||||
|
||||
本文将介绍标准 Linux 文件系统权限,并进一步研究特殊权限,以及使用 `umask` 解释默认权限的出处。
|
||||
本文将介绍标准 Linux 文件系统权限,并进一步研究特殊权限,以及使用 `umask` 来解释默认权限作为文章的结束。
|
||||
|
||||
### 理解 ls 命令的输出
|
||||
|
||||
@ -61,7 +61,7 @@ drwxrwxrwx. 2 root root 4.0K Mar 4 20:04 testdir
|
||||
* 组
|
||||
* 所有其他人
|
||||
|
||||
第 2、3 和 4 节涉及用户、组和“其他用户”权限。每个部分都可以包含 `r`(读)、`w`(写)和 `x`(可执行)权限的组合。
|
||||
第 2、3 和 4 节涉及用户(属主)、组和“其他用户”权限。每个部分都可以包含 `r`(读取)、`w`(写入)和 `x`(执行)权限的组合。
|
||||
|
||||
每个权限还分配了一个数值,这在以八进制表示形式讨论权限时很重要。
|
||||
|
||||
@ -71,7 +71,7 @@ drwxrwxrwx. 2 root root 4.0K Mar 4 20:04 testdir
|
||||
`w` | 2
|
||||
`x` | 1
|
||||
|
||||
第 5 节描述了其他访问方法,例如 SELinux 或文件访问控制列表(FACL)。
|
||||
第 5 节描述了其他替代访问方法,例如 SELinux 或文件访问控制列表(FACL)。
|
||||
|
||||
访问方法 | 字符
|
||||
---|---
|
||||
@ -95,7 +95,7 @@ $ chown root:root foo
|
||||
$ chown root: foo
|
||||
```
|
||||
|
||||
在用户后跟冒号(`:`)运行该命令将同时设置用户和组所有权。
|
||||
在用户名后跟冒号(`:`)运行该命令将同时设置用户和组所有权。
|
||||
|
||||
要仅将文件 `foo` 的用户所有权设置为 `root` 用户,请输入:
|
||||
|
||||
@ -115,9 +115,9 @@ $ chown :root foo
|
||||
|
||||
`chmod` 命令可以以八进制(例如 `755`、`644` 等)和符号(例如 `u+rwx`、`g-rwx`、`o=rw`)格式设置权限。
|
||||
|
||||
八进制表示法将 4 个“点”分配给“读取”,将 2 个“点”分配给“写入”,将 1 个点分配给“执行”。如果要给用户(属主)分配“读”权限,则将 4 分配给第一个插槽,但是如果要添加“写”权限,则必须添加 2。如果要添加“执行”,则要添加 1。我们对每种权限类型执行此操作:属主、组和其他。
|
||||
八进制表示法将 4 个“点”分配给“读取”,将 2 个“点”分配给“写入”,将 1 个点分配给“执行”。如果要给用户(属主)分配“读取”权限,则将 4 分配给第一个插槽,但是如果要添加“写入”权限,则必须添加 2。如果要添加“执行”,则要添加 1。我们对每种权限类型执行此操作:属主、组和其他。
|
||||
|
||||
例如,如果我们想将 “读取”、“写入”和“执行”分配给文件的属主,但仅将“读取”和“执行”分配给组成员和所有其他用户,则我们应使用 `755`(八进制格式)。这是属主的所有权限位(`4 + 2 + 1`),但组和其他权限的所有权限位只有 `4` 和 `1`(`4 + 1`)。
|
||||
例如,如果我们想将“读取”、“写入”和“执行”分配给文件的属主,但仅将“读取”和“执行”分配给组成员和所有其他用户,则我们应使用 `755`(八进制格式)。这是属主的所有权限位(`4+2+1`),但组和其他权限的所有权限位只有 `4` 和 `1`(`4+1`)。
|
||||
|
||||
> 细分为:4+2+1=7,4+1=5 和 4+1=5。
|
||||
|
||||
@ -149,11 +149,11 @@ $ chmod o=rw
|
||||
|
||||
### 特殊位:设置 UID、设置 GID 和粘滞位
|
||||
|
||||
除了标准权限外,还有一些特殊的权限位,它们具有一些有用的好处。
|
||||
除了标准权限外,还有一些特殊的权限位,它们具有一些别的用处。
|
||||
|
||||
#### 设置用户 ID(suid)
|
||||
|
||||
当在文件上设置 `suid` 时,将以文件的属主的身份而不是运行该文件的用户身份执行操作。一个[好例子][3]是 `passwd` 命令。它需要设置 `suid` 位,以便更改密码的操作具有 root 权限。
|
||||
当在文件上设置 `suid` 时,将以文件的属主的身份而不是运行该文件的用户身份执行操作。一个[好的例子][3]是 `passwd` 命令。它需要设置 `suid` 位,以便更改密码的操作具有 root 权限。
|
||||
|
||||
```
|
||||
$ ls -l /bin/passwd
|
||||
@ -168,7 +168,7 @@ $ chmod u+s /bin/foo_file_name
|
||||
|
||||
#### 设置组 ID(sgid)
|
||||
|
||||
`sgid` 位与 `suid` 位类似,因为操作是在目录的组所有权下完成的,而不是以运行命令的用户身份。
|
||||
`sgid` 位与 `suid` 位类似,操作是在目录的组所有权下完成的,而不是以运行命令的用户身份。
|
||||
|
||||
一个使用 `sgid` 的例子是,如果多个用户正在同一个目录中工作,并且目录中创建的每个文件都需要具有相同的组权限。下面的示例创建一个名为 `collab_dir` 的目录,设置 `sgid` 位,并将组所有权更改为 `webdev`。
|
||||
|
||||
@ -189,14 +189,14 @@ $ ls -lah file-sgid
|
||||
|
||||
#### “粘滞”位
|
||||
|
||||
粘滞位表示只有文件所有者才能删除该文件,即使组权限也允许该文件可以删除。通常,在 `/tmp` 这样的通用或协作目录上,此设置最有意义。在下面的示例中,“所有其他人”权限集的“执行”列中的 `t` 表示已应用粘滞位。
|
||||
粘滞位表示,只有文件所有者才能删除该文件,即使组权限允许该文件可以删除。通常,在 `/tmp` 这样的通用或协作目录上,此设置最有意义。在下面的示例中,“所有其他人”权限集的“执行”列中的 `t` 表示已应用粘滞位。
|
||||
|
||||
```
|
||||
$ ls -ld /tmp
|
||||
drwxrwxrwt. 8 root root 4096 Jun 12 06:07 /tmp/
|
||||
```
|
||||
|
||||
请记住,这不会阻止某个人编辑该文件,它只是阻止他们删除该目录的内容。
|
||||
请记住,这不会阻止某个人编辑该文件,它只是阻止他们删除该目录的内容(LCTT 译注:即删除目录下文件)。
|
||||
|
||||
我们将粘滞位设置为:
|
||||
|
||||
@ -220,7 +220,7 @@ $ chmod 1755
|
||||
|
||||
#### 大写还是小写?
|
||||
|
||||
如果要设置特殊位并看到大写的 `S` 或 `T` 而不是小写的字符(如我们之前所见),那是因为不存在(对应的)底层的执行位。为了说明这一点,下面的示例创建一个设置了粘滞位的文件。然后,我们可以添加和删除执行位以演示大小写更改。
|
||||
如果要设置特殊位时看到大写的 `S` 或 `T` 而不是小写的字符(如我们之前所见),那是因为不存在(对应的)底层的执行位。为了说明这一点,下面的示例创建一个设置了粘滞位的文件。然后,我们可以添加和删除执行位以演示大小写更改。
|
||||
|
||||
```
|
||||
$ touch file cap-ST-demo
|
||||
@ -262,7 +262,7 @@ ls -l cap-X-file
|
||||
|
||||
### 理解 umask
|
||||
|
||||
`umask 会屏蔽(或“阻止”)默认权限集中的位,以定义文件或目录的权限。例如,`umask`输出中的 `2` 表示它至少在默认情况下阻止了文件的写入位。
|
||||
`umask` 会屏蔽(或“阻止”)默认权限集中的位,以定义文件或目录的权限。例如,`umask`输出中的 `2` 表示它至少在默认情况下阻止了文件的“写入”位。
|
||||
|
||||
使用不带任何参数的 `umask` 命令可以使我们看到当前的 `umask` 设置。共有四列:第一列为特殊的`suid`、`sgid` 或粘滞位而保留,其余三列代表属主、组和其他人的权限。
|
||||
|
||||
@ -271,7 +271,7 @@ $ umask
|
||||
0022
|
||||
```
|
||||
|
||||
为了理解这意味着什么,我们可以用 `-S` 标志来执行 `umask`(如下所示)以了解屏蔽位的结果。例如,由于第三列中的值为 `2`,因此将“写入”位从组和其他部分中屏蔽掉了;只能为它们分配“读取”和“执行”。
|
||||
为了理解这意味着什么,我们可以用 `-S` 标志来执行 `umask`(如下所示)以解释屏蔽位的结果。例如,由于第三列中的值为 `2`,因此将“写入”位从组和其他部分中屏蔽掉了;只能为它们分配“读取”和“执行”。
|
||||
|
||||
```
|
||||
$ umask -S
|
||||
@ -302,7 +302,7 @@ drwxrwxrwx. 2 root root 4096 Jul 17 22:03 dir-umask-000/
|
||||
|
||||
### 总结
|
||||
|
||||
管理员还有许多其他方法可以控制对系统文件的访问。这些权限是 Linux 的基本权限,我们可以在这些基础上进行构建。如果你的工作将你带入 FACL 或 SELinux,你会发现它们也建立在这些文件访问的首要规则之上。
|
||||
管理员还有许多其他方法可以控制对系统文件的访问。这些权限是 Linux 的基本权限,我们可以在这些基础上进行构建。如果你的工作为你引入了 FACL 或 SELinux,你会发现它们也建立在这些文件访问的首要规则之上。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
@ -1,8 +1,8 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (wxy)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11556-1.html)
|
||||
[#]: subject: (11 Essential Keyboard Shortcuts Google Chrome/Chromium Users Should Know)
|
||||
[#]: via: (https://itsfoss.com/google-chrome-shortcuts/)
|
||||
[#]: author: (Abhishek Prakash https://itsfoss.com/author/abhishek/)
|
||||
@ -12,6 +12,8 @@ Chrome/Chromium 用户必知必会的 11 个基本快捷键
|
||||
|
||||
> 掌握这些 Google Chrome 键盘快捷键,以获得更好、更流畅、更高效的 Web 浏览体验。还包括可下载的备忘单。
|
||||
|
||||

|
||||
|
||||
无可否认,Google Chrome 是[最受欢迎的网络浏览器][1]。它的开源版本 [Chromium][2] 也越来越受欢迎,现在一些 Linux 发行版将其作为默认的网络浏览器。
|
||||
|
||||
如果你经常在台式机上使用它,则可以使用 Google Chrome 键盘快捷键来改善浏览体验。没有必要用你的鼠标移来移去、点来点去。只要掌握这些快捷方式,你可以节省一些时间并提高工作效率。
|
||||
@ -20,7 +22,7 @@ Chrome/Chromium 用户必知必会的 11 个基本快捷键
|
||||
|
||||
### 你应该使用的 11 个酷炫的 Chrome 键盘快捷键
|
||||
|
||||
如果你是专业人士,则可能已经知道其中一些 Chrome 快捷方式,但是有可能你仍然可以在这里找到一些隐藏的宝石。让我们来看看。
|
||||
如果你是专业人士,可能已经知道其中一些 Chrome 快捷方式,但是有可能你仍然可以在这里找到一些隐藏的宝石。让我们来看看。
|
||||
|
||||
**键盘快捷键** | **动作**
|
||||
---|---
|
||||
@ -41,7 +43,7 @@ Chrome/Chromium 用户必知必会的 11 个基本快捷键
|
||||
|
||||
#### 1、用 `Ctrl+T` 打开一个新标签页
|
||||
|
||||
需要打开一个新标签页吗?只需同时按 `Ctrl 和 `T`键,你就会打开一个新标签。
|
||||
需要打开一个新标签页吗?只需同时按 `Ctrl` 和 `T` 键,你就会打开一个新标签。
|
||||
|
||||
#### 2、使用 `Ctrl+N` 打开一个新窗口
|
||||
|
||||
@ -49,7 +51,7 @@ Chrome/Chromium 用户必知必会的 11 个基本快捷键
|
||||
|
||||
#### 3、使用 `Ctrl+Shift+N` 隐身
|
||||
|
||||
在线查询航班或酒店价格?隐身可能会有所帮助。使用 `Ctrl+Shift+N`在 Chrome 中打开一个隐身窗口。
|
||||
在线查询航班或酒店价格?隐身可能会有所帮助。使用 `Ctrl+Shift+N` 在 Chrome 中打开一个隐身窗口。
|
||||
|
||||
#### 4、使用 `Ctrl+W` 关闭标签页
|
||||
|
||||
@ -65,13 +67,13 @@ Chrome/Chromium 用户必知必会的 11 个基本快捷键
|
||||
|
||||
#### 7、使用 `Ctrl+Tab` 在标签之间切换
|
||||
|
||||
打开的标签页太多了吗?你可以使用 `Ctrl+Tab` 移至右侧标签页。想左移吗?使用 `Ctrl+Shift+Tab`。 重复按这些键,你可以在当前浏览器窗口的所有打开的标签页之间移动。
|
||||
打开的标签页太多了吗?你可以使用 `Ctrl+Tab` 移至右侧标签页。想左移吗?使用 `Ctrl+Shift+Tab`。重复按这些键,你可以在当前浏览器窗口的所有打开的标签页之间移动。
|
||||
|
||||
你也可以使用 `Ctrl+0` 直到 `Ctrl+9` 转到前 10 个标签页之一。但是此 Chrome 键盘快捷键不适用于第 11 个及更多标签页。
|
||||
|
||||
#### 8、使用 `Ctrl+L` 转到搜索/地址栏
|
||||
|
||||
想要输入新的 URL 或快速搜索一些内容。你可以使用 `Ctrl+L,它将在顶部突出显示地址栏。
|
||||
想要输入新的 URL 或快速搜索一些内容。你可以使用 `Ctrl+L`,它将在顶部突出显示地址栏。
|
||||
|
||||
#### 9、用 `Ctrl+D` 收藏当前网站
|
||||
|
||||
@ -112,7 +114,7 @@ via: https://itsfoss.com/google-chrome-shortcuts/
|
||||
作者:[Abhishek Prakash][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[wxy](https://github.com/wxy)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
@ -0,0 +1,214 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (robsean)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11554-1.html)
|
||||
[#]: subject: (6 Open Source Paint Applications for Linux Users)
|
||||
[#]: via: (https://itsfoss.com/open-source-paint-apps/)
|
||||
[#]: author: (Ankush Das https://itsfoss.com/author/ankush/)
|
||||
|
||||
6 款面向 Linux 用户的开源绘图应用程序
|
||||
======
|
||||
|
||||
小时候,当我开始使用计算机(在 Windows XP 中)时,我最喜欢的应用程序是微软的“画图”。我能在它上面涂鸦数个小时。出乎意料,孩子们仍然喜欢这个“画图”应用程序。不仅仅是孩子们,这个简单的“画图”应用程序,在很多情况下都能派上用场。
|
||||
|
||||
你可以找到一堆可以让你绘制/绘图或操作图片的应用程序。然而,其中一些是专有软件。既然你是一名 Linux 用户,为什么不关注一下开源绘图应用程序呢?
|
||||
|
||||
在这篇文章中,我们将列出一些最好的开源绘图应用程序,它们可以替代可用于 Linux 的专有绘画软件。
|
||||
|
||||
### 开源绘图 & 绘制应用程序
|
||||
|
||||
![][1]
|
||||
|
||||
**注意:** 该列表没有特别的排名顺序。
|
||||
|
||||
#### 1、Pinta
|
||||
|
||||
![][2]
|
||||
|
||||
主要亮点:
|
||||
|
||||
* Paint.NET / 微软“画图”的极好替代品
|
||||
* 支持附加组件(有对 WebP 图像的支持)
|
||||
* 支持图层
|
||||
|
||||
[Pinta][3] 是一款令人赞叹的开源绘图应用程序,非常适合绘图和简单的图片编辑。换句话说,它是一款具有精美功能的简单绘图应用程序。
|
||||
|
||||
你可以将 [Pinta][4] 视为 Linux 上的“画图”的一个替代品,但是带有图层支持等等。不仅仅是“画图”,它也可以替代 Windows 上的 Paint.NET。尽管 Paint.NET 更好一些,但 Pinta 似乎是个不错的选择。
|
||||
|
||||
几个附加组件可以用于增强功能,例如[在 Linux 上支持 WebP 图像][5]。除了图层支持之外,你还可以轻松地调整图片大小、添加特效、进行调整(亮度、对比度等等),以及在导出图片时调整其质量。
|
||||
|
||||
##### 如何安装 Pinta ?
|
||||
|
||||
你应该能够在软件中心/应用程序中心/软件包管理器中简单地找到它。只需要输入 “Pinta”,并开始安装它。要么也可以尝试 [Flatpak][6] 软件包。
|
||||
|
||||
或者,你可以在终端中输入下面的命令(Ubuntu/Debian):
|
||||
|
||||
```
|
||||
sudo apt install pinta
|
||||
```
|
||||
|
||||
下载软件包和安装指南的更多信息,参考[官方下载页面][7]。
|
||||
|
||||
#### 2、Krita
|
||||
|
||||
![][8]
|
||||
|
||||
主要亮点:
|
||||
|
||||
* HDR 绘图
|
||||
* 支持 PSD
|
||||
* 支持图层
|
||||
* 笔刷稳定器
|
||||
* 二维动画
|
||||
|
||||
Krita 是 Linux 上最高级的开源绘图应用程序之一。当然,对于本文而言,它可以帮助你绘制草图和在画布上胡写乱画。除此之外,它还提供很多功能。
|
||||
|
||||
例如,如果你的手有点颤抖,它可以帮助你稳定笔刷的笔划。你可以使用内置的矢量工具来创建漫画画板和其它有趣的东西。如果你正在寻找具有全面的颜色管理支持、绘图助理和图层管理的软件,Krita 应该是你最好的选择。
|
||||
|
||||
##### 如何安装 Krita ?
|
||||
|
||||
类似于 pinta,你可以在软件中心/应用程序中心或软件包管理器的列表中找到它。它也可以 [Flatpak 存储库][10]中找到。
|
||||
|
||||
考虑通过终端安装它?输入下面的命令:
|
||||
|
||||
```
|
||||
sudo apt install krita
|
||||
```
|
||||
|
||||
要么你也可以前往它们的[官方下载页面][11]来获取 AppImage 文件并运行它。
|
||||
|
||||
如果你对 AppImage 文件一无所知,查看我们的指南 —— [如何使用 AppImage][12]。
|
||||
|
||||
#### 3、Tux Paint
|
||||
|
||||
![][13]
|
||||
|
||||
主要亮点:
|
||||
|
||||
* 给儿童用的一个简单直接的绘图应用程序
|
||||
|
||||
我不是开玩笑,对于 3-12 岁儿童来说,Tux Paint 是最好的开源绘图应用程序之一。当然,当你只想乱画时,那无需选择,所以,在这种情况下,Tux Paint 似乎是最好的选择(即使是成年人!)。
|
||||
|
||||
##### 如何安装 Tuxpaint ?
|
||||
|
||||
Tuxpaint 可以从软件中心或软件包管理器下载。无论哪种情况,在 Ubuntu/Debian 上安装它,在终端中输入下面的命令:
|
||||
|
||||
```
|
||||
sudo apt install tuxpaint
|
||||
```
|
||||
|
||||
关于它的更多信息,前往[官方站点][14]。
|
||||
|
||||
#### 4、Drawpile
|
||||
|
||||
![][15]
|
||||
|
||||
主要亮点:
|
||||
|
||||
* 协同绘制
|
||||
* 内置聊天功能,可与其他用户互动
|
||||
* 图层支持
|
||||
* 记录绘制会话
|
||||
|
||||
Drawpile 是一个有趣的开源绘图应用程序,在该程序中,你可以与其他用户实时协作。确切地说,你们可以单个画布中同时绘制。除了这个独特的功能,它还有图层支持、记录绘制会话的能力,甚至还有与协作用户进行交互的聊天功能。
|
||||
|
||||
你可以主持或加入一个公共会话,或通过一个密码与你的朋友建立私有会话。默认情况下,服务器将是你的计算机,但是如果你需要远程服务器那也可以。
|
||||
|
||||
注意,你将需要[注册一个 Drawpile 账户][16] 才能进行协作。
|
||||
|
||||
##### 如何安装 Drawpile ?
|
||||
|
||||
据我所知,你只能在 [Flatpak 存储库][17]的列表中找到它。
|
||||
|
||||
#### 5、MyPaint
|
||||
|
||||
![][19]
|
||||
|
||||
主要亮点:
|
||||
|
||||
* 易用的数码画家工具
|
||||
* 支持图层管理
|
||||
* 很多微调你的画笔和绘制的选项
|
||||
|
||||
对于数码画家来说,[MyPaint][20] 是一个简单而强大的工具。它具有许多选项,可以调整以制作出完美的数字画笔笔触。我不是一个数字艺术家(但我是一个涂鸦者),但是我注意到有很多调整笔刷、颜色的选项,和一个添加中间结果暂存器面板的选项。
|
||||
|
||||
它也支持图层管理,也许你需要它。最新的稳定版本已经有几年没有更新了,但是当前的 alpha 构建版本(我测试过)运行良好。如果你正在 Linux 上寻找一个开源绘图应用程序 —— 试试这个。
|
||||
|
||||
##### 如何安装 MyPaint ?
|
||||
|
||||
MyPaint 可在官方存储库中获得。然而,这是老旧的版本。如果你仍然想继续,你可以在软件中心搜索它,或在终端中输入下面的命令:
|
||||
|
||||
```
|
||||
sudo apt install mypaint
|
||||
```
|
||||
|
||||
你可以前往它的官方 [GitHub 发布页面][21]获取最新的 alpha 构建版本,获取 [AppImage 文件][12](任意版本)并使它可执行并启动应用程序。
|
||||
|
||||
#### 6、KolourPaint
|
||||
|
||||
![][22]
|
||||
|
||||
主要亮点:
|
||||
|
||||
* 一个 Linux 上的“画图”的简单替代品
|
||||
* 不支持图层管理
|
||||
|
||||
如果你不需要任何图层管理的支持,而只是想要一个开源绘图应用程序来绘制东西 —— 那就是它了。
|
||||
|
||||
[KolourPaint][23] 最初是为 KDE 桌面环境定制的,但是它在其它的桌面环境中也能完美地工作。
|
||||
|
||||
##### 如何安装 KolourPaint ?
|
||||
|
||||
你可以从软件中心安装 KolourPaint,或通过终端使用下面的命令:
|
||||
|
||||
```
|
||||
sudo apt install kolourpaint4
|
||||
```
|
||||
|
||||
你总可以试试 [Flathub][24]。
|
||||
|
||||
### 总结
|
||||
|
||||
如果你在考虑如 GIMP/Inkscape 这样的应用程序,我们在另一篇关于[给数码艺术家的最好 Linux 工具][25]的文章中列出。如果你对更多的选择好奇,我建议你去查看它。
|
||||
|
||||
在这里,我们尝试编写一份 Linux 可用的最佳开源绘图应用程序列表。如果你认为我们错过一些东西,请在下面的评论区告诉我们!
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://itsfoss.com/open-source-paint-apps/
|
||||
|
||||
作者:[Ankush Das][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[robsean](https://github.com/robsean)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://itsfoss.com/author/ankush/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2019/09/open-source-paint-apps.png?resize=800%2C450&ssl=1
|
||||
[2]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2019/09/pinta.png?ssl=1
|
||||
[3]: https://pinta-project.com/pintaproject/pinta/
|
||||
[4]: https://itsfoss.com/pinta-1-6-ubuntu-linux-mint/
|
||||
[5]: https://itsfoss.com/webp-ubuntu-linux/
|
||||
[6]: https://www.flathub.org/apps/details/com.github.PintaProject.Pinta
|
||||
[7]: https://pinta-project.com/pintaproject/pinta/releases
|
||||
[8]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2019/09/krita-paint.png?ssl=1
|
||||
[9]: https://itsfoss.com/things-to-do-after-installing-fedora-24/
|
||||
[10]: https://www.flathub.org/apps/details/org.kde.krita
|
||||
[11]: https://krita.org/en/download/krita-desktop/
|
||||
[12]: https://itsfoss.com/use-appimage-linux/
|
||||
[13]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2019/09/tux-paint.jpg?ssl=1
|
||||
[14]: http://www.tuxpaint.org/
|
||||
[15]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2019/09/drawpile.png?ssl=1
|
||||
[16]: https://drawpile.net/accounts/signup/
|
||||
[17]: https://flathub.org/apps/details/net.drawpile.drawpile
|
||||
[18]: https://itsfoss.com/ocs-store/
|
||||
[19]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2019/09/mypaint.png?ssl=1
|
||||
[20]: https://mypaint.org/
|
||||
[21]: https://github.com/mypaint/mypaint/releases
|
||||
[22]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2019/09/kolourpaint.png?ssl=1
|
||||
[23]: http://kolourpaint.org/
|
||||
[24]: https://flathub.org/apps/details/org.kde.kolourpaint
|
||||
[25]: https://itsfoss.com/best-linux-graphic-design-software/
|
@ -0,0 +1,194 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (MjSeven)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11590-1.html)
|
||||
[#]: subject: (How to fix common pitfalls with the Python ORM tool SQLAlchemy)
|
||||
[#]: via: (https://opensource.com/article/19/9/common-pitfalls-python)
|
||||
[#]: author: (Zach Todd https://opensource.com/users/zchtoddhttps://opensource.com/users/lauren-pritchetthttps://opensource.com/users/liranhaimovitchhttps://opensource.com/users/moshez)
|
||||
|
||||
如何修复使用 Python ORM 工具 SQLAlchemy 时的常见陷阱
|
||||
======
|
||||
|
||||
> 在使用 SQLAlchemy 时,那些看似很小的选择可能对这种对象关系映射工具包的性能产生重要影响。
|
||||
|
||||
![A python with a package.][1]
|
||||
|
||||
<ruby>对象关系映射<rt>Object-relational mapping</rt></ruby>([ORM][2])使应用程序开发人员的工作更轻松,在很大程度是因为它允许你使用你可能知道的语言(例如 Python)与数据库交互,而不是使用原始 SQL 语句查询。[SQLAlchemy][3] 是一个 Python ORM 工具包,它提供使用 Python 访问 SQL 数据库的功能。它是一个成熟的 ORM 工具,增加了模型关系、强大的查询构造范式、简单的序列化等优点。然而,它的易用性使得人们很容易忘记其背后发生了什么。使用 SQLAlchemy 时做出的看似很小的选择可能产生非常大的性能影响。
|
||||
|
||||
本文解释了开发人员在使用 SQLAlchemy 时遇到的一些最重要的性能问题,以及如何解决这些问题。
|
||||
|
||||
### 只需要计数但检索整个结果集
|
||||
|
||||
有时开发人员只需要一个结果计数,但是没有使用数据库计数功能,而是获取了所有结果,然后使用 Python 中的 `len` 完成计数。
|
||||
|
||||
```
|
||||
count = len(User.query.filter_by(acct_active=True).all())
|
||||
```
|
||||
|
||||
相反,使用 SQLAlchemy 的 `count` 方法将在服务器端执行计数,从而减少发送到客户端的数据。在前面的例子中调用 `all()` 也会导致模型对象的实例化,如果有很多数据,那么时间代价可能会非常昂贵。
|
||||
|
||||
除非还需要做其他的事情,否则只需使用 `count` 方法:
|
||||
|
||||
```
|
||||
count = User.query.filter_by(acct_active=True).count()
|
||||
```
|
||||
|
||||
### 只需要几列时检索整个模型
|
||||
|
||||
在许多情况下,发出查询时只需要几列数据。SQLAlchemy 可以只获取你想要的列,而不是返回整个模型实例。这不仅减少了发送的数据量,还避免了实例化整个对象。使用列数据的元组而不是模型可以快得多。
|
||||
|
||||
```
|
||||
result = User.query.all()
|
||||
for user in result:
|
||||
print(user.name, user.email)
|
||||
```
|
||||
|
||||
反之,使用 `with_entities` 方法只选择所需要的内容:
|
||||
|
||||
```
|
||||
result = User.query.with_entities(User.name, User.email).all()
|
||||
for (username, email) in result:
|
||||
print(username, email)
|
||||
```
|
||||
|
||||
### 每次循环都更新一个对象
|
||||
|
||||
避免使用循环来单独更新集合。虽然数据库可以非常快地执行单个更新,但应用程序和数据库服务器之间的往返时间将快速累加。通常,在合理的情况下争取更少的查询。
|
||||
|
||||
```
|
||||
for user in users_to_update:
|
||||
user.acct_active = True
|
||||
db.session.add(user)
|
||||
```
|
||||
|
||||
改用批量更新方法:
|
||||
|
||||
```
|
||||
query = User.query.filter(user.id.in_([user.id for user in users_to_update]))
|
||||
query.update({"acct_active": True}, synchronize_session=False)
|
||||
```
|
||||
|
||||
### 触发级联删除
|
||||
|
||||
ORM 允许在模型关系上进行简单的配置,但是有一些微妙的行为可能会令人吃惊。大多数数据库通过外键和各种级联选项维护关系完整性。SQLAlchemy 允许你使用外键和级联选项定义模型,但是 ORM 具有自己的级联逻辑,可以取代数据库。
|
||||
|
||||
考虑以下模型:
|
||||
|
||||
```
|
||||
class Artist(Base):
|
||||
__tablename__ = "artist"
|
||||
|
||||
id = Column(Integer, primary_key=True)
|
||||
songs = relationship("Song", cascade="all, delete")
|
||||
|
||||
|
||||
class Song(Base):
|
||||
__tablename__ = "song"
|
||||
|
||||
id = Column(Integer, primary_key=True)
|
||||
artist_id = Column(Integer, ForeignKey("artist.id", ondelete="CASCADE"))
|
||||
```
|
||||
|
||||
删除歌手将导致 ORM 在 `song` 表上发出 `delete` 查询,从而防止由于外键导致的删除操作。这种行为可能会成为复杂关系和大量记录的瓶颈。
|
||||
|
||||
请包含 `passive_deletes` 选项,以确保让数据库来管理关系。但是,请确保你的数据库具有此功能。例如,SQLite 默认情况下不管理外键。
|
||||
|
||||
```
|
||||
songs = relationship("Song", cascade all, delete", passive_deletes=True)
|
||||
```
|
||||
|
||||
### 当要使用贪婪加载时,应使用延迟加载
|
||||
|
||||
延迟加载是 SQLAlchemy 处理关系的默认方法。从上一个例子构建来看,加载一个歌手时不会同时加载他或她的歌曲。这通常是一个好主意,但是如果总是需要加载某些关系,单独的查询可能会造成浪费。
|
||||
|
||||
如果允许以延迟方式加载关系,像 [Marshmallow][4] 这样流行的序列化框架可以触发级联查询。
|
||||
|
||||
有几种方法可以控制此行为。最简单的方法是通过 relationship 函数本身。
|
||||
|
||||
```
|
||||
songs = relationship("Song", lazy="joined", cascade="all, delete")
|
||||
```
|
||||
|
||||
这将导致一个左连接被添加到任何歌手的查询中,因此,`songs` 集合将立即可用。尽管有更多数据返回给客户端,但往返次数可能会少得多。
|
||||
|
||||
SQLAlchemy 为无法采用这种综合方法的情况提供了更细粒度的控制,可以使用 `joinedload()` 函数在每个查询的基础上切换连接的加载。
|
||||
|
||||
```
|
||||
from sqlalchemy.orm import joinedload
|
||||
|
||||
artists = Artist.query.options(joinedload(Artist.songs))
|
||||
print(artists.songs) # Does not incur a roundtrip to load
|
||||
```
|
||||
|
||||
### 使用 ORM 进行批量记录导入
|
||||
|
||||
导入成千上万条记录时,构建完整模型实例的开销会成为主要瓶颈。想象一下,从一个文件中加载数千首歌曲记录,其中每首歌曲都先被转换为字典。
|
||||
|
||||
```
|
||||
for song in songs:
|
||||
db.session.add(Song(`song))
|
||||
```
|
||||
|
||||
相反,绕过 ORM,只使用核心的 SQLAlchemy 参数绑定功能。
|
||||
|
||||
```
|
||||
batch = []
|
||||
insert_stmt = Song.__table__.insert()
|
||||
for song in songs:
|
||||
if len(batch) > 1000:
|
||||
db.session.execute(insert_stmt, batch)
|
||||
batch.clear()
|
||||
batch.append(song)
|
||||
if batch:
|
||||
db.session.execute(insert_stmt, batch)
|
||||
```
|
||||
|
||||
请记住,此方法会自然而然地跳过你可能依赖的任何客户端 ORM 逻辑,例如基于 Python 的列默认值。尽管此方法比将对象加载为完整的模型实例要快,但是你的数据库可能具有更快的批量加载方法。例如,PostgreSQL 的 `COPY` 命令为加载大量记录提供了最佳性能。
|
||||
|
||||
### 过早调用提交或刷新
|
||||
|
||||
在很多情况下,你需要将子记录与其父记录相关联,反之亦然。一种显然的方法是刷新会话,以便为有问题的记录分配一个 ID。
|
||||
|
||||
```
|
||||
artist = Artist(name="Bob Dylan")
|
||||
song = Song(title="Mr. Tambourine Man")
|
||||
|
||||
db.session.add(artist)
|
||||
db.session.flush()
|
||||
|
||||
song.artist_id = artist.id
|
||||
```
|
||||
|
||||
对于每个请求,多次提交或刷新通常是不必要的,也是不可取的。数据库刷新涉及强制在数据库服务器上进行磁盘写入,在大多数情况下,客户端将阻塞,直到服务器确认已写入数据为止。
|
||||
|
||||
SQLAlchemy 可以在幕后跟踪关系和管理相关键。
|
||||
|
||||
```
|
||||
artist = Artist(name="Bob Dylan")
|
||||
song = Song(title="Mr. Tambourine Man")
|
||||
|
||||
artist.songs.append(song)
|
||||
```
|
||||
|
||||
### 总结
|
||||
|
||||
我希望这一系列常见的陷阱可以帮助你避免这些问题,并使你的应用平稳运行。通常,在诊断性能问题时,测量是关键。大多数数据库都提供性能诊断功能,可以帮助你定位问题,例如 PostgreSQL 的 `pg_stat_statements` 模块。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/19/9/common-pitfalls-python
|
||||
|
||||
作者:[Zach Todd][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[MjSeven](https://github.com/MjSeven)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/zchtoddhttps://opensource.com/users/lauren-pritchetthttps://opensource.com/users/liranhaimovitchhttps://opensource.com/users/moshez
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/python_snake_file_box.jpg?itok=UuDVFLX- (A python with a package.)
|
||||
[2]: https://en.wikipedia.org/wiki/Object-relational_mapping
|
||||
[3]: https://www.sqlalchemy.org/
|
||||
[4]: https://marshmallow.readthedocs.io/en/stable/
|
215
published/201911/20191007 7 Java tips for new developers.md
Normal file
215
published/201911/20191007 7 Java tips for new developers.md
Normal file
@ -0,0 +1,215 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (robsean)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11620-1.html)
|
||||
[#]: subject: (7 Java tips for new developers)
|
||||
[#]: via: (https://opensource.com/article/19/10/java-basics)
|
||||
[#]: author: (Seth Kenlon https://opensource.com/users/seth)
|
||||
|
||||
给新手 Java 开发者的 7 点提示
|
||||
======
|
||||
|
||||
> 如果你才刚开始学习 Java 编程,这里有七个你需要知道的基础知识。
|
||||
|
||||

|
||||
|
||||
Java 是一个多功能的编程语言,在某种程度上,它用在几乎所有可能涉及计算机的行业了里。Java 的最大优势是,它运行在一个 Java 虚拟机(JVM)中,这是一个翻译 Java 代码为与操作系统兼容的字节码的层。只要有 JVM 存在于你的操作系统上 —— 不管这个操作系统是在一个服务器(或“[无服务器][2]”,也是同样的)、桌面电脑、笔记本电脑、移动设备,或嵌入式设备 —— 那么,Java 应用程序就可以运行在它上面。
|
||||
|
||||
这使得 Java 成为程序员和用户的一种流行语言。程序员知道,他们只需要写一个软件版本就能最终得到一个可以运行在任何平台上的应用程序;用户知道,应用程序可以运行在他们的计算机上,而不用管他们使用的是什么样的操作系统。
|
||||
|
||||
很多语言和框架是跨平台的,但是没有实现同样的抽象层。使用 Java,你针对的是 JVM,而不是操作系统。对于程序员,当面对一些编程难题时,这是阻力最小的线路,但是它仅在当你知道如何编程 Java 时有用。如果你刚开始学习 Java 编程,这里有你需要知道的七个基础的提示。
|
||||
|
||||
但是,首先,如果你不确定是否你安装了 Java ,你可以在一个终端(例如 [Bash][3] 或 [PowerShell][4])中找出来,通过运行:
|
||||
|
||||
```
|
||||
$ java --version
|
||||
openjdk 12.0.2 2019-07-16
|
||||
OpenJDK Runtime Environment 19.3 (build 12.0.2+9)
|
||||
OpenJDK 64-Bit Server VM 19.3 (build 12.0.2+9, mixed mode, sharing)
|
||||
```
|
||||
|
||||
如果你得到一个错误,或未返回任何东西,那么你应该安装 [Java 开发套件][5](JDK)来开始 Java 开发。或者,安装一个 Java 运行时环境(JRE),如果你只是需要来运行 Java 应用程序。
|
||||
|
||||
### 1、Java 软件包
|
||||
|
||||
在 Java 语言中,相关的类被分组到一个*软件包*中。当你下载 JDK 时所获得的 Java 基础库将被分组到以 `java` 或 `javax` 开头的软件包中。软件包提供一种类似于计算机上的文件夹的功能:它们为相关的元素提供结构和定义(以编程术语说,*命名空间*)。额外的软件包可以从独立开发者、开源项目和商业供应商获得,就像可以为任何编程语言获得库一样。
|
||||
|
||||
当你写一个 Java 程序时,你应该在你的代码是顶部声明一个软件包名称。如果你只是编写一个简单的应用程序来入门 Java,你的软件包名称可以简单地用你的项目名称。如果你正在使用一个 Java 集成开发环境,如 [Eclipse][6],当你启动一个新的项目时,它为你生成一个合乎情理的软件包名称。
|
||||
|
||||
```
|
||||
package helloworld;
|
||||
|
||||
/**
|
||||
* @author seth
|
||||
* An application written in Java.
|
||||
*/
|
||||
```
|
||||
|
||||
除此之外,你可以通过查找它相对于你的项目整体的路径来确定你的软件包名称。例如,如果你正在写一组类来帮助游戏开发,并且该集合被称为 `jgamer`,那么你可能在其中有一些唯一的类。
|
||||
|
||||
```
|
||||
package jgamer.avatar;
|
||||
|
||||
/**
|
||||
* @author seth
|
||||
* An imaginary game library.
|
||||
*/
|
||||
```
|
||||
|
||||
你的软件包的顶层是 `jgamer`,并且在其内部中每个软件包都是一个独立的派生物,例如 `jgamer.avatar` 和 `jgamer.score` 等等。在你的文件系统里,其目录结构反映了这一点,`jgamer` 是包含文件 `avatar.java` 和 `score.java` 的顶级目录。
|
||||
|
||||
### 2、Java 导入
|
||||
|
||||
作为一名通晓多种语言的程序员,最大的乐趣是找出是否用 `include`、`import`、`use`、`require`,或一些其它术语来引入你不管使用何种编程语言编写的库。在 Java 中,顺便说一句,当导入你的代码的需要的库时,使用 `import` 关键字。
|
||||
|
||||
```
|
||||
package helloworld;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
|
||||
/**
|
||||
* @author seth
|
||||
* A GUI hello world.
|
||||
*/
|
||||
```
|
||||
|
||||
导入是基于该环境的 Java 路径。如果 Java 不知道 Java 库存储在系统上的何处,那么,就不能成功导入。只要一个库被存储在系统的 Java 路径中,那么导入能够成功,并且库能够被用于构建和运行一个 Java 应用程序。
|
||||
|
||||
如果一个库并不在 Java 路径中(因为,例如,你正在写你自己的库),那么该库可以与你的应用程序绑定在一起(协议许可),以便导入可以按预期地工作。
|
||||
|
||||
### 3、Java 类
|
||||
|
||||
Java 类使用关键字 `public class` 声明,以及一个唯一的对应于它的文件名的类名。例如,在项目 `helloworld` 中的一个文件 `Hello.java` 中:
|
||||
|
||||
```
|
||||
package helloworld;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
|
||||
/**
|
||||
* @author seth
|
||||
* A GUI hello world.
|
||||
*/
|
||||
|
||||
public class Hello {
|
||||
// this is an empty class
|
||||
}
|
||||
```
|
||||
|
||||
你可以在一个类内部声明变量和函数。在 Java 中,在一个类中的变量被称为*字段*。
|
||||
|
||||
### 4、Java 方法
|
||||
|
||||
Java 的方法本质上是对象中的函数。基于预期返回的数据类型(例如 `void`、`int`、`float` 等等),它们被定义为 `public`(意味着它们可以被任何其它类访问)或 `private`(限制它们的使用)。
|
||||
|
||||
|
||||
```
|
||||
public void helloPrompt(ActionEvent event) {
|
||||
String salutation = "Hello %s";
|
||||
|
||||
string helloMessage = "World";
|
||||
message = String.format(salutation, helloMessage);
|
||||
JOptionPane.showMessageDialog(this, message);
|
||||
}
|
||||
|
||||
private int someNumber (x) {
|
||||
return x*2;
|
||||
}
|
||||
```
|
||||
|
||||
当直接调用一个方法时,以其类和方法名称来引用。例如,`Hello.someNumber` 指向在 `Hello` 类中的 `someNumber` 方法。
|
||||
|
||||
### 5、static
|
||||
|
||||
Java 中的 `static` 关键字使代码中的成员可以独立于包含其的对象而被访问。
|
||||
|
||||
在面向对象编程中,你编写的代码用作“对象”的模板,这些对象在应用程序运行时产生。例如,你不需要编写一个具体的窗口,而是编写基于 Java 中的窗口类的窗口实例(并由你的代码修改)。由于在应用程序生成它的实例之前,你编写的所有代码都不会“存在”,因此在创建它们所依赖的对象之前,大多数方法和变量(甚至是嵌套类)都无法使用。
|
||||
|
||||
然而,有时,在对象被通过应用程序创建前,你需要访问或使用其中的数据。(例如,除非事先知道球是红色时,应用程序无法生成一个红色的球)。对于这些情况,请使用 `static` 关键字。
|
||||
|
||||
### 6、try 和 catch
|
||||
|
||||
Java 擅长捕捉错误,但是,只有你告诉它遇到错误时该做什么,它才能优雅地恢复。在 Java 中,尝试执行一个动作的级联层次结构以 `try` 开头,出现错误时回落到 `catch`,并以 `finally` 结束。如果 `try` 子句失败,则将调用 `catch`,最后,不管结果如何,总是由 `finally` 来执行一些合理的动作。这里是一个示例:
|
||||
|
||||
```
|
||||
try {
|
||||
cmd = parser.parse(opt, args);
|
||||
|
||||
if(cmd.hasOption("help")) {
|
||||
HelpFormatter helper = new HelpFormatter();
|
||||
helper.printHelp("Hello <options>", opt);
|
||||
System.exit(0);
|
||||
}
|
||||
else {
|
||||
if(cmd.hasOption("shell") || cmd.hasOption("s")) {
|
||||
String target = cmd.getOptionValue("tgt");
|
||||
} // else
|
||||
} // fi
|
||||
} catch (ParseException err) {
|
||||
System.out.println(err);
|
||||
System.exit(1);
|
||||
} //catch
|
||||
finally {
|
||||
new Hello().helloWorld(opt);
|
||||
} //finally
|
||||
} //try
|
||||
```
|
||||
|
||||
这是一个健壮的系统,它试图避免无法挽回的错误,或者,至少,为你提供让用户提交有用的反馈的选项。经常使用它,你的用户将会感谢你!
|
||||
|
||||
### 7、运行 Java 应用程序
|
||||
|
||||
Java 文件,通常以 `.java` 结尾,理论上说,可以使用 `java` 命令运行。然而,如果一个应用程序很复杂,运行一个单个文件是否会产生有意义的结果是另外一个问题。
|
||||
|
||||
来直接运行一个 `.java` 文件:
|
||||
|
||||
```
|
||||
$ java ./Hello.java
|
||||
```
|
||||
|
||||
通常,Java 应用程序以 Java 存档(JAR)文件的形式分发,以 `.jar` 结尾。一个 JAR 文件包含一个清单文件(可以指定主类、项目结构的一些元数据),以及运行应用程序所需的所有代码部分。
|
||||
|
||||
要运行一个 JAR 文件,你可以双击它的图标(取决于你的操作系统设置),你也可以从终端中启动它:
|
||||
|
||||
```
|
||||
$ java -jar ./Hello.jar
|
||||
```
|
||||
|
||||
### 适合所有人的 Java
|
||||
|
||||
Java 是一种强大的语言,由于有了 [OpenJDK][12] 项目及其它的努力,它是一种开放式规范,允许像 [IcedTea][13]、[Dalvik][14] 和 [Kotlin][15] 项目的茁壮成长。学习 Java 是一种准备在各种行业中工作的好方法,而且,[使用 Java 的理由很多][16]。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/19/10/java-basics
|
||||
|
||||
作者:[Seth Kenlon][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[robsean](https://github.com/robsean)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [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/coffee_cafe_brew_laptop_desktop.jpg?itok=G-n1o1-o (Coffee and laptop)
|
||||
[2]: https://www.redhat.com/en/resources/building-microservices-eap-7-reference-architecture
|
||||
[3]: https://www.gnu.org/software/bash/
|
||||
[4]: https://docs.microsoft.com/en-us/powershell/scripting/install/installing-powershell?view=powershell-6
|
||||
[5]: http://openjdk.java.net/
|
||||
[6]: http://www.eclipse.org/
|
||||
[7]: http://www.google.com/search?hl=en&q=allinurl%3Adocs.oracle.com+javase+docs+api+actionevent
|
||||
[8]: http://www.google.com/search?hl=en&q=allinurl%3Adocs.oracle.com+javase+docs+api+string
|
||||
[9]: http://www.google.com/search?hl=en&q=allinurl%3Adocs.oracle.com+javase+docs+api+joptionpane
|
||||
[10]: http://www.google.com/search?hl=en&q=allinurl%3Adocs.oracle.com+javase+docs+api+system
|
||||
[11]: http://www.google.com/search?hl=en&q=allinurl%3Adocs.oracle.com+javase+docs+api+parseexception
|
||||
[12]: https://openjdk.java.net/
|
||||
[13]: https://icedtea.classpath.org/wiki/Main_Page
|
||||
[14]: https://source.android.com/devices/tech/dalvik/
|
||||
[15]: https://kotlinlang.org/
|
||||
[16]: https://opensource.com/article/19/9/why-i-use-java
|
@ -0,0 +1,489 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (wxy)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11600-1.html)
|
||||
[#]: subject: (How to use Protobuf for data interchange)
|
||||
[#]: via: (https://opensource.com/article/19/10/protobuf-data-interchange)
|
||||
[#]: author: (Marty Kalin https://opensource.com/users/mkalindepauledu)
|
||||
|
||||
如何使用 Protobuf 做数据交换
|
||||
======
|
||||
|
||||
> 在以不同语言编写并在不同平台上运行的应用程序之间交换数据时,Protobuf 编码可提高效率。
|
||||
|
||||

|
||||
|
||||
<ruby>协议缓冲区<rt>Protocol Buffers</rt></ruby>([Protobufs][2])像 XML 和 JSON 一样,可以让用不同语言编写并在不同平台上运行的应用程序交换数据。例如,用 Go 编写的发送程序可以在 Protobuf 中对以 Go 表示的销售订单数据进行编码,然后用 Java 编写的接收方可以对它进行解码,以获取所接收订单数据的 Java 表示方式。这是在网络连接上的结构示意图:
|
||||
|
||||
> Go 销售订单 ---> Pbuf 编码 ---> 网络 ---> Pbuf 界面 ---> Java 销售订单
|
||||
|
||||
与 XML 和 JSON 相比,Protobuf 编码是二进制而不是文本,这会使调试复杂化。但是,正如本文中的代码示例所确认的那样,Protobuf 编码在大小上比 XML 或 JSON 编码要有效得多。
|
||||
|
||||
Protobuf 以另一种方式提供了这种有效性。在实现级别,Protobuf 和其他编码系统对结构化数据进行<ruby>序列化<rt>serialize</rt></ruby>和<ruby>反序列化<rt>deserialize</rt></ruby>。序列化将特定语言的数据结构转换为字节流,反序列化是将字节流转换回特定语言的数据结构的逆运算。序列化和反序列化可能成为数据交换的瓶颈,因为这些操作会占用大量 CPU。高效的序列化和反序列化是 Protobuf 的另一个设计目标。
|
||||
|
||||
最近的编码技术,例如 Protobuf 和 FlatBuffers,源自 1990 年代初期的 [DCE/RPC][3](<ruby>分布式计算环境/远程过程调用<rt>Distributed Computing Environment/Remote Procedure Call</rt></ruby>)计划。与 DCE/RPC 一样,Protobuf 在数据交换中为 [IDL][4](接口定义语言)和编码层做出了贡献。
|
||||
|
||||
本文将着眼于这两层,然后提供 Go 和 Java 中的代码示例以充实 Protobuf 的细节,并表明 Protobuf 是易于使用的。
|
||||
|
||||
### Protobuf 作为一个 IDL 和编码层
|
||||
|
||||
像 Protobuf 一样,DCE/RPC 被设计为与语言和平台无关。适当的库和实用程序允许任何语言和平台用于 DCE/RPC 领域。此外,DCE/RPC 体系结构非常优雅。IDL 文档是一侧的远程过程与另一侧的调用者之间的协定。Protobuf 也是以 IDL 文档为中心的。
|
||||
|
||||
IDL 文档是文本,在 DCE/RPC 中,使用基本 C 语法以及元数据的语法扩展(方括号)和一些新的关键字,例如 `interface`。这是一个例子:
|
||||
|
||||
```
|
||||
[uuid (2d6ead46-05e3-11ca-7dd1-426909beabcd), version(1.0)]
|
||||
interface echo {
|
||||
const long int ECHO_SIZE = 512;
|
||||
void echo(
|
||||
[in] handle_t h,
|
||||
[in, string] idl_char from_client[ ],
|
||||
[out, string] idl_char from_service[ECHO_SIZE]
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
该 IDL 文档声明了一个名为 `echo` 的过程,该过程带有三个参数:类型为 `handle_t`(实现指针)和 `idl_char`(ASCII 字符数组)的 `[in]` 参数被传递给远程过程,而 `[out]` 参数(也是一个字符串)从该过程中传回。在此示例中,`echo` 过程不会显式返回值(`echo` 左侧的 `void`),但也可以返回值。返回值,以及一个或多个 `[out]` 参数,允许远程过程任意返回许多值。下一节将介绍 Protobuf IDL,它的语法不同,但同样用作数据交换中的协定。
|
||||
|
||||
DCE/RPC 和 Protobuf 中的 IDL 文档是创建用于交换数据的基础结构代码的实用程序的输入:
|
||||
|
||||
> IDL 文档 ---> DCE/PRC 或 Protobuf 实用程序 ---> 数据交换的支持代码
|
||||
|
||||
作为相对简单的文本,IDL 是同样便于人类阅读的关于数据交换细节的文档(特别是交换的数据项的数量和每个项的数据类型)。
|
||||
|
||||
Protobuf 可用于现代 RPC 系统,例如 [gRPC][5];但是 Protobuf 本身仅提供 IDL 层和编码层,用于从发送者传递到接收者的消息。与原本的 DCE/RPC 一样,Protobuf 编码是二进制的,但效率更高。
|
||||
|
||||
目前,XML 和 JSON 编码仍在通过 Web 服务等技术进行的数据交换中占主导地位,这些技术利用 Web 服务器、传输协议(例如 TCP、HTTP)以及标准库和实用程序等原有的基础设施来处理 XML 和 JSON 文档。 此外,各种类型的数据库系统可以存储 XML 和 JSON 文档,甚至旧式关系型系统也可以轻松生成查询结果的 XML 编码。现在,每种通用编程语言都具有支持 XML 和 JSON 的库。那么,是什么让我们回到 Protobuf 之类的**二进制**编码系统呢?
|
||||
|
||||
让我们看一下负十进制值 `-128`。以 2 的补码二进制表示形式(在系统和语言中占主导地位)中,此值可以存储在单个 8 位字节中:`10000000`。此整数值在 XML 或 JSON 中的文本编码需要多个字节。例如,UTF-8 编码需要四个字节的字符串,即 `-128`,即每个字符一个字节(十六进制,值为 `0x2d`、`0x31`、`0x32` 和 `0x38`)。XML 和 JSON 还添加了标记字符,例如尖括号和大括号。有关 Protobuf 编码的详细信息下面就会介绍,但现在的关注点是一个通用点:文本编码的压缩性明显低于二进制编码。
|
||||
|
||||
### 在 Go 中使用 Protobuf 的示例
|
||||
|
||||
我的代码示例着重于 Protobuf 而不是 RPC。以下是第一个示例的概述:
|
||||
|
||||
* 名为 `dataitem.proto` 的 IDL 文件定义了一个 Protobuf 消息,它具有六个不同类型的字段:具有不同范围的整数值、固定大小的浮点值以及两个不同长度的字符串。
|
||||
* Protobuf 编译器使用 IDL 文件生成 Go 版本(以及后面的 Java 版本)的 Protobuf 消息及支持函数。
|
||||
* Go 应用程序使用随机生成的值填充原生的 Go 数据结构,然后将结果序列化为本地文件。为了进行比较, XML 和 JSON 编码也被序列化为本地文件。
|
||||
* 作为测试,Go 应用程序通过反序列化 Protobuf 文件的内容来重建其原生数据结构的实例。
|
||||
* 作为语言中立性测试,Java 应用程序还会对 Protobuf 文件的内容进行反序列化以获取原生数据结构的实例。
|
||||
|
||||
[我的网站][6]上提供了该 IDL 文件以及两个 Go 和一个 Java 源文件,打包为 ZIP 文件。
|
||||
|
||||
最重要的 Protobuf IDL 文档如下所示。该文档存储在文件 `dataitem.proto` 中,并具有常规的`.proto` 扩展名。
|
||||
|
||||
#### 示例 1、Protobuf IDL 文档
|
||||
|
||||
```
|
||||
syntax = "proto3";
|
||||
|
||||
package main;
|
||||
|
||||
message DataItem {
|
||||
int64 oddA = 1;
|
||||
int64 evenA = 2;
|
||||
int32 oddB = 3;
|
||||
int32 evenB = 4;
|
||||
float small = 5;
|
||||
float big = 6;
|
||||
string short = 7;
|
||||
string long = 8;
|
||||
}
|
||||
```
|
||||
|
||||
该 IDL 使用当前的 proto3 而不是较早的 proto2 语法。软件包名称(在本例中为 `main`)是可选的,但是惯例使用它以避免名称冲突。这个结构化的消息包含八个字段,每个字段都有一个 Protobuf 数据类型(例如,`int64`、`string`)、名称(例如,`oddA`、`short`)和一个等号 `=` 之后的数字标签(即键)。标签(在此示例中为 1 到 8)是唯一的整数标识符,用于确定字段序列化的顺序。
|
||||
|
||||
Protobuf 消息可以嵌套到任意级别,而一个消息可以是另外一个消息的字段类型。这是一个使用 `DataItem` 消息作为字段类型的示例:
|
||||
|
||||
```
|
||||
message DataItems {
|
||||
repeated DataItem item = 1;
|
||||
}
|
||||
```
|
||||
|
||||
单个 `DataItems` 消息由重复的(零个或多个)`DataItem` 消息组成。
|
||||
|
||||
为了清晰起见,Protobuf 还支持枚举类型:
|
||||
|
||||
```
|
||||
enum PartnershipStatus {
|
||||
reserved "FREE", "CONSTRAINED", "OTHER";
|
||||
}
|
||||
```
|
||||
|
||||
`reserved` 限定符确保用于实现这三个符号名的数值不能重复使用。
|
||||
|
||||
为了生成一个或多个声明 Protobuf 消息结构的特定于语言的版本,包含这些结构的 IDL 文件被传递到`protoc` 编译器(可在 [Protobuf GitHub 存储库][7]中找到)。对于 Go 代码,可以以通常的方式安装支持的 Protobuf 库(这里以 `%` 作为命令行提示符):
|
||||
|
||||
```
|
||||
% go get github.com/golang/protobuf/proto
|
||||
```
|
||||
|
||||
将 Protobuf IDL 文件 `dataitem.proto` 编译为 Go 源代码的命令是:
|
||||
|
||||
```
|
||||
% protoc --go_out=. dataitem.proto
|
||||
```
|
||||
|
||||
标志 `--go_out` 指示编译器生成 Go 源代码。其他语言也有类似的标志。在这种情况下,结果是一个名为 `dataitem.pb.go` 的文件,该文件足够小,可以将其基本内容复制到 Go 应用程序中。以下是生成的代码的主要部分:
|
||||
|
||||
```
|
||||
var _ = proto.Marshal
|
||||
|
||||
type DataItem struct {
|
||||
OddA int64 `protobuf:"varint,1,opt,name=oddA" json:"oddA,omitempty"`
|
||||
EvenA int64 `protobuf:"varint,2,opt,name=evenA" json:"evenA,omitempty"`
|
||||
OddB int32 `protobuf:"varint,3,opt,name=oddB" json:"oddB,omitempty"`
|
||||
EvenB int32 `protobuf:"varint,4,opt,name=evenB" json:"evenB,omitempty"`
|
||||
Small float32 `protobuf:"fixed32,5,opt,name=small" json:"small,omitempty"`
|
||||
Big float32 `protobuf:"fixed32,6,opt,name=big" json:"big,omitempty"`
|
||||
Short string `protobuf:"bytes,7,opt,name=short" json:"short,omitempty"`
|
||||
Long string `protobuf:"bytes,8,opt,name=long" json:"long,omitempty"`
|
||||
}
|
||||
|
||||
func (m *DataItem) Reset() { *m = DataItem{} }
|
||||
func (m *DataItem) String() string { return proto.CompactTextString(m) }
|
||||
func (*DataItem) ProtoMessage() {}
|
||||
func init() {}
|
||||
```
|
||||
|
||||
编译器生成的代码具有 Go 结构 `DataItem`,该结构导出 Go 字段(名称现已大写开头),该字段与 Protobuf IDL 中声明的名称匹配。该结构字段具有标准的 Go 数据类型:`int32`、`int64`、`float32` 和 `string`。在每个字段行的末尾,是描述 Protobuf 类型的字符串,提供 Protobuf IDL 文档中的数字标签及有关 JSON 信息的元数据,这将在后面讨论。
|
||||
|
||||
此外也有函数;最重要的是 `Proto.Marshal`,用于将 `DataItem` 结构的实例序列化为 Protobuf 格式。辅助函数包括:清除 `DataItem` 结构的 `Reset`,生成 `DataItem` 的单行字符串表示的 `String`。
|
||||
|
||||
描述 Protobuf 编码的元数据应在更详细地分析 Go 程序之前进行仔细研究。
|
||||
|
||||
### Protobuf 编码
|
||||
|
||||
Protobuf 消息的结构为键/值对的集合,其中数字标签为键,相应的字段为值。字段名称(例如,`oddA` 和 `small`)是供人类阅读的,但是 `protoc` 编译器的确使用了字段名称来生成特定于语言的对应名称。例如,Protobuf IDL 中的 `oddA` 和 `small` 名称在 Go 结构中分别成为字段 `OddA` 和 `Small`。
|
||||
|
||||
键和它们的值都被编码,但是有一个重要的区别:一些数字值具有固定大小的 32 或 64 位的编码,而其他数字(包括消息标签)则是 `varint` 编码的,位数取决于整数的绝对值。例如,整数值 1 到 15 需要 8 位 `varint` 编码,而值 16 到 2047 需要 16 位。`varint` 编码在本质上与 UTF-8 编码类似(但细节不同),它偏爱较小的整数值而不是较大的整数值。(有关详细分析,请参见 Protobuf [编码指南][8])结果是,Protobuf 消息应该在字段中具有较小的整数值(如果可能),并且键数应尽可能少,但每个字段至少得有一个键。
|
||||
|
||||
下表 1 列出了 Protobuf 编码的要点:
|
||||
|
||||
编码 | 示例类型 | 长度
|
||||
---|---|---
|
||||
`varint` | `int32`、`uint32`、`int64` | 可变长度
|
||||
`fixed` | `fixed32`、`float`、`double` | 固定的 32 位或 64 位长度
|
||||
字节序列 | `string`、`bytes` | 序列长度
|
||||
|
||||
*表 1. Protobuf 数据类型*
|
||||
|
||||
未明确固定长度的整数类型是 `varint` 编码的;因此,在 `varint` 类型中,例如 `uint32`(`u` 代表无符号),数字 32 描述了整数的范围(在这种情况下为 0 到 2^32 - 1),而不是其位的大小,该位大小取决于值。相比之下,对于固定长度类型(例如 `fixed32` 或 `double`),Protobuf 编码分别需要 32 位和 64 位。Protobuf 中的字符串是字节序列;因此,字段编码的大小就是字节序列的长度。
|
||||
|
||||
另一个高效的方法值得一提。回想一下前面的示例,其中的 `DataItems` 消息由重复的 `DataItem` 实例组成:
|
||||
|
||||
```
|
||||
message DataItems {
|
||||
repeated DataItem item = 1;
|
||||
}
|
||||
```
|
||||
|
||||
`repeated` 表示 `DataItem` 实例是*打包的*:集合具有单个标签,在这里是 1。因此,具有重复的 `DataItem` 实例的 `DataItems` 消息比具有多个但单独的 `DataItem` 字段、每个字段都需要自己的标签的消息的效率更高。
|
||||
|
||||
了解了这一背景,让我们回到 Go 程序。
|
||||
|
||||
### dataItem 程序的细节
|
||||
|
||||
`dataItem` 程序创建一个 `DataItem` 实例,并使用适当类型的随机生成的值填充字段。Go 有一个 `rand` 包,带有用于生成伪随机整数和浮点值的函数,而我的 `randString` 函数可以从字符集中生成指定长度的伪随机字符串。设计目标是要有一个具有不同类型和位大小的字段值的 `DataItem` 实例。例如,`OddA` 和 `EvenA` 值分别是 64 位非负整数值的奇数和偶数;但是 `OddB` 和 `EvenB` 变体的大小为 32 位,并存放 0 到 2047 之间的小整数值。随机浮点值的大小为 32 位,字符串为 16(`Short`)和 32(`Long`)字符的长度。这是用随机值填充 `DataItem` 结构的代码段:
|
||||
|
||||
```
|
||||
// 可变长度整数
|
||||
n1 := rand.Int63() // 大整数
|
||||
if (n1 & 1) == 0 { n1++ } // 确保其是奇数
|
||||
...
|
||||
n3 := rand.Int31() % UpperBound // 小整数
|
||||
if (n3 & 1) == 0 { n3++ } // 确保其是奇数
|
||||
|
||||
// 固定长度浮点数
|
||||
...
|
||||
t1 := rand.Float32()
|
||||
t2 := rand.Float32()
|
||||
...
|
||||
// 字符串
|
||||
str1 := randString(StrShort)
|
||||
str2 := randString(StrLong)
|
||||
|
||||
// 消息
|
||||
dataItem := &DataItem {
|
||||
OddA: n1,
|
||||
EvenA: n2,
|
||||
OddB: n3,
|
||||
EvenB: n4,
|
||||
Big: f1,
|
||||
Small: f2,
|
||||
Short: str1,
|
||||
Long: str2,
|
||||
}
|
||||
```
|
||||
|
||||
创建并填充值后,`DataItem` 实例将以 XML、JSON 和 Protobuf 进行编码,每种编码均写入本地文件:
|
||||
|
||||
```
|
||||
func encodeAndserialize(dataItem *DataItem) {
|
||||
bytes, _ := xml.MarshalIndent(dataItem, "", " ") // Xml to dataitem.xml
|
||||
ioutil.WriteFile(XmlFile, bytes, 0644) // 0644 is file access permissions
|
||||
|
||||
bytes, _ = json.MarshalIndent(dataItem, "", " ") // Json to dataitem.json
|
||||
ioutil.WriteFile(JsonFile, bytes, 0644)
|
||||
|
||||
bytes, _ = proto.Marshal(dataItem) // Protobuf to dataitem.pbuf
|
||||
ioutil.WriteFile(PbufFile, bytes, 0644)
|
||||
}
|
||||
```
|
||||
|
||||
这三个序列化函数使用术语 `marshal`,它与 `serialize` 意思大致相同。如代码所示,三个 `Marshal` 函数均返回一个字节数组,然后将其写入文件。(为简单起见,忽略可能的错误处理。)在示例运行中,文件大小为:
|
||||
|
||||
```
|
||||
dataitem.xml: 262 bytes
|
||||
dataitem.json: 212 bytes
|
||||
dataitem.pbuf: 88 bytes
|
||||
```
|
||||
|
||||
Protobuf 编码明显小于其他两个编码方案。通过消除缩进字符(在这种情况下为空白和换行符),可以稍微减小 XML 和 JSON 序列化的大小。
|
||||
|
||||
以下是 `dataitem.json` 文件,该文件最终是由 `json.MarshalIndent` 调用产生的,并添加了以 `##` 开头的注释:
|
||||
|
||||
```
|
||||
{
|
||||
"oddA": 4744002665212642479, ## 64-bit >= 0
|
||||
"evenA": 2395006495604861128, ## ditto
|
||||
"oddB": 57, ## 32-bit >= 0 but < 2048
|
||||
"evenB": 468, ## ditto
|
||||
"small": 0.7562016, ## 32-bit floating-point
|
||||
"big": 0.85202795, ## ditto
|
||||
"short": "ClH1oDaTtoX$HBN5", ## 16 random chars
|
||||
"long": "xId0rD3Cri%3Wt%^QjcFLJgyXBu9^DZI" ## 32 random chars
|
||||
}
|
||||
```
|
||||
|
||||
尽管这些序列化的数据写入到本地文件中,但是也可以使用相同的方法将数据写入网络连接的输出流。
|
||||
|
||||
### 测试序列化和反序列化
|
||||
|
||||
Go 程序接下来通过将先前写入 `dataitem.pbuf` 文件的字节反序列化为 `DataItem` 实例来运行基本测试。这是代码段,其中去除了错误检查部分:
|
||||
|
||||
```
|
||||
filebytes, err := ioutil.ReadFile(PbufFile) // get the bytes from the file
|
||||
...
|
||||
testItem.Reset() // clear the DataItem structure
|
||||
err = proto.Unmarshal(filebytes, testItem) // deserialize into a DataItem instance
|
||||
```
|
||||
|
||||
用于 Protbuf 反序列化的 `proto.Unmarshal` 函数与 `proto.Marshal` 函数相反。原始的 `DataItem` 和反序列化的副本将被打印出来以确认完全匹配:
|
||||
|
||||
```
|
||||
Original:
|
||||
2041519981506242154 3041486079683013705 1192 1879
|
||||
0.572123 0.326855
|
||||
boPb#T0O8Xd&Ps5EnSZqDg4Qztvo7IIs 9vH66AiGSQgCDxk&
|
||||
|
||||
Deserialized:
|
||||
2041519981506242154 3041486079683013705 1192 1879
|
||||
0.572123 0.326855
|
||||
boPb#T0O8Xd&Ps5EnSZqDg4Qztvo7IIs 9vH66AiGSQgCDxk&
|
||||
```
|
||||
|
||||
### 一个 Java Protobuf 客户端
|
||||
|
||||
用 Java 写的示例是为了确认 Protobuf 的语言中立性。原始 IDL 文件可用于生成 Java 支持代码,其中涉及嵌套类。但是,为了抑制警告信息,可以进行一些补充。这是修订版,它指定了一个 `DataMsg` 作为外部类的名称,内部类在该 Protobuf 消息后面自动命名为 `DataItem`:
|
||||
|
||||
```
|
||||
syntax = "proto3";
|
||||
|
||||
package main;
|
||||
|
||||
option java_outer_classname = "DataMsg";
|
||||
|
||||
message DataItem {
|
||||
...
|
||||
```
|
||||
|
||||
进行此更改后,`protoc` 编译与以前相同,只是所期望的输出现在是 Java 而不是 Go:
|
||||
|
||||
```
|
||||
% protoc --java_out=. dataitem.proto
|
||||
```
|
||||
|
||||
生成的源文件(在名为 `main` 的子目录中)为 `DataMsg.java`,长度约为 1,120 行:Java 并不简洁。编译然后运行 Java 代码需要具有 Protobuf 库支持的 JAR 文件。该文件位于 [Maven 存储库][9]中。
|
||||
|
||||
放置好这些片段后,我的测试代码相对较短(并且在 ZIP 文件中以 `Main.java` 形式提供):
|
||||
|
||||
```
|
||||
package main;
|
||||
import java.io.FileInputStream;
|
||||
|
||||
public class Main {
|
||||
public static void main(String[] args) {
|
||||
String path = "dataitem.pbuf"; // from the Go program's serialization
|
||||
try {
|
||||
DataMsg.DataItem deserial =
|
||||
DataMsg.DataItem.newBuilder().mergeFrom(new FileInputStream(path)).build();
|
||||
|
||||
System.out.println(deserial.getOddA()); // 64-bit odd
|
||||
System.out.println(deserial.getLong()); // 32-character string
|
||||
}
|
||||
catch(Exception e) { System.err.println(e); }
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
当然,生产级的测试将更加彻底,但是即使是该初步测试也可以证明 Protobuf 的语言中立性:`dataitem.pbuf` 文件是 Go 程序对 Go 语言版的 `DataItem` 进行序列化的结果,并且该文件中的字节被反序列化以产生一个 Java 语言的 `DataItem` 实例。Java 测试的输出与 Go 测试的输出相同。
|
||||
|
||||
### 用 numPairs 程序来结束
|
||||
|
||||
让我们以一个示例作为结尾,来突出 Protobuf 效率,但又强调在任何编码技术中都会涉及到的成本。考虑以下 Protobuf IDL 文件:
|
||||
|
||||
```
|
||||
syntax = "proto3";
|
||||
package main;
|
||||
|
||||
message NumPairs {
|
||||
repeated NumPair pair = 1;
|
||||
}
|
||||
|
||||
message NumPair {
|
||||
int32 odd = 1;
|
||||
int32 even = 2;
|
||||
}
|
||||
```
|
||||
|
||||
`NumPair` 消息由两个 `int32` 值以及每个字段的整数标签组成。`NumPairs` 消息是嵌入的 `NumPair` 消息的序列。
|
||||
|
||||
Go 语言的 `numPairs` 程序(如下)创建了 200 万个 `NumPair` 实例,每个实例都附加到 `NumPairs` 消息中。该消息可以按常规方式进行序列化和反序列化。
|
||||
|
||||
#### 示例 2、numPairs 程序
|
||||
|
||||
```
|
||||
package main
|
||||
|
||||
import (
|
||||
"math/rand"
|
||||
"time"
|
||||
"encoding/xml"
|
||||
"encoding/json"
|
||||
"io/ioutil"
|
||||
"github.com/golang/protobuf/proto"
|
||||
)
|
||||
|
||||
// protoc-generated code: start
|
||||
var _ = proto.Marshal
|
||||
type NumPairs struct {
|
||||
Pair []*NumPair `protobuf:"bytes,1,rep,name=pair" json:"pair,omitempty"`
|
||||
}
|
||||
|
||||
func (m *NumPairs) Reset() { *m = NumPairs{} }
|
||||
func (m *NumPairs) String() string { return proto.CompactTextString(m) }
|
||||
func (*NumPairs) ProtoMessage() {}
|
||||
func (m *NumPairs) GetPair() []*NumPair {
|
||||
if m != nil { return m.Pair }
|
||||
return nil
|
||||
}
|
||||
|
||||
type NumPair struct {
|
||||
Odd int32 `protobuf:"varint,1,opt,name=odd" json:"odd,omitempty"`
|
||||
Even int32 `protobuf:"varint,2,opt,name=even" json:"even,omitempty"`
|
||||
}
|
||||
|
||||
func (m *NumPair) Reset() { *m = NumPair{} }
|
||||
func (m *NumPair) String() string { return proto.CompactTextString(m) }
|
||||
func (*NumPair) ProtoMessage() {}
|
||||
func init() {}
|
||||
// protoc-generated code: finish
|
||||
|
||||
var numPairsStruct NumPairs
|
||||
var numPairs = &numPairsStruct
|
||||
|
||||
func encodeAndserialize() {
|
||||
// XML encoding
|
||||
filename := "./pairs.xml"
|
||||
bytes, _ := xml.MarshalIndent(numPairs, "", " ")
|
||||
ioutil.WriteFile(filename, bytes, 0644)
|
||||
|
||||
// JSON encoding
|
||||
filename = "./pairs.json"
|
||||
bytes, _ = json.MarshalIndent(numPairs, "", " ")
|
||||
ioutil.WriteFile(filename, bytes, 0644)
|
||||
|
||||
// ProtoBuf encoding
|
||||
filename = "./pairs.pbuf"
|
||||
bytes, _ = proto.Marshal(numPairs)
|
||||
ioutil.WriteFile(filename, bytes, 0644)
|
||||
}
|
||||
|
||||
const HowMany = 200 * 100 * 100 // two million
|
||||
|
||||
func main() {
|
||||
rand.Seed(time.Now().UnixNano())
|
||||
|
||||
// uncomment the modulus operations to get the more efficient version
|
||||
for i := 0; i < HowMany; i++ {
|
||||
n1 := rand.Int31() // % 2047
|
||||
if (n1 & 1) == 0 { n1++ } // ensure it's odd
|
||||
n2 := rand.Int31() // % 2047
|
||||
if (n2 & 1) == 1 { n2++ } // ensure it's even
|
||||
|
||||
next := &NumPair {
|
||||
Odd: n1,
|
||||
Even: n2,
|
||||
}
|
||||
numPairs.Pair = append(numPairs.Pair, next)
|
||||
}
|
||||
encodeAndserialize()
|
||||
}
|
||||
```
|
||||
|
||||
每个 `NumPair` 中随机生成的奇数和偶数值的范围在 0 到 20 亿之间变化。就原始数据(而非编码数据)而言,Go 程序中生成的整数总共为 16MB:每个 `NumPair` 为两个整数,总计为 400 万个整数,每个值的大小为四个字节。
|
||||
|
||||
为了进行比较,下表列出了 XML、JSON 和 Protobuf 编码的示例 `NumsPairs` 消息的 200 万个 `NumPair` 实例。原始数据也包括在内。由于 `numPairs` 程序生成随机值,因此样本运行的输出有所不同,但接近表中显示的大小。
|
||||
|
||||
编码 | 文件 | 字节大小 | Pbuf/其它 比例
|
||||
---|---|---|---
|
||||
无 | pairs.raw | 16MB | 169%
|
||||
Protobuf | pairs.pbuf | 27MB | —
|
||||
JSON | pairs.json | 100MB | 27%
|
||||
XML | pairs.xml | 126MB | 21%
|
||||
|
||||
*表 2. 16MB 整数的编码开销*
|
||||
|
||||
不出所料,Protobuf 和之后的 XML 和 JSON 差别明显。Protobuf 编码大约是 JSON 的四分之一,是 XML 的五分之一。但是原始数据清楚地表明 Protobuf 也会产生编码开销:序列化的 Protobuf 消息比原始数据大 11MB。包括 Protobuf 在内的任何编码都涉及结构化数据,这不可避免地会增加字节。
|
||||
|
||||
序列化的 200 万个 `NumPair` 实例中的每个实例都包含**四**个整数值:Go 结构中的 `Even` 和 `Odd` 字段分别一个,而 Protobuf 编码中的每个字段、每个标签一个。对于原始数据(而不是编码数据),每个实例将达到 16 个字节,样本 `NumPairs` 消息中有 200 万个实例。但是 Protobuf 标记(如 `NumPair` 字段中的 `int32` 值)使用 `varint` 编码,因此字节长度有所不同。特别是,小的整数值(在这种情况下,包括标签在内)需要不到四个字节进行编码。
|
||||
|
||||
如果对 `numPairs` 程序进行了修改,以使两个 `NumPair` 字段的值小于 2048,且其编码为一或两个字节,则 Protobuf 编码将从 27MB 下降到 16MB,这正是原始数据的大小。下表总结了样本运行中的新编码大小。
|
||||
|
||||
编码 | 文件 | 字节大小 | Pbuf/其它 比例
|
||||
---|---|---|---
|
||||
None | pairs.raw | 16MB | 100%
|
||||
Protobuf | pairs.pbuf | 16MB | —
|
||||
JSON | pairs.json | 77MB | 21%
|
||||
XML | pairs.xml | 103MB | 15%
|
||||
|
||||
*表 3. 编码 16MB 的小于 2048 的整数*
|
||||
|
||||
总之,修改后的 `numPairs` 程序的字段值小于 2048,可减少原始数据中每个四字节整数值的大小。但是 Protobuf 编码仍然需要标签,这些标签会在 Protobuf 消息中添加字节。Protobuf 编码确实会增加消息大小,但是如果要编码相对较小的整数值(无论是字段还是键),则可以通过 `varint` 因子来减少此开销。
|
||||
|
||||
对于包含混合类型的结构化数据(且整数值相对较小)的中等大小的消息,Protobuf 明显优于 XML 和 JSON 等选项。在其他情况下,数据可能不适合 Protobuf 编码。例如,如果两个应用程序需要共享大量文本记录或大整数值,则可以采用压缩而不是编码技术。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/19/10/protobuf-data-interchange
|
||||
|
||||
作者:[Marty Kalin][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[wxy](https://github.com/wxy)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/mkalindepauledu
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/metrics_data_dashboard_system_computer_analytics.png?itok=oxAeIEI- (metrics and data shown on a computer screen)
|
||||
[2]: https://developers.google.com/protocol-buffers/
|
||||
[3]: https://en.wikipedia.org/wiki/DCE/RPC
|
||||
[4]: https://en.wikipedia.org/wiki/Interface_description_language
|
||||
[5]: https://grpc.io/
|
||||
[6]: http://condor.depaul.edu/mkalin
|
||||
[7]: https://github.com/protocolbuffers/protobuf
|
||||
[8]: https://developers.google.com/protocol-buffers/docs/encoding
|
||||
[9]: https://mvnrepository.com/artifact/com.google.protobuf/protobuf-java
|
@ -0,0 +1,261 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (wenwensnow)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11557-1.html)
|
||||
[#]: subject: (How to dual boot Windows 10 and Debian 10)
|
||||
[#]: via: (https://www.linuxtechi.com/dual-boot-windows-10-debian-10/)
|
||||
[#]: author: (James Kiarie https://www.linuxtechi.com/author/james/)
|
||||
|
||||
如何拥有一个 Windows 10 和 Debian 10 的双系统
|
||||
======
|
||||
|
||||
在无数次劝说自己后,你终于做出了一个大胆的决定,试试 Linux。不过,在完全熟悉 Linux 之前,你依旧需要使用 Windows 10 系统。幸运的是,通过一个双系统引导设置,能让你在启动时,选择自己想要进入的系统。在这个指南中,你会看到如何 如何双重引导 Windows 10 和 Debian 10。
|
||||
|
||||
![如何拥有一个 Windows 10 和 Debian 10 的双系统][2]
|
||||
|
||||
### 前提条件
|
||||
|
||||
在开始之前,确保你满足下列条件:
|
||||
|
||||
* 一个 Debian 10 的可引导 USB 或 DVD
|
||||
* 一个快速且稳定的网络(为了安装更新以及第三方软件)
|
||||
|
||||
另外,记得注意你系统的引导策略(UEFI 或 Legacy),需要确保两个系统使用同一种引导模式。
|
||||
|
||||
### 第一步:在硬盘上创建一个空余分区
|
||||
|
||||
第一步,你需要在你的硬盘上创建一个空余分区。之后,这将是我们安装 Debian 系统的地方。为了实现这一目的,需要使用下图所示的磁盘管理器:
|
||||
|
||||
同时按下 `Windows + R` 键,启动“运行程序”。接下来,输入 `diskmgmt.msc`,按回车键。
|
||||
|
||||
![启动“运行程序”][3]
|
||||
|
||||
这会启动“磁盘管理”窗口,它会显示你 Windows 上所有已有磁盘。
|
||||
|
||||
![磁盘管理][4]
|
||||
|
||||
接下来,你需要为安装的 Debian 系统创建空余空间。为此,你需要缩小其中一个磁盘(卷)上的分区,从而创建一个未分配的新分区。在这个例子里,我会从 D 盘中创建一个 30 GB 的新分区。
|
||||
|
||||
为了缩小一个卷,右键点击它,然后选中选项 “<ruby>缩小<rt>Shrink volume...</rt></ruby>”。
|
||||
|
||||
![缩小卷][5]
|
||||
|
||||
在弹出窗口中,定义你想缩小的空间大小。记住,这是将来要安装 Debian 10 的磁盘空间。我选择了 30000MB(大约 30 GB)。压缩完成后,点击“<ruby>缩小<rt>Shrink</rt></ruby>”。
|
||||
|
||||
![缩小空间][6]
|
||||
|
||||
在缩小操作结束后,你会看到一个如下图所示的未分配分区:
|
||||
|
||||
![未分配分区][7]
|
||||
|
||||
完美!现在可以准备开始安装了。
|
||||
|
||||
### 第二步:开始安装 Debian 10
|
||||
|
||||
空余分区已经创建好了,将你的可引导 USB 或安装 DVD 插入电脑,重新启动系统。记得更改 BIOS 中的引导顺序,需要在启动时按住功能键(通常,根据品牌不同,是 `F9`、`F10` 或 `F12` 中的某一个)。 这一步骤,对系统是否能进入安装媒体来说,至关重要。保存 BIOS 设置,并重启电脑。
|
||||
|
||||
如下图所示,界面会显示一个新的引导菜单:点击 “Graphical install”。
|
||||
|
||||
![图形化界面安装][8]
|
||||
|
||||
下一步,选择你的偏好语言,然后点击 “<ruby>继续<rt>Continue</rt></ruby>”。
|
||||
|
||||
![设置语言-Debian10][9]
|
||||
|
||||
接着,选择你的地区,点击“<ruby>继续<rt>Continue</rt></ruby>”。 根据地区,系统会自动选择当地对应的时区。如果你无法找到你所对应的地区,将界面往下拉, 点击“<ruby>其他<rt>Other</rt></ruby>”后,选择相对应位置。
|
||||
|
||||
![选择地区-Debain10][10]
|
||||
|
||||
而后,选择你的键盘布局。
|
||||
|
||||
![设置键盘-Debain10][11]
|
||||
|
||||
接下来,设置系统的主机名,点击 “<ruby>继续<rt>Continue</rt></ruby>”。
|
||||
|
||||
![设置主机名-Debian10][12]
|
||||
|
||||
下一步,确定域名。如果你的电脑不在域中,直接点击 “<ruby>继续<rt>Continue</rt></ruby>”按钮。
|
||||
|
||||
![设置域名-Debian10][13]
|
||||
|
||||
然后,如图所示,设置 root 密码,点击 “<ruby>继续<rt>Continue</rt></ruby>”。
|
||||
|
||||
![设置 root 密码-Debian10][14]
|
||||
|
||||
下一步骤,设置账户的用户全名,点击 “<ruby>继续<rt>Continue</rt></ruby>”。
|
||||
|
||||
![设置用户全名-debain10][15]
|
||||
|
||||
接着,设置与此账户相关联的用户名。
|
||||
|
||||
![指定用户名-Debian10][16]
|
||||
|
||||
下一步,设置用户密码,点击“<ruby>继续<rt>Continue</rt></ruby>”。
|
||||
|
||||
![设置用户密码-Debian10][17]
|
||||
|
||||
然后,设置时区。
|
||||
|
||||
![设置时区-Debian10][18]
|
||||
|
||||
这时,你要为 Debian10 安装创建分区。如果你是新手用户,点击菜单中的第一个选项,“<ruby>使用最大的连续空余空间<rt>Use the largest continuous free space</rt></ruby>”,点击“<ruby>继续<rt>Continue</rt></ruby>”。
|
||||
|
||||
![使用最大的连续空余空间-debian10][19]
|
||||
|
||||
不过,如果你对创建分区有所了解的话,选择“<ruby>手动<rt>Manual</rt></ruby>” 选项,点击 “<ruby>继续<rt>Continue</rt></ruby>”。
|
||||
|
||||
![选择手动-Debain10][20]
|
||||
|
||||
接着,选择被标记为 “<ruby>空余空间<rt>FREE SPACE</rt></ruby>” 的磁盘,点击 “<ruby>继续<rt>Continue</rt></ruby>” 。接下来,点击“<ruby>创建新分区<rt>Create a new partition</rt></ruby>”。
|
||||
|
||||
![创建新分区-Debain10][21]
|
||||
|
||||
下一界面,首先确定交换空间大小。我的交换空间大小为 2GB,点击 “<ruby>继续<rt>Continue</rt></ruby>”。
|
||||
|
||||
![确定交换空间大小-debian10][22]
|
||||
|
||||
点击下一界面的 “<ruby>主分区<rt>Primary</rt></ruby>”,点击“<ruby>继续<rt>Continue</rt></ruby>”。
|
||||
|
||||
![磁盘主分区-Debian10][23]
|
||||
|
||||
选择在磁盘 “<ruby>初始位置<rt>beginning</rt></ruby>” 创建新分区后,点击继续。
|
||||
|
||||
![在初始位置创建-Debain10][24]
|
||||
|
||||
选择 “<ruby>Ext 4 日志文件系统<rt>Ext 4 journaling file system</rt></ruby>”,点击 “<ruby>继续<rt>Continue</rt></ruby>”。
|
||||
|
||||
![选择 Ext4 日志文件系统-debain10][25]
|
||||
|
||||
下个界面选择“<ruby>交换空间<rt>swap space</rt></ruby>” ,点击 “<ruby>继续<rt>Continue</rt></ruby>”。
|
||||
|
||||
![选择交换空间-debian10][26]
|
||||
|
||||
选中 “<ruby>完成此分区设置<rt>done setting the partition</rt></ruby>”,点击 “<ruby>继续<rt>Continue</rt></ruby>”。
|
||||
|
||||
![完成此分区设置-debian10][27]
|
||||
|
||||
返回磁盘分区界面,点击 “<ruby>空余空间<rt>FREE SPACE</rt></ruby>”,点击 “<ruby>继续<rt>Continue</rt></ruby>”。
|
||||
|
||||
![点击空余空间-Debain10][28]
|
||||
|
||||
为了让自己能轻松一点,选中 “<ruby>自动为空余空间分区<rt>Automatically partition the free space</rt></ruby>”后,点击 “<ruby>继续<rt>Continue</rt></ruby>”。
|
||||
|
||||
![自动为空余空间分区-Debain10][29]
|
||||
|
||||
接着点击 “<ruby>将所有文件存储在同一分区(新手用户推荐)<rt>All files in one partition (recommended for new users)</rt></ruby>”。
|
||||
|
||||
![将所有文件存储在同一分区-debian10][30]
|
||||
|
||||
最后, 点击 “<ruby>完成分区设置,并将改动写入磁盘<rt>Finish partitioning and write changes to disk</rt></ruby>” ,点击 “<ruby>继续<rt>Continue</rt></ruby>”。
|
||||
|
||||
![完成分区设置,并将改动写入磁盘][31]
|
||||
|
||||
确定你要将改动写入磁盘,点击 “<ruby>是<rt>Yes</rt></ruby>”。
|
||||
|
||||
![将改动写入磁盘-Debian10][32]
|
||||
|
||||
而后,安装程序会开始安装所有必要的软件包。
|
||||
|
||||
当系统询问是否要扫描其他 CD 时,选择 “<ruby>否<rt>No</rt></ruby>” ,并点击 “<ruby>继续<rt>Continue</rt></ruby>”。
|
||||
|
||||
![扫描其他CD-No-Debain10][33]
|
||||
|
||||
接着,选择离你最近的镜像站点地区,点击 “<ruby>继续<rt>Continue</rt></ruby>”。
|
||||
|
||||
![Debian-镜像站点-国家][34]
|
||||
|
||||
然后,选择最适合你的镜像站点,点击“<ruby>继续<rt>Continue</rt></ruby>”。
|
||||
|
||||
![选择镜像站点][35]
|
||||
|
||||
如果你打算使用代理服务器,在下面输入具体信息,没有的话就留空,点击 “<ruby>继续<rt>Continue</rt></ruby>”。
|
||||
|
||||
![输入代理信息-debian10][36]
|
||||
|
||||
随着安装进程的继续, 你会被问到,是否想参加一个软件包用途调查。你可以选择任意一个选项,之后点击“<ruby>继续<rt>Continue</rt></ruby>”,我选择了“<ruby>否<rt>No</rt></ruby>”。
|
||||
|
||||
![参与调查-debain10][37]
|
||||
|
||||
在软件选择窗口选中你想安装的软件包,点击“<ruby>继续<rt>Continue</rt></ruby>”。
|
||||
|
||||
![软件选择-debian10][38]
|
||||
|
||||
安装程序会将选中的软件一一安装,在这期间,你可以去喝杯咖啡休息一下。
|
||||
|
||||
系统将会询问你,是否要将 grub 的引导装载程序安装到主引导记录表(MBR)上。点击 “<ruby>是<rt>Yes</rt></ruby>”,而后点击 “<ruby>继续<rt>Continue</rt></ruby>”。
|
||||
|
||||
![安装-grub-bootloader-debian10][39]
|
||||
|
||||
接着,选中你想安装 grub 的硬盘,点击“<ruby>继续<rt>Continue</rt></ruby>”。
|
||||
|
||||
![选择硬盘-安装 grub-Debian10][40]
|
||||
|
||||
最后,安装完成,直接点击 “<ruby>继续<rt>Continue</rt></ruby>”。
|
||||
|
||||
![安装完成-重新启动-debian10][41]
|
||||
|
||||
你现在应该会有一个列出 Windows 和 Debian 的 grub 菜单。为了引导 Debian 系统,往下选择 Debian。之后,你就能看见登录界面。输入密码之后,按回车键。
|
||||
|
||||
![Debian10-登录][42]
|
||||
|
||||
这就完成了!这样,你就拥有了一个全新的 Debian 10 和 Windows 10 双系统。
|
||||
|
||||
![Debian10-Buster-Details][43]
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.linuxtechi.com/dual-boot-windows-10-debian-10/
|
||||
|
||||
作者:[James Kiarie][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[wenwensnow](https://github.com/wenwensnow)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://www.linuxtechi.com/author/james/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7
|
||||
[2]: https://www.linuxtechi.com/wp-content/uploads/2019/10/How-to-dual-boot-Windows-and-Debian10.jpg
|
||||
[3]: https://www.linuxtechi.com/wp-content/uploads/2019/10/Launch-Run-dialogue.jpg
|
||||
[4]: https://www.linuxtechi.com/wp-content/uploads/2019/10/Disk-management.jpg
|
||||
[5]: https://www.linuxtechi.com/wp-content/uploads/2019/10/Shrink-volume.jpg
|
||||
[6]: https://www.linuxtechi.com/wp-content/uploads/2019/10/Shrink-space.jpg
|
||||
[7]: https://www.linuxtechi.com/wp-content/uploads/2019/10/Unallocated-partition.jpg
|
||||
[8]: https://www.linuxtechi.com/wp-content/uploads/2019/10/Graphical-Install-Debian10.jpg
|
||||
[9]: https://www.linuxtechi.com/wp-content/uploads/2019/10/Select-Language-Debian10.jpg
|
||||
[10]: https://www.linuxtechi.com/wp-content/uploads/2019/10/Select-location-Debain10.jpg
|
||||
[11]: https://www.linuxtechi.com/wp-content/uploads/2019/10/Configure-Keyboard-layout-Debain10.jpg
|
||||
[12]: https://www.linuxtechi.com/wp-content/uploads/2019/10/Set-hostname-Debian10.jpg
|
||||
[13]: https://www.linuxtechi.com/wp-content/uploads/2019/10/Set-domain-name-Debian10.jpg
|
||||
[14]: https://www.linuxtechi.com/wp-content/uploads/2019/10/Set-root-Password-Debian10.jpg
|
||||
[15]: https://www.linuxtechi.com/wp-content/uploads/2019/10/Specify-fullname-user-debain10.jpg
|
||||
[16]: https://www.linuxtechi.com/wp-content/uploads/2019/10/Specify-username-Debian10.jpg
|
||||
[17]: https://www.linuxtechi.com/wp-content/uploads/2019/10/Specify-user-password-Debian10.jpg
|
||||
[18]: https://www.linuxtechi.com/wp-content/uploads/2019/10/Configure-timezone-Debian10.jpg
|
||||
[19]: https://www.linuxtechi.com/wp-content/uploads/2019/10/Use-largest-continuous-free-space-debian10.jpg
|
||||
[20]: https://www.linuxtechi.com/wp-content/uploads/2019/10/Select-Manual-Debain10.jpg
|
||||
[21]: https://www.linuxtechi.com/wp-content/uploads/2019/10/Create-new-partition-Debain10.jpg
|
||||
[22]: https://www.linuxtechi.com/wp-content/uploads/2019/10/Define-swap-space-debian10.jpg
|
||||
[23]: https://www.linuxtechi.com/wp-content/uploads/2019/10/Partition-Disks-Primary-Debain10.jpg
|
||||
[24]: https://www.linuxtechi.com/wp-content/uploads/2019/10/Start-at-the-beginning-Debain10.jpg
|
||||
[25]: https://www.linuxtechi.com/wp-content/uploads/2019/10/Select-Ext4-Journaling-system-debain10.jpg
|
||||
[26]: https://www.linuxtechi.com/wp-content/uploads/2019/10/Select-swap-debain10.jpg
|
||||
[27]: https://www.linuxtechi.com/wp-content/uploads/2019/10/Done-setting-partition-debian10.jpg
|
||||
[28]: https://www.linuxtechi.com/wp-content/uploads/2019/10/Click-Free-space-Debain10.jpg
|
||||
[29]: https://www.linuxtechi.com/wp-content/uploads/2019/10/Automatically-partition-free-space-Debain10.jpg
|
||||
[30]: https://www.linuxtechi.com/wp-content/uploads/2019/10/All-files-in-one-partition-debian10.jpg
|
||||
[31]: https://www.linuxtechi.com/wp-content/uploads/2019/10/Finish-partitioning-write-changes-to-disk.jpg
|
||||
[32]: https://www.linuxtechi.com/wp-content/uploads/2019/10/Write-changes-to-disk-Yes-Debian10.jpg
|
||||
[33]: https://www.linuxtechi.com/wp-content/uploads/2019/10/Scan-another-CD-No-Debain10.jpg
|
||||
[34]: https://www.linuxtechi.com/wp-content/uploads/2019/10/Debian-archive-mirror-country.jpg
|
||||
[35]: https://www.linuxtechi.com/wp-content/uploads/2019/10/Select-Debian-archive-mirror.jpg
|
||||
[36]: https://www.linuxtechi.com/wp-content/uploads/2019/10/Enter-proxy-details-debian10.jpg
|
||||
[37]: https://www.linuxtechi.com/wp-content/uploads/2019/10/Participate-in-survey-debain10.jpg
|
||||
[38]: https://www.linuxtechi.com/wp-content/uploads/2019/10/Software-selection-debian10.jpg
|
||||
[39]: https://www.linuxtechi.com/wp-content/uploads/2019/10/Install-grub-bootloader-debian10.jpg
|
||||
[40]: https://www.linuxtechi.com/wp-content/uploads/2019/10/Select-hard-drive-install-grub-Debian10.jpg
|
||||
[41]: https://www.linuxtechi.com/wp-content/uploads/2019/10/Installation-complete-reboot-debian10.jpg
|
||||
[42]: https://www.linuxtechi.com/wp-content/uploads/2019/10/Debian10-log-in.jpg
|
||||
[43]: https://www.linuxtechi.com/wp-content/uploads/2019/10/Debian10-Buster-Details.jpg
|
@ -0,0 +1,132 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (wxy)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11592-1.html)
|
||||
[#]: subject: (How I used the wget Linux command to recover lost images)
|
||||
[#]: via: (https://opensource.com/article/19/10/how-community-saved-artwork-creative-commons)
|
||||
[#]: author: (Seth Kenlon https://opensource.com/users/seth)
|
||||
|
||||
丢失的开放剪贴画库和新的公共艺术品图书馆 FreeSVG.org 的诞生
|
||||
======
|
||||
|
||||
> 开放剪贴画库兴衰的故事以及一个新的公共艺术品图书馆 FreeSVG.org 的诞生。
|
||||
|
||||

|
||||
|
||||
<ruby>开放剪贴画库<rt>Open Clip Art Library</rt></ruby>(OCAL)发布于 2004 年,成为了免费插图的来源,任何人都可以出于任何目的使用它们,而无需注明出处或提供任何回报。针对 1990 年代每个家庭办公室书架上的大量剪贴画 CD 以及由闭源公司和艺术品软件提供的艺术品转储,这个网站是开源世界的回应。
|
||||
|
||||
最初,这个剪贴画库主要由一些贡献者提供,但是在 2010 年,它重新打造成了一个全新的交互式网站,可以让任何人使用矢量插图应用程序创建和贡献剪贴画。该网站立即获得了来自全球的、各种形式的自由软件和自由文化项目的贡献。[Inkscape][2] 中甚至包含了该库的专用导入器。
|
||||
|
||||
但是,在 2019 年初,托管开放剪贴画库的网站离线了,没有任何警告或解释。它已经成长为有着成千上万的人的社区,起初以为这是暂时的故障。但是,这个网站一直离线已超过六个月,而没有任何清楚的解释。
|
||||
|
||||
谣言开始膨胀。该网站一直在更新中(“要偿还数年的技术债务”,网站开发者 Jon Philips 在一封电子邮件中说)。一个 Twitter 帐户声称,该网站遭受了猖狂的 DDoS 攻击。另一个 Twitter 帐户声称,该网站维护者已经成为身份盗用的牺牲品。今天,在撰写本文时,该网站的一个且唯一的页面声明它处于“维护和保护模式”,其含义不清楚,只是用户无法访问其内容。
|
||||
|
||||
### 恢复公地
|
||||
|
||||
网站会随着时间的流逝而消失,但是对其社区而言,开放剪贴画库的丢失尤其令人惊讶,因为它被视为一个社区项目。很少有社区成员知道托管该库的网站已经落入单个维护者手中,因此,由于 [CC0 许可证][3],该库中的艺术品归所有人所有,但对它的访问是由单个维护者功能性拥有的。而且,由于该社区通过网站彼此保持联系,因此该维护者实际上拥有该社区。
|
||||
|
||||
当网站发生故障时,社区以及成员彼此之间都无法访问剪贴画。没有该网站,就没有社区。
|
||||
|
||||
最初,该网站离线后其上的所有东西都是被封锁的。不过,在几个月之后,用户开始意识到该网站的数据仍然在线,这意味着用户能够通过输入精确的 URL 访问单个剪贴画。换句话说,你不能通过在网站上到处点击来浏览剪贴画文件,但是如果你确切地知道该地址,你就可以在浏览器中访问它。类似的,技术型(或偷懒的)用户意识到能够通过类似 `wget` 的自动 Web 浏览器将网站“抓取”下来。
|
||||
|
||||
Linux 的 `wget` 命令从技术上来说是一个 Web 浏览器,虽然它不能让你像用 Firefox 一样交互式地浏览。相反,`wget` 可以连到互联网,获取文件或文件集,并下载到你的本次硬盘。然后,你可以在 Firefox、文本编辑器或最合适的应用程序中打开这些文件,查看内容。
|
||||
|
||||
通常,`wget` 需要知道要提取的特定文件。如果你使用的是安装了 `wget` 的 Linux 或 macOS,则可以通过下载 [example.com][4] 的索引页来尝试此过程:
|
||||
|
||||
```
|
||||
$ wget example.org/index.html
|
||||
[...]
|
||||
$ tail index.html
|
||||
|
||||
<body><div>
|
||||
<h1>Example Domain</h1>
|
||||
<p>This domain is for illustrative examples in documents.
|
||||
You may use this domain in examples without permission.</p>
|
||||
<p><a href="http://www.iana.org/domains/example">More info</a></p>
|
||||
</div></body></html>
|
||||
```
|
||||
|
||||
为了抓取 OCAL,我使用了 `--mirror` 选项,以便可以只是将 `wget` 指向到包含剪贴画的目录,就可以下载该目录中的所有内容。此操作持续下载了连续四天(96 个小时),最终得到了超过 50,000 个社区成员贡献的 100,000 个 SVG 文件。不幸的是,任何没有适当元数据的文件的作者信息都是无法恢复的,因为此信息被锁定在该数据库中不可访问的文件中,但是 CC0 许可证意味着此问题*在技术上*无关紧要(因为 CC0 文件不需要归属)。
|
||||
|
||||
随意分析了一下下载的文件进行还显示,其中近 45,000 个文件是同一个文件(该网站的徽标)的副本。这是由于指向该网站徽标的重定向引起的(原因未知),仔细分析能够提取到原始的文件,又过了 96 个小时,并且恢复了直到最后一天发布在 OCAL 上的所有剪贴画:总共约有 156,000 张图像。
|
||||
|
||||
SVG 文件通常很小,但这仍然是大量工作,并且会带来一些非常实际的问题。首先,将需要数 GB 的在线存储空间,这样这些剪贴画才能供其先前的社区使用。其次,必须使用一种搜索剪贴画的方法,因为手动浏览 55,000 个文件是不现实的。
|
||||
|
||||
很明显,社区真正需要的是一个平台。
|
||||
|
||||
### 构建新的平台
|
||||
|
||||
一段时间以来,[公共领域矢量图][6] 网站一直在发布公共领域的矢量图。虽然它仍然是一个受欢迎的网站,但是开源用户通常只是将其用作辅助的图片资源,因为其中大多数文件都是 EPS 和 AI 格式的,这两者均与 Adobe 相关。这两种文件格式通常都可以转换为 SVG,但是特性会有所损失。
|
||||
|
||||
当公共领域矢量图网站的维护者(Vedran 和 Boris)得知 OCAL 丢失时,他们决定创建一个面向开源社区的网站。诚然,他们选择了开源 [Laravel][7] 框架作为后端,该框架为网站提供了管理控制台和用户访问权限。该框架功能强大且开发完善,还使他们能够快速响应错误报告和功能请求,并根据需要升级网站。他们正在建立的网站称为 [FreeSVG.org][8],已经是一个强大而繁荣的公共艺术品图书馆。
|
||||
|
||||
从那时起,他们就一直从 OCAL 上载所有剪贴画,并且他们甚至在努力地对这些剪贴画进行标记和分类。作为公共领域矢量图网站的创建者,他们还以 SVG 格式贡献了自己的图像。他们的目标是成为互联网上具有 CC0 许可证的 SVG 图像的主要资源。
|
||||
|
||||
### 贡献
|
||||
|
||||
[FreeSVG.org][8] 的维护者意识到他们已经继承了重要的管理权。他们正在努力对网站上的所有图像加上标题和描述,以便用户可以轻松找到这些剪贴画,并在准备就绪后将其提供给社区,同时坚信同这些剪贴画一样,与这些剪贴画有关的元数据属于创建和使用它们的人。他们还意识到可能会发生无法预料的情况,因此他们会定期为其网站和内容创建备份,并打算在其网站出现故障时向公众提供最新备份。
|
||||
|
||||
如果要为 [FreeSVG.org][9]的知识共享内容添砖加瓦,请下载 [Inkscape][10] 并开始绘制。世界上有很多公共领域的艺术品,例如[历史广告][11]、[塔罗牌][12]和[故事书][13],只是在等待转换为 SVG,因此即使你对自己的绘画技巧没有信心你也可以做出贡献。访问 [FreeSVG 论坛][14]与其他贡献者联系并支持他们。
|
||||
|
||||
*公地*的概念很重要。无论你是学生、老师、图书馆员、小企业主还是首席执行官,[知识共享都会使所有人受益][15]。如果你不直接捐款,那么你随时可以帮助推广。
|
||||
|
||||
这是自由文化的力量:它不仅可以扩展,而且随着更多人的参与,它会变得更好。
|
||||
|
||||
### 艰辛的教训
|
||||
|
||||
从 OCAL 的消亡到 FreeSVG.org 的兴起,开放文化社区已经吸取了一些艰辛的经验。对于以后,以下是我认为最重要的那些。
|
||||
|
||||
#### 维护你的元数据
|
||||
|
||||
如果你是内容创建者,请帮助将来的档案管理员,将元数据添加到文件中。大多数图像、音乐、字体和视频文件格式都可以嵌入 EXIF 数据,其他格式在创建它们的应用程序中具有元数据输入界面。勤于用你的姓名、网站或公共电子邮件以及许可证来标记你的作品。
|
||||
|
||||
#### 做个副本
|
||||
|
||||
不要以为别人在做备份。如果你关心公用数字内容,请自己备份,否则不要指望永远提供它。无论*任何上传到互联网上的内容是永久的*的说法是不是正确的,但这并不意味着你永远可以使用。如果 OCAL 文件不再暗地可用,那么任何人都不太可能成功地从网络上的某个位置或从全球范围内的人们的硬盘中成功地发现全部的 55,000 张图像。
|
||||
|
||||
#### 创建外部渠道
|
||||
|
||||
如果一个社区是由单个网站或实际位置来定义的,那么该社区失去访问该空间的能力就如同解散了一样。如果你是由单个组织或网站驱动的社区的成员,则你应该自己与关心的人共享联系信息,并即使在该网站不可用时也可以建立沟通渠道。
|
||||
|
||||
例如,[Opensource.com][16] 本身维护其作者和通讯者的邮件列表和其他异地渠道,以便在有或没有网站干预或甚至没有网站的情况下相互交流。
|
||||
|
||||
#### 自由文化值得为此努力
|
||||
|
||||
互联网有时被视为懒人社交俱乐部。你可以在需要时登录并在感到疲倦时将其关闭,也可以漫步到所需的任何社交圈。
|
||||
|
||||
但实际上,自由文化可能是项艰难的工作。但是这种艰难从某种意义上讲并不是说要成为其中的一分子很困难,而是你必须努力维护。如果你忽略你所在的社区,那么该社区可能会在你意识到之前就枯萎并褪色。
|
||||
|
||||
花点时间环顾四周,确定你属于哪个社区,如果不是,那么请告诉某人你对他们带给你生活的意义表示赞赏。同样重要的是,请记住,这样你也为社区的生活做出了贡献。
|
||||
|
||||
几周前,知识共享组织在华沙举行了它的全球峰会,令人惊叹的国际盛会...
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/19/10/how-community-saved-artwork-creative-commons
|
||||
|
||||
作者:[Seth Kenlon][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[wxy](https://github.com/wxy)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [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/tribal_pattern_shoes.png?itok=e5dSf2hS (White shoes on top of an orange tribal pattern)
|
||||
[2]: https://opensource.com/article/18/1/inkscape-absolute-beginners
|
||||
[3]: https://creativecommons.org/share-your-work/public-domain/cc0/
|
||||
[4]: http://example.com
|
||||
[5]: http://www.iana.org/domains/example"\>More
|
||||
[6]: http://publicdomainvectors.org
|
||||
[7]: https://github.com/viralsolani/laravel-adminpanel
|
||||
[8]: https://freesvg.org
|
||||
[9]: http://freesvg.org
|
||||
[10]: http://inkscape.org
|
||||
[11]: https://freesvg.org/drinking-coffee-vector-drawing
|
||||
[12]: https://freesvg.org/king-of-swords-tarot-card
|
||||
[13]: https://freesvg.org/space-pioneers-135-scene-vector-image
|
||||
[14]: http://forum.freesvg.org/
|
||||
[15]: https://opensource.com/article/18/1/creative-commons-real-world
|
||||
[16]: http://Opensource.com
|
@ -0,0 +1,79 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (wxy)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11586-1.html)
|
||||
[#]: subject: (Why I made the switch from Mac to Linux)
|
||||
[#]: via: (https://opensource.com/article/19/10/why-switch-mac-linux)
|
||||
[#]: author: (Matthew Broberg https://opensource.com/users/mbbroberg)
|
||||
|
||||
为什么我从 Mac 换到了 Linux
|
||||
======
|
||||
|
||||
> 感谢这么多的开源开发人员,日常使用 Linux 比以往任何时候都容易得多。
|
||||
|
||||

|
||||
|
||||
自 2004 年开始从事 IT 工作以来,我一直是 Mac 的忠实粉丝。但是几个月前,由于种种原因,我决定将 Linux 用作日常使用的系统。这不是我第一次尝试完全采用 Linux,但是我发现它比以往更加容易。下面是促使我转换的原因。
|
||||
|
||||
### 我在个人电脑上的首次 Linux 体验
|
||||
|
||||
我记得,我抬头看着投影机,而它和我面面相觑。我们俩都不明白为什么它不显示。VGA 线完全接好了,针脚也没有弯折。我按了我所有想到的可能的按键组合,以向我的笔记本电脑发出信号,想让它克服“舞台恐惧症”。
|
||||
|
||||
我在大学里运行 Linux 只是作为实验。而我在 IT 部门的经理是多种口味的倡导者,随着我对桌面支持和编写脚本的信心增强,我想了解更多 Linux 的信息。对我来说,IT 比我的计算机科学学位课程有趣得多,课程的感觉是如此抽象和理论化:“二叉树有啥用?”,我如是想 —— 而我们的系统管理员团队的工作却是如此的真真切切。
|
||||
|
||||
这个故事的结尾是,我登录到 Windows 工作站完成了我的课堂演讲,这标志着我将 Linux 作为我的日常操作系统的第一次尝试的终结。我很欣赏 Linux 的灵活性,但是它缺乏兼容性。我偶尔会写个脚本,脚本通过 SSH 连接到一个机器中以运行另一个脚本,但是我对 Linux 的日常使用仅止于此。
|
||||
|
||||
### 对 Linux 兼容性的全新印象
|
||||
|
||||
几个月前,当我决定再试一次 Linux 时,我曾觉得我遇到更多的兼容性噩梦,但我错了。
|
||||
|
||||
安装过程完成后,我立即插入了 USB-C 集线器以了解兼容性到底如何。一切立即工作。连接 HDMI 的超宽显示器作为镜像显示器弹出到我的笔记本电脑屏幕上,我轻松地将其调整为第二台显示器。USB 连接的网络摄像头对我的[在家工作方式][2]至关重要,它可以毫无问题地显示视频。甚至自从我使用 Mac 以来就一直插在集线器的 Mac 充电器可以为我的非常不 Mac 的硬件充电。
|
||||
|
||||
我的正面体验可能与 USB-C 的一些更新有关,它在 2018 年得到一些所需的关注,因此才能与其他操作系统的体验相媲美。正如 [Phoronix 解释的那样][3]:
|
||||
|
||||
> “USB Type-C 接口为非 USB 信号提供了‘替代模式’扩展,在规范中该替代模式的最大使用场景是支持 DisplayPort。除此之外,另一个替代模式是支持 Thunderbolt 3。DisplayPort 替代模式支持 4K 甚至 8Kx4K 的视频输出,包括多声道音频。
|
||||
>
|
||||
> “虽然 USB-C 替代模式和 DisplayPort 已经存在了一段时间,并且在 Windows 上很常见,但是主线 Linux 内核不支持此功能。所幸的是,多亏英特尔,这种情况正在改变。”
|
||||
>
|
||||
|
||||
而在端口之外,快速浏览一下 [笔记本电脑 Linux][4] 的硬件选择,列出了比我 2000 年代初期所经历的更加完整的选择集。
|
||||
|
||||
与我第一次尝试采用 Linux 相比,这已经天差地别,这是我张开双臂欢迎的。
|
||||
|
||||
### 突破 Apple 的樊篱
|
||||
|
||||
使用 Linux 给我的日常工作流程增加了一些新的麻烦,而我喜欢这种麻烦。
|
||||
|
||||
我的 Mac 工作流程是无缝的:早上打开 iPad,写下关于我今天想要做什么的想法,然后开始在 Safari 中阅读一些文章;移到我的 iPhone 上可以继续阅读;然后登录我的 MacBook,这些地方我进行了多年的微调,已经弄清楚了所有这些部分之间的连接方式。键盘快捷键已内置在我的大脑中;用户体验一如既往。简直不要太舒服了。
|
||||
|
||||
这种舒适需要付出代价。我基本上忘记了我的环境如何运作的,也无法解答我想解答的问题。我是否自定义了一些 [PLIST 文件][5]以获得快捷方式,是不是记得将其签入[我的 dotfiles][6] 当中?当 Firefox 的功能更好时,我为何还如此依赖 Safari 和 Chrome?为什么我不使用基于 Android 的手机代替我的 i-系列产品呢?
|
||||
|
||||
关于这一点,我经常考虑改用基于 Android 的手机,但是我会失去在所有这些设备之间的连接性以及为这种生态系统设计的一些便利。例如,我将无法在 iPhone 上为 Apple TV 输入搜索内容,也无法与其他用 Apple 的朋友用 AirDrop 共享密码。这些功能是同类设备环境的巨大好处,并且是一项了不起的工程。也就是说,这些便利是被生态系统所困的代价。
|
||||
|
||||
我喜欢了解设备的工作方式。我希望能够解释使我的系统变得有趣或容易使用的环境配置,但我也想看看增加一些麻烦对我的观点有什么影响。用 [Marcel Proust][7] 的话来说,“真正的发现之旅不在于寻找新的土地,而在于用新的眼光来看待。”技术的使用是如此的方便,以至于我不再对它的工作原理感到好奇,而 Linux 使我有机会再次有了新的眼光。
|
||||
|
||||
### 受你的启发
|
||||
|
||||
以上所有内容足以成为探索 Linux 的理由,但我也受到了你的启发。尽管所有操作系统都受到开源社区的欢迎,但 Opensource.com 的作者和读者对 Linux 的喜悦是充满感染力的。它激发了我重新潜入的乐趣,我享受这段旅途的乐趣。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/19/10/why-switch-mac-linux
|
||||
|
||||
作者:[Matthew Broberg][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[wxy](https://github.com/wxy)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/mbbroberg
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/programming-code-keyboard-laptop.png?itok=pGfEfu2S (Hands programming)
|
||||
[2]: https://opensource.com/article/19/8/rules-remote-work-sanity
|
||||
[3]: https://www.phoronix.com/scan.php?page=news_item&px=Linux-USB-Type-C-Port-DP-Driver
|
||||
[4]: https://www.linux-laptop.net/
|
||||
[5]: https://fileinfo.com/extension/plist
|
||||
[6]: https://opensource.com/article/19/3/move-your-dotfiles-version-control
|
||||
[7]: https://www.age-of-the-sage.org/quotations/proust_having_seeing_with_new_eyes.html
|
@ -0,0 +1,282 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11572-1.html)
|
||||
[#]: subject: (How to Install and Configure Nagios Core on CentOS 8 / RHEL 8)
|
||||
[#]: via: (https://www.linuxtechi.com/install-nagios-core-rhel-8-centos-8/)
|
||||
[#]: author: (James Kiarie https://www.linuxtechi.com/author/james/)
|
||||
|
||||
如何在 CentOS 8/RHEL 8 上安装和配置 Nagios Core
|
||||
======
|
||||
|
||||
Nagios 是一个自由开源的网络和警报引擎,它用于监控各种设备,例如网络设备和网络中的服务器。它支持 Linux 和 Windows,并提供了直观的 Web 界面,可让你轻松监控网络资源。经过专业配置后,它可以在服务器或网络设备下线或者故障时向你发出邮件警报。在本文中,我们说明了如何在 RHEL 8/CentOS 8 上安装和配置 Nagios Core。
|
||||
|
||||
![Install-Nagios-Core-RHEL8-CentOS8][2]
|
||||
|
||||
### Nagios Core 的先决条件
|
||||
|
||||
在开始之前,请先检查并确保有以下各项:
|
||||
|
||||
* RHEL 8/CentOS 8 环境
|
||||
* 能通过 SSH 访问该环境
|
||||
* 快速稳定的互联网连接
|
||||
|
||||
满足上述要求后,我们开始吧!
|
||||
|
||||
### 步骤 1:安装 LAMP
|
||||
|
||||
为了使 Nagios 能够按预期工作,你需要安装 LAMP 或其他 Web 软件,因为它们将在浏览器上运行。为此,请执行以下命令:
|
||||
|
||||
```
|
||||
# dnf install httpd mariadb-server php-mysqlnd php-fpm
|
||||
```
|
||||
|
||||
![Install-LAMP-stack-CentOS8][3]
|
||||
|
||||
你需要确保 Apache Web 服务器已启动并正在运行。为此,请使用以下命令启用并启动 Apache 服务器:
|
||||
|
||||
```
|
||||
# systemctl start httpd
|
||||
# systemctl enable httpd
|
||||
```
|
||||
|
||||
![Start-enable-httpd-centos8][4]
|
||||
|
||||
检查 Apache 服务器运行状态:
|
||||
|
||||
```
|
||||
# systemctl status httpd
|
||||
```
|
||||
|
||||
![Check-status-httpd-centos8][5]
|
||||
|
||||
接下来,我们需要启用并启动 MariaDB 服务器,运行以下命令:
|
||||
|
||||
```
|
||||
# systemctl start mariadb
|
||||
# systemctl enable mariadb
|
||||
```
|
||||
|
||||
![Start-enable-MariaDB-CentOS8][6]
|
||||
|
||||
要检查 MariaDB 状态,请运行:
|
||||
|
||||
```
|
||||
# systemctl status mariadb
|
||||
```
|
||||
|
||||
![Check-MariaDB-status-CentOS8][7]
|
||||
|
||||
另外,你可能会考虑加强或保护服务器,使其不容易受到未经授权的访问。要保护服务器,请运行以下命令:
|
||||
|
||||
```
|
||||
# mysql_secure_installation
|
||||
```
|
||||
|
||||
确保为你的 MySQL 实例设置一个强密码。对于后续提示,请输入 “Y” 并按回车。
|
||||
|
||||
![Secure-MySQL-server-CentOS8][8]
|
||||
|
||||
### 步骤 2:安装必需的软件包
|
||||
|
||||
除了安装 LAMP 外,还需要一些其他软件包来安装和正确配置 Nagios。因此,如下所示安装软件包:
|
||||
|
||||
```
|
||||
# dnf install gcc glibc glibc-common wget gd gd-devel perl postfix
|
||||
```
|
||||
|
||||
![Install-requisite-packages-CentOS8][9]
|
||||
|
||||
### 步骤 3:创建 Nagios 用户帐户
|
||||
|
||||
接下来,我们需要为 Nagios 用户创建一个用户帐户。为此,请运行以下命令:
|
||||
|
||||
```
|
||||
# adduser nagios
|
||||
# passwd nagios
|
||||
```
|
||||
|
||||
![Create-new-user-for-Nagios][10]
|
||||
|
||||
现在,我们需要为 Nagios 创建一个组,并将 Nagios 用户添加到该组中。
|
||||
|
||||
```
|
||||
# groupadd nagiosxi
|
||||
```
|
||||
|
||||
现在添加 Nagios 用户到组中:
|
||||
|
||||
```
|
||||
# usermod -aG nagiosxi nagios
|
||||
```
|
||||
|
||||
另外,将 Apache 用户添加到 Nagios 组:
|
||||
|
||||
```
|
||||
# usermod -aG nagiosxi apache
|
||||
```
|
||||
|
||||
![Add-Nagios-group-user][11]
|
||||
|
||||
### 步骤 4:下载并安装 Nagios Core
|
||||
|
||||
现在,我们可以继续安装 Nagios Core。Nagios 4.4.5 的最新稳定版本于 2019 年 8 月 19 日发布。但首先,请从它的官方网站下载 Nagios tarball 文件。
|
||||
|
||||
要下载 Nagios Core,请首进入 `/tmp` 目录:
|
||||
|
||||
```
|
||||
# cd /tmp
|
||||
```
|
||||
|
||||
接下来下载 tarball 文件:
|
||||
|
||||
```
|
||||
# wget https://assets.nagios.com/downloads/nagioscore/releases/nagios-4.4.5.tar.gz
|
||||
```
|
||||
|
||||
![Download-Nagios-CentOS8][12]
|
||||
|
||||
下载完 tarball 文件后,使用以下命令将其解压缩:
|
||||
|
||||
```
|
||||
# tar -xvf nagios-4.4.5.tar.gz
|
||||
```
|
||||
|
||||
接下来,进入未压缩的文件夹:
|
||||
|
||||
```
|
||||
# cd nagios-4.4.5
|
||||
```
|
||||
|
||||
按此顺序运行以下命令:
|
||||
|
||||
```
|
||||
# ./configure --with-command-group=nagcmd
|
||||
# make all
|
||||
# make install
|
||||
# make install-init
|
||||
# make install-daemoninit
|
||||
# make install-config
|
||||
# make install-commandmode
|
||||
# make install-exfoliation
|
||||
```
|
||||
|
||||
要配置 Apache,请运行以下命令:
|
||||
|
||||
```
|
||||
# make install-webconf
|
||||
```
|
||||
|
||||
### 步骤 5:配置 Apache Web 服务器身份验证
|
||||
|
||||
接下来,我们将为用户 `nagiosadmin` 设置身份验证。请注意不要更改该用户名,否则,可能会要求你进一步的配置,这可能很繁琐。
|
||||
|
||||
要设置身份验证,请运行以下命令:
|
||||
|
||||
```
|
||||
# htpasswd -c /usr/local/nagios/etc/htpasswd.users nagiosadmin
|
||||
```
|
||||
|
||||
![Configure-Apache-webserver-authentication-CentOS8][13]
|
||||
|
||||
系统将提示你输入 `nagiosadmin` 用户的密码。输入并按要求确认密码。在本教程结束时,你将使用该用户登录 Nagios。
|
||||
|
||||
为使更改生效,请重新启动 Web 服务器:
|
||||
|
||||
```
|
||||
# systemctl restart httpd
|
||||
```
|
||||
|
||||
### 步骤 6:下载并安装 Nagios 插件
|
||||
|
||||
插件可以扩展 Nagios 服务器的功能。它们将帮助你监控各种服务、网络设备和应用。要下载插件的 tarball 文件,请运行以下命令:
|
||||
|
||||
```
|
||||
# wget https://nagios-plugins.org/download/nagios-plugins-2.2.1.tar.gz
|
||||
```
|
||||
|
||||
接下来,解压 tarball 文件并进入到未压缩的插件文件夹:
|
||||
|
||||
```
|
||||
# tar -xvf nagios-plugins-2.2.1.tar.gz
|
||||
# cd nagios-plugins-2.2.1
|
||||
```
|
||||
|
||||
要安装插件,请编译源代码,如下所示:
|
||||
|
||||
```
|
||||
# ./configure --with-nagios-user=nagios --with-nagios-group=nagiosxi
|
||||
# make
|
||||
# make install
|
||||
```
|
||||
|
||||
### 步骤 7:验证和启动 Nagios
|
||||
|
||||
成功安装 Nagios 插件后,验证 Nagios 配置以确保一切良好,并且配置中没有错误:
|
||||
|
||||
```
|
||||
# /usr/local/nagios/bin/nagios -v /usr/local/nagios/etc/nagios.cfg
|
||||
```
|
||||
|
||||
![Verify-Nagios-settings-CentOS8][14]
|
||||
|
||||
接下来,启动 Nagios 并验证其状态:
|
||||
|
||||
```
|
||||
# systemctl start nagios
|
||||
# systemctl status nagios
|
||||
```
|
||||
|
||||
![Start-check-status-Nagios-CentOS8][15]
|
||||
|
||||
如果系统中有防火墙,那么使用以下命令允许 ”80“ 端口:
|
||||
|
||||
```
|
||||
# firewall-cmd --permanent --add-port=80/tcp# firewall-cmd --reload
|
||||
```
|
||||
|
||||
### 步骤 8:通过 Web 浏览器访问 Nagios 面板
|
||||
|
||||
要访问 Nagios,请打开服务器的 IP 地址,如下所示:<http://server-ip/nagios> 。
|
||||
|
||||
这将出现一个弹出窗口,提示输入我们在步骤 5 创建的用户名和密码。输入凭据并点击“Sign In”。
|
||||
|
||||
![Access-Nagios-via-web-browser-CentOS8][16]
|
||||
|
||||
这将引导你到 Nagios 面板,如下所示:
|
||||
|
||||
![Nagios-dashboard-CentOS8][17]
|
||||
|
||||
我们终于成功地在 CentOS 8 / RHEL 8 上安装和配置了 Nagios Core。欢迎你的反馈。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.linuxtechi.com/install-nagios-core-rhel-8-centos-8/
|
||||
|
||||
作者:[James Kiarie][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://www.linuxtechi.com/author/james/
|
||||
[b]: https://github.com/lujun9972
|
||||
[2]: https://www.linuxtechi.com/wp-content/uploads/2019/10/Install-Nagios-Core-RHEL8-CentOS8.jpg
|
||||
[3]: https://www.linuxtechi.com/wp-content/uploads/2019/10/Install-LAMP-stack-CentOS8.jpg
|
||||
[4]: https://www.linuxtechi.com/wp-content/uploads/2019/10/Start-enable-httpd-centos8.jpg
|
||||
[5]: https://www.linuxtechi.com/wp-content/uploads/2019/10/Check-status-httpd-centos8.jpg
|
||||
[6]: https://www.linuxtechi.com/wp-content/uploads/2019/10/Start-enable-MariaDB-CentOS8.jpg
|
||||
[7]: https://www.linuxtechi.com/wp-content/uploads/2019/10/Check-MariaDB-status-CentOS8.jpg
|
||||
[8]: https://www.linuxtechi.com/wp-content/uploads/2019/10/Secure-MySQL-server-CentOS8.jpg
|
||||
[9]: https://www.linuxtechi.com/wp-content/uploads/2019/10/Install-requisite-packages-CentOS8.jpg
|
||||
[10]: https://www.linuxtechi.com/wp-content/uploads/2019/10/Create-new-user-for-Nagios.jpg
|
||||
[11]: https://www.linuxtechi.com/wp-content/uploads/2019/10/Add-Nagios-group-user.jpg
|
||||
[12]: https://www.linuxtechi.com/wp-content/uploads/2019/10/Download-Nagios-CentOS8.jpg
|
||||
[13]: https://www.linuxtechi.com/wp-content/uploads/2019/10/Configure-Apache-webserver-authentication-CentOS8.jpg
|
||||
[14]: https://www.linuxtechi.com/wp-content/uploads/2019/10/Verify-Nagios-settings-CentOS8.jpg
|
||||
[15]: https://www.linuxtechi.com/wp-content/uploads/2019/10/Start-check-status-Nagios-CentOS8.jpg
|
||||
[16]: https://www.linuxtechi.com/wp-content/uploads/2019/10/Access-Nagios-via-web-browser-CentOS8.jpg
|
||||
[17]: https://www.linuxtechi.com/wp-content/uploads/2019/10/Nagios-dashboard-CentOS8.jpg
|
||||
|
@ -0,0 +1,187 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (wxy)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11595-1.html)
|
||||
[#]: subject: (What you probably didn’t know about sudo)
|
||||
[#]: via: (https://opensource.com/article/19/10/know-about-sudo)
|
||||
[#]: author: (Peter Czanik https://opensource.com/users/czanik)
|
||||
|
||||
关于 sudo 你可能不知道的
|
||||
======
|
||||
|
||||
> 觉得你已经了解了 sudo 的所有知识了吗?再想想。
|
||||
|
||||

|
||||
|
||||
大家都知道 `sudo`,对吗?默认情况下,该工具已安装在大多数 Linux 系统上,并且可用于大多数 BSD 和商业 Unix 变体。不过,在与数百名 `sudo` 用户交谈之后,我得到的最常见的答案是 `sudo` 是一个使生活复杂化的工具。
|
||||
|
||||
有 root 用户和 `su` 命令,那么为什么还要使用另一个工具呢?对于许多人来说,`sudo` 只是管理命令的前缀。只有极少数人提到,当你在同一个系统上有多个管理员时,可以使用 `sudo` 日志查看谁做了什么。
|
||||
|
||||
那么,`sudo` 是什么? 根据 [sudo 网站][2]:
|
||||
|
||||
> “sudo 允许系统管理员通过授予某些用户以 root 用户或其他用户身份运行某些命令的能力,同时提供命令及其参数的审核记录,从而委派权限。”
|
||||
|
||||
默认情况下,`sudo` 只有简单的配置,一条规则允许一个用户或一组用户执行几乎所有操作(在本文后面的配置文件中有更多信息):
|
||||
|
||||
```
|
||||
%wheel ALL=(ALL) ALL
|
||||
```
|
||||
|
||||
在此示例中,参数表示以下含义:
|
||||
|
||||
* 第一个参数(`%wheel`)定义组的成员。
|
||||
* 第二个参数(`ALL`)定义组成员可以在其上运行命令的主机。
|
||||
* 第三个参数(`(ALL)`)定义了可以执行命令的用户名。
|
||||
* 最后一个参数(`ALL`)定义可以运行的应用程序。
|
||||
|
||||
因此,在此示例中,`wheel` 组的成员可以以所有主机上的所有用户身份运行所有应用程序。但即使是这个一切允许的规则也很有用,因为它会记录谁在计算机上做了什么。
|
||||
|
||||
### 别名
|
||||
|
||||
当然,它不仅可以让你和你最好的朋友管理一个共享机器,你还可以微调权限。你可以将以上配置中的项目替换为列表:用户列表、命令列表等。多数情况下,你可能会复制并粘贴配置中的一些列表。
|
||||
|
||||
在这种情况下,别名可以派上用场。在多个位置维护相同的列表容易出错。你可以定义一次别名,然后可以多次使用。因此,当你对一位管理员不再信任时,将其从别名中删除就行了。使用多个列表而不是别名,很容易忘记从具有较高特权的列表之一中删除用户。
|
||||
|
||||
### 为特定组的用户启用功能
|
||||
|
||||
`sudo` 命令带有大量默认设置。不过,在某些情况下,你想覆盖其中的一些情况,这时你可以在配置中使用 `Defaults` 语句。通常,对每个用户都强制使用这些默认值,但是你可以根据主机、用户名等将设置缩小到一部分用户。这里有个我那一代的系统管理员都喜欢玩的一个示例:“羞辱”。这些只不过是一些有人输入错误密码时的有趣信息:
|
||||
|
||||
```
|
||||
czanik@linux-mewy:~> sudo ls
|
||||
[sudo] password for root:
|
||||
Hold it up to the light --- not a brain in sight! # 把灯举高点,脑仁太小看不到
|
||||
[sudo] password for root:
|
||||
My pet ferret can type better than you! # 我的宠物貂也比你输入的好
|
||||
[sudo] password for root:
|
||||
sudo: 3 incorrect password attempts
|
||||
czanik@linux-mewy:~>
|
||||
```
|
||||
|
||||
由于并非所有人都喜欢系统管理员的这种幽默,因此默认情况下会禁用这些羞辱信息。以下示例说明了如何仅对经验丰富的系统管理员(即 `wheel` 组的成员)启用此设置:
|
||||
|
||||
```
|
||||
Defaults !insults
|
||||
Defaults:%wheel insults
|
||||
```
|
||||
|
||||
我想,感谢我将这些消息带回来的人用两只手也数不过来吧。
|
||||
|
||||
### 摘要验证
|
||||
|
||||
当然,`sudo` 还有更严肃的功能。其中之一是摘要验证。你可以在配置中包括应用程序的摘要:
|
||||
|
||||
```
|
||||
peter ALL = sha244:11925141bb22866afdf257ce7790bd6275feda80b3b241c108b79c88 /usr/bin/passwd
|
||||
```
|
||||
|
||||
在这种情况下,`sudo` 在运行应用程序之前检查应用程序摘要,并将其与配置中存储的摘要进行比较。如果不匹配,`sudo` 拒绝运行该应用程序。尽管很难在配置中维护此信息(没有用于此目的的自动化工具),但是这些摘要可以为你提供额外的保护层。
|
||||
|
||||
### 会话记录
|
||||
|
||||
会话记录也是 `sudo` 鲜为人知的功能。在演示之后,许多人离开我的演讲后就计划在其基础设施上实施它。为什么?因为使用会话记录,你不仅可以看到命令名称,还可以看到终端中发生的所有事情。你可以看到你的管理员在做什么,要不他们用 shell 访问了机器而日志仅会显示启动了 `bash`。
|
||||
|
||||
当前有一个限制。记录存储在本地,因此具有足够的权限的话,用户可以删除他们的痕迹。所以请继续关注即将推出的功能。
|
||||
|
||||
### 插件
|
||||
|
||||
从 1.8 版开始,`sudo` 更改为基于插件的模块化体系结构。通过将大多数功能实现为插件,你可以编写自己的功能轻松地替换或扩展 `sudo` 的功能。已经有了 `sudo` 上的开源和商业插件。
|
||||
|
||||
在我的演讲中,我演示了 `sudo_pair` 插件,该插件可在 [GitHub][3] 上获得。这个插件是用 Rust 开发的,这意味着它不是那么容易编译,甚至更难以分发其编译结果。另一方面,该插件提供了有趣的功能,需要第二个管理员通过 `sudo` 批准(或拒绝)运行命令。不仅如此,如果有可疑活动,可以在屏幕上跟踪会话并终止会话。
|
||||
|
||||
在最近的 All Things Open 会议上的一次演示中,我做了一个臭名昭著的演示:
|
||||
|
||||
```
|
||||
czanik@linux-mewy:~> sudo rm -fr /
|
||||
```
|
||||
|
||||
看着屏幕上显示的命令。每个人都屏住呼吸,想看看我的笔记本电脑是否被毁了,然而它逃过一劫。
|
||||
|
||||
### 日志
|
||||
|
||||
正如我在开始时提到的,日志记录和警报是 `sudo` 的重要组成部分。如果你不会定期检查 `sudo` 日志,那么日志在使用 `sudo` 中并没有太多价值。该工具通过电子邮件提醒配置中指定的事件,并将所有事件记录到 syslog 中。可以打开调试日志用于调试规则或报告错误。
|
||||
|
||||
### 警报
|
||||
|
||||
电子邮件警报现在有点过时了,但是如果你使用 syslog-ng 来收集日志消息,则会自动解析 `sudo` 日志消息。你可以轻松创建自定义警报并将其发送到各种各样的目的地,包括 Slack、Telegram、Splunk 或 Elasticsearch。你可以从[我在 syslong-ng.com 上的博客][4]中了解有关此功能的更多信息。
|
||||
|
||||
### 配置
|
||||
|
||||
我们谈论了很多 `sudo` 功能,甚至还看到了几行配置。现在,让我们仔细看看 `sudo` 的配置方式。配置本身可以在 `/etc/sudoers` 中获得,这是一个简单的文本文件。不过,不建议直接编辑此文件。相反,请使用 `visudo`,因为此工具还会执行语法检查。如果你不喜欢 `vi`,则可以通过将 `EDITOR` 环境变量指向你的首选编辑器来更改要使用的编辑器。
|
||||
|
||||
在开始编辑 `sudo` 配置之前,请确保你知道 root 密码。(是的,即使在默认情况下 root 用户没有密码的 Ubuntu 上也是如此。)虽然 `visudo` 会检查语法,但创建语法正确而将你锁定在系统之外的配置也很容易。
|
||||
|
||||
如果在紧急情况下,而你手头有 root 密码,你也可以直接编辑配置。当涉及到 `sudoers` 文件时,有一件重要的事情要记住:从上到下读取该文件,以最后的设置为准。这个事实对你来说意味着你应该从通用设置开始,并在末尾放置例外情况,否则,通用设置会覆盖例外情况。
|
||||
|
||||
你可以在下面看到一个基于 CentOS 的简单 `sudoers` 文件,并添加我们之前讨论的几行:
|
||||
|
||||
```
|
||||
Defaults !visiblepw
|
||||
Defaults always_set_home
|
||||
Defaults match_group_by_gid
|
||||
Defaults always_query_group_plugin
|
||||
Defaults env_reset
|
||||
Defaults env_keep = "COLORS DISPLAY HOSTNAME HISTSIZE KDEDIR LS_COLORS"
|
||||
Defaults env_keep += "MAIL PS1 PS2 QTDIR USERNAME LANG LC_ADDRESS LC_CTYPE"
|
||||
Defaults secure_path = /sbin:/bin:/usr/sbin:/usr/bin
|
||||
root ALL=(ALL) ALL
|
||||
%wheel ALL=(ALL) ALL
|
||||
Defaults:%wheel insults
|
||||
Defaults !insults
|
||||
Defaults log_output
|
||||
```
|
||||
|
||||
该文件从更改多个默认值开始。然后是通常的默认规则:`root` 用户和 `wheel` 组的成员对计算机具有完全权限。接下来,我们对 `wheel` 组启用“羞辱”,但对其他所有人禁用它们。最后一行启用会话记录。
|
||||
|
||||
上面的配置在语法上是正确的,但是你可以发现逻辑错误吗?是的,有一个:后一个通用设置覆盖了先前的更具体设置,让所有人均禁用了“羞辱”。一旦交换了这两行的位置,设置就会按预期进行:`wheel` 组的成员会收到有趣的消息,但其他用户则不会收到。
|
||||
|
||||
### 配置管理
|
||||
|
||||
一旦必须在多台机器上维护 `sudoers` 文件,你很可能希望集中管理配置。这里主要有两种可能的开源方法。两者都有其优点和缺点。
|
||||
|
||||
你可以使用也用来配置其余基础设施的配置管理应用程序之一:Red Hat Ansible、Puppet 和 Chef 都具有用于配置 `sudo` 的模块。这种方法的问题在于更新配置远非实时。同样,用户仍然可以在本地编辑 `sudoers` 文件并更改设置。
|
||||
|
||||
`sudo` 工具也可以将其配置存储在 LDAP 中。在这种情况下,配置更改是实时的,用户不能弄乱`sudoers` 文件。另一方面,该方法也有局限性。例如,当 LDAP 服务器不可用时,你不能使用别名或使用 `sudo`。
|
||||
|
||||
### 新功能
|
||||
|
||||
新版本的 `sudo` 即将推出。1.9 版将包含许多有趣的新功能。以下是最重要的计划功能:
|
||||
|
||||
* 记录服务可集中收集会话记录,与本地存储相比,它具有许多优点:
|
||||
* 在一个地方搜索更方便。
|
||||
* 即使发送记录的机器关闭,也可以进行记录。
|
||||
* 记录不能被想要删除其痕迹的人删除。
|
||||
* audit 插件没有向 `sudoers` 添加新功能,而是为插件提供了 API,以方便地访问任何类型的 `sudo` 日志。这个插件允许使用插件从 `sudo` 事件创建自定义日志。
|
||||
* approval 插件无需使用第三方插件即可启用会话批准。
|
||||
* 以及我个人最喜欢的:插件的 Python 支持,这使你可以轻松地使用 Python 代码扩展 `sudo`,而不是使用 C 语言进行原生编码。
|
||||
|
||||
### 总结
|
||||
|
||||
希望本文能向你证明 `sudo` 不仅仅是一个简单的命令前缀。有无数种可能性可以微调系统上的权限。你不仅可以微调权限,还可以通过检查摘要来提高安全性。会话记录使你能够检查系统上正在发生的事情。你也可以使用插件扩展 `sudo` 的功能,或者使用已有的插件或编写自己的插件。最后,从即将发布的功能列表中你可以看到,即使 `sudo` 已有数十年的历史,它也是一个不断发展的有生命力的项目。
|
||||
|
||||
如果你想了解有关 `sudo` 的更多信息,请参考以下资源:
|
||||
|
||||
* [sudo 网站][5]
|
||||
* [sudo 博客][6]
|
||||
* [在 Twitter 上关注我们][7]
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/19/10/know-about-sudo
|
||||
|
||||
作者:[Peter Czanik][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[wxy](https://github.com/wxy)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/czanik
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/command_line_prompt.png?itok=wbGiJ_yg (Command line prompt)
|
||||
[2]: https://www.sudo.ws
|
||||
[3]: https://github.com/square/sudo_pair/
|
||||
[4]: https://www.syslog-ng.com/community/b/blog/posts/alerting-on-sudo-events-using-syslog-ng
|
||||
[5]: https://www.sudo.ws/
|
||||
[6]: https://blog.sudo.ws/
|
||||
[7]: https://twitter.com/sudoproject
|
@ -0,0 +1,57 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11564-1.html)
|
||||
[#]: subject: (Cloning a MAC address to bypass a captive portal)
|
||||
[#]: via: (https://fedoramagazine.org/cloning-a-mac-address-to-bypass-a-captive-portal/)
|
||||
[#]: author: (Esteban Wilson https://fedoramagazine.org/author/swilson/)
|
||||
|
||||
克隆 MAC 地址来绕过强制门户
|
||||
======
|
||||
|
||||
![][1]
|
||||
|
||||
如果你曾经在家和办公室之外连接到 WiFi,那么通常会看到一个门户页面。它可能会要求你接受服务条款或其他协议才能访问。但是,当你无法通过这类门户进行连接时会发生什么?本文向你展示了如何在 Fedora 上使用 NetworkManager 在某些故障情况下让你仍然可以访问互联网。
|
||||
|
||||
### 强制门户如何工作
|
||||
|
||||
强制门户是新设备连接到网络时显示的网页。当用户首次访问互联网时,门户网站会捕获所有网页请求并将其重定向到单个门户页面。
|
||||
|
||||
然后,页面要求用户采取一些措施,通常是同意使用政策。用户同意后,他们可以向 RADIUS 或其他类型的身份验证系统进行身份验证。简而言之,强制门户根据设备的 MAC 地址和终端用户接受条款来注册和授权设备。(MAC 地址是附加到任何网络接口的[基于硬件的值][2],例如 WiFi 芯片或卡。)
|
||||
|
||||
有时设备无法加载强制门户来进行身份验证和授权以使用 WiFI 接入。这种情况的例子包括移动设备和游戏机(Switch、Playstation 等)。当连接到互联网时,它们通常不会打开强制门户页面。连接到酒店或公共 WiFi 接入点时,你可能会看到这种情况。
|
||||
|
||||
不过,你可以在 Fedora 上使用 NetworkManager 来解决这些问题。Fedora 可以使你临时克隆要连接的设备的 MAC 地址,并代表该设备通过强制门户进行身份验证。你需要得到连接设备的 MAC 地址。通常,它被打印在设备上的某个地方并贴上标签。它是一个六字节的十六进制值,因此看起来类似 `4A:1A:4C:B0:38:1F`。通常,你也可以通过设备的内置菜单找到它。
|
||||
|
||||
### 使用 NetworkManager 克隆
|
||||
|
||||
首先,打开 `nm-connection-editor`,或通过“设置”打开 WiFi 设置。然后,你可以使用 NetworkManager 进行克隆:
|
||||
|
||||
* 对于以太网:选择已连接的以太网连接。然后选择 “Ethernet” 选项卡。记录或复制当前的 MAC 地址。在 “<ruby>克隆 MAC 地址<rt>Cloned MAC address</rt></ruby>” 字段中输入游戏机或其他设备的 MAC 地址。
|
||||
* 对于 WiFi:选择 WiFi 配置名。然后选择 “WiFi” 选项卡。记录或复制当前的 MAC 地址。在 “<ruby>克隆 MAC 地址<rt>Cloned MAC address</rt></ruby>” 字段中输入游戏机或其他设备的 MAC 地址。
|
||||
|
||||
### 启动所需的设备
|
||||
|
||||
当 Fedora 系统与以太网或 WiFi 配置连接,克隆的 MAC 地址将用于请求 IP 地址,并加载强制门户。输入所需的凭据和/或选择用户协议。该 MAC 地址将获得授权。
|
||||
|
||||
现在,断开 WiF i或以太网配置连接,然后将 Fedora 系统的 MAC 地址更改回其原始值。然后启动游戏机或其他设备。该设备现在应该可以访问互联网了,因为它的网络接口已通过你的 Fedora 系统进行了授权。
|
||||
|
||||
不过,这不是 NetworkManager 全部能做的。例如,请参阅[随机化系统硬件地址][3],来获得更好的隐私保护。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://fedoramagazine.org/cloning-a-mac-address-to-bypass-a-captive-portal/
|
||||
|
||||
作者:[Esteban Wilson][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://fedoramagazine.org/author/swilson/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://fedoramagazine.org/wp-content/uploads/2019/10/clone-mac-nm-816x345.jpg
|
||||
[2]: https://en.wikipedia.org/wiki/MAC_address
|
||||
[3]: https://linux.cn/article-10028-1.html
|
@ -0,0 +1,234 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (wenwensnow)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11611-1.html)
|
||||
[#]: subject: (Fields, records, and variables in awk)
|
||||
[#]: via: (https://opensource.com/article/19/11/fields-records-variables-awk)
|
||||
[#]: author: (Seth Kenlon https://opensource.com/users/seth)
|
||||
|
||||
awk 中的字段、记录和变量
|
||||
======
|
||||
|
||||
> 这个系列的第二篇,我们会学习字段,记录和一些非常有用的 Awk 变量。
|
||||
|
||||

|
||||
|
||||
Awk 有好几个变种:最早的 `awk`,是 1977 年 AT&T 贝尔实验室所创。它还有一些重构版本,例如 `mawk`、`nawk`。在大多数 Linux 发行版中能见到的,是 GNU awk,也叫 `gawk`。在大多数 Linux 发行版中,`awk` 和 `gawk` 都是指向 GNU awk 的软链接。输入 `awk`,调用的是同一个命令。[GNU awk 用户手册][2]中,能看到 `awk` 和 `gawk` 的全部历史。
|
||||
|
||||
这一系列的[第一篇文章][3] 介绍了 `awk` 命令的基本格式:
|
||||
|
||||
```
|
||||
$ awk [选项] '模式 {动作}' 输入文件
|
||||
```
|
||||
|
||||
`awk` 是一个命令,后面要接选项 (比如用 `-F` 来定义字段分隔符)。想让 `awk` 执行的部分需要写在两个单引号之间,至少在终端中需要这么做。在 `awk` 命令中,为了进一步强调你想要执行的部分,可以用 `-e` 选项来突出显示(但这不是必须的):
|
||||
|
||||
```
|
||||
$ awk -F, -e '{print $2;}' colours.txt
|
||||
yellow
|
||||
blue
|
||||
green
|
||||
[...]
|
||||
```
|
||||
|
||||
### 记录和字段
|
||||
|
||||
`awk` 将输入数据视为一系列*记录*,通常是按行分割的。换句话说,`awk` 将文本中的每一行视作一个记录。每一记录包含多个*字段*。一个字段由*字段分隔符*分隔开来,字段是记录的一部分。
|
||||
|
||||
默认情况下,`awk` 将各种空白符,如空格、制表符、换行符等视为分隔符。值得注意的是,在 `awk` 中,多个*空格*将被视为一个分隔符。所以下面这行文本有两个字段:
|
||||
|
||||
```
|
||||
raspberry red
|
||||
```
|
||||
|
||||
这行也是:
|
||||
|
||||
|
||||
```
|
||||
tuxedo black
|
||||
```
|
||||
|
||||
其他分隔符,在程序中不是这么处理的。假设字段分隔符是逗号,如下所示的记录,就有三个字段。其中一个字段可能会是 0 个字节(假设这一字段中不包含隐藏字符)
|
||||
|
||||
```
|
||||
a,,b
|
||||
```
|
||||
|
||||
### awk 程序
|
||||
|
||||
`awk` 命令的*程序部分*是由一系列规则组成的。通常来说,程序中每个规则占一行(尽管这不是必须的)。每个规则由一个模式,或一个或多个动作组成:
|
||||
|
||||
```
|
||||
模式 { 动作 }
|
||||
```
|
||||
|
||||
在一个规则中,你可以通过定义模式,来确定动作是否会在记录中执行。模式可以是简单的比较条件、正则表达式,甚至两者结合等等。
|
||||
|
||||
这个例子中,程序*只会*显示包含单词 “raspberry” 的记录:
|
||||
|
||||
```
|
||||
$ awk '/raspberry/ { print $0 }' colours.txt
|
||||
raspberry red 99
|
||||
```
|
||||
|
||||
如果没有文本符合模式,该动作将会应用到所有记录上。
|
||||
|
||||
并且,在一条规则只包含模式时,相当于对整个记录执行 `{ print }`,全部打印出来。
|
||||
|
||||
Awk 程序本质上是*数据驱动*的,命令执行结果取决于数据。所以,与其他编程语言中的程序相比,它还是有些区别的。
|
||||
|
||||
### NF 变量
|
||||
|
||||
每个字段都有指定变量,但针对字段和记录,也存在一些特殊变量。`NF` 变量,能存储 `awk` 在当前记录中找到的字段数量。其内容可在屏幕上显示,也可用于测试。下面例子中的数据,来自上篇文章[文本][3]:
|
||||
|
||||
```
|
||||
$ awk '{ print $0 " (" NF ")" }' colours.txt
|
||||
name color amount (3)
|
||||
apple red 4 (3)
|
||||
banana yellow 6 (3)
|
||||
[...]
|
||||
```
|
||||
|
||||
`awk` 的 `print` 函数会接受一系列参数(可以是变量或者字符串),并将它们拼接起来。这就是为什么在这个例子里,每行结尾处,`awk` 会以一个被括号括起来的整数表示字段数量。
|
||||
|
||||
### NR 变量
|
||||
|
||||
另外,除了统计每个记录中的字段数,`awk` 也统计输入记录数。记录数被存储在变量 `NR` 中,它的使用方法和其他变量没有任何区别。例如,为了在每一行开头显示行号:
|
||||
|
||||
```
|
||||
$ awk '{ print NR ": " $0 }' colours.txt
|
||||
1: name color amount
|
||||
2: apple red 4
|
||||
3: banana yellow 6
|
||||
4: raspberry red 3
|
||||
5: grape purple 10
|
||||
[...]
|
||||
```
|
||||
|
||||
注意,写这个命令时可以不在 `print` 后的多个参数间添加空格,尽管这样会降低可读性:
|
||||
|
||||
```
|
||||
$ awk '{print NR": "$0}' colours.txt
|
||||
```
|
||||
|
||||
### printf() 函数
|
||||
|
||||
为了让输出结果时格式更灵活,你可以使用 `awk` 的 `printf()` 函数。 它与 C、Lua、Bash 和其他语言中的 `printf` 相类似。它也接受以逗号分隔的*格式*参数。参数列表需要写在括号里。
|
||||
|
||||
```
|
||||
$ printf 格式, 项目1, 项目2, ...
|
||||
```
|
||||
|
||||
格式这一参数(也叫*格式符*)定义了其他参数如何显示。这一功能是用*格式修饰符*实现的。`%s` 输出字符,`%d` 输出十进制数字。下面的 `printf` 语句,会在括号内显示字段数量:
|
||||
|
||||
```
|
||||
$ awk 'printf "%s (%d)\n",$0,NF}' colours.txt
|
||||
name color amount (3)
|
||||
raspberry red 4 (3)
|
||||
banana yellow 6 (3)
|
||||
[...]
|
||||
```
|
||||
|
||||
在这个例子里,`%s (%d)` 确定了每一行的输出格式,`$0,NF` 定义了插入 `%s` 和 `%d` 位置的数据。注意,和 `print` 函数不同,在没有明确指令时,输出不会转到下一行。出现转义字符 `\n` 时才会换行。
|
||||
|
||||
### Awk 脚本编程
|
||||
|
||||
这篇文章中出现的所有 `awk` 代码,都在 Bash 终端中执行过。面对更复杂的程序,将命令放在文件(*脚本*)中会更容易。`-f FILE` 选项(不要和 `-F` 弄混了,那个选项用于字段分隔符),可用于指明包含可执行程序的文件。
|
||||
|
||||
举个例子,下面是一个简单的 awk 脚本。创建一个名为 `example1.awk` 的文件,包含以下内容:
|
||||
|
||||
```
|
||||
/^a/ {print "A: " $0}
|
||||
/^b/ {print "B: " $0}
|
||||
```
|
||||
|
||||
如果一个文件包含 `awk` 程序,那么在给文件命名时,最好写上 `.awk` 的扩展名。 这样命名不是强制的,但这么做,会给文件管理器、编辑器(和你)一个关于文件内容的很有用的提示。
|
||||
|
||||
执行这一脚本:
|
||||
|
||||
```
|
||||
$ awk -f example1.awk colours.txt
|
||||
A: raspberry red 4
|
||||
B: banana yellow 6
|
||||
A: apple green 8
|
||||
```
|
||||
|
||||
一个包含 `awk` 命令的文件,在最开头一行加上释伴 `#!`,就能变成可执行脚本。创建一个名为 `example2.awk` 的文件,包含以下内容:
|
||||
|
||||
```
|
||||
#!/usr/bin/awk -f
|
||||
#
|
||||
# 除了第一行,在其他行前显示行号
|
||||
#
|
||||
|
||||
NR > 1 {
|
||||
printf "%d: %s\n",NR,$0
|
||||
}
|
||||
```
|
||||
|
||||
可以说,脚本中只有一行,大多数情况下没什么用。但在某些情况下,执行一个脚本,比记住,然后打一条命令要容易的多。一个脚本文件,也提供了一个记录命令具体作用的好机会。以 `#` 号开头的行是注释,`awk` 会忽略它们。
|
||||
|
||||
给文件可执行权限:
|
||||
|
||||
```
|
||||
$ chmod u+x example2.awk
|
||||
```
|
||||
|
||||
执行脚本:
|
||||
|
||||
```
|
||||
$ ./example2.awk colours.txt
|
||||
2: apple red 4
|
||||
2: banana yellow 6
|
||||
4: raspberry red 3
|
||||
5: grape purple 10
|
||||
[...]
|
||||
```
|
||||
|
||||
将 `awk` 命令放在脚本文件中,有一个好处就是,修改和格式化输出会更容易。在终端中,如果能用一行执行多条 `awk` 命令,那么输入多行,才能达到同样效果,就显得有些多余了。
|
||||
|
||||
### 试一试
|
||||
|
||||
你现在已经足够了解,`awk` 是如何执行指令的了。现在你应该能编写复杂的 `awk` 程序了。试着编写一个 awk 脚本,它需要: 至少包括一个条件模式,以及多个规则。如果你想使用除 `print` 和 `printf` 以外的函数,可以参考在线 [gawk 手册][4]。
|
||||
|
||||
下面这个例子是个很好的切入点:
|
||||
|
||||
```
|
||||
#!/usr/bin/awk -f
|
||||
#
|
||||
# 显示所有记录 除了出现以下情况
|
||||
# 如果第一个记录 包含 “raspberry”
|
||||
# 将 “red” 替换成 “pi”
|
||||
|
||||
$1 == "raspberry" {
|
||||
gsub(/red/,"pi")
|
||||
}
|
||||
|
||||
{ print }
|
||||
```
|
||||
|
||||
试着执行这个脚本,看看输出是什么。接下来就看你自己的了。
|
||||
|
||||
这一系列的下一篇文章,将会介绍更多,能在更复杂(更有用!) 脚本中使用的函数。
|
||||
|
||||
这篇文章改编自 [Hacker Public Radio][5] 系列,一个技术社区博客。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/19/11/fields-records-variables-awk
|
||||
|
||||
作者:[Seth Kenlon][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[wenwensnow](https://github.com/wenwensnow)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [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/computer_laptop_code_programming_mountain_view.jpg?itok=yx5buqkr (Man at laptop on a mountain)
|
||||
[2]: https://www.gnu.org/software/gawk/manual/html_node/History.html#History
|
||||
[3]: https://linux.cn/article-11543-1.html
|
||||
[4]: https://www.gnu.org/software/gawk/manual/
|
||||
[5]: http://hackerpublicradio.org/eps.php?id=2129
|
@ -1,42 +1,38 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11580-1.html)
|
||||
[#]: subject: (Bash Script to Generate Patching Compliance Report on CentOS/RHEL Systems)
|
||||
[#]: via: (https://www.2daygeek.com/bash-script-to-generate-patching-compliance-report-on-centos-rhel-systems/)
|
||||
[#]: author: (Magesh Maruthamuthu https://www.2daygeek.com/author/magesh/)
|
||||
|
||||
Bash Script to Generate Patching Compliance Report on CentOS/RHEL Systems
|
||||
在 CentOS/RHEL 系统上生成补丁合规报告的 Bash 脚本
|
||||
======
|
||||
|
||||
If you are running a large Linux environment you may have already integrated your Red Hat systems with the Satellite.
|
||||

|
||||
|
||||
If yes, there is a way to export this from the Satellite Server so you don’t have to worry about patching compliance reports.
|
||||
如果你运行的是大型 Linux 环境,那么你可能已经将 Red Hat 与 Satellite 集成了。如果是的话,你不必担心补丁合规性报告,因为有一种方法可以从 Satellite 服务器导出它。
|
||||
|
||||
But if you are running a small Red Hat environment without satellite integration, or if it is CentOS systems, this script will help you to create a report.
|
||||
但是,如果你运行的是没有 Satellite 集成的小型 Red Hat 环境,或者它是 CentOS 系统,那么此脚本将帮助你创建该报告。
|
||||
|
||||
The patching compliance report is usually created monthly once or three months once, depending on the company’s needs.
|
||||
补丁合规性报告通常每月创建一次或三个月一次,具体取决于公司的需求。根据你的需要添加 cronjob 来自动执行此功能。
|
||||
|
||||
Add a cronjob based on your needs to automate this.
|
||||
此 [bash 脚本][1] 通常适合于少于 50 个系统运行,但没有限制。
|
||||
|
||||
This **[bash script][1]** is generally good to run with less than 50 systems, but there is no limit.
|
||||
保持系统最新是 Linux 管理员的一项重要任务,它使你的计算机非常稳定和安全。
|
||||
|
||||
Keeping the system up-to-date is an important task for Linux administrators, keeping your computer very stable and secure.
|
||||
以下文章可以帮助你了解有关在红帽 (RHEL) 和 CentOS 系统上安装安全修补程序的更多详细信息。
|
||||
|
||||
The following articles may help you to learn more about installing security patches on Red Hat (RHEL) and CentOS systems.
|
||||
* [如何在 CentOS 或 RHEL 系统上检查可用的安全更新?][2]
|
||||
* [在 RHEL 和 CentOS 系统上安装安全更新的四种方法][3]
|
||||
* [在 RHEL 和 CentOS 上检查或列出已安装的安全更新的两种方法][4]
|
||||
|
||||
* **[How to check available security updates on Red Hat (RHEL) and CentOS system][2]**
|
||||
* **[Four ways to install security updates on Red Hat (RHEL) & CentOS systems][3]**
|
||||
* **[Two methods to check or list out installed security updates on Red Hat (RHEL) & CentOS system][4]**
|
||||
此教程中包含四个 [shell 脚本][5],请选择适合你的脚本。
|
||||
|
||||
### 方法 1:为 CentOS / RHEL 系统上的安全修补生成补丁合规性报告的 Bash 脚本
|
||||
|
||||
|
||||
Four **[shell scripts][5]** are included in this tutorial and pick the suitable one for you.
|
||||
|
||||
### Method-1: Bash Script to Generate Patching Compliance Report for Security Errata on CentOS/RHEL Systems
|
||||
|
||||
This script allows you to create a security errata patch compliance report only. It sends the output via a mail in a plain text.
|
||||
此脚本只会生成安全修补合规性报告。它会通过纯文本发送邮件。
|
||||
|
||||
```
|
||||
# vi /opt/scripts/small-scripts/sec-errata.sh
|
||||
@ -58,13 +54,13 @@ echo "+---------------------------------------------+" >> $MESSAGE
|
||||
mail -s "$SUBJECT" "$TO" < $MESSAGE
|
||||
```
|
||||
|
||||
Run the script file once you have added the above script.
|
||||
添加完上面的脚本后运行它。
|
||||
|
||||
```
|
||||
# sh /opt/scripts/small-scripts/sec-errata.sh
|
||||
```
|
||||
|
||||
You get an output like the one below.
|
||||
你会看到下面的输出。
|
||||
|
||||
```
|
||||
# cat /tmp/sec-up.txt
|
||||
@ -79,7 +75,7 @@ server4
|
||||
+-----------------------------------+
|
||||
```
|
||||
|
||||
Add the following cronjob to get the patching compliance report once a month.
|
||||
添加下面的 cronjob 来每个月得到一份补丁合规性报告。
|
||||
|
||||
```
|
||||
# crontab -e
|
||||
@ -87,9 +83,9 @@ Add the following cronjob to get the patching compliance report once a month.
|
||||
@monthly /bin/bash /opt/scripts/system-uptime-script-1.sh
|
||||
```
|
||||
|
||||
### Method-1a: Bash Script to Generate Patching Compliance Report for Security Errata on CentOS/RHEL Systems
|
||||
### 方法 1a:为 CentOS / RHEL 系统上的安全修补生成补丁合规性报告的 Bash 脚本
|
||||
|
||||
This script allows you to generate a security errata patch compliance report. It sends the output through a mail with the CSV file.
|
||||
脚本会为你生成安全修补合规性报告。它会通过 CSV 文件发送邮件。
|
||||
|
||||
```
|
||||
# vi /opt/scripts/small-scripts/sec-errata-1.sh
|
||||
@ -105,19 +101,19 @@ echo "Patching Report for `date +"%B %Y"`" | mailx -s "Patching Report on `date`
|
||||
rm /tmp/sec-up.csv
|
||||
```
|
||||
|
||||
Run the script file once you have added the above script.
|
||||
添加完上面的脚本后运行它。
|
||||
|
||||
```
|
||||
# sh /opt/scripts/small-scripts/sec-errata-1.sh
|
||||
```
|
||||
|
||||
You get an output like the one below.
|
||||
你会看到下面的输出。
|
||||
|
||||
![][6]
|
||||
|
||||
### Method-2: Bash Script to Generate Patching Compliance Report for Security Errata, Bugfix, and Enhancement on CentOS/RHEL Systems
|
||||
### 方法 2:为 CentOS / RHEL 系统上的安全修补、bugfix、增强生成补丁合规性报告的 Bash 脚本
|
||||
|
||||
This script allows you to generate patching compliance reports for Security Errata, Bugfix, and Enhancement. It sends the output via a mail in a plain text.
|
||||
脚本会为你生成安全修补、bugfix、增强的补丁合规性报告。它会通过纯文本发送邮件。
|
||||
|
||||
```
|
||||
# vi /opt/scripts/small-scripts/sec-errata-bugfix-enhancement.sh
|
||||
@ -141,13 +137,13 @@ echo "+------------------------------------------------------------------+" >> $
|
||||
mail -s "$SUBJECT" "$TO" < $MESSAGE
|
||||
```
|
||||
|
||||
Run the script file once you have added the above script.
|
||||
添加完上面的脚本后运行它。
|
||||
|
||||
```
|
||||
# sh /opt/scripts/small-scripts/sec-errata-bugfix-enhancement.sh
|
||||
```
|
||||
|
||||
You get an output like the one below.
|
||||
你会看到下面的输出。
|
||||
|
||||
```
|
||||
# cat /tmp/sec-up.txt
|
||||
@ -162,7 +158,7 @@ server04 16
|
||||
+------------------------------------------------------------------+
|
||||
```
|
||||
|
||||
Add the following cronjob to get the patching compliance report once every three months. This script is scheduled to run on the 1’st of January, April, July and October months.
|
||||
添加下面的 cronjob 来每三个月得到补丁合规性报告。该脚本计划在一月、四月、七月、十月的 1 号运行。
|
||||
|
||||
```
|
||||
# crontab -e
|
||||
@ -170,9 +166,9 @@ Add the following cronjob to get the patching compliance report once every three
|
||||
0 0 01 */3 * /bin/bash /opt/scripts/system-uptime-script-1.sh
|
||||
```
|
||||
|
||||
### Method-2a: Bash Script to Generate Patching Compliance Report for Security Errata, Bugfix, and Enhancement on CentOS/RHEL Systems
|
||||
### 方法 2a:为 CentOS / RHEL 系统上的安全修补、bugfix、增强生成补丁合规性报告的 Bash 脚本
|
||||
|
||||
This script allows you to generate patching compliance reports for Security Errata, Bugfix, and Enhancement. It sends the output through a mail with the CSV file.
|
||||
脚本会为你生成安全修补、bugfix、增强的补丁合规性报告。它会通过 CSV 文件发送邮件。
|
||||
|
||||
```
|
||||
# vi /opt/scripts/small-scripts/sec-errata-bugfix-enhancement-1.sh
|
||||
@ -190,15 +186,15 @@ echo "Patching Report for `date +"%B %Y"`" | mailx -s "Patching Report on `date`
|
||||
rm /tmp/sec-up.csv
|
||||
```
|
||||
|
||||
Run the script file once you have added the above script.
|
||||
添加完上面的脚本后运行它。
|
||||
|
||||
```
|
||||
# sh /opt/scripts/small-scripts/sec-errata-bugfix-enhancement-1.sh
|
||||
```
|
||||
|
||||
You get an output like the one below.
|
||||
你会看到下面的输出。
|
||||
|
||||
![][6]
|
||||
![][7]
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
@ -206,16 +202,17 @@ via: https://www.2daygeek.com/bash-script-to-generate-patching-compliance-report
|
||||
|
||||
作者:[Magesh Maruthamuthu][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://www.2daygeek.com/author/magesh/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://www.2daygeek.com/category/bash-script/
|
||||
[2]: https://www.2daygeek.com/check-list-view-find-available-security-updates-on-redhat-rhel-centos-system/
|
||||
[2]: https://linux.cn/article-10938-1.html
|
||||
[3]: https://www.2daygeek.com/install-security-updates-on-redhat-rhel-centos-system/
|
||||
[4]: https://www.2daygeek.com/check-installed-security-updates-on-redhat-rhel-and-centos-system/
|
||||
[4]: https://linux.cn/article-10960-1.html
|
||||
[5]: https://www.2daygeek.com/category/shell-script/
|
||||
[6]: data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7
|
||||
[6]: https://www.2daygeek.com/wp-content/uploads/2019/11/bash-script-to-generate-patching-compliance-report-on-centos-rhel-systems-2.png
|
||||
[7]: https://www.2daygeek.com/wp-content/uploads/2019/11/bash-script-to-generate-patching-compliance-report-on-centos-rhel-systems-3.png
|
@ -0,0 +1,290 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (wxy)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11571-1.html)
|
||||
[#]: subject: (How to Schedule and Automate tasks in Linux using Cron Jobs)
|
||||
[#]: via: (https://www.linuxtechi.com/schedule-automate-tasks-linux-cron-jobs/)
|
||||
[#]: author: (Pradeep Kumar https://www.linuxtechi.com/author/pradeep/)
|
||||
|
||||
如何使用 cron 任务在 Linux 中计划和自动化任务
|
||||
======
|
||||
|
||||
有时,你可能需要定期或以预定的时间间隔执行任务。这些任务包括备份数据库、更新系统、执行定期重新引导等。这些任务称为 “cron 任务”。cron 任务用于“自动执行的任务”,它有助于简化重复的、有时是乏味的任务的执行。cron 是一个守护进程,可让你安排这些任务,然后按指定的时间间隔执行这些任务。在本教程中,你将学习如何使用 cron 来安排任务。
|
||||
|
||||
![Schedule -tasks-in-Linux-using cron][2]
|
||||
|
||||
### crontab 文件
|
||||
|
||||
crontab 即 “cron table”,是一个简单的文本文件,其中包含指定任务执行时间间隔的规则和命令。 crontab 文件分为两类:
|
||||
|
||||
1)系统范围的 crontab 文件
|
||||
|
||||
这些通常由需要 root 特权的 Linux 服务及关键应用程序使用。系统 crontab 文件位于 `/etc/crontab` 中,并且只能由 root 用户访问和编辑。通常用于配置系统范围的守护进程。`crontab` 文件的看起来类似如下所示:
|
||||
|
||||
![etc-crontab-linux][3]
|
||||
|
||||
2)用户创建的 crontab 文件
|
||||
|
||||
Linux 用户还可以在 `crontab` 命令的帮助下创建自己的 cron 任务。创建的 cron 任务将以创建它们的用户身份运行。
|
||||
|
||||
所有 cron 任务都存储在 `/var/spool/cron`(对于 RHEL 和 CentOS 发行版)和 `/var/spool/cron/crontabs`(对于 Debian 和 Ubuntu 发行版)中,cron 任务使用创建该文件的用户的用户名列出。
|
||||
|
||||
cron 守护进程在后台静默地检查 `/etc/crontab` 文件和 `/var/spool/cron` 及 `/etc/cron.d*/` 目录。
|
||||
|
||||
`crontab` 命令用于编辑 cron 文件。让我们看一下 crontab 文件的结构。
|
||||
|
||||
### crontab 文件剖析
|
||||
|
||||
在继续之前,我们要首先探索 crontab 文件的格式。crontab 文件的基本语法包括 5 列,由星号表示,后跟要执行的命令。
|
||||
|
||||
```
|
||||
* * * * * command
|
||||
```
|
||||
|
||||
此格式也可以表示如下:
|
||||
|
||||
```
|
||||
m h d moy dow command
|
||||
```
|
||||
|
||||
或
|
||||
|
||||
```
|
||||
m h d moy dow /path/to/script
|
||||
```
|
||||
|
||||
让我们来解释一下每个条目
|
||||
|
||||
* `m`:代表分钟。范围是 0 到 59
|
||||
* `h`:表示小时,范围是 0 到 23
|
||||
* `d`:代表一个月中的某天,范围是 1 到 31
|
||||
* `moy`:这是一年中的月份。范围是 1 到 12
|
||||
* `dow`:这是星期几。范围是 0 到 6,其中 0 代表星期日
|
||||
* `command`:这是要执行的命令,例如备份命令、重新启动和复制命令等
|
||||
|
||||
### 管理 cron 任务
|
||||
|
||||
看完 crontab 文件的结构之后,让我们看看如何创建、编辑和删除 cron 任务。
|
||||
|
||||
#### 创建 cron 任务
|
||||
|
||||
要以 root 用户身份创建或编辑 cron 任务,请运行以下命令:
|
||||
|
||||
```
|
||||
# crontab -e
|
||||
```
|
||||
|
||||
要为另一个用户创建或安排 cron 任务,请使用以下语法:
|
||||
|
||||
```
|
||||
# crontab -u username -e
|
||||
```
|
||||
|
||||
例如,要以 Pradeep 用户身份运行 cron 任务,请发出以下命令:
|
||||
|
||||
```
|
||||
# crontab -u Pradeep -e
|
||||
```
|
||||
|
||||
如果该 crontab 文件尚不存在,那么你将打开一个空白文本文件。如果该 crontab 文件已经存在,则 `-e` 选项会让你编辑该文件,
|
||||
|
||||
#### 列出 crontab 文件
|
||||
|
||||
要查看已创建的 cron 任务,只需传递 `-l` 选项:
|
||||
|
||||
```
|
||||
# crontab -l
|
||||
```
|
||||
|
||||
#### 删除 crontab 文件
|
||||
|
||||
要删除 cron 任务,只需运行 `crontab -e` 并删除所需的 cron 任务行,然后保存该文件。
|
||||
|
||||
要删除所有的 cron 任务,请运行以下命令:
|
||||
|
||||
```
|
||||
# crontab -r
|
||||
```
|
||||
|
||||
然后,让我们看一下安排任务的不同方式。
|
||||
|
||||
### 使用 crontab 安排任务示例
|
||||
|
||||
如图所示,所有 cron 任务文件都带有<ruby>释伴<rt>shebang</rt></ruby>标头。
|
||||
|
||||
```
|
||||
#!/bin/bash
|
||||
```
|
||||
|
||||
这表示你正在使用的 shell,在这种情况下,即 bash shell。
|
||||
|
||||
接下来,使用我们之前指定的 cron 任务条目指定要安排任务的时间间隔。
|
||||
|
||||
要每天下午 12:30 重启系统,请使用以下语法:
|
||||
|
||||
```
|
||||
30 12 * * * /sbin/reboot
|
||||
```
|
||||
|
||||
要安排在凌晨 4:00 重启,请使用以下语法:
|
||||
|
||||
```
|
||||
0 4 * * * /sbin/reboot
|
||||
```
|
||||
|
||||
注:星号 `*` 用于匹配所有记录。
|
||||
|
||||
要每天两次运行脚本(例如,凌晨 4:00 和下午 4:00),请使用以下语法:
|
||||
|
||||
```
|
||||
0 4,16 * * * /path/to/script
|
||||
```
|
||||
|
||||
要安排 cron 任务在每个星期五下午 5:00 运行,请使用以下语法:
|
||||
|
||||
```
|
||||
0 17 * * Fri /path/to/script
|
||||
```
|
||||
|
||||
或
|
||||
|
||||
```
|
||||
0 17 * * * 5 /path/to/script
|
||||
```
|
||||
|
||||
如果你希望每 30 分钟运行一次 cron 任务,请使用:
|
||||
|
||||
```
|
||||
*/30 * * * * /path/to/script
|
||||
```
|
||||
|
||||
要安排 cron 任务每 5 小时运行一次,请运行:
|
||||
|
||||
```
|
||||
* */5 * * * /path/to/script
|
||||
```
|
||||
|
||||
要在选定的日期(例如,星期三和星期五的下午 6:00)运行脚本,请执行以下操作:
|
||||
|
||||
```
|
||||
0 18 * * wed,fri /path/to/script
|
||||
```
|
||||
|
||||
要使用单个 cron 任务运行多个命令,请使用分号分隔任务,例如:
|
||||
|
||||
```
|
||||
* * * * * /path/to/script1 ; /path/to/script2
|
||||
```
|
||||
|
||||
### 使用特殊字符串节省编写 cron 任务的时间
|
||||
|
||||
某些 cron 任务可以使用对应于特定时间间隔的特殊字符串轻松配置。例如,
|
||||
|
||||
1)`@hourly` 时间戳等效于 `0 * * * *`
|
||||
|
||||
它将在每小时的第一分钟执行一次任务。
|
||||
|
||||
```
|
||||
@hourly /path/to/script
|
||||
```
|
||||
|
||||
2)`@daily` 时间戳等效于 `0 0 * * *`
|
||||
|
||||
它在每天的第一分钟(午夜)执行任务。它可以在执行日常工作时派上用场。
|
||||
|
||||
```
|
||||
@daily /path/to/script
|
||||
```
|
||||
|
||||
3)`@weekly` 时间戳等效于 `0 0 * * 0`
|
||||
|
||||
它在每周的第一分钟执行 cron 任务,一周第一天是从星期日开始的。
|
||||
|
||||
```
|
||||
@weekly /path/to/script
|
||||
```
|
||||
|
||||
3)`@monthly` 时间戳等效于 `0 0 1 * *`
|
||||
|
||||
它在每月第一天的第一分钟执行任务。
|
||||
|
||||
```
|
||||
@monthly /path/to/script
|
||||
```
|
||||
|
||||
4)`@yearly` 时间戳等效于 `0 0 1 1 *`
|
||||
|
||||
它在每年的第一分钟执行任务,可以用于发送新年问候。
|
||||
|
||||
```
|
||||
@yearly /path/to/script
|
||||
```
|
||||
|
||||
### 限制 crontab
|
||||
|
||||
作为 Linux 用户,你可以控制谁有权使用 `crontab` 命令。可以使用 `/etc/cron.deny` 和 `/etc/cron.allow` 文件来控制。默认情况下,只有一个 `/etc/cron.deny` 文件,并且不包含任何条目。要限制用户使用 `crontab` 实用程序,只需将用户的用户名添加到该文件中即可。当用户添加到该文件中,并且该用户尝试运行 `crontab` 命令时,他/她将遇到以下错误。
|
||||
|
||||
![restricted-cron-user][4]
|
||||
|
||||
要允许用户继续使用 `crontab` 实用程序,只需从 `/etc/cron.deny` 文件中删除用户名即可。
|
||||
|
||||
如果存在 `/etc/cron.allow` 文件,则仅文件中列出的用户可以访问和使用 `crontab` 实用程序。
|
||||
|
||||
如果两个文件都不存在,则只有 root 用户具有使用 `crontab` 命令的特权。
|
||||
|
||||
### 备份 crontab 条目
|
||||
|
||||
始终建议你备份 crontab 条目。为此,请使用语法:
|
||||
|
||||
```
|
||||
# crontab -l > /path/to/file.txt
|
||||
```
|
||||
|
||||
例如:
|
||||
|
||||
```
|
||||
# crontab -l > /home/james/backup.txt
|
||||
```
|
||||
|
||||
### 检查 cron 日志
|
||||
|
||||
cron 日志存储在 `/var/log/cron` 文件中。要查看 cron 日志,请运行以下命令:
|
||||
|
||||
```
|
||||
# cat /var/log/cron
|
||||
```
|
||||
|
||||
![view-cron-log-files-linux][5]
|
||||
|
||||
要实时查看日志,请使用 `tail` 命令,如下所示:
|
||||
|
||||
```
|
||||
# tail -f /var/log/cron
|
||||
```
|
||||
|
||||
![view-live-cron-logs][6]
|
||||
|
||||
### 总结
|
||||
|
||||
在本指南中,你学习了如何创建 cron 任务以自动执行重复性任务,如何备份和查看 cron 日志。我们希望本文提供有关 cron 作业的有用见解。请随时分享你的反馈和意见。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.linuxtechi.com/schedule-automate-tasks-linux-cron-jobs/
|
||||
|
||||
作者:[Pradeep Kumar][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[wxy](https://github.com/wxy)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://www.linuxtechi.com/author/pradeep/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7
|
||||
[2]: https://www.linuxtechi.com/wp-content/uploads/2019/11/Schedule-tasks-in-Linux-using-cron.jpg
|
||||
[3]: https://www.linuxtechi.com/wp-content/uploads/2019/11/etc-crontab-linux.png
|
||||
[4]: https://www.linuxtechi.com/wp-content/uploads/2019/11/restricted-cron-user.png
|
||||
[5]: https://www.linuxtechi.com/wp-content/uploads/2019/11/view-cron-log-files-linux.png
|
||||
[6]: https://www.linuxtechi.com/wp-content/uploads/2019/11/view-live-cron-logs.png
|
234
published/201911/20191107 Demystifying Kubernetes.md
Normal file
234
published/201911/20191107 Demystifying Kubernetes.md
Normal file
@ -0,0 +1,234 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (Morisun029)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11628-1.html)
|
||||
[#]: subject: (Demystifying Kubernetes)
|
||||
[#]: via: (https://opensourceforu.com/2019/11/demystifying-kubernetes/)
|
||||
[#]: author: (Abhinav Nath Gupta https://opensourceforu.com/author/abhinav-gupta/)
|
||||
|
||||
揭开 Kubernetes 的神秘面纱
|
||||
======
|
||||
|
||||
![][2]
|
||||
|
||||
> Kubernetes 是一款生产级的开源系统,用于容器化应用程序的自动部署、扩展和管理。本文关于使用 Kubernetes 来管理容器。
|
||||
|
||||
“容器”已成为最新的流行语之一。但是,这个词到底意味着什么呢?说起“容器”,人们通常会把它和 Docker 联系起来,Docker 是一个被定义为软件的标准化单元容器。该容器将软件和运行软件所需的环境封装到一个易于交付的单元中。
|
||||
|
||||
容器是一个软件的标准单元,用它来打包代码及其所有依赖项,这样应用程序就可以从一个计算环境到另一个计算环境快速可靠地运行。容器通过创建类似于 ISO 镜像的方式来实现此目的。容器镜像是一个轻量级的、独立的、可执行的软件包,其中包含运行应用程序所需的所有信息,包括代码、运行时、系统工具、系统库和设置。
|
||||
|
||||
容器镜像在运行时变成容器,对于 Docker 容器,镜像在 Docker 引擎上运行时变成容器。容器将软件与环境隔离开来,确保不同环境下的实例,都可以正常运行。
|
||||
|
||||
###什么是容器管理?
|
||||
|
||||
容器管理是组织、添加或替换大量软件容器的过程。容器管理使用软件来自动化创建、部署和扩展容器。这一过程就需要容器编排,容器编排是一个自动对基于容器的应用程序进行部署、管理、扩展、联网和提供可用性的工具。
|
||||
|
||||
### Kubernetes
|
||||
|
||||
Kubernetes 是一个可移植的、可扩展的开源平台,用于管理容器化的工作负载和服务,它有助于配置和自动化。它最初由 Google 开发,拥有一个庞大且快速增长的生态系统。Kubernetes 的服务、技术支持和工具得到广泛应用。
|
||||
|
||||
Google 在 2014 年开源了 Kubernetes 项目。Kubernetes 建立在 Google 十五年大规模运行生产工作负载的经验基础上,并结合了社区中最好的想法和实践以及声明式句法的使用。
|
||||
|
||||
下面列出了与Kubernetes生态系统相关的一些常用术语。
|
||||
|
||||
**Pod**:Pod 是 Kubernetes 应用程序的基本执行单元,是你创建或部署的 Kubernetes 对象模型中的最小和最简单的单元。Pod 代表在 Kubernetes 集群上运行的进程。
|
||||
|
||||
Pod 将运行中的容器、存储、网络 IP(唯一)和控制容器应如何运行的命令封装起来。它代表 Kubernetes 生态系统内的单个部署单元,代表一个应用程序的单个实例,该程序可能包含一个或多个紧密耦合并共享资源的容器。
|
||||
|
||||
Kubernetes 集群中的 Pod 有两种主要的使用方式。第一种是运行单个容器。即“一个容器一个 Pod”,这种方式是最常见的。第二种是运行多个需要一起工作的容器。
|
||||
|
||||
Pod 可能封装一个由紧密关联且需要共享资源的多个同位容器组成的应用程序。
|
||||
|
||||
<ruby>副本集<rt>ReplicaSet</rt></ruby>:副本集的目的是维护在任何给定时间运行的一组稳定的副本容器集。 副本集包含有关一个特定 Pod 应该运行多少个副本的信息。为了创建多个 Pod 以匹配副本集条件,Kubernetes 使用 Pod 模板。副本集与其 Pod 的链接是通过后者的 `metas.ownerReferences` 字段实现,该字段指定哪个资源拥有当前对象。
|
||||
|
||||
<ruby>服务<rt>Services</rt></ruby>:服务是一种抽象,用来公开一组 Pod 功能。使用 Kubernetes,你无需修改应用程序即可使用陌生服务发现机制。Kubernetes 给 Pod 提供了其自己的 IP 地址和一组 Pod 的单个 DNS 名称,并且可以在它们之间负载平衡。
|
||||
|
||||
服务解决的一个主要问题是 Web 应用程序前端和后端的集成。由于 Kubernetes 将幕后的 IP 地址提供给 Pod,因此当 Pod 被杀死并复活时,IP 地址会更改。这给给定的后端 IP 地址连接到相应的前端 IP 地址带来一个大问题。服务通过在 Pod 上提供抽象来解决此问题,类似于负载均衡器。
|
||||
|
||||
<ruby>卷<rt>Volumes</rt></ruby>: Kubernetes 卷具有明确的生命周期,与围绕它的 Pod 相同。 因此,卷超过了 Pod 中运行的任何容器的寿命,并且在容器重新启动后保留了数据。当然,当 Pod 不存在时,该卷也将不再存在。也许比这更重要的是 Kubernetes 支持多种类型的卷,并且 Pod 可以同时使用任意数量的卷。
|
||||
|
||||
卷的核心只是一个目录,其中可能包含一些数据,Pod 中的容器可以访问该目录。该目录是如何产生的,它后端基于什么存储介质,其中的数据内容是什么,这些都由使用的特定卷类型来决定的。
|
||||
|
||||
### 为什么选择 Kubernetes?
|
||||
|
||||
容器是捆绑和运行应用程序的好方法。在生产环境中,你需要管理运行应用程序的容器,并确保没有停机时间。例如,如果一个容器发生故障,则需要启动另一个容器。如果由系统自动实现这一操作,岂不是更好? Kubernetes 就是来解决这个问题的!Kubernetes 提供了一个框架来弹性运行分布式系统。该框架负责扩展需求、故障转移、部署模式等。例如,Kubernetes 可以轻松管理系统的金丝雀部署。
|
||||
|
||||
Kubernetes 为用户提供了:
|
||||
|
||||
1. 服务发现和负载平衡
|
||||
2. 存储编排
|
||||
3. 自动退出和回退
|
||||
4. 自动打包
|
||||
5. 自我修复
|
||||
6. 秘密配置管理
|
||||
|
||||
### Kubernetes 可以做什么?
|
||||
|
||||
在本文中,我们将会看到一些从头构建 Web 应用程序时如何使用 Kubernetes 的代码示例。我们将在 Python 中使用 Flask 创建一个简单的后端服务器。
|
||||
|
||||
对于那些想从头开始构建 Web 应用程序的人,有一些前提条件,即:
|
||||
|
||||
1. 对 Docker、Docker 容器和 Docker 镜像的基本了解。可以访问[这里][8]快速了解。
|
||||
2. 系统中应该安装 Docker。
|
||||
3. 系统中应该安装 Kubernetes,有关如何在本地计算机上安装的说明,请访问[这里][9]。
|
||||
|
||||
现在,创建一个目录,如下代码片段所示:
|
||||
|
||||
```
|
||||
mkdir flask-kubernetes/app && cd flask-kubernetes/app
|
||||
```
|
||||
|
||||
接下来,在 `flask-kubernetes/app` 目录中,创建一个名为 `main.py` 的文件,如下面的代码片段所示:
|
||||
|
||||
```
|
||||
touch main.py
|
||||
```
|
||||
|
||||
在新创建的 `main.py` 文件中,粘贴下面代码:
|
||||
|
||||
```
|
||||
from flask import Flask
|
||||
app = Flask(__name__)
|
||||
|
||||
@app.route("/")
|
||||
def hello():
|
||||
return "Hello from Kubernetes!"
|
||||
|
||||
if __name__ == "__main__":
|
||||
app.run(host='0.0.0.0')
|
||||
```
|
||||
|
||||
使用下面命令在本地安装 Flask:
|
||||
|
||||
```
|
||||
pip install Flask==0.10.1
|
||||
```
|
||||
|
||||
Flask 安装后,执行下面的命令:
|
||||
|
||||
```
|
||||
python app.py
|
||||
```
|
||||
|
||||
应该在本地 5000 端口运行 Flask 服务器,这是 Flask 应用程序的默认端口,并且你可以在 http://localhost:5000 上看到输出 “Hello from Kubernetes!”。服务器在本地运行之后,我们创建一个供 Kubernetes 使用的 Docker 镜像。创建一个名为 `Dockerfile` 的文件,并将以下代码片段粘贴到其中:
|
||||
|
||||
```
|
||||
FROM python:3.7
|
||||
|
||||
RUN mkdir /app
|
||||
WORKDIR /app
|
||||
ADD . /app/
|
||||
RUN pip install -r requirements.txt
|
||||
|
||||
EXPOSE 5000
|
||||
CMD ["python", "/app/main.py"]
|
||||
```
|
||||
|
||||
`Dockerfile` 文件的说明如下:
|
||||
|
||||
1. Docker 将从 DockerHub 获取 Python 3.7 镜像。
|
||||
2. 将在镜像中创建一个应用程序目录。
|
||||
3. 它将一个 `/app` 目录设置为工作目录。
|
||||
4. 将内容从主机中的应用程序目录复制到镜像应用程序目录。
|
||||
5. 发布端口 5000。
|
||||
6. 最后,它运行命令,启动 Flask 服务器。
|
||||
|
||||
接下来,我们将使用以下命令创建 Docker 镜像:
|
||||
|
||||
```
|
||||
docker build -f Dockerfile -t flask-kubernetes:latest .
|
||||
```
|
||||
|
||||
创建 Docker 镜像后,我们可以使用以下命令在本地运行该镜像进行测试:
|
||||
|
||||
```
|
||||
docker run -p 5001:5000 flask-kubernetes
|
||||
```
|
||||
|
||||
通过运行容器在本地完成测试之后,我们需要在 Kubernetes 中部署它。我们将首先使用 `kubectl` 命令验证 Kubernetes 是否正在运行。如果没有报错,则说明它正在工作。如果有报错,请参考[该信息][9]。
|
||||
|
||||
接下来,我们创建一个部署文件。这是一个 Yaml 文件,其中包含有关 Kubernetes 的说明,该说明涉及如何以声明性的方式创建 Pod 和服务。因为我们有 Flask Web 应用程序,我们将创建一个 `deployment.yaml` 文件,并在其中包含 Pod 和服务声明。
|
||||
|
||||
创建一个名为 `deployment.yaml` 的文件并向其中添加以下内容,然后保存:
|
||||
|
||||
```
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: flask-kubernetes -service
|
||||
spec:
|
||||
selector:
|
||||
app: flask-kubernetes
|
||||
ports:
|
||||
- protocol: "TCP"
|
||||
port: 6000
|
||||
targetPort: 5000
|
||||
type: LoadBalancer
|
||||
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: flask-kubernetes
|
||||
spec:
|
||||
replicas: 4
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: flask-kubernetes
|
||||
spec:
|
||||
containers:
|
||||
- name: flask-kubernetes
|
||||
image: flask-kubernetes:latest
|
||||
imagePullPolicy: Never
|
||||
ports:
|
||||
- containerPort: 5000
|
||||
```
|
||||
|
||||
使用以下命令将 yaml 文件发送到 Kubernetes:
|
||||
|
||||
```
|
||||
kubectl apply -f deployment.yaml
|
||||
```
|
||||
|
||||
如果执行以下命令,你会看到 Pod 正在运行:
|
||||
|
||||
```
|
||||
kubectl get pods
|
||||
```
|
||||
|
||||
现在,导航至 http://localhost:6000,你应该会看到 “Hello from Kubernetes!”消息。成功了! 该应用程序现在正在 Kubernetes 中运行!
|
||||
|
||||
### Kubernetes 做不了什么?
|
||||
|
||||
Kubernetes 不是一个传统的,包罗万象的 PaaS(平台即服务)系统。 由于 Kubernetes 运行在容器级别而非硬件级别,因此它提供了 PaaS 产品共有的一些普遍适用功能,如部署、扩展、负载平衡、日志记录和监控。Kubernetes 为开发人员平台提供了构建块,但在重要的地方保留了用户的选择和灵活性。
|
||||
|
||||
* Kubernetes 不限制所支持的应用程序的类型。如果应用程序可以在容器中运行,那么它应该可以在 Kubernetes 上更好地运行。
|
||||
* 它不部署和构建源代码。
|
||||
* 它不决定日志记录、监视或警报解决方案。
|
||||
* 它不提供或不要求配置语言/系统。它提供了一个声明式的 API 供所有人使用。
|
||||
* 它不提供或不采用任何全面的机器配置、维护、管理或自我修复系统。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensourceforu.com/2019/11/demystifying-kubernetes/
|
||||
|
||||
作者:[Abhinav Nath Gupta][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[Morisun029](https://github.com/Morisun029)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensourceforu.com/author/abhinav-gupta/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://i2.wp.com/opensourceforu.com/wp-content/uploads/2019/11/Gear-kubernetes.jpg?resize=696%2C457&ssl=1 (Gear kubernetes)
|
||||
[2]: https://i2.wp.com/opensourceforu.com/wp-content/uploads/2019/11/Gear-kubernetes.jpg?fit=800%2C525&ssl=1
|
||||
[3]: https://secure.gravatar.com/avatar/f65917facf5f28936663731fedf545c4?s=100&r=g
|
||||
[4]: https://opensourceforu.com/author/abhinav-gupta/
|
||||
[5]: mailto:abhi.aec89@gmail.com
|
||||
[6]: http://opensourceforu.com/wp-content/uploads/2013/10/assoc.png
|
||||
[7]: https://feedburner.google.com/fb/a/mailverify?uri=LinuxForYou&loc=en_US
|
||||
[8]: https://www.docker.com/sites/default/files/Docker_CheatSheet_08.09.2016_0.pdf
|
||||
[9]: https://kubernetes.io/docs/setup/learning-environment/minikube/
|
@ -0,0 +1,88 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11584-1.html)
|
||||
[#]: subject: (How to add a user to your Linux desktop)
|
||||
[#]: via: (https://opensource.com/article/19/11/add-user-gui-linux)
|
||||
[#]: author: (Alan Formy-Duval https://opensource.com/users/alanfdoss)
|
||||
|
||||
如何在 Linux 桌面添加用户
|
||||
======
|
||||
|
||||
> 无论是在安装过程中还是在桌面中,通过图形界面管理用户都非常容易。
|
||||
|
||||
![Team of people around the world][1]
|
||||
|
||||
添加用户是你在一个新系统上要做的第一件事。而且,你通常需要在计算机的整个生命周期中管理用户。
|
||||
|
||||
我的关于 [useradd 命令][2]文章提供了更深入的对 Linux 的用户管理的了解。`useradd` 是一个命令行工具,但是你也可以在 Linux 上以图形方式管理用户。这就是本文的主题。
|
||||
|
||||
### 在 Linux 安装过程中添加用户
|
||||
|
||||
大多数 Linux 发行版都提供了在安装过程中创建用户的步骤。例如,Fedora 30 安装程序 Anaconda 创建标准的 `root` 用户和另一个本地用户帐户。在安装过程中进入“配置”页面时,单击“用户设置”下的“用户创建”。
|
||||
|
||||
![Fedora Anaconda Installer - Add a user][3]
|
||||
|
||||
在用户创建页面上,输入用户的详细信息:全名、用户名和密码。你还可以选择是否使用户成为管理员。
|
||||
|
||||
![Create a user during installation][4]
|
||||
|
||||
点击“高级”按钮打开“高级用户配置”页面。如果需要除默认设置以外的其他设置,那么可以在此处指定主目录的路径以及用户和组 ID。你也可以输入用户所属的其他组。
|
||||
|
||||
![Advanced user configuration][5]
|
||||
|
||||
### 在 Linux 桌面上添加用户
|
||||
|
||||
#### GNOME
|
||||
|
||||
许多 Linux 发行版都使用 GNOME 桌面。以下截图来自 Red Hat Enterprise Linux 8.0,但是在其他发行版(如 Fedora、Ubuntu 或 Debian)中,该过程相似。
|
||||
|
||||
首先打开“设置”。然后打开“详细”,选择“用户”,单击“解锁”,然后输入密码(除非你已经以 root 用户登录)。这样将用“添加用户”按钮代替“解锁”按钮。
|
||||
|
||||
![GNOME user settings][6]
|
||||
|
||||
现在,你可以通过单击“添加用户”,然后选择“帐户类型”然后输入“用户名”和“密码”来添加用户。
|
||||
|
||||
在下面的截图中,已经输入了用户名,设置保留为默认设置。我不必输入“用户名”,因为它是在我在“全名”字段中输入时自动创建的。如果你不喜欢自动补全,你仍然可以对其进行修改。
|
||||
|
||||
![GNOME settings - add user][7]
|
||||
|
||||
这将为名为 Sonny 的用户创建一个标准帐户。Sonny 首次登录时需要提供密码。
|
||||
|
||||
接下来,将显示用户。在此页面可以选择每个用户进行自定义或者删除。例如,你可能想选择一个头像或设置默认语言。
|
||||
|
||||
![GNOME new user][8]
|
||||
|
||||
#### KDE
|
||||
|
||||
KDE 是另一个流行的 Linux 桌面环境。下面是 Fedora 30 上 KDE Plasma 的截图。你可以看到,在 KDE 中添加用户与在 GNOME 中添加用户非常相似。
|
||||
|
||||
![KDE settings - add user][9]
|
||||
|
||||
### 总结
|
||||
|
||||
除 GNOME 和 KDE 外,其他桌面环境和窗口管理器也有图形用户管理工具。无论是在安装时还是安装后,在 Linux 中以图形方式添加用户都是快速简便的。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/19/11/add-user-gui-linux
|
||||
|
||||
作者:[Alan Formy-Duval][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/alanfdoss
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/team_global_people_gis_location.png?itok=Rl2IKo12 (Team of people around the world)
|
||||
[2]: https://opensource.com/article/19/10/linux-useradd-command
|
||||
[3]: https://opensource.com/sites/default/files/uploads/screenshot_fedora30_anaconda2.png (Fedora Anaconda Installer - Add a user)
|
||||
[4]: https://opensource.com/sites/default/files/uploads/screenshot_fedora30_anaconda3.png (Create a user during installation)
|
||||
[5]: https://opensource.com/sites/default/files/uploads/screenshot_fedora30_anaconda4.png (Advanced user configuration)
|
||||
[6]: https://opensource.com/sites/default/files/uploads/gnome_settings_user_unlock.png (GNOME user settings)
|
||||
[7]: https://opensource.com/sites/default/files/uploads/gnome_settings_adding_user.png (GNOME settings - add user)
|
||||
[8]: https://opensource.com/sites/default/files/uploads/gnome_settings_user_new.png (GNOME new user)
|
||||
[9]: https://opensource.com/sites/default/files/uploads/kde_settings_adding_user.png (KDE settings - add user)
|
@ -0,0 +1,258 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (wxy)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11560-1.html)
|
||||
[#]: subject: (Tuning your bash or zsh shell on Fedora Workstation and Silverblue)
|
||||
[#]: via: (https://fedoramagazine.org/tuning-your-bash-or-zsh-shell-in-workstation-and-silverblue/)
|
||||
[#]: author: (George Luiz Maluf https://fedoramagazine.org/author/georgelmaluf/)
|
||||
|
||||
在 Fedora 上优化 bash 或 zsh
|
||||
======
|
||||
|
||||
![][1]
|
||||
|
||||
本文将向你展示如何在 Fedora 的命令行解释器(CLI)Shell 中设置一些强大的工具。如果使用bash(默认)或zsh,Fedora 可让你轻松设置这些工具。
|
||||
|
||||
### 前置需求
|
||||
|
||||
这需要一些已安装的软件包。在 Fedora 工作站上,运行以下命令:
|
||||
|
||||
```
|
||||
sudo dnf install git wget curl ruby ruby-devel zsh util-linux-user redhat-rpm-config gcc gcc-c++ make
|
||||
```
|
||||
|
||||
在 Silverblue 上运行:
|
||||
|
||||
```
|
||||
sudo rpm-ostree install git wget curl ruby ruby-devel zsh util-linux-user redhat-rpm-config gcc gcc-c++ make
|
||||
```
|
||||
|
||||
注意:在 Silverblue 上,你需要重新启动才能继续。
|
||||
|
||||
### 字体
|
||||
|
||||
你可以通过安装新字体使终端焕然一新。为什么不使用可以同时显示字符和图标的字体呢?
|
||||
|
||||
#### Nerd-Fonts
|
||||
|
||||
打开一个新终端,然后键入以下命令:
|
||||
|
||||
```
|
||||
git clone https://github.com/ryanoasis/nerd-fonts ~/.nerd-fonts
|
||||
cd .nerd-fonts
|
||||
sudo ./install.sh
|
||||
```
|
||||
|
||||
#### Awesome-Fonts
|
||||
|
||||
在工作站上,使用以下命令进行安装:
|
||||
|
||||
```
|
||||
sudo dnf fontawesome-fonts
|
||||
```
|
||||
|
||||
在 Silverblue 上键入:
|
||||
|
||||
```
|
||||
sudo rpm-ostree install fontawesome-fonts
|
||||
```
|
||||
|
||||
### Powerline
|
||||
|
||||
Powerline 是 vim 的状态行插件,并为其他几个应用程序也提供了状态行和提示符,包括 bash、zsh、tmus、i3、Awesome、IPython 和 Qtile。你也可以在官方[文档站点][3]上找到更多信息。
|
||||
|
||||
#### 安装
|
||||
|
||||
要在 Fedora 工作站上安装 Powerline 实用程序,请打开一个新终端并运行:
|
||||
|
||||
```
|
||||
sudo dnf install powerline vim-powerline tmux-powerline powerline-fonts
|
||||
```
|
||||
|
||||
在 Silverblue 上,命令更改为:
|
||||
|
||||
```
|
||||
sudo rpm-ostree install powerline vim-powerline tmux-powerline powerline-fonts
|
||||
```
|
||||
|
||||
注意:在 Silverblue 上,你需要重新启动才能继续。
|
||||
|
||||
#### 激活 Powerline
|
||||
|
||||
要使 Powerline 默认处于活动状态,请将下面的代码放在 `~/.bashrc` 文件的末尾:
|
||||
|
||||
```
|
||||
if [ -f `which powerline-daemon` ]; then
|
||||
powerline-daemon -q
|
||||
POWERLINE_BASH_CONTINUATION=1
|
||||
POWERLINE_BASH_SELECT=1
|
||||
. /usr/share/powerline/bash/powerline.sh
|
||||
fi
|
||||
```
|
||||
|
||||
最后,关闭终端并打开一个新终端。它看起来像这样:
|
||||
|
||||
![][4]
|
||||
|
||||
### Oh-My-Zsh
|
||||
|
||||
[Oh-My-Zsh][5] 是用于管理 Zsh 配置的框架。它捆绑了有用的功能、插件和主题。要了解如何将 Zsh 设置为默认外壳程序,请参见[这篇文章][6]。
|
||||
|
||||
#### 安装
|
||||
|
||||
在终端中输入:
|
||||
|
||||
```
|
||||
sh -c "$(curl -fsSL https://raw.github.com/robbyrussell/oh-my-zsh/master/tools/install.sh)"
|
||||
```
|
||||
|
||||
或者,你也可以输入以下内容:
|
||||
|
||||
```
|
||||
sh -c "$(wget https://raw.github.com/robbyrussell/oh-my-zsh/master/tools/install.sh -O -)"
|
||||
```
|
||||
|
||||
最后,你将看到如下所示的终端:
|
||||
|
||||
![][7]
|
||||
|
||||
恭喜,Oh-my-zsh 已安装成功。
|
||||
|
||||
#### 主题
|
||||
|
||||
安装后,你可以选择主题。我喜欢使用 powerlevel10k。优点之一是它比 powerlevel9k 主题快 100 倍。要安装它,请运行以下命令行:
|
||||
|
||||
```
|
||||
git clone https://github.com/romkatv/powerlevel10k.git ~/.oh-my-zsh/themes/powerlevel10k
|
||||
```
|
||||
|
||||
并在你的 `~/.zshrc` 文件设置 `ZSH_THEME`:
|
||||
|
||||
```
|
||||
ZSH_THEME=powerlevel10k/powerlevel10k
|
||||
```
|
||||
|
||||
关闭终端。再次打开终端时,powerlevel10k 配置向导将询问你几个问题以正确配置提示符。
|
||||
|
||||
![][8]
|
||||
|
||||
完成 powerline10k 配置向导后,你的提示符将如下所示:
|
||||
|
||||
![][9]
|
||||
|
||||
如果你不喜欢它。你可以随时使用 `p10k configure` 命令来运行 powerline10k 向导。
|
||||
|
||||
#### 启用插件
|
||||
|
||||
插件存储在 `.oh-my-zsh/plugins` 文件夹中。要激活插件,你需要编辑 `~/.zshrc` 文件。安装插件意味着你创建了一系列执行特定功能的别名或快捷方式。
|
||||
|
||||
例如,要启用 firewalld 和 git 插件,请首先编辑 `~/.zshrc`:
|
||||
|
||||
```
|
||||
plugins=(firewalld git)
|
||||
```
|
||||
|
||||
注意:使用空格分隔插件名称列表。
|
||||
|
||||
然后重新加载配置:
|
||||
|
||||
```
|
||||
source ~/.zshrc
|
||||
```
|
||||
|
||||
要查看创建的别名,请使用以下命令:
|
||||
|
||||
```
|
||||
alias | grep firewall
|
||||
```
|
||||
|
||||
![][10]
|
||||
|
||||
#### 更多配置
|
||||
|
||||
我建议安装语法高亮和语法自动建议插件。
|
||||
|
||||
```
|
||||
git clone https://github.com/zsh-users/zsh-syntax-highlighting.git ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-syntax-highlighting
|
||||
git clone https://github.com/zsh-users/zsh-autosuggestions ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-autosuggestions
|
||||
```
|
||||
|
||||
将它们添加到文件 `~/.zshrc` 的插件列表中。
|
||||
|
||||
```
|
||||
plugins=( [plugins...] zsh-syntax-highlighting zsh-autosuggestions)
|
||||
```
|
||||
|
||||
重新加载配置。
|
||||
|
||||
```
|
||||
source ~/.zshrc
|
||||
```
|
||||
|
||||
查看结果:
|
||||
|
||||
![][11]
|
||||
|
||||
### 彩色的文件夹和图标
|
||||
|
||||
`colorls` 是一个 ruby gem,可使用颜色和超棒的字体图标美化终端的 `ls` 命令。你可以访问官方[网站][12]以获取更多信息。
|
||||
|
||||
因为它是个 ruby gem,所以请按照以下简单步骤操作:
|
||||
|
||||
```
|
||||
sudo gem install colorls
|
||||
```
|
||||
|
||||
要保持最新状态,只需执行以下操作:
|
||||
|
||||
```
|
||||
sudo gem update colorls
|
||||
```
|
||||
|
||||
为防止每次输入 `colorls`,你可以在 `~/.bashrc` 或 `~/.zshrc` 中创建别名。
|
||||
|
||||
```
|
||||
alias ll='colorls -lA --sd --gs --group-directories-first'
|
||||
alias ls='colorls --group-directories-first'
|
||||
```
|
||||
|
||||
另外,你可以为 `colorls` 的选项启用制表符补完功能,只需在 shell 配置末尾输入以下行:
|
||||
|
||||
```
|
||||
source $(dirname ($gem which colorls))/tab_complete.sh
|
||||
```
|
||||
|
||||
重新加载并查看会发生什么:
|
||||
|
||||
![][13]
|
||||
|
||||
![][14]
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://fedoramagazine.org/tuning-your-bash-or-zsh-shell-in-workstation-and-silverblue/
|
||||
|
||||
作者:[George Luiz Maluf][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[wxy](https://github.com/wxy)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://fedoramagazine.org/author/georgelmaluf/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://fedoramagazine.org/wp-content/uploads/2019/10/tuning-shell-816x345.jpg
|
||||
[2]: https://fedoramagazine.org/add-power-terminal-powerline/
|
||||
[3]: https://powerline.readthedocs.io/en/latest/
|
||||
[4]: https://fedoramagazine.org/wp-content/uploads/2019/10/terminal_bash_powerline.png
|
||||
[5]: https://ohmyz.sh
|
||||
[6]: https://fedoramagazine.org/set-zsh-fedora-system/
|
||||
[7]: https://fedoramagazine.org/wp-content/uploads/2019/10/oh-my-zsh.png
|
||||
[8]: https://fedoramagazine.org/wp-content/uploads/2019/10/powerlevel10k_config_wizard.png
|
||||
[9]: https://fedoramagazine.org/wp-content/uploads/2019/10/powerlevel10k.png
|
||||
[10]: https://fedoramagazine.org/wp-content/uploads/2019/10/aliases_plugin.png
|
||||
[11]: https://fedoramagazine.org/wp-content/uploads/2019/10/sintax.png
|
||||
[12]: https://github.com/athityakumar/colorls
|
||||
[13]: https://fedoramagazine.org/wp-content/uploads/2019/10/ls-1024x495.png
|
||||
[14]: https://fedoramagazine.org/wp-content/uploads/2019/10/ll-1024x495.png
|
@ -0,0 +1,142 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11587-1.html)
|
||||
[#]: subject: (7 Best Open Source Tools that will help in AI Technology)
|
||||
[#]: via: (https://opensourceforu.com/2019/11/7-best-open-source-tools-that-will-help-in-ai-technology/)
|
||||
[#]: author: (Nitin Garg https://opensourceforu.com/author/nitin-garg/)
|
||||
|
||||
7 个有助于 AI 技术的最佳开源工具
|
||||
======
|
||||
|
||||
![][1]
|
||||
|
||||
> 人工智能是一种紧跟未来道路的卓越技术。在这个不断发展的时代,它吸引了所有跨国组织的关注。谷歌、IBM、Facebook、亚马逊、微软等业内知名公司不断投资于这种新时代技术。
|
||||
|
||||
预测业务需求需要利用人工智能,并在另一个层面上进行研发。这项先进技术正成为提供超智能解决方案的研发组织不可或缺的一部分。它可以帮助你保持准确性并以更好的结果提高生产率。
|
||||
|
||||
AI 开源工具和技术以频繁且准确的结果吸引了每个行业的关注。这些工具可帮助你分析绩效,同时为你带来更大的收益。
|
||||
|
||||
无需赘言,这里我们列出了一些最佳的开源工具,来帮助你更好地了解人工智能。
|
||||
|
||||
### 1、TensorFlow
|
||||
|
||||
TensorFlow 是用于人工智能的开源机器学习框架。它主要是为了进行机器学习和深度学习的研究和生产而开发的。TensorFlow 允许开发者创建数据流的图结构,它会在网络或系统节点中移动,图提供了数据的多维数组或张量。
|
||||
|
||||
TensorFlow 是一个出色的工具,它有无数的优势。
|
||||
|
||||
* 简化数值计算
|
||||
* TensorFlow 在多种模型上提供了灵活性。
|
||||
* TensorFlow 提高了业务效率
|
||||
* 高度可移植
|
||||
* 自动区分能力
|
||||
|
||||
### 2、Apache SystemML
|
||||
|
||||
Apache SystemML 是由 IBM 创建的非常流行的开源机器学习平台,它提供了使用大数据的良好平台。它可以在 Apache Spark 上高效运行,并自动扩展数据,同时确定代码是否可以在磁盘或 Apache Spark 集群上运行。不仅如此,它丰富的功能使其在行业产品中脱颖而出;
|
||||
|
||||
* 算法自定义
|
||||
* 多种执行模式
|
||||
* 自动优化
|
||||
|
||||
它还支持深度学习,让开发者更有效率地实现机器学习代码并优化。
|
||||
|
||||
### 3、OpenNN
|
||||
|
||||
OpenNN 是用于渐进式分析的开源人工智能神经网络库。它可帮助你使用 C++ 和 Python 开发健壮的模型,它还包含用于处理机器学习解决方案(如预测和分类)的算法和程序。它还涵盖了回归和关联,可提供业界的高性能和技术演化。
|
||||
|
||||
它有丰富的功能,如:
|
||||
|
||||
* 数字化协助
|
||||
* 预测分析
|
||||
* 快速的性能
|
||||
* 虚拟个人协助
|
||||
* 语音识别
|
||||
* 高级分析
|
||||
|
||||
它可帮助你设计实现数据挖掘的先进方案,而从取得丰硕结果。
|
||||
|
||||
### 4、Caffe
|
||||
|
||||
Caffe(快速特征嵌入的卷积结构)是一个开源深度学习框架。它优先考虑速度、模块化和表达式。Caffe 最初由加州大学伯克利分校视觉和学习中心开发,它使用 C++ 编写,带有 Python 接口。能在 Linux、macOS 和 Windows 上顺利运行。
|
||||
|
||||
Caffe 中的一些有助于 AI 技术的关键特性。
|
||||
|
||||
1. 具有表现力的结构
|
||||
2. 具有扩展性的代码
|
||||
3. 大型社区
|
||||
4. 开发活跃
|
||||
5. 性能快速
|
||||
|
||||
它可以帮助你激发创新,同时引入刺激性增长。充分利用此工具来获得所需的结果。
|
||||
|
||||
### 5、Torch
|
||||
|
||||
Torch 是一个开源机器学习库,通过提供多种方便的功能,帮助你简化序列化、面向对象编程等复杂任务。它在机器学习项目中提供了最大的灵活性和速度。Torch 使用脚本语言 Lua 编写,底层使用 C 实现。它用于多个组织和研究实验室中。
|
||||
|
||||
Torch 有无数的优势,如:
|
||||
|
||||
* 快速高效的 GPU 支持
|
||||
* 线性代数子程序
|
||||
* 支持 iOS 和 Android 平台
|
||||
* 数值优化子程序
|
||||
* N 维数组
|
||||
|
||||
### 6、Accord .NET
|
||||
|
||||
Accord .NET 是著名的自由开源 AI 开发工具之一。它有一组库,可以用来组合使用 C# 编写的音频和图像处理库。从计算机视觉到计算机听觉、信号处理和统计应用,它可以帮助你构建用于商业用途一切需求。它附带了一套全面的示例应用来快速运行各类库。
|
||||
|
||||
你可以使用 Accord .NET 引人注意的功能开发一个高级应用,例如:
|
||||
|
||||
* 统计分析
|
||||
* 数据接入
|
||||
* 自适应
|
||||
* 深度学习
|
||||
* 二阶神经网络学习算法
|
||||
* 数字协助和多语言
|
||||
* 语音识别
|
||||
|
||||
### 7、Scikit-Learn
|
||||
|
||||
Scikit-Learn 是流行的辅助 AI 技术的开源工具之一。它是 Python 中用于机器学习的一个很有价值的库。它包括机器学习和统计建模(包括分类、聚类、回归和降维)等高效工具。
|
||||
|
||||
让我们了解下 Scikit-Learn 的更多功能:
|
||||
|
||||
* 交叉验证
|
||||
* 聚类和分类
|
||||
* 流形学习
|
||||
* 机器学习
|
||||
* 虚拟流程自动化
|
||||
* 工作流自动化
|
||||
|
||||
从预处理到模型选择,Scikit-learn 可帮助你处理所有问题。它简化了从数据挖掘到数据分析的所有任务。
|
||||
|
||||
### 总结
|
||||
|
||||
这些是一些流行的开源 AI 工具,它们提供了全面的功能。在开发新时代应用之前,人们必须选择其中一个工具并做相应的工作。这些工具提供先进的人工智能解决方案,并紧跟最新趋势。
|
||||
|
||||
人工智能在全球范围内应用,无处不在。借助 Amazon Alexa、Siri 等应用,AI 为客户提供了很好的用户体验。它在吸引用户关注的行业中具有显著优势。在医疗保健、银行、金融、电子商务等所有行业中,人工智能在促进增长和生产力的同时节省了大量的时间和精力。
|
||||
|
||||
选择这些开源工具中的任何一个,获得更好的用户体验和令人难以置信的结果。它将帮助你成长,并在质量和安全性方面获得更好的结果。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensourceforu.com/2019/11/7-best-open-source-tools-that-will-help-in-ai-technology/
|
||||
|
||||
作者:[Nitin Garg][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensourceforu.com/author/nitin-garg/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://i1.wp.com/opensourceforu.com/wp-content/uploads/2018/05/Artificial-Intelligence_EB-June-17.jpg?resize=696%2C464&ssl=1 (Artificial Intelligence_EB June 17)
|
||||
[2]: https://i1.wp.com/opensourceforu.com/wp-content/uploads/2018/05/Artificial-Intelligence_EB-June-17.jpg?fit=1000%2C667&ssl=1
|
||||
[3]: https://secure.gravatar.com/avatar/d4e6964b80590824b981f06a451aa9e6?s=100&r=g
|
||||
[4]: https://opensourceforu.com/author/nitin-garg/
|
||||
[5]: https://www.brsoftech.com/bi-consulting-services.html
|
||||
[6]: https://opensourceforu.com/wp-content/uploads/2019/11/assoc.png
|
||||
[7]: https://feedburner.google.com/fb/a/mailverify?uri=LinuxForYou&loc=en_US
|
@ -0,0 +1,101 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (wxy)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11559-1.html)
|
||||
[#]: subject: (Budget-friendly Linux Smartphone PinePhone Will be Available to Pre-order Next Week)
|
||||
[#]: via: (https://itsfoss.com/pinephone/)
|
||||
[#]: author: (Ankush Das https://itsfoss.com/author/ankush/)
|
||||
|
||||
低价 Linux 智能手机 PinePhone 即将接受预订
|
||||
======
|
||||
|
||||
![PinePhone Prototype | Image by Martjin Braam][3]
|
||||
|
||||
你还记得[在 2017 年首次披露][1]的 Pine64 正在开发一个基于 Linux(可以运行 KDE Plasma 及其他发行版)的智能手机的事情吗?从那以后已经有一段时间了,但是好消息是 PinePhone 将从 11 月 15 日开始接受预订。
|
||||
|
||||
让我来为你提供有关 PinePhone 的更多详细信息,例如其规格、价格和发布日期。
|
||||
|
||||
### PinePhone:基于 Linux 的廉价智能手机
|
||||
|
||||
PinePhone 开发者套件已经经过了一些开发人员的测试,更多此类套件将于 11 月 15 日发货。你可以查看下面的照片:
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
开发者套件是由 PINE A64 基板 + SOPine 模块 + 7 英寸触摸屏显示器 + 摄像头 + Wifi / BT + 外壳 + 锂离子电池盒 + LTE cat 4 USB 软件狗组成的组合套件。
|
||||
|
||||
这些组合套件可以使开发人员快速开始 PinePhone 开发。由于 PINE64 社区和 [KDE neon][2] 的支持,主线 Linux 操作系统已经可以在 PINE A64 平台上构建。
|
||||
|
||||
#### PinePhone 规格
|
||||
|
||||
* Allwinner A64 四核 SoC,带有 Mali 400 MP2 GPU
|
||||
* 2GB 的 LPDDR3 RAM
|
||||
* 5.95 英寸 LCD 1440×720,长宽比 18:9(钢化玻璃)
|
||||
* 可启动的 Micro SD
|
||||
* 16GB eMMC
|
||||
* 高清数字视频输出
|
||||
* USB Type-C(电源、数据和视频输出)
|
||||
* Quectel EG-25G 全球波段
|
||||
* WiFi:802.11 b/g/n,单频,支持热点
|
||||
* 蓝牙:4.0,A2DP
|
||||
* GNSS:GPS,GPS-A,GLONASS
|
||||
* 振动器
|
||||
* RGB 状态 LED
|
||||
* 自拍和主摄像头(分别为 2/5 Mpx)
|
||||
* 主摄像头:单颗 OV6540、5MP,1/4 英寸,LED 闪光灯
|
||||
* 自拍相机:单 GC2035、2MP,f/2.8、1/5 英寸
|
||||
* 传感器:加速器、陀螺仪、距离感应器、罗盘、气压计、环境光感
|
||||
* 3 个外部开关:上、下和电源
|
||||
* 硬件开关:LTE/GNSS、WiFi、麦克风、扬声器、USB
|
||||
* 三星 J7 外形尺寸 3000mAh 电池
|
||||
* 外壳是磨砂黑色成品塑料
|
||||
* 耳机插孔
|
||||
|
||||
#### 产品、价格和交付时间
|
||||
|
||||
PinePhone 的价格约为 150 美元。尝鲜版命名为“勇敢的心”,将于 2019 年 11 月 15 日开始销售。如上图所示,[Pine64 的主页][5]包含了用于首次预订 PinePhone 的计时器。
|
||||
|
||||
预期“勇敢的心”尝鲜版在 2019 年 12 月或 2020 年 1 月之前发货。
|
||||
|
||||
大规模生产将在中国的农历新年后开始,也就是说在 2020 年第二季度早期或最早 2020 年 3 月开始。
|
||||
|
||||
该电话尚未在 Pine Store 中列出,因此,如果你想成为尝鲜者之一,请务必查看 [Pine64 在线商店][6]以预订“勇敢的心”版本。
|
||||
|
||||
#### 你对 PinePhone 如何看?
|
||||
|
||||
Pine64 已经开发了一款名为 [Pinebook][7] 的廉价笔记本电脑和一款功能相对强大的 [Pinebook Pro][8] 笔记本电脑。因此,PinePhone 至少在 DIY 爱好者和 Linux 忠实拥护者的狭窄市场中绝对有希望获得成功。与其他价格超过 600 美元的 [Linux 智能手机 Librem5][9] 相比,低廉的价格绝对是一个巨大的优势。
|
||||
|
||||
PinePhone 的另一个优点是,你可以通过安装 Ubuntu Touch、Plasma Mobile 或 Aurora OS/Sailfish OS 来试验操作系统。
|
||||
|
||||
这些基于 Linux 的智能手机尚不具备取代 Android 或 iOS 的功能。如果你正在寻找功能全面的智能手机来替代你的 Android 智能手机,那么 PinePhone 当然不适合你。但对于喜欢尝试并且不害怕排除故障的人来说,它的优势更大。
|
||||
|
||||
如果你想购买 PinePhone,请记住这个日期并设置提醒。供应应该是限量的,到目前为止,我所了解的,Pine 设备很快就会脱销。
|
||||
|
||||
你要预订 PinePhone 吗?在评论部分将你的意见告知我们。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://itsfoss.com/pinephone/
|
||||
|
||||
作者:[Ankush Das][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[wxy](https://github.com/wxy)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://itsfoss.com/author/ankush/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://itsfoss.com/pinebook-kde-smartphone/
|
||||
[2]: https://neon.kde.org/
|
||||
[3]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2019/11/pinephone-prototype.jpeg?ssl=1
|
||||
[4]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2019/11/pinephone-brave-heart-pre-order.jpg?ssl=1
|
||||
[5]: https://www.pine64.org/
|
||||
[6]: https://store.pine64.org/
|
||||
[7]: https://itsfoss.com/pinebook-linux-notebook/
|
||||
[8]: https://itsfoss.com/pinebook-pro/
|
||||
[9]: https://itsfoss.com/librem-linux-phone/
|
@ -0,0 +1,145 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11579-1.html)
|
||||
[#]: subject: (How to manage music tags using metaflac)
|
||||
[#]: via: (https://opensource.com/article/19/11/metaflac-fix-music-tags)
|
||||
[#]: author: (Chris Hermansen https://opensource.com/users/clhermansen)
|
||||
|
||||
如何使用 metaflac 管理音乐标签
|
||||
======
|
||||
|
||||
> 使用这个强大的开源工具可以在命令行中纠正音乐标签错误。
|
||||
|
||||

|
||||
|
||||
很久以来我就将 CD 翻录到电脑。在此期间,我用过几种不同的翻录工具,观察到每种工具在标记上似乎有不同的做法,特别是在保存哪些音乐元数据上。所谓“观察”,我是指音乐播放器似乎按照有趣的顺序对专辑进行排序,它们将一个目录中的曲目分为两张专辑,或者产生了其他令人沮丧的烦恼。
|
||||
|
||||
我还看到有些标签非常不明确,许多音乐播放器和标签编辑器没有显示它们。即使这样,在某些极端情况下,它们仍可以使用这些标签来分类或显示音乐,例如播放器将所有包含 XYZ 标签的音乐文件与不包含该标签的所有文件分离到不同的专辑中。
|
||||
|
||||
那么,如果标记应用和音乐播放器没有显示“奇怪”的标记,但是它们受到了某种影响,你该怎么办?
|
||||
|
||||
### Metaflac 来拯救!
|
||||
|
||||
我一直想要熟悉 [metaflac][2],它是一款开源命令行 [FLAC 文件][3]元数据编辑器,这是我选择的开源音乐文件格式。并不是说 [EasyTAG][4] 这样出色的标签编辑软件有什么问题,但我想起“如果你手上有个锤子……”这句老话(LCTT 译注:指如果你手上有个锤子,那么所有的东西看起来都像钉子。意指人们惯于用熟悉的方式解决问题,而不管合不合适)。另外,从实际的角度来看,带有 [Armbian][5] 和 [MPD][6] 的小型专用服务器,音乐存储在本地、运行精简的仅限音乐的无头环境就可以满足我的家庭和办公室的立体音乐的需求,因此命令行元数据管理工具将非常有用。
|
||||
|
||||
下面的截图显示了我的长期翻录过程中产生的典型问题:Putumayo 的哥伦比亚音乐汇编显示为两张单独的专辑,一张包含单首曲目,另一张包含其余 11 首:
|
||||
|
||||
![Album with incorrect tags][7]
|
||||
|
||||
我使用 `metaflac` 为目录中包含这些曲目的所有 FLAC 文件生成了所有标签的列表:
|
||||
|
||||
```
|
||||
rm -f tags.txt
|
||||
for f in *.flac; do
|
||||
echo $f >> tags.txt
|
||||
metaflac --export-tags-to=tags.tmp "$f"
|
||||
cat tags.tmp >> tags.txt
|
||||
rm tags.tmp
|
||||
done
|
||||
```
|
||||
|
||||
我将其保存为可执行的 shell 脚本(请参阅我的同事 [David Both][8] 关于 Bash shell 脚本的精彩系列专栏文章,[特别是关于循环这章][9])。基本上,我在这做的是创建一个文件 `tags.txt`,包含文件名(`echo` 命令),后面是它的所有标签,然后是下一个文件名,依此类推。这是结果的前几行:
|
||||
|
||||
|
||||
```
|
||||
A Guapi.flac
|
||||
TITLE=A Guapi
|
||||
ARTIST=Grupo Bahia
|
||||
ALBUMARTIST=Various Artists
|
||||
ALBUM=Putumayo Presents: Colombia
|
||||
DATE=2001
|
||||
TRACKTOTAL=12
|
||||
GENRE=Latin Salsa
|
||||
MUSICBRAINZ_ALBUMARTISTID=89ad4ac3-39f7-470e-963a-56509c546377
|
||||
MUSICBRAINZ_ALBUMID=6e096386-1655-4781-967d-f4e32defb0a3
|
||||
MUSICBRAINZ_ARTISTID=2993268d-feb6-4759-b497-a3ef76936671
|
||||
DISCID=900a920c
|
||||
ARTISTSORT=Grupo Bahia
|
||||
MUSICBRAINZ_DISCID=RwEPU0UpVVR9iMP_nJexZjc_JCc-
|
||||
COMPILATION=1
|
||||
MUSICBRAINZ_TRACKID=8a067685-8707-48ff-9040-6a4df4d5b0ff
|
||||
ALBUMARTISTSORT=50 de Joselito, Los
|
||||
Cumbia Del Caribe.flac
|
||||
```
|
||||
|
||||
经过一番调查,结果发现我同时翻录了很多 Putumayo CD,并且当时我所使用的所有软件似乎给除了一个之外的所有文件加上了 `MUSICBRAINZ_*` 标签。(是 bug 么?大概吧。我在六张专辑中都看到了。)此外,关于有时不寻常的排序,我注意到,`ALBUMARTISTSORT` 标签将西班牙语标题 “Los” 移到了标题的最后面(逗号之后)。
|
||||
|
||||
我使用了一个简单的 `awk` 脚本来列出 `tags.txt` 中报告的所有标签:
|
||||
|
||||
```
|
||||
awk -F= 'index($0,"=") > 0 {print $1}' tags.txt | sort -u
|
||||
```
|
||||
|
||||
这会使用 `=` 作为字段分隔符将所有行拆分为字段,并打印包含等号的行的第一个字段。结果通过使用 `sort` 及其 `-u` 标志来传递,从而消除了输出中的所有重复项(请参阅我的同事 Seth Kenlon 的[关于 `sort` 程序的文章][10])。对于这个 `tags.txt` 文件,输出为:
|
||||
|
||||
```
|
||||
ALBUM
|
||||
ALBUMARTIST
|
||||
ALBUMARTISTSORT
|
||||
ARTIST
|
||||
ARTISTSORT
|
||||
COMPILATION
|
||||
DATE
|
||||
DISCID
|
||||
GENRE
|
||||
MUSICBRAINZ_ALBUMARTISTID
|
||||
MUSICBRAINZ_ALBUMID
|
||||
MUSICBRAINZ_ARTISTID
|
||||
MUSICBRAINZ_DISCID
|
||||
MUSICBRAINZ_TRACKID
|
||||
TITLE
|
||||
TRACKTOTAL
|
||||
```
|
||||
|
||||
研究一会后,我发现 `MUSICBRAINZ_*` 标签出现在除了一个 FLAC 文件之外的所有文件上,因此我使用 `metaflac` 命令删除了这些标签:
|
||||
|
||||
```
|
||||
for f in *.flac; do metaflac --remove-tag MUSICBRAINZ_ALBUMARTISTID "$f"; done
|
||||
for f in *.flac; do metaflac --remove-tag MUSICBRAINZ_ALBUMID "$f"; done
|
||||
for f in *.flac; do metaflac --remove-tag MUSICBRAINZ_ARTISTID "$f"; done
|
||||
for f in *.flac; do metaflac --remove-tag MUSICBRAINZ_DISCID "$f"; done
|
||||
for f in *.flac; do metaflac --remove-tag MUSICBRAINZ_TRACKID "$f"; done
|
||||
```
|
||||
|
||||
完成后,我可以使用音乐播放器重建 MPD 数据库。结果如下:
|
||||
|
||||
![Album with correct tags][11]
|
||||
|
||||
完成了,12 首曲目出现在了一张专辑中。
|
||||
|
||||
太好了,我很喜欢 `metaflac`。我希望我会更频繁地使用它,因为我会试图去纠正最后一些我弄乱的音乐收藏标签。强烈推荐!
|
||||
|
||||
### 关于音乐
|
||||
|
||||
我花了几个晚上在 CBC 音乐(CBC 是加拿大的公共广播公司)上收听 Odario Williams 的节目 After Dark。感谢 Odario,我听到了让我非常享受的 [Kevin Fox 的 Songs for Cello and Voice] [12]。在这里,他演唱了 Eurythmics 的歌曲 “[Sweet Dreams(Are Made of This)][13]”。
|
||||
|
||||
我购买了这张 CD,现在它在我的音乐服务器上,还有组织正确的标签!
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/19/11/metaflac-fix-music-tags
|
||||
|
||||
作者:[Chris Hermansen][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/clhermansen
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/web-design-monitor-website.png?itok=yUK7_qR0 (website design image)
|
||||
[2]: https://xiph.org/flac/documentation_tools_metaflac.html
|
||||
[3]: https://xiph.org/flac/index.html
|
||||
[4]: https://wiki.gnome.org/Apps/EasyTAG
|
||||
[5]: https://www.armbian.com/
|
||||
[6]: https://www.musicpd.org/
|
||||
[7]: https://opensource.com/sites/default/files/uploads/music-tags1_before.png (Album with incorrect tags)
|
||||
[8]: https://opensource.com/users/dboth
|
||||
[9]: https://opensource.com/article/19/10/programming-bash-loops
|
||||
[10]: https://opensource.com/article/19/10/get-sorted-sort
|
||||
[11]: https://opensource.com/sites/default/files/uploads/music-tags2_after.png (Album with correct tags)
|
||||
[12]: https://burlingtonpac.ca/events/kevin-fox/
|
||||
[13]: https://www.youtube.com/watch?v=uyN66XI1zp4
|
@ -0,0 +1,90 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (wxy)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11562-1.html)
|
||||
[#]: subject: (Confirmed! Microsoft Edge Will be Available on Linux)
|
||||
[#]: via: (https://itsfoss.com/microsoft-edge-linux/)
|
||||
[#]: author: (Abhishek Prakash https://itsfoss.com/author/abhishek/)
|
||||
|
||||
确认了!微软 Edge 浏览器将发布 Linux 版
|
||||
======
|
||||
|
||||

|
||||
|
||||
> 微软正在全面重制其 Edge Web 浏览器,它将基于开源 [Chromium][2] 浏览器。微软还要将新的 Edge 浏览器带到 Linux 桌面上,但是 Linux 版本可能会有所延迟。
|
||||
|
||||
微软的 Internet Explorer 曾经一度统治了浏览器市场,但在过去的十年中,它将统治地位丢给了谷歌的 Chrome。
|
||||
|
||||
微软试图通过创造 Edge 浏览器来找回失去的位置,Edge 是一种使用 EdgeHTML 和 [Chakra 引擎][6]构建的全新 Web 浏览器。它与 Microsoft 的数字助手 [Cortana][7] 和 Windows 10 紧密集成。
|
||||
|
||||
但是,它仍然无法夺回冠军位置,截至目前,它处于[桌面浏览器使用份额的第四位][8]。
|
||||
|
||||
最近,微软决定通过基于[开源 Chromium 项目][9]重新对 Edge 进行大修。谷歌的 Chrome 浏览器也是基于 Chromium 的。[Chromium 还可以作为独立的 Web 浏览器使用][2],某些 Linux 发行版将其用作默认的 Web 浏览器。
|
||||
|
||||
### Linux 上新的微软 Edge Web 浏览器
|
||||
|
||||
经过最初的犹豫和不确定性之后,微软似乎最终决定把新的 Edge 浏览器引入到 Linux。
|
||||
|
||||
在其年度开发商大会 [Microsoft Ignite][10] 中,[关于 Edge 浏览器的演讲][11]中提到了它未来将进入 Linux 中。
|
||||
|
||||
![微软确认 Edge 未来将进入 Linux 中][12]
|
||||
|
||||
新的 Edge 浏览器将于 2020 年 1 月 15 日发布,但我认为 Linux 版本会推迟。
|
||||
|
||||
### 微软 Edge 进入 Linux 真的重要吗?
|
||||
|
||||
微软 Edge 进入 Linux 有什么大不了的吗?我们又不是没有很多[可用于 Linux 的 Web 浏览器][13]?
|
||||
|
||||
我认为这与 “微软 Linux 竞争”(如果有这样的事情)有关。微软为 Linux(特别是 Linux 桌面)做的任何事情,都会成为新闻。
|
||||
|
||||
我还认为 Linux 上的 Edge 对于微软和 Linux 用户都有好处。这就是为什么。
|
||||
|
||||
#### 对于微软有什么用?
|
||||
|
||||
当谷歌在 2008 年推出其 Chrome 浏览器时,没有人想到它会在短短几年内占领市场。但是,为什么作为一个搜索引擎会在一个“免费的 Web 浏览器”后面投入如此多的精力呢?
|
||||
|
||||
答案是谷歌是一家搜索引擎,它希望有更多的人使用其搜索引擎和其他服务,以便它可以从广告服务中获得收入。使用 Chrome,Google 是默认的搜索引擎。在 Firefox 和 Safari 等其他浏览器上,谷歌支付了数亿美元作为默认 Web 浏览器的费用。如果没有 Chrome,则谷歌必须完全依赖其他浏览器。
|
||||
|
||||
微软也有一个名为 Bing 的搜索引擎。Internet Explorer 和 Edge 使用 Bing 作为默认搜索引擎。如果更多用户使用 Edge,它可以增加将更多用户带到 Bing 的机会。而微软显然希望拥有更多的 Bing 用户。
|
||||
|
||||
#### 对 Linux 用户有什么用?
|
||||
|
||||
对于 Linux 桌面用户,我看到有两个好处。借助 Edge,你可以在 Linux 上使用某些微软特定的产品。 例如,微软的流式游戏服务 [xCloud][14] 可能仅能在 Edge 浏览器上使用。另一个好处是提升了 [Linux 上的 Netflix 体验][15]。当然,你可以在 Linux 上使用 Chrome 或 [Firefox 观看 Netflix][16],但可能无法获得全高清或超高清流。
|
||||
|
||||
据我所知,[全高清和超高清 Netflix 流仅在微软 Edge 上可用][17]。这意味着你可以使用 Linux 上的 Edge 以高清格式享受 Netflix。
|
||||
|
||||
### 你怎么看?
|
||||
|
||||
你对微软 Edge 进入 Linux 有什么感觉?当 Linux 版本可用时,你会使用吗?请在下面的评论部分中分享你的观点。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://itsfoss.com/microsoft-edge-linux/
|
||||
|
||||
作者:[Abhishek Prakash][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[wxy](https://github.com/wxy)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://itsfoss.com/author/abhishek/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2019/11/microsoft_edge_logo_transparent.png?ssl=1
|
||||
[2]: https://itsfoss.com/install-chromium-ubuntu/
|
||||
[3]: https://twitter.com/hashtag/opensource?src=hash&ref_src=twsrc%5Etfw
|
||||
[4]: https://t.co/Co5Xj3dKIQ
|
||||
[5]: https://twitter.com/abhishek_foss/status/844666818665025537?ref_src=twsrc%5Etfw
|
||||
[6]: https://itsfoss.com/microsoft-chakra-core/
|
||||
[7]: https://www.microsoft.com/en-in/windows/cortana
|
||||
[8]: https://en.wikipedia.org/wiki/Usage_share_of_web_browsers
|
||||
[9]: https://www.chromium.org/Home
|
||||
[10]: https://www.microsoft.com/en-us/ignite
|
||||
[11]: https://myignite.techcommunity.microsoft.com/sessions/79341?source=sessions
|
||||
[12]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2019/11/Microsoft_Edge_Linux.jpg?ssl=1
|
||||
[13]: https://itsfoss.com/open-source-browsers-linux/
|
||||
[14]: https://www.pocket-lint.com/games/news/147429-what-is-xbox-project-xcloud-cloud-gaming-service-price-release-date-devices
|
||||
[15]: https://itsfoss.com/watch-netflix-in-ubuntu-linux/
|
||||
[16]: https://itsfoss.com/netflix-firefox-linux/
|
||||
[17]: https://help.netflix.com/en/node/23742
|
201
published/201911/20191112 Getting started with PostgreSQL.md
Normal file
201
published/201911/20191112 Getting started with PostgreSQL.md
Normal file
@ -0,0 +1,201 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11593-1.html)
|
||||
[#]: subject: (Getting started with PostgreSQL)
|
||||
[#]: via: (https://opensource.com/article/19/11/getting-started-postgresql)
|
||||
[#]: author: (Greg Pittman https://opensource.com/users/greg-p)
|
||||
|
||||
PostgreSQL 入门
|
||||
======
|
||||
|
||||
> 安装、设置、创建和开始使用 PostgreSQL 数据库。
|
||||
|
||||

|
||||
|
||||
每个人或许都有需要在数据库中保存的东西。即使你执着于使用纸质文件或电子文件,它们也会变得很麻烦。纸质文档可能会丢失或混乱,你需要访问的电子信息可能会隐藏在段落和页面的深处。
|
||||
|
||||
在我从事医学工作的时候,我使用 [PostgreSQL][2] 来跟踪我的住院患者名单并提交有关住院患者的信息。我将我的每日患者名单打印在口袋里,以便快速了解患者房间、诊断或其他细节的任何变化并做出快速记录。
|
||||
|
||||
我以为一切没问题,直到去年我妻子决定买一辆新车,我“接手”了她以前的那辆车。她保留了汽车维修和保养服务收据的文件夹,但随着时间的流逝,它变得杂乱。与其花时间筛选所有纸条以弄清楚什么时候做了什么,我认为 PostgreSQL 将是更好的跟踪此信息的方法。
|
||||
|
||||
### 安装 PostgreSQL
|
||||
|
||||
自上次使用 PostgreSQL 以来已经有一段时间了,我已经忘记了如何使用它。实际上,我甚至没有在计算机上安装它。安装它是第一步。我使用 Fedora,因此在控制台中运行:
|
||||
|
||||
```
|
||||
dnf list postgresql*
|
||||
```
|
||||
|
||||
请注意,你无需使用 `sudo` 即可使用 `list` 选项。该命令返回了很长的软件包列表。看了眼后,我决定只需要三个:postgresql、postgresql-server 和 postgresql-docs。
|
||||
|
||||
为了了解下一步需要做什么,我决定查看 [PostgreSQL 文档][3]。文档参考内容非常丰富,实际上,丰富到令人生畏。幸运的是,我发现我在升级 Fedora 时曾经做过的一些笔记,希望有效地导出数据库,在新版本上重新启动 PostgreSQL,以及导入旧数据库。
|
||||
|
||||
### 设置 PostgreSQL
|
||||
|
||||
与大多数其他软件不同,你不能只是安装好 PostgreSQL 就开始使用它。你必须预先执行两个基本步骤:首先,你需要设置 PostgreSQL,第二,你需要启动它。你必须以 `root` 用户身份执行这些操作(`sudo` 在这里不起作用)。
|
||||
|
||||
要设置它,请输入:
|
||||
|
||||
```
|
||||
postgresql-setup –initdb
|
||||
```
|
||||
|
||||
这将确定 PostgreSQL 数据库在计算机上的位置。然后(仍为 `root`)输入以下两个命令:
|
||||
|
||||
```
|
||||
systemctl start postgresql.service
|
||||
systemctl enable postgresql.service
|
||||
```
|
||||
|
||||
第一个命令为当前会话启动 PostgreSQL(如果你关闭机器,那么 PostgreSQL 也将关闭)。第二个命令使 PostgreSQL 在随后的重启中自动启动。
|
||||
|
||||
### 创建用户
|
||||
|
||||
PostgreSQL 正在运行,但是你仍然不能使用它,因为你还没有用户。为此,你需要切换到特殊用户 `postgres`。当你仍以 `root` 身份运行时,输入:
|
||||
|
||||
```
|
||||
su postgres
|
||||
```
|
||||
|
||||
由于你是以 `root` 的身份执行此操作的,因此无需输入密码。root 用户可以在不知道密码的情况下以任何用户身份操作;这就是使其强大而危险的原因之一。
|
||||
|
||||
现在你就是 `postgres` 了,请运行下面两个命令,如下所示创建用户(创建用户 `gregp`):
|
||||
|
||||
```
|
||||
createuser gregp
|
||||
createdb gregp
|
||||
```
|
||||
|
||||
你可能会看到错误消息,如:`Could not switch to /home/gregp`。这只是意味着用户 `postgres`不能访问该目录。尽管如此,你的用户和数据库已创建。接下来,输入 `exit` 并按回车两次,这样就回到了原来的用户下(`root`)。
|
||||
|
||||
### 设置数据库
|
||||
|
||||
要开始使用 PostgreSQL,请在命令行输入 `psql`。你应该在每行左侧看到类似 `gregp=>` 的内容,以显示你使用的是 PostgreSQL,并且只能使用它理解的命令。你自动获得一个数据库(我的名为 `gregp`),它里面完全没有内容。对 PostgreSQL 来说,数据库只是一个工作空间。在空间内,你可以创建*表*。表包含变量列表,而表中的每个变量是构成数据库的数据。
|
||||
|
||||
以下是我设置汽车服务数据库的方式:
|
||||
|
||||
```
|
||||
CREATE TABLE autorepairs (
|
||||
date date,
|
||||
repairs varchar(80),
|
||||
location varchar(80),
|
||||
cost numeric(6,2)
|
||||
);
|
||||
```
|
||||
|
||||
我本可以在一行内输入,但为了更好地说明结构,并表明 PostgreSQL 不会解释制表符和换行的空白,我分成了多行。字段包含在括号中,每个变量名和数据类型与下一个变量用逗号分隔(最后一个除外),命令以分号结尾。所有命令都必须以分号结尾!
|
||||
|
||||
第一个变量名是 `date`,它的数据类型也是 `date`,这在 PostgreSQL 中没关系。第二个和第三个变量 `repairs` 和 `location` 都是 `varchar(80)` 类型,这意味着它们可以是最多 80 个任意字符(字母、数字等)。最后一个变量 `cost` 使用 `numeric` 类型。括号中的数字表示最多有六位数字,其中两位是小数。最初,我尝试了 `real` 类型,这将是一个浮点数。`real` 类型的问题是作为数据类型在使用时,在遇到 `WHERE` 子句,类似 `WHERE cost = 0` 或其他任何特定数字。由于 `real` 值有些不精确,因此特定数字将永远不会匹配。
|
||||
|
||||
### 输入数据
|
||||
|
||||
接下来,你可以使用 `INSERT INTO` 命令添加一些数据(在 PostgreSQL 中称为*行*):
|
||||
|
||||
```
|
||||
INSERT INTO autorepairs VALUES ('2017-08-11', 'airbag recall', 'dealer', 0);
|
||||
```
|
||||
|
||||
请注意,括号构成了一个值的容器,它必须以正确的顺序,用逗号分隔,并在命令末尾加上分号。`date` 和 `varchar(80)` 类型的值必须包含在单引号中,但数字值(如 `numeric`)不用。作为反馈,你应该会看到:
|
||||
|
||||
```
|
||||
INSERT 0 1
|
||||
```
|
||||
|
||||
与常规终端会话一样,你会有输入命令的历史记录,因此,在输入后续行时,通常可以按向上箭头键来显示最后一个命令并根据需要编辑数据,从而节省大量时间。
|
||||
|
||||
如果出了什么问题怎么办?使用 `UPDATE` 更改值:
|
||||
|
||||
```
|
||||
UPDATE autorepairs SET date = '2017-11-08' WHERE repairs = 'airbag recall';
|
||||
```
|
||||
|
||||
或者,也许你不再需要表中的行。使用 `DELETE`:
|
||||
|
||||
```
|
||||
DELETE FROM autorepairs WHERE repairs = 'airbag recall';
|
||||
```
|
||||
|
||||
这将删除整行。
|
||||
|
||||
最后一件事:即使我在 PostgreSQL 命令中一直使用大写字母(在大多数文档中也这么做),你也可以用小写字母输入,我也经常如此。
|
||||
|
||||
### 输出数据
|
||||
|
||||
如果你想展示数据,使用 `SELECT`:
|
||||
|
||||
```
|
||||
SELECT * FROM autorepairs ORDER BY date;
|
||||
```
|
||||
|
||||
没有 `ORDER BY` 的话,行将不管你输入的内容来显示。例如,以下就是我终端中输出的我的汽车服务数据:
|
||||
|
||||
```
|
||||
SELECT date, repairs FROM autorepairs ORDER BY date;
|
||||
|
||||
date | repairs
|
||||
-----------+-----------------------------------------------------------------
|
||||
2008-08-08 | oil change, air filter, spark plugs
|
||||
2011-09-30 | 35000 service, oil change, rotate tires/balance wheels
|
||||
2012-03-07 | repl battery
|
||||
2012-11-14 | 45000 maint, oil/filter
|
||||
2014-04-09 | 55000 maint, oil/filter, spark plugs, air/dust filters
|
||||
2014-04-21 | replace 4 tires
|
||||
2014-04-21 | wheel alignment
|
||||
2016-06-01 | 65000 mile service, oil change
|
||||
2017-05-16 | oil change, replce oil filt housing
|
||||
2017-05-26 | rotate tires
|
||||
2017-06-05 | air filter, cabin filter,spark plugs
|
||||
2017-06-05 | brake pads and rotors, flush brakes
|
||||
2017-08-11 | airbag recall
|
||||
2018-07-06 | oil/filter change, fuel filter, battery svc
|
||||
2018-07-06 | transmission fl, p steering fl, rear diff fl
|
||||
2019-07-22 | oil & filter change, brake fluid flush, front differential flush
|
||||
2019-08-20 | replace 4 tires
|
||||
2019-10-09 | replace passenger taillight bulb
|
||||
2019-10-25 | replace passenger taillight assembly
|
||||
(19 rows)
|
||||
```
|
||||
|
||||
要将此发送到文件,将输出更改为:
|
||||
|
||||
|
||||
```
|
||||
\o autorepairs.txt
|
||||
```
|
||||
|
||||
然后再次运行 `SELECT` 命令。
|
||||
|
||||
### 退出 PostgreSQL
|
||||
|
||||
最后,在终端中退出 PostgreSQL,输入:
|
||||
|
||||
```
|
||||
quit
|
||||
```
|
||||
|
||||
或者它的缩写版:
|
||||
|
||||
```
|
||||
\q
|
||||
```
|
||||
|
||||
虽然这只是 PostgreSQL 的简要介绍,但我希望它展示了将数据库用于这样的简单任务既不困难也不费时。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/19/11/getting-started-postgresql
|
||||
|
||||
作者:[Greg Pittman][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/greg-p
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/computer_code_programming_laptop.jpg?itok=ormv35tV (Guy on a laptop on a building)
|
||||
[2]: https://www.postgresql.org/
|
||||
[3]: http://www.postgresql.org/docs
|
@ -0,0 +1,166 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (guevaraya)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11598-1.html)
|
||||
[#]: subject: (Getting Started With ZFS Filesystem on Ubuntu 19.10)
|
||||
[#]: via: (https://itsfoss.com/zfs-ubuntu/)
|
||||
[#]: author: (John Paul https://itsfoss.com/author/john/)
|
||||
|
||||
在 Ubuntu 19.10 上入门 ZFS 文件系统
|
||||
======
|
||||
|
||||
![][4]
|
||||
|
||||
Ubuntu 19.10 的主要新特性之一就是 [ZFS][2]。现在你可以很容易的无需额外努力就可以在 Ubuntu 系统上安装 ZFS了。
|
||||
|
||||
一般情况下,安装 Linux 都会选择 Ext4 文件系统。但是如果是全新安装 Ubuntu 19.10,在安装的启动阶段可以看到 ZFS 选项。
|
||||
|
||||
![你可以在安装 Ubuntu 19.10 的时候选择 ZFS][3]
|
||||
|
||||
让我们看看 ZFS 为何重要,以及如何在已经安装了 ZFS 的 Ubuntu 上使用它。
|
||||
|
||||
### ZFS 与其他文件系统有哪些区别?
|
||||
|
||||
ZFS 的设计初衷是:处理海量存储和避免数据损坏。ZFS 可以处理 256 千万亿的 ZB 数据。(这就是 ZFS 的 Z)且它可以处理最大 16 EB 的文件。
|
||||
|
||||
如果你仅有一个单磁盘的笔记本电脑,你可以体验 ZFS 的数据保护特性。写时复制(COW)特性确保正在使用的数据不会被覆盖,相反,新的数据会被写到一个新的块中,同时文件系统的元数据会被更新到新块中。ZFS 可容易的创建文件系统的快照。这个快照可追踪文件系统的更改,并共享数据块确保节省数据空间。
|
||||
|
||||
ZFS 为磁盘上的每个文件分配一个校验和。它会不断的校验文件的状态和校验和。如果发现文件被损坏了,它就会尝试修复文件。
|
||||
|
||||
我写过一个文章详细介绍 [什么是 ZFS以及它有哪些特性][2]。如果你感兴趣可以去阅读下。
|
||||
|
||||
注:请谨记 ZFS 的数据保护特性会导致性能下降。
|
||||
|
||||
### Ubuntu 下使用 ZFS [适用于中高级用户]
|
||||
|
||||
一旦你在你的主磁盘上全新安装了带有 ZFS 的 Ubuntu,你就可以开始体验它的特性。
|
||||
|
||||
请注意所有的 ZFS 设置过程都需要命令行。我不知道它有任何 GUI 工具。
|
||||
|
||||
#### 创建一个 ZFS 池
|
||||
|
||||
**这段仅针对拥有多个磁盘的系统。如果你只有一个磁盘,Ubuntu 会在安装的时候自动创建池。**
|
||||
|
||||
在创建池之前,你需要为池找到磁盘的 id。你可以用命令 `lsblk` 查询出这个信息。
|
||||
|
||||
为三个磁盘创建一个基础池,用以下命令:
|
||||
|
||||
```
|
||||
sudo zpool create pool-test /dev/sdb /dev/sdc /dev/sdd
|
||||
```
|
||||
|
||||
请记得替换 `pool-test` 为你选择的的命名。
|
||||
|
||||
这个命令将会设置“无冗余 RAID-0 池”。这意味着如果一个磁盘被破坏或有故障,你将会丢失数据。如果你执行以上命令,还是建议做一个常规备份。
|
||||
|
||||
你可以用下面命令将另一个磁盘增加到池中:
|
||||
|
||||
```
|
||||
sudo zpool add pool-name /dev/sdx
|
||||
```
|
||||
|
||||
#### 查看 ZFS 池的状态
|
||||
|
||||
你可以用这个命令查询新建池的状态:
|
||||
|
||||
```
|
||||
sudo zpool status pool-test
|
||||
```
|
||||
|
||||
![Zpool 状态][6]
|
||||
|
||||
#### 镜像一个 ZFS 池
|
||||
|
||||
为确保数据的安全性,你可以创建镜像。镜像意味着每个磁盘包含同样的数据。使用镜像设置,你可能会丢失三个磁盘中的两个,并且仍然拥有所有信息。
|
||||
|
||||
要创建镜像你可以用下面命令:
|
||||
|
||||
```
|
||||
sudo zpool create pool-test mirror /dev/sdb /dev/sdc /dev/sdd
|
||||
```
|
||||
|
||||
#### 创建 ZFS 用于备份恢复的快照
|
||||
|
||||
快照允许你创建一个后备,以防某个文件被删除或被覆盖。比如,我们创建一个快照,当在用户主目录下删除一些目录后,然后把它恢复。
|
||||
|
||||
首先,你需要找到你想要的快照数据集。你可以这样做:
|
||||
|
||||
```
|
||||
zfs list
|
||||
```
|
||||
|
||||
![Zfs List][7]
|
||||
|
||||
你可以看到我的家目录位于 `rpool/USERDATA/johnblood_uwcjk7`。
|
||||
|
||||
我们用下面命令创建一个名叫 `1910` 的快照:
|
||||
|
||||
```
|
||||
sudo zfs snapshot rpool/USERDATA/johnblood_uwcjk7@1019
|
||||
```
|
||||
|
||||
快照很快创建完成。现在你可以删除 `Downloads` 和 `Documents` 目录。
|
||||
|
||||
现在你用以下命令恢复快照:
|
||||
|
||||
```
|
||||
sudo zfs rollback rpool/USERDATA/johnblood_uwcjk7@1019
|
||||
```
|
||||
|
||||
回滚的时间长短取决于有多少信息改变。现在你可以查看家目录,被删除的目录(和它的内容)将会被恢复过来。
|
||||
|
||||
### 要不要试试 ZFS ?
|
||||
|
||||
这篇文章仅简单介绍的 Ubuntu下 ZFS 的用法。更多的信息请参考 [Ubuntu 的 ZFS Wiki页面][5]。我也推荐阅读 [ArsTechnica 的精彩文章][8]。
|
||||
|
||||
这个是试验性的功能。如果你还不了解 ZFS,你想用一个简单稳定的系统,请安装标准文件系统 EXT4。如果你想用闲置的机器体验,可以参照上面了解 ZFS。如果你是一个“专家”,并且知道自己在做什么,则可以随时随地随意尝试ZFS。
|
||||
|
||||
你之前用过 ZFS 吗?请在下面留言。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://itsfoss.com/zfs-ubuntu/
|
||||
|
||||
作者:[John Paul][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[guevaraya](https://github.com/guevaraya)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://itsfoss.com/author/john/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://itsfoss.com/ubuntu-19-04-release-features/
|
||||
[2]: https://itsfoss.com/what-is-zfs/
|
||||
[3]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2019/05/zfs-ubuntu-19-10.jpg?ssl=1
|
||||
[4]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2019/11/Using_ZFS_Ubuntu.jpg?resize=800%2C450&ssl=1
|
||||
[5]: https://wiki.ubuntu.com/Kernel/Reference/ZFS
|
||||
[6]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2019/10/zpool-status.png?ssl=1
|
||||
[7]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2019/10/zfs-list.png?ssl=1
|
||||
[8]: https://arstechnica.com/information-technology/2019/10/a-detailed-look-at-ubuntus-new-experimental-zfs-installer/
|
||||
[9]: https://reddit.com/r/linuxusersgroup
|
||||
know in the comments below. If you found this article interesting, please take a minute to share it on social media, Hacker News or [Reddit][9].
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://itsfoss.com/zfs-ubuntu/
|
||||
|
||||
作者:[John Paul][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://itsfoss.com/author/john/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://itsfoss.com/ubuntu-19-04-release-features/
|
||||
[2]: https://linux.cn/article-10034-1.html
|
||||
[3]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2019/05/zfs-ubuntu-19-10.jpg?ssl=1
|
||||
[4]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2019/11/Using_ZFS_Ubuntu.jpg?resize=800%2C450&ssl=1
|
||||
[5]: https://wiki.ubuntu.com/Kernel/Reference/ZFS
|
||||
[6]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2019/10/zpool-status.png?ssl=1
|
||||
[7]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2019/10/zfs-list.png?ssl=1
|
||||
[8]: https://arstechnica.com/information-technology/2019/10/a-detailed-look-at-ubuntus-new-experimental-zfs-installer/
|
||||
[9]: https://reddit.com/r/linuxusersgroup
|
@ -0,0 +1,345 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11597-1.html)
|
||||
[#]: subject: (How to install and Configure Postfix Mail Server on CentOS 8)
|
||||
[#]: via: (https://www.linuxtechi.com/install-configure-postfix-mailserver-centos-8/)
|
||||
[#]: author: (James Kiarie https://www.linuxtechi.com/author/james/)
|
||||
|
||||
如何在 CentOS 8 上安装和配置 Postfix 邮件服务器
|
||||
======
|
||||
|
||||
Postfix 是一个自由开源的 MTA(邮件传输代理),用于在 Linux 系统上路由或传递电子邮件。在本指南中,你将学习如何在 CentOS 8 上安装和配置 Postfix。
|
||||
|
||||
![Install-configure-Postfx-Server-CentOS8][2]
|
||||
|
||||
实验室设置:
|
||||
|
||||
* 系统:CentOS 8 服务器
|
||||
* IP 地址:192.168.1.13
|
||||
* 主机名:server1.crazytechgeek.info(确保域名指向服务器的 IP)
|
||||
|
||||
### 步骤 1)更新系统
|
||||
|
||||
第一步是确保系统软件包是最新的。为此,请按如下所示更新系统:
|
||||
|
||||
```
|
||||
# dnf update
|
||||
```
|
||||
|
||||
继续之前,还请确保不存在其他 MTA(如 Sendmail),因为这将导致与 Postfix 配置冲突。例如,要删除 Sendmail,请运行以下命令:
|
||||
|
||||
```
|
||||
# dnf remove sendmail
|
||||
```
|
||||
|
||||
### 步骤 2)设置主机名并更新 /etc/hosts
|
||||
|
||||
使用下面的 `hostnamectl` 命令在系统上设置主机名:
|
||||
|
||||
```
|
||||
# hostnamectl set-hostname server1.crazytechgeek.info
|
||||
# exec bash
|
||||
```
|
||||
|
||||
此外,你需要在 `/etc/hosts` 中添加系统的主机名和 IP:
|
||||
|
||||
```
|
||||
# vim /etc/hosts
|
||||
192.168.1.13 server1.crazytechgeek.info
|
||||
```
|
||||
|
||||
保存并退出文件。
|
||||
|
||||
### 步骤 3)安装 Postfix 邮件服务器
|
||||
|
||||
验证系统上没有其他 MTA 在运行后,运行以下命令安装 Postfix:
|
||||
|
||||
```
|
||||
# dnf install postfix
|
||||
```
|
||||
|
||||
![Install-Postfix-Centos8][3]
|
||||
|
||||
### 步骤 4)启动并启用 Postfix 服务
|
||||
|
||||
成功安装 Postfix 后,运行以下命令启动并启用 Postfix 服务:
|
||||
|
||||
```
|
||||
# systemctl start postfix
|
||||
# systemctl enable postfix
|
||||
```
|
||||
|
||||
要检查 Postfix 状态,请运行以下 `systemctl` 命令:
|
||||
|
||||
```
|
||||
# systemctl status postfix
|
||||
```
|
||||
|
||||
![Start-Postfix-check-status-centos8][9]
|
||||
|
||||
太好了,我们已经验证了 Postfix 已启动并正在运行。接下来,我们将配置 Postfix 从本地发送邮件到我们的服务器。
|
||||
|
||||
### 步骤 5)安装 mailx 邮件客户端
|
||||
|
||||
在配置 Postfix 服务器之前,我们需要安装 `mailx`,要安装它,请运行以下命令:
|
||||
|
||||
```
|
||||
# dnf install mailx
|
||||
```
|
||||
|
||||
![Install-Mailx-CentOS8][10]
|
||||
|
||||
### 步骤 6)配置 Postfix 邮件服务器
|
||||
|
||||
Postfix 的配置文件位于 `/etc/postfix/main.cf` 中。我们需要对配置文件进行一些修改,因此请使用你喜欢的文本编辑器将其打开:
|
||||
|
||||
```
|
||||
# vi /etc/postfix/main.cf
|
||||
```
|
||||
|
||||
更改以下几行:
|
||||
|
||||
```
|
||||
myhostname = server1.crazytechgeek.info
|
||||
mydomain = crazytechgeek.info
|
||||
myorigin = $mydomain
|
||||
## 取消注释并将 inet_interfaces 设置为 all##
|
||||
inet_interfaces = all
|
||||
## 更改为 all ##
|
||||
inet_protocols = all
|
||||
## 注释 ##
|
||||
#mydestination = $myhostname, localhost.$mydomain, localhost
|
||||
## 取消注释 ##
|
||||
mydestination = $myhostname, localhost.$mydomain, localhost, $mydomain
|
||||
## 取消注释并添加 IP 范围 ##
|
||||
mynetworks = 192.168.1.0/24, 127.0.0.0/8
|
||||
## 取消注释 ##
|
||||
home_mailbox = Maildir/
|
||||
```
|
||||
|
||||
完成后,保存并退出配置文件。重新启动 postfix 服务以使更改生效:
|
||||
|
||||
```
|
||||
# systemctl restart postfix
|
||||
```
|
||||
|
||||
### 步骤 7)测试 Postfix 邮件服务器
|
||||
|
||||
测试我们的配置是否有效,首先,创建一个测试用户。
|
||||
|
||||
```
|
||||
# useradd postfixuser
|
||||
# passwd postfixuser
|
||||
```
|
||||
|
||||
接下来,运行以下命令,从本地用户 `pkumar` 发送邮件到另一个用户 `postfixuser`。
|
||||
|
||||
```
|
||||
# telnet localhost smtp
|
||||
或者
|
||||
# telnet localhost 25
|
||||
```
|
||||
|
||||
如果未安装 telnet 服务,那么可以使用以下命令进行安装:
|
||||
|
||||
```
|
||||
# dnf install telnet -y
|
||||
```
|
||||
|
||||
如前所述运行命令时,应获得如下输出:
|
||||
|
||||
```
|
||||
[root@linuxtechi ~]# telnet localhost 25
|
||||
Trying 127.0.0.1...
|
||||
Connected to localhost.
|
||||
Escape character is '^]'.
|
||||
220 server1.crazytechgeek.info ESMTP Postfix
|
||||
```
|
||||
|
||||
上面的结果确认与 postfix 邮件服务器的连接正常。接下来,输入命令:
|
||||
|
||||
```
|
||||
# ehlo localhost
|
||||
```
|
||||
|
||||
输出看上去像这样:
|
||||
|
||||
```
|
||||
250-server1.crazytechgeek.info
|
||||
250-PIPELINING
|
||||
250-SIZE 10240000
|
||||
250-VRFY
|
||||
250-ETRN
|
||||
250-STARTTLS
|
||||
250-ENHANCEDSTATUSCODES
|
||||
250-8BITMIME
|
||||
250-DSN
|
||||
250 SMTPUTF8
|
||||
```
|
||||
|
||||
接下来,运行橙色高亮的命令,例如 `mail from`、`rcpt to`、`data`,最后输入 `quit`:
|
||||
|
||||
```
|
||||
mail from:<pkumar>
|
||||
250 2.1.0 Ok
|
||||
rcpt to:<postfixuser>
|
||||
250 2.1.5 Ok
|
||||
data
|
||||
354 End data with <CR><LF>.<CR><LF>
|
||||
Hello, Welcome to my mailserver (Postfix)
|
||||
.
|
||||
250 2.0.0 Ok: queued as B56BF1189BEC
|
||||
quit
|
||||
221 2.0.0 Bye
|
||||
Connection closed by foreign host
|
||||
```
|
||||
|
||||
完成 `telnet` 命令可从本地用户 `pkumar` 发送邮件到另一个本地用户 `postfixuser`,如下所示:
|
||||
|
||||
![Send-email-with-telnet-centos8][11]
|
||||
|
||||
如果一切都按计划进行,那么你应该可以在新用户的家目录中查看发送的邮件:
|
||||
|
||||
```
|
||||
# ls /home/postfixuser/Maildir/new
|
||||
1573580091.Vfd02I20050b8M635437.server1.crazytechgeek.info
|
||||
#
|
||||
```
|
||||
|
||||
要阅读邮件,只需使用 cat 命令,如下所示:
|
||||
|
||||
```
|
||||
# cat /home/postfixuser/Maildir/new/1573580091.Vfd02I20050b8M635437.server1.crazytechgeek.info
|
||||
```
|
||||
|
||||
![Read-postfix-email-linux][12]
|
||||
|
||||
### Postfix 邮件服务器日志
|
||||
|
||||
Postfix 邮件服务器邮件日志保存在文件 `/var/log/maillog` 中,使用以下命令查看实时日志,
|
||||
|
||||
```
|
||||
# tail -f /var/log/maillog
|
||||
```
|
||||
|
||||
![postfix-maillogs-centos8][13]
|
||||
|
||||
### 保护 Postfix 邮件服务器
|
||||
|
||||
建议始终确保客户端和 Postfix 服务器之间的通信安全,这可以使用 SSL 证书来实现,它们可以来自受信任的权威机构或自签名证书。在本教程中,我们将使用 `openssl` 命令生成用于 Postfix 的自签名证书,
|
||||
|
||||
我假设 `openssl` 已经安装在你的系统上,如果未安装,请使用以下 `dnf` 命令:
|
||||
|
||||
```
|
||||
# dnf install openssl -y
|
||||
```
|
||||
|
||||
使用下面的 `openssl` 命令生成私钥和 CSR(证书签名请求):
|
||||
|
||||
```
|
||||
# openssl req -nodes -newkey rsa:2048 -keyout mail.key -out mail.csr
|
||||
```
|
||||
|
||||
![Postfix-Key-CSR-CentOS8][14]
|
||||
|
||||
现在,使用以下 openssl 命令生成自签名证书:
|
||||
|
||||
```
|
||||
# openssl x509 -req -days 365 -in mail.csr -signkey mail.key -out mail.crt
|
||||
Signature ok
|
||||
subject=C = IN, ST = New Delhi, L = New Delhi, O = IT, OU = IT, CN = server1.crazytechgeek.info, emailAddress = root@linuxtechi
|
||||
Getting Private key
|
||||
#
|
||||
```
|
||||
|
||||
现在将私钥和证书文件复制到 `/etc/postfix` 目录下:
|
||||
|
||||
```
|
||||
# cp mail.key mail.crt /etc/postfix
|
||||
```
|
||||
|
||||
在 Postfix 配置文件中更新私钥和证书文件的路径:
|
||||
|
||||
```
|
||||
# vi /etc/postfix/main.cf
|
||||
………
|
||||
smtpd_use_tls = yes
|
||||
smtpd_tls_cert_file = /etc/postfix/mail.crt
|
||||
smtpd_tls_key_file = /etc/postfix/mail.key
|
||||
smtpd_tls_security_level = may
|
||||
………
|
||||
```
|
||||
|
||||
重启 Postfix 服务以使上述更改生效:
|
||||
|
||||
```
|
||||
# systemctl restart postfix
|
||||
```
|
||||
|
||||
让我们尝试使用 `mailx` 客户端将邮件发送到内部本地域和外部域。
|
||||
|
||||
从 `pkumar` 发送内部本地邮件到 `postfixuser` 中:
|
||||
|
||||
```
|
||||
# echo "test email" | mailx -s "Test email from Postfix MailServer" -r root@linuxtechi root@linuxtechi
|
||||
```
|
||||
|
||||
使用以下命令检查并阅读邮件:
|
||||
|
||||
```
|
||||
# cd /home/postfixuser/Maildir/new/
|
||||
# ll
|
||||
total 8
|
||||
-rw-------. 1 postfixuser postfixuser 476 Nov 12 17:34 1573580091.Vfd02I20050b8M635437.server1.crazytechgeek.info
|
||||
-rw-------. 1 postfixuser postfixuser 612 Nov 13 02:40 1573612845.Vfd02I20050bbM466643.server1.crazytechgeek.info
|
||||
# cat 1573612845.Vfd02I20050bbM466643.server1.crazytechgeek.info
|
||||
```
|
||||
|
||||
![Read-Postfixuser-Email-CentOS8][15]
|
||||
|
||||
从 `postfixuser` 发送邮件到外部域(`root@linuxtechi.com`):
|
||||
|
||||
```
|
||||
# echo "External Test email" | mailx -s "Postfix MailServer" -r root@linuxtechi root@linuxtechi
|
||||
```
|
||||
|
||||
注意:如果你的 IP 没有被任何地方列入黑名单,那么你发送到外部域的邮件将被发送,否则它将被退回,并提示你的 IP 被 spamhaus 之类的数据库列入黑名单。
|
||||
|
||||
### 检查 Postfix 邮件队列
|
||||
|
||||
使用 `mailq` 命令列出队列中的邮件:
|
||||
|
||||
```
|
||||
# mailq
|
||||
Mail queue is empty
|
||||
#
|
||||
```
|
||||
|
||||
完成!我们的 Postfix 配置正常工作了!目前就这样了。我们希望你觉得本教程有见地,并且你可以轻松地设置本地 Postfix 服务器。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.linuxtechi.com/install-configure-postfix-mailserver-centos-8/
|
||||
|
||||
作者:[James Kiarie][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://www.linuxtechi.com/author/james/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7
|
||||
[2]: https://www.linuxtechi.com/wp-content/uploads/2019/11/Install-configure-Postfx-Server-CentOS8.jpg
|
||||
[3]: https://www.linuxtechi.com/wp-content/uploads/2019/11/Install-Postfix-Centos8.png
|
||||
[4]: https://www.linuxtechi.com/cdn-cgi/l/email-protection
|
||||
[9]: https://www.linuxtechi.com/wp-content/uploads/2019/11/Start-Postfix-check-status-centos8.png
|
||||
[10]: https://www.linuxtechi.com/wp-content/uploads/2019/11/Install-Mailx-CentOS8.png
|
||||
[11]: https://www.linuxtechi.com/wp-content/uploads/2019/11/Send-email-with-telnet-centos8.png
|
||||
[12]: https://www.linuxtechi.com/wp-content/uploads/2019/11/Read-postfix-email-linux.png
|
||||
[13]: https://www.linuxtechi.com/wp-content/uploads/2019/11/postfix-maillogs-centos8.png
|
||||
[14]: https://www.linuxtechi.com/wp-content/uploads/2019/11/Postfix-Key-CSR-CentOS8.png
|
||||
[15]: https://www.linuxtechi.com/wp-content/uploads/2019/11/Read-Postfixuser-Email-CentOS8.png
|
87
published/201911/20191114 Cleaning up with apt-get.md
Normal file
87
published/201911/20191114 Cleaning up with apt-get.md
Normal file
@ -0,0 +1,87 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11601-1.html)
|
||||
[#]: subject: (Cleaning up with apt-get)
|
||||
[#]: via: (https://www.networkworld.com/article/3453032/cleaning-up-with-apt-get.html)
|
||||
[#]: author: (Sandra Henry-Stocker https://www.networkworld.com/author/Sandra-Henry_Stocker/)
|
||||
|
||||
使用 apt-get 清理
|
||||
======
|
||||
|
||||
> 大多数使用基于 Debian 的系统的人通常会使用 apt-get 来安装软件包和升级,但是我们多久才清理一次?让我们看下该工具本身的一些清理选项。
|
||||
|
||||

|
||||
|
||||
在基于 Debian 的系统上运行 `apt-get` 命令是很常规的。软件包的更新相当频繁,诸如 `apt-get update` 和 `apt-get upgrade` 之类的命令使此过程非常容易。另一方面,你多久使用一次 `apt-get clean`、`apt-get autoclean` 或 `apt-get autoremove`?
|
||||
|
||||
这些命令会在 `apt-get` 的安装操作后清理并删除仍在系统上但不再需要的文件,这通常是因为需要它们的程序已经卸载。
|
||||
|
||||
### apt-get clean
|
||||
|
||||
`apt-get clean` 命令清除遗留在 `/var/cache` 中的已取回的包文件的本地仓库。它清除的目录是 `/var/cache/apt/archives/` 和 `/var/cache/apt/archives/partial/`。它留在 `/var/cache/apt/archives` 中的唯一文件是 `lock` 文件和 `partial` 子目录。
|
||||
|
||||
在运行清理操作之前,目录中可能包含许多文件:
|
||||
|
||||
```
|
||||
/var/cache/apt/archives/db5.3-util_5.3.28+dfsg1-0.6ubuntu1_amd64.deb
|
||||
/var/cache/apt/archives/db-util_1%3a5.3.21~exp1ubuntu2_all.deb
|
||||
/var/cache/apt/archives/lock
|
||||
/var/cache/apt/archives/postfix_3.4.5-1ubuntu1_amd64.deb
|
||||
/var/cache/apt/archives/sasl2-bin_2.1.27+dfsg-1build3_amd64.deb
|
||||
```
|
||||
|
||||
之后,只会存在这些:
|
||||
|
||||
```
|
||||
$ sudo ls -lR /var/cache/apt/archives
|
||||
/var/cache/apt/archives:
|
||||
total 4
|
||||
-rw-r----- 1 root root 0 Jan 5 2018 lock
|
||||
drwx------ 2 _apt root 4096 Nov 12 07:24 partial
|
||||
|
||||
/var/cache/apt/archives/partial:
|
||||
total 0 <== 空
|
||||
```
|
||||
|
||||
`apt-get clean` 命令通常用于根据需要清除磁盘空间,一般作为定期计划维护的一部分。
|
||||
|
||||
### apt-get autoclean
|
||||
|
||||
`apt-get autoclean` 类似于 `apt-get clean`,它会清除已检索包文件的本地仓库,但它只会删除不会再下载且几乎无用的文件。它有助于防止缓存过大。
|
||||
|
||||
### apt-get autoremove
|
||||
|
||||
`apt-get autoremove` 将删除自动安装的软件包,因为某些其他软件包需要它们,但是在删除了其他软件包之后,而不再需要它们。有时会在升级时建议运行此命令。
|
||||
|
||||
```
|
||||
The following packages were automatically installed and are no longer required:
|
||||
g++-8 gir1.2-mutter-4 libapache2-mod-php7.2 libcrystalhd3
|
||||
libdouble-conversion1 libgnome-desktop-3-17 libigdgmm5 libisl19 libllvm8
|
||||
liblouisutdml8 libmutter-4-0 libmysqlclient20 libpoppler85 libstdc++-8-dev
|
||||
libtagc0 libvpx5 libx265-165 php7.2 php7.2-cli php7.2-common php7.2-json
|
||||
php7.2-opcache php7.2-readline
|
||||
Use 'sudo apt autoremove' to remove them. <==
|
||||
```
|
||||
|
||||
要删除的软件包通常称为“未使用的依赖项”。实际上,一个好的做法是在卸载软件包后使用 `autoremove`,以确保不会留下不需要的文件。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.networkworld.com/article/3453032/cleaning-up-with-apt-get.html
|
||||
|
||||
作者:[Sandra Henry-Stocker][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://www.networkworld.com/author/Sandra-Henry_Stocker/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://unsplash.com/photos/nbKaLT4cmRM
|
||||
[2]: https://creativecommons.org/publicdomain/zero/1.0/
|
||||
[3]: https://www.networkworld.com/newsletters/signup.html
|
||||
[5]: https://www.facebook.com/NetworkWorld/
|
||||
[6]: https://www.linkedin.com/company/network-world
|
@ -0,0 +1,66 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (wxy)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11576-1.html)
|
||||
[#]: subject: (Microsoft Defender ATP is Coming to Linux! What Does it Mean?)
|
||||
[#]: via: (https://itsfoss.com/microsoft-defender-atp-linux/)
|
||||
[#]: author: (Abhishek Prakash https://itsfoss.com/author/abhishek/)
|
||||
|
||||
微软 Defender ATP 要出 Linux 版了!
|
||||
======
|
||||
|
||||
> 微软宣布将于 2020 年将其企业安全产品 Defender 高级威胁防护(ATP)引入 Linux。
|
||||
|
||||

|
||||
|
||||
微软的年度开发者大会 Microsoft Ignite 刚刚结束,会上发布了一些与 Linux 有关的重要公告。你可能已经知道[微软将 Edge Web 浏览器引入 Linux][1],而下一个大新闻是微软将 Defender ATP 引入 Linux!
|
||||
|
||||
让我们详细介绍一下它是什么,以及微软为何不厌其烦为 Linux 开发某些东西。
|
||||
|
||||
### 微软 Defender ATP 是什么?
|
||||
|
||||
如果你过去几年使用过 Windows,那么你一定遇到过 Windows Defender。它基本上可以说是微软的防病毒产品,通过检测病毒和恶意软件来提供一定程度的安全性。
|
||||
|
||||
微软通过引入 Windows Defender ATP(高级威胁防护)来为其企业用户改进了此功能。Defender ATP 致力于行为分析。它收集使用使用数据并将其存储在同一系统上。但是,当发现行为不一致时,它将数据发送到 Azure 服务(微软的云服务)。在这里,它将收集行为数据和异常信息。
|
||||
|
||||
例如,如果你收到一封包含 PDF 附件的电子邮件,你将其打开并打开了命令提示符,Defender ATP 就会注意到此异常行为。我建议[阅读本文以了解有关 Defender 和 Defender ATP 之间的区别的更多信息] [2]。
|
||||
|
||||
现在,这完全是一种企业级产品。在具有成百上千个端点(计算机)的大型企业中,Defender ATP 提供了很好的保护层。IT 管理员可以在其 Azure 实例上集中查看端点的视图,可以分析威胁并采取相应措施。
|
||||
|
||||
### 适用于 Linux(和 Mac)的微软 Defender ATP
|
||||
|
||||
通常,企业的计算机上装有 Windows,但 Mac 和 Linux 在开发人员中也特别受欢迎。在混合了 Mac 和 Linux 的 Windows 机器环境中,Defender ATP 必须将其服务扩展到这些操作系统,以便它可以为网络上的所有设备提供整体防御。
|
||||
|
||||
请注意,微软先是[在 2019 年 3 月将 Windows Defender ATP 更改为微软 Defender ATP][3],这表明该产品不仅限于 Windows 操作系统。
|
||||
|
||||
此后不久微软[宣布推出 Mac 版 Defender ATP][4]。
|
||||
|
||||
现在,为了涵盖企业环境中的所有主要操作系统,[微软将于 2020 年将 Defender ATP 引入到 Linux][5]。
|
||||
|
||||
### Linux 上的微软 Defender ATP 对 Linux 用户有何影响?
|
||||
|
||||
由于 Defender ATP 是企业产品,因此我认为你无需为此而烦恼。组织需要保护其端点免受威胁,因此,微软也在改进其产品以使其涵盖 Linux。
|
||||
|
||||
对于像你我这样的普通 Linux 用户,这没有任何区别。我不会用它“保护”我的三个 Linux 系统,并为此而向微软付费。
|
||||
|
||||
请随时在评论部分中分享你对微软将 Defender ATP 引入 Linux 的看法。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://itsfoss.com/microsoft-defender-atp-linux/
|
||||
|
||||
作者:[Abhishek Prakash][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[wxy](https://github.com/wxy)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://itsfoss.com/author/abhishek/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://itsfoss.com/microsoft-edge-linux/
|
||||
[2]: https://www.concurrency.com/blog/november-2017/windows-defender-vs-windows-defender-atp
|
||||
[3]: https://www.theregister.co.uk/2019/03/21/microsoft_defender_atp/
|
||||
[4]: https://techcommunity.microsoft.com/t5/Microsoft-Defender-ATP/Announcing-Microsoft-Defender-ATP-for-Mac/ba-p/378010
|
||||
[5]: https://www.zdnet.com/article/microsoft-defender-atp-is-coming-to-linux-in-2020/
|
@ -0,0 +1,82 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (wxy)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11583-1.html)
|
||||
[#]: subject: (Red Hat Responds to Zombieload v2)
|
||||
[#]: via: (https://www.networkworld.com/article/3453596/red-hat-responds-to-zombieload-v2.html)
|
||||
[#]: author: (Sandra Henry-Stocker https://www.networkworld.com/author/Sandra-Henry_Stocker/)
|
||||
|
||||
红帽对 Zombieload v2 缺陷的应对
|
||||
======
|
||||

|
||||
|
||||
> 红帽呼吁更新 Linux 软件,以解决可能导致数据盗用的英特尔处理器缺陷。
|
||||
|
||||
前两天公开的三个“常见漏洞和披露”(CVE)跟踪的是某些英特尔处理器中的三个漏洞,如果利用这些漏洞,可能会使敏感数据面临风险。
|
||||
|
||||
在报告的缺陷中,新发现的英特尔处理器缺陷是今年早些时候发现的 Zombieload 攻击的变种,并且仅会影响英特尔的 Cascade Lake 芯片。
|
||||
|
||||
红帽强烈建议,所有的红帽系统即使不认为其配置构成直接威胁,也要对其进行更新,并且红帽正在向其客户和企业 IT 社区提供资源。
|
||||
|
||||
这三个 CVE 是:
|
||||
|
||||
* CVE-2018-12207:页面大小更改时的机器检查错误
|
||||
* CVE-2019-11135:TSX异步中止
|
||||
* CVE-2019-0155 和 CVE-2019-0154:i915 图形驱动程序
|
||||
|
||||
### CVE-2018-12207
|
||||
|
||||
红帽将该漏洞评为重要。此漏洞可能使本地和非特权的攻击者绕过安全控制并导致系统范围的拒绝服务。
|
||||
|
||||
硬件缺陷是在英特尔微处理器中发现的,并且与指令翻译后备缓冲区(ITLB)有关。它缓存从虚拟地址到物理地址的转换,旨在提高性能。但是,在缓存页面更改后,使缓存的条目无效的延迟可能导致处理器使用无效的地址转换,从而导致机器检查错误异常并使系统进入挂起状态。
|
||||
|
||||
攻击者可以制作这种情况来关闭系统。
|
||||
|
||||
### CVE-2019-11135
|
||||
|
||||
红帽将此漏洞评为中级。这个事务同步扩展(TSX)异步中止是一个微体系结构数据采样(MDS)缺陷。使用定制代码的本地攻击者可以利用此漏洞从处理器以及支持同时多线程(SMT)和 TSX 的处理器上的缓存内容中收集信息。
|
||||
|
||||
### CVE-2019-0155,CVE-2019-0154
|
||||
|
||||
红帽将 CVE-2019-0155 漏洞评为重要,将 CVE-2019-0154 漏洞评为中级。这两个缺陷都与 i915 图形驱动程序有关。
|
||||
|
||||
CVE-2019-0155 允许攻击者绕过常规的内存安全限制,从而允许对应该受到限制的特权内存进行写访问。
|
||||
|
||||
当图形处理单元(GPU)处于低功耗模式时,CVE-2019-0154 可能允许本地攻击者创建无效的系统状态,从而导致系统无法访问。
|
||||
|
||||
唯一受 CVE-2019-0154 影响的的显卡在 i915 内核模块上受到影响。`lsmod` 命令可用于指示该漏洞。 如下所示的任何输出(即以 i915 开头)都表明该系统易受攻击:
|
||||
|
||||
```
|
||||
$ lsmod | grep ^i915
|
||||
i915 2248704 10
|
||||
```
|
||||
|
||||
### 更多资源
|
||||
|
||||
红帽在以下链接中向其客户和其他人提供了详细信息和进一步的说明:
|
||||
|
||||
- <https://access.redhat.com/security/vulnerabilities/ifu-page-mce>
|
||||
- <https://access.redhat.com/solutions/tsx-asynchronousabort>
|
||||
- <https://access.redhat.com/solutions/i915-graphics>
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.networkworld.com/article/3453596/red-hat-responds-to-zombieload-v2.html
|
||||
|
||||
作者:[Sandra Henry-Stocker][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[wxy](https://github.com/wxy)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://www.networkworld.com/author/Sandra-Henry_Stocker/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://www.networkworld.com/newsletters/signup.html
|
||||
[2]: 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)
|
||||
[3]: https://access.redhat.com/solutions/tsx-asynchronousabort%20
|
||||
[4]: https://access.redhat.com/solutions/i915-graphics
|
||||
[5]: https://www.facebook.com/NetworkWorld/
|
||||
[6]: https://www.linkedin.com/company/network-world
|
@ -0,0 +1,150 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11604-1.html)
|
||||
[#]: subject: (Developing a Simple Web Application Using Flutter)
|
||||
[#]: via: (https://opensourceforu.com/2019/11/developing-a-simple-web-application-using/)
|
||||
[#]: author: (Jis Joe Mathew https://opensourceforu.com/author/jis-joe/)
|
||||
|
||||
使用 Flutter 开发简单的 Web 应用
|
||||
======
|
||||
|
||||
![][2]
|
||||
|
||||
> 本文指导读者如何使用 Flutter 运行和部署第一个 Web 应用。
|
||||
|
||||
Flutter 在 Android 和 iOS 开发方面走了很长一段路之后,已经迈入了一个新的阶段,即 Web 开发。Google 发布了 Flutter 1.5,同时支持 Web 应用开发。
|
||||
|
||||
### 为 Web 开发配置 Flutter
|
||||
|
||||
为了使用 Web 包,输入命令 `flutter upgrade` 更新到 Flutter 1.5.4。
|
||||
|
||||
* 打开终端
|
||||
* 输入 `flutter upgrade`
|
||||
* 输入 `flutter –version` 检查版本
|
||||
|
||||
|
||||
![图 1: 升级 Flutter 到最新版][3]
|
||||
|
||||
也可以将 Android Studio 3.0 或更高版本用于 Flutter Web 开发,但在本教程中,我们使用 Visual Studio Code。
|
||||
|
||||
### 使用 Flutter Web 创建新项目
|
||||
|
||||
打开 Visual Studio Code,然后按 `Shift+Ctrl+P` 开始一个新项目。输入 `flutter` 并选择 “New Web Project”。
|
||||
|
||||
![图 2:在 VSC 中开始一个新的 Flatter 项目][4]
|
||||
|
||||
现在,为项目命名。我将其命名为 `open_source_for_you`。
|
||||
|
||||
![图 3: 给项目命名][5]
|
||||
|
||||
在 VSC 中打开终端窗口,然后输入以下命令:
|
||||
|
||||
```
|
||||
flutter packages pub global activate webdev
|
||||
flutter packages upgrade
|
||||
```
|
||||
|
||||
现在,使用以下命令在 localhost 上运行网站,IP 地址是 127.0.0.1。
|
||||
|
||||
```
|
||||
flutter packages pub global run webdev serve
|
||||
```
|
||||
|
||||
打开任何浏览器,然后输入 `http://127.0.0.1:8080/`。
|
||||
|
||||
|
||||
![图 4:运行于 8080 端口的 Flutter 演示应用][6]
|
||||
|
||||
在项目目录中有个 Web 文件夹,其中包含了 `index.html`。`dart` 文件被编译成 JavaScript 文件,并使用以下代码包含在 HTML 文件中:
|
||||
|
||||
```
|
||||
<script defer src="main.dart.js" type="application/javascript"></script>
|
||||
```
|
||||
|
||||
### 编码和修改演示页面
|
||||
|
||||
让我们创建一个简单的应用,它会在网页上打印 “Welcome to OSFY”。
|
||||
|
||||
现在打开 Dart 文件,它位于 `lib` 文件夹 `main.dart`(默认名)中(参见图 5)。
|
||||
|
||||
![图 5:main.dart 文件的位置][7]
|
||||
|
||||
现在,我们可以在 `MaterialApp` 的属性中删除调试标记,如下所示:
|
||||
|
||||
```
|
||||
debugShowCheckedModeBanner: false
|
||||
```
|
||||
|
||||
现在,向 Dart 中添加更多内容与用 Dart 编写 Flutter 很类似。为此,我们可以声明一个名为 `MyClass` 的类,它继承了 `StatelessWidget`。
|
||||
|
||||
我们使用 `Center` 部件将元素定位到中心。我们还可以添加 `Padding` 部件来添加填充。使用以下代码获得图 5 所示的输出。使用刷新按钮查看更改。
|
||||
|
||||
```
|
||||
class MyClass extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
body: Center(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
Padding(
|
||||
padding: EdgeInsets.all(20.0),
|
||||
child: Text(
|
||||
'Welcome to OSFY',
|
||||
style: TextStyle(fontSize: 24.0, fontWeight: FontWeight.bold),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
![图 6:MyClass 的输出][8]
|
||||
|
||||
让我们从互联网中添加一张图片,我已经从一个杂志网站选择了一张 “Open Source for You” 徽标。我们使用 `Image.network`。
|
||||
|
||||
```
|
||||
Image.network(
|
||||
'https://opensourceforu.com/wp-content/uploads/2014/03/OSFY-Logo.jpg',
|
||||
height: 100,
|
||||
width: 150
|
||||
),
|
||||
```
|
||||
|
||||
最终输出如图 7 所示。
|
||||
|
||||
![图 7:最终输出][9]
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensourceforu.com/2019/11/developing-a-simple-web-application-using/
|
||||
|
||||
作者:[Jis Joe Mathew][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensourceforu.com/author/jis-joe/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://i1.wp.com/opensourceforu.com/wp-content/uploads/2019/11/Screenshot-from-2019-11-15-16-20-30.png
|
||||
[2]: https://i1.wp.com/opensourceforu.com/wp-content/uploads/2019/11/Screenshot-from-2019-11-15-16-20-30.png
|
||||
[3]: https://i0.wp.com/opensourceforu.com/wp-content/uploads/2019/11/Figure-1-Upgrading-Flutter-to-the-latest-version.jpg
|
||||
[4]: https://i0.wp.com/opensourceforu.com/wp-content/uploads/2019/11/Figure-2-Starting-a-new-Flutter-Web-project-in-VSC.jpg
|
||||
[5]: https://i2.wp.com/opensourceforu.com/wp-content/uploads/2019/11/Figure-3-Naming-the-project.jpg
|
||||
[6]: https://i0.wp.com/opensourceforu.com/wp-content/uploads/2019/11/Figure-4-The-Flutter-demo-application-running-on-port-8080.jpg
|
||||
[7]: https://i2.wp.com/opensourceforu.com/wp-content/uploads/2019/11/Figure-5-Location-of-main.dart-file.jpg
|
||||
[8]: https://i2.wp.com/opensourceforu.com/wp-content/uploads/2019/11/Figure-6-Output-of-MyClass.jpg
|
||||
[9]: https://i0.wp.com/opensourceforu.com/wp-content/uploads/2019/11/Figure-7-Final-output.jpg
|
||||
[10]: https://secure.gravatar.com/avatar/64db0e07799ae14fd1b51d0633db6593?s=100&r=g
|
||||
[11]: https://opensourceforu.com/author/jis-joe/
|
||||
[12]: mailto:jisjoemathew@gmail.com
|
||||
[13]: https://opensourceforu.com/wp-content/uploads/2019/11/assoc.png
|
||||
[14]: https://feedburner.google.com/fb/a/mailverify?uri=LinuxForYou&loc=en_US
|
@ -0,0 +1,151 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11627-1.html)
|
||||
[#]: subject: (How to Install VirtualBox 6.0 on CentOS 8 / RHEL 8)
|
||||
[#]: via: (https://www.linuxtechi.com/install-virtualbox-6-centos-8-rhel-8/)
|
||||
[#]: author: (Pradeep Kumar https://www.linuxtechi.com/author/pradeep/)
|
||||
|
||||
如何在 CentOS 8 / RHEL 8 上安装 VirtualBox 6.0
|
||||
======
|
||||
|
||||

|
||||
|
||||
VirtualBox 是一款自由开源的虚拟化工具,它允许技术人员同时运行多个不同风格的虚拟机(VM)。它通常用于运行桌面(Linux 和 Windows),当人们尝试探索新的 Linux 发行版的功能或希望在 VM 中安装 OpenStack、Ansible 和 Puppet 等软件时,它会非常方便,在这种情况下,我们可以使用 VirtualBox 启动 VM。
|
||||
|
||||
VirtualBox 被分类为 2 类虚拟机管理程序,这意味着它需要一个现有的操作系统,在上面安装 VirtualBox 软件。VirtualBox 提供功能来创建本机网络或 NAT 网络。在本文中,我们将演示如何在 CentOS 8 和 RHEL 8 系统上安装最新版本的 VirtualBox 6.0,并演示如何安装 VirtualBox 扩展。
|
||||
|
||||
### 在 CentOS 8 / RHEL 8 上安装 VirtualBox 6.0 的安装步骤
|
||||
|
||||
#### 步骤 1: 启用 VirtualBox 和 EPEL 仓库
|
||||
|
||||
登录到你的 CentOS 8 或 RHEL 8 系统并打开终端,执行以下命令并启用 VirtualBox 和 EPEL 包仓库:
|
||||
|
||||
```
|
||||
[root@linuxtechi ~]# dnf config-manager --add-repo=https://download.virtualbox.org/virtualbox/rpm/el/virtualbox.repo
|
||||
```
|
||||
|
||||
使用以下 `rpm` 命令导入 Oracle VirtualBox 公钥:
|
||||
|
||||
```
|
||||
[root@linuxtechi ~]# rpm --import https://www.virtualbox.org/download/oracle_vbox.asc
|
||||
```
|
||||
|
||||
使用以下 `dnf` 命令启用 EPEL 仓库:
|
||||
|
||||
```
|
||||
[root@linuxtechi ~]# dnf install https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm -y
|
||||
```
|
||||
|
||||
#### 步骤 2: 安装 VirtualBox 构建工具和依赖项
|
||||
|
||||
运行以下命令来安装所有 VirtualBox 构建工具和依赖项:
|
||||
|
||||
```
|
||||
[root@linuxtechi ~]# dnf install binutils kernel-devel kernel-headers libgomp make patch gcc glibc-headers glibc-devel dkms -y
|
||||
```
|
||||
|
||||
成功安装上面的依赖项和构建工具后,使用 `dnf` 命令继续安装 VirtualBox。
|
||||
|
||||
#### 步骤 3: 在 CentOS 8 / RHEL 8 上安装 VirtualBox 6.0
|
||||
|
||||
如果希望在安装之前列出 VirtualBox 的可用版本,请执行以下 dnf 命令:
|
||||
|
||||
```
|
||||
[root@linuxtechi ~]# dnf search virtualbox
|
||||
Last metadata expiration check: 0:14:36 ago on Sun 17 Nov 2019 04:13:16 AM GMT.
|
||||
=============== Summary & Name Matched: virtualbox =====================
|
||||
VirtualBox-5.2.x86_64 : Oracle VM VirtualBox
|
||||
VirtualBox-6.0.x86_64 : Oracle VM VirtualBox
|
||||
[root@linuxtechi ~]#
|
||||
```
|
||||
|
||||
让我们使用以下 `dnf` 命令安装最新版本的 VirtualBox 6.0:
|
||||
|
||||
```
|
||||
[root@linuxtechi ~]# dnf install VirtualBox-6.0 -y
|
||||
```
|
||||
|
||||
如果有本地用户希望将 usb 设备连接到 VirtualBox VM,那么他/她应该是 `vboxusers` 组的一员,请使用下面的 `usermod` 命令将本地用户添加到 `vboxusers` 组。
|
||||
|
||||
|
||||
```
|
||||
[root@linuxtechi ~]# usermod -aG vboxusers pkumar
|
||||
```
|
||||
|
||||
#### 步骤 4: 访问 CentOS 8 / RHEL 8 上的 VirtualBox
|
||||
|
||||
有两种方法可以访问 VirtualBox,在命令行输入 `virtualbox` 然后回车:
|
||||
|
||||
```
|
||||
[root@linuxtechi ~]# virtualbox
|
||||
```
|
||||
|
||||
在桌面环境中,在搜索框中搜索 “VirtualBox”。
|
||||
|
||||
![Access-VirtualBox-CentOS8][3]
|
||||
|
||||
单击 VirtualBox 图标:
|
||||
|
||||
![VirtualBox-CentOS8][4]
|
||||
|
||||
这确认 VirtualBox 6.0 已成功安装,让我们安装它的扩展包。
|
||||
|
||||
#### 步骤 5: 安装 VirtualBox 6.0 扩展包
|
||||
|
||||
顾名思义,VirtualBox 扩展包用于扩展 VirtualBox 的功能。它添加了以下功能:
|
||||
|
||||
* USB 2.0 和 USB 3.0 支持
|
||||
* 虚拟 RDP(VRDP)
|
||||
* 磁盘镜像加密
|
||||
* Intel PXE 启动
|
||||
* 主机网络摄像头
|
||||
|
||||
使用下面的 `wget` 命令下载 Virtualbox 扩展包到下载文件夹中:
|
||||
|
||||
```
|
||||
[root@linuxtechi ~]$ cd Downloads/
|
||||
[root@linuxtechi Downloads]$ wget https://download.virtualbox.org/virtualbox/6.0.14/Oracle_VM_VirtualBox_Extension_Pack-6.0.14.vbox-extpack
|
||||
```
|
||||
|
||||
下载后,打开 VirtualBox 并依次点击 “File -> Preferences -> Extension”,然后点击 “+” 号图标添加下载的扩展包:
|
||||
|
||||
![Install-VirtualBox-Extension-Pack-CentOS8][5]
|
||||
|
||||
单击 “Install” 开始安装扩展包:
|
||||
|
||||
![Accept-VirtualBox-Extension-Pack-License-CentOS8][6]
|
||||
|
||||
单击 “I Agree” 接受 VirtualBox 扩展包许可证。
|
||||
|
||||
成功安装 VirtualBox 扩展包后,我们将看到下面的页面,单击 “OK” 并开始使用 VirtualBox。
|
||||
|
||||
![VirtualBox-Extension-Pack-Install-Message-CentOS8][7]
|
||||
|
||||
本文就是这些了,我希望这些步骤可以帮助你在 CentOS 8 和 RHEL 8 系统上安装 VirtualBox 6.0。请分享你的宝贵的反馈和意见。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.linuxtechi.com/install-virtualbox-6-centos-8-rhel-8/
|
||||
|
||||
作者:[Pradeep Kumar][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://www.linuxtechi.com/author/pradeep/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://www.linuxtechi.com/dnf-command-examples-rpm-management-fedora-linux/
|
||||
[2]: data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7
|
||||
[3]: https://www.linuxtechi.com/wp-content/uploads/2019/11/Access-VirtualBox-CentOS8.jpg
|
||||
[4]: https://www.linuxtechi.com/wp-content/uploads/2019/11/VirtualBox-CentOS8.jpg
|
||||
[5]: https://www.linuxtechi.com/wp-content/uploads/2019/11/Install-VirtualBox-Extension-Pack-CentOS8.jpg
|
||||
[6]: https://www.linuxtechi.com/wp-content/uploads/2019/11/Accept-VirtualBox-Extension-Pack-License-CentOS8.jpg
|
||||
[7]: https://www.linuxtechi.com/wp-content/uploads/2019/11/VirtualBox-Extension-Pack-Install-Message-CentOS8.jpg
|
||||
[9]: http://www.facebook.com/sharer.php?u=https%3A%2F%2Fwww.linuxtechi.com%2Finstall-virtualbox-6-centos-8-rhel-8%2F&t=How%20to%20Install%20VirtualBox%206.0%20on%20CentOS%208%20%2F%20RHEL%208
|
||||
[10]: http://twitter.com/share?text=How%20to%20Install%20VirtualBox%206.0%20on%20CentOS%208%20%2F%20RHEL%208&url=https%3A%2F%2Fwww.linuxtechi.com%2Finstall-virtualbox-6-centos-8-rhel-8%2F&via=Linuxtechi
|
||||
[11]: http://www.linkedin.com/shareArticle?mini=true&url=https%3A%2F%2Fwww.linuxtechi.com%2Finstall-virtualbox-6-centos-8-rhel-8%2F&title=How%20to%20Install%20VirtualBox%206.0%20on%20CentOS%208%20%2F%20RHEL%208
|
||||
[12]: http://www.reddit.com/submit?url=https%3A%2F%2Fwww.linuxtechi.com%2Finstall-virtualbox-6-centos-8-rhel-8%2F&title=How%20to%20Install%20VirtualBox%206.0%20on%20CentOS%208%20%2F%20RHEL%208
|
166
published/201911/20191118 How containers work- overlayfs.md
Normal file
166
published/201911/20191118 How containers work- overlayfs.md
Normal file
@ -0,0 +1,166 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11605-1.html)
|
||||
[#]: subject: (How containers work: overlayfs)
|
||||
[#]: via: (https://jvns.ca/blog/2019/11/18/how-containers-work--overlayfs/)
|
||||
[#]: author: (Julia Evans https://jvns.ca/)
|
||||
|
||||
容器如何工作:OverlayFS
|
||||
======
|
||||
|
||||
今天早上,我为未来潜在容器[杂志][1]画了一幅 OverlayFS 的漫画,我对这个主题感到兴奋,想写一篇关于它的博客来提供更多详细信息。
|
||||
|
||||

|
||||
|
||||
### 容器镜像很大
|
||||
|
||||
容器镜像可能会很大(尽管有些很小,例如 [alpine linux 才 2.5MB][2])。Ubuntu 16.04 约为 27 MB,[Anaconda Python 发行版为 800MB 至 1.5GB][3]。
|
||||
|
||||
你以镜像启动的每个容器都是原始空白状态,仿佛它只是为使用容器而复制的一份镜像拷贝一样。但是对于大的容器镜像,像 800MB 的 Anaconda 镜像,复制一份拷贝既浪费磁盘空间也很慢。因此 Docker 不会复制,而是采用**叠加**。
|
||||
|
||||
### 叠加如何工作
|
||||
|
||||
OverlayFS,也被称为 **联合文件系统**或 **联合挂载**,它可让你使用 2 个目录挂载文件系统:“下层”目录和“上层”目录。
|
||||
|
||||
基本上:
|
||||
|
||||
* 文件系统的**下层**目录是只读的
|
||||
* 文件系统的**上层**目录可以读写
|
||||
|
||||
当进程“读取”文件时,OverlayFS 文件系统驱动将在上层目录中查找并从该目录中读取文件(如果存在)。否则,它将在下层目录中查找。
|
||||
|
||||
当进程“写入”文件时,OverlayFS 会将其写入上层目录。
|
||||
|
||||
### 让我们使用 mount 制造一个叠加层!
|
||||
|
||||
这有点抽象,所以让我们制作一个 OverlayFS 并尝试一下!这将只包含一些文件:我将创建上、下层目录,以及用来挂载合并的文件系统的 `merged ` 目录:
|
||||
|
||||
```
|
||||
$ mkdir upper lower merged work
|
||||
$ echo "I'm from lower!" > lower/in_lower.txt
|
||||
$ echo "I'm from upper!" > upper/in_upper.txt
|
||||
$ # `in_both` is in both directories
|
||||
$ echo "I'm from lower!" > lower/in_both.txt
|
||||
$ echo "I'm from upper!" > upper/in_both.txt
|
||||
```
|
||||
|
||||
合并上层目录和下层目录非常容易:我们可以通过 `mount` 来完成!
|
||||
|
||||
```
|
||||
$ sudo mount -t overlay overlay
|
||||
-o lowerdir=/home/bork/test/lower,upperdir=/home/bork/test/upper,workdir=/home/bork/test/work
|
||||
/home/bork/test/merged
|
||||
```
|
||||
|
||||
在执行此操作时,我不断收到一条非常烦人的错误消息,内容为:`mount: /home/bork/test/merged: special device overlay does not exist.`。这条消息是错误的,实际上只是意味着我指定的一个目录缺失(我写成了 `~/test/merged`,但它没有被展开)。
|
||||
|
||||
让我们尝试从 OverlayFS 中读取其中一个文件!文件 `in_both.txt` 同时存在于 `lower/` 和 `upper/` 中,因此应从 `upper/` 目录中读取该文件。
|
||||
|
||||
```
|
||||
$ cat merged/in_both.txt
|
||||
"I'm from upper!
|
||||
```
|
||||
|
||||
可以成功!
|
||||
|
||||
目录的内容就是我们所期望的:
|
||||
|
||||
```
|
||||
find lower/ upper/ merged/
|
||||
lower/
|
||||
lower/in_lower.txt
|
||||
lower/in_both.txt
|
||||
upper/
|
||||
upper/in_upper.txt
|
||||
upper/in_both.txt
|
||||
merged/
|
||||
merged/in_lower.txt
|
||||
merged/in_both.txt
|
||||
merged/in_upper.txt
|
||||
```
|
||||
|
||||
### 创建新文件时会发生什么?
|
||||
|
||||
```
|
||||
$ echo 'new file' > merged/new_file
|
||||
$ ls -l */new_file
|
||||
-rw-r--r-- 1 bork bork 9 Nov 18 14:24 merged/new_file
|
||||
-rw-r--r-- 1 bork bork 9 Nov 18 14:24 upper/new_file
|
||||
```
|
||||
|
||||
这是有作用的,新文件会在 `upper` 目录创建。
|
||||
|
||||
### 删除文件时会发生什么?
|
||||
|
||||
读写似乎很简单。但是删除会发生什么?开始试试!
|
||||
|
||||
```
|
||||
$ rm merged/in_both.txt
|
||||
```
|
||||
|
||||
发生了什么?让我们用 `ls` 看下:
|
||||
|
||||
```
|
||||
ls -l upper/in_both.txt lower/lower1.txt merged/lower1.txt
|
||||
ls: cannot access 'merged/in_both.txt': No such file or directory
|
||||
-rw-r--r-- 1 bork bork 6 Nov 18 14:09 lower/in_both.txt
|
||||
c--------- 1 root root 0, 0 Nov 18 14:19 upper/in_both.txt
|
||||
```
|
||||
|
||||
所以:
|
||||
|
||||
* `in_both.txt` 仍在 `lower` 目录中,并且保持不变
|
||||
* 它不在 `merged` 目录中。到目前为止,这就是我们所期望的。
|
||||
* 但是在 `upper` 中发生的事情有点奇怪:有一个名为 `upper/in_both.txt` 的文件,但是它是字符设备?我想这就是 overlayfs 驱动表示删除的文件的方式。
|
||||
|
||||
如果我们尝试复制这个奇怪的字符设备文件,会发生什么?
|
||||
|
||||
```
|
||||
$ sudo cp upper/in_both.txt upper/in_lower.txt
|
||||
cp: cannot open 'upper/in_both.txt' for reading: No such device or address
|
||||
```
|
||||
|
||||
好吧,这似乎很合理,复制这个奇怪的删除信号文件并没有任何意义。
|
||||
|
||||
### 你可以挂载多个“下层”目录
|
||||
|
||||
Docker 镜像通常由 25 个“层”组成。OverlayFS 支持具有多个下层目录,因此你可以运行:
|
||||
|
||||
```
|
||||
mount -t overlay overlay
|
||||
-o lowerdir:/dir1:/dir2:/dir3:...:/dir25,upperdir=...
|
||||
```
|
||||
|
||||
因此,我假设这是有多个 Docker 层的容器的工作方式,它只是将每个层解压缩到一个单独的目录中,然后要求 OverlayFS 将它们全部合并在一起,并使用一个空的上层目录,容器将对其进行更改。
|
||||
|
||||
### Docker 也可以使用 btrfs 快照
|
||||
|
||||
现在,我使用的是 ext4,而 Docker 使用 OverlayFS 快照来运行容器。但是我曾经用过 btrfs,接着 Docker 将改为使用 btrfs 的写时复制快照。(这是 Docker 何时使用哪种[存储驱动][4]的列表)
|
||||
|
||||
以这种方式使用 btrfs 快照会产生一些有趣的结果:去年某个时候,我在笔记本上运行了数百个临时的 Docker 容器,这导致我用尽了 btrfs 元数据空间(像[这个人][5]一样)。这真的很令人困惑,因为我以前从未听说过 btrfs 元数据,而且弄清楚如何清理文件系统以便再次运行 Docker 容器非常棘手。([这个 docker github 上的提案][6]描述了 Docker 和 btrfs 的类似问题)
|
||||
|
||||
### 以简单的方式尝试容器功能很有趣!
|
||||
|
||||
我认为容器通常看起来像是在做“复杂的”事情,我认为将它们分解成这样很有趣。你可以运行一条 `mount` 咒语,而实际上并没有做任何与容器相关的其他事情,看看叠加层是如何工作的!
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://jvns.ca/blog/2019/11/18/how-containers-work--overlayfs/
|
||||
|
||||
作者:[Julia Evans][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://jvns.ca/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://wizardzines.com
|
||||
[2]: https://hub.docker.com/_/alpine?tab=tags
|
||||
[3]: https://hub.docker.com/r/continuumio/anaconda3/tags
|
||||
[4]: https://docs.docker.com/storage/storagedriver/select-storage-driver/
|
||||
[5]: https://www.reddit.com/r/archlinux/comments/5jrmfe/btrfs_metadata_and_docker/
|
||||
[6]: https://github.com/moby/moby/issues/27653
|
204
published/201911/20191119 How to use pkgsrc on Linux.md
Normal file
204
published/201911/20191119 How to use pkgsrc on Linux.md
Normal file
@ -0,0 +1,204 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11613-1.html)
|
||||
[#]: subject: (How to use pkgsrc on Linux)
|
||||
[#]: via: (https://opensource.com/article/19/11/pkgsrc-netbsd-linux)
|
||||
[#]: author: (Seth Kenlon https://opensource.com/users/seth)
|
||||
|
||||
如何在 Linux 上使用 pkgsrc
|
||||
======
|
||||
|
||||
> NetBSD 的软件包管理器通用、灵活又容易。下面是如何使用它。
|
||||
|
||||

|
||||
|
||||
NetBSD 以能在几乎所有平台上运行而闻名,但你知道它*第二*有名的 [pkgsrc][2] 包管理器吗?像 NetBSD 一样,pkgsrc 基本上可以在任何系统上运行,或者至少在任意 Unix 和类 Unix 的系统上上运行。你可以在 BSD、Linux、Illumos、Solaris 和 Mac 上安装 pkgsrc。它总共支持 20 多种操作系统。
|
||||
|
||||
### 为什么使用 pkgsrc?
|
||||
|
||||
除了 MacOS 之外,所有 Unix 操作系统均自带包管理器。你不一定*需要* pkgsrc,但这可能是你想尝试的三个重要原因:
|
||||
|
||||
* **打包**。如果你对打包感到好奇,但尚未尝试自己创建一个软件包,那么 pkgsrc 是一个相对简单的系统,尤其是如果你已经熟悉 Makefile 和类似 [GNU Autotools][3] 之类的构建系统时。
|
||||
* **通用**。如果你使用多个操作系统或发行版,那么可能会遇到每个系统的包管理器。你可以在不同的系统上使用 pkgsrc,以便你为一个系统打包了程序,就为所有系统打包了。
|
||||
* **灵活**。在许多打包系统中,如何选择二进制包或源码包并不总是很明显。使用 pkgsrc,区别很明显,两种安装方法都一样容易,并且都可以为你解决依赖关系。
|
||||
|
||||
### 如何安装 pkgsrc
|
||||
|
||||
无论你使用的是 BSD、Linux、Illumos、Solaris 还是 MacOS,安装过程都基本相同:
|
||||
|
||||
1. 使用 CVS 检出 pkgsrc 树
|
||||
2. 引导 pkgsrc 系统
|
||||
3. 安装软件包
|
||||
|
||||
#### 使用 CVS 检出 pkgsrc 树
|
||||
|
||||
在 Git 和 Subversion 之前,就有了 [CVS][4]。要检出代码你无需了解 CVS 太多,如果你习惯 Git,那么可以将<ruby>检出<rt>checkout</rt></ruby>称为<ruby>克隆<rt>clone</rt></ruby>。当你用 CVS 检出 pkgsrc 时,你就下载了详细说明如何构建每个软件包的“<ruby>配方<rt>recipes</rt></ruby>”。它有很多文件,但是它们都很小,因为你实际上并没有拉取每个包的源码,而只有按需构建时需要的构建基础架构和 Makefile。使用 CVS,你可以轻松地在新版本发布时更新 pkgsrc 检出。
|
||||
|
||||
pkgsrc 文档建议将其源码树放在 `/usr` 目录下,因此你必须使用 `sudo`(或成为 root)运行此命令:
|
||||
|
||||
```
|
||||
$ cd /usr
|
||||
$ sudo cvs -q -z2 -d anoncvs@anoncvs.NetBSD.org:/cvsroot checkout -r pkgsrc-2019Q3 -P pkgsrc
|
||||
```
|
||||
|
||||
在我撰写本文时,最新版本是 2019Q3。请检查 [pkgsrc.org][6] 主页的新闻部分或 [NetBSD文档][7],以确定最新版本。
|
||||
|
||||
#### 引导 pkgsrc
|
||||
|
||||
pkgsrc 树复制到你的计算机后,你会看到一个充满构建脚本的 `/usr/pkgsrc` 目录。在使用之前,你必须引导 pkgsrc,以便你可以轻松地访问构建和安装软件所需的相关命令。
|
||||
|
||||
引导 pkgsrc 的方式取决于你所使用操作系统。
|
||||
|
||||
对于 NetBSD,你只需使用捆绑的引导器:
|
||||
|
||||
```
|
||||
# cd pkgsrc/bootstrap
|
||||
# ./bootstrap
|
||||
```
|
||||
|
||||
在其他系统上,还有更好的方法,包括一些自定义功能,它是由 Joyent 提供的。要了解运行的确切命令,请访问 [pkgsrc.joyent.com][8]。比如,在 Linux(Fedora、Debian、Slackware 等)上:
|
||||
|
||||
```
|
||||
$ curl -O https://pkgsrc.joyent.com/packages/Linux/el7/bootstrap/bootstrap-trunk-x86_64-20170127.tar.gz
|
||||
$ BOOTSTRAP_SHA="eb0d6911489579ca893f67f8a528ecd02137d43a"
|
||||
```
|
||||
|
||||
尽管路径暗示文件适用于 RHEL 7,但二进制文件往往与所有(最前沿的 Linux 发行版)兼容。如果你发现二进制文件与你的发行版不兼容,你可以选择从源码构建。
|
||||
|
||||
验证 SHA1 校验和:
|
||||
|
||||
```
|
||||
$ echo "${BOOTSTRAP_SHA}" bootstrap-trunk*gz > check-shasum
|
||||
sha1sum -c check-shasum
|
||||
```
|
||||
|
||||
你还可以验证 PGP 签名:
|
||||
|
||||
```
|
||||
$ curl -O https://pkgsrc.joyent.com/packages/Linux/el7/bootstrap/bootstrap-trunk-x86_64-20170127.tar.gz.asc
|
||||
$ curl -sS https://pkgsrc.joyent.com/pgp/56AAACAF.asc | gpg --import
|
||||
$ gpg --verify ${BOOTSTRAP_TAR}{.asc,}
|
||||
```
|
||||
|
||||
当你确认你已有正确的引导套件,将其安装到 `/usr/pkg`:
|
||||
|
||||
```
|
||||
sudo tar -zxpf ${BOOTSTRAP_TAR} -C /
|
||||
```
|
||||
|
||||
它为你提供了通常的 pkgsrc 命令。将这些位置添加到[你的 PATH 环境变量中][9]:
|
||||
|
||||
```
|
||||
$ echo "PATH=/usr/pkg/sbin:/usr/pkg/bin:$PATH" >> ~/.bashrc
|
||||
$ echo "MANPATH=/usr/pkg/man:$MANPATH" >> ~/.bashrc
|
||||
```
|
||||
|
||||
如果你宁愿使用 pkgsrc 而不依赖于 Joyent 的构建,那么只需运行 pkgsrc 源码树的引导脚本即可。在运行特定于系统的脚本之前,请先阅读 `bootstrap` 目录中相关 `README` 文件。
|
||||
|
||||
![Bootstrapping pkgsrc on NetBSD][10]
|
||||
|
||||
### 如何使用 pkgsrc 安装软件
|
||||
|
||||
使用 pkgsrc 安装预编译的二进制文件(就像使用 DNF 或 Apt 一样)是很容易的。二进制安装的命令是 `pgkin`,它有自己的专门网站 [pkgin.net][11]。对于任何用过 Linux 的人来说,这个过程应该感觉相当熟悉。
|
||||
|
||||
要搜索 `tmux` 包:
|
||||
|
||||
```
|
||||
$ pkgin search tmux
|
||||
```
|
||||
|
||||
要安装 tmux 包:
|
||||
|
||||
```
|
||||
$ sudo pkgin install tmux
|
||||
```
|
||||
|
||||
`pkgin` 命令的目的是模仿典型的 Linux 包管理器的行为,因此有选项可以列出可用的包、查找包提供的特定可执行文件,等等。
|
||||
|
||||
### 如何使用 pkgsrc 从源码构建
|
||||
|
||||
然而,pkgsrc 真正强大的地方是方便地从源码构建包。你在第一步中检出了所有 20000 多个构建脚本,你可以直接进入 pkgsrc 源码树来访问这些脚本。
|
||||
|
||||
例如,要从源码构建 `tcsh`,首先找到构建脚本:
|
||||
|
||||
```
|
||||
$ find /usr/pkgsrc -type d -name "tcsh"
|
||||
/usr/pkgsrc/shells/tcsh
|
||||
```
|
||||
|
||||
接下来,进入源码目录:
|
||||
|
||||
```
|
||||
$ cd /usr/pgksrc/shells/tcsh
|
||||
```
|
||||
|
||||
构建脚本目录包含许多文件来帮助在你的系统上构建应用,但值得注意的是,这里面有包含了软件说明的 `DESCR` 文件,以及触发构建的 `Makefile`。
|
||||
|
||||
```
|
||||
$ ls
|
||||
CVS DESCR Makefile
|
||||
PLIST distinfo patches
|
||||
$ cat DESCR
|
||||
TCSH is an extended C-shell with many useful features like
|
||||
filename completion, history editing, etc.
|
||||
$
|
||||
```
|
||||
|
||||
准备就绪后,构建并安装:
|
||||
|
||||
```
|
||||
$ sudo bmake install
|
||||
```
|
||||
|
||||
pkgsrc 系统使用 `bmake` 命令(在第一步检出 pkgsrc 后提供),因此请务必使用 `bmake`(而不是出于习惯使用 `make`)。
|
||||
|
||||
如果要为多个系统构建,那么你可以创建一个包,而不是立即安装:
|
||||
|
||||
```
|
||||
$ cd /usr/pgksrc/shells/tcsh
|
||||
$ sudo bmake package
|
||||
[...]
|
||||
=> Creating binary package in /usr/pkgsrc/packages/All/tcsh-X.Y.Z.tgz
|
||||
```
|
||||
|
||||
pkgsrc 创建的包是标准的 tarball,但它可以方便地通过 `pkg_add` 安装:
|
||||
|
||||
```
|
||||
$ sudo pkg_add /usr/pkgsrc/packages/All/tcsh-X.Y.Z.tgz
|
||||
tcsh-X.Y.Z: adding /usr/pkg/bin/tcsh to /etc/shells
|
||||
$ tcsh
|
||||
localhost%
|
||||
```
|
||||
|
||||
pkgsrc 的 pkgtools 集合提供 `pkg_add`、`pkg_info`、`pkg_admin`、`pkg_create` 和 `pkg_delete` 命令,来帮助管理你在系统上构建和维护软件包。
|
||||
|
||||
### pkgsrc,易于管理
|
||||
|
||||
pkgsrc 系统提供了直接,容易上手的软件包管理方法。如果你正在寻找一个不妨碍你并且可以定制的包管理器,请在任何运行 Unix 或类 Unix 的系统上试试 pkgsrc。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/19/11/pkgsrc-netbsd-linux
|
||||
|
||||
作者:[Seth Kenlon][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [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/computer_keyboard_laptop_development_code_woman.png?itok=vbYz6jjb (A person programming)
|
||||
[2]: http://pkgsrc.org
|
||||
[3]: https://opensource.com/article/19/7/introduction-gnu-autotools
|
||||
[4]: http://www.netbsd.org/developers/cvs-repos/cvs_intro.html#intro
|
||||
[5]: mailto:anoncvs@anoncvs.NetBSD.org
|
||||
[6]: http://pkgsrc.org/
|
||||
[7]: http://www.netbsd.org/docs/pkgsrc/getting.html
|
||||
[8]: http://pkgsrc.joyent.com/
|
||||
[9]: https://opensource.com/article/17/6/set-path-linux
|
||||
[10]: https://opensource.com/sites/default/files/uploads/pkgsrc-bootstrap.jpg (Bootstrapping pkgsrc on NetBSD)
|
||||
[11]: http://pkgin.net
|
@ -0,0 +1,155 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11619-1.html)
|
||||
[#]: subject: (How to Use TimeShift to Backup and Restore Ubuntu Linux)
|
||||
[#]: via: (https://www.linuxtechi.com/timeshift-backup-restore-ubuntu-linux/)
|
||||
[#]: author: (James Kiarie https://www.linuxtechi.com/author/james/)
|
||||
|
||||
如何使用 TimeShift 备份和还原 Ubuntu Linux
|
||||
======
|
||||
|
||||
你是否曾经想过如何备份和还原 Ubuntu 或 Debian 系统?Timeshift 是一款自由开源工具,可让你创建文件系统的增量快照。你可以使用 RSYNC 或 BTRFS 两种方式创建快照。
|
||||
|
||||

|
||||
|
||||
让我们深入研究并安装 Timeshift。在本教程,我们将安装在 Ubuntu 18.04 LTS 系统上。
|
||||
|
||||
### 在 Ubuntu / Debian Linux 上安装 TimeShift
|
||||
|
||||
TimeShift 尚未正式托管在 Ubuntu 和 Debian 仓库中。考虑到这一点,我们将运行以下命令来添加 PPA:
|
||||
|
||||
```
|
||||
# add-apt-repository -y ppa:teejee2008/ppa
|
||||
```
|
||||
|
||||
![Add timeshift repository][3]
|
||||
|
||||
接下来,使用以下命令更新系统软件包:
|
||||
|
||||
```
|
||||
# apt update
|
||||
```
|
||||
|
||||
成功更新系统后,使用以下 `apt` 命令安装 Timeshift:
|
||||
|
||||
```
|
||||
# apt install timeshift
|
||||
```
|
||||
|
||||
![apt install timeshift][4]
|
||||
|
||||
### 准备备份存储设备
|
||||
|
||||
最佳实践要求我们将系统快照保存在系统硬盘之外的单独的存储卷上。对于本指南,我们将使用 16GB 闪存作为第二个驱动器,并在该驱动器上保存快照。
|
||||
|
||||
```
|
||||
# lsblk | grep sdb
|
||||
```
|
||||
|
||||
![lsblk sdb ubuntu][5]
|
||||
|
||||
为了将闪存用作快照的备份位置,我们需要在设备上创建一个分区表。运行以下命令:
|
||||
|
||||
```
|
||||
# parted /dev/sdb mklabel gpt
|
||||
# parted /dev/sdb mkpart primary 0% 100%
|
||||
# mkfs.ext4 /dev/sdb1
|
||||
```
|
||||
|
||||
![create partition table on drive ubuntu][6]
|
||||
|
||||
在 USB 闪存上创建分区表后,我们可以开始创建文件系统的快照!
|
||||
|
||||
### 使用 Timeshift 创建快照
|
||||
|
||||
要启动 Timeshift,使用应用程序菜单搜索 “Timeshift”。
|
||||
|
||||
![Access timeshift][7]
|
||||
|
||||
单击 Timeshift 图标,系统将提示你输入管理员密码。提供密码,然后单击验证。
|
||||
|
||||
![Authentication required][8]
|
||||
|
||||
接下来,选择你喜欢的快照类型。
|
||||
|
||||
![Select rsync option][9]
|
||||
|
||||
点击 “Next”。选择快照的目标驱动器。在这里,我的位置是标记为 `/dev/sdb` 的外部 USB 驱动器。
|
||||
|
||||
![Select snapshot location][10]
|
||||
|
||||
接下来,定义快照级别。级别是指创建快照的时间间隔。你可以选择每月、每周、每天或每小时的快照级别。
|
||||
|
||||
![Select snapshot levels][11]
|
||||
|
||||
点击 “Finish”。
|
||||
|
||||
在下一个窗口中,单击 “Create” 按钮开始创建快照。此后,系统将开始创建快照。
|
||||
|
||||
![Create snapshot][12]
|
||||
|
||||
最后,你的快照将显示如下:
|
||||
|
||||
![Snapshot created][13]
|
||||
|
||||
### 从快照还原 Ubuntu / Debian
|
||||
|
||||
创建系统快照后,现在让我们看看如何从同一快照还原系统。在同一个 Timeshift 中,单击快照,然后单击 “Restore” 按钮,如图所示。
|
||||
|
||||
![Restore snapshot][14]
|
||||
|
||||
接下来,将提示你选择目标设备。保留默认选择,然后点击 “Next”。
|
||||
|
||||
![Select target device][15]
|
||||
|
||||
恢复过程开始之前,Timeshift 将会试运行。
|
||||
|
||||
![Comparing files dry run][16]
|
||||
|
||||
在下一个窗口中,点击 “Next” 按钮确认显示的操作。
|
||||
|
||||
![Confirm actions][17]
|
||||
|
||||
如图所示,你会看到警告和免责声明。点击 “Next” 初始化恢复过程。
|
||||
|
||||
此后,将开始还原过程,最后,系统之后将重新启动到快照定义的早期版本。
|
||||
|
||||
![Restoring snapshot][18]
|
||||
|
||||
### 总结
|
||||
|
||||
如你所见,使用 TimeShift 从快照还原系统非常容易。在备份系统文件时,它非常方便,并允许你在系统故障时进行恢复。因此,不要害怕修改系统或弄乱系统。TimeShift 使你能够返回到一切运行平稳的时间点。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.linuxtechi.com/timeshift-backup-restore-ubuntu-linux/
|
||||
|
||||
作者:[James Kiarie][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://www.linuxtechi.com/author/james/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7
|
||||
[2]: https://www.linuxtechi.com/wp-content/uploads/2019/11/TimeShift-Backup-Restore-Tool-Ubuntu.png
|
||||
[3]: https://www.linuxtechi.com/wp-content/uploads/2019/11/Add-timeshift-repository.png
|
||||
[4]: https://www.linuxtechi.com/wp-content/uploads/2019/11/apt-install-timeshift.png
|
||||
[5]: https://www.linuxtechi.com/wp-content/uploads/2019/11/lsblk-sdb-ubuntu.png
|
||||
[6]: https://www.linuxtechi.com/wp-content/uploads/2019/11/create-partition-table-on-drive-ubuntu.jpg
|
||||
[7]: https://www.linuxtechi.com/wp-content/uploads/2019/11/Access-Timeshift-Ubuntu.jpg
|
||||
[8]: https://www.linuxtechi.com/wp-content/uploads/2019/11/Authentication-required-ubuntu.jpg
|
||||
[9]: https://www.linuxtechi.com/wp-content/uploads/2019/11/Select-Rsync-option-timeshift.jpg
|
||||
[10]: https://www.linuxtechi.com/wp-content/uploads/2019/11/Select-snapshot-location.png
|
||||
[11]: https://www.linuxtechi.com/wp-content/uploads/2019/11/Select-snapshot-levels-Timeshift.jpg
|
||||
[12]: https://www.linuxtechi.com/wp-content/uploads/2019/11/Create-snapshot-timeshift.jpg
|
||||
[13]: https://www.linuxtechi.com/wp-content/uploads/2019/11/Snapshot-created-TimeShift.jpg
|
||||
[14]: https://www.linuxtechi.com/wp-content/uploads/2019/11/Restore-snapshot-timeshift.jpg
|
||||
[15]: https://www.linuxtechi.com/wp-content/uploads/2019/11/Select-target-device-timeshift.jpg
|
||||
[16]: https://www.linuxtechi.com/wp-content/uploads/2019/11/Comparing-files-Dry-Run-timeshift.jpg
|
||||
[17]: https://www.linuxtechi.com/wp-content/uploads/2019/11/Confirm-actions-timeshift.jpg
|
||||
[18]: https://www.linuxtechi.com/wp-content/uploads/2019/11/Restoring-snapshot-timeshift.png
|
215
published/201911/20191120 How to install Java on Linux.md
Normal file
215
published/201911/20191120 How to install Java on Linux.md
Normal file
@ -0,0 +1,215 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (wxy)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11614-1.html)
|
||||
[#]: subject: (How to install Java on Linux)
|
||||
[#]: via: (https://opensource.com/article/19/11/install-java-linux)
|
||||
[#]: author: (Seth Kenlon https://opensource.com/users/seth)
|
||||
|
||||
如何在 Linux 上安装 Java
|
||||
======
|
||||
|
||||
> 在桌面上拥抱 Java 应用程序,然后在所有桌面上运行它们。
|
||||
|
||||

|
||||
|
||||
无论你运行的是哪种操作系统,通常都有几种安装应用程序的方法。有时你可能会在应用程序商店中找到一个应用程序,或者使用 Fedora 上的 DNF 或 Mac 上的 Brew 这样的软件包管理器进行安装,而有时你可能会从网站上下载可执行文件或安装程序。因为 Java 是这么多流行的应用程序的后端,所以最好了解安装它的不同方法。好消息是你有很多选择,本文涵盖了所有这些内容。
|
||||
|
||||
坏消息是 Java *太大*,我说的不仅仅是文件大小。Java 是一种开放源代码语言和规范,这意味着从理论上讲,任何人都可以创建它的实现版本。这意味着,在安装任何东西之前,必须确定要安装的 Java 发行版。
|
||||
|
||||
### 我需要 JVM 还是 JRE 或者 JDK?
|
||||
|
||||
Java 大致分为两个下载类别。<ruby>Java 虚拟机<rt>Java Virtual Machine</rt></ruby>(JVM)是运行时组件;它是使 Java 应用程序能够在计算机上启动和运行的“引擎”。它包含在 <ruby>Java 运行时环境<rt>Java Runtime Environment</rt></ruby>(JRE)中。
|
||||
|
||||
<ruby>Java 开发工具包<rt>Java Development Kit</rt></ruby>(JDK)是一个开发工具包:你可以将其视为一个车库,修理工可以坐在那里进行调整、修理和改进。JDK 包含 Java 运行时环境(JRE)。
|
||||
|
||||
以下载来说,这意味着:
|
||||
|
||||
* 如果你是希望运行 Java 应用程序的用户,则只需 JRE(包括了 JVM)。
|
||||
* 如果你是希望使用 Java 进行编程的开发人员,则需要 JDK(包括 JRE 库,而 JRE 库又包括 JVM)。
|
||||
|
||||
### OpenJDK、IcedTea 和 OracleJDK 有什么不同?
|
||||
|
||||
当<ruby>太阳微系统<rt>Sun Microsystems</rt></ruby>被 Oracle 收购时,Java 是该交易的主要部分。幸运的是,Java 是一种开源技术,因此,如果你对 Oracle 维护该项目的方式不满意,则可以选择其他方法。Oracle 将专有组件与 Java 下载捆绑在一起,而 OpenJDK 项目是完全开源的。
|
||||
|
||||
IcedTea 项目本质上是 OpenJDK,但其目标是使用户在使用完全自由开源的工具时更容易构建和部署 OpenJDK。
|
||||
|
||||
(LCTT 译注:阿里巴巴也有一个它自己维护的 Open JDK 发行版“<ruby>龙井<rt>Dragonwell</rt></ruby>”。以下引自其官网:“Alibaba Dragonwell 是一款免费的,生产就绪型 Open JDK 发行版,提供长期支持,包括性能增强和安全修复。……Alibaba Dragonwell 作为 Java 应用的基石,支撑了阿里经济体内所有的 Java 业务。Alibaba Dragonwell 完全兼容 Java SE 标准,……”)
|
||||
|
||||
### 我应该安装哪个 Java?
|
||||
|
||||
如果你对这些选择感到不知所措,那么简单的答案就是你应该安装的 Java 实现应该是最容易安装的那个。当应用程序告诉你需要 Java 12,但你的存储库中只有 Java 8 时,可以安装可以从可靠来源中找到的 Java 12 的任何实现。在 Linux 上,你可以一次安装几个不同版本的 Java,它们不会互相干扰。
|
||||
|
||||
如果你是需要选择使用哪个版本的开发人员,则应考虑所需的组件。如果选择 Oracle 的版本,请注意,软件包中包含专有的插件和字体,可能会[影响你分发你的应用程序][2]。在 IcedTea 或 OpenJDK 上进行开发是最安全的。
|
||||
|
||||
### 从存储库安装 OpenJDK?
|
||||
|
||||
现在,你已经知道要选择什么了,你可以使用软件包管理器搜索 OpenJDK 或 IcedTea,然后安装所需的版本。有些发行版使用关键字 `latest` 来指示最新版本,这通常是你要运行的应用程序所需要的。根据你使用的软件包管理器,你甚至可以考虑使用 `grep` 过滤搜索结果以仅包括最新版本。例如,在 Fedora 上:
|
||||
|
||||
```
|
||||
$ sudo dnf search openjdk | grep latest | cut -f1 -d':'
|
||||
|
||||
java-latest-openjdk-demo.x86_64
|
||||
java-openjdk.i686
|
||||
java-openjdk.x86_64
|
||||
java-latest-openjdk-jmods.x86_64
|
||||
java-latest-openjdk-src.x86_64
|
||||
java-latest-openjdk.x86_64
|
||||
[...]
|
||||
```
|
||||
|
||||
只有当你尝试运行的应用程序坚持要求你使用 Java 的旧版本时,你才应该看看 `latest` 之前的版本。
|
||||
|
||||
在 Fedora 或类似系统上安装 Java:
|
||||
|
||||
```
|
||||
$ sudo dnf install java-latest-openjdk
|
||||
```
|
||||
|
||||
如果你的发行版不使用 `latest` 标签,则可以使用其他关键字,例如 `default`。以下是在 Debian 上搜索 OpenJDK 的信息:
|
||||
|
||||
```
|
||||
$ sudo apt search openjdk | less
|
||||
default-jdk
|
||||
Standard Java development kit
|
||||
|
||||
default-jre
|
||||
Standard Java runtime
|
||||
|
||||
openjdk-11-jdk
|
||||
OpenJDK development kit (JDK)
|
||||
|
||||
[...]
|
||||
```
|
||||
|
||||
在这种情况下,`default-jre` 软件包适合用户,而 `default-jdk` 则适合开发人员。
|
||||
|
||||
例如,要在 Debian 上安装 JRE:
|
||||
|
||||
```
|
||||
$ sudo apt install default-jre
|
||||
```
|
||||
|
||||
现在已安装好 Java。
|
||||
|
||||
你的存储库中可能有*许多*与 Java 相关的软件包。要搜索 OpenJDK,如果你是用户,则查找最新的 JRE 或 JVM,如果你是开发人员,则查找最新的 JDK。
|
||||
|
||||
### 从互联网上安装 Java
|
||||
|
||||
如果在存储库中找不到 JRE 或 JDK,或者找不到满足你需求的 JRE 或 JDK,则可以从互联网上下载开源的 Java 软件包。你可以在 [openjdk.java.net][3] 中找到需要手动安装的 tar 形式的 OpenJDK 下载文件,或者可以从 Azul 下载 tar 形式的 [Zulu 社区版][4]或其可安装的 RPM 或 DEB 软件包。
|
||||
|
||||
#### 从 TAR 文件安装 Java
|
||||
|
||||
如果从 Java.net 或 Azul 下载 TAR 文件,则必须手动安装。这通常称为“本地”安装,因为你没有将 Java 安装到“全局”位置。你可以在 `PATH` 中选择一个合适的位置。
|
||||
|
||||
如果你不知道 `PATH` 中包含什么,请查看一下以找出:
|
||||
|
||||
```
|
||||
$ echo $PATH
|
||||
/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/home/seth/bin
|
||||
```
|
||||
|
||||
在此示例 `PATH` 中,位置 `/usr/local/bin` 和 `/home/seth/bin` 是不错的选择。如果你是计算机上的唯一用户,那么你自己的家目录就很有意义。如果你的计算机上有很多用户,则最好选择一个通用位置,例如 `/usr/local` 或 `/opt`。
|
||||
|
||||
如果你无权访问需要 `sudo` 权限的 `/usr/local` 之类的系统级目录,则可以在你自己的家目录中创建一个本地 `bin`(意思是 “<ruby>二进制<rt>binary</rt></ruby>”,而不是“<ruby>垃圾箱<rt>waste bin</rt></ruby>”)或 `Applications` 文件夹:
|
||||
|
||||
```
|
||||
$ mkdir ~/bin
|
||||
```
|
||||
|
||||
如果它不在你的 `PATH` 中,请将其添加到其中:
|
||||
|
||||
```
|
||||
$ echo PATH=$PATH:$HOME/bin >> ~/.bashrc
|
||||
$ source ~/.bashrc
|
||||
```
|
||||
|
||||
最后,将压缩包解压缩到你选择的目录中。
|
||||
|
||||
```
|
||||
$ tar --extract --file openjdk*linux-x64_bin.tar.gz --directory=$HOME/bin
|
||||
```
|
||||
|
||||
Java 现在安装好了。
|
||||
|
||||
#### 从 RPM 或 DEB 安装 Java
|
||||
|
||||
如果从 Azul.com 下载 RPM 或 DEB 文件,则可以使用软件包管理器进行安装。
|
||||
|
||||
对于 Fedora、CentOS、RHEL 等,请下载 RPM 并使用 DNF 进行安装:
|
||||
|
||||
```
|
||||
$ sudo dnf install zulu*linux.x86_64.rpm
|
||||
```
|
||||
|
||||
对于 Debian、Ubuntu、Pop_OS 和类似发行版,请下载 DEB 软件包并使用 Apt 安装它:
|
||||
|
||||
```
|
||||
$ sudo dpkg -i zulu*linux_amd64.deb
|
||||
```
|
||||
|
||||
Java 现在安装好了。
|
||||
|
||||
#### 用 alternatives 安装你的 Java 版本
|
||||
|
||||
一些应用程序是为特定版本的 Java 开发的,不能与其他任何版本一起使用。这种情况很少见,但确实会发生,在 Linux 上,你可以使用本地安装方法(请参阅上面“从 TAR 文件安装 Java”一节)或使用 `alternatives` 应用程序来解决此冲突。
|
||||
|
||||
`alternatives` 命令会查找 Linux 系统上安装的应用程序,并让你选择要使用的版本。有些发行版,例如 Slackware,不提供 `alternatives` 命令,因此你必须使用本地安装方法。在 Fedora、CentOS 和类似的发行版上,该命令是 `alternatives`。在 Debian、Ubuntu 和类似的系统上,该命令是 `update-alternatives`。
|
||||
|
||||
要获取当前已安装在 Fedora 系统上的应用程序的可用版本列表:
|
||||
|
||||
```
|
||||
$ alternatives --list
|
||||
```
|
||||
|
||||
在 Debian 上,你必须指定可供替代的应用程序:
|
||||
|
||||
```
|
||||
$ update-alternatives --list java
|
||||
```
|
||||
|
||||
在 Fedora 上选择要使系统将哪个版本作为默认版本:
|
||||
|
||||
```
|
||||
$ sudo alternatives --config java
|
||||
```
|
||||
|
||||
在 Debian 上:
|
||||
|
||||
```
|
||||
$ sudo updates-alternatives --config java
|
||||
```
|
||||
|
||||
你可以根据需要运行的应用程序,根据需要更改默认的 Java 版本。
|
||||
|
||||
### 运行 Java 应用
|
||||
|
||||
Java 应用程序通常以 JAR 文件的形式分发。根据你安装 Java 的方式,你的系统可能已经为运行 Java 应用程序配置好了,这使你只需双击应用程序图标(或从应用程序菜单中选择它)即可运行。如果必须执行未与系统其余部分集成的本地 Java 安装,则可以直接从终端启动 Java 应用程序:
|
||||
|
||||
```
|
||||
$ java -jar ~/bin/example.jar &
|
||||
```
|
||||
|
||||
### Java 是个好东西
|
||||
|
||||
Java 是少数将跨平台开发放在首位的编程环境之一。没有什么比问一个应用程序是否能在你的平台上运行然后发现该应用程序是用 Java 编写要让人感到松一口气的了。它是如此简单,无论你是开发人员还是用户,你都可以摆脱任何平台上的焦虑。在桌面上拥抱 Java 应用程序,然后在*所有*桌面上运行它们吧。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/19/11/install-java-linux
|
||||
|
||||
作者:[Seth Kenlon][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[wxy](https://github.com/wxy)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [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/java-coffee-beans.jpg?itok=3hkjX5We (Coffee beans)
|
||||
[2]: https://www.oracle.com/technetwork/java/javase/overview/oracle-jdk-faqs.html
|
||||
[3]: http://openjdk.java.net
|
||||
[4]: https://www.azul.com/downloads/zulu-community
|
||||
[5]: tmp.wuzOCnXHry#installing-java-from-a-tar-file
|
@ -0,0 +1,175 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11624-1.html)
|
||||
[#]: subject: (How to document Python code with Sphinx)
|
||||
[#]: via: (https://opensource.com/article/19/11/document-python-sphinx)
|
||||
[#]: author: (Moshe Zadka https://opensource.com/users/moshez)
|
||||
|
||||
如何使用 Sphinx 给 Python 代码写文档
|
||||
======
|
||||
|
||||
> 最好将文档作为开发过程的一部分。Sphinx 加上 Tox,让文档可以轻松书写,并且外观漂亮。
|
||||
|
||||
![Python in a coffee cup.][1]
|
||||
|
||||
Python 代码可以在源码中包含文档。这种方式默认依靠 **docstring**,它以三引号格式定义。虽然文档的价值是很大的,但是没有充足的文档的代码还是很常见。让我们演练一个场景,了解出色的文档的强大功能。
|
||||
|
||||
经历了太多在白板技术面试上要求你实现斐波那契数列,你已经受够了。你回家用 Python 写了一个可重用的斐波那契计算器,使用浮点技巧来实现 `O(1)` 复杂度。
|
||||
|
||||
代码很简单:
|
||||
|
||||
```
|
||||
# fib.py
|
||||
import math
|
||||
|
||||
_SQRT_5 = math.sqrt(5)
|
||||
_PHI = (1 + _SQRT_5) / 2
|
||||
|
||||
def approx_fib(n):
|
||||
return round(_PHI**(n+1) / _SQRT_5)
|
||||
```
|
||||
|
||||
(该斐波那契数列是四舍五入到最接近的整数的几何序列,这是我最喜欢的鲜为人知的数学事实之一。)
|
||||
|
||||
作为一个好人,你可以将代码开源,并将它放在 [PyPI][2] 上。`setup.py` 文件很简单:
|
||||
|
||||
```
|
||||
import setuptools
|
||||
|
||||
setuptools.setup(
|
||||
name='fib',
|
||||
version='2019.1.0',
|
||||
description='Fibonacci',
|
||||
py_modules=["fib"],
|
||||
)
|
||||
```
|
||||
|
||||
但是,没有文档的代码是没有用的。因此,你可以向函数添加 docstring。我最喜欢的 docstring 样式之一是 [“Google” 样式][3]。标记很轻量,当它放在源代码中时很好。
|
||||
|
||||
|
||||
```
|
||||
def approx_fib(n):
|
||||
"""
|
||||
Approximate Fibonacci sequence
|
||||
|
||||
Args:
|
||||
n (int): The place in Fibonacci sequence to approximate
|
||||
|
||||
Returns:
|
||||
float: The approximate value in Fibonacci sequence
|
||||
"""
|
||||
# ...
|
||||
```
|
||||
|
||||
但是函数的文档只是成功的一半。普通文档对于情境化代码用法很重要。在这种情况下,情景是恼人的技术面试。
|
||||
|
||||
有一种添加更多文档的方式,专业 Python 人的方式通常是在 `docs/` 添加 rst 文件( [reStructuredText][4] 的缩写)。因此 `docs/index.rst` 文件最终看起来像这样:
|
||||
|
||||
```
|
||||
Fibonacci
|
||||
=========
|
||||
|
||||
Are you annoyed at tech interviewers asking you to implement
|
||||
the Fibonacci sequence?
|
||||
Do you want to have some fun with them?
|
||||
A simple
|
||||
:code:`pip install fib`
|
||||
is all it takes to tell them to,
|
||||
um,
|
||||
fib off.
|
||||
|
||||
.. automodule:: fib
|
||||
:members:
|
||||
```
|
||||
|
||||
我们完成了,对吧?我们已经将文本放在了文件中。人们应该会看的。
|
||||
|
||||
### 使 Python 文档更漂亮
|
||||
|
||||
为了使你的文档看起来更漂亮,你可以利用 [Sphinx][5],它旨在制作漂亮的 Python 文档。这三个 Sphinx 扩展特别有用:
|
||||
|
||||
* `sphinx.ext.autodoc`:从模块内部获取文档
|
||||
* `sphinx.ext.napoleon`:支持 Google 样式的 docstring
|
||||
* `sphinx.ext.viewcode`:将 ReStructured Text 源码与生成的文档打包在一起
|
||||
|
||||
为了告诉 Sphinx 该生成什么以及如何生成,我们在 `docs/conf.py` 中配置一个辅助文件:
|
||||
|
||||
```
|
||||
extensions = [
|
||||
'sphinx.ext.autodoc',
|
||||
'sphinx.ext.napoleon',
|
||||
'sphinx.ext.viewcode',
|
||||
]
|
||||
# 该入口点的名称,没有 .rst 扩展名。
|
||||
# 惯例该名称是 index
|
||||
master_doc = "index"
|
||||
# 这些值全部用在生成的文档当中。
|
||||
# 通常,发布(release)与版本(version)是一样的,
|
||||
# 但是有时候我们会有带有 rc 标签的发布。
|
||||
project = "Fib"
|
||||
copyright = "2019, Moshe Zadka"
|
||||
author = "Moshe Zadka"
|
||||
version = release = "2019.1.0"
|
||||
```
|
||||
|
||||
此文件使我们可以使用所需的所有元数据来发布代码,并注意扩展名(上面的注释说明了方式)。最后,要确保生成我们想要的文档,请使用 [Tox][6] 管理虚拟环境以确保我们顺利生成文档:
|
||||
|
||||
```
|
||||
[tox]
|
||||
# 默认情况下,`.tox` 是该目录。
|
||||
# 将其放在非点文件中可以从
|
||||
# 文件管理器或浏览器的
|
||||
# 打开对话框中打开生成的文档,
|
||||
# 这些对话框有时会隐藏点文件。
|
||||
toxworkdir = {toxinidir}/build/tox
|
||||
|
||||
[testenv:docs]
|
||||
# 从 `docs` 目录内运行 `sphinx`,
|
||||
# 以确保它不会拾取任何可能进入顶层目录下的
|
||||
# 虚拟环境或 `build/` 目录下的其他工件的杂散文件。
|
||||
changedir = docs
|
||||
# 唯一的依赖关系是 `sphinx`。
|
||||
# 如果我们使用的是单独打包的扩展程序,
|
||||
# 我们将在此处指定它们。
|
||||
# 更好的做法是指定特定版本的 sphinx。
|
||||
deps =
|
||||
sphinx
|
||||
# 这是用于生成 HTML 的 `sphinx` 命令。
|
||||
# 在其他情况下,我们可能想生成 PDF 或电子书。
|
||||
commands =
|
||||
sphinx-build -W -b html -d {envtmpdir}/doctrees . {envtmpdir}/html
|
||||
# 我们使用 Python 3.7。
|
||||
# Tox 有时会根据 testenv 的名称尝试自动检测它,
|
||||
# 但是 `docs` 没有给出有用的线索,因此我们必须明确它。
|
||||
basepython = python3.7
|
||||
```
|
||||
|
||||
现在,无论何时运行 Tox,它都会为你的 Python 代码生成漂亮的文档。
|
||||
|
||||
### 在 Python 中写文档很好
|
||||
|
||||
作为 Python 开发人员,我们可以使用的工具链很棒。我们可以从 **docstring** 开始,添加 .rst 文件,然后添加 Sphinx 和 Tox 来为用户美化结果。
|
||||
|
||||
你对好的文档有何评价?你还有其他喜欢的方式么?请在评论中分享它们!
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/19/11/document-python-sphinx
|
||||
|
||||
作者:[Moshe Zadka][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/moshez
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/coffee_python.jpg?itok=G04cSvp_ (Python in a coffee cup.)
|
||||
[2]: https://pypi.org/
|
||||
[3]: http://google.github.io/styleguide/pyguide.html#381-docstrings
|
||||
[4]: http://docutils.sourceforge.net/rst.html
|
||||
[5]: http://www.sphinx-doc.org/en/master/
|
||||
[6]: https://tox.readthedocs.io/en/latest/
|
@ -0,0 +1,125 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (wxy)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11603-1.html)
|
||||
[#]: subject: (Zorin OS 15 Lite Release: Good Looking Lightweight Linux)
|
||||
[#]: via: (https://itsfoss.com/zorin-os-lite/)
|
||||
[#]: author: (Ankush Das https://itsfoss.com/author/ankush/)
|
||||
|
||||
Zorin OS 15 Lite 发布:好看的轻量级 Linux
|
||||
======
|
||||
|
||||
> Zorin OS 15 Lite 版刚刚发布。我们将向你展示此新版本的桌面体验,并向你重点展示其主要功能。
|
||||
|
||||
[Zorin OS][1] 是一款日益流行的 Linux 发行版。它基于 Ubuntu,因此,毫不奇怪,它也正是[适合初学者的最佳 Linux 发行版][2]之一。 类似 Windows 的界面是许多从 Windows 到 Linux 的迁移者偏爱它的主要原因之一。
|
||||
|
||||
Zorin OS 有两个主要变体:
|
||||
|
||||
* Zorin Core:它使用 GNOME 桌面,用于较新的机器。
|
||||
* Zorin Lite:它使用轻量级的 [Xfce 桌面][3],可以用作[老旧的笔记本电脑和计算机的 Linux][4]。
|
||||
|
||||
### Zorin OS 15 Lite:新特性
|
||||
|
||||
Zorin OS 15 Core 发布之后过了很久,Zorin OS 15 Lite 版终于出现了。你现在就可以使用免费的 Lite 版或付费的 Lite Ultimate 版。
|
||||
|
||||
我尝试了 Zorin OS 15 Lite Ultimate 版。在本文中,我将介绍此版本的详细信息以及在为你的计算机下载 Zorin OS 15 Lite 之前应了解的知识。
|
||||
|
||||
Zorin OS 15 Lite 与全面的 Zorin OS 15 版本基本差不多。你可以在我们的原来的报道中查看 [Zorin OS 15 的功能][6]。
|
||||
|
||||
此发行版重点关注资源,因此过去十年中任何类型的旧硬件配置都可以轻松地在其上运行。
|
||||
|
||||
![][7]
|
||||
|
||||
在此版本中,它们依靠基于 Xfce 4.14 的轻量级桌面环境在低规格计算机上提供了最佳体验。除了 Xfce 桌面环境外,与使用 GNOME 的完整版本相比,它还做了一些底层更改。
|
||||
|
||||
#### Zorin OS 15 Lite 是针对 Windows 7 用户的
|
||||
|
||||
![][8]
|
||||
|
||||
Zorin OS 15 Lite 主要针对 Windows 7 用户,因为对 Windows 7 的官方支持结束于今年 1 月。因此,如果你对 Windows 7 感到满意,可以尝试一下,切换到此版本应该是一种流畅的体验。
|
||||
|
||||
Zorin OS 15 Lite 允许你在 “Zorin 外观”设置中将布局切换为 macOS 风格/ Windows 风格的外观。
|
||||
|
||||
#### 32 位和 64 位支持
|
||||
|
||||
很高兴看到 Zorin OS 考虑到对 32 位/ 64 位 ISO 的支持,因为 Lite 版本是针对具有低规格硬件的用户的。
|
||||
|
||||
#### 默认启用 Flatpak 支持
|
||||
|
||||
![][9]
|
||||
|
||||
你可以使用软件中心利用 Flathub 来立即安装 Flatpak 软件包。如果你不确定该怎么做,请务必查看有关[使用 Flatpak][10]的指南。
|
||||
|
||||
除此之外,你已经拥有 Snap 软件包支持。因此,通过软件中心安装任何内容应该更容易。
|
||||
|
||||
#### 用户界面的印象
|
||||
|
||||
![][11]
|
||||
|
||||
老实说,默认的 Xfce 界面看起来很陈旧。有一些方法可以 [定制 Xfce][12],但是 Zorin 也可以开箱即用。定制外观给人以良好印象。它看起来非常整洁,可以按预期工作。
|
||||
|
||||
#### 性能
|
||||
|
||||
![][13]
|
||||
|
||||
即使我没有在超级老旧的系统上尝试过,但我也在老式硬盘上安装了它,它难以启动 Ubuntu 或类似发行版。
|
||||
|
||||
根据我的体验,我可以肯定该性能非常出色。感觉就好像我将其安装在 SSD 上。这显然是一件好事。如果你碰巧在超级老旧的系统上尝试使用它,可以在本文底部的评论部分中告诉我您的经验。
|
||||
|
||||
### Ultimate Lite 版和免费的 Lite 版有何区别?
|
||||
|
||||
![][14]
|
||||
|
||||
没错,你可以免费下载 Zorin OS 15。
|
||||
|
||||
但是,有一个单独的“终极版”(Ultimate),其基本目的是用来支持该项目及其开发者。除此之外,它还捆绑了许多预安装的软件,作为计算机的“最终”软件包。
|
||||
|
||||
因此,如果你购买 Ultimate 版,则可以访问 Lite 版和完整版。
|
||||
|
||||
如果你不想为此付费,仍然可以根据需要选择免费版本(Core、Lite、Education)。你可以在它们的[下载页面][15]上了解更多信息。
|
||||
|
||||
### 如何下载 Zorin OS 15 Lite?
|
||||
|
||||
你可以转到其[官方下载网页][15],然后向下滚动找到 Zorin OS 15 Lite 版。
|
||||
|
||||
你可以找到 32 位/ 64 位的 ISO,可以下载所需的 ISO。
|
||||
|
||||
- [Zorin OS 15 Lite] [15]
|
||||
|
||||
安装 Zorin OS 与安装 Ubuntu 类似。
|
||||
|
||||
### 总结
|
||||
|
||||
虽然 Zorin OS 15 作为向 Windows / macOS 老手提供的 Linux 发行版已经是一个不错的产品,但新的 Lite 版本肯定会吸引更多的眼球。
|
||||
|
||||
您是否尝试过 Lite 版?在下面的评论中让我知道你的想法。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://itsfoss.com/zorin-os-lite/
|
||||
|
||||
作者:[Ankush Das][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[wxy](https://github.com/wxy)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://itsfoss.com/author/ankush/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://zorinos.com/
|
||||
[2]: https://itsfoss.com/best-linux-beginners/
|
||||
[3]: https://www.xfce.org/
|
||||
[4]: https://itsfoss.com/lightweight-linux-beginners/
|
||||
[5]: https://www.youtube.com/c/itsfoss?sub_confirmation=1
|
||||
[6]: https://linux.cn/article-11058-1.html
|
||||
[7]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2019/11/file-explorer-zorin-os-15-lite.jpg?ssl=1
|
||||
[8]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2019/11/zorin-lite-ultimate-appearance.jpg?ssl=1
|
||||
[9]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2019/11/zorin-os-software.png?ssl=1
|
||||
[10]: https://itsfoss.com/flatpak-guide/
|
||||
[11]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2019/11/zorin-os-15-lite-appearance.jpg?ssl=1
|
||||
[12]: https://itsfoss.com/customize-xfce/
|
||||
[13]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2019/11/homescreen-zorin-os-15-lite.jpg?ssl=1
|
||||
[14]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2019/11/zorin-os-ultimate.jpg?ssl=1
|
||||
[15]: https://zorinos.com/download/
|
@ -0,0 +1,141 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (wxy)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11617-1.html)
|
||||
[#]: subject: (Bauh – Manage Snaps, Flatpaks and AppImages from One Interface)
|
||||
[#]: via: (https://itsfoss.com/bauh-package-manager/)
|
||||
[#]: author: (John Paul https://itsfoss.com/author/john/)
|
||||
|
||||
bauh:在一个界面中管理 Snap、Flatpak 和 AppImage
|
||||
======
|
||||
|
||||

|
||||
|
||||
[Snap][1]、[Flatpak][2] 和 [AppImage][3] 等通用软件包的最大问题之一就是管理它们。大多数内置的软件包管理器都不能全部支持这些新格式。
|
||||
|
||||
幸运的是,我偶然发现了一个支持这几种通用包格式的应用程序。
|
||||
|
||||
### bauh:多包装需求的管理器
|
||||
|
||||
[bauh][4](LCTT:我给该软件建议一个中文名:“包豪”)最初名为 fpakman,旨在处理 Flatpak、Snap、[AppImage][5] 和 [AUR][6] 软件包。创建者 [vinifmor][7] 在 2019 年 6 月启动了该项目,[意图][8]“为 Manjaro 用户提供管理 Flatpak 的图形界面”。此后,他扩展了该应用程序,以添加对基于 Debian 的系统的支持。
|
||||
|
||||
![Bauh About][9]
|
||||
|
||||
首次打开 bauh 时,它将扫描已安装的应用程序并检查更新。如果有任何需要更新的内容,它们将列在前面并居中。更新所有软件包后,你将看到已安装的软件包列表。你可以取消选择不需要更新的软件包,以防止其被更新。你也可以选择安装该应用程序的早期版本。
|
||||
|
||||
![With Bauh you can manage various types of packages from one application][10]
|
||||
|
||||
你也可以搜索应用程序。bauh 提供了有关已安装和已搜索软件包的详细信息。如果你对一种(或多种)软件包类型不感兴趣,则可以在设置中取消选择它们。
|
||||
|
||||
![Bauh Search][22]
|
||||
|
||||
![Bauh Package Info][13]
|
||||
|
||||
![Bauh Updating][19]
|
||||
|
||||
### 在你的 Linux 发行版上安装 bauh
|
||||
|
||||
让我们看看如何安装 bauh。
|
||||
|
||||
#### 基于 Arch 的发行版
|
||||
|
||||
如果你安装的是最近的 [Manjaro][11],则应该一切已经就绪。bauh 默认情况下已安装。如果你安装的是较早版本的 Manjaro(如我一样)或其他基于 Arch 的发行版,则可以在终端中输入以下内容从 [AUR][12] 中进行安装:
|
||||
|
||||
```
|
||||
sudo pacman -S bauh
|
||||
```
|
||||
|
||||
#### 基于 Debian/Ubuntu 的发行版
|
||||
|
||||
如果你拥有基于 Debian 或 Ubuntu 的 Linux 发行版,则可以使用 `pip` 安装 bauh。首先,请确保[在 Ubuntu 上安装了 pip][14]。
|
||||
|
||||
```
|
||||
sudo apt install python3-pip
|
||||
```
|
||||
|
||||
然后使用它来安装 bauh:
|
||||
|
||||
```
|
||||
pip3 install bauh
|
||||
```
|
||||
|
||||
但是,该软件的创建者建议[手动][15]安装它,以避免弄乱系统的库。
|
||||
|
||||
要手动安装 bauh,你必须先下载其[最新版本][16]。下载后,可以[使用图形工具][17]或 [unzip 命令][18]解压缩。接下来,在终端中打开该文件夹。你将需要使用以下步骤来完成安装。
|
||||
|
||||
首先,在名为 `env` 的文件夹中创建一个虚拟环境:
|
||||
|
||||
```
|
||||
python3 -m venv env
|
||||
```
|
||||
|
||||
现在在该环境中安装该应用程序的代码:
|
||||
|
||||
```
|
||||
env/bin/pip install .
|
||||
```
|
||||
|
||||
启动该应用程序:
|
||||
|
||||
```
|
||||
env/bin/bauh
|
||||
```
|
||||
|
||||
一旦完成了 bauh 的安装,就可以通过更改环境设置和参数来对其进行[微调][20]。
|
||||
|
||||
### bauh 的未来之路
|
||||
|
||||
bauh 在短短的几个月中增长了很多。它有计划继续增长。当前的[路线图][21]包括:
|
||||
|
||||
* 支持其他打包技术
|
||||
* 每种打包技术一个单独模块
|
||||
* 内存和性能改进
|
||||
* 改善用户体验
|
||||
|
||||
### 结语
|
||||
|
||||
当我尝试 bauh 时,遇到了两个问题。当我第一次打开它时,它告诉我尚未安装 Snap,如果要使用 Snap 软件包,则必须安装它。我知道我已经安装了 Snap,因为我在终端中运行了 `snap list`,并且可以正常工作。我重新启动系统,Snap 才工作正常。
|
||||
|
||||
我遇到的另一个问题是我的一个 AUR 软件包无法更新。我可以用 `yay` 更新软件包,而没有任何问题。可能是我的 Manjaro 有问题,我已经使用了它 3 到 4 年。
|
||||
|
||||
总体而言,bauh 可以工作。它做到了宣称的功能。我不能要求更多。
|
||||
|
||||
你有没有用过 hauh?如果有的话,你最喜欢的用于管理不同打包格式的工具是什么?在下面的评论中让我们知道。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://itsfoss.com/bauh-package-manager/
|
||||
|
||||
作者:[John Paul][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[wxy](https://github.com/wxy)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://itsfoss.com/author/john/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://snapcraft.io/
|
||||
[2]: https://flatpak.org/
|
||||
[3]: https://appimage.org/
|
||||
[4]: https://github.com/vinifmor/bauh
|
||||
[5]: https://itsfoss.com/use-appimage-linux/
|
||||
[6]: https://itsfoss.com/best-aur-helpers/
|
||||
[7]: https://github.com/vinifmor
|
||||
[8]: https://forum.manjaro.org/t/bauh-formerly-known-as-fpakman-a-gui-for-flatpak-and-snap-management/96180
|
||||
[9]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2019/11/bauh-about.jpg?ssl=1
|
||||
[10]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2019/11/bauh.jpg?ssl=1
|
||||
[11]: https://manjaro.org/
|
||||
[12]: https://aur.archlinux.org/packages/bauh
|
||||
[13]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2019/11/bauh-package-info.jpg?ssl=1
|
||||
[14]: https://itsfoss.com/install-pip-ubuntu/
|
||||
[15]: https://github.com/vinifmor/bauh#manual-installation
|
||||
[16]: https://github.com/vinifmor/bauh/releases
|
||||
[17]: https://itsfoss.com/unzip-linux/
|
||||
[18]: https://linuxhandbook.com/unzip-command/
|
||||
[19]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2019/11/bauh-updating.jpg?ssl=1
|
||||
[20]: https://github.com/vinifmor/bauh#general-settings
|
||||
[21]: https://github.com/vinifmor/bauh#roadmap
|
||||
[22]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2019/11/bauh-search.png?resize=800%2C319&ssl=1
|
||||
[23]: https://reddit.com/r/linuxusersgroup
|
@ -0,0 +1,82 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (wxy)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11616-1.html)
|
||||
[#]: subject: (Google to Add Mainline Linux Kernel Support to Android)
|
||||
[#]: via: (https://itsfoss.com/mainline-linux-kernel-android/)
|
||||
[#]: author: (John Paul https://itsfoss.com/author/john/)
|
||||
|
||||
谷歌为安卓添加主线 Linux 内核支持
|
||||
======
|
||||
|
||||
当前的安卓生态系统被数百种不同版本的安卓所污染,每种版本都运行着 Linux 内核的不同变体。每个版本均针对不同的手机和不同的配置而设计。谷歌试图通过将主线 Linux 内核添加到安卓来解决该问题。
|
||||
|
||||
### 当前在安卓中是如何处理 Linux 内核的
|
||||
|
||||
在到达你的手机之前,你手机上的 Linux 内核经历了[三个主要步骤][1]。
|
||||
|
||||
首先,谷歌采用了 Linux 内核的 LTS(长期支持)版本,并添加了所有的安卓专用代码。这将成为“安卓通用内核”。
|
||||
|
||||
然后,谷歌将此代码发送给创建可运行在手机的片上系统(SoC)的公司。这通常是高通公司。
|
||||
|
||||
SoC 制造商添加了支持 CPU 和其他芯片的代码后,便会将该内核传递给实际的设备制造商,例如三星和摩托罗拉。然后,设备制造商添加代码以支持手机的其余部分,例如显示屏和摄像头。
|
||||
|
||||
每个步骤都需要一段时间才能完成,并且会导致该内核无法与其他任何设备一起使用。这也意味着内核会非常旧,通常是大约两年前的内核。例如,上个月交付的谷歌 Pixel 4 带有来自 2017 年 11 月的内核,而且它将永远不会得到更新。
|
||||
|
||||
谷歌承诺会为较旧的设备创建安全补丁,这意味着他们会一直盯着大量的旧代码。
|
||||
|
||||
### 将来
|
||||
|
||||
![][2]
|
||||
|
||||
去年,谷歌宣布[计划][3]解决此问题。今年,他们在 2019 Linux Plumbers Conference 上展示了他们取得的进展。
|
||||
|
||||
> “我们知道运行安卓需要什么,但不一定是在任何给定的硬件上。因此,我们的目标是从根本上找出所有这些,然后将其交给上游,并尝试尽可能接近主线。”
|
||||
>
|
||||
> Sandeep Patil,[安卓内核团队负责人][1]
|
||||
|
||||
他们确实炫耀了运行带有合适的 Linux 内核的小米 Poco F1。但是,有些东西[似乎没有工作][4],例如电池电量百分比一直留在 0%。
|
||||
|
||||
那么,谷歌计划如何使其工作呢?从他们的 [Treble 项目][5]计划中摘录。在 Treble 项目之前,与设备和安卓本身交互的底层代码是一大堆代码。Treble 项目将两者分开,并使它们模块化,以便可以更快地交付安卓更新,并且在更新时,这些低级代码可以保持不变。
|
||||
|
||||
谷歌希望为内核带来同样的模块化。他们的[计划][1]“涉及稳定 Linux 的内核 ABI,并为 Linux 内核和硬件供应商提供稳定的接口来进行写入。谷歌希望将 Linux 内核与其硬件支持脱钩。”
|
||||
|
||||
因此,这意味着谷歌将交付一个内核,而硬件驱动程序将作为内核模块加载。目前,这只是一个草案。仍然有很多技术问题有待解决。因此,这不会很快有结果。
|
||||
|
||||
### 来自开源的反对意见
|
||||
|
||||
开源社区不会对将专有代码放入内核的想法感到满意。[Linux 内核准则][6]指出,驱动程序必须具有 GPL 许可证才能包含在内核中。他们还指出,如果驱动程序的更改导致错误,应由导致该错误的人来解决。从长远来看,这意味着设备制造商的工作量将减少。
|
||||
|
||||
### 关于将主线内核包含到安卓中的最终想法
|
||||
|
||||
到目前为止,这只是一个草案。谷歌有很大的可能会开始进行该项目,除非他们意识到这将需要多少工作后才会放弃。看看谷歌[已经放弃][7]了多少个项目!
|
||||
|
||||
[Android Police][4] 指出谷歌正在开发其 [Fuchsia 操作系统][8],这似乎是为了有一天取代安卓。
|
||||
|
||||
那么,问题是谷歌会尝试完成那些艰巨的任务,使安卓以主线 Linux 内核运行,还是完成他们统一的安卓替代产品的工作?只有时间可以回答。
|
||||
|
||||
你对此话题有何看法?请在下面的评论中告诉我们。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://itsfoss.com/mainline-linux-kernel-android/
|
||||
|
||||
作者:[John Paul][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[wxy](https://github.com/wxy)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://itsfoss.com/author/john/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://arstechnica.com/gadgets/2019/11/google-outlines-plans-for-mainline-linux-kernel-support-in-android/
|
||||
[2]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2019/11/mainline_linux_kernel_android.png?ssl=1
|
||||
[3]: https://lwn.net/Articles/771974/
|
||||
[4]: https://www.androidpolice.com/2019/11/19/google-wants-android-to-use-regular-linux-kernel-potentially-improving-updates-and-security/
|
||||
[5]: https://www.computerworld.com/article/3306443/what-is-project-treble-android-upgrade-fix-explained.html
|
||||
[6]: https://www.kernel.org/doc/Documentation/process/stable-api-nonsense.rst
|
||||
[7]: https://killedbygoogle.com/
|
||||
[8]: https://itsfoss.com/fuchsia-os-what-you-need-to-know/
|
||||
[9]: https://reddit.com/r/linuxusersgroup
|
168
published/201911/20191127 Displaying dates and times your way.md
Normal file
168
published/201911/20191127 Displaying dates and times your way.md
Normal file
@ -0,0 +1,168 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (wxy)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11623-1.html)
|
||||
[#]: subject: (Displaying dates and times your way)
|
||||
[#]: via: (https://www.networkworld.com/article/3481602/displaying-dates-and-times-your-way-with-linux.html)
|
||||
[#]: author: (Sandra Henry-Stocker https://www.networkworld.com/author/Sandra-Henry_Stocker/)
|
||||
|
||||
在终端里按你的方式显示日期和时间
|
||||
======
|
||||
|
||||
> Linux 的 date 命令提供了很多显示日期和时间的选项,要比你想的还要多。这是一些有用的选择。
|
||||
|
||||

|
||||
|
||||
在 Linux 系统上,`date` 命令非常简单。你键入 `date`,日期和时间将以一种有用的方式显示。它包括星期几、日期、时间和时区:
|
||||
|
||||
```
|
||||
$ date
|
||||
Tue 26 Nov 2019 11:45:11 AM EST
|
||||
```
|
||||
|
||||
只要你的系统配置正确,你就会看到日期和当前时间以及时区。
|
||||
|
||||
但是,该命令还提供了许多选项来以不同方式显示日期和时间信息。例如,如果要显示日期以便进行排序,则可能需要使用如下命令:
|
||||
|
||||
```
|
||||
$ date "+%Y-%m-%d"
|
||||
2019-11-26
|
||||
```
|
||||
|
||||
在这种情况下,年、月和日按该顺序排列。请注意,我们使用大写字母 `Y` 来获得四位数的年份。如果我们使用小写的 `y`,则只会看到两位数字的年份(例如 19)。不要让这种做法使你错误地联想到如果 `%m` 给你一个数字月份,`%M` 可能会给你月份的名称。不,`%M` 将给你分钟数。要以缩写名称格式获得月份,你要使用 `%b`,而对于完全拼写的月份,则要使用 `%B`。
|
||||
|
||||
```
|
||||
$ date "+%b %B"
|
||||
Nov November
|
||||
```
|
||||
|
||||
或者,你可能希望以这种常用格式显示日期:
|
||||
|
||||
```
|
||||
$ date "+%D"
|
||||
11/26/19
|
||||
```
|
||||
|
||||
如果你需要四位数的年份,则可以执行以下操作:
|
||||
|
||||
```
|
||||
$ date "+%x"
|
||||
11/26/2019
|
||||
```
|
||||
|
||||
下面是一个可能有用的示例。假设你需要创建一个每日报告并在文件名中包含日期,则可以使用以下命令来创建文件(可能用在脚本中):
|
||||
|
||||
```
|
||||
$ touch Report-`date "+%Y-%m-%d"`
|
||||
```
|
||||
|
||||
当你列出你的报告时,它们将按日期顺序或反向日期顺序(如果你添加 `-r`)列出。
|
||||
|
||||
```
|
||||
$ ls -r Report*
|
||||
Report-2019-11-26
|
||||
Report-2019-11-25
|
||||
Report-2019-11-22
|
||||
Report-2019-11-21
|
||||
Report-2019-11-20
|
||||
```
|
||||
|
||||
你还可以在日期字符串中添加其他详细信息。可用的各种选项多得令人惊讶。你可以使用 `date "+%q"` 来显示你所在的一年中的哪个季度,或使用类似以下命令来显示两个月前的日期:
|
||||
|
||||
```
|
||||
$ date --date="2 months ago"
|
||||
Thu 26 Sep 2019 09:02:43 AM EDT
|
||||
```
|
||||
|
||||
是否想知道下周四的日期?你可以使用类似 `date --date="next thu"` 的命令,但是要理解,对于Linux,下个周四意味着今天之后的周四。如果今天是星期三,那就是明天,而不是下周的星期四。但是,你可以像下面的第二个命令一样指定下周的星期四。
|
||||
|
||||
```
|
||||
$ date --date="next thu"
|
||||
Thu 28 Nov 2019 12:00:00 AM EST
|
||||
$ date --date="next week thu"
|
||||
Thu 05 Dec 2019 12:00:00 AM EST
|
||||
```
|
||||
|
||||
`date` 命令的手册页列出了其所有选项。该列表多得令人难以置信,但是你可能会发现一些日期/时间显示选项非常适合你。以下是一些你可能会发现有趣的东西。
|
||||
|
||||
世界标准时间(UTC):
|
||||
|
||||
```
|
||||
$ date -u
|
||||
Tue 26 Nov 2019 01:13:59 PM UTC
|
||||
```
|
||||
|
||||
自 1970 年 1 月 1 日以来的秒数(与 Linux 系统上日期的存储方式有关):
|
||||
|
||||
```
|
||||
$ date +%s
|
||||
1574774137
|
||||
```
|
||||
|
||||
以下是 `date` 命令选项的完整列表。正如我所说,它比我们大多数人想象的要广泛得多。
|
||||
|
||||
- `%%` 显示字母 %
|
||||
- `%a` 本地语言环境的缩写星期名称(例如,日 / Sun)
|
||||
- `%A` 本地语言环境的完整星期名称(例如,星期日 / Sunday)
|
||||
- `%b` 本地语言环境的缩写月份名称(例如 一 / Jan)
|
||||
- `%B` 本地语言环境的完整月份名称(例如,一月 / January)
|
||||
- `%c` 本地语言环境的日期和时间(例如 2005年3月3日 星期四 23:05:25 / Thu Mar 3 23:05:25 2005)
|
||||
- `%C` 世纪;类似于 `%Y`,但省略了后两位数字(例如,20)
|
||||
- `%d` 月份的天(例如,01)
|
||||
- `%D` 日期;与 `%m/%d/%y` 相同
|
||||
- `%e` 月份的天,填充前缀空格;与 `%_d` 相同
|
||||
- `%F` 完整日期;与 `%Y-%m-%d` 相同
|
||||
- `%g` ISO 周号的年份的后两位数字(请参见 `%G`)
|
||||
- `%G` ISO 周号的年份(请参阅 `%V`);通常仅配合 `%V` 使用
|
||||
- `%h` 与 `%b` 相同
|
||||
- `%H` 24 小时制的小时(00..23)
|
||||
- `%I` 12 小时制的小时(01..12)
|
||||
- `%j` 一年的天(001..366)
|
||||
- `%k` 24 小时制的小时,填充前缀空格( 0..23);与 `%_H` 相同
|
||||
- `%l` 12 小时制的小时,填充前缀空格( 1..12);与 `%_I` 相同
|
||||
- `%m` 月份(01..12)
|
||||
- `%M` 分钟(00..59)
|
||||
- `%n` 换行符
|
||||
- `%N` 纳秒(000000000..999999999)
|
||||
- `%p` 本地语言环境中等同于 AM 或 PM 的字符串;如果未知,则为空白
|
||||
- `%P` 像 `%p`,但使用小写
|
||||
- `%q` 季度(1..4)
|
||||
- `%r` 本地语言环境的 12 小时制时间(例如,晚上 11:11:04 / 11:11:04 PM)
|
||||
- `%R` 24 小时制的小时和分钟;与 `%H:%M` 相同
|
||||
- `%s` 自 1970-01-01 00:00:00 UTC 以来的秒数
|
||||
- `%S` 秒(00..60)
|
||||
- `%t` 制表符
|
||||
- `%T` 时间;与 `%H:%M:%S` 相同
|
||||
- `%u` 星期(1..7);1 是星期一
|
||||
- `%U` 年的周号,以星期日为一周的第一天,从 00 开始(00..53)
|
||||
- `%V` ISO 周号,以星期一为一周的第一天,从 01 开始(01..53)
|
||||
- `%w` 星期(0..6);0 是星期日
|
||||
- `%W` 年的周号,星期一为一周的第一天,从 00 开始(00..53)
|
||||
- `%x` 本地语言环境的日期表示形式(例如,1999年12月31日 / 12/31/99)
|
||||
- `%X` 本地语言环境的时间表示形式(例如,23:13:48)
|
||||
- `%y` 年的最后两位数字(00..99)
|
||||
- `%Y` 年份
|
||||
- `%z` +hhmm 格式的数字时区(例如,-0400)
|
||||
- `%:z` +hh:mm 格式的数字时区(例如,-04:00)
|
||||
- `%::z` +hh:mm:ss 格式的数字时区(例如,-04:00:00)
|
||||
- `%:::z` 数字时区,`:` 指明精度(例如,-04, +05:30)
|
||||
- `%Z` 字母时区缩写(例如,EDT)
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.networkworld.com/article/3481602/displaying-dates-and-times-your-way-with-linux.html
|
||||
|
||||
作者:[Sandra Henry-Stocker][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[wxy](https://github.com/wxy)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://www.networkworld.com/author/Sandra-Henry_Stocker/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://www.networkworld.com/newsletters/signup.html
|
||||
[2]: 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)
|
||||
[3]: https://www.facebook.com/NetworkWorld/
|
||||
[4]: https://www.linkedin.com/company/network-world
|
@ -0,0 +1,242 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (wxy)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11684-1.html)
|
||||
[#]: subject: (Awk one-liners and scripts to help you sort text files)
|
||||
[#]: via: (https://opensource.com/article/19/11/how-sort-awk)
|
||||
[#]: author: (Seth Kenlon https://opensource.com/users/seth)
|
||||
|
||||
帮助你排序文本文件的 Awk 命令行或脚本
|
||||
======
|
||||
|
||||
> Awk 是一个强大的工具,可以执行某些可能由其它常见实用程序(包括 `sort`)来完成的任务。
|
||||
|
||||

|
||||
|
||||
Awk 是个普遍存在的 Unix 命令,用于扫描和处理包含可预测模式的文本。但是,由于它具有函数功能,因此也可以合理地称之为编程语言。
|
||||
|
||||
令人困惑的是,有不止一个 awk。(或者,如果你认为只有一个,那么其它几个就是克隆。)有 `awk`(由Aho、Weinberger 和 Kernighan 编写的原始程序),然后有 `nawk` 、`mawk` 和 GNU 版本的 `gawk`。GNU 版本的 awk 是该实用程序的一个高度可移植的自由软件版本,具有几个独特的功能,因此本文是关于 GNU awk 的。
|
||||
|
||||
虽然它的正式名称是 `gawk`,但在 GNU+Linux 系统上,它的别名是 `awk`,并用作该命令的默认版本。 在其他没有带有 GNU awk 的系统上,你必须先安装它并将其称为 `gawk`,而不是 `awk`。本文互换使用术语 `awk` 和 `gawk`。
|
||||
|
||||
`awk` 既是命令语言又是编程语言,这使其成为一个强大的工具,可以处理原本留给 `sort`、`cut`、`uniq` 和其他常见实用程序的任务。幸运的是,开源中有很多冗余空间,因此,如果你面临是否使用 `awk` 的问题,答案可能是肯定的“随便”。
|
||||
|
||||
`awk` 的灵活之美在于,如果你已经确定使用 `awk` 来完成一项任务,那么无论接下来发生什么,你都可以继续使用 `awk`。这包括对数据排序而不是按交付给你的顺序的永恒需求。
|
||||
|
||||
### 样本数据集
|
||||
|
||||
在探索 `awk` 的排序方法之前,请生成要使用的样本数据集。保持简单,这样你就不会为极端情况和意想不到的复杂性所困扰。这是本文使用的样本集:
|
||||
|
||||
```
|
||||
Aptenodytes;forsteri;Miller,JF;1778;Emperor
|
||||
Pygoscelis;papua;Wagler;1832;Gentoo
|
||||
Eudyptula;minor;Bonaparte;1867;Little Blue
|
||||
Spheniscus;demersus;Brisson;1760;African
|
||||
Megadyptes;antipodes;Milne-Edwards;1880;Yellow-eyed
|
||||
Eudyptes;chrysocome;Viellot;1816;Sothern Rockhopper
|
||||
Torvaldis;linux;Ewing,L;1996;Tux
|
||||
```
|
||||
|
||||
这是一个很小的数据集,但它提供了多种数据类型:
|
||||
|
||||
* 属名和种名,彼此相关但又是分开的
|
||||
* 姓,有时是以逗号开头的首字母缩写
|
||||
* 代表日期的整数
|
||||
* 任意术语
|
||||
* 所有字段均以分号分隔
|
||||
|
||||
根据你的教育背景,你可能会认为这是二维数组或表格,或者只是行分隔的数据集合。你如何看待它只是你的问题,而 `awk` 只认识文本。由你决定告诉 `awk` 你想如何解析它。
|
||||
|
||||
### 只想排序
|
||||
|
||||
如果你只想按特定的可定义字段(例如电子表格中的“单元格”)对文本数据集进行排序,则可以使用 [sort 命令][2]。
|
||||
|
||||
### 字段和记录
|
||||
|
||||
无论输入的格式如何,都必须在其中找到模式才可以专注于对你重要的数据部分。在此示例中,数据由两个因素定界:行和字段。每行都代表一个新的*记录*,就如你在电子表格或数据库转储中看到的一样。在每一行中,都有用分号(`;`)分隔的不同的*字段*(将其视为电子表格中的单元格)。
|
||||
|
||||
`awk` 一次只处理一条记录,因此,当你在构造发给 `awk` 的这指令时,你可以只关注一行记录。写下你想对一行数据执行的操作,然后在下一行进行测试(无论是心理上还是用 `awk` 进行测试),然后再进行其它的一些测试。最后,你要对你的 `awk` 脚本要处理的数据做好假设,以便可以按你要的数据结构提供给你数据。
|
||||
|
||||
在这个例子中,很容易看到每个字段都用分号隔开。为简单起见,假设你要按每行的第一字段对列表进行排序。
|
||||
|
||||
在进行排序之前,你必须能够让 `awk` 只关注在每行的第一个字段上,因此这是第一步。终端中 awk 命令的语法为 `awk`,后跟相关选项,最后是要处理的数据文件。
|
||||
|
||||
```
|
||||
$ awk --field-separator=";" '{print $1;}' penguins.list
|
||||
Aptenodytes
|
||||
Pygoscelis
|
||||
Eudyptula
|
||||
Spheniscus
|
||||
Megadyptes
|
||||
Eudyptes
|
||||
Torvaldis
|
||||
```
|
||||
|
||||
因为字段分隔符是对 Bash shell 具有特殊含义的字符,所以必须将分号括在引号中或在其前面加上反斜杠。此命令仅用于证明你可以专注于特定字段。你可以使用另一个字段的编号尝试相同的命令,以查看数据的另一个“列”的内容:
|
||||
|
||||
```
|
||||
$ awk --field-separator=";" '{print $3;}' penguins.list
|
||||
Miller,JF
|
||||
Wagler
|
||||
Bonaparte
|
||||
Brisson
|
||||
Milne-Edwards
|
||||
Viellot
|
||||
Ewing,L
|
||||
```
|
||||
|
||||
我们尚未进行任何排序,但这是良好的基础。
|
||||
|
||||
### 脚本编程
|
||||
|
||||
`awk` 不仅仅是命令,它是一种具有索引、数组和函数的编程语言。这很重要,因为这意味着你可以获取要排序的字段列表,将列表存储在内存中,进行处理,然后打印结果数据。对于诸如此类的一系列复杂操作,在文本文件中进行操作会更容易,因此请创建一个名为 `sort.awk` 的新文件并输入以下文本:
|
||||
|
||||
```
|
||||
#!/bin/gawk -f
|
||||
|
||||
BEGIN {
|
||||
FS=";";
|
||||
}
|
||||
```
|
||||
|
||||
这会将该文件建立为 `awk` 脚本,该脚本中包含执行的行。
|
||||
|
||||
`BEGIN` 语句是 `awk` 提供的特殊设置功能,用于只需要执行一次的任务。定义内置变量 `FS`,它代表<ruby>字段分隔符<rt>field separator</rt></ruby>,并且与你在 `awk` 命令中使用 `--field-separator` 设置的值相同,它只需执行一次,因此它包含在 `BEGIN` 语句中。
|
||||
|
||||
#### awk 中的数组
|
||||
|
||||
你已经知道如何通过使用 `$` 符号和字段编号来收集特定字段的值,但是在这种情况下,你需要将其存储在数组中而不是将其打印到终端。这是通过 `awk` 数组完成的。`awk` 数组的重要之处在于它包含键和值。 想象一下有关本文的内容;它看起来像这样:`author:"seth",title:"How to sort with awk",length:1200`。诸如作者、标题和长度之类的元素是键,跟着的内容为值。
|
||||
|
||||
在排序的上下文中这样做的好处是,你可以将任何字段分配为键,将任何记录分配为值,然后使用内置的 `awk` 函数 `asorti()`(按索引排序)按键进行排序。现在,随便假设你*只*想按第二个字段排序。
|
||||
|
||||
*没有*被特殊关键字 `BEGIN` 或 `END` 引起来的 `awk` 语句是在每个记录都要执行的循环。这是脚本的一部分,该脚本扫描数据中的模式并进行相应的处理。每次 `awk` 将注意力转移到一条记录上时,都会执行 `{}` 中的语句(除非以 `BEGIN` 或 `END` 开头)。
|
||||
|
||||
要将键和值添加到数组,请创建一个包含数组的变量(在本示例脚本中,我将其称为 `ARRAY`,虽然不是很原汁原味,但很清楚),然后在方括号中分配给它键,用等号(`=`)连接值。
|
||||
|
||||
```
|
||||
{ # dump each field into an array
|
||||
ARRAY[$2] = $R;
|
||||
}
|
||||
```
|
||||
|
||||
在此语句中,第二个字段的内容(`$2`)用作关键字,而当前记录(`$R`)用作值。
|
||||
|
||||
### asorti() 函数
|
||||
|
||||
除了数组之外,`awk` 还具有一些基本函数,你可以将它们用作常见任务的快速简便的解决方案。GNU awk中引入的函数之一 `asorti()` 提供了按键(*索引*)或值对数组进行排序的功能。
|
||||
|
||||
你只能在对数组进行填充后对其进行排序,这意味着此操作不能对每个新记录都触发,而只能在脚本的最后阶段进行。为此,`awk` 提供了特殊的 `END` 关键字。与 `BEGIN` 相反,`END` 语句仅在扫描了所有记录之后才触发一次。
|
||||
|
||||
将这些添加到你的脚本:
|
||||
|
||||
```
|
||||
END {
|
||||
asorti(ARRAY,SARRAY);
|
||||
# get length
|
||||
j = length(SARRAY);
|
||||
|
||||
for (i = 1; i <= j; i++) {
|
||||
printf("%s %s\n", SARRAY[i],ARRAY[SARRAY[i]])
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
`asorti()` 函数获取 `ARRAY` 的内容,按索引对其进行排序,然后将结果放入名为 `SARRAY` 的新数组(我在本文中发明的任意名称,表示“排序的 ARRAY”)。
|
||||
|
||||
接下来,将变量 `j`(另一个任意名称)分配给 `length()` 函数的结果,该函数计算 `SARRAY` 中的项数。
|
||||
|
||||
最后,使用 `for` 循环使用 `printf()` 函数遍历 `SARRAY` 中的每一项,以打印每个键,然后在 `ARRAY` 中打印该键的相应值。
|
||||
|
||||
### 运行该脚本
|
||||
|
||||
要运行你的 `awk` 脚本,先使其可执行:
|
||||
|
||||
```
|
||||
$ chmod +x sorter.awk
|
||||
```
|
||||
|
||||
然后针对 `penguin.list` 示例数据运行它:
|
||||
|
||||
```
|
||||
$ ./sorter.awk penguins.list
|
||||
antipodes Megadyptes;antipodes;Milne-Edwards;1880;Yellow-eyed
|
||||
chrysocome Eudyptes;chrysocome;Viellot;1816;Sothern Rockhopper
|
||||
demersus Spheniscus;demersus;Brisson;1760;African
|
||||
forsteri Aptenodytes;forsteri;Miller,JF;1778;Emperor
|
||||
linux Torvaldis;linux;Ewing,L;1996;Tux
|
||||
minor Eudyptula;minor;Bonaparte;1867;Little Blue
|
||||
papua Pygoscelis;papua;Wagler;1832;Gentoo
|
||||
```
|
||||
|
||||
如你所见,数据按第二个字段排序。
|
||||
|
||||
这有点限制。最好可以在运行时灵活选择要用作排序键的字段,以便可以在任何数据集上使用此脚本并获得有意义的结果。
|
||||
|
||||
### 添加命令选项
|
||||
|
||||
你可以通过在脚本中使用字面值 `var` 将命令变量添加到 `awk` 脚本中。更改脚本,以使迭代子句在创建数组时使用 `var`:
|
||||
|
||||
```
|
||||
{ # dump each field into an array
|
||||
ARRAY[$var] = $R;
|
||||
}
|
||||
```
|
||||
|
||||
尝试运行该脚本,以便在执行脚本时使用 `-v var` 选项将其按第三字段排序:
|
||||
|
||||
```
|
||||
$ ./sorter.awk -v var=3 penguins.list
|
||||
Bonaparte Eudyptula;minor;Bonaparte;1867;Little Blue
|
||||
Brisson Spheniscus;demersus;Brisson;1760;African
|
||||
Ewing,L Torvaldis;linux;Ewing,L;1996;Tux
|
||||
Miller,JF Aptenodytes;forsteri;Miller,JF;1778;Emperor
|
||||
Milne-Edwards Megadyptes;antipodes;Milne-Edwards;1880;Yellow-eyed
|
||||
Viellot Eudyptes;chrysocome;Viellot;1816;Sothern Rockhopper
|
||||
Wagler Pygoscelis;papua;Wagler;1832;Gentoo
|
||||
```
|
||||
|
||||
### 修正
|
||||
|
||||
本文演示了如何在纯 GNU awk 中对数据进行排序。你可以对脚本进行改进,以便对你有用,花一些时间在`gawk` 的手册页上研究 [awk 函数][3]并自定义脚本以获得更好的输出。
|
||||
|
||||
这是到目前为止的完整脚本:
|
||||
|
||||
```
|
||||
#!/usr/bin/awk -f
|
||||
# GPLv3 appears here
|
||||
# usage: ./sorter.awk -v var=NUM FILE
|
||||
|
||||
BEGIN { FS=";"; }
|
||||
|
||||
{ # dump each field into an array
|
||||
ARRAY[$var] = $R;
|
||||
}
|
||||
|
||||
END {
|
||||
asorti(ARRAY,SARRAY);
|
||||
# get length
|
||||
j = length(SARRAY);
|
||||
|
||||
for (i = 1; i <= j; i++) {
|
||||
printf("%s %s\n", SARRAY[i],ARRAY[SARRAY[i]])
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/19/11/how-sort-awk
|
||||
|
||||
作者:[Seth Kenlon][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[wxy](https://github.com/wxy)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [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/metrics_lead-steps-measure.png?itok=DG7rFZPk (Green graph of measurements)
|
||||
[2]: https://opensource.com/article/19/10/get-sorted-sort
|
||||
[3]: https://www.gnu.org/software/gawk/manual/html_node/Built_002din.html#Built_002din
|
85
published/20191113 Edit images on Fedora easily with GIMP.md
Normal file
85
published/20191113 Edit images on Fedora easily with GIMP.md
Normal file
@ -0,0 +1,85 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (robsean)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11632-1.html)
|
||||
[#]: subject: (Edit images on Fedora easily with GIMP)
|
||||
[#]: via: (https://fedoramagazine.org/edit-images-on-fedora-easily-with-gimp/)
|
||||
[#]: author: (Mehdi Haghgoo https://fedoramagazine.org/author/powergame/)
|
||||
|
||||
在 Fedora 上使用 GIMP 轻松编辑图像
|
||||
======
|
||||
|
||||
![][1]
|
||||
|
||||
GIMP(GNU Image Manipulation Program 的缩写)是自由开源的图像处理软件。它有很多的功能,从简单的图像编辑,到复杂的滤镜、脚本,甚至是动画,它是流行的商业同类软件的一款很好的替代品。
|
||||
|
||||
继续阅读来学习如何在 Fedora 上安装和使用 GIMP。这篇文章涉及基本的日常图像编辑工作。
|
||||
|
||||
### 安装 GIMP
|
||||
|
||||
GIMP 在官方 Fedora 存储库中可获得。为安装它,运行:
|
||||
|
||||
```
|
||||
sudo dnf install gimp
|
||||
```
|
||||
|
||||
### 单窗口模式
|
||||
|
||||
在你打开应用程序后,它显示带有工具箱和主编辑区的暗色主题窗口。注意,它有两种窗口模式,你可以通过选择“<ruby>窗口<rt>Windows</rt></ruby> -> <ruby>单窗口模式<rt>Single Window Mode</rt></ruby>”在其中切换。通过选中这个选项,用户界面的所有组件将显示在单个窗口中。否则,它们将是分离的。
|
||||
|
||||
### 加载图像
|
||||
|
||||
![][2]
|
||||
|
||||
为加载图像,转到“<ruby>文件<rt>File</rt></ruby> -> <ruby>打开<rt>Open</rt></ruby>”,然后选择你的文件并选择你的图像文件。
|
||||
|
||||
### 重新调整一个图像的大小
|
||||
|
||||
为重新调整图像大小,你可以基于一对参数重新调整大小,包括像素和百分比 —— 在编辑图像时,这两个参数很方便。
|
||||
|
||||
让我们假使我们需要缩小 Fedora 30 背景图像到它当前大小的 75%。为此,选择“<ruby>图像<rt> Image</rt></ruby> -> <ruby>比例<rt>Scale</rt></ruby>”,然后在比例对话框上,在单位下拉列表中选择“<ruby>百分比<rt>percentage</rt></ruby>”。接下来,输入 “75” 作为宽度或高度,然后按 Tab 键。默认情况下,其它尺寸将自动地调整大小,以相应地与更改的尺寸保持纵横比。现在,保存其它选项不变,并按比例。
|
||||
|
||||
![][3]
|
||||
|
||||
该图像缩小到其原始尺寸的 75%。
|
||||
|
||||
### 旋转图像
|
||||
|
||||
旋转是一种变换操作,因此,你可以从主菜单下的“<ruby>图像<rt>Image</rt></ruby> -> <ruby>变换<rt>Transform</rt></ruby>”下找到它,其中有图像旋转 90° 或 180° 的选项。在上述选项下也有垂直或水平翻转图像的选项。
|
||||
|
||||
让我们假使我们需要旋转图像 90°。在应用一次 90° 顺时针旋转和水平翻转后,我们的图像将看起来像这样:
|
||||
|
||||
![Transforming an image with GIMP][4]
|
||||
|
||||
### 添加文本
|
||||
|
||||
添加文本非常简单。只需要从工具箱中选择 “A” 图标,然后,在你的图像上,单击你想要添加文本的位置。如果工具箱不可见,从“<ruby>窗口<rt>Windows</rt></ruby> -> <ruby>新建工具箱<rt>New Toolbox</rt></ruby>”打开它。
|
||||
|
||||
当你编辑文本时,你可能注意到,文本对话框有字体自定义选项,包括字体系列、字体大小等等。
|
||||
|
||||
![Adding text to image in GIMP][5]
|
||||
|
||||
### 保存和导出
|
||||
|
||||
你可以从“<ruby>文件<rt>File</rt></ruby> -> <ruby>保存<rt>Save</rt></ruby>”或通过按 `Ctrl+S` 来将你的编辑保存为一个带有 `.xcf` 扩展名的 GIMP 工程。或者,你可以导出你的图像,例如,以 PNG 或 JPEG 格式。为导出图像,转到“<ruby>文件<rt>File</rt></ruby> -> <ruby>导出为<rt>Export As</rt></ruby>”或按 `Ctrl+Shift+E`,接下来,在你面前将产生一个你可以选择输出图像和名称的对话框。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://fedoramagazine.org/edit-images-on-fedora-easily-with-gimp/
|
||||
|
||||
作者:[Mehdi Haghgoo][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[robsean](https://github.com/robsean)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://fedoramagazine.org/author/powergame/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://fedoramagazine.org/wp-content/uploads/2019/10/gimp-magazine-816x346.jpg
|
||||
[2]: https://fedoramagazine.org/wp-content/uploads/2019/10/Screenshot-from-2019-10-25-11-00-44-300x165.png
|
||||
[3]: https://fedoramagazine.org/wp-content/uploads/2019/10/Screenshot-from-2019-10-25-11-17-33-300x262.png
|
||||
[4]: https://fedoramagazine.org/wp-content/uploads/2019/10/Screenshot-from-2019-10-25-11-41-28-300x243.png
|
||||
[5]: https://fedoramagazine.org/wp-content/uploads/2019/10/Screenshot-from-2019-10-25-11-47-54-300x237.png
|
||||
|
345
published/20191114 Debugging Software Deployments with strace.md
Normal file
345
published/20191114 Debugging Software Deployments with strace.md
Normal file
@ -0,0 +1,345 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (hanwckf)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11667-1.html)
|
||||
[#]: 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。很久以前,软件拥有直接访问硬件的权限。如果软件需要在屏幕上显示一些东西,它将会与视频硬件的端口和内存映射寄存器纠缠不清。当多任务操作系统变得流行以后,这就导致了混乱的局面,因为不同的应用程序将“争夺”硬件,并且一个应用程序的错误可能致使其它应用程序崩溃,甚至导致整个系统崩溃。所以 CPU 开始支持多种不同的特权模式(或者称为“保护环”)。它们让操作系统内核在具有完全硬件访问权限的最高特权模式下运行,于此同时,其它在低特权模式下运行的应用程序必须通过向内核发起系统调用才能够与硬件进行交互。
|
||||
|
||||
在二进制级别上,发起系统调用相比简单的函数调用有一些区别,但是大部分程序都使用标准库提供的封装函数。例如,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`),但是你看不到子进程内触发的任何调用。
|
||||
|
||||
如果你认为在子进程中存在错误,则需要使用 `-f` 参数启用子进程追踪功能。这样做的缺点是输出的内容会让人更加困惑。当追踪一个进程时,`strace` 显示的是单个调用事件流。当追踪多个进程的时候,你将会看到以 `<unfinished ...>` 开始的初始调用,接着是一系列针对其它线程的调用,最后才出现以 `<... foocall resumed>` 结束的初始调用。此外,你可以使用 `-ff` 参数将所有的调用分离到不同的文件中(查看 [strace 手册][6] 获取更多信息)。
|
||||
|
||||
#### 使用 -e 进行过滤
|
||||
|
||||
正如你所看到的,默认的追踪输出是所有的系统调用。你可以使用 `-e` 参数过滤你需要追踪的调用(查看 [strace 手册][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 语言,那么阅读系统调用追踪信息就非常容易。例如,如果你在调试网络系统调用,你可以尝试略读 [Beej 经典的《网络编程指南》][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)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [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
|
201
published/20191115 How to port an awk script to Python.md
Normal file
201
published/20191115 How to port an awk script to Python.md
Normal file
@ -0,0 +1,201 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (wxy)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11654-1.html)
|
||||
[#]: subject: (How to port an awk script to Python)
|
||||
[#]: via: (https://opensource.com/article/19/11/awk-to-python)
|
||||
[#]: author: (Moshe Zadka https://opensource.com/users/moshez)
|
||||
|
||||
如何把 awk 脚本移植到 Python
|
||||
======
|
||||
|
||||
> 将一个 awk 脚本移植到 Python 主要在于代码风格而不是转译。
|
||||
|
||||

|
||||
|
||||
脚本是解决问题的有效方法,而 awk 是编写脚本的出色语言。它特别擅长于简单的文本处理,它可以带你完成配置文件的某些复杂重写或目录中文件名的重新格式化。
|
||||
|
||||
### 何时从 awk 转向 Python
|
||||
|
||||
但是在某些方面,awk 的限制开始显现出来。它没有将文件分解为模块的真正概念,它缺乏质量错误报告,并且缺少了现在被认为是编程语言工作原理的其他内容。当编程语言的这些丰富功能有助于维护关键脚本时,移植将是一个不错的选择。
|
||||
|
||||
我最喜欢的完美移植 awk 的现代编程语言是 Python。
|
||||
|
||||
在将 awk 脚本移植到 Python 之前,通常值得考虑一下其原始使用场景。例如,由于 awk 的局限性,通常从 Bash 脚本调用 awk 代码,其中包括一些对 `sed`、`sort` 之类的其它命令行常见工具的调用。 最好将所有内容转换为一个一致的 Python 程序。有时,脚本会做出过于宽泛的假设,例如,即使实际上只运行一个文件,该代码也可能允许任意数量的文件。
|
||||
|
||||
在仔细考虑了上下文并确定了要用 Python 替代的东西之后,该编写代码了。
|
||||
|
||||
### 标准 awk 到 Python 功能
|
||||
|
||||
以下 Python 功能是有用的,需要记住:
|
||||
|
||||
```
|
||||
with open(some_file_name) as fpin:
|
||||
for line in fpin:
|
||||
pass # do something with line
|
||||
```
|
||||
|
||||
此代码将逐行循环遍历文件并处理这些行。
|
||||
|
||||
如果要访问行号(相当于 awk 的 `NR`),则可以使用以下代码:
|
||||
|
||||
```
|
||||
with open(some_file_name) as fpin:
|
||||
for nr, line in enumerate(fpin):
|
||||
pass # do something with line
|
||||
```
|
||||
|
||||
### 在 Python 中实现多文件的 awk 式行为
|
||||
|
||||
如果你需要能够遍历任意数量的文件同时保持行数的持续计数(类似 awk 的 `FNR`),则此循环可以做到这一点:
|
||||
|
||||
```
|
||||
def awk_like_lines(list_of_file_names):
|
||||
def _all_lines():
|
||||
for filename in list_of_file_names:
|
||||
with open(filename) as fpin:
|
||||
yield from fpin
|
||||
yield from enumerate(_all_lines())
|
||||
```
|
||||
|
||||
此语法使用 Python 的*生成器*和 `yield from` 来构建*迭代器*,该迭代器将遍历所有行并保持一个持久计数。
|
||||
|
||||
如果你需要同时使用 `FNR` 和 `NR`,这是一个更复杂的循环:
|
||||
|
||||
```
|
||||
def awk_like_lines(list_of_file_names):
|
||||
def _all_lines():
|
||||
for filename in list_of_file_names:
|
||||
with open(filename) as fpin:
|
||||
yield from enumerate(fpin)
|
||||
for nr, (fnr, line) in _all_lines:
|
||||
yield nr, fnr, line
|
||||
```
|
||||
|
||||
### 更复杂的 FNR、NR 和行数的 awk 行为
|
||||
|
||||
如果 `FNR`、`NR` 和行数这三个你全都需要,仍然会有一些问题。如果确实如此,则使用三元组(其中两个项目是数字)会导致混淆。命名参数可使该代码更易于阅读,因此最好使用 `dataclass`:
|
||||
|
||||
```
|
||||
import dataclass
|
||||
|
||||
@dataclass.dataclass(frozen=True)
|
||||
class AwkLikeLine:
|
||||
content: str
|
||||
fnr: int
|
||||
nr: int
|
||||
|
||||
def awk_like_lines(list_of_file_names):
|
||||
def _all_lines():
|
||||
for filename in list_of_file_names:
|
||||
with open(filename) as fpin:
|
||||
yield from enumerate(fpin)
|
||||
for nr, (fnr, line) in _all_lines:
|
||||
yield AwkLikeLine(nr=nr, fnr=fnr, line=line)
|
||||
```
|
||||
|
||||
你可能想知道,为什么不一直用这种方法呢?使用其它方式的的原因是总用这种方法太复杂了。如果你的目标是把一个通用库更容易地从 awk 移植到 Python,请考虑这样做。但是编写一个可以使你确切地了解特定情况所需的循环的方法通常更容易实现,也更容易理解(因而易于维护)。
|
||||
|
||||
### 理解 awk 字段
|
||||
|
||||
一旦有了与一行相对应的字符串,如果要转换 awk 程序,则通常需要将其分解为*字段*。Python 有几种方法可以做到这一点。这将把行按任意数量的连续空格拆分,返回一个字符串列表:
|
||||
|
||||
```
|
||||
line.split()
|
||||
```
|
||||
|
||||
如果需要另一个字段分隔符,比如以 `:` 分隔行,则需要 `rstrip` 方法来删除最后一个换行符:
|
||||
|
||||
```
|
||||
line.rstrip("\n").split(":")
|
||||
```
|
||||
|
||||
完成以下操作后,列表 `parts` 将存有分解的字符串:
|
||||
|
||||
```
|
||||
parts = line.rstrip("\n").split(":")
|
||||
```
|
||||
|
||||
这种拆分非常适合用来处理参数,但是我们处于[偏差一个的错误][2]场景中。现在 `parts[0]` 将对应于 awk 的 `$1`,`parts[1]` 将对应于 awk 的 `$2`,依此类推。之所以偏差一个,是因为 awk 计数“字段”从 1 开始,而 Python 从 0 开始计数。在 awk 中,`$0` 是整个行 —— 等同于 `line.rstrip("\n")`,而 awk 的 `NF`(字段数)更容易以 `len(parts)` 的形式得到。
|
||||
|
||||
### 移植 awk 字段到 Python
|
||||
|
||||
例如,让我们将这个单行代码“[如何使用 awk 从文件中删除重复行][3]”转换为 Python。
|
||||
|
||||
`awk` 中的原始代码是:
|
||||
|
||||
```
|
||||
awk '!visited[$0]++' your_file > deduplicated_file
|
||||
```
|
||||
|
||||
“真实的” Python 转换将是:
|
||||
|
||||
```
|
||||
import collections
|
||||
import sys
|
||||
|
||||
visited = collections.defaultdict(int)
|
||||
for line in open("your_file"):
|
||||
did_visit = visited[line]
|
||||
visited[line] += 1
|
||||
if not did_visit:
|
||||
sys.stdout.write(line)
|
||||
```
|
||||
|
||||
但是,Python 比 awk 具有更多的数据结构。与其计数访问次数(除了知道是否看到一行,我们不使用它),为什么不记录访问的行呢?
|
||||
|
||||
```
|
||||
import sys
|
||||
|
||||
visited = set()
|
||||
for line in open("your_file"):
|
||||
if line in visited:
|
||||
continue
|
||||
visited.add(line)
|
||||
sys.stdout.write(line)
|
||||
```
|
||||
|
||||
### 编写 Python 化的 awk 代码
|
||||
|
||||
Python 社区提倡编写 Python 化的代码,这意味着它要遵循公认的代码风格。更加 Python 化的方法将区分*唯一性*和输入/输出的关注点。此更改将使对代码进行单元测试更加容易:
|
||||
|
||||
```
|
||||
def unique_generator(things):
|
||||
visited = set()
|
||||
for thing in things:
|
||||
if thing in visited:
|
||||
continue
|
||||
visited.add(things)
|
||||
yield thing
|
||||
|
||||
import sys
|
||||
|
||||
for line in unique_generator(open("your_file")):
|
||||
sys.stdout.write(line)
|
||||
```
|
||||
|
||||
将所有逻辑置于输入/输出代码之外,可以更好地分离问题,并提高代码的可用性和可测试性。
|
||||
|
||||
### 结论:Python 可能是一个不错的选择
|
||||
|
||||
将 awk 脚本移植到 Python 时,通常是在考虑适当的 Python 代码风格时重新实现核心需求,而不是按条件/操作进行笨拙的音译。考虑原始上下文并产生高质量的 Python 解决方案。虽然有时候使用 awk 的 Bash 单行代码可以完成这项工作,但 Python 编码是通往更易于维护的代码的途径。
|
||||
|
||||
另外,如果你正在编写 awk 脚本,我相信您也可以学习 Python!如果你有任何疑问,请告诉我。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/19/11/awk-to-python
|
||||
|
||||
作者:[Moshe Zadka][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[wxy](https://github.com/wxy)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/moshez
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/OSDC_women_computing_4.png?itok=VGZO8CxT (Woman sitting in front of her laptop)
|
||||
[2]: https://en.wikipedia.org/wiki/Off-by-one_error
|
||||
[3]: https://opensource.com/article/19/10/remove-duplicate-lines-files-awk
|
@ -0,0 +1,415 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (lxbwolf)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11661-1.html)
|
||||
[#]: subject: (6 Methods to Quickly Check if a Website is up or down from the Linux Terminal)
|
||||
[#]: via: (https://www.2daygeek.com/linux-command-check-website-is-up-down-alive/)
|
||||
[#]: author: (Magesh Maruthamuthu https://www.2daygeek.com/author/magesh/)
|
||||
|
||||
在 Linux 终端快速检测网站是否宕机的 6 个方法
|
||||
======
|
||||
|
||||
> 本教程教你怎样在 Linux 终端快速检测一个网站是否宕机。
|
||||
|
||||

|
||||
|
||||
你可能已经了解了一些类似的命令,像 `ping`、`curl` 和 `wget`。我们在本教程中又加入了一些其他命令。同时,我们也加入了不同的选项来检测单个和多个主机的信息。
|
||||
|
||||
本文将帮助你检测网站是否宕机。但是如果你在维护一些网站,希望网站宕掉时得到实时的报警,我推荐你去使用实时网站监控工具。这种工具有很多,有些是免费的,大部分收费。根据你的需求,选择合适的工具。在后续的文章中我们会涉及这个主题。
|
||||
|
||||
### 方法 1:使用 fping 命令检测一个网站是否宕机
|
||||
|
||||
[fping 命令][1] 是一个类似 `ping` 的程序,使用互联网控制消息协议(ICMP)的<ruby>回应请求报文<rt>echo request</rt></ruby>来判断目标主机是否能回应。`fping` 与 `ping` 的不同之处在于它可以并行地 `ping` 任意数量的主机,也可以从一个文本文件读入主机名称。`fping` 发送一个 ICMP 回应请求后不等待目标主机响应,就以轮询模式向下一个目标主机发请求。如果一个目标主机有响应,那么它就被标记为存活的,然后从检查目标列表里去掉。如果一个目标主机在限定的时间和(或)重试次数内没有响应,则被指定为网站无法到达的。
|
||||
|
||||
```
|
||||
# fping 2daygeek.com linuxtechnews.com magesh.co.in
|
||||
|
||||
2daygeek.com is alive
|
||||
linuxtechnews.com is alive
|
||||
magesh.co.in is alive
|
||||
```
|
||||
|
||||
### 方法 2:使用 http 命令检测一个网站是否宕机
|
||||
|
||||
HTTPie(读作 aitch-tee-tee-pie)是一个命令行 HTTP 客户端。[httpie][2] 是一个可以与 web 服务通过 CLI 进行交互的现代工具。httpie 工具提供了简单的 `http` 命令,可以通过发送简单的、自然语言语法的任意 HTTP 请求得到多彩的结果输出。HTTPie 可以用来对 HTTP 服务器进行测试、调试和基本的交互。
|
||||
|
||||
```
|
||||
# http 2daygeek.com
|
||||
|
||||
HTTP/1.1 301 Moved Permanently
|
||||
CF-RAY: 535b66722ab6e5fc-LHR
|
||||
Cache-Control: max-age=3600
|
||||
Connection: keep-alive
|
||||
Date: Thu, 14 Nov 2019 19:30:28 GMT
|
||||
Expires: Thu, 14 Nov 2019 20:30:28 GMT
|
||||
Location: https://2daygeek.com/
|
||||
Server: cloudflare
|
||||
Transfer-Encoding: chunked
|
||||
Vary: Accept-Encoding
|
||||
```
|
||||
|
||||
### 方法 3:使用 curl 命令检测一个网站是否宕机
|
||||
|
||||
[curl 命令][3] 是一个用于在服务器间通过支持的协议(DICT、FILE、FTP、FTPS、GOPHER、HTTP、HTTPS、IMAP、IMAPS、LDAP、LDAPS、POP3、POP3S、RTMP、RTSP、SCP、SFTP、SMTP、SMTPS、TELNET 和 TFTP)传输数据的工具。这个工具不支持用户交互。`curl` 也支持使用代理、用户认证、FTP 上传、HTTP POST 请求、SSL 连接、cookie、断点续传、Metalink 等等。`curl `由 libcurl 库提供所有与传输有关的能力。
|
||||
|
||||
```
|
||||
# curl -I https://www.magesh.co.in
|
||||
|
||||
HTTP/2 200
|
||||
date: Thu, 14 Nov 2019 19:39:47 GMT
|
||||
content-type: text/html
|
||||
set-cookie: __cfduid=db16c3aee6a75c46a504c15131ead3e7f1573760386; expires=Fri, 13-Nov-20 19:39:46 GMT; path=/; domain=.magesh.co.in; HttpOnly
|
||||
vary: Accept-Encoding
|
||||
last-modified: Sun, 14 Jun 2015 11:52:38 GMT
|
||||
x-cache: HIT from Backend
|
||||
cf-cache-status: DYNAMIC
|
||||
expect-ct: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"
|
||||
server: cloudflare
|
||||
cf-ray: 535b74123ca4dbf3-LHR
|
||||
```
|
||||
|
||||
如果你只想看 HTTP 状态码而不是返回的全部信息,用下面的 `curl` 命令:
|
||||
|
||||
```
|
||||
# curl -I "www.magesh.co.in" 2>&1 | awk '/HTTP\// {print $2}'
|
||||
200
|
||||
```
|
||||
|
||||
如果你想看一个网站是否宕机,用下面的 bash 脚本:
|
||||
|
||||
```
|
||||
# vi curl-url-check.sh
|
||||
|
||||
#!/bin/bash
|
||||
if curl -I "https://www.magesh.co.in" 2>&1 | grep -w "200\|301" ; then
|
||||
echo "magesh.co.in is up"
|
||||
else
|
||||
echo "magesh.co.in is down"
|
||||
fi
|
||||
```
|
||||
|
||||
当你把脚本内容添加到一个文件后,执行文件,查看结果:
|
||||
|
||||
```
|
||||
# sh curl-url-check.sh
|
||||
|
||||
HTTP/2 200
|
||||
magesh.co.in is up
|
||||
```
|
||||
|
||||
如果你想看多个网站的状态,使用下面的 shell 脚本:
|
||||
|
||||
```
|
||||
# vi curl-url-check-1.sh
|
||||
|
||||
#!/bin/bash
|
||||
for site in www.google.com google.co.in www.xyzzz.com
|
||||
do
|
||||
if curl -I "$site" 2>&1 | grep -w "200\|301" ; then
|
||||
echo "$site is up"
|
||||
else
|
||||
echo "$site is down"
|
||||
fi
|
||||
echo "----------------------------------"
|
||||
done
|
||||
```
|
||||
|
||||
当你把上面脚本内容添加到一个文件后,执行文件,查看结果:
|
||||
|
||||
```
|
||||
# sh curl-url-check-1.sh
|
||||
|
||||
HTTP/1.1 200 OK
|
||||
www.google.com is up
|
||||
----------------------------------
|
||||
HTTP/1.1 301 Moved Permanently
|
||||
google.co.in is up
|
||||
----------------------------------
|
||||
www.xyzzz.com is down
|
||||
----------------------------------
|
||||
```
|
||||
|
||||
### 方法 4:使用 wget 命令检测一个网站是否宕机
|
||||
|
||||
[wget 命令][4](前身是 Geturl)是一个自由开源的命令行下载工具,通过 HTTP、HTTPS、FTP 和其他广泛使用的互联网协议获取文件。`wget` 是非交互式的命令行工具,由 World Wide Web 和 get 得名。`wget` 相对于其他工具来说更优秀,功能包括后台运行、递归下载、多文件下载、断点续传、非交互式下载和大文件下载。
|
||||
|
||||
```
|
||||
# wget -S --spider https://www.magesh.co.in
|
||||
|
||||
Spider mode enabled. Check if remote file exists.
|
||||
--2019-11-15 01:22:00-- https://www.magesh.co.in/
|
||||
Loaded CA certificate '/etc/ssl/certs/ca-certificates.crt'
|
||||
Resolving www.magesh.co.in (www.magesh.co.in)… 104.18.35.52, 104.18.34.52, 2606:4700:30::6812:2334, …
|
||||
Connecting to www.magesh.co.in (www.magesh.co.in)|104.18.35.52|:443… connected.
|
||||
HTTP request sent, awaiting response…
|
||||
HTTP/1.1 200 OK
|
||||
Date: Thu, 14 Nov 2019 19:52:01 GMT
|
||||
Content-Type: text/html
|
||||
Connection: keep-alive
|
||||
Set-Cookie: __cfduid=db73306a2f1c72c1318ad4709ef49a3a01573761121; expires=Fri, 13-Nov-20 19:52:01 GMT; path=/; domain=.magesh.co.in; HttpOnly
|
||||
Vary: Accept-Encoding
|
||||
Last-Modified: Sun, 14 Jun 2015 11:52:38 GMT
|
||||
X-Cache: HIT from Backend
|
||||
CF-Cache-Status: DYNAMIC
|
||||
Expect-CT: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"
|
||||
Server: cloudflare
|
||||
CF-RAY: 535b85fe381ee684-LHR
|
||||
Length: unspecified [text/html]
|
||||
Remote file exists and could contain further links,
|
||||
but recursion is disabled -- not retrieving.
|
||||
```
|
||||
|
||||
如果你只想看 HTTP 状态码而不是返回的全部结果,用下面的 `wget` 命令:
|
||||
|
||||
```
|
||||
# wget --spider -S "www.magesh.co.in" 2>&1 | awk '/HTTP\// {print $2}'
|
||||
200
|
||||
```
|
||||
|
||||
如果你想看一个网站是否宕机,用下面的 bash 脚本:
|
||||
|
||||
```
|
||||
# vi wget-url-check.sh
|
||||
|
||||
#!/bin/bash
|
||||
if wget --spider -S "https://www.google.com" 2>&1 | grep -w "200\|301" ; then
|
||||
echo "Google.com is up"
|
||||
else
|
||||
echo "Google.com is down"
|
||||
fi
|
||||
```
|
||||
|
||||
当你把脚本内容添加到一个文件后,执行文件,查看结果:
|
||||
|
||||
```
|
||||
# wget-url-check.sh
|
||||
|
||||
HTTP/1.1 200 OK
|
||||
Google.com is up
|
||||
```
|
||||
|
||||
如果你想看多个网站的状态,使用下面的 shell 脚本:
|
||||
|
||||
```
|
||||
# vi curl-url-check-1.sh
|
||||
|
||||
#!/bin/bash
|
||||
for site in www.google.com google.co.in www.xyzzz.com
|
||||
do
|
||||
if wget --spider -S "$site" 2>&1 | grep -w "200\|301" ; then
|
||||
echo "$site is up"
|
||||
else
|
||||
echo "$site is down"
|
||||
fi
|
||||
echo "----------------------------------"
|
||||
done
|
||||
```
|
||||
|
||||
当你把上面脚本内容添加到一个文件后,执行文件,查看结果:
|
||||
|
||||
```
|
||||
# sh wget-url-check-1.sh
|
||||
|
||||
HTTP/1.1 200 OK
|
||||
www.google.com is up
|
||||
----------------------------------
|
||||
HTTP/1.1 301 Moved Permanently
|
||||
google.co.in is up
|
||||
----------------------------------
|
||||
www.xyzzz.com is down
|
||||
----------------------------------
|
||||
```
|
||||
|
||||
### 方法 5:使用 lynx 命令检测一个网站是否宕机
|
||||
|
||||
[lynx][5] 是一个在<ruby>可寻址光标字符单元终端<rt>cursor-addressable character cell terminals</rt></ruby>上使用的基于文本的高度可配的 web 浏览器,它是最古老的 web 浏览器并且现在仍在活跃开发。
|
||||
|
||||
```
|
||||
# lynx -head -dump http://www.magesh.co.in
|
||||
|
||||
HTTP/1.1 200 OK
|
||||
Date: Fri, 15 Nov 2019 08:14:23 GMT
|
||||
Content-Type: text/html
|
||||
Connection: close
|
||||
Set-Cookie: __cfduid=df3cb624024b81df7362f42ede71300951573805662; expires=Sat, 1
|
||||
4-Nov-20 08:14:22 GMT; path=/; domain=.magesh.co.in; HttpOnly
|
||||
Vary: Accept-Encoding
|
||||
Last-Modified: Sun, 14 Jun 2015 11:52:38 GMT
|
||||
X-Cache: HIT from Backend
|
||||
CF-Cache-Status: DYNAMIC
|
||||
Server: cloudflare
|
||||
CF-RAY: 535fc5704a43e694-LHR
|
||||
```
|
||||
|
||||
如果你只想看 HTTP 状态码而不是返回的全部结果,用下面的 `lynx` 命令:
|
||||
|
||||
```
|
||||
# lynx -head -dump https://www.magesh.co.in 2>&1 | awk '/HTTP\// {print $2}'
|
||||
200
|
||||
```
|
||||
|
||||
如果你想看一个网站是否宕机,用下面的 bash 脚本:
|
||||
|
||||
```
|
||||
# vi lynx-url-check.sh
|
||||
|
||||
#!/bin/bash
|
||||
if lynx -head -dump http://www.magesh.co.in 2>&1 | grep -w "200\|301" ; then
|
||||
echo "magesh.co.in is up"
|
||||
else
|
||||
echo "magesh.co.in is down"
|
||||
fi
|
||||
```
|
||||
|
||||
当你把脚本内容添加到一个文件后,执行文件,查看结果:
|
||||
|
||||
```
|
||||
# sh lynx-url-check.sh
|
||||
|
||||
HTTP/1.1 200 OK
|
||||
magesh.co.in is up
|
||||
```
|
||||
|
||||
如果你想看多个网站的状态,使用下面的 shell 脚本:
|
||||
|
||||
```
|
||||
# vi lynx-url-check-1.sh
|
||||
|
||||
#!/bin/bash
|
||||
for site in http://www.google.com https://google.co.in http://www.xyzzz.com
|
||||
do
|
||||
if lynx -head -dump "$site" 2>&1 | grep -w "200\|301" ; then
|
||||
echo "$site is up"
|
||||
else
|
||||
echo "$site is down"
|
||||
fi
|
||||
echo "----------------------------------"
|
||||
done
|
||||
```
|
||||
|
||||
当你把上面脚本内容添加到一个文件后,执行文件,查看结果:
|
||||
|
||||
```
|
||||
# sh lynx-url-check-1.sh
|
||||
|
||||
HTTP/1.0 200 OK
|
||||
http://www.google.com is up
|
||||
----------------------------------
|
||||
HTTP/1.0 301 Moved Permanently
|
||||
https://google.co.in is up
|
||||
----------------------------------
|
||||
www.xyzzz.com is down
|
||||
----------------------------------
|
||||
```
|
||||
|
||||
### 方法 6:使用 ping 命令检测一个网站是否宕机
|
||||
|
||||
[ping 命令][1](Packet Internet Groper)是网络工具的代表,用于在互联网协议(IP)的网络中测试一个目标主机是否可用/可连接。通过向目标主机发送 ICMP 回应请求报文包并等待 ICMP 回应响应报文来检测主机的可用性。它基于已发送的包、接收到的包和丢失了的包来统计结果数据,通常包含最小/平均/最大响应时间。
|
||||
|
||||
```
|
||||
# ping -c 5 2daygeek.com
|
||||
|
||||
PING 2daygeek.com (104.27.157.177) 56(84) bytes of data.
|
||||
64 bytes from 104.27.157.177 (104.27.157.177): icmp_seq=1 ttl=58 time=228 ms
|
||||
64 bytes from 104.27.157.177 (104.27.157.177): icmp_seq=2 ttl=58 time=227 ms
|
||||
64 bytes from 104.27.157.177 (104.27.157.177): icmp_seq=3 ttl=58 time=250 ms
|
||||
64 bytes from 104.27.157.177 (104.27.157.177): icmp_seq=4 ttl=58 time=171 ms
|
||||
64 bytes from 104.27.157.177 (104.27.157.177): icmp_seq=5 ttl=58 time=193 ms
|
||||
|
||||
--- 2daygeek.com ping statistics ---
|
||||
5 packets transmitted, 5 received, 0% packet loss, time 13244ms
|
||||
rtt min/avg/max/mdev = 170.668/213.824/250.295/28.320 ms
|
||||
```
|
||||
|
||||
### 附加 1:使用 telnet 命令检测一个网站是否宕机
|
||||
|
||||
`telnet` 命令是一个使用 TELNET 协议用于 TCP/IP 网络中多个主机相互通信的古老的网络协议。它通过 23 端口连接其他设备如计算机和网络设备。`telnet` 是不安全的协议,现在由于用这个协议发送的数据没有经过加密可能被黑客拦截,所以不推荐使用。大家都使用经过加密且非常安全的 SSH 协议来代替 `telnet`。
|
||||
|
||||
```
|
||||
# telnet google.com 80
|
||||
|
||||
Trying 216.58.194.46…
|
||||
Connected to google.com.
|
||||
Escape character is '^]'.
|
||||
^]
|
||||
telnet> quit
|
||||
Connection closed.
|
||||
```
|
||||
|
||||
### 附加 2:使用 bash 脚本检测一个网站是否宕机
|
||||
|
||||
简而言之,一个 [shell 脚本][6] 就是一个包含一系列命令的文件。shell 从文件读取内容按输入顺序逐行在命令行执行。为了让它更有效,我们添加一些条件。这也减轻了 Linux 管理员的负担。
|
||||
|
||||
如果你想想用 `wget` 命令看多个网站的状态,使用下面的 shell 脚本:
|
||||
|
||||
```
|
||||
# vi wget-url-check-2.sh
|
||||
|
||||
#!/bin/bash
|
||||
for site in www.google.com google.co.in www.xyzzz.com
|
||||
do
|
||||
if wget --spider -S "$site" 2>&1 | grep -w "200\|301" > /dev/null ; then
|
||||
echo "$site is up"
|
||||
else
|
||||
echo "$site is down"
|
||||
fi
|
||||
done
|
||||
```
|
||||
|
||||
当你把上面脚本内容添加到一个文件后,执行文件,查看结果:
|
||||
|
||||
```
|
||||
# sh wget-url-check-2.sh
|
||||
|
||||
www.google.com is up
|
||||
google.co.in is up
|
||||
www.xyzzz.com is down
|
||||
```
|
||||
|
||||
如果你想用 `wget` 命令看多个网站的状态,使用下面的 [shell 脚本][7]:
|
||||
|
||||
```
|
||||
# vi curl-url-check-2.sh
|
||||
|
||||
#!/bin/bash
|
||||
for site in www.google.com google.co.in www.xyzzz.com
|
||||
do
|
||||
if curl -I "$site" 2>&1 | grep -w "200\|301" > /dev/null ; then
|
||||
echo "$site is up"
|
||||
else
|
||||
echo "$site is down"
|
||||
fi
|
||||
done
|
||||
```
|
||||
|
||||
当你把上面脚本内容添加到一个文件后,执行文件,查看结果:
|
||||
|
||||
```
|
||||
# sh curl-url-check-2.sh
|
||||
|
||||
www.google.com is up
|
||||
google.co.in is up
|
||||
www.xyzzz.com is down
|
||||
```
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.2daygeek.com/linux-command-check-website-is-up-down-alive/
|
||||
|
||||
作者:[Magesh Maruthamuthu][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[lxbwolf](https://github.com/lxbwolf)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://www.2daygeek.com/author/magesh/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://www.2daygeek.com/how-to-use-ping-fping-gping-in-linux/
|
||||
[2]: https://www.2daygeek.com/httpie-curl-wget-alternative-http-client-linux/
|
||||
[3]: https://www.2daygeek.com/curl-linux-command-line-download-manager/
|
||||
[4]: https://www.2daygeek.com/wget-linux-command-line-download-utility-tool/
|
||||
[5]: https://www.2daygeek.com/best-text-mode-based-command-line-web-browser-for-linux/
|
||||
[6]: https://www.2daygeek.com/category/shell-script/
|
||||
[7]: https://www.2daygeek.com/category/bash-script/
|
@ -0,0 +1,136 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (hopefully2333)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11699-1.html)
|
||||
[#]: subject: (How internet security works: TLS, SSL, and CA)
|
||||
[#]: via: (https://opensource.com/article/19/11/internet-security-tls-ssl-certificate-authority)
|
||||
[#]: author: (Bryant Son https://opensource.com/users/brson)
|
||||
|
||||
互联网的安全是如何保证的:TLS、SSL 和 CA
|
||||
======
|
||||
|
||||
> 你的浏览器里的锁的图标的后面是什么?
|
||||
|
||||
![Lock][1]
|
||||
|
||||
每天你都会重复这件事很多次,访问网站,网站需要你用你的用户名或者电子邮件地址和你的密码来进行登录。银行网站、社交网站、电子邮件服务、电子商务网站和新闻网站。这里只在使用了这种机制的网站中列举了其中一小部分。
|
||||
|
||||
每次你登录进一个这种类型的网站时,你实际上是在说:“是的,我信任这个网站,所以我愿意把我的个人信息共享给它。”这些数据可能包含你的姓名、性别、实际地址、电子邮箱地址,有时候甚至会包括你的信用卡信息。
|
||||
|
||||
但是你怎么知道你可以信任这个网站?换个方式问,为了让你可以信任它,网站应该如何保护你的交易?
|
||||
|
||||
本文旨在阐述使网站变得安全的机制。我会首先论述 web 协议 http 和 https,以及<ruby>传输层安全<rt>Transport Layer Security</rt></ruby>(TLS)的概念,后者是<ruby>互联网协议<rt>Internet Protocol</rt></ruby>(IP)层中的加密协议之一。然后,我会解释<ruby>证书颁发机构<rt>certificate authority</rt></ruby>和自签名证书,以及它们如何帮助保护一个网站。最后,我会介绍一些开源的工具,你可以使用它们来创建和管理你的证书。
|
||||
|
||||
### 通过 https 保护路由
|
||||
|
||||
了解一个受保护的网站的最简单的方式就是在交互中观察它,幸运的是,在今天的互联网上,发现一个安全的网站远远比找到一个不安全的网站要简单。但是,因为你已经在 Opensource.com 这个网站上了,我会使用它来作为案例,无论你使用的是哪个浏览器,你应该在你的地址栏旁边看到一个像锁一样的图标。点击这个锁图标,你应该会看见一些和下面这个类似的东西。
|
||||
|
||||
![Certificate information][2]
|
||||
|
||||
默认情况下,如果一个网站使用的是 http 协议,那么它是不安全的。为通过网站主机的路由添加一个配置过的证书,可以把这个网站从一个不安全的 http 网站变为一个安全的 https 网站。那个锁图标通常表示这个网站是受 https 保护的。
|
||||
|
||||
点击证书来查看网站的 CA,根据你的浏览器,你可能需要下载证书来查看它。
|
||||
|
||||
![Certificate information][3]
|
||||
|
||||
在这里,你可以了解有关 Opensource.com 证书的信息。例如,你可以看到 CA 是 DigiCert,并以 Opensource.com 的名称提供给 Red Hat。
|
||||
|
||||
这个证书信息可以让终端用户检查该网站是否可以安全访问。
|
||||
|
||||
> 警告:如果你没有在网站上看到证书标志,或者如果你看见的标志显示这个网站不安全——请不要登录或者做任何需要你个人数据的操作。这种情况非常危险!
|
||||
|
||||
如果你看到的是警告标志,对于大多数面向公众开放的网站来说,这很少见,它通常意味着该证书已经过期或者是该证书是自签名的,而非通过一个受信任的第三方来颁发。在我们进入这些主题之前,我想解释一下 TLS 和 SSL。
|
||||
|
||||
### 带有 TLS 和 SSL 的互联网协议
|
||||
|
||||
TLS 是旧版<ruby>安全套接字层协议<rt>Secure Socket Layer</rt></ruby>(SSL)的最新版本。理解这一点的最好方法就是仔细理解互联网协议的不同协议层。
|
||||
|
||||
![IP layers][4]
|
||||
|
||||
我们知道当今的互联网是由 6 个层面组成的:物理层、数据链路层、网络层、传输层、安全层、应用层。物理层是基础,这一层是最接近实际的硬件设备的。应用层是最抽象的一层,是最接近终端用户的一层。安全层可以被认为是应用层的一部分,TLS 和 SSL,是被设计用来在一个计算机网络中提供通信安全的加密协议,它们位于安全层中。
|
||||
|
||||
这个过程可以确保终端用户使用网络服务时,通信的安全性和保密性。
|
||||
|
||||
### 证书颁发机构和自签名证书
|
||||
|
||||
<ruby>证书颁发机构<rt>Certificate authority</rt></ruby>(CA)是受信任的组织,它可以颁发数字证书。
|
||||
|
||||
TLS 和 SSL 可以使连接更安全,但是这个加密机制需要一种方式来验证它;这就是 SSL/TLS 证书。TLS 使用了一种叫做非对称加密的加密机制,这个机制有一对称为私钥和公钥的安全密钥。(这是一个非常复杂的主题,超出了本文的讨论范围,但是如果你想去了解这方面的东西,你可以阅读“[密码学和公钥密码基础体系简介][5]”)你要知道的基础内容是,证书颁发机构们,比如 GlobalSign、DigiCert 和 GoDaddy,它们是受人们信任的可以颁发证书的供应商,它们颁发的证书可以用于验证网站使用的 TLS/SSL 证书。网站使用的证书是导入到主机服务器里的,用于保护网站。
|
||||
|
||||
然而,如果你只是要测试一下正在开发中的网站或服务,CA 证书可能对你而言太昂贵或者是太复杂了。你必须有一个用于生产目的的受信任的证书,但是开发者和网站管理员需要有一种更简单的方式来测试网站,然后他们才能将其部署到生产环境中;这就是自签名证书的来源。
|
||||
|
||||
自签名证书是一种 TLS/SSL 证书,是由创建它的人而非受信任的 CA 机构颁发的。用电脑生成一个自签名证书很简单,它可以让你在无需购买昂贵的 CA 颁发的证书的情况下测试一个安全网站。虽然自签名证书肯定不能拿到生产环境中去使用,但对于开发和测试阶段来说,这是一种简单灵活的方法。
|
||||
|
||||
### 生成证书的开源工具
|
||||
|
||||
有几种开源工具可以用来管理 TLS/SSL 证书。其中最著名的就是 openssl,这个工具包含在很多 Linux 发行版中和 MacOS 中。当然,你也可以使用其他开源工具。
|
||||
|
||||
| 工具名 | 描述 | 许可证 |
|
||||
| --------- | ------------------------------------------------------------------------------ | --------------------------------- |
|
||||
| [OpenSSL][7] | 实现 TLS 和加密库的最著名的开源工具 | Apache License 2.0 |
|
||||
| [EasyRSA][8] | 用于构建 PKI CA 的命令行实用工具 | GPL v2 |
|
||||
| [CFSSL][9] | 来自 cloudflare 的 PKI/TLS 瑞士军刀 | BSD 2-Clause "Simplified" License |
|
||||
| [Lemur][10] | 来自<ruby>网飞<rt>Netflix</rt></ruby>的 TLS 创建工具 | Apache License 2.0 |
|
||||
|
||||
如果你的目的是扩展和对用户友好,网飞的 Lemur 是一个很有趣的选择。你在[网飞的技术博客][6]上可以查看更多有关它的信息。
|
||||
|
||||
### 如何创建一个 Openssl 证书
|
||||
|
||||
你可以靠自己来创建证书,下面这个案例就是使用 Openssl 生成一个自签名证书。
|
||||
|
||||
1、使用 `openssl` 命令行生成一个私钥:
|
||||
|
||||
```
|
||||
openssl genrsa -out example.key 2048
|
||||
```
|
||||
|
||||

|
||||
|
||||
2、使用在第一步中生成的私钥来创建一个<ruby>证书签名请求<rt>certificate signing request</rt></ruby>(CSR):
|
||||
|
||||
```
|
||||
openssl req -new -key example.key -out example.csr -subj "/C=US/ST=TX/L=Dallas/O=Red Hat/OU=IT/CN=test.example.com"
|
||||
```
|
||||
|
||||

|
||||
|
||||
3、使用你的 CSR 和私钥创建一个证书:
|
||||
|
||||
```
|
||||
openssl x509 -req -days 366 -in example.csr -signkey example.key -out example.crt
|
||||
```
|
||||
|
||||

|
||||
|
||||
### 了解更多关于互联网安全的知识
|
||||
|
||||
如果你想要了解更多关于互联网安全和网站安全的知识,请看我为这篇文章一起制作的 Youtube 视频。
|
||||
|
||||
- <https://youtu.be/r0F1Hlcmjsk>
|
||||
|
||||
你有什么问题?发在评论里让我们知道。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/19/11/internet-security-tls-ssl-certificate-authority
|
||||
|
||||
作者:[Bryant Son][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[hopefully2333](https://github.com/hopefully2333)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/brson
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/security-lock-password.jpg?itok=KJMdkKum
|
||||
[2]: https://opensource.com/sites/default/files/uploads/1_certificatecheckwebsite.jpg
|
||||
[3]: https://opensource.com/sites/default/files/uploads/2_certificatedisplaywebsite.jpg
|
||||
[4]: https://opensource.com/sites/default/files/uploads/3_internetprotocol.jpg
|
||||
[5]: https://opensource.com/article/18/5/cryptography-pki
|
||||
[6]: https://medium.com/netflix-techblog/introducing-lemur-ceae8830f621
|
||||
[7]: https://www.openssl.org/
|
||||
[8]: https://github.com/OpenVPN/easy-rsa
|
||||
[9]: https://github.com/cloudflare/cfssl
|
||||
[10]: https://github.com/Netflix/lemur
|
@ -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 插件,可以让你在写代码或运维时,感觉更棒。
|
||||
|
||||

|
||||
|
||||
我使用 [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 编程时,使用 Monokai;Bash 编程时,使用 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) ) ) "
|
@ -0,0 +1,105 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (wxy)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11629-1.html)
|
||||
[#]: subject: (Switching from Python 2 to Python 3: What you need to know)
|
||||
[#]: via: (https://opensource.com/article/19/11/end-of-life-python-2)
|
||||
[#]: author: (Katie McLaughlin https://opensource.com/users/glasnt)
|
||||
|
||||
从 Python 2 切换到 Python 3 你所需要了解的
|
||||
======
|
||||
|
||||
> Python 2 将在几周内走到生命终点,这篇文章是你迁移到 Python 3 之前应该知道的。
|
||||
|
||||

|
||||
|
||||
从 2020 年 1 月 1 日开始,Python 2.7 将不再得到正式支持。在此日期之后,将会发布一个[最终错误修复][2]计划,但是仅此而已。
|
||||
|
||||
Python 2 的生命终点(EOL)对你意味着什么?如果正在运行着 Python 2,你需要迁移。
|
||||
|
||||
### 是谁决定 Python 2 的生命终点?
|
||||
|
||||
在 [2012][3] 年,维护 Python 编程语言的团队审查了其选项。有两个越来越不同的代码库,Python 2 和 Python 3。这两者都很流行,但是较新的版本并未得到广泛采用。
|
||||
|
||||
除了 Python 3 中完全重写的 Unicode 支持改变了处理数据的底层方式造成的断层,这个主要版本的变化还一次性出现了一些非向后兼容的更改。这种断层的决定成文于 [2006 年][4]。为了减轻该断层的影响,Python 2 继续保持了维护,并向后移植了一些 Python 3 的功能。为了进一步帮助社区过渡,EOL 日期[从 2015 年延长至 2020 年][5],又延长了五年。
|
||||
|
||||
该团队知道,维护不同的代码库是必须解决的麻烦。最终,他们[宣布了][6]一项决定:
|
||||
|
||||
>“我们是制作和照料 Python 编程语言的志愿者。我们已决定 2020 年 1 月 1 日将是我们停止使用 Python 2 的日子。这意味着在这一天之后,即使有人发现其中存在安全问题,我们也将不再对其进行改进。你应尽快升级到 Python 3。”
|
||||
|
||||
[Nick Coghlan][7] 是 CPython 的核心开发人员,也是 Python 指导委员会的现任成员,[在他的博客中添加了更多信息][8]。由 [Barry Warsaw][10](也是 Python 指导委员会的成员)撰写的 [PEP 404][9] 详细说明了 Python 2.8 永远不会面世的原因。
|
||||
|
||||
### 有人还在支持 Python 2 吗?
|
||||
|
||||
提供者和供应商对 Python 2 的支持会有所不同。[Google Cloud 宣布了][11]它计划未来如何支持 Python 2。红帽还[宣布了红帽企业 Linux(RHEL)的计划][12],而 AWS 宣布了 AWS 命令行界面和 [SDK][14] 的[次要版本更新要求][13]。
|
||||
|
||||
你还可以阅读 [Vicki Boykis][16] 在 Stack Overflow 撰写的博客文章“[为什么迁移到 Python 3 需要这么长时间?][15]”,其中她指出了采用 Python 3 缓慢的三个原因。
|
||||
|
||||
### 使用 Python 3 的原因
|
||||
|
||||
不管是否有持续的支持,尽快迁移到 Python 3 是一个好主意。Python 3 将继续受到支持,它具有 Python 2 所没有的一些非常优雅的东西。
|
||||
|
||||
最近发布的 [Python 3.8][17] 包含 [海象运算符][19]、[位置参数][20]和[自描述的格式化字符串][21]等[功能][18]。Python 3 的早期版本引入的[功能][22],例如 [异步 IO][23]、[格式化字符串][24]、[类型提示][25] 和 [pathlib][26],这里只提及了一点点。
|
||||
|
||||
下载最多的前 360 个软件包[已迁移到 Python 3][27]。你可以使用 [caniusepython3][28] 软件包检查你的 `requirements.txt` 文件,以查看你依赖的任何软件包是否尚未迁移。
|
||||
|
||||
### 将 Python 2 移植到 Python 3 的参考资源
|
||||
|
||||
有许多参考资源可简化你向 Python 3 的迁移。例如,“[将 Python 2 移植到 Python 3 指南][29]”列出了许多工具和技巧,可帮助你实现与 Python 2/3 单一源代码的兼容性。在 [Python3statement.org][30] 上也有一些有用的技巧。
|
||||
|
||||
[Dustin Ingram][31] 和 [Chris Wilcox][32] 在 [Cloud Next '19][33]上作了一个演讲,详细介绍了向 Python 3 过渡的一些动机和迁移模式。[Trey Hunner][34] 在 [PyCon 2018 演讲][35]上介绍了 Python 3 最有用的功能,鼓励你进行迁移,以便你可以利用它们。
|
||||
|
||||
### 加入我们!
|
||||
|
||||
距 2020 年 1 月 1 日仅有几周了。如果你需要每天提醒一下它即将到来的时间(并且你使用 Twitter 的话),请关注 [Python 2 日落倒计时][36] Twitter 机器人。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/19/11/end-of-life-python-2
|
||||
|
||||
作者:[Katie McLaughlin][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[wxy](https://github.com/wxy)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/glasnt
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/govt_a%20new%20dawn.png?itok=b4zU-VAY (A sunrise)
|
||||
[2]: https://www.python.org/dev/peps/pep-0373/#maintenance-releases
|
||||
[3]: https://github.com/python/peps/commit/a733bc927acbca16bfa3de486fb2c7d3f767a748
|
||||
[4]: https://www.python.org/dev/peps/pep-3000/#compatibility-and-transition
|
||||
[5]: https://github.com/python/peps/commit/f82462002b86feff36215b4230be28967039b0cc
|
||||
[6]: https://www.python.org/doc/sunset-python-2/
|
||||
[7]: https://twitter.com/ncoghlan_dev
|
||||
[8]: http://python-notes.curiousefficiency.org/en/latest/python3/questions_and_answers.html
|
||||
[9]: https://www.python.org/dev/peps/pep-0404/
|
||||
[10]: https://twitter.com/pumpichank
|
||||
[11]: https://cloud.google.com/python/docs/python2-sunset/?utm_source=osdc&utm_medium=blog&utm_campaign=pysunset
|
||||
[12]: https://access.redhat.com/solutions/4455511
|
||||
[13]: https://aws.amazon.com/blogs/developer/deprecation-of-python-2-6-and-python-3-3-in-botocore-boto3-and-the-aws-cli/
|
||||
[14]: https://aws.amazon.com/sdk-for-python/
|
||||
[15]: https://stackoverflow.blog/2019/11/14/why-is-the-migration-to-python-3-taking-so-long/
|
||||
[16]: https://twitter.com/vboykis
|
||||
[17]: https://www.python.org/downloads/
|
||||
[18]: https://docs.python.org/3.8/whatsnew/3.8.html
|
||||
[19]: https://docs.python.org/3.8/whatsnew/3.8.html#assignment-expressions
|
||||
[20]: https://docs.python.org/3.8/whatsnew/3.8.html#positional-only-parameters
|
||||
[21]: https://docs.python.org/3.8/whatsnew/3.8.html#f-strings-support-for-self-documenting-expressions-and-debugging
|
||||
[22]: https://docs.python.org/3.8/whatsnew/index.html
|
||||
[23]: https://docs.python.org/3.8/library/asyncio.html#module-asyncio
|
||||
[24]: https://docs.python.org/3.7/whatsnew/3.6.html#pep-498-formatted-string-literals
|
||||
[25]: https://docs.python.org/3.7/whatsnew/3.5.html#pep-484-type-hints
|
||||
[26]: https://docs.python.org/3.8/library/pathlib.html#module-pathlib
|
||||
[27]: http://py3readiness.org/
|
||||
[28]: https://pypi.org/project/caniusepython3/
|
||||
[29]: https://docs.python.org/3/howto/pyporting.html
|
||||
[30]: https://python3statement.org/practicalities/
|
||||
[31]: https://twitter.com/di_codes
|
||||
[32]: https://twitter.com/chriswilcox47
|
||||
[33]: https://www.youtube.com/watch?v=Bye7Rms0Vgw&utm_source=osdc&utm_medium=blog&utm_campaign=pysunset
|
||||
[34]: https://twitter.com/treyhunner
|
||||
[35]: https://www.youtube.com/watch?v=klaGx9Q_SOA
|
||||
[36]: https://twitter.com/python2sunset
|
@ -0,0 +1,220 @@
|
||||
[#]: collector: "lujun9972"
|
||||
[#]: translator: "lxbwolf"
|
||||
[#]: 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/"
|
||||
|
||||
Bash 脚本实现每次登录到 Shell 时可以查看 Linux 系统信息
|
||||
======
|
||||
|
||||
Linux 中有很多可以查看系统信息如处理器信息、生产商名字、序列号等的命令。你可能需要执行多个命令来收集这些信息。同时,记住所有的命令和他们的选项也是有难度。
|
||||
|
||||
你可以写一个 [shell 脚本](https://www.2daygeek.com/category/shell-script/) 基于你的需求来自定义显示的信息。
|
||||
|
||||
以前我们出于不同的目的需要写很多个 [bash 脚本](https://www.2daygeek.com/category/bash-script/)。
|
||||
|
||||
现在我们写一个新的 shell 脚本,在每次登录到 shell 时显示需要的系统信息。
|
||||
|
||||
这个j脚本有 6 部分,细节如下:
|
||||
|
||||
1. 通用系统信息
|
||||
2. CPU/内存当前使用情况
|
||||
3. 硬盘使用率超过 80%
|
||||
4. 列出系统 WWN 详情
|
||||
5. Oracle DB 实例
|
||||
6. 可更新的包
|
||||
|
||||
我们已经基于我们的需求把可能需要到的信息加到了每个部分。之后你可以基于自己的意愿修改这个脚本。
|
||||
|
||||
这个j脚本需要用到很多工具,其中大部分我们之前已经涉及到了。
|
||||
|
||||
你可以参照以前文章,了解工具详情。
|
||||
|
||||
* [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]
|
||||
|
||||
如果你想为这个脚本增加其他的信息,请在评论去留下你的需求,以便我们帮助你。
|
||||
|
||||
### Bash 脚本实现每次登录到 Shell 时可以查看 Linux 系统信息
|
||||
|
||||
这个脚本会在你每次登录 shell 时把系统信息打印到 terminal。
|
||||
|
||||
```
|
||||
# vi /opt/scripts/system-info.sh
|
||||
```
|
||||
|
||||
```
|
||||
#!/bin/bash
|
||||
echo -e "-------------------------------System Information----------------------------"
|
||||
echo -e "Hostname:\t\t"`hostname`
|
||||
echo -e "uptime:\t\t\t"`uptime | awk '{print $3,$4}' | sed 's/,//'`
|
||||
echo -e "Manufacturer:\t\t"`cat /sys/class/dmi/id/chassis_vendor`
|
||||
echo -e "Product Name:\t\t"`cat /sys/class/dmi/id/product_name`
|
||||
echo -e "Version:\t\t"`cat /sys/class/dmi/id/product_version`
|
||||
echo -e "Serial Number:\t\t"`cat /sys/class/dmi/id/product_serial`
|
||||
echo -e "Machine Type:\t\t"`vserver=$(lscpu | grep Hypervisor | wc -l); if [ $vserver -gt 0 ]; then echo "VM"; else echo "Physical"; fi`
|
||||
echo -e "Operating System:\t"`hostnamectl | grep "Operating System" | cut -d ' ' -f5-`
|
||||
echo -e "Kernel:\t\t\t"`uname -r`
|
||||
echo -e "Architecture:\t\t"`arch`
|
||||
echo -e "Processor Name:\t\t"`awk -F':' '/^model name/ {print $2}' /proc/cpuinfo | uniq | sed -e 's/^[ \t]*//'`
|
||||
echo -e "Active User:\t\t"`w | cut -d ' ' -f1 | grep -v USER | xargs -n1`
|
||||
echo -e "System Main IP:\t\t"`hostname -I`
|
||||
echo ""
|
||||
echo -e "-------------------------------CPU/Memory Usage------------------------------"
|
||||
echo -e "Memory Usage:\t"`free | awk '/Mem/{printf("%.2f%"), $3/$2*100}'`
|
||||
echo -e "Swap Usage:\t"`free | awk '/Swap/{printf("%.2f%"), $3/$2*100}'`
|
||||
echo -e "CPU Usage:\t"`cat /proc/stat | awk '/cpu/{printf("%.2f%\n"), ($2+$4)*100/($2+$4+$5)}' | awk '{print $0}' | head -1`
|
||||
echo ""
|
||||
echo -e "-------------------------------Disk Usage >80%-------------------------------"
|
||||
df -Ph | sed s/%//g | awk '{ if($5 > 80) print $0;}'
|
||||
echo ""
|
||||
|
||||
echo -e "-------------------------------For WWN Details-------------------------------"
|
||||
vserver=$(lscpu | grep Hypervisor | wc -l)
|
||||
if [ $vserver -gt 0 ]
|
||||
then
|
||||
echo "$(hostname) is a VM"
|
||||
else
|
||||
cat /sys/class/fc_host/host?/port_name
|
||||
fi
|
||||
echo ""
|
||||
|
||||
echo -e "-------------------------------Oracle DB Instances---------------------------"
|
||||
if id oracle >/dev/null 2>&1; then
|
||||
/bin/ps -ef|grep pmon
|
||||
then
|
||||
else
|
||||
echo "oracle user does not exist on $(hostname)"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
if (( $(cat /etc/*-release | grep -w "Oracle|Red Hat|CentOS|Fedora" | wc -l) > 0 ))
|
||||
then
|
||||
echo -e "-------------------------------Package Updates-------------------------------"
|
||||
yum updateinfo summary | grep 'Security|Bugfix|Enhancement'
|
||||
echo -e "-----------------------------------------------------------------------------"
|
||||
else
|
||||
echo -e "-------------------------------Package Updates-------------------------------"
|
||||
cat /var/lib/update-notifier/updates-available
|
||||
echo -e "-----------------------------------------------------------------------------"
|
||||
fi
|
||||
```
|
||||
|
||||
把上面脚本内容保存到一个文件 `system-info.sh`,之后添加可执行权限:
|
||||
|
||||
```
|
||||
# chmod +x ~root/system-info.sh
|
||||
```
|
||||
|
||||
当脚本准备好后,把脚本文件的路径加到 `.bash_profile` 文件末尾(红帽系列的系统:CentOS、Oracle Linux 和 Fedora):
|
||||
|
||||
```
|
||||
# echo "/root/system-info.sh" >> ~root/.bash_profile
|
||||
```
|
||||
|
||||
执行以下命令,来让修改的内容生效:
|
||||
|
||||
```
|
||||
# source ~root/.bash_profile
|
||||
```
|
||||
|
||||
对于 Debian 系统的系统,你可能需要把文件路径加到 `.profile` 文件中:
|
||||
|
||||
```
|
||||
# echo "/root/system-info.sh" >> ~root/.profile
|
||||
```
|
||||
|
||||
运行以下命令使修改生效:
|
||||
|
||||
```
|
||||
# source ~root/.profile
|
||||
```
|
||||
|
||||
你以前运行上面 `source` 命令时可能见过类似下面的输出。从下次开始,你在每次登录 shell 时会看到这些信息。当然,如果有必要你也可以随时手动执行这个脚本。
|
||||
|
||||
```
|
||||
-------------------------------System Information---------------------------
|
||||
Hostname: daygeek-Y700
|
||||
uptime: 1:20 1
|
||||
Manufacturer: LENOVO
|
||||
Product Name: 80NV
|
||||
Version: Lenovo ideapad Y700-15ISK
|
||||
Serial Number: AA0CMRN1
|
||||
Machine Type: Physical
|
||||
Operating System: Manjaro Linux
|
||||
Kernel: 4.19.80-1-MANJARO
|
||||
Architecture: x86_64
|
||||
Processor Name: Intel(R) Core(TM) i7-6700HQ CPU @ 2.60GHz
|
||||
Active User: daygeek renu thanu
|
||||
System Main IP: 192.168.1.6 192.168.122.1
|
||||
|
||||
-------------------------------CPU/Memory Usage------------------------------
|
||||
Memory Usage: 37.28%
|
||||
Swap Usage: 0.00%
|
||||
CPU Usage: 15.43%
|
||||
|
||||
-------------------------------Disk Usage >80%-------------------------------
|
||||
Filesystem Size Used Avail Use Mounted on
|
||||
/dev/nvme0n1p1 217G 202G 4.6G 98 /
|
||||
/dev/loop0 109M 109M 0 100 /var/lib/snapd/snap/odrive-unofficial/2
|
||||
/dev/loop1 91M 91M 0 100 /var/lib/snapd/snap/core/6405
|
||||
/dev/loop2 90M 90M 0 100 /var/lib/snapd/snap/core/7713
|
||||
|
||||
-------------------------------For WWN Details-------------------------------
|
||||
CentOS8.2daygeek.com is a VM
|
||||
|
||||
-------------------------------Oracle DB Instances---------------------------
|
||||
oracle user does not exist on CentOS8.2daygeek.com
|
||||
|
||||
-------------------------------Package Updates-------------------------------
|
||||
13 Security notice(s)
|
||||
9 Important Security notice(s)
|
||||
3 Moderate Security notice(s)
|
||||
1 Low Security notice(s)
|
||||
35 Bugfix notice(s)
|
||||
1 Enhancement notice(s)
|
||||
-----------------------------------------------------------------------------
|
||||
```
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.2daygeek.com/bash-shell-script-view-linux-system-information/
|
||||
|
||||
作者:[Magesh Maruthamuthu][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[lxbwolf](https://github.com/lxbwolf)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://www.2daygeek.com/author/magesh/
|
||||
[b]: https://github.com/lujun9972
|
||||
[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/
|
@ -0,0 +1,200 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11633-1.html)
|
||||
[#]: subject: (How to Install Ansible (Automation Tool) on CentOS 8/RHEL 8)
|
||||
[#]: via: (https://www.linuxtechi.com/install-ansible-centos-8-rhel-8/)
|
||||
[#]: author: (Pradeep Kumar https://www.linuxtechi.com/author/pradeep/)
|
||||
|
||||
如何在 CentOS 8/RHEL 8 上安装 Ansible(自动化工具)
|
||||
======
|
||||
|
||||
Ansible 是给 Linux 系统管理员使用的出色自动化工具。它是一种开源配置工具,能让系统管理员可以从一个中心节点(即 Ansible 服务器)管理数百台服务器。将 Ansible 与 Puppet、Chef 和 Salt 等类似工具进行比较时,它是首选的配置工具,因为它不需要任何代理,并且可以工作在 SSH 和 python 上。
|
||||
|
||||

|
||||
|
||||
在本教程中,我们将学习如何在 CentOS 8 和 RHEL 8 系统上安装和使用 Ansble。
|
||||
|
||||
Ansible 实验环境信息:
|
||||
|
||||
* 最小化安装的 CentOS 8 / RHEL 8 服务器(192.168.1.10),且有互联网连接
|
||||
* 两个 Ansible 节点 - Ubuntu 18.04 LTS (192.168.1.20) 和 CentOS 7 (192.168.1.30)
|
||||
|
||||
### CentOS 8 上的 Ansible 安装步骤
|
||||
|
||||
Ansible 包不在 CentOS 8 默认的软件包仓库中。因此,我们需要执行以下命令启用 [EPEL 仓库][3]:
|
||||
|
||||
```
|
||||
[root@linuxtechi ~]$ sudo dnf install https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm -y
|
||||
```
|
||||
|
||||
启用 epel 仓库后,执行以下 `dnf` 命令安装 Ansible:
|
||||
|
||||
```
|
||||
[root@linuxtechi ~]$ sudo dnf install ansible
|
||||
```
|
||||
|
||||
上面命令的输出:
|
||||
|
||||
![dnf-install-ansible-centos8][4]
|
||||
|
||||
成功安装 Ansible 后,运行以下命令验证它的版本:
|
||||
|
||||
```
|
||||
[root@linuxtechi ~]$ sudo ansible --version
|
||||
```
|
||||
|
||||
![Ansible-version-CentOS8][5]
|
||||
|
||||
上面的输出确认在 CentOS 8 上安装完成。
|
||||
|
||||
让我们看下 RHEL 8 系统。
|
||||
|
||||
### RHEL 8 上的 Ansible 安装步骤
|
||||
|
||||
如果你有有效的 RHEL 8 订阅,请使用以下订阅管理器命令启用 Ansble 仓库:
|
||||
|
||||
```
|
||||
[root@linuxtechi ~]$ sudo subscription-manager repos --enable ansible-2.8-for-rhel-8-x86_64-rpms
|
||||
```
|
||||
|
||||
启用仓库后,执行以下 `dnf` 命令安装 Ansible:
|
||||
|
||||
```
|
||||
[root@linuxtechi ~]$ sudo dnf install ansible -y
|
||||
```
|
||||
|
||||
安装 Ansible 及其依赖包后,执行以下命令来验证它的版本:
|
||||
|
||||
```
|
||||
[root@linuxtechi ~]$ sudo ansible --version
|
||||
```
|
||||
|
||||
### 在 CentOS 8 / RHEL 8 上通过 pip3 安装 Ansible 的可选方法
|
||||
|
||||
如果你希望使用 `pip`(Python 的包管理器)安装 Ansible,请首先使用以下命令安装 pyhton3 和 python3-pip 包:
|
||||
|
||||
```
|
||||
[root@linuxtechi ~]$ sudo dnf install python3 python3-pip -y
|
||||
```
|
||||
|
||||
安装 python3 后,运行以下命令来验证它的版本:
|
||||
|
||||
```
|
||||
[root@linuxtechi ~]$ python3 -V
|
||||
Python 3.6.8
|
||||
[root@linuxtechi ~]$
|
||||
```
|
||||
|
||||
用下面的 `pip3` 命令安装 Ansible:
|
||||
|
||||
```
|
||||
[root@linuxtechi ~]$ pip3 install ansible --user
|
||||
```
|
||||
|
||||
输出:
|
||||
|
||||
![Ansible-Install-pip3-centos8][6]
|
||||
|
||||
上面的输出确认 Ansible 已成功使用 `pip3` 安装。让我们看下如何使用 Ansible。
|
||||
|
||||
### 如何使用 Ansible 自动化工具?
|
||||
|
||||
当我们使用 `yum` 或 `dnf` 命令安装 Ansible 时,它的配置文件、清单文件和角色目录会自动在 `/etc/ansible` 文件夹下创建。
|
||||
|
||||
让我们添加一个名称为 `labservers` 的组,并在 `/etc/ansible/hosts` 文件中给该组添加上述的 Ubuntu 18.04 和 CentOS 7 系统的 IP 地址:
|
||||
|
||||
```
|
||||
[root@linuxtechi ~]$ sudo vi /etc/ansible/hosts
|
||||
…
|
||||
[labservers]
|
||||
192.168.1.20
|
||||
192.168.1.30
|
||||
…
|
||||
```
|
||||
|
||||
保存并退出文件。
|
||||
|
||||
更新清单文件(`/etc/ansible/hosts`)后,将用户的 ssh 公钥放到属于 `labservers` 组的远程系统。
|
||||
|
||||
让我们首先使用 `ssh-keygen` 命令生成本地用户的公钥和私钥:
|
||||
|
||||
```
|
||||
[root@linuxtechi ~]$ ssh-keygen
|
||||
```
|
||||
|
||||
现在使用以下命令在 Ansible 服务器及其客户端之间交换公钥:
|
||||
|
||||
```
|
||||
[root@linuxtechi ~]$ ssh-copy-id root@linuxtechi
|
||||
[root@linuxtechi ~]$ ssh-copy-id root@linuxtechi
|
||||
```
|
||||
|
||||
现在,让我们尝试几个 Ansible 命令,首先使用 `ping` 模块验证 Ansible 服务器与客户端的连接:
|
||||
|
||||
```
|
||||
[root@linuxtechi ~]$ ansible -m ping "labservers"
|
||||
```
|
||||
|
||||
注意: 如果我们没有在上面的命令中指定清单文件,那么它将引用默认主机文件(即 `/etc/ansible/hosts`)。
|
||||
|
||||
输出:
|
||||
|
||||
![ansible-ping-module-centos8][7]
|
||||
|
||||
让我们使用 Ansible shell 命令检查每个客户端的内核版本:
|
||||
|
||||
```
|
||||
[root@linuxtechi ~]$ ansible -m command -a "uname -r" "labservers"
|
||||
192.168.1.30 | CHANGED | rc=0 >>
|
||||
4.15.0-20-generic
|
||||
192.168.1.20 | CHANGED | rc=0 >>
|
||||
3.10.0-327.el7.x86_64
|
||||
[root@linuxtechi ~]$
|
||||
```
|
||||
|
||||
使用以下命令列出清单文件中的所有主机:
|
||||
|
||||
```
|
||||
[root@linuxtechi ~]$ ansible all -i /etc/ansible/hosts --list-hosts
|
||||
hosts (4):
|
||||
192.168.100.1
|
||||
192.168.100.10
|
||||
192.168.1.20
|
||||
192.168.1.30
|
||||
[root@linuxtechi ~]$
|
||||
```
|
||||
|
||||
使用以下 Ansible 命令仅列出 `labservers` 组中的主机:
|
||||
|
||||
```
|
||||
root@linuxtechi ~]$ ansible labservers -i /etc/ansible/hosts --list-hosts
|
||||
hosts (2):
|
||||
192.168.1.20
|
||||
192.168.1.30
|
||||
[root@linuxtechi ~]$
|
||||
```
|
||||
|
||||
本文就是这些了,我们成功演示了如何在 CentOS 8 和 RHEL 8 系统中安装和使用 Ansible。请分享你的反馈和意见。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.linuxtechi.com/install-ansible-centos-8-rhel-8/
|
||||
|
||||
作者:[Pradeep Kumar][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://www.linuxtechi.com/author/pradeep/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7
|
||||
[2]: http://www.linuxtechi.com/wp-content/uploads/2019/11/Install-Ansible-CentOS8-RHEL8.png
|
||||
[3]: http://www.linuxtechi.com/enable-epel-repo-centos8-rhel8-server/
|
||||
[4]: https://www.linuxtechi.com/wp-content/uploads/2019/11/dnf-install-ansible-centos8-1536x652.png
|
||||
[5]: https://www.linuxtechi.com/wp-content/uploads/2019/11/Ansible-version-CentOS8.png
|
||||
[6]: https://www.linuxtechi.com/wp-content/uploads/2019/11/Ansible-Install-pip3-centos8-1536x545.png
|
||||
[7]: https://www.linuxtechi.com/wp-content/uploads/2019/11/ansible-ping-module-centos8.png
|
153
published/20191125 How to use loops in awk.md
Normal file
153
published/20191125 How to use loops in awk.md
Normal file
@ -0,0 +1,153 @@
|
||||
[#]: collector: "lujun9972"
|
||||
[#]: translator: "lxbwolf"
|
||||
[#]: reviewer: "wxy"
|
||||
[#]: publisher: "wxy"
|
||||
[#]: url: "https://linux.cn/article-11636-1.html"
|
||||
[#]: subject: "How to use loops in awk"
|
||||
[#]: via: "https://opensource.com/article/19/11/loops-awk"
|
||||
[#]: author: "Seth Kenlon https://opensource.com/users/seth"
|
||||
|
||||
在 awk 中怎么使用循环
|
||||
======
|
||||
|
||||
> 来学习一下多次执行同一条命令的不同类型的循环。
|
||||
|
||||

|
||||
|
||||
`awk` 脚本有三个主要部分:`BEGIN` 和 `END` 函数(都可选),用户自己写的每次要执行的函数。某种程度上,`awk` 的主体部分就是一个循环,因为函数中的命令对每一条记录都会执行一次。然而,有时你希望对于一条记录执行多次命令,那么你就需要用到循环。
|
||||
|
||||
有多种类型的循环,分别适合不同的场景。
|
||||
|
||||
### while 循环
|
||||
|
||||
一个 `while` 循环检测一个表达式,如果表达式为 `true` 就执行命令。当表达式变为 `false` 时,循环中断。
|
||||
|
||||
```
|
||||
#!/bin/awk -f
|
||||
|
||||
BEGIN {
|
||||
# Loop through 1 to 10
|
||||
|
||||
i=1;
|
||||
while (i <= 10) {
|
||||
print i, " to the second power is ", i*i;
|
||||
i = i+1;
|
||||
}
|
||||
exit;
|
||||
}
|
||||
```
|
||||
|
||||
在这个简单实例中,`awk` 打印了放在变量 `i` 中的整数值的平方。`while (i <= 10)` 语句告诉 `awk` 仅在 `i` 的值小于或等于 10 时才执行循环。在循环最后一次执行时(`i` 的值是 10),循环终止。
|
||||
|
||||
### do-while 循环
|
||||
|
||||
do-while 循环执行在关键字 `do` 之后的命令。在每次循环结束时检测一个测试表达式来决定是否终止循环。仅在测试表达式返回 `true` 时才会重复执行命令(即还没有到终止循环的条件)。如果测试表达式返回 `false`,因为到了终止循环的条件所以循环被终止。
|
||||
|
||||
```
|
||||
#!/usr/bin/awk -f
|
||||
BEGIN {
|
||||
|
||||
i=2;
|
||||
do {
|
||||
print i, " to the second power is ", i*i;
|
||||
i = i + 1
|
||||
}
|
||||
while (i < 10)
|
||||
|
||||
exit;
|
||||
}
|
||||
```
|
||||
|
||||
### for 循环
|
||||
|
||||
`awk` 中有两种 `for` 循环。
|
||||
|
||||
一种 `for` 循环初始化一个变量,检测一个测试表达式,执行变量递增,当表达式的结果为 `true` 时循环就会一直执行。
|
||||
|
||||
```
|
||||
#!/bin/awk -f
|
||||
|
||||
BEGIN {
|
||||
for (i=1; i <= 10; i++) {
|
||||
print i, " to the second power is ", i*i;
|
||||
}
|
||||
exit;
|
||||
}
|
||||
```
|
||||
|
||||
另一种 `for` 循环设置一个有连续索引的数组变量,对每一个索引执行一个命令集。换句话说,它用一个数组“收集”每一条命令执行后的结果。
|
||||
|
||||
本例实现了一个简易版的 Unix 命令 `uniq`。通过把一系列字符串作为键加到数组 `a` 中,当相同的键再次出现时就增加键值,可以得到某个字符串出现的次数(就像 `uniq` 的 `--count` 选项)。如果你打印该数组的所有键,将会得到出现过的所有字符串。
|
||||
|
||||
用演示文件 `colours.txt`(前一篇文章中的文件)来举例:
|
||||
|
||||
```
|
||||
name color amount
|
||||
apple red 4
|
||||
banana yellow 6
|
||||
raspberry red 99
|
||||
strawberry red 3
|
||||
grape purple 10
|
||||
apple green 8
|
||||
plum purple 2
|
||||
kiwi brown 4
|
||||
potato brown 9
|
||||
pineapple yellow 5
|
||||
```
|
||||
|
||||
这是 `awk` 版的简易 `uniq -c`:
|
||||
|
||||
```
|
||||
#! /usr/bin/awk -f
|
||||
|
||||
NR != 1 {
|
||||
a[$2]++
|
||||
}
|
||||
END {
|
||||
for (key in a) {
|
||||
print a[key] " " key
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
示例数据文件的第三列是第一列列出的条目的计数。你可以用一个数组和 `for` 循环来按颜色统计第三列的条目。
|
||||
|
||||
```
|
||||
#! /usr/bin/awk -f
|
||||
|
||||
BEGIN {
|
||||
FS=" ";
|
||||
OFS="\t";
|
||||
print("color\tsum");
|
||||
}
|
||||
NR != 1 {
|
||||
a[$2]+=$3;
|
||||
}
|
||||
END {
|
||||
for (b in a) {
|
||||
print b, a[b]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
你可以看到,在处理文件之前也需要在 `BEFORE` 函数(仅仅执行一次)中打印一列表头。
|
||||
|
||||
### 循环
|
||||
|
||||
在任何编程语言中循环都是很重要的一部分,`awk` 也不例外。使用循环你可以控制 `awk` 脚本怎样去运行,它可以统计什么信息,还有它怎么去处理你的数据。我们下一篇文章会讨论 `switch`、`continue` 和 `next` 语句。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/19/11/loops-awk
|
||||
|
||||
作者:[Seth Kenlon][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[lxbwolf](https://github.com/lxbwolf)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [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/fail_progress_cycle_momentum_arrow.png?itok=q-ZFa_Eh "arrows cycle symbol for failing faster"
|
||||
[2]: http://hackerpublicradio.org/eps.php?id=2330
|
225
published/20191125 The many faces of awk.md
Normal file
225
published/20191125 The many faces of awk.md
Normal file
@ -0,0 +1,225 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (luuming)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11658-1.html)
|
||||
[#]: subject: (The many faces of awk)
|
||||
[#]: via: (https://www.networkworld.com/article/3454979/the-many-faces-of-awk.html)
|
||||
[#]: author: (Sandra Henry-Stocker https://www.networkworld.com/author/Sandra-Henry_Stocker/)
|
||||
|
||||
千面 awk
|
||||
======
|
||||
|
||||
> `awk` 命令不仅提供了简单的输入字符串筛选功能,还包含提取数据列、打印简单文本、筛选内容——甚至做一些数学计算。
|
||||
|
||||
![Thinkstock][6]
|
||||
|
||||
如果你仅使用 `awk` 选取一行中的特定文本,那么你可能错过了它的很多功能。在这篇文章中,我们会来看看使用 `awk` 可以帮你做一些其他的什么事情,并提供一些例子。
|
||||
|
||||
### 提取数据列
|
||||
|
||||
`awk` 所提供的最简单与最常用的功能便是从文件或管道传输的数据中选取特定的内容。默认使用空格当做分隔符,这非常简单。
|
||||
|
||||
```
|
||||
$ echo one two three four five | awk ‘{print $4}’
|
||||
four
|
||||
$ who | awk ‘{print $1}’
|
||||
jdoe
|
||||
fhenry
|
||||
```
|
||||
|
||||
空格指的是一系列的 `space` 或 `tab` 字符。在下面所展示的命令里,`awk` 从提供的数据中筛选第一和第四项。
|
||||
|
||||
`awk` 命令也可以通过在其后增加文件名参数的方式从文本文件中获取数据。
|
||||
|
||||
```
|
||||
$ awk '{print $1,$5,$NF}' HelenKellerQuote
|
||||
The beautiful heart.
|
||||
```
|
||||
|
||||
(LCTT 译注:“The best and most beautiful things in the world can not be seen or even touched , they must be felt with heart.” ——海伦凯勒)
|
||||
|
||||
在这个例子中,`awk` 挑选了一行中的第一个、第五个和最后一个字段。
|
||||
|
||||
命令中的 `$NF` 指定选取每行的最后一个字段。这是因为 `NF` 代表一行中的<ruby>字段数量<rt>Number of Field</rt></ruby>,也就是 23,而 `$NF` 就代表着那个字段的值,也就是`heart`。最后的句号也包含进去了,因为它是最后一个字符串的一部分。
|
||||
|
||||
字段能以任何有用的形式打印。在这个例子中,我们将字段以日期的格式进行打印输出。
|
||||
|
||||
```
|
||||
$ date | awk '{print $4,$3,$2}'
|
||||
2019 Nov 22
|
||||
```
|
||||
|
||||
如果你省略了 `awk` 命令中字段指示符之间的逗号,输出将会挤成一个字符串。
|
||||
|
||||
```
|
||||
$ date | awk '{print $4 $3 $2}'
|
||||
2019Nov21
|
||||
```
|
||||
|
||||
如果你将通常使用的逗号替换为连字符,`awk` 就会尝试将两个字段的值相减——或许这并不是你想要的。它不会将连字符插入到输出结果中。相反地,它对输出做了一些数学计算。
|
||||
|
||||
```
|
||||
$ date | awk '{print $4-$3-$2}'
|
||||
1997
|
||||
```
|
||||
|
||||
在这个例子中,它将年 “2019” 和日期 “22” 相减,并忽略了中间的 “Nov”。
|
||||
|
||||
如果你想要空格之外的字符作为输出分隔符,你可以通过 `OFS`(<ruby>输出分隔符<rt>output field separator</rt></ruby>)指定分隔符,就像这样:
|
||||
|
||||
```
|
||||
$ date | awk '{OFS="-"; print $4,$3,$2}'
|
||||
2019-Nov-22
|
||||
```
|
||||
|
||||
### 打印简单文本
|
||||
|
||||
你也可以使用 `awk` 简单地显示一些文本。当然了,比起 `awk` 你可能更想使用 `echo` 命令。但换句话说,作为 `awk` 脚本的一部分,打印某些相关性文本将会非常实用。这里有一个没什么用的例子:
|
||||
|
||||
```
|
||||
$ awk 'BEGIN {print "Hello, World" }'
|
||||
Hello, World
|
||||
```
|
||||
|
||||
下面的例子更加合理,添加一行文本标签来更好的辨识数据。
|
||||
|
||||
```
|
||||
$ who | awk 'BEGIN {print "Current logins:"} {print $1}'
|
||||
Current logins:
|
||||
shs
|
||||
nemo
|
||||
```
|
||||
|
||||
### 指定字段分隔符
|
||||
|
||||
不是所有的输入都以空格作为分隔符的。如果你的文本通过其它的字符作为分隔符(例如:逗号、冒号、分号),你可以通过 `-F` 选项(输入分隔符)告诉 `awk`:
|
||||
|
||||
```
|
||||
$ cat testfile
|
||||
a:b:c,d:e
|
||||
$ awk -F : '{print $2,$3}' testfile
|
||||
b c,d
|
||||
```
|
||||
|
||||
下面是一个更加有用的例子——从冒号分隔的 `/etc/passwd` 文件中获取数据:
|
||||
|
||||
```
|
||||
$ awk -F: '{print $1}' /etc/passwd | head -11
|
||||
root
|
||||
daemon
|
||||
bin
|
||||
sys
|
||||
sync
|
||||
games
|
||||
man
|
||||
lp
|
||||
mail
|
||||
news
|
||||
uucp
|
||||
```
|
||||
|
||||
### 筛选内容
|
||||
|
||||
你也可以使用 `awk` 命令评估字段。例如你仅仅想列出 `/etc/passwd` 中的用户账号,就可以对第三个字段做一些筛选。下面的例子中我们只关注大于等于 1000 的 UID:
|
||||
|
||||
```
|
||||
$ awk -F":" ' $3 >= 1000 ' /etc/passwd
|
||||
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
|
||||
shs:x:1000:1000:Sandra Henry-Stocker,,,:/home/shs:/bin/bash
|
||||
nemo:x:1001:1001:Nemo,,,:/home/nemo:/usr/bin/zsh
|
||||
dory:x:1002:1002:Dory,,,:/home/dory:/bin/bash
|
||||
...
|
||||
```
|
||||
|
||||
如果你想为输出增加标题,可以添加 `BEGIN` 从句:
|
||||
|
||||
```
|
||||
$ awk -F":" 'BEGIN {print "user accounts:"} $3 >= 1000 ' /etc/passwd
|
||||
user accounts:
|
||||
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
|
||||
shs:x:1000:1000:Sandra Henry-Stocker,,,:/home/shs:/bin/bash
|
||||
nemo:x:1001:1001:Nemo,,,:/home/nemo:/usr/bin/zsh
|
||||
dory:x:1002:1002:Dory,,,:/home/dory:/bin/bash
|
||||
```
|
||||
|
||||
如果你想要不止一行的标题,你可以通过 `"\n"` 分隔输出:
|
||||
|
||||
```
|
||||
$ awk -F":" 'BEGIN {print "user accounts\n============="} $3 >= 1000 ' /etc/passwd
|
||||
user accounts
|
||||
=============
|
||||
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
|
||||
shs:x:1000:1000:Sandra Henry-Stocker,,,:/home/shs:/bin/bash
|
||||
nemo:x:1001:1001:Nemo,,,:/home/nemo:/usr/bin/zsh
|
||||
dory:x:1002:1002:Dory,,,:/home/dory:/bin/bash
|
||||
```
|
||||
|
||||
### 在 awk 中进行数学计算
|
||||
|
||||
`awk` 提供了惊人的数学计算能力,并且可以开平方,算 `log`,算 `tan` 等等。
|
||||
|
||||
这里有一对例子:
|
||||
|
||||
```
|
||||
$ awk 'BEGIN {print sqrt(2019)}'
|
||||
44.9333
|
||||
$ awk 'BEGIN {print log(2019)}'
|
||||
7.61036
|
||||
```
|
||||
|
||||
想要详细了解 `awk` 的数学计算能力,可以看《[使用 awk 进行数学计算][3]》这篇文章。
|
||||
|
||||
### awk 脚本
|
||||
|
||||
你也可以使用 `awk` 写一套单独的脚本。下面的例子模仿了之前写过的一个,不过还计算了系统里账户的数量。
|
||||
|
||||
```
|
||||
#!/usr/bin/awk -f
|
||||
|
||||
# 这一行是注释
|
||||
|
||||
BEGIN {
|
||||
printf "%s\n","User accounts:"
|
||||
print "=============="
|
||||
FS=":"
|
||||
n=0
|
||||
}
|
||||
|
||||
# 现在开始遍历数据
|
||||
{
|
||||
if ($3 >= 1000) {
|
||||
print $1
|
||||
n ++
|
||||
}
|
||||
}
|
||||
|
||||
END {
|
||||
print "=============="
|
||||
print n " accounts"
|
||||
}
|
||||
```
|
||||
|
||||
注意 `BEGIN` 那一节是如何提供标题、指定字段分隔符和初始化计数器的,它仅在脚本初始化时期执行。这个脚本也包含 `END` 节,它仅在中间所有命令处理完成之后运行,显示了所有中间小节所筛选数据的最终行数(第三个字段大于等于 1000)。
|
||||
|
||||
作为一个长存于 Unix 之上的命令,`awk` 依旧提供着非常有用的服务,这也是我几十年前爱上 Unix 的原因之一。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.networkworld.com/article/3454979/the-many-faces-of-awk.html
|
||||
|
||||
作者:[Sandra Henry-Stocker][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[LuuMing](https://github.com/LuuMing)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://www.networkworld.com/author/Sandra-Henry_Stocker/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://www.networkworld.com/newsletters/signup.html
|
||||
[2]: 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)
|
||||
[3]: https://www.networkworld.com/article/2974753/doing-math-with-awk.html
|
||||
[4]: https://www.facebook.com/NetworkWorld/
|
||||
[5]: https://www.linkedin.com/company/network-world
|
||||
[6]:https://images.techhive.com/images/article/2015/09/thinkstockphotos-512100549-100611755-large.jpg
|
@ -0,0 +1,259 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11637-1.html)
|
||||
[#]: subject: (5 Commands to Find the IP Address of a Domain in the Linux Terminal)
|
||||
[#]: via: (https://www.2daygeek.com/linux-command-find-check-domain-ip-address/)
|
||||
[#]: author: (Magesh Maruthamuthu https://www.2daygeek.com/author/magesh/)
|
||||
|
||||
5 个用于在 Linux 终端中查找域名 IP 地址的命令
|
||||
======
|
||||
|
||||

|
||||
|
||||
本教程介绍了如何在 Linux 终端验证域名或计算机名的 IP 地址。本教程将允许你一次检查多个域。你可能已经使用过这些命令来验证信息。但是,我们将教你如何有效使用这些命令在 Linux 终端中识别多个域的 IP 地址信息。
|
||||
|
||||
可以使用以下 5 个命令来完成此操作。
|
||||
|
||||
* `dig` 命令:它是一个用于查询 DNS 名称服务器的灵活命令行工具。
|
||||
* `host` 命令:它是用于执行 DNS 查询的简单程序。
|
||||
* `nslookup` 命令:它用于查询互联网域名服务器。
|
||||
* `fping` 命令:它用于向网络主机发送 ICMP ECHO_REQUEST 数据包。
|
||||
* `ping` 命令:它用于向网络主机发送 ICMP ECHO_REQUEST 数据包。
|
||||
|
||||
为了测试,我们创建了一个名为 `domains-list.txt` 的文件,并添加了以下域。
|
||||
|
||||
```
|
||||
# vi /opt/scripts/domains-list.txt
|
||||
|
||||
2daygeek.com
|
||||
magesh.co.in
|
||||
linuxtechnews.com
|
||||
```
|
||||
|
||||
### 方法 1:如何使用 dig 命令查找域的 IP 地址
|
||||
|
||||
[dig 命令][1]代表 “<ruby>域名信息抓手<rt>Domain Information Groper</rt></ruby>”,它是一个功能强大且灵活的命令行工具,用于查询 DNS 名称服务器。
|
||||
|
||||
它执行 DNS 查询,并显示来自查询的名称服务器的返回信息。大多数 DNS 管理员使用 `dig` 命令来解决 DNS 问题,因为它灵活、易用且输出清晰。
|
||||
|
||||
它还有批处理模式,可以从文件读取搜索请求。
|
||||
|
||||
```
|
||||
# dig 2daygeek.com | awk '{print $1,$5}'
|
||||
|
||||
2daygeek.com. 104.27.157.177
|
||||
2daygeek.com. 104.27.156.177
|
||||
```
|
||||
|
||||
使用以下 bash 脚本查找多个域的 IP 地址。
|
||||
|
||||
```
|
||||
# vi /opt/scripts/dig-command.sh
|
||||
|
||||
#!/bin/bash
|
||||
for server in `cat /opt/scripts/domains-list.txt`
|
||||
do echo $server "-"
|
||||
dig $server +short
|
||||
done | paste -d " " - - -
|
||||
```
|
||||
|
||||
添加以上内容到脚本后,给 `dig-command.sh` 文件设置可执行权限。
|
||||
|
||||
```
|
||||
# chmod +x /opt/scripts/dig-command.sh
|
||||
```
|
||||
|
||||
最后运行 bash 脚本获得输出。
|
||||
|
||||
```
|
||||
# sh /opt/scripts/dig-command.sh
|
||||
|
||||
2daygeek.com - 104.27.156.177 104.27.157.177
|
||||
magesh.co.in - 104.18.35.52 104.18.34.52
|
||||
linuxtechnews.com - 104.27.144.3 104.27.145.3
|
||||
```
|
||||
|
||||
如果要在一行中运行上面的脚本,请使用以下脚本。
|
||||
|
||||
```
|
||||
# for server in 2daygeek.com magesh.co.in linuxtechnews.com; do echo $server "-"; dig $server +short; done | paste -d " " - - -
|
||||
```
|
||||
|
||||
或者,你可以使用以下 Shell 脚本查找多个域的 IP 地址。
|
||||
|
||||
```
|
||||
# for server in 2daygeek.com magesh.co.in linuxtechnews.com; do dig $server | awk '{print $1,$5}'; done
|
||||
|
||||
2daygeek.com. 104.27.157.177
|
||||
2daygeek.com. 104.27.156.177
|
||||
magesh.co.in. 104.18.34.52
|
||||
magesh.co.in. 104.18.35.52
|
||||
linuxtechnews.com. 104.27.144.3
|
||||
linuxtechnews.com. 104.27.145.3
|
||||
```
|
||||
|
||||
### 方法 2:如何使用 host 命令查找域的 IP 地址
|
||||
|
||||
[host 命令][2]是一个简单的命令行程序,用于执行 [DNS 查询][3]。它通常用于将名称转换为 IP 地址,反之亦然。如果未提供任何参数或选项,`host` 将打印它的命令行参数和选项摘要。
|
||||
|
||||
你可以在 `host` 命令中添加特定选项或记录类型来查看域中的所有记录类型。
|
||||
|
||||
```
|
||||
# host 2daygeek.com | grep "has address" | sed 's/has address/-/g'
|
||||
|
||||
2daygeek.com - 104.27.157.177
|
||||
2daygeek.com - 104.27.156.177
|
||||
```
|
||||
|
||||
使用以下 bash 脚本查找多个域的 IP 地址。
|
||||
|
||||
```
|
||||
# vi /opt/scripts/host-command.sh
|
||||
|
||||
for server in `cat /opt/scripts/domains-list.txt`
|
||||
do host $server | grep "has address" | sed 's/has address/-/g'
|
||||
done
|
||||
```
|
||||
|
||||
添加以上内容到脚本后,给 `host-command.sh` 文件设置可执行权限。
|
||||
|
||||
```
|
||||
# chmod +x /opt/scripts/host-command.sh
|
||||
```
|
||||
|
||||
最后运行 bash 脚本获得输出。
|
||||
|
||||
```
|
||||
# sh /opt/scripts/host-command.sh
|
||||
|
||||
2daygeek.com - 104.27.156.177
|
||||
2daygeek.com - 104.27.157.177
|
||||
magesh.co.in - 104.18.35.52
|
||||
magesh.co.in - 104.18.34.52
|
||||
linuxtechnews.com - 104.27.144.3
|
||||
linuxtechnews.com - 104.27.145.3
|
||||
```
|
||||
|
||||
### 方法 3:如何使用 nslookup 命令查找域的 IP 地址
|
||||
|
||||
[nslookup 命令][4]是用于查询互联网[域名服务器(DNS)] [5]的程序。
|
||||
|
||||
`nslookup` 有两种模式,分别是交互式和非交互式。交互模式允许用户查询名称服务器以获取有关各种主机和域的信息,或打印域中的主机列表。非交互模式用于仅打印主机或域的名称和请求的信息。
|
||||
|
||||
它是一个网络管理工具,可以帮助诊断和解决 DNS 相关问题。
|
||||
|
||||
```
|
||||
# nslookup -q=A 2daygeek.com | tail -n+4 | sed -e '/^$/d' -e 's/Address://g' | grep -v 'Name|answer' | xargs -n1
|
||||
|
||||
104.27.157.177
|
||||
104.27.156.177
|
||||
```
|
||||
|
||||
使用以下 bash 脚本查找多个域的 IP 地址。
|
||||
|
||||
```
|
||||
# vi /opt/scripts/nslookup-command.sh
|
||||
|
||||
#!/bin/bash
|
||||
for server in `cat /opt/scripts/domains-list.txt`
|
||||
do echo $server "-"
|
||||
nslookup -q=A $server | tail -n+4 | sed -e '/^$/d' -e 's/Address://g' | grep -v 'Name|answer' | xargs -n1 done | paste -d " " - - -
|
||||
```
|
||||
|
||||
添加以上内容到脚本后,给 `nslookup-command.sh` 文件设置可执行权限。
|
||||
|
||||
```
|
||||
# chmod +x /opt/scripts/nslookup-command.sh
|
||||
```
|
||||
|
||||
最后运行 bash 脚本获得输出。
|
||||
|
||||
```
|
||||
# sh /opt/scripts/nslookup-command.sh
|
||||
|
||||
2daygeek.com - 104.27.156.177 104.27.157.177
|
||||
magesh.co.in - 104.18.35.52 104.18.34.52
|
||||
linuxtechnews.com - 104.27.144.3 104.27.145.3
|
||||
```
|
||||
|
||||
### 方法 4:如何使用 fping 命令查找域的 IP 地址
|
||||
|
||||
[fping 命令][6]是类似 `ping` 之类的程序,它使用互联网控制消息协议(ICMP)echo 请求来确定目标主机是否响应。
|
||||
|
||||
`fping` 与 `ping` 不同,因为它允许用户并行 ping 任意数量的主机。另外,它可以从文本文件输入主机。
|
||||
|
||||
`fping` 发送 ICMP echo 请求,并以循环方式移到下一个目标,并且不等到目标主机做出响应。
|
||||
|
||||
如果目标主机答复,那么将其标记为活动主机并从要检查的目标列表中删除;如果目标在特定时间限制和/或重试限制内未响应,那么将其指定为不可访问。
|
||||
|
||||
```
|
||||
# fping -A -d 2daygeek.com magesh.co.in linuxtechnews.com
|
||||
|
||||
104.27.157.177 (104.27.157.177) is alive
|
||||
104.18.35.52 (104.18.35.52) is alive
|
||||
104.27.144.3 (104.27.144.3) is alive
|
||||
```
|
||||
|
||||
### 方法 5:如何使用 ping 命令查找域的 IP 地址
|
||||
|
||||
[ping 命令][6](<ruby>数据包互联网抓手<rt>Packet Internet Groper</rt></ruby>)是一个网络程序,用于测试 Internet 协议(IP)网络上主机的可用性/连接性。
|
||||
|
||||
通过向目标主机发送互联网控制消息协议(ICMP)Echo 请求数据包并等待 ICMP Echo 应答来验证主机的可用性。
|
||||
|
||||
它基于发送的数据包、接收的数据包、丢失的数据包,通常包含最小/平均/最大时间来汇总统计结果。
|
||||
|
||||
```
|
||||
# ping -c 2 2daygeek.com | head -2 | tail -1 | awk '{print $5}' | sed 's/[(:)]//g'
|
||||
|
||||
104.27.157.177
|
||||
```
|
||||
|
||||
使用以下 bash 脚本查找多个域的 IP 地址。
|
||||
|
||||
```
|
||||
# vi /opt/scripts/ping-command.sh
|
||||
|
||||
#!/bin/bash
|
||||
for server in `cat /opt/scripts/domains-list.txt`
|
||||
do echo $server "-"
|
||||
ping -c 2 $server | head -2 | tail -1 | awk '{print $5}' | sed 's/[(:)]//g'
|
||||
done | paste -d " " - -
|
||||
```
|
||||
|
||||
添加以上内容到脚本后,给 `ping-command.sh` 文件设置可执行权限。
|
||||
|
||||
```
|
||||
# chmod +x /opt/scripts/ping-command.sh
|
||||
```
|
||||
|
||||
最后运行 bash 脚本获得输出。
|
||||
|
||||
```
|
||||
# sh /opt/scripts/ping-command.sh
|
||||
|
||||
2daygeek.com - 104.27.156.177
|
||||
magesh.co.in - 104.18.35.52
|
||||
linuxtechnews.com - 104.27.144.3
|
||||
```
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.2daygeek.com/linux-command-find-check-domain-ip-address/
|
||||
|
||||
作者:[Magesh Maruthamuthu][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://www.2daygeek.com/author/magesh/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://www.2daygeek.com/dig-command-check-find-dns-records-lookup-linux/
|
||||
[2]: https://www.2daygeek.com/linux-host-command-check-find-dns-records-lookup/
|
||||
[3]: https://www.2daygeek.com/category/dns-lookup/
|
||||
[4]: https://www.2daygeek.com/nslookup-command-check-find-dns-records-lookup-linux/
|
||||
[5]: https://www.2daygeek.com/check-find-dns-records-of-domain-in-linux-terminal/
|
||||
[6]: https://www.2daygeek.com/how-to-use-ping-fping-gping-in-linux/
|
140
published/20191127 How to write a Python web API with Flask.md
Normal file
140
published/20191127 How to write a Python web API with Flask.md
Normal file
@ -0,0 +1,140 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (hj24)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11701-1.html)
|
||||
[#]: subject: (How to write a Python web API with Flask)
|
||||
[#]: via: (https://opensource.com/article/19/11/python-web-api-flask)
|
||||
[#]: author: (Rachel Waston https://opensource.com/users/rachelwaston)
|
||||
|
||||
如何使用 Flask 编写 Python Web API
|
||||
======
|
||||
|
||||
> 这是一个快速教程,用来展示如何通过 Flask(目前发展最迅速的 Python 框架之一)来从服务器获取数据。
|
||||
|
||||
![spiderweb diagram][1]
|
||||
|
||||
[Python][2] 是一个以语法简洁著称的高级的、面向对象的程序语言。它一直都是一个用来构建 RESTful API 的顶级编程语言。
|
||||
|
||||
[Flask][3] 是一个高度可定制化的 Python 框架,可以为开发人员提供用户访问数据方式的完全控制。Flask 是一个基于 Werkzeug 的 [WSGI][4] 工具包和 Jinja 2 模板引擎的”微框架“。它是一个被设计来开发 RESTful API 的 web 框架。
|
||||
|
||||
Flask 是 Python 发展最迅速的框架之一,很多知名网站如:Netflix、Pinterest 和 LinkedIn 都将 Flask 纳入了它们的开发技术栈。下面是一个简单的示例,展示了 Flask 是如何允许用户通过 HTTP GET 请求来从服务器获取数据的。
|
||||
|
||||
### 初始化一个 Flask 应用
|
||||
|
||||
首先,创建一个你的 Flask 项目的目录结构。你可以在你系统的任何地方来做这件事。
|
||||
|
||||
```
|
||||
$ mkdir tutorial
|
||||
$ cd tutorial
|
||||
$ touch main.py
|
||||
$ python3 -m venv env
|
||||
$ source env/bin/activate
|
||||
(env) $ pip3 install flask-restful
|
||||
Collecting flask-restful
|
||||
Downloading https://files.pythonhosted.org/packages/17/44/6e49...8da4/Flask_RESTful-0.3.7-py2.py3-none-any.whl
|
||||
Collecting Flask>=0.8 (from flask-restful)
|
||||
[...]
|
||||
```
|
||||
|
||||
### 导入 Flask 模块
|
||||
|
||||
然后,在你的 `main.py` 代码中导入 `flask` 模块和它的 `flask_restful` 库:
|
||||
|
||||
```
|
||||
from flask import Flask
|
||||
from flask_restful import Resource, Api
|
||||
|
||||
app = Flask(__name__)
|
||||
api = Api(app)
|
||||
|
||||
class Quotes(Resource):
|
||||
def get(self):
|
||||
return {
|
||||
'William Shakespeare': {
|
||||
'quote': ['Love all,trust a few,do wrong to none',
|
||||
'Some are born great, some achieve greatness, and some greatness thrust upon them.']
|
||||
},
|
||||
'Linus': {
|
||||
'quote': ['Talk is cheap. Show me the code.']
|
||||
}
|
||||
}
|
||||
|
||||
api.add_resource(Quotes, '/')
|
||||
|
||||
if __name__ == '__main__':
|
||||
app.run(debug=True)
|
||||
```
|
||||
|
||||
### 运行 app
|
||||
|
||||
Flask 包含一个内建的用于测试的 HTTP 服务器。来测试一下这个你创建的简单的 API:
|
||||
|
||||
```
|
||||
(env) $ python main.py
|
||||
* Serving Flask app "main" (lazy loading)
|
||||
* Environment: production
|
||||
WARNING: This is a development server. Do not use it in a production deployment.
|
||||
Use a production WSGI server instead.
|
||||
* Debug mode: on
|
||||
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
|
||||
```
|
||||
|
||||
启动开发服务器时将启动 Flask 应用程序,该应用程序包含一个名为 `get` 的方法来响应简单的 HTTP GET 请求。你可以通过 `wget`、`curl` 命令或者任意的 web 浏览器来测试它。
|
||||
|
||||
```
|
||||
$ curl http://localhost:5000
|
||||
{
|
||||
"William Shakespeare": {
|
||||
"quote": [
|
||||
"Love all,trust a few,do wrong to none",
|
||||
"Some are born great, some achieve greatness, and some greatness thrust upon them."
|
||||
]
|
||||
},
|
||||
"Linus": {
|
||||
"quote": [
|
||||
"Talk is cheap. Show me the code."
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
要查看使用 Python 和 Flask 的类似 Web API 的更复杂版本,请导航至美国国会图书馆的 [Chronicling America][5] 网站,该网站可提供有关这些信息的历史报纸和数字化报纸。
|
||||
|
||||
### 为什么使用 Flask?
|
||||
|
||||
Flask 有以下几个主要的优点:
|
||||
|
||||
1. Python 很流行并且广泛被应用,所以任何熟悉 Python 的人都可以使用 Flask 来开发。
|
||||
2. 它轻巧而简约。
|
||||
3. 考虑安全性而构建。
|
||||
4. 出色的文档,其中包含大量清晰,有效的示例代码。
|
||||
|
||||
还有一些潜在的缺点:
|
||||
|
||||
1. 它轻巧而简约。但如果你正在寻找具有大量捆绑库和预制组件的框架,那么这可能不是最佳选择。
|
||||
2. 如果必须围绕 Flask 构建自己的框架,则你可能会发现维护自定义项的成本可能会抵消使用 Flask 的好处。
|
||||
|
||||
|
||||
如果你要构建 Web 程序或 API,可以考虑选择 Flask。它功能强大且健壮,并且其优秀的项目文档使入门变得容易。试用一下,评估一下,看看它是否适合你的项目。
|
||||
|
||||
在本课中了解更多信息关于 Python 异常处理以及如何以安全的方式进行操作。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/19/11/python-web-api-flask
|
||||
|
||||
作者:[Rachel Waston][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[hj24](https://github.com/hj24)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/rachelwaston
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/web-cms-build-howto-tutorial.png?itok=bRbCJt1U (spiderweb diagram)
|
||||
[2]: https://www.python.org/
|
||||
[3]: https://palletsprojects.com/p/flask/
|
||||
[4]: https://en.wikipedia.org/wiki/Web_Server_Gateway_Interface
|
||||
[5]: https://chroniclingamerica.loc.gov/about/api
|
@ -0,0 +1,54 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11640-1.html)
|
||||
[#]: subject: (Nvidia quietly unveils faster, lower power Tesla GPU accelerator)
|
||||
[#]: via: (https://www.networkworld.com/article/3482097/nvidia-quietly-unveils-faster-lower-power-tesla-gpu-accelerator.html)
|
||||
[#]: author: (Andy Patrizio https://www.networkworld.com/author/Andy-Patrizio/)
|
||||
|
||||
Nvidia 悄悄推出更快、更低功耗的 Tesla GPU 加速器
|
||||
======
|
||||
|
||||
> Nvidia 升级了其 Volta 系列的 Tesla GPU 加速卡,使其能够以旧型号的相同功率更快地工作。
|
||||
|
||||

|
||||
|
||||
Nvidia 上周举行了 Supercomputing 19 大会,不出意外的是公布了很多新闻,这些我们将稍后提到。但被忽略的一条或许是其中最有趣的:一张更快、功耗更低的新一代图形加速卡。
|
||||
|
||||
多名与会者与多个新闻站点发现了这点,Nvidia 向我证实这确实是一张新卡。Nvidia 的 “Volta” 这代 Tesla GPU 加速卡在 2017 年就已淘汰,因此升级工作应该早已过期。
|
||||
|
||||
V100S 目前仅提供 PCI Express 3 接口,但有望最终支持 Nvidia 的 SXM2 接口。SXM 是 Nvidia 的双插槽卡设计,与 PCIe 卡不同,它不需要连接电源。SXM2 允许 GPU 通过 Nvidia 的 NVLink(一种高带宽、节能的互连)相互之间或与 CPU 进行通信,其数据传输速度比 PCIe 快十倍。
|
||||
|
||||
借助此卡,Nvidia 声称拥有单精度 16.4 TFLOPS,双精度 8.2 TFLOPS 并且 Tensor Core 性能高达 130 TFLOPS。这仅比 V100 SXM2 设计提高了 4% 至 5%,但比 PCIe V100 变体提高了 16% 至 17%。
|
||||
|
||||
内存容量保持在 32 GB,但 Nvidia 添加了 High Bandwidth Memory 2(HBM2),以将内存性能提高到 1,134 GB/s,这比 PCIe 和 SXM2 都提高了 26%。
|
||||
|
||||
通常情况下,性能提升将同时导致功率增加,但在这里,PCIe 卡的总体功率为 250 瓦,与上一代 PCIe 卡相同。因此,在相同功耗下,该卡可额外提供 16-17% 的计算性能,并增加 26% 的内存带宽。
|
||||
|
||||
### 其他新闻
|
||||
|
||||
Nvidia 在会上还发布了其他新闻:
|
||||
|
||||
* 其 GPU 加速的基于 Arm 的高性能计算参考服务器的新参考设计和生态系统支持。该公司表示,它得到了 HPE/Cray、Marvell、富士通和 Ampere 的支持,Ampere 是 Intel 前高管勒尼·詹姆斯(Renee James)领导的一家初创公司,它希望建立基于 Arm 的服务器处理器。
|
||||
* 这些公司将使用 Nvidia 的参考设计(包括硬件和软件组件)来使用 GPU 构建从超大规模云提供商到高性能存储和百亿亿次超级计算等。该设计还带来了 CUDA-X,这是 Nvidia 用于 Arm 处理器的 CUDA GPU 的特殊版本开发语言。
|
||||
* 推出 Nvidia Magnum IO 套件,旨在帮助数据科学家和 AI 以及高性能计算研究人员在几分钟而不是几小时内处理大量数据。它经过优化,消除了存储和 I/O 瓶颈,可为多服务器、多 GPU 计算节点提供高达 20 倍的数据处理速度。
|
||||
* Nvidia 和 DDN (AI 以及多云数据管理开发商)宣布将 DDN 的 A3ITM 数据管理系统与 Nvidia 的 DGX SuperPOD 系统捆绑在一起,以便客户能够以最小的复杂性和更短的时限部署 HPC 基础架构。SuperPOD 还带有新的 NVIDIA Magnum IO 软件栈。
|
||||
* DDN 表示,SuperPOD 能够在数小时内部署,并且单个设备可扩展至 80 个节点。不同的深度学习模型的基准测试表明,DDN 系统可以使 DGXSuperPOD 系统完全保持数据饱和。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.networkworld.com/article/3482097/nvidia-quietly-unveils-faster-lower-power-tesla-gpu-accelerator.html
|
||||
|
||||
作者:[Andy Patrizio][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://www.networkworld.com/author/Andy-Patrizio/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://www.networkworld.com/newsletters/signup.html
|
||||
[4]: https://www.facebook.com/NetworkWorld/
|
||||
[5]: https://www.linkedin.com/company/network-world
|
113
published/20191129 A quick introduction to Toolbox on Fedora.md
Normal file
113
published/20191129 A quick introduction to Toolbox on Fedora.md
Normal file
@ -0,0 +1,113 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11651-1.html)
|
||||
[#]: subject: (A quick introduction to Toolbox on Fedora)
|
||||
[#]: via: (https://fedoramagazine.org/a-quick-introduction-to-toolbox-on-fedora/)
|
||||
[#]: author: (Ryan Walter https://fedoramagazine.org/author/rwaltr/)
|
||||
|
||||
Fedora 中的 Toolbox 简介
|
||||
======
|
||||
|
||||
![][1]
|
||||
|
||||
Toolbox 使你可以[在容器中分类和管理开发环境][2],而无需 root 权限或手动添加卷。它创建一个容器,你可以在其中安装自己的命令行工具,而无需在基础系统中安装它们。当你没有 root 权限或无法直接安装程序时,也可以使用它。本文会介绍 Toolbox 及其功能。
|
||||
|
||||
### 安装 Toolbox
|
||||
|
||||
[Silverblue][3] 默认包含 Toolbox。对于 Workstation 和 Server 版本,你可以使用 `dnf install toolbox` 从默认仓库中获取它。
|
||||
|
||||
### 创建 Toolbox
|
||||
|
||||
打开终端并运行 `toolbox enter`。程序将自动请求许可来下载最新的镜像,创建第一个容器并将你的 shell 放在该容器中。
|
||||
|
||||
```
|
||||
$ toolbox enter
|
||||
No toolbox containers found. Create now? [y/N] y
|
||||
Image required to create toolbox container.
|
||||
Download registry.fedoraproject.org/f30/fedora-toolbox:30 (500MB)? [y/N]: y
|
||||
```
|
||||
|
||||
当前,Toolbox 和你的基本系统之间没有区别。你的文件系统和软件包未曾改变。下面是一个使用仓库的示例,它包含 `~/src/resume` 文件夹下的简历的文档源文件。简历是使用 `pandoc` 工具构建的。
|
||||
|
||||
```
|
||||
$ pwd
|
||||
/home/rwaltr
|
||||
$ cd src/resume/
|
||||
$ head -n 5 Makefile
|
||||
all: pdf html rtf text docx
|
||||
|
||||
pdf: init
|
||||
pandoc -s -o BUILDS/resume.pdf markdown/*
|
||||
|
||||
$ make pdf
|
||||
bash: make: command not found
|
||||
$ pandoc -v
|
||||
bash: pandoc: command not found
|
||||
```
|
||||
|
||||
这个 toolbox 没有构建简历所需的程序。你可以通过使用 `dnf` 安装工具来解决此问题。由于正在容器中运行,因此不会提示你输入 root 密码。
|
||||
|
||||
```
|
||||
$ sudo dnf groupinstall "Authoring and Publishing" -y && sudo dnf install pandoc make -y
|
||||
...
|
||||
$ make all #Successful builds
|
||||
mkdir -p BUILDS
|
||||
pandoc -s -o BUILDS/resume.pdf markdown/*
|
||||
pandoc -s -o BUILDS/resume.html markdown/*
|
||||
pandoc -s -o BUILDS/resume.rtf markdown/*
|
||||
pandoc -s -o BUILDS/resume.txt markdown/*
|
||||
pandoc -s -o BUILDS/resume.docx markdown/*
|
||||
$ ls BUILDS/
|
||||
resume.docx resume.html resume.pdf resume.rtf resume.txt
|
||||
```
|
||||
|
||||
运行 `exit` 可以退出 toolbox。
|
||||
|
||||
```
|
||||
$ cd BUILDS/
|
||||
$ pandoc --version || ls
|
||||
pandoc 2.2.1
|
||||
Compiled with pandoc-types 1.17.5.4, texmath 0.11.1.2, skylighting 0.7.5
|
||||
...
|
||||
for a particular purpose.
|
||||
resume.docx resume.html resume.pdf resume.rtf resume.txt
|
||||
$ exit
|
||||
logout
|
||||
$ pandoc --version || ls
|
||||
bash: pandoc: command not found...
|
||||
resume.docx resume.html resume.pdf resume.rtf resume.txt
|
||||
```
|
||||
|
||||
你会在主目录中得到由 toolbox 创建的文件。而在 toolbox 中安装的程序无法在外部访问。
|
||||
|
||||
### 提示和技巧
|
||||
|
||||
本介绍仅涉及 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 的更多信息。)
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://fedoramagazine.org/a-quick-introduction-to-toolbox-on-fedora/
|
||||
|
||||
作者:[Ryan Walter][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://fedoramagazine.org/author/rwaltr/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://fedoramagazine.org/wp-content/uploads/2019/11/toolbox-816x345.jpg
|
||||
[2]: https://docs.fedoraproject.org/en-US/fedora-silverblue/toolbox/
|
||||
[3]: https://fedoramagazine.org/what-is-silverblue/
|
||||
[4]: https://podman.io/
|
||||
[5]: https://fedoramagazine.org/running-containers-with-podman/
|
||||
[6]: https://flickr.com/photos/florianric/
|
||||
[7]: https://flickr.com/photos/florianric/7263382550/
|
63
published/20191202 Use the Window Maker desktop on Linux.md
Normal file
63
published/20191202 Use the Window Maker desktop on Linux.md
Normal file
@ -0,0 +1,63 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11650-1.html)
|
||||
[#]: subject: (Use the Window Maker desktop on Linux)
|
||||
[#]: via: (https://opensource.com/article/19/12/linux-window-maker-desktop)
|
||||
[#]: author: (Seth Kenlon https://opensource.com/users/seth)
|
||||
|
||||
在 Linux 上使用 Window Maker 桌面
|
||||
======
|
||||
> 本文是 24 天 Linux 桌面特别系列的一部分。让我们和 Window Maker 一起时光倒流,它为如今的用户实现了老式 Unix NeXTSTEP 环境。
|
||||
|
||||
![Penguin with green background][1]
|
||||
|
||||
在 Mac OS X 之前,有一个奇怪的闭源 Unix 系统,称为 [NeXTSTEP][2]。Sun Microsystems 后来将 NeXTSTEP 的底层设为开放规范,这使其它项目可以创建许多自由开源的 NeXT 库和组件。GNUStep 实现了许多 NeXTSTEP 库,而 [Window Maker][3] 实现了其桌面环境。
|
||||
|
||||
Window Maker 非常接近地模仿了 NeXTSTEP 桌面 GUI,并提供了一个有趣的视角,可以让人了解 80 年代末 90 年代初的 Unix 是什么样子的。它还揭示了窗口管理器(例如 Fluxbox 和 Openbox)背后的一些基本概念。
|
||||
|
||||
你可以从发行版的仓库中安装 Window Maker。要尝试它,请在安装完成后退出桌面会话。默认情况下,会话管理器(KDM、GDM、LightDM 或 XDM,这取决于你的设置)将继续将登录到默认桌面,因此登录时必须覆盖默认设置。
|
||||
|
||||
要在 GDM 上切换到 Window Maker:
|
||||
|
||||
![Selecting the Window Maker desktop in GDM][4]
|
||||
|
||||
在 KDM 上:
|
||||
|
||||
![Selecting the Window Maker desktop in KDM][5]
|
||||
|
||||
### Window Maker 程序坞
|
||||
|
||||
默认情况下,Window Maker 桌面是空的,但每个角落都有几个*程序坞*。像在 NeXTSTEP 中一样,在 Window Maker 中,在程序坞区域,应用可最小化成图标后停靠,可创建启动器来快速访问常见应用,并且可运行微型的 “dockapp”。
|
||||
|
||||
你可以在软件仓库中搜索 “dockapp” 来试用 dockapp。它们常常是网络和系统监控器、音频设置面板、时钟等。这是在 Fedora 上运行的 Window Maker:
|
||||
|
||||
![Window Maker running on Fedora][6]
|
||||
|
||||
### 应用菜单
|
||||
|
||||
要访问应用菜单,请右键单击桌面上的任意位置。要关闭它,请再次单击鼠标右键。Window Maker 不是桌面环境(DE),而是一个窗口管理器(DM)。它可以帮助你安排和管理窗口。它唯一捆绑的程序是 [WPrefs][7](或更常见的说法 Window Maker 偏好),它可帮助你配置常用设置,而应用菜单则提供对其他选项(包括主题)的访问。
|
||||
|
||||
运行什么应用完全由你决定。在 Window Maker 中,你可以选择运行 KDE 应用、GNOME 应用以及不被视为任何其他主流桌面应用的程序。你可以创建自己的工作环境,并且可以使用 Window Maker 对其进行管理。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/19/12/linux-window-maker-desktop
|
||||
|
||||
作者:[Seth Kenlon][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [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/linux_penguin_green.png?itok=ENdVzW22 (Penguin with green background)
|
||||
[2]: https://en.wikipedia.org/wiki/NeXTSTEP
|
||||
[3]: https://www.windowmaker.org/
|
||||
[4]: https://opensource.com/sites/default/files/uploads/advent-windowmaker-gdm.jpg (Selecting the Window Maker desktop in GDM)
|
||||
[5]: https://opensource.com/sites/default/files/uploads/advent-windowmaker-kdm.jpg (Selecting the Window Maker desktop in KDM)
|
||||
[6]: https://opensource.com/sites/default/files/uploads/advent-windowmaker.jpg (Window Maker running on Fedora)
|
||||
[7]: http://www.windowmaker.org/docs/guidedtour/prefs.html
|
@ -0,0 +1,72 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (algzjh)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11681-1.html)
|
||||
[#]: subject: (An idiot's guide to Kubernetes, low-code developers, and other industry trends)
|
||||
[#]: via: (https://opensource.com/article/19/12/technology-advice-and-other-industry-trends)
|
||||
[#]: author: (Tim Hildred https://opensource.com/users/thildred)
|
||||
|
||||
每周开源点评:Kubernetes 傻瓜指南、低代码开发人员和其他行业趋势
|
||||
======
|
||||
> 每周开源社区、市场和行业趋势。
|
||||
|
||||
![Person standing in front of a giant computer screen with numbers, data][1]
|
||||
|
||||
作为我在具有开源开发模型的企业软件公司担任高级产品营销经理的角色的一部分,我为产品营销人员、经理和其他影响者定期发布有关开源社区,市场和行业趋势的定期更新。这里有该更新中我和他们最喜欢的四篇文章。
|
||||
|
||||
### Kubernetes 傻瓜指南
|
||||
|
||||
- [文章链接][2]
|
||||
|
||||
> Kubernetes 已经发展出了新的特性,这使其成为企业软件的更好的容器平台。安全性和高级网络等元素已被纳入 Kubernetes 上游代码的主体,并且现在可供所有人使用。
|
||||
>
|
||||
> 然而,企业解决方案的其他方面总会有补充需求;比如日志记录和性能监控。这就是像 Istio 等辅助包发挥作用的地方,它带来了额外的功能,但是仍使 Kubernetes 的核心保持了合理的大小和特性集。
|
||||
|
||||
**影响**: 我总是发现,人们很容易把对技术发展的认识视为理所当然。当与你打交道的每个人都处于“最前沿”时,你的观点就会歪曲到这样的程度:你甚至可能会认为对最新的(*此处插入首选技术*)一无所知的人跟不上潮流,而实际上这并没有开始影响他们做自己需要做的事情的能力。那些人不是白痴;他们是我们的朋友、客户、合作伙伴、合作者和社区。
|
||||
|
||||
### Gartner: 采用低代码开发之前应该考虑什么
|
||||
|
||||
- [文章链接][3]
|
||||
|
||||
> 尽管专注于商业 IT 团队,但 Gartner 发现,一个日益重要的开发人员社区是需要快速开发简单应用程序或构建最低可行产品或多体验功能的核心 IT 专业开发人员。当应用程序领导者在传统的应用程序项目中使用低代码时,他们可能希望使用标准的 IT DevOps 自动化方法和低代码工具。
|
||||
|
||||
**影响**: 越来越多的用例和用户体验可以通过需要更少时间和技能来创建的应用程序来处理和交互。而低代码开发人员也可能会结合成一个具有他们自己的规范和亚文化的独特群体。
|
||||
|
||||
### 诺基亚认为云原生对 5G 核心至关重要
|
||||
|
||||
- [文章链接][4]
|
||||
|
||||
> 诺基亚概述了 5G 的五个关键业务目标,这些目标只能通过云原生环境来实现。其中包括:更好的带宽、延迟和密度;通过网络切片将服务扩展到新的企业、行业和[物联网][5]市场;根据敏捷性和效率定义的快速服务部署;超越传统带宽、语音和信息传递的新服务;以及利用端到端网络获取更多收入的数字服务的出现。
|
||||
|
||||
**影响**: 在越来越多的事物连接到网络的情况下,这是最有意义的。4G 主要与越来越多的手机有关;只有当你开始连接其他所有东西时,5G 才是真正必要的。4G 意味着我们的手机上有更丰富的应用程序,而 5G 几乎与手机无关。
|
||||
|
||||
### API:隐藏的业务加速器
|
||||
|
||||
- [文章链接][6]
|
||||
|
||||
> 要想让组织成功地进行数字化转型,API 策略至关重要。从解锁有价值的数据到加快开发时间,API 都是数字时代的幕后英雄。那些已经尝试过 API 的人已经感受到了好处。例如,研究表明,使用 API 的企业中,有 53% 认为它们提高了生产力,而 29% 声称它们的收入增长是使用 API 的直接结果。当 API 被视为存在于一个项目之外的可发现和可重用的产品时,它有助于为持续的变更奠定灵活的基础。
|
||||
|
||||
**影响**: 隐藏的业务加速器实际上是这样一种思想,即功能应该以一种方式进行打包,使其能够在原始提供者没有预料到的环境中进行重新利用和组合。
|
||||
|
||||
我希望你喜欢这份上周给我留下深刻印象的列表,并于下周一回来了解更多开源社区、市场和行业的趋势。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/19/12/technology-advice-and-other-industry-trends
|
||||
|
||||
作者:[Tim Hildred][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[algzjh](https://github.com/algzjh)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/thildred
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/data_metrics_analytics_desktop_laptop.png?itok=9QXd7AUr "Person standing in front of a giant computer screen with numbers, data"
|
||||
[2]: https://www.cbronline.com/feature/an-idiots-guide-to-kubernetes
|
||||
[3]: https://www.computerweekly.com/feature/Gartner-What-to-consider-before-adopting-low-code-development
|
||||
[4]: https://www.sdxcentral.com/articles/news/nokia-argues-cloud-native-is-essential-to-5g-core/2019/11/
|
||||
[5]: https://www.sdxcentral.com/5g/iot/ "IoT"
|
||||
[6]: https://www.cbronline.com/opinion/digital-transformation-3
|
@ -0,0 +1,121 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (hj24)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11653-1.html)
|
||||
[#]: subject: (Using Ansible to organize your SSH keys in AWS)
|
||||
[#]: via: (https://fedoramagazine.org/using-ansible-to-organize-your-ssh-keys-in-aws/)
|
||||
[#]: author: (Daniel Leite de Abreu https://fedoramagazine.org/author/dabreu/)
|
||||
|
||||
在 AWS 中使用 Ansible 来管理你的 SSH 密钥
|
||||
======
|
||||
|
||||
![][1]
|
||||
|
||||
如果你长期使用亚马逊 Web 服务(AWS)中的实例,你可能会遇到下面这个常见的问题,它不是因为技术性的原因导致的,更多的是因为人类追求方便舒适的天性:当你登录一台你最近没有使用的区域的新实例,你最终会创建一个新的 SSH 密钥对,久而久之这最终就会造成个人拥有太多密钥,导致管理起来复杂混乱。
|
||||
|
||||
本文将会介绍一种在所有区域中使用你的公钥的方法。最近,一篇 [Fedora Magazine 的文章][2]介绍了另一种解决方案。但本文中的解决方案可以进一步的以更简洁和可扩展的方式实现自动化。
|
||||
|
||||
假设你有一个 Fedora 30 或 31 系统,其中存储了你的密钥,并且还安装了 Ansible。当这两件事同时满足时,就提供了解决这个问题的办法,甚至它还能做到更多。
|
||||
|
||||
使用 Ansible 的 [ec2_key 模块][3],你可以创建一个简单的 Ansible 剧本来在所有区域中维护你的 SSH 密钥对。如果你需要增加或者删除密钥,在 Ansible 中这就像从文件中添加和删除行一样简单。
|
||||
|
||||
### 设置和运行 Ansible 剧本
|
||||
|
||||
如果要使用剧本,首先需要安装 `ec2_key` 模块的必要依赖项:
|
||||
|
||||
```
|
||||
$ sudo dnf install python3-boto python3-boto3
|
||||
```
|
||||
|
||||
该剧本很简单:你只需要像下面的例子一样,修改其中的密钥及其对应的名称。然后,运行该剧本,它会帮你遍历所有列出的公共 AWS 区域。该示例还包括一些你可能要访问的受限区域,只需根据需要来取消对应行的注释,然后,保存文件重新运行剧本即可。
|
||||
|
||||
```
|
||||
---
|
||||
- name: Maintain an ssh key pair in ec2
|
||||
hosts: localhost
|
||||
connection: local
|
||||
gather_facts: no
|
||||
vars:
|
||||
ansible_python_interpreter: python
|
||||
tasks:
|
||||
- name: Make available your ssh public key in ec2 for new instances
|
||||
ec2_key:
|
||||
name: "YOUR KEY NAME GOES HERE"
|
||||
key_material: 'YOUR KEY GOES HERE'
|
||||
state: present
|
||||
region: "{{ item }}"
|
||||
with_items:
|
||||
- us-east-2 #US East (Ohio)
|
||||
- us-east-1 #US East (N. Virginia)
|
||||
- us-west-1 #US West (N. California)
|
||||
- us-west-2 #US West (Oregon)
|
||||
- ap-east-1 #Asia Pacific (Hong Kong)
|
||||
- ap-south-1 #Asia Pacific (Mumbai)
|
||||
- ap-northeast-2 #Asia Pacific (Seoul)
|
||||
- ap-southeast-1 #Asia Pacific (Singapore)
|
||||
- ap-southeast-2 #Asia Pacific (Sydney)
|
||||
- ap-northeast-1 #Asia Pacific (Tokyo)
|
||||
- ca-central-1 #Canada (Central)
|
||||
- eu-central-1 #EU (Frankfurt)
|
||||
- eu-west-1 #EU (Ireland)
|
||||
- eu-west-2 #EU (London)
|
||||
- eu-west-3 #EU (Paris)
|
||||
- eu-north-1 #EU (Stockholm)
|
||||
- me-south-1 #Middle East (Bahrain)
|
||||
- sa-east-1 #South America (Sao Paulo)
|
||||
# - us-gov-east-1 #AWS GovCloud (US-East)
|
||||
# - us-gov-west-1 #AWS GovCloud (US-West)
|
||||
# - ap-northeast-3 #Asia Pacific (Osaka-Local)
|
||||
# - cn-north-1 #China (Beijing)
|
||||
# - cn-northwest-1 #China (Ningxia)
|
||||
```
|
||||
|
||||
这个剧本需要通过 API 访问 AWS,为此,请使用环境变量,如下所示:
|
||||
|
||||
```
|
||||
$ AWS_ACCESS_KEY="aws-access-key-id" AWS_SECRET_KEY="aws-secret-key-id" ansible-playbook ec2-playbook.yml
|
||||
```
|
||||
|
||||
另一个方式是安装 aws 命令行工具并添加凭据,如以前的一篇 [Fedora Magazine 文章][4]所述。如果你在线存储它们,这些参数将**不建议**插入到剧本中!你可以在 [GitHub][5] 中找到本文的剧本代码。
|
||||
|
||||
完成该剧本之后,请确认你的密钥在 AWS 控制台上可用。为此,可以做如下操作:
|
||||
|
||||
1. 登录你的 AWS 控制台
|
||||
2. 转到 “EC2 > Key Pairs”
|
||||
3. 你应该会看到列出的密钥。唯一的限制是你必须使用此方法逐个区域来检查。
|
||||
|
||||
另一种方法是在 shell 中使用一个快速命令来为你做这些检查。
|
||||
|
||||
首先在剧本上创建一个包含所有区域的变量:
|
||||
|
||||
```
|
||||
AWS_REGION="us-east-1 us-west-1 us-west-2 ap-east-1 ap-south-1 ap-northeast-2 ap-southeast-1 ap-southeast-2 ap-northeast-1 ca-central-1 eu-central-1 eu-west-1 eu-west-2 eu-west-3 eu-north-1 me-south-1 sa-east-1"
|
||||
```
|
||||
|
||||
然后,执行如下循环,你就可以从 aws 的 API 获得结果:
|
||||
|
||||
```
|
||||
for each in ${AWS_REGION} ; do aws ec2 describe-key-pairs --key-name <YOUR KEY GOES HERE> ; done
|
||||
```
|
||||
|
||||
请记住,要执行上述操作,你需要安装 aws 命令行。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://fedoramagazine.org/using-ansible-to-organize-your-ssh-keys-in-aws/
|
||||
|
||||
作者:[Daniel Leite de Abreu][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[hj24](https://github.com/hj24)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://fedoramagazine.org/author/dabreu/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://fedoramagazine.org/wp-content/uploads/2019/12/ansible-aws-keys-816x345.jpg
|
||||
[2]: https://fedoramagazine.org/ssh-key-aws-regions/
|
||||
[3]: https://docs.ansible.com/ansible/latest/modules/ec2_key_module.html
|
||||
[4]: https://fedoramagazine.org/aws-tools-fedora/
|
||||
[5]: https://github.com/dlabreu/aws
|
@ -0,0 +1,72 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-11660-1.html)
|
||||
[#]: subject: (Why use the Pantheon desktop for Linux Elementary OS)
|
||||
[#]: via: (https://opensource.com/article/19/12/pantheon-linux-desktop)
|
||||
[#]: author: (Seth Kenlon https://opensource.com/users/seth)
|
||||
|
||||
为何 Elementary OS 中使用 Pantheon 桌面
|
||||
======
|
||||
|
||||
> 本文是 Linux 桌面特别系列的一部分。通过在 Elementary OS 上运行 Pantheon 桌面获得广受喜爱的 Mac OS 特性。
|
||||
|
||||

|
||||
|
||||
你愿意为 Linux 桌面支付 20 美元吗?事实上,我会在下载自由软件时选择支付更多的钱!我这样做的原因是开源是值得的。对于 [Elementary OS][2] 的拷贝,默认价格是 20 美元(你可以选择 1 美元,如果你无法负担,你甚至可以用 0 美元下载)。作为回报,你将获得一个出色且精心制作的发行版,同时拥有它自己的 Pantheon 桌面设计。
|
||||
|
||||
你可能会发现 Pantheon 已包含在软件仓库中,因为它是开源的,但你更可能需要下载并安装 [Elementary][3] Linux 才能体验它。如果你还不准备在计算机上将 Elementary 作为主操作系统,那么可以将其安装到虚拟机中,例如 [GNOME Boxes][4] 中。
|
||||
|
||||
Pantheon 桌面整洁、吸引人,并且有许多用户希望在桌面中获得的东西,但在普通的 Linux 桌面上却无法获得。
|
||||
|
||||
### Pantheon 桌面之旅
|
||||
|
||||
乍一看,Pantheon 桌面看起来有点像 Cinnamon、Budgie 或 GNOME 3 的经典模式。但是,Pantheon 最令人兴奋的功能是极小的接触。它在你很少注意到的地方都表现出色,直到有一天这里成为了你一天都会看的地方,并且会意识到它的工作方式确实改善了你的生活质量,更不用说让你过得愉快多了。
|
||||
|
||||
最明显的例子是“文件名高亮”。几十年来,Mac OS 一直有一个广受欢迎的功能,你可以高亮显示重要文件的名称。人们使用此功能作为快速视觉指示器,来告诉自己哪个文件是这几个的“最佳”版本,或者哪个文件应该发送给朋友,或者哪个文件仍然需要处理。它们可以是任意颜色,可以表示用户想要的任何含义。最重要的是,它是引人注目的视觉元数据。
|
||||
|
||||
从 Mac OS 切换过来用户往往会在 GNOME 和 KDE 以及 Linux 提供的其它桌面里怀念这个功能。Pantheon 悄悄地随手解决了这个问题。
|
||||
|
||||
![A highlighted file in the Pantheon desktop][5]
|
||||
|
||||
当然,那只是其中一个例子。Pantheon 有很多你直到用才会想到的小功能。
|
||||
|
||||
桌面精致而吸引人,有所有其他很多桌面缺少的直观组件。在许多方面,它充分吸取了其他桌面好的想法,并避免实现多余的东西。
|
||||
|
||||
![Pantheon desktop on Elementary OS][6]
|
||||
|
||||
### 自定义 Pantheon 桌面
|
||||
|
||||
Pantheon 桌面表达了如何操作计算机的清晰愿景。这种设计的“问题”(至少在开源之外)是,一个人的偏好可能无法满足另一个人的效率。
|
||||
|
||||
但它是开源的。它可以更改,任何不能改变的东西都可以被丢弃。Pantheon 绝对是针对特定用户群的桌面,但是即使对于那些对桌面应该如何工作抱有自己期望的人,Pantheon 也会比初看上去更加灵活。许多内置设计都具有替代选项,当你无法根据自己的喜好进行调整时,你可以轻松选择其他应用。主题引擎可确保你的替换应用看起来与桌面的其它部分和谐一致,而通常的 Linux 系统兼容性可确保你选择的所有应用都能按预期相互配合。
|
||||
|
||||
![Which one is the guest?][7]
|
||||
|
||||
这些替代品,可使你事半功倍。
|
||||
|
||||
### 受欢迎的补充
|
||||
|
||||
撇开这个桌面的词源不说,此桌面确实是许多 Linux 用户祈祷的答案(LCTT 译注:Pantheon 的意思是“万神庙”)。无论它是否是你的风格,Pantheon 桌面都是 Linux 用户体验中重要且受欢迎的补充。自己尝试一下,看看它是否是你一直期待的。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/19/12/pantheon-linux-desktop
|
||||
|
||||
作者:[Seth Kenlon][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [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/computer_keyboard_laptop_development_code_woman.png?itok=vbYz6jjb (A person programming)
|
||||
[2]: https://elementary.io/
|
||||
[3]: http://elementary.io
|
||||
[4]: https://opensource.com/article/19/5/getting-started-gnome-boxes-virtualization
|
||||
[5]: https://opensource.com/sites/default/files/uploads/advent-pantheon-highlight.jpg (A highlighted file in the Pantheon desktop)
|
||||
[6]: https://opensource.com/sites/default/files/uploads/advent-pantheon.jpg (Pantheon desktop on Elementary OS)
|
||||
[7]: https://opensource.com/sites/default/files/uploads/advent-pantheon-pcmanfm.jpg (Which one is the guest?)
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user