代码之家  ›  专栏  ›  技术社区  ›  ivan_pozdeev RenanSS

Get pre-shebang可执行路径(相当于getauxval(AT_EXECFN))

  •  0
  • ivan_pozdeev RenanSS  · 技术社区  · 3 年前

    对于中描述的问题 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) --这是可行的,但只适用于Linux。

    由于PYENV项目也正式支持MACOS,如果我们要考虑这个解决方案,我们需要一个等价物。


    我查过了 Finding current executable's path without /proc/self/exe --但两者都有 _dyld_get_image_name(0) _NSGetExecutablePath 给帖子起个名字。下面是一个我用来进行检查的示例程序(参见上面关于如何使用它的问题链接;需要将其编译结果替换为 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);
    }
    
    0 回复  |  直到 3 年前
        1
  •  -1
  •   jdevries3133    3 年前

    这个答案基于以下假设:;我相信其他人会审查他们是否属实,但据我所知,他们是:

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

    您已经可以获得原始文件的路径,这很好,因为您可以读取shebang的内容 ,但你还不知道是否使用了shebang,对吗?Python 3.10提供了一个吸引人的解决方案: sys.orig_argv ,其中包括 全部的 命令行参数,而不仅仅是程序名中的参数 sys.argv .

    不过,我相信你不会在pyenv中实现3.10独占特性!如果是这样的话,你可以看到旧的C-API Py_GetArgcArgv ,其文档仅说明:

    在Python修改之前获取原始命令行参数。

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