How To Get Python Interpreter Full Argv Command Line Options?
Solution 1:
If I start werkzeug development server, then it will lost -c cmd option on fork.
First of all, the process is not simply forked. A fresh Python interpreter is invoked.
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']
Indeed, the cmd
string is not accessible from within sys.argv
. This is related documentation:
If the command was executed using the -c command line option to the interpreter, argv[0] is set to the string '-c'
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.
Edit:
The actual command string is consumed in Modules/main.c
in function Py_Main()
:
wcscpy(command, _PyOS_optarg);
This command
is what is being executed later on in main.c
.
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.
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";
}
Edit2:
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) {
Test:
$ ./python -c "import sys; print(sys.argv)"
['./python', '-c', 'import sys; print(sys.argv)']
Post a Comment for "How To Get Python Interpreter Full Argv Command Line Options?"