When the script is called explicitly with python, it is argvreset so that argv[0]is the path to the running script. This is the case if called as python foo/bar.pyor even as python -m foo.bar.
I need a way to restore the original argv(i.e. the one that is received python). Unfortunately, this is not as simple as adding sys.executablein sys.argv, because it python foo/bar.pydiffers from python -m foo.bar(implicit PYTHONPATHdiffers, which can be crucial depending on the structure of your module).
In particular, in cases python foo/bar.py some other argsand python -m foo.bar some other argsI want to restore ['python', 'foo/bar.py', 'some', 'other', 'args']and ['python', '-m', 'foo.bar', 'some', 'other', 'args']accordingly.
I know previous questions about this:
But they seem to have a misunderstanding of how shells work, and the answers reflect that. I'm not interested in canceling the shell (for example, evaluated shell shells and functions in order), I just want to get the original argvone specified in python.
The only solution I found is to use /proc/<PID>/cmdline:
import os
with open("/proc/{}/cmdline".format(os.getpid()), 'rb') as f:
original_argv = f.read().split('\0')[:-1]
This works, but Linux-only (without OSX and Windows support, it seems that installing a wmi package is required ). Fortunately for my current use case, this restriction is in order. But it would be nice to have a cleaner cross-platform approach.
, /proc/<PID>/cmdline , , python script ( , syscall exec, , , exec ). , - , (, -m) , C ( , python -m this.does.not.exist , , ). , , - argv (, spelunking ?).
tl; dr - (, ) argv, python ( python -m blah blah.py)?
edit spelunking Py_GetArgcArgv, ctypes ( , qaru.site/questions/1022330/..., ):
import ctypes
_argv = ctypes.POINTER(ctypes.c_wchar_p)()
_argc = ctypes.c_int()
ctypes.pythonapi.Py_GetArgcArgv(ctypes.byref(_argc),
ctypes.byref(_argv))
argv = _argv[:_argc.value]
print(argv)
, python, ( cpython ctypes, yucky, ). , , Ubunutu 16.04 (python -m foo.bar ['python', '-m', '-m']), ( OSX). ( ctypes).