包含有关如何在 hashbang 或其他地方运行文件的更多说明

包含有关如何在 hashbang 或其他地方运行文件的更多说明

我在脚本的顶部有这个

#!/usr/bin/env mocha

大多数人都知道,这告诉操作系统使用哪个可执行文件来执行脚本。

但是,我的问题是 - 我们如何在 mocha 可执行文件中包含更多关于如何执行脚本的信息?

摩卡需要可选参数,所以我想做这样的事情:

#!/usr/bin/env mocha --reporter=tap --output=foo

但我认为这是不允许的。

如何为 mocha 可执行文件提供有关如何运行该文件的更多信息?

答案1

舍邦line 由内核解释,不太灵活。在 Linux 上,它仅限于单个参数:语法为#!、可选空格、解释器路径(不包含空格)、可选空格和可选单个参数(除了开头之外可以包含空格)。此外,shebang 行的总大小限制为 128 字节(BINPRM_BUF_SIZE内核源代码中的常量,用于load_script)。

如果您想传递多个参数,则需要一种解决方法。如果您用于#!/usr/bin/env路径扩展,则只有命令名称的空间,没有其他参数。

最明显的解决方法是包装脚本。/path/to/my-script您可以将 mocha 代码放入其他文件中/path/to/my-script.real并制作/path/to/my-script一个小型 shell 脚本,而不是包含mocha 代码。下面是一个示例包装器,它假设真正的代码位于与脚本同名的文件中,并.real在末尾加上。

#!/bin/sh
exec mocha --reporter=tap --output=foo "$0.real" "$@"

使用 shell 包装器,您可以借此机会执行更复杂的操作,例如定义环境变量、查找可用的解释器版本等。

在解释器之前使用exec可确保 mocha 脚本与 shell 包装器在同一进程中运行。如果没有exec,根据 shell,它可能作为子进程运行,这很重要,例如,如果您想向脚本发送信号。

有时,包装器脚本和实际代码可以位于同一个文件中,如果您设法编写多语言— 包含两种不同语言的有效代码的文件。编写多语言并不总是容易(甚至可能),但它的优点是不必管理和部署两个单独的文件。这是一个 JavaScript/shell 多语言程序,其中 shell 部分对文件执行 JS 解释器(假设 JS 解释器忽略 shebang 行,如果不忽略,你就无能为力):

#!/bin/sh
///bin/true; exec mocha --reporter=tap --output=foo "$0" "$@"
… (the rest is the JS code) …

答案2

作为后续吉尔斯的回答,这是一个独立的包装器。这是他的两种解决方案的混合。它具有 Gilles 提到的多语言脚本(一个需要维护和部署的脚本)的优点,但没有缺点(引用 Gilles:“编写多语言脚本并不总是容易甚至不可能”)。

它只需在脚本顶部添加几行:

#!/bin/bash
exec mocha --reporter=tap --output=foo <(sed -n '/^#MOCHA_START#/,$ p' "$0")
#MOCHA_START#
....
....
(mocha script)
....
....

该行后面的#MOCHA_START#是您的实际摩卡脚本,保持不变。前三行的作用是提取 mocha 脚本并使用它以及所需的参数调用 mocha。

但是,您可能必须强制文本编辑器将文件解释为 Mocha 脚本并相应地为其着色,因为它可能会被脚本的第一行(表明这是一个 Bash 脚本)所混淆:

在此输入图像描述

答案3

使用 shebang 线的缺点之一#!/usr/bin/env是我们无法传递参数。

但是,如果您使用解释器的路径,则可以传递参数:

#!/path/to/mocha --reporter=tap --output=foo

也可以看看:

答案4

我目前知道如何做到这一点的唯一方法是使用环境变量,所以在我的 hashbang 中我有这个:

#!/usr/bin/env mocha

...摩卡或任何可执行文件都必须接受环境变量,而不是命令行参数,以使其正常工作。

不幸的是,这是非常有限的,因为许多可执行文件不使用环境变量,因此这对于必须调用其他库等的库来说非常困难。

相关内容