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

Ale*_*lls 5 executable shell-script node.js

我在脚本的顶部有这个

#!/usr/bin/env mocha
Run Code Online (Sandbox Code Playgroud)

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

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

mocha 接受可选参数,所以我想做这样的事情:

#!/usr/bin/env mocha --reporter=tap --output=foo
Run Code Online (Sandbox Code Playgroud)

但我认为这是不允许的。

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

Gil*_*il' 9

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

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

最明显的解决方法是使用包装脚本。不是/path/to/my-script包含 mocha 代码,而是将 mocha 代码放在其他文件中/path/to/my-script.real并制作/path/to/my-script一个小的 shell 脚本。这是一个示例包装器,它假定实际代码位于与脚本同名的文件中,并.real在末尾加上。

#!/bin/sh
exec mocha --reporter=tap --output=foo "$0.real" "$@"
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

  • 作为后一种选择的一个例子:Scala 编程语言有一个“脚本模式”,它是专门为这样的事情设计的,特别是 Scala 执行引擎会忽略 `#!` 和 `!#` 之间的任何内容,所以您可以在其中使用复杂的 shell / Perl / Python / Ruby 脚本,以找到并启动合适的 JVM、定位 Scala 安装、为 JVM 和 Scala 编译器找出适当的参数和配置选项等等,然后只需`exec`你拼凑起来的任何命令行,Scala将忽略脚本部分。 (3认同)