作为"is known",以
开头的脚本my-script-file
#!/path/to/interpreter -arg1 val1 -arg2 val2
由exec
使用 2 (!)参数调用/path/to/interpreter
执行:
-arg1 val1 -arg2 val2
my-script-file
(和不是,正如人们可能天真地期待的那样,有5个参数
-arg1
val1
-arg2
val2
my-script-file
正如之前许多问题中所解释的那样,例如, https://stackoverflow.com/a/4304187/850781)。
我的问题来自解释程序开发人员的POV,不是脚本编写者。
interpreter
可执行文件内部而不是命令行?然后我将能够决定是否需要拆分我的第一个参数
按空格从"-arg1 val1 -arg2 val2"
转到["-arg1", "val1", "-arg2", "val2"]
或不。{/ p>
这里的主要问题是以空格命名的脚本文件。 如果我总是分开第一个论点,我会这样失败:
$ my-interpreter "weird file name with spaces"
my-interpreter: "weird": No such file or directory
答案 0 :(得分:2)
在Linux上,使用GNU libc或musl libc,您可以使用aux-vector区分这两种情况。
以下是一些示例代码:
#define _GNU_SOURCE 1
#include <stdio.h>
#include <errno.h>
#include <sys/auxv.h>
#include <sys/stat.h>
int
main (int argc, char* argv[])
{
printf ("argv[0] = %s\n", argv[0]);
/* https://www.gnu.org/software/libc/manual/html_node/Error-Messages.html */
printf ("program_invocation_name = %s\n", program_invocation_name);
/* http://man7.org/linux/man-pages/man3/getauxval.3.html */
printf ("auxv[AT_EXECFN] = %s\n", (const char *) getauxval (AT_EXECFN));
/* Determine whether the last two are the same. */
struct stat statbuf1, statbuf2;
if (stat (program_invocation_name, &statbuf1) >= 0
&& stat ((const char *) getauxval (AT_EXECFN), &statbuf2) >= 0)
printf ("same? %d\n", statbuf1.st_dev == statbuf2.st_dev && statbuf1.st_ino == statbuf2.st_ino);
}
直接调用的结果:
$ ./a.out
argv[0] = ./a.out
program_invocation_name = ./a.out
auxv[AT_EXECFN] = ./a.out
same? 1
通过以#!/home/bruno/a.out
开头的脚本调用的结果:
$ ./a.script
argv[0] = /home/bruno/a.out
program_invocation_name = /home/bruno/a.out
auxv[AT_EXECFN] = ./a.script
same? 0
这种方法当然非常不可移植:只有Linux具有getauxv
功能。并且肯定会出现效果不佳的情况。