![包含有关如何在 hashbang 或其他地方运行文件的更多说明](https://linux22.com/image/108263/%E5%8C%85%E5%90%AB%E6%9C%89%E5%85%B3%E5%A6%82%E4%BD%95%E5%9C%A8%20hashbang%20%E6%88%96%E5%85%B6%E4%BB%96%E5%9C%B0%E6%96%B9%E8%BF%90%E8%A1%8C%E6%96%87%E4%BB%B6%E7%9A%84%E6%9B%B4%E5%A4%9A%E8%AF%B4%E6%98%8E.png)
我在脚本的顶部有这个
#!/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
...摩卡或任何可执行文件都必须接受环境变量,而不是命令行参数,以使其正常工作。
不幸的是,这是非常有限的,因为许多可执行文件不使用环境变量,因此这对于必须调用其他库等的库来说非常困难。