2019年8月

如果你仍未使用过 Autotools,那么这篇文章将改变你递交代码的方式。

你有没有下载过流行的软件项目的源代码,要求你输入几乎是仪式般的 ./configure; make && make install 命令序列来构建和安装它?如果是这样,你已经使用过 GNU Autotools 了。如果你曾经研究过这样的项目所附带的一些文件,你可能会对这种构建系统的显而易见的复杂性感到害怕。

好的消息是,GNU Autotools 的设置要比你想象的要简单得多,GNU Autotools 本身可以为你生成这些上千行的配置文件。是的,你可以编写 20 或 30 行安装代码,并免费获得其他 4,000 行。

Autotools 工作方式

如果你是初次使用 Linux 的用户,正在寻找有关如何安装应用程序的信息,那么你不必阅读本文!如果你想研究如何构建软件,欢迎阅读它;但如果你只是要安装一个新应用程序,请阅读我在在 Linux 上安装应用程序的文章。

对于开发人员来说,Autotools 是一种管理和打包源代码的快捷方式,以便用户可以编译和安装软件。 Autotools 也得到了主要打包格式(如 DEB 和 RPM)的良好支持,因此软件存储库的维护者可以轻松管理使用 Autotools 构建的项目。

Autotools 工作步骤:

  1. 首先,在 ./configure 步骤中,Autotools 扫描宿主机系统(即当前正在运行的计算机)以发现默认设置。默认设置包括支持库所在的位置,以及新软件应放在系统上的位置。
  2. 接下来,在 make 步骤中,Autotools 通常通过将人类可读的源代码转换为机器语言来构建应用程序。
  3. 最后,在 make install 步骤中,Autotools 将其构建好的文件复制到计算机上(在配置阶段检测到)的相应位置。

这个过程看起来很简单,和你使用 Autotools 的步骤一样。

Autotools 的优势

GNU Autotools 是我们大多数人认为理所当然的重要软件。与 GCC(GNU 编译器集合)一起,Autotools 是支持将自由软件构建和安装到正在运行的系统的脚手架。如果你正在运行 POSIX 系统,可以毫不保守地说,你的计算机上的操作系统里大多数可运行软件都是这些这样构建的。

即使是你的项目是个玩具项目不是操作系统,你可能会认为 Autotools 对你的需求来说太过分了。但是,尽管它的名气很大,Autotools 有许多可能对你有益的小功能,即使你的项目只是一个相对简单的应用程序或一系列脚本。

可移植性

首先,Autotools 考虑到了可移植性。虽然它无法使你的项目在所有 POSIX 平台上工作(这取决于你,编码的人),但 Autotools 可以确保你标记为要安装的文件安装到已知平台上最合理的位置。而且由于 Autotools,高级用户可以轻松地根据他们自己的系统情况定制和覆盖任何非最佳设定。

使用 Autotools,你只要知道需要将文件安装到哪个常规位置就行了。它会处理其他一切。不需要可能破坏未经测试的操作系统的定制安装脚本。

打包

Autotools 也得到了很好的支持。将一个带有 Autotools 的项目交给一个发行版打包者,无论他们是打包成 RPM、DEB、TGZ 还是其他任何东西,都很简单。打包工具知道 Autotools,因此可能不需要修补、魔改或调整。在许多情况下,将 Autotools 项目结合到流程中甚至可以实现自动化。

如何使用 Autotools

要使用 Autotools,必须先安装它。你的发行版可能提供一个单个的软件包来帮助开发人员构建项目,或者它可能为每个组件提供了单独的软件包,因此你可能需要在你的平台上进行一些研究以发现需要安装的软件包。

Autotools 的组件是:

  • automake
  • autoconf
  • automake
  • make

虽然你可能需要安装项目所需的编译器(例如 GCC),但 Autotools 可以很好地处理不需要编译的脚本或二进制文件。实际上,Autotools 对于此类项目非常有用,因为它提供了一个 make uninstall 脚本,以便于删除。

安装了所有组件之后,现在让我们了解一下你的项目文件的组成结构。

Autotools 项目结构

GNU Autotools 有非常具体的预期规范,如果你经常下载和构建源代码,可能大多数都很熟悉。首先,源代码本身应该位于一个名为 src 的子目录中。

你的项目不必遵循所有这些预期规范,但如果你将文件放在非标准位置(从 Autotools 的角度来看),那么你将不得不稍后在 Makefile 中对其进行调整。

此外,这些文件是必需的:

  • NEWS
  • README
  • AUTHORS
  • ChangeLog

你不必主动使用这些文件,它们可以是包含所有信息的单个汇总文档(如 README.md)的符号链接,但它们必须存在。

Autotools 配置

在你的项目根目录下创建一个名为 configure.ac 的文件。autoconf 使用此文件来创建用户在构建之前运行的 configure shell 脚本。该文件必须至少包含 AC_INITAC_OUTPUT M4 宏。你不需要了解有关 M4 语言的任何信息就可以使用这些宏;它们已经为你编写好了,并且所有与 Autotools 相关的内容都在该文档中定义好了。

在你喜欢的文本编辑器中打开该文件。AC_INIT 宏可以包括包名称、版本、报告错误的电子邮件地址、项目 URL 以及可选的源 TAR 文件名称等参数。

AC\_OUTPUT 宏更简单,不用任何参数。

AC_INIT([penguin], [2019.3.6], [[[email protected]][8]])
AC_OUTPUT

如果你此刻运行 autoconf,会依据你的 configure.ac 文件生成一个 configure 脚本,它是可以运行的。但是,也就是能运行而已,因为到目前为止你所做的就是定义项目的元数据,并要求创建一个配置脚本。

你必须在 configure.ac 文件中调用的下一个宏是创建 Makefile 的函数。 Makefile 会告诉 make 命令做什么(通常是如何编译和链接程序)。

创建 Makefile 的宏是 AM_INIT_AUTOMAKE,它不接受任何参数,而 AC_CONFIG_FILES 接受的参数是你要输出的文件的名称。

最后,你必须添加一个宏来考虑你的项目所需的编译器。你使用的宏显然取决于你的项目。如果你的项目是用 C++ 编写的,那么适当的宏是 AC_PROG_CXX,而用 C 编写的项目需要 AC_PROG_CC,依此类推,详见 Autoconf 文档中的 Building Programs and Libraries 部分。

例如,我可能会为我的 C++ 程序添加以下内容:

AC_INIT([penguin], [2019.3.6], [[[email protected]][8]])
AC_OUTPUT
AM_INIT_AUTOMAKE
AC_CONFIG_FILES([Makefile])
AC_PROG_CXX

保存该文件。现在让我们将目光转到 Makefile

生成 Autotools Makefile

Makefile 并不难手写,但 Autotools 可以为你编写一个,而它生成的那个将使用在 ./configure 步骤中检测到的配置选项,并且它将包含比你考虑要包括或想要自己写的还要多得多的选项。然而,Autotools 并不能检测你的项目构建所需的所有内容,因此你必须在文件 Makefile.am 中添加一些细节,然后在构造 Makefile 时由 automake 使用。

Makefile.am 使用与 Makefile 相同的语法,所以如果你曾经从头开始编写过 Makefile,那么这个过程将是熟悉和简单的。通常,Makefile.am 文件只需要几个变量定义来指示要构建的文件以及它们的安装位置即可。

_PROGRAMS 结尾的变量标识了要构建的代码(这通常被认为是 原语 primary 目标;这是 Makefile 存在的主要意义)。Automake 也会识别其他原语,如 _SCRIPTS_ DATA_LIBRARIES,以及构成软件项目的其他常见部分。

如果你的应用程序在构建过程中需要实际编译,那么你可以用 bin_PROGRAMS 变量将其标记为二进制程序,然后使用该程序名称作为变量前缀引用构建它所需的源代码的任何部分(这些部分可能是将被编译和链接在一起的一个或多个文件):

bin_PROGRAMS = penguin
penguin_SOURCES = penguin.cpp

bin_PROGRAMS 的目标被安装在 bindir 中,它在编译期间可由用户配置。

如果你的应用程序不需要实际编译,那么你的项目根本不需要 bin_PROGRAMS 变量。例如,如果你的项目是用 Bash、Perl 或类似的解释语言编写的脚本,那么定义一个 _SCRIPTS 变量来替代:

bin_SCRIPTS = bin/penguin

Automake 期望源代码位于名为 src 的目录中,因此如果你的项目使用替代目录结构进行布局,则必须告知 Automake 接受来自外部源的代码:

AUTOMAKE_OPTIONS = foreign subdir-objects

最后,你可以在 Makefile.am 中创建任何自定义的 Makefile 规则,它们将逐字复制到生成的 Makefile 中。例如,如果你知道一些源代码中的临时值需要在安装前替换,则可以为该过程创建自定义规则:

all-am: penguin
        touch bin/penguin.sh
       
penguin: bin/penguin.sh
        @sed "s|__datadir__|@datadir@|" $< >bin/$@

一个特别有用的技巧是扩展现有的 clean 目标,至少在开发期间是这样的。make clean 命令通常会删除除了 Automake 基础结构之外的所有生成的构建文件。它是这样设计的,因为大多数用户很少想要 make clean 来删除那些便于构建代码的文件。

但是,在开发期间,你可能需要一种方法可靠地将项目返回到相对不受 Autotools 影响的状态。在这种情况下,你可能想要添加:

clean-local:
        @rm config.status configure config.log
        @rm Makefile
        @rm -r autom4te.cache/
        @rm aclocal.m4
        @rm compile install-sh missing Makefile.in

这里有很多灵活性,如果你还不熟悉 Makefile,那么很难知道你的 Makefile.am 需要什么。最基本需要的是原语目标,无论是二进制程序还是脚本,以及源代码所在位置的指示(无论是通过 _SOURCES 变量还是使用 AUTOMAKE_OPTIONS 告诉 Automake 在哪里查找源代码)。

一旦定义了这些变量和设置,如下一节所示,你就可以尝试生成构建脚本,并调整缺少的任何内容。

生成 Autotools 构建脚本

你已经构建了基础结构,现在是时候让 Autotools 做它最擅长的事情:自动化你的项目工具。对于开发人员(你),Autotools 的接口与构建代码的用户的不同。

构建者通常使用这个众所周知的顺序:

$ ./configure
$ make
$ sudo make install

但是,要使这种咒语起作用,你作为开发人员必须引导构建这些基础结构。首先,运行 autoreconf 以生成用户在运行 make 之前调用的 configure 脚本。使用 -install 选项将辅助文件(例如符号链接)引入到 depcomp(这是在编译过程中生成依赖项的脚本),以及 compile 脚本的副本(一个编译器的包装器,用于说明语法,等等)。

$ autoreconf --install
configure.ac:3: installing './compile'
configure.ac:2: installing './install-sh'
configure.ac:2: installing './missing'

使用此开发构建环境,你可以创建源代码分发包:

$ make dist

dist 目标是从 Autotools “免费”获得的规则。这是一个内置于 Makefile 中的功能,它是通过简单的 Makefile.am 配置生成的。该目标可以生成一个 tar.gz 存档,其中包含了所有源代码和所有必要的 Autotools 基础设施,以便下载程序包的人员可以构建项目。

此时,你应该仔细查看存档文件的内容,以确保它包含你要发送给用户的所有内容。当然,你也应该尝试自己构建:

$ tar --extract --file penguin-0.0.1.tar.gz
$ cd penguin-0.0.1
$ ./configure
$ make
$ DESTDIR=/tmp/penguin-test-build make install

如果你的构建成功,你将找到由 DESTDIR 指定的已编译应用程序的本地副本(在此示例的情况下为 /tmp/penguin-test-build)。

$ /tmp/example-test-build/usr/local/bin/example
hello world from GNU Autotools

去使用 Autotools

Autotools 是一个很好的脚本集合,可用于可预测的自动发布过程。如果你习惯使用 Python 或 Bash 构建器,这个工具集对你来说可能是新的,但它为你的项目提供的结构和适应性可能值得学习。

而 Autotools 也不只是用于代码。Autotools 可用于构建 Docbook 项目,保持媒体有序(我使用 Autotools 进行音乐发布),文档项目以及其他任何可以从可自定义安装目标中受益的内容。


via: https://opensource.com/article/19/7/introduction-gnu-autotools

作者:Seth Kenlon 选题:lujun9972 译者:wxy 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

下拉式终端可以一键打开,并快速输入桌面上的任何命令。通常它会以平滑的方式创建终端,有时会带有下拉效果。本文演示了如何使用 Yakuake、Tilda、Guake 和 GNOME 扩展等下拉式终端来改善和加速日常任务。

Yakuake

Yakuake 是一个基于 KDE Konsole 技术的下拉式终端模拟器。它以 GNU GPLv2 条款分发。它包括以下功能:

  • 从屏幕顶部平滑地滚下
  • 标签式界面
  • 尺寸和动画速度可配置
  • 换肤
  • 先进的 D-Bus 接口

要安装 Yakuake,请使用以下命令:

$ sudo dnf install -y yakuake

启动和配置

如果你运行 KDE,请打开系统设置,然后转到“启动和关闭”。将“yakuake”添加到“自动启动”下的程序列表中,如下所示:

Yakuake 运行时很容易配置,首先在命令行启动该程序:

$ yakuake &

随后出现欢迎对话框。如果标准的快捷键和你已经使用的快捷键冲突,你可以设置一个新的。

点击菜单按钮,出现如下帮助菜单。接着,选择“配置 Yakuake……”访问配置选项。

你可以自定义外观选项,例如透明度、行为(例如当鼠标指针移过它们时聚焦终端)和窗口(如大小和动画)。在窗口选项中,你会发现当你使用两个或更多监视器时最有用的选项之一:“在鼠标所在的屏幕上打开”。

使用 Yakuake

主要的快捷键有:

  • F12 = 打开/撤回 Yakuake
  • Ctrl+F11 = 全屏模式
  • Ctrl+) = 上下分割
  • Ctrl+( = 左右分割
  • Ctrl+Shift+T = 新会话
  • Shift+Right = 下一个会话
  • Shift+Left = 上一个会话
  • Ctrl+Alt+S = 重命名会话

以下是 Yakuake 像终端多路复用器一样分割会话的示例。使用此功能,你可以在一个会话中运行多个 shell。

Tilda

Tilda 是一个下拉式终端,可与其他流行的终端模拟器相媲美,如 GNOME 终端、KDE 的 Konsole、xterm 等等。

它具有高度可配置的界面。你甚至可以更改终端大小和动画速度等选项。Tilda 还允许你启用热键,以绑定到各种命令和操作。

要安装 Tilda,请运行以下命令:

$ sudo dnf install -y tilda

启动和配置

大多数用户更喜欢在登录时就在后台运行一个下拉式终端。要设置此选项,请首先转到桌面上的应用启动器,搜索 Tilda,然后将其打开。

接下来,打开 Tilda 配置窗口。 选择“隐藏启动 Tilda”,即启动时不会立即显示终端。

接下来,你要设置你的桌面自动启动 Tilda。如果你使用的是 KDE,请转到“系统设置 > 启动与关闭 > 自动启动”并“添加一个程序”。

如果你正在使用 GNOME,则可以在终端中运行此命令:

$ ln -s /usr/share/applications/tilda.desktop ~/.config/autostart/

当你第一次运行它时,会出现一个向导来设置首选项。如果需要更改设置,请右键单击终端并转到菜单中的“首选项”。

你还可以创建多个配置文件,并绑定其他快捷键以在屏幕上的不同位置打开新终端。为此,请运行以下命令:

$ tilda -C

每次使用上述命令时,Tilda 都会在名为 ~/.config/tilda/ 文件夹中创建名为 config_0config_1 之类的新配置文件。然后,你可以映射组合键以打开具有一组特定选项的新 Tilda 终端。

使用 Tilda

主要快捷键有:

  • F1 = 拉下终端 Tilda(注意:如果你有多个配置文件,快捷方式是 F1、F2、F3 等)
  • F11 = 全屏模式
  • F12 = 切换透明模式
  • Ctrl+Shift+T = 添加标签
  • Ctrl+Page Up = 下一个标签
  • Ctrl+Page Down = 上一个标签

GNOME 扩展

Drop-down Terminal GNOME 扩展允许你在 GNOME Shell 中使用这个有用的工具。它易于安装和配置,使你可以快速访问终端会话。

安装

打开浏览器并转到此 GNOME 扩展的站点。启用扩展设置为“On”,如下所示:

然后选择“Install”以在系统上安装扩展。

执行此操作后,无需设置任何自动启动选项。只要你登录 GNOME,扩展程序就会自动运行!

配置

安装后,将打开 Drop-down Terminal 配置窗口以设置首选项。例如,可以设置终端大小、动画、透明度和使用滚动条。

如果你将来需要更改某些首选项,请运行 gnome-shell-extension-prefs 命令并选择“Drop Down Terminal”。

使用该扩展

快捷键很简单:

  • 反尖号 (通常是 Tab 键上面的一个键) = 打开/撤回终端
  • F12 (可以定制) = 打开/撤回终端

via: https://fedoramagazine.org/use-a-drop-down-terminal-for-fast-commands-in-fedora/

作者:Guilherme Schelp 选题:lujun9972 译者:wxy 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

学习如何复刻一个仓库,进行更改,并要求维护人员审查并合并它。

你知道如何使用 git 了,你有一个 GitHub 仓库并且可以向它推送。这一切都很好。但是你如何为他人的 GitHub 项目做出贡献? 这是我在学习 git 和 GitHub 之后想知道的。在本文中,我将解释如何 复刻 fork 一个 git 仓库、进行更改并提交一个 拉取请求 pull request

当你想要在一个 GitHub 项目上工作时,第一步是复刻一个仓库。

 title=

你可以使用我的演示仓库试一试。

当你在这个页面时,单击右上角的 “Fork”(复刻)按钮。这将在你的 GitHub 用户账户下创建我的演示仓库的一个新副本,其 URL 如下:

https://github.com/<你的用户名>/demo

这个副本包含了原始仓库中的所有代码、分支和提交。

接下来,打开你计算机上的终端并运行命令来 克隆 clone 仓库:

git clone https://github.com/<你的用户名>/demo

一旦仓库被克隆后,你需要做两件事:

1、通过发出命令创建一个新分支 new_branch

git checkout -b new_branch

2、使用以下命令为上游仓库创建一个新的 远程 remote

git remote add upstream https://github.com/kedark3/demo

在这种情况下,“上游仓库”指的是你创建复刻来自的原始仓库。

现在你可以更改代码了。以下代码创建一个新分支,进行任意更改,并将其推送到 new_branch 分支:

$ git checkout -b new_branch
Switched to a new branch ‘new_branch’
$ echo “some test file” &gt; test
$ cat test
Some test file
$ git status
On branch new_branch
No commits yet
Untracked files:
  (use "git add &lt;file&gt;..." to include in what will be committed)
    test
nothing added to commit but untracked files present (use "git add" to track)
$ git add test
$ git commit -S -m "Adding a test file to new_branch"
[new_branch (root-commit) 4265ec8] Adding a test file to new_branch
 1 file changed, 1 insertion(+)
 create mode 100644 test
$ git push -u origin new_branch
Enumerating objects: 3, done.
Counting objects: 100% (3/3), done.
Writing objects: 100% (3/3), 918 bytes | 918.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)
Remote: Create a pull request for ‘new_branch’ on GitHub by visiting:
Remote:   <http://github.com/example/Demo/pull/new/new\_branch>
Remote:
 * [new branch]         new_branch -&gt; new_branch

一旦你将更改推送到您的仓库后, “Compare & pull request”(比较和拉取请求)按钮将出现在GitHub。

 title=

单击它,你将进入此屏幕:

 title=

单击 “Create pull request”(创建拉取请求)按钮打开一个拉取请求。这将允许仓库的维护者们审查你的贡献。然后,如果你的贡献是没问题的,他们可以合并它,或者他们可能会要求你做一些改变。

精简版

总之,如果您想为一个项目做出贡献,最简单的方法是:

  1. 找到您想要贡献的项目
  2. 复刻它
  3. 将其克隆到你的本地系统
  4. 建立一个新的分支
  5. 进行你的更改
  6. 将其推送回你的仓库
  7. 单击 “Compare & pull request”(比较和拉取请求)按钮
  8. 单击 “Create pull request”(创建拉取请求)以打开一个新的拉取请求

如果审阅者要求更改,请重复步骤 5 和 6,为你的拉取请求添加更多提交。

快乐编码!


via: https://opensource.com/article/19/7/create-pull-request-github

作者:Kedar Vijay Kulkarni 选题:lujun9972 译者:furrybear 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

面对倾泻的洪水或地震时业务需要继续运转。在飓风卡特里娜、桑迪和其他灾难中幸存下来的系统管理员向在紧急状况下负责 IT 的人们分享真实世界中的建议。

说到自然灾害,2017 年可算是多灾多难。(LCTT 译注:本文发表于 2017 年)飓风哈维、厄玛和玛莉亚给休斯顿、波多黎各、弗罗里达和加勒比造成了严重破坏。此外,西部的野火将多处住宅和商业建筑付之一炬。

再来一篇关于有备无患的警示文章 —— 当然其中都是好的建议 —— 是很简单的,但这无法帮助网络管理员应对湿漉漉的烂摊子。那些善意的建议中大多数都假定掌权的人乐于投入资金来实施这些建议。

我们对真实世界更感兴趣。不如让我们来充分利用这些坏消息。

一个很好的例子:自然灾害的一个后果是老板可能突然愿意给灾备计划投入预算。如同一个纽约地区的系统管理员所言,“我发现飓风桑迪的最大好处是我们的客户对 IT 投资更有兴趣了,但愿你也能得到更多预算。”

不过别指望这种意愿持续很久。任何想提议改进基础设施的系统管理员最好趁热打铁。如同另一位飓风桑迪中幸存下来的 IT 专员懊悔地提及那样,“对 IT 开支最初的兴趣持续到当年为止。到了第二年,任何尚未开工的计划都因为‘预算约束’被搁置了,大约 6 个月之后则完全被遗忘。”

在管理层忘记恶劣的自然灾害也可能降临到好公司头上之前提醒他们这点会有所帮助。根据 商业和家庭安全协会 Institute for Business & Home Safety 的说法,自然灾害后歇业的公司中 25% 再也没能重新开业 联邦紧急事务管理署 FEMA 认为这过于乐观。根据他们的统计,“灾后 40% 的小公司再也没能重新开门营业。”

如果你是个系统管理员,你能帮忙挽救你的公司。这里有一些幸存者的最好的主意,这些主意是基于他们从过去几次自然灾害中得到的经验。

制订一个计划

当灯光忽明忽暗,狂风象火车机车一样怒号时,就该启动你的业务持续计划和灾备计划了。

有太多的系统管理员报告当暴风雨来临时这两个计划中一个也没有。这并不令人惊讶。2014 年 灾备预备状态委员会 Disaster Recovery Preparedness Council 发现世界范围内被调查的公司中有 73% 没有足够的灾备计划

足够”是关键词。正如一个系统管理员 2016 年在 Reddit 上写的那样,“我们的灾备计划就是一场灾难。我们所有的数据都备份在离这里大约 30 英里的一个 存储区域网络 SAN 。我们没有将数据重新上线的硬件,甚至好几天过去了都没能让核心服务器启动运行起来。我们是个年营收 40 亿美元的公司,却不愿为适当的设备投入几十万美元,或是在数据中心添置几台服务器。当添置硬件的提案被提出的时候,我们的管理层说,‘嗐,碰到这种事情的机会能有多大呢’。”

同一个帖子中另一个人说得更简洁:“眼下我的灾备计划只能在黑暗潮湿的角落里哭泣,但愿没人在乎损失的任何东西。”

如果你在哭泣,但愿你至少不是独自流泪。任何灾备计划,即便是 IT 部门制订的灾备计划,必须确定你能跟别人通讯,如同系统管理员 Jim Thompson 从卡特里娜飓风中得到的教训:“确保你有一个与人们通讯的计划。在一场严重的区域性灾难期间,你将无法给身处灾区的任何人打电话。”

有一个选择可能会让有技术头脑的人感兴趣: 业余电台 ham radio 它在波多黎各发挥了巨大作用

列一个愿望清单

第一步是承认问题。“许多公司实际上对灾备计划不感兴趣,或是消极对待”,Micro Focus 的首席架构师 Joshua Focus 说。“将灾备看作业务持续性的一个方面是种不同的视角。所有公司都要应对业务持续性,所以灾备应被视为业务持续性的一部分。”

IT 部门需要将其需求书面化以确保适当的灾备和业务持续性计划。即使是你不知道如何着手,或尤其是这种时候,也是如此。正如一个系统管理员所言,“我喜欢有一个‘想法转储’,让所有计划、点子、改进措施毫无保留地提出来。(这)对一类情况尤其有帮助,即当你提议变更,并付诸实施,接着 6 个月之后你警告过的状况就要来临。”现在你做好了一切准备并且可以开始讨论:“如同我们之前在 4 月讨论过的那样……”

因此,当你的管理层对业务持续性计划回应道“嗐,碰到这种事的机会能有多大呢?”的时候你能做些什么呢?有个系统管理员称这也完全是管理层的正常行为。在这种糟糕的处境下,老练的系统管理员建议用书面形式把这些事情记录下来。记录应清楚表明你告知管理层需要采取的措施,且他们拒绝采纳建议。“总的来说就是有足够的书面材料能让他们搓成一根绳子上吊,”该系统管理员补充道。

如果那也不起作用,恢复一个被洪水淹没的数据中心的相关经验对你找个新工作是很有帮助的。

保护有形的基础设施

我们的办公室是幢摇摇欲坠的建筑,”飓风哈维重创休斯顿之后有个系统管理员提到。“我们盲目地进入那幢建筑,现场的基础设施糟透了。正是我们给那幢建筑里带去了最不想要的一滴水,现在基础设施整个都沉在水下了。”

尽管如此,如果你想让数据中心继续运转——或在暴风雨过后恢复运转 —— 你需要确保该场所不仅能经受住你所在地区那些意料中的灾难,而且能经受住那些意料之外的灾难。一个旧金山的系统管理员知道为什么重要的是确保公司的服务器安置在可以承受里氏 7 级地震的建筑内。一家圣路易斯的公司知道如何应对龙卷风。但你应当为所有可能发生的事情做好准备:加州的龙卷风、密苏里州的地震,或僵尸末日(给你在 IT 预算里增加一把链锯提供了充分理由)。

在休斯顿的情况下,多数数据中心保持运转,因为它们是按照抵御暴风雨和洪水的标准建造的。Data Foundry 的首席技术官 Edward Henigin 说他们公司的数据中心之一,“专门建造的休斯顿 2 号的设计能抵御 5 级飓风的风速。这个场所的公共供电没有中断,我们得以避免切换到后备发电机。”

那是好消息。坏消息是伴随着超级飓风桑迪于 2012 年登场,如果你的数据中心没准备好应对洪水,你会陷入一个麻烦不断的世界。一个不能正常运转的数据中心 Datagram 服务的客户包括 Gawker、Gizmodo 和 Buzzfeed 等知名网站。

当然,有时候你什么也做不了。正如某个波多黎各圣胡安的系统管理员在飓风厄玛扫过后悲伤地写到,“发电机没油了。服务器机房靠电池在运转但是没有(空调)。永别了,服务器。”由于 MPLS Multiprotocol Lable Switching 线路亦中断,该系统管理员没法切换到灾备措施:“多么充实的一天。”

总而言之,IT 专业人士需要了解他们所处的地区,了解他们面临的风险并将他们的服务器安置在能抵御当地自然灾害的数据中心内。

关于云的争议

当暴风雨席卷一切时避免 IT 数据中心失效的最佳方法就是确保灾备数据中心在其他地方。选择地点时需要审慎的决策。你的灾备数据中心不应在会被同一场自然灾害影响到的 地域 region ;你的资源应安置在多个 可用区 availability zone 内。考虑一下主备数据中心位于一场地震中的同一条断层带上,或是主备数据中心易于受互通河道导致的洪灾影响这类情况。

有些系统管理员利用云作为冗余设施。例如,总是用微软 Azure 云存储服务保存副本以确保持久性和高可用性。根据你的选择,Azure 复制功能将你的数据要么拷贝到同一个数据中心要么拷贝到另一个数据中心。多数公有云提供类似的自动备份服务以确保数据安全,不论你的数据中心发生什么情况——除非你的云服务供应商全部设施都在暴风雨的行进路径上。

昂贵么?是的。跟业务中断 1、2 天一样昂贵么?并非如此。

信不过公有云?可以考虑 colo colocation 服务。有了 colo,你依旧拥有你的硬件,运行你自己的应用,但这些硬件可以远离麻烦。例如飓风哈维期间,一家公司“虚拟地”将它的资源从休斯顿搬到了其位于德克萨斯奥斯汀的 colo。但是那些本地数据中心和 colo 场所需要准备好应对灾难;这点是你选择场所时要考虑的一个因素。举个例子,一个寻找 colo 场所的西雅图系统管理员考虑的“全都是抗震和旱灾应对措施(加固的地基以及补给冷却系统的运水卡车)。”

周围一片黑暗时

正如 Forrester Research 的分析师 Rachel Dines 在一份为灾备期刊所做的调查中报告的那样,宣布的灾难中最普遍的原因就是断电。尽管你能应对一般情况下的断电,飓风、火灾和洪水的考验会超越设备的极限。

某个系统管理员挖苦式的计划是什么呢?“趁 UPS 完蛋之前把你能关的机器关掉,不能关的就让它崩溃咯。然后,喝个痛快直到供电恢复。”

在 2016 年德尔塔和西南航空停电事故之后,IT 员工推动的一个更加严肃的计划是由一个有管理的服务供应商为其客户部署不间断电源:“对于至关重要的部分,在供电中断时我们结合使用 简单网络管理协议 SNMP 信令和 PowerChute 网络关机 PowerChute Nrework Shutdown 客户端来关闭设备。至于重新开机,那取决于客户。有些是自动启动,有些则需要人工干预。”

另一种做法是用来自两个供电所的供电线路支持数据中心。例如,西雅图威斯汀大厦数据中心有来自不同供电所的多路 13.4 千伏供电线路,以及多个 480 伏三相变电箱。

预防严重断电的系统不是“通用的”设备。系统管理员应当为数据中心请求一台定制的柴油发电机。除了按你特定的需求调整,发电机必须能迅速跳至全速运转并承载全部电力负荷而不致影响系统负载性能。”

这些发电机也必须加以保护。例如,将你的发电机安置在泛洪区的一楼就不是个聪明的主意。位于纽约 百老街 Broad street 的数据中心在超级飓风桑迪期间就是类似情形,备用发电机的燃料油桶在地下室 —— 并且被水淹了。尽管一场“人力接龙”用容量 5 加仑的水桶将柴油输送到 17 段楼梯之上的发电机使 Peer 1 Hosting 得以继续运营,但这不是一个切实可行的业务持续计划。

正如多数数据中心专家所知那样,如果你有时间 —— 假设一个飓风离你有一天的距离 —— 确保你的发电机正常工作,加满油,准备好当供电线路被刮断时立即开启,不管怎样你之前应当每月测试你的发电机。你之前是那么做的,是吧?是就好!

测试你对备份的信心

普通用户几乎从不备份,检查备份是否实际完好的就更少了。系统管理员对此更加了解。

有些 IT 部门在寻求将他们的备份迁移到云端。但有些系统管理员仍对此不买账 —— 他们有很好的理由。最近有人报告,“在用了整整 5 天从亚马逊 Glacier 恢复了(400 GB)数据之后,我欠了亚马逊将近 200 美元的传输费,并且(我还是)处于未完全恢复状态,还差大约 100 GB 文件。”

结果是有些系统管理员依然喜欢磁带备份。磁带肯定不够时髦,但正如操作系统专家 Andrew S. Tanenbaum 说的那样,“永远不要低估一辆装满磁带在高速上飞驰的旅行车的带宽。”

目前每盘磁带可以存储 10 TB 数据;有的进行中的实验可在磁带上存储高达 200 TB 数据。诸如 线性磁带文件系统 Linear Tape File System 之类的技术允许你象访问网络硬盘一样读取磁带数据。

然而对许多人而言,磁带绝对是最后选择的手段。没关系,因为备份应该有大量的可选方案。在这种情况下,一个系统管理员说到,“故障时我们会用这些方法(恢复备份):(Windows)服务器层面的 VSS (Volume Shadow Storage)快照, 存储区域网络 SAN 层面的卷快照,以及存储区域网络层面的异地归档快照。但是万一有什么事情发生并摧毁了我们的虚拟机,存储区域网络和备份存储区域网络,我们还是可以取回磁带并恢复数据。”

当麻烦即将到来时,可使用副本工具如 Veeam,它会为你的服务器创建一个虚拟机副本。若出现故障,副本会自动启动。没有麻烦,没有手忙脚乱,正如某个系统管理员在这个流行的系统管理员帖子中所说,“我爱你 Veeam。”

网络?什么网络?

当然,如果员工们无法触及他们的服务,没有任何云、colo 和远程数据中心能帮到你。你不需要一场自然灾害来证明冗余互联网连接的正确性。只需要一台挖断线路的挖掘机或断掉的光缆就能让你在工作中渡过糟糕的一天。

“理想状态下”,某个系统管理员明智地观察到,“你应该有两路互联网接入线路连接到有独立基础设施的两个 ISP。例如,你不希望两个 ISP 都依赖于同一根光缆。你也不希望采用两家本地 ISP,并发现他们的上行带宽都依赖于同一家骨干网运营商。”

聪明的系统管理员知道他们公司的互联网接入线路必须是商业级别的,带有 服务等级协议 service-level agreement(SLA) ,其中包含“修复时间”条款。或者更好的是采用 互联网接入专线 dedicated Internet access。技术上这与任何其他互联网接入方式没有区别。区别在于互联网接入专线不是一种“尽力而为”的接入方式,而是你会得到明确规定的专供你使用的带宽并附有服务等级协议。这种专线不便宜,但正如一句格言所说的那样,“速度、可靠性、便宜,只能挑两个。”当你的业务跑在这条线路上并且一场暴风雨即将来袭,“可靠性”必须是你挑的两个之一。

晴空重现之时

你没法准备应对所有自然灾害,但你可以为其中很多做好计划。有一个深思熟虑且经过测试的灾备和业务持续计划,并逐字逐句严格执行,当竞争对手溺毙的时候,你的公司可以幸存下来。

系统管理员对抗自然灾害:给领导者的教训

  • 你的 IT 员工得说多少次:不要仅仅备份,还得测试备份?
  • 没电就没公司。确保你的服务器有足够的应急电源来满足业务需要,并确保它们能正常工作。
  • 如果你的公司在一场自然灾害中幸存下来,或者避开了灾害,明智的系统管理员知道这就是向管理层申请被他们推迟的灾备预算的时候了。因为下次你就未必有这么幸运了。

via: https://www.hpe.com/us/en/insights/articles/it-disaster-recovery-sysadmins-vs-natural-disasters-1711.html

作者:Steven-J-Vaughan-Nichols 译者:0x996 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

Webhook 可用于外部系统通知你的系统发生了某个事件或更新。可能最知名的 Webhook 类型是支付服务提供商(PSP)通知你的系统支付状态有了更新。

它们通常以监听的预定义 URL 的形式出现,例如 http://example.com/webhooks/payment-update。同时,另一个系统向该 URL 发送具有特定有效载荷的 POST 请求(例如支付 ID)。一旦请求进入,你就会获得支付 ID,可以通过 PSP 的 API 用这个支付 ID 向它们询问最新状态,然后更新你的数据库。

其他例子可以在这个对 Webhook 的出色的解释中找到:https://sendgrid.com/blog/whats-webhook/

只要系统可通过互联网公开访问(这可能是你的生产环境或可公开访问的临时环境),测试这些 webhook 就相当顺利。而当你在笔记本电脑上或虚拟机内部(例如,Vagrant 虚拟机)进行本地开发时,它就变得困难了。在这些情况下,发送 webhook 的一方无法公开访问你的本地 URL。此外,监视发送的请求也很困难,这可能使开发和调试变得困难。

因此,这个例子将解决:

  • 测试来自本地开发环境的 webhook,该环境无法通过互联网访问。从服务器向 webhook 发送数据的服务无法访问它。
  • 监控发送的请求和数据,以及应用程序生成的响应。这样可以更轻松地进行调试,从而缩短开发周期。

前置需求:

  • 可选:如果你使用虚拟机(VM)进行开发,请确保它正在运行,并确保在 VM 中完成后续步骤。
  • 对于本教程,我们假设你定义了一个 vhost:webhook.example.vagrant。我在本教程中使用了 Vagrant VM,但你可以自由选择 vhost。
  • 按照这个安装说明安装 ngrok。在 VM 中,我发现它的 Node 版本也很有用:https://www.npmjs.com/package/ngrok,但你可以随意使用其他方法。

我假设你没有在你的环境中运行 SSL,但如果你使用了,请将在下面的示例中的端口 80 替换为端口 433,http:// 替换为 https://

使 webhook 可测试

我们假设以下示例代码。我将使用 PHP,但请将其视作伪代码,因为我留下了一些关键部分(例如 API 密钥、输入验证等)没有编写。

第一个文件:payment.php。此文件创建一个 $payment 对象,将其注册到 PSP。然后它获取客户需要访问的 URL,以便支付并将用户重定向到客户那里。

请注意,此示例中的 webhook.example.vagrant 是我们为开发设置定义的本地虚拟主机。它无法从外部世界进入。

<?php
/*
 * This file creates a payment and tells the PSP what webhook URL to use for updates
 * After creating the payment, we get a URL to send the customer to in order to pay at the PSP
 */
$payment = [
    'order_id' => 123,
    'amount' => 25.00,
    'description' => 'Test payment',
    'redirect_url' => 'http://webhook.example.vagrant/redirect.php',
    'webhook_url' => 'http://webhook.example.vagrant/webhook.php',
];

$payment = $paymentProvider->createPayment($payment);
header("Location: " . $payment->getPaymentUrl());

第二个文件:webhook.php。此文件等待 PSP 调用以获得有关更新的通知。

<?php
/*
 * This file gets called by the PSP and in the $_POST they submit an 'id'
 * We can use this ID to get the latest status from the PSP and update our internal systems afterward
 */
 
$paymentId = $_POST['id'];
$paymentInfo = $paymentProvider->getPayment($paymentId);
$status = $paymentInfo->getStatus();

// Perform actions in here to update your system
if ($status === 'paid') {
    ..
}
elseif ($status === 'cancelled') {
    ..
}

我们的 webhook URL 无法通过互联网访问(请记住它:webhook.example.vagrant)。因此,PSP 永远不可能调用文件 webhook.php,你的系统将永远不会知道付款状态,这最终导致订单永远不会被运送给客户。

幸运的是,ngrok 可以解决这个问题。 ngrok 将自己描述为:

ngrok 通过安全隧道将 NAT 和防火墙后面的本地服务器暴露给公共互联网。

让我们为我们的项目启动一个基本的隧道。在你的环境中(在你的系统上或在 VM 上)运行以下命令:

ngrok http -host-header=rewrite webhook.example.vagrant:80
阅读其文档可以了解更多配置选项:https://ngrok.com/docs

会出现这样的屏幕:

ngrok 输出

我们刚刚做了什么?基本上,我们指示 ngrok 在端口 80 建立了一个到 http://webhook.example.vagrant 的隧道。同一个 URL 也可以通过 http://39741ffc.ngrok.iohttps://39741ffc.ngrok.io 访问,它们能被任何知道此 URL 的人通过互联网公开访问。

请注意,你可以同时获得 HTTP 和 HTTPS 两个服务。这个文档提供了如何将此限制为 HTTPS 的示例:https://ngrok.com/docs#bind-tls

那么,我们如何让我们的 webhook 现在工作起来?将 payment.php 更新为以下代码:

<?php
/*
 * This file creates a payment and tells the PSP what webhook URL to use for updates
 * After creating the payment, we get a URL to send the customer to in order to pay at the PSP
 */
$payment = [
    'order_id' => 123,
    'amount' => 25.00,
    'description' => 'Test payment',
    'redirect_url' => 'http://webhook.example.vagrant/redirect.php',
    'webhook_url' => 'https://39741ffc.ngrok.io/webhook.php',
];

$payment = $paymentProvider->createPayment($payment);
header("Location: " . $payment->getPaymentUrl());

现在,我们告诉 PSP 通过 HTTPS 调用此隧道 URL。只要 PSP 通过隧道调用 webhook,ngrok 将确保使用未修改的有效负载调用内部 URL。

如何监控对 webhook 的调用?

你在上面看到的屏幕截图概述了对隧道主机的调用,这些数据相当有限。幸运的是,ngrok 提供了一个非常好的仪表板,允许你检查所有调用:

我不会深入研究这个问题,因为它是不言自明的,你只要运行它就行了。因此,我将解释如何在 Vagrant 虚拟机上访问它,因为它不是开箱即用的。

仪表板将允许你查看所有调用、其状态代码、标头和发送的数据。你将看到应用程序生成的响应。

仪表板的另一个优点是它允许你重放某个调用。假设你的 webhook 代码遇到了致命的错误,开始新的付款并等待 webhook 被调用将会很繁琐。重放上一个调用可以使你的开发过程更快。

默认情况下,仪表板可在 http://localhost:4040 访问。

虚拟机中的仪表盘

为了在 VM 中完成此工作,你必须执行一些额外的步骤:

首先,确保可以在端口 4040 上访问 VM。然后,在 VM 内创建一个文件已存放此配置:

web_addr: 0.0.0.0:4040

现在,杀死仍在运行的 ngrok 进程,并使用稍微调整过的命令启动它:

ngrok http -config=/path/to/config/ngrok.conf -host-header=rewrite webhook.example.vagrant:80

尽管 ID 已经更改,但你将看到类似于上一屏幕截图的屏幕。之前的网址不再有效,但你有了一个新网址。 此外,Web Interface URL 已更改:

现在将浏览器指向 http://webhook.example.vagrant:4040 以访问仪表板。另外,对 https://e65642b5.ngrok.io/webhook.php 做个调用。这可能会导致你的浏览器出错,但仪表板应显示正有一个请求。

最后的备注

上面的例子是伪代码。原因是每个外部系统都以不同的方式使用 webhook。我试图基于一个虚构的 PSP 实现给出一个例子,因为可能很多开发人员在某个时刻肯定会处理付款。

请注意,你的 webhook 网址也可能被意图不好的其他人使用。确保验证发送给它的任何输入。

更好的的,可以向 URL 添加令牌,该令牌对于每个支付是唯一的。只有你的系统和发送 webhook 的系统才能知道此令牌。

祝你测试和调试你的 webhook 顺利!

注意:我没有在 Docker 上测试过本教程。但是,这个 Docker 容器看起来是一个很好的起点,并包含了明确的说明:https://github.com/wernight/docker-ngrok


via: https://medium.freecodecamp.org/testing-webhooks-while-using-vagrant-for-development-98b5f3bedb1d

作者:Stefan Doorn 译者:wxy 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

如何在 Linux 中校验 ISO 镜像

你从喜爱的 Linux 发行版的官方网站或第三方网站下载了它的 ISO 镜像之后,接下来要做什么呢?是创建可启动介质并开始安装系统吗?并不是,请稍等一下。在开始使用它之前,强烈建议你检查一下你刚下载到本地系统中的 ISO 文件是否是下载镜像站点中 ISO 文件的一个精确拷贝。因为在前几年 Linux Mint 的网站被攻破了,并且攻击者创建了一个包含后门的经过修改的 Linux Mint ISO 文件。 所以验证下载的 Linux ISO 镜像的可靠性和完整性是非常重要的一件事儿。假如你不知道如何在 Linux 中验证 ISO 镜像,本次的简要介绍将给予你帮助,请接着往下看!

在 Linux 中验证 ISO 镜像

我们可以使用 ISO 镜像的“校验和”来验证 ISO 镜像。校验和是一系列字母和数字的组合,用来检验下载文件的数据是否有错以及验证其可靠性和完整性。当前存在不同类型的校验和,例如 SHA-0、SHA-1、SHA-2(224、256、384、512)和 MD5。MD5 校验和最为常用,但对于现代的 Linux 发行版,SHA-256 最常被使用。

我们将使用名为 gpgsha256 的两个工具来验证 ISO 镜像的可靠性和完整性。

下载校验和及签名

针对本篇指南的目的,我将使用 Ubuntu 18.04 LTS 服务器 ISO 镜像来做验证,但对于其他的 Linux 发行版应该也是适用的。

在靠近 Ubuntu 下载页的最上端,你将看到一些额外的文件(校验和及签名),正如下面展示的图片那样:

Ubuntu 18.04 的校验和及签名

其中名为 SHA256SUMS 的文件包含了这里所有可获取镜像的校验和,而 SHA256SUMS.gpg 文件则是这个文件的 GnuPG 签名。在下面的步骤中,我们将使用这个签名文件来 验证 校验和文件。

下载 Ubuntu 的 ISO 镜像文件以及刚才提到的那两个文件,然后将它们放到同一目录下,例如这里的 ISO 目录:

$ ls ISO/
SHA256SUMS SHA256SUMS.gpg ubuntu-18.04.2-live-server-amd64.iso

如你所见,我已经下载了 Ubuntu 18.04.2 LTS 服务器版本的镜像,以及对应的校验和文件和签名文件。

下载有效的签名秘钥

现在,使用下面的命令来下载正确的签名秘钥:

$ gpg --keyid-format long --keyserver hkp://keyserver.ubuntu.com --recv-keys 0x46181433FBB75451 0xD94AA3F0EFE21092

示例输出如下:

gpg: key D94AA3F0EFE21092: 57 signatures not checked due to missing keys
gpg: key D94AA3F0EFE21092: public key "Ubuntu CD Image Automatic Signing Key (2012) <[email protected]>" imported
gpg: key 46181433FBB75451: 105 signatures not checked due to missing keys
gpg: key 46181433FBB75451: public key "Ubuntu CD Image Automatic Signing Key <[email protected]>" imported
gpg: no ultimately trusted keys found
gpg: Total number processed: 2
gpg: imported: 2

验证 SHA-256 校验和

接下来我们将使用签名来验证校验和文件:

$ gpg --keyid-format long --verify SHA256SUMS.gpg SHA256SUMS

下面是示例输出:

gpg: Signature made Friday 15 February 2019 04:23:33 AM IST
gpg: using DSA key 46181433FBB75451
gpg: Good signature from "Ubuntu CD Image Automatic Signing Key <[email protected]>" [unknown]
gpg: WARNING: This key is not certified with a trusted signature!
gpg: There is no indication that the signature belongs to the owner.
Primary key fingerprint: C598 6B4F 1257 FFA8 6632 CBA7 4618 1433 FBB7 5451
gpg: Signature made Friday 15 February 2019 04:23:33 AM IST
gpg: using RSA key D94AA3F0EFE21092
gpg: Good signature from "Ubuntu CD Image Automatic Signing Key (2012) <[email protected]>" [unknown]
gpg: WARNING: This key is not certified with a trusted signature!
gpg: There is no indication that the signature belongs to the owner.
Primary key fingerprint: 8439 38DF 228D 22F7 B374 2BC0 D94A A3F0 EFE2 1092

假如你在输出中看到 Good signature 字样,那么该校验和文件便是由 Ubuntu 开发者制作的,并且由秘钥文件的所属者签名认证。

检验下载的 ISO 文件

下面让我们继续检查下载的 ISO 文件是否和所给的校验和相匹配。为了达到该目的,只需要运行:

$ sha256sum -c SHA256SUMS 2>&1 | grep OK
ubuntu-18.04.2-live-server-amd64.iso: OK

假如校验和是匹配的,你将看到 OK 字样,这意味着下载的文件是合法的,没有被改变或篡改过。

假如你没有获得类似的输出,或者看到不同的输出,则该 ISO 文件可能已经被修改过或者没有被正确地下载。你必须从一个更好的下载源重新下载该文件。

某些 Linux 发行版已经在它的下载页面中包含了校验和。例如 Pop!\_os 的开发者在他们的下载页面中提供了所有 ISO 镜像的 SHA-256 校验和,这样你就可以快速地验证这些 ISO 镜像。

Pop os 位于其下载页面中的 SHA256 校验和

在下载完 ISO 镜像文件后,可以使用下面的命令来验证它们:

$ sha256sum Soft_backup/ISOs/pop-os_18.04_amd64_intel_54.iso

示例输出如下:

680e1aa5a76c86843750e8120e2e50c2787973343430956b5cbe275d3ec228a6 Soft_backup/ISOs/pop-os_18.04_amd64_intel_54.iso

Pop os 的 SHA256 校验和的值

在上面的输出中,以 680elaa 开头的部分为 SHA-256 校验和的值。请将该值与位于下载页面中提供的 SHA-256 校验和的值进行比较,如果这两个值相同,那说明这个下载的 ISO 文件是合法的,与它的原有状态相比没有经过更改或者篡改。万事俱备,你可以进行下一步了!

上面的内容便是我们如何在 Linux 中验证一个 ISO 文件的可靠性和完整性的方法。无论你是从官方站点或者第三方站点下载 ISO 文件,我们总是推荐你在使用它们之前做一次简单的快速验证。希望本篇的内容对你有所帮助。

参考文献:


via: https://www.ostechnix.com/how-to-verify-iso-images-in-linux/

作者:sk 选题:lujun9972 译者:FSSlc 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出