解释器如何检测从脚本而不是命令行调用?

数据表

正如“已知”,一个my-script-file

#!/path/to/interpreter -arg1 val1 -arg2 val2

通过使用2 (!) 个参数exec调用来执行/path/to/interpreter

  1. -arg1 val1 -arg2 val2
  2. my-script-file

(而不是,正如人们可能天真地预期的那样,有 5 个参数

  1. -arg1
  2. val1
  3. -arg2
  4. val2
  5. my-script-file

正如之前许多问题中所解释的,例如,https : //stackoverflow.com/a/4304187/850781)。

我的问题来自解释器开发人员的 POV 而不是脚本编写者

interpreter与命令行相反,我如何从shebang调用可执行文件内部检测到?

然后我将能够决定是否需要按空间拆分我的第一个参数以从"-arg1 val1 -arg2 val2"["-arg1", "val1", "-arg2", "val2"]或不。

这里的主要问题是其中以空格命名的脚本文件。如果我总是拆分第一个参数,我会像这样失败:

$ my-interpreter "weird file name with spaces"
my-interpreter: "weird": No such file or directory
布鲁诺·海布尔

在 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功能。并且肯定存在它不能正常工作的情况。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

命令行解释器如何工作?

告诉 python 解释器在脚本本身中使用解释器命令行开关

node js 命令行解释器?

C-命令行解释器

如何从命令行而不是SQL调用PL / pgSQL

在bash命令行上如何*解释?

从Windows命令行调用脚本

我怎么知道我的Python脚本是通过命令行中的解释器还是作为可执行文件(通过shebang)调用的?

Shell脚本:如何将脚本的命令行参数传递给它调用的命令?

如何使python命令行程序自动完成任意内容而不是解释程序

如何在命令行上强制解释为关键字而不是别名?

如何防止命令行参数由R与仅由脚本解释?

如何使python命令行程序自动完成任意内容NOT解释器

如何在pudb中增大命令行/解释器窗格/窗口?

检测脚本是否从Racket的命令行执行?

从命令行运行特定的 python 解释器

检索Python解释器的命令行参数

OS GUI的外壳与命令行解释器是否不同?

Perl命令行解释器在退出时崩溃

PHP Imagick 类在从 Web 服务器而不是从命令行调用时工作

在没有脚本文件的情况下将命令行参数传递给python解释器

无法使用 Python 3.8.0 在命令行上运行 python 文件;它改为调用 python 解释器

R: Reticulate -- 如何调用需要多个命令行参数的 Python 脚本

如何在 PowerShell 脚本形式的命令行中调用特定函数?

在命令行中如何解释括号?

如何调用命令行命令(AFNI命令)?

Nutch:用Java而不是命令行调用?

在批处理脚本中调用命令行

从bash脚本调用时获取Python命令行输出