来自 bash 手册关于 shebang
大多数 Unix 版本都将其作为操作系统命令执行机制的一部分。如果脚本的第一行以两个字符“#!”开头,则该行的其余部分指定程序的解释器。因此,您可以指定 Bash、awk、Perl 或其他一些解释器,并用该语言编写脚本文件的其余部分。
向解释者提出的论点包括单个可选参数跟随脚本文件第一行的解释器名称,然后是脚本文件的名称, 其次是 其余的论点。 Bash 将在本身不处理此操作的操作系统上执行此操作。请注意,某些旧版本的 Unix 将解释器名称和参数限制为最多 32 个字符。
“可选参数”是指选项的参数,还是可能存在或不存在的参数?
为什么是“单一可选参数”?它不允许多个“可选参数”吗?
如果脚本看起来像
#! /path/to/interpreter --opt1 opt1-arg --opt2 opt2-arg --opt3 nonopt-arg1 nonopt-arg2
...
当我在 bash 中运行脚本时
$ myscript arg1 arg2 arg3
bash 中实际执行的命令是什么?是吗
$ /path/to/interpreter --opt1 opt1-arg --opt2 opt2-arg --opt3 nonopt-arg1 nonopt-arg2 myscript arg1 arg2 arg3
谢谢。
答案1
在这种情况下,解释器的参数是在解释 shebang 行之后构造的参数,将 shebang 行与脚本名称及其命令行参数组合起来。
因此,AWK 脚本以
#! /usr/bin/awk -f
命名myscript
和称呼为
./myscript file1 file2
结果为实际参数
/usr/bin/awk -f ./myscript file1 file2
-f
在这种情况下是单个可选参数。并非所有解释器都需要一个(参见/bin/sh
示例),并且许多系统最多只允许一个(因此您的 shebang 行将无法按您的预期工作)。但参数可以包含空格;解释器之后的 shebang 行的全部内容作为单个参数传递。
要试验 shebang 行,您可以使用#! /bin/echo
(尽管当涉及空格时这无助于区分参数)。
看程序如何运行有关如何处理 shebang 行的更详细说明(在 Linux 上)。
答案2
阅读你的execve(2)
手册页。对单个可选参数的限制取决于操作系统。 Linux 将解释器之后的所有单词视为一个参数
如果你想这样做:
#! /path/to/interpreter --opt1 opt1-arg --opt2 opt2-arg --opt3 nonopt-arg1 nonopt-arg2
事实上你应该这样做
#!/bin/sh
exec /path/to/interpreter --opt1 opt1-arg --opt2 opt2-arg --opt3 nonopt-arg1 nonopt-arg2 "$@"
# ...................................................................................... ^^^^
更新:我注意到该env
程序有一个-S
用于此目的的选项:shebang 可以是(尽管如果我必须维护这个程序,我会不高兴)
#!/usr/bin/env -S /path/to/interpreter --opt1 opt1-arg --opt2 opt2-arg --opt3 nonopt-arg1 nonopt-arg2
阅读你的env(1)
手册页。