9

I want to obtain the true value of the operating system's argv[0] in a Python program. Python's sys.argv[0] is not this value: it is the name of the Python script being executed (with some exceptions). What I want is a foo.py that will print "somestring" when executed as

exec -a "somestring" python foo.py

The trivial program

#! /usr/bin/env python
import sys
print sys.argv[0]

will print "foo.py" instead.

Does anyone know how to obtain this? There are some related functions in the Python C API: e.g. Py_GetProgramName. But this doesn't seem to be exposed to the Python world anywhere. Py_GetProgramFullPath works off of argv[0] but munges it try to obtain a path to a Python interpreter. (This value is propagated to sys.executable, so that variable isn't right either.) Do I really have to write a C module to get this value?

Edit: Also asked (but not helpfully answered) here.

pkgw
  • 93
  • 5

1 Answers1

7

On Linux you can read the contents of /proc/self/cmdline:

#!/usr/bin/env python
import sys
print sys.argv[0]

f = open('/proc/self/cmdline', 'rb')
cmdline = f.read()
f.close()

print repr(cmdline.split('\x00'))

And the output is:

$ bash
$ exec -a "somestring" python foo.py 
foo.py
['somestring', 'foo.py', '']

There seems to be a bug in bash The exec command replaces the shell closing the terminal session after the interpreter exits. That's the first bash for.

vz0
  • 32,345
  • 7
  • 44
  • 77
  • It's not a bash bug, the `exec` command replaces the shell with another program. – interjay Feb 01 '11 at 21:08
  • Ooh, devious. I wouldn't be surprised if this had portability issues but it's good for me. – pkgw Feb 01 '11 at 21:11
  • One caveat is that the above example breaks if the "python" is left out of the `exec` line, since the hashbang interpreter and `/usr/bin/env` don't propagate the setting of argv[0]. But those aren't Python's fault. – pkgw Feb 01 '11 at 21:17
  • and on Windows, you should be able to use wmi to read the command line arguments: see: http://mail.python.org/pipermail/python-win32/2007-December/006498.html – Gerrat Feb 01 '11 at 21:18
  • I've posted a more universal solution, which does not rely on /proc, since FreeBSD doesn't have that, here: https://stackoverflow.com/questions/59297692/python-obtaining-the-oss-argv0-not-sys-argv0/59315498#59315498. (It works on Linux, too.) – Bill Evans at Mariposa Dec 13 '19 at 02:55
  • @BillEvansatMariposa in Python there's even a better version, works everywhere https://stackoverflow.com/a/59334493/209629 – vz0 Dec 14 '19 at 11:00
  • It doesn't work if there's a shebang #!/usr/bin/env python3 at the beginning of the program. – Bill Evans at Mariposa Dec 15 '19 at 09:41
  • Correction: it doesn't work if there's a shebang #!/usr/bin/env python3 at the beginning of the program and you run the program directly, without "python3" on the command line. – Bill Evans at Mariposa Dec 15 '19 at 10:36