c - 在 MacOS 中获取 pre-shebang 可执行文件路径(相当于 getauxval(

针对 bash - Detect if a script is being run via shebang or was specified as a command line argument - Unix & Linux Stack Exchange 描述的问题,我们需要区分脚本通过 shebang 运行和作为解释器的参数的情况。

An answer to that question建议使用 getauxval(AT_EXECFN) 获取 pre-shebang 可执行文件名称——这有效,但仅在 Linux 中有效。

由于 Pyenv 项目也正式支持 MacOS,如果我们要考虑该解决方案,我们需要一个等效项。


我检查过 Finding current executable's path without /proc/self/exe -- 但是 _dyld_get_image_name(0)_NSGetExecutablePath 都给出了 post-shebang 名称。这是我用来进行检查的示例程序(请参阅上面关于如何使用它的问题链接;其编译结果需要代替该问题中给出的 python3 Bash 脚本):

#include <stdio.h>
#include <unistd.h>
/*#include <sys/auxv.h>*/
#include <mach-o/dyld.h>
#include <sys/param.h>
#include <alloca.h>

int main(int argc, char** argv) {
        //char *at_execfn = (char*)getauxval(AT_EXECFN);
        //const char *at_execfn = _dyld_get_image_name(0);
        char *at_execfn = (char*)alloca(MAXPATHLEN);
        uint32_t at_execfn_len = MAXPATHLEN;
        _NSGetExecutablePath(at_execfn,&at_execfn_len);          
        printf("original executable: '%s'\n",at_execfn);
        for(int i=0; i<argc; i++) {
                printf("'%s'\n",argv[i]);
        }
        execvp("python3",argv);
}

最佳答案

此答案基于以下假设;我相信其他人会核实它们是否属实,但据我了解,它们是:

  1. Python 脚本只有在直接执行时才会使用 shebang。
  2. 否则,第一个命令行参数将始终是 pythonpython3 或其他变体(python3.x 等) .

您已经可以获得原始文件的路径,这很好,因为您可以阅读 shebang 的内容,但您还不知道是否使用了 shebang,对吗? Python 3.10 提供了一个有吸引力的解决方案:sys.orig_argv ,其中包括所有命令行参数,而不仅仅是那些从程序名称开始的参数,就像您使用普通的 sys.argv 一样。

但是,我确定您不会在 pyenv 中实现 3.10 独有的功能!如果是这种情况,您可以查看较旧的 C-API Py_GetArgcArgv ,其文档简单地说明:

Get the original command line arguments, before Python modified them.

无论哪种方式,我认为拥有文件路径以便您可以阅读 shebang 是难题的第一部分。第二部分是确定是否实际使用了 shebang,我认为大多数情况下答案都在命令行参数中。

关于c - 在 MacOS 中获取 pre-shebang 可执行文件路径(相当于 getauxval(AT_EXECFN) ),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68238888/

相关文章:

c++ - std::reference_wrapper 和 T 之间的最佳可行重

postgresql - psql:致命:用户 ""aws rds Postgresql 的 PAM

javascript - 来自 "pages/[...slug].js"的 Next.js 路由不起

reactjs - 如何使可选的对等依赖项真正可选

python - Pycharm调试Django项目(Dev分支)的问题

nestjs - 如何在 typeorm 中合并两个表?

android - 如何公开 StateFlow 但启动和停止底层 Flow

java - 如何在@Async 方法中测试异常?

node.js - PrismaClient 验证错误 : Invalid `prisma.user

android-studio - 在 Play Store Console 中更改草稿应用程序的应用