Title Text:The failures usually don’t hurt anything, and if it installs several versions, it increases the chance that one of them is right. (Note: The ‘yes’ command and ‘2>/dev/null’ are recommended additions.)<
Origin:https://xkcd.com/1654/
https://www.explainxkcd.com/wiki/index.php/1654:_Universal_Install_Script
萬用安裝 script
今天大多数计算机用户习惯于简单,容易地安装程序。您只需下载.exe或.pkg,双击它,然后执行它所说的内容。有时您根本不需要安装任何东西,并且它在没有任何安装的情况下运行。
然而,当事情更“自制”时,例如下载源代码,事情就更复杂了。在类Unix系统(此通用安装脚本所针对的系统)下,您可能必须使用“构建环境”和“makefile”以及命令行工具。为了使这个过程更简单,存在程序的存储库,它们托管源代码包和构建它所需的东西或预构建的程序。下载软件包时,它会自动完成将代码构建为必要的可执行代码然后安装它的大部分工作。然而,有许多这样的存储库,例如“pip”和“brew”等,在漫画中列出。如果您只知道程序或包的名称,则可能不知道它驻留在哪个存储库中。
漫画中提供的install.sh文件是一个shell脚本,它试图通过充当“通用安装脚本”来解决这个问题,该脚本包含在各种类Unix系统中使用的许多常见安装命令。特别是这个脚本由Bourne Again Shell(Bash)解释,它由第一行中的#!/bin /bash表示。在脚本中的每个安装命令之间是&amp;在POSIX兼容shell(包括Bash,一种流行的shell脚本语言)中的字符意味着它应该继续运行下一个命令而不等待第一个命令完成,也称为“在后台运行”。这具有同时运行所有安装命令的效果;它们提供的所有输出和错误文本将混合在一起,因为它们都在同一时间显示在屏幕上。
脚本在运行时接受程序或包的名称作为参数。然后将该值引用为“$ 1”(参数编号1)。脚本所说的每个地方都写着“1美元”,它会以你给它的包名取而代之。最终结果是针对大量软件存储库和包管理器尝试了名称,并且希望其中至少有一个是合适的,并且将成功安装该程序。接近结束时,它甚至尝试将当前工作目录更改为假定要保存要安装的包的目录,然后运行几个从源代码构建程序的命令。
总而言之,这个脚本可能会起作用;它运行许多标准的流行存储库程序和包管理器,并运行构建程序所需的几乎通用的命令。大多数命令只会给出错误并退出,但希望正确的命令将继续安装。
漫画中一个更微妙的笑话是在同一个剧本中包含了apt-get和sudo apt-get。良好的unix实践决定永远不以root身份登录;相反,您保持以普通用户身份登录,并通过sudo程序名称运行系统管理员帐户。这可以防止意外错误并启用所有敏感命令的记录。然而,这样做的副作用是管理员可能忘记在命令前添加sudo,并在第二次正确地重新运行它。这是Linux社区中的一个常见笑话,其中一个例子可以在这个病毒推文中找到,该推文显示了该问题的幽默解决方法。
由于Randall的脚本除了apt-get命令之外不使用sudo,因此有两种可能:脚本本身是通过root用户或sudo运行的,在这种情况下不需要sudo apt-get,或者脚本是作为普通用户运行,在这种情况下,命令可以根据本地条件安装本地(而不是系统范围)版本。例如,npm将在$ HOME /.npm下安装软件包的副本,只要用户使用virtualenv(这是Python开发人员的标准做法),pip就可以工作。
Sudo也被Randall在149:Sandwich和Jason Fox用来强迫Randall让他出现在xkcd上的824:Guest Week:Bill Amend(FoxTrot)。工具卷曲从网络(例如,因特网)下载文件。例如,curl http://xkcd.com/downloads并显示xkcd HTML源代码。管道|在脚本中将管道之前的命令输出附加到管道之后的命令输入,从而运行Web内容中存在的任何命令。虽然这种“卷曲”模式是方便安装软件的常用做法,但它被认为是非常不明智的;如果您未经验证运行不受信任的代码,可能会有MITM修改您收到的代码,或者远程系统可能已被劫持且代码被恶意攻击。大多数本地包管理器(例如apt,yum)提供数字签名包以阻止此问题。您可以找到很多软件提供商的例子,建议在curlpipesh上使用curl | sh解决方案
&amp;和/和在“git clone”行的末尾;因为git存储库通常包含程序源代码,而不是可执行文件,所以它可能是用git检索源代码,然后在下一行编译和安装程序。在这种情况下,单&amp;应该替换为&amp;&amp;&amp;运算符,只有在第一个命令成功完成后才会运行第二个命令。这会在“配置”行中出现第二个错误,其中放置了&amp;表示只有“make install”命令将在“configure”和“make”步骤按顺序完成后异步运行(尽管由于缺少写入权限,除非使用sudo运行,否则这可能会失败)。为了尽可能地取得成功,这两行应该是这样的,否则脚本应该执行两次:
git clone https://github.com/”$1″/”$1“&amp;&amp; (cd“$ 1”; ./configure; make; sudo make install)&amp;
由于所有命令都在后台运行,因此任何需要用户输入的命令都将停止并等待直到前台。常见的请求是数据库密码,或者是否允许重新启动安装服务。这可能导致仅部分安装或配置包。 (请参阅下面有关“是”的更多信息。)
标题文本提到了同一个程序可能在多个存储库中的可能性,因此在这种情况下,脚本将下载并安装多个版本,或者它可能在许多存储库上失败,在这种情况下通常没有什么不好的事情发生。由于所有命令都来自不同的操作系统,版本或发行版,因此不太可能有多个命令可用(除了pip /easy_install和两种形式的apt-get)或甚至存在于同一系统中。它提到在不同的存储库获取程序运行期间添加一种自动对所提出的问题说“是”的方法,通过使它们从另一个编写(几乎)无穷无尽的“y”流的程序读取输入,可以简化事情进一步。这不适用于任何基于curses的菜单,也不适用于回答任何更复杂的问题。向命令添加2&gt; /dev /null会将第二个输出流(“错误流”)重定向到空设备驱动程序,该驱动程序会丢弃对它的所有写入,这意味着错误(程序包不存在)将不会发送到屏幕。