问题
Inspired by another question here, I would like to retrieve the Python interpreter's full command line in a portable way. That is, I want to get the original argv
of the interpreter, not the sys.argv
which excludes options to the interpreter itself (like -m
, -O
, etc.).
sys.flags tells us which boolean options were set, but it doesn't tell us about -m
arguments, and the set of flags is bound to change over time, creating a maintenance burden.
On Linux you can use procfs to retrieve the original command line, but this is not portable (and it's sort of gross):
open('/proc/{}/cmdline'.format(os.getpid())).read().split('\0')
回答1:
You can use ctypes
~$ python2 -B -R -u
Python 2.7.9 (default, Dec 11 2014, 04:42:00)
[GCC 4.9.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
Persistent session history and tab completion are enabled.
>>> import ctypes
>>> argv = ctypes.POINTER(ctypes.c_char_p)()
>>> argc = ctypes.c_int()
>>> ctypes.pythonapi.Py_GetArgcArgv(ctypes.byref(argc), ctypes.byref(argv))
1227013240
>>> argc.value
4
>>> argv[0]
'python2'
>>> argv[1]
'-B'
>>> argv[2]
'-R'
>>> argv[3]
'-u'
回答2:
I'm going to add another answer to this. @bav had the right answer for Python 2.7, but it breaks in Python 3 as @szmoore points out (not just 3.7). The code below, however, will work in both Python 2 and Python 3 (the key to that is c_wchar_p
in Python 3 instead of c_char_p
in Python 2) and will properly convert the argv
into a Python list so that it's safe to use in other Python code without segfaulting:
def get_python_interpreter_arguments():
argc = ctypes.c_int()
argv = ctypes.POINTER(ctypes.c_wchar_p if sys.version_info >= (3, ) else ctypes.c_char_p)()
ctypes.pythonapi.Py_GetArgcArgv(ctypes.byref(argc), ctypes.byref(argv))
# Ctypes are weird. They can't be used in list comprehensions, you can't use `in` with them, and you can't
# use a for-each loop on them. We have to do an old-school for-i loop.
arguments = list()
for i in range(argc.value - len(sys.argv) + 1):
arguments.append(argv[i])
return arguments
You'll notice that it also returns only the interpreter arguments and excludes the augments found in sys.argv
. You can eliminate this behavior by removing - len(sys.argv) + 1
.
来源:https://stackoverflow.com/questions/28336431/retrieve-the-command-line-arguments-of-the-python-interpreter