运行以 shebang 作为名称且参数相同的脚本时,实际执行的命令是什么?

Tim*_*Tim 0 command-line bash shebang

来自关于shebang的bash手册

大多数版本的 Unix 都将此作为操作系统命令执行机制的一部分。如果脚本的第一行以两个字符“#!”开头,则该行的其余部分指定程序的解释器。因此,您可以指定 Bash、awk、Perl 或其他一些解释器,并用该语言编写脚本文件的其余部分。

解释器的参数由脚本文件第一行的解释器名称后面的单个可选参数组成,后跟脚本文件的名称,然后 是其余参数。Bash 将在自己不处理它的操作系统上执行此操作。请注意,某些较旧版本的 Unix 将解释器名称和参数限制为最多 32 个字符。

“可选参数”是指选项的参数,还是可能存在或不存在的参数?

为什么是“单个可选参数”?它不允许多个“可选参数”吗?

如果脚本看起来像

#! /path/to/interpreter --opt1 opt1-arg --opt2 opt2-arg --opt3 nonopt-arg1 nonopt-arg2

...
Run Code Online (Sandbox Code Playgroud)

当我在 bash 中运行脚本时

$ myscript arg1 arg2 arg3
Run Code Online (Sandbox Code Playgroud)

在 bash 中执行的实际命令是什么?是吗

$ /path/to/interpreter --opt1 opt1-arg --opt2 opt2-arg --opt3 nonopt-arg1 nonopt-arg2 myscript arg1 arg2 arg3
Run Code Online (Sandbox Code Playgroud)

谢谢。

Ste*_*itt 6

在这种情况下,解释器的参数是在解释 shebang 行之后构造的参数,将 shebang 行与脚本名称及其命令行参数组合在一起。

因此,一个 AWK 脚本以

#! /usr/bin/awk -f
Run Code Online (Sandbox Code Playgroud)

命名myscript并称为

./myscript file1 file2
Run Code Online (Sandbox Code Playgroud)

导致实际参数

/usr/bin/awk -f ./myscript file1 file2
Run Code Online (Sandbox Code Playgroud)

-f在这种情况下是单个可选参数。并非所有解释器都需要一个(参见/bin/sh示例),并且许多系统最多只允许一个(因此您的 shebang 行不会像您期望的那样工作)。参数可以包含空格;解释器之后的 shebang 行的全部内容作为单个参数传递。

要尝试使用 shebang 行,您可以使用#! /bin/echo(尽管在涉及空格时这无助于区分参数)。

有关如何处理 shebang 行的更详细说明(在 Linux 上),请参阅程序如何运行


gle*_*man 5

阅读你的execve(2)手册页。对单个可选参数的限制取决于操作系统。Linux 将解释器之后的所有单词视为一个参数

如果你想这样做:

#! /path/to/interpreter --opt1 opt1-arg --opt2 opt2-arg --opt3 nonopt-arg1 nonopt-arg2
Run Code Online (Sandbox Code Playgroud)

事实上你应该这样做

#!/bin/sh
exec /path/to/interpreter --opt1 opt1-arg --opt2 opt2-arg --opt3 nonopt-arg1 nonopt-arg2 "$@"
# ...................................................................................... ^^^^
Run Code Online (Sandbox Code Playgroud)

更新:我注意到该env程序有一个-S用于此目的的选项:shebang 可以(尽管如果我必须维护这个程序,我不会高兴)

#!/usr/bin/env -S /path/to/interpreter --opt1 opt1-arg --opt2 opt2-arg --opt3 nonopt-arg1 nonopt-arg2
Run Code Online (Sandbox Code Playgroud)

阅读你的env(1)手册页。