I want the command that was used to invoke the python script to be available in the script itself.
Like:
python3 foo.py -a -b
python foo.py -c
Is it possible in foo.py to get these whole commands.
I want the command that was used to invoke the python script to be available in the script itself.
Like:
python3 foo.py -a -b
python foo.py -c
Is it possible in foo.py to get these whole commands.
Use sys.executable
and sys.argv
:
from __future__ import print_function
import sys
print(sys.executable)
print(sys.argv)
The above should work with Python 2 and Python 3 (below is from macOS):
howes% python2 blah.py 1 -m 123 53131
/System/Library/Frameworks/Python.framework/Versions/2.7/Resources/Python.app/Contents/MacOS/Python
['blah.py', '1', '-m', '123', '53131']
howes% python3 blah.py 1 -m 123 53131
/usr/local/opt/python/bin/python3.7
['blah.py', '1', '-m', '123', '53131']
EDIT
If that is not enough, you can try the psutil library (pip install psutil):
from __future__ import print_function
import os, psutil
us = psutil.Process(os.getpid())
print(us.cmdline())
print(us.exe())
macOS 10.15.2 (Python 2.7 and Python 3.7*):
howes% python blah.py -a 1 -b 2 3 4
['/System/Library/Frameworks/Python.framework/Versions/2.7/Resources/Python.app/Contents/MacOS/Python', 'blah.py', '-a', '1', '-b', '2', '3', '4']
/System/Library/Frameworks/Python.framework/Versions/2.7/Resources/Python.app/Contents/MacOS/Python
howes% python3 blah.py -a 1 -b 2 3 4
['/usr/local/Cellar/python/3.7.6_1/Frameworks/Python.framework/Versions/3.7/Resources/Python.app/Contents/MacOS/Python', 'blah.py', '-a', '1', '-b', '2', '3', '4']
/usr/local/Cellar/python/3.7.6_1/Frameworks/Python.framework/Versions/3.7/Resources/Python.app/Contents/MacOS/Python
howes%
Windows 10 (Python 2.7 and Python 3.8):
C:\Users\b.howes>python2 blah.py -a 1 -b 2 3 4
['python2', 'blah.py', '-a', '1', '-b', '2', '3', '4']
C:\Python27\python2.exe
C:\Users\b.howes>python blah.py -a 1 -b 2 3 4
['python', 'blah.py', '-a', '1', '-b', '2', '3', '4']
C:\Users\b.howes\AppData\Local\Programs\Python\Python38\python.exe
The closest thing I can think of is this:
import sys
import os
s = ""
for arg in sys.argv:
s = s + arg + " "
print(os.path.basename(sys.executable) + " " + s)
Example output (on windows):
$ python tmp.py -a -b
python.exe tmp.py -a -b
In Unix environments, you do not have access to the command line itself -- this is not python specific. However, a shell or other well-behaved program executing another program will place the executable name or path in the first argument.
Python's sys.argv
is not giving you, however, the OS-level command line.
You can obtain the python executable with sys.executable
, but neither this nor sys.argv
would give you the full command line:
Say this is foo.py
:
import sys
print(sys.argv)
print(sys.executable)
Then:
$ python -O foo.py a b c
['foo.py', 'a', 'b', 'c']
/usr/bin/python
As you can see, the -O
flag is not present there.
If you really need these, the way to obtain it is probably dependent on the OS (I do not know if python gives you access to these "low-level" command line arguments).
If you are on Linux, you could do:
import os
with open("/proc/%s/cmdline" % os.getpid(), "rb") as f:
cmdline = f.read()
print(cmdline.split(b"\x00"))
With the result:
$ python -O foo.py a b c
['python', '-O', 'foo.py', 'a', 'b', 'c', '']
Note the last empty string is due to how cmdline
has NUL-terminated strings, so the last character will be b"\x00"
, hence split()
will give you the last empty string.