如何获得python解释器完整的argv命令行选项? [英] How to get python interpreter full argv command line options?

查看:23
本文介绍了如何获得python解释器完整的argv命令行选项?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们从文档中了解到:

-c如果给出这个选项,sys.argv 的第一个元素将是-c",当前目录将被添加到 sys.path 的开头(允许该目录中的模块作为顶级模块导入).

-c If this option is given, the first element of sys.argv will be "-c" and the current directory will be added to the start of sys.path (allowing modules in that directory to be imported as top level modules).

如何获得完整的解释器命令行选项?我需要它来解决这个问题:

How can I get full interpreter command line options? I need it to solve this:

https://github.com/mitsuughiblob/f50bdc04cf1c8d71d12d13a0c8ef2878477f4d24/werkzeug/_reloader.py#L141

如果我启动 werkzeug 开发服务器,那么它会在 fork 上丢失 -c cmd 选项.我想修补werkzeug,但找不到如何获得真实选项.

If I start werkzeug development server, then it will lost -c cmd option on fork. I want to patch werkzeug, but cant find how to get real options.

如果你想知道我为什么需要这个 - 我想在 manage.py 之前预执行一些想要解析 sys.argv 的代码.而且我认为 werkzeug 方法是不正确的,因为它在极端情况下不起作用.

If you want to know why I need this - I want to preexecute some code before manage.py that want to parse sys.argv. And also I think that werkzeug method is incorrect due it is not working in corner case.

推荐答案

如果我启动werkzeug开发服务器,那么它会丢失-c cmd前叉选项.

If I start werkzeug development server, then it will lost -c cmd option on fork.

首先,进程不是简单的分叉.一个新的 Python 解释器被调用.

First of all, the process is not simply forked. A fresh Python interpreter is invoked.

它会丢失 -c cmd 是什么意思?cmd 字符串在 argv 中消失的事实?即:

What do you mean with it will lost -c cmd? The fact that the cmd string is gone in argv? That is:

$ python -c "import sys; print(sys.argv)"
['-c']

确实,cmd 字符串无法从 sys.argv 中访问.这个是相关文档:

Indeed, the cmd string is not accessible from within sys.argv. This is related documentation:

如果命令是使用 -c 命令行选项执行的解释器,argv[0] 设置为字符串 '-c'

If the command was executed using the -c command line option to the interpreter, argv[0] is set to the string '-c'

文档不对实际的命令字符串进行评论.尽管该命令字符串显然是作为参数发送"给 Python 解释器可执行文件的,但 CPython 实现似乎并未在 sys.argv 中公开此信息.我想如果不更改 sysmodule.c 的源代码,就无法重建这些信息.所以,如果你认为你依赖于提取 cmd —— 你不应该!您需要找到另一种方式来注入这些信息.

The docs do not comment on the actual command string. While that command string was clearly "sent" as an argument to the Python interpreter exectuable, the CPython implementation does not seem to expose this information within sys.argv. I guess there is no way to reconstruct this information without changing the source code of sysmodule.c. So, if you think you depend on extracting cmd -- you shouldn't! You need to find another way to inject this information.

实际的命令字符串在 Modules/main 中使用.c在函数Py_Main()中:

The actual command string is consumed in Modules/main.c in function Py_Main():

wcscpy(command, _PyOS_optarg);

command 是稍后在main.c 中执行的内容.

This command is what is being executed later on in main.c.

命令行参数通过PySys_SetArgv(argc-_PyOS_optind, argv+_PyOS_optind); 处理,它依次调用sysmodule.c 中的makeargvobject().后一个函数在 for (i = 0; i < argc; i++) {}-like 循环中将二进制参数数据转换为 Python unicode 对象(至少在 Python 3 中是这样).因此,argc 必须(故意)关闭 -1 以忽略所述循环中的命令.

The command line arguments are processed via PySys_SetArgv(argc-_PyOS_optind, argv+_PyOS_optind);, which in turn calls makeargvobject() in sysmodule.c. The latter function translates the binary argument data into Python unicode objects (at least in Python 3 it does) in a for (i = 0; i < argc; i++) {}-like loop. So, argc must (purposely) be off by -1 in order to ignore the command in said loop.

也就是说,删除命令参数的神奇之处在于设置_PyOS_optind,以便后续调用PySys_SetArgv(argc-_PyOS_optind, argv+_PyOS_optind);参数计数比实际值小(1).

That is, the magic of dropping the command argument is in setting _PyOS_optind, so that the subsequent call to PySys_SetArgv(argc-_PyOS_optind, argv+_PyOS_optind); suggests an argument count smaller (by 1) than it actually is.

我并没有真正坚持到底,但我想这些行中的递减是负责任的:

I did not really follow through, but I guess the decrement in these lines is responsible:

if (command != NULL) {
    /* Backup _PyOS_optind and force sys.argv[0] = '-c' */
    _PyOS_optind--;
    argv[_PyOS_optind] = L"-c";
}

编辑 2:

在此处验证了 _PyOS_optind 的关键作用,其中包含当前 Python 3 提示的以下补丁:

Verified the crucial role of _PyOS_optind here with the following patch to the current Python 3 tip:

diff --git a/Modules/main.c b/Modules/main.c
--- a/Modules/main.c
+++ b/Modules/main.c
@@ -679,9 +679,11 @@
     }

     if (command != NULL) {
         /* Backup _PyOS_optind and force sys.argv[0] = '-c' */
         _PyOS_optind--;
-        argv[_PyOS_optind] = L"-c";
+        _PyOS_optind = 0;
+        //argv[_PyOS_optind] = L"-c";
     }

     if (module != NULL) {

测试:

 $ ./python -c "import sys; print(sys.argv)"
['./python', '-c', 'import sys; print(sys.argv)']

这篇关于如何获得python解释器完整的argv命令行选项?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆