0

I have a Python module that I call like this

python -m foo.bar arg1 -a foo --some-arg=10

And inside the bar.py module, I need to query the command that was used to call the module. For example, get_raw_terminal_command() would return "python -m foo.bar arg1 -a foo --some-arg=10".

I've seen several posts suggest import sys; sys.argv but sys.argv fails in multiple ways.

  1. sys.argv returns the full path the foo/bar.py file. I need the raw command for debugging purposes and calling python /path/to/foo/bar.py is not the same as calling python foo.bar
  2. In my production use-case, sys.argv is returning ['-c'] instead of the name or path of any Python module. I'm still in the middle of troubleshooting why this is happening but I've already made a case for why sys.argv isn't what I'm looking for anyway.

Another popular solution is to use argparse to rebuild the command-line input but I can't use it because I don't control how the Python code is being called. The solution must be generic.

Does anyone know how to get the raw command that is used to call a Python script from within the Python script? If possible, the solution should be compatible with Windows.

ColinKennedy
  • 828
  • 7
  • 24
  • 1
    Do you mind to edit your answer? I suggest you to use `argparse` [doc](https://docs.python.org/3/library/argparse.html) instead of `sys.argv`. – rpanai Feb 14 '19 at 15:56
  • The method that's being used to call the Python code isn't always my implementation so I can't use `argparse`. The solution needs to be generic. That said, I'll update my question to exclude `argparse` so people don't post it – ColinKennedy Feb 14 '19 at 17:52
  • Possible duplicate: https://stackoverflow.com/questions/11938327/what-is-the-proc-self-cmdline-getcommandline-equivalent-on-mac-os-x – ColinKennedy Feb 14 '19 at 17:58

2 Answers2

1

This won't be compatible with windows, but in GNU/Linux or Solaris (credit: tripleee) you should be able to use /proc/self/cmdline to see exactly how you were called :

 Import os

 with open("/proc/self/cmdline") as f:
      print(f.readline())
  • On my CentOS 7 machine, I had to `[line.replace('\x00', ' ') for line in f.readlines()]` to show spaces between command-line args but it seems to work well. If there's a Windows-specific solution that does the same thing, that'd be perfect – ColinKennedy Feb 14 '19 at 17:55
  • This also doesn't work on OSX, or a large number of OSes other than Linux and Solaris. The *nix isn't really correct here. https://en.wikipedia.org/wiki/Procfs has some further notes. – tripleee Feb 14 '19 at 17:55
  • Yep, you're right tripleee, updated answer accordingly – Mobus Dorphin Feb 14 '19 at 18:39
0

I found something that may be helpful for Windows users: https://bytes.com/topic/python/answers/706727-get-complete-command-line

I'll paste the code again, here:

import ctypes

p = ctypes.windll.kernel32.GetCommandLineA()
print ctypes.c_char_p(p).value

The ctypes solution worked for me. Another commenter pointed out that pywin32 also has its own flavor:

import win32api
print win32api.GetCommandLine ()

I didn't test it but that may work better.

ColinKennedy
  • 828
  • 7
  • 24