如果我啓動werkzeug開發服務器,那麼它將在fork上丟失-c cmd 選項。
首先,該過程不是簡單的分叉。一個新的Python解釋器被調用。
與it will lost -c cmd
是什麼意思? cmd
字符串在argv中消失的事實?那就是:
$ python -c "import sys; print(sys.argv)"
['-c']
事實上,cmd
字符串不是從sys.argv
中訪問。 This是相關文檔:
如果是使用-c命令行選項的 解釋器執行的命令,argv的[0]被設定爲字符串「-c」
該文檔做沒有評論實際的命令字符串。儘管該命令字符串被明確「發送」爲Python解釋器可執行文件的參數,但CPython實現似乎並未在sys.argv
中公開此信息。我想沒有辦法在不更改sysmodule.c
的源代碼的情況下重構此信息。所以,如果你認爲你依靠提取cmd
- 你不應該!你需要找到另一種方式來注入這些信息。
編輯:
實際的命令字符串在Modules/main.c
消耗功能Py_Main()
:
wcscpy(command, _PyOS_optarg);
這command
是main.c
正在執行以後什麼。
命令行參數通過PySys_SetArgv(argc-_PyOS_optind, argv+_PyOS_optind);
進行處理,後者又調用sysmodule.c
中的makeargvobject()
。後者函數將二進制參數數據翻譯成類似for (i = 0; i < argc; i++) {}
的循環中的Python unicode對象(至少在Python 3中)。所以,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) {
測試:
$ ./python -c "import sys; print(sys.argv)"
['./python', '-c', 'import sys; print(sys.argv)']
謝謝!沒有找到「cmd」真的有條紋的地方。在這個文件中我找到了Py_GetArgcArgv! 然後我嘗試了一些奇怪的工作人員,像這樣奇怪的結果: '>>> python -c'import ctypes; argv = ctypes.POINTER(ctypes.c_char_p)(); argc = ctypes.c_int(); ctypes.pythonapi.Py_GetArgcArgv(ctypes.byref(argc),ctypes.byref(argv)); print([argv [i] for i in xrange(0,argc.value)])'' '['python','-c','-c']' – 2015-02-10 09:01:40