如果我启动 werkzeug 开发服务器,那么它会丢失 -c cmd
叉子上的选项。
首先,进程并不是简单的分叉。调用新的 Python 解释器。
你是什么意思it will lost -c cmd
?事实是cmd
argv 中的字符串消失了?那是:
$ python -c "import sys; print(sys.argv)"
['-c']
确实,cmd
无法从内部访问字符串sys.argv
. This https://docs.python.org/2/library/sys.html#sys.argv是相关文档:
如果使用 -c 命令行选项执行该命令
解释器,argv[0] 设置为字符串 '-c'
该文档没有评论实际的命令字符串。虽然该命令字符串显然是作为参数“发送”给 Python 解释器可执行文件的,但 CPython 实现似乎并未在其中公开此信息sys.argv
。我想在不改变源代码的情况下无法重建这些信息sysmodule.c
。所以,如果你认为你依赖于提取cmd
——你不应该!您需要找到另一种方法来注入此信息。
Edit:
实际的命令字符串消耗在Modules/main.c https://github.com/python/cpython/blob/master/Modules/main.c在功能上Py_Main()
:
wcscpy(command, _PyOS_optarg);
This command
是稍后执行的main.c
.
命令行参数通过以下方式处理PySys_SetArgv(argc-_PyOS_optind, argv+_PyOS_optind);
,这又调用makeargvobject()
in sysmodule.c
。后一个函数将二进制参数数据转换为 Python unicode 对象(至少在 Python 3 中是这样)for (i = 0; i < argc; i++) {}
类似循环。所以,argc
必须(故意)关闭 -1 以忽略所述循环中的命令。
也就是说,删除命令参数的魔力在于设置_PyOS_optind
,以便后续调用PySys_SetArgv(argc-_PyOS_optind, argv+_PyOS_optind);
建议参数计数比实际小(1)。
我并没有真正跟进,但我想这些行中的减少是有原因的:
if (command != NULL) {
/* Backup _PyOS_optind and force sys.argv[0] = '-c' */
_PyOS_optind--;
argv[_PyOS_optind] = L"-c";
}
Edit2:
验证了关键作用_PyOS_optind
这里是当前 Python 3 技巧的以下补丁:
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) {
Test:
$ ./python -c "import sys; print(sys.argv)"
['./python', '-c', 'import sys; print(sys.argv)']