0

I'm building a cgi script with python on my web host and using wget to test it. The shebang #!/home/me/virtualenv/public_html/chartex/3.6/bin/python3.6 points it at the right version of python to use so that print(sys.version, sys.executable) in the cgi correctly returns:

3.6.15 (default, Jan 14 2022, 12:16:54) 
[GCC 4.8.5 20150623 (Red Hat 4.8.5-44)] /home/me/virtualenv/public_html/chartex/3.6/bin/python3.6_bin

Moreover print(os.path.abspath('.')) in the cgi returns the correct path to where the script resides.

However, if I want the cgi to report the version of an existing binary on the system print(os.system('twopi -V')) returns only 0. The same thing happens doing print(os.system('ls')).

If I run the same python installed in this virtualenv (calling it by its full pathname on the server) at the command line, and there call print(os.system('twopi -V')), it correctly tells me: twopi - graphviz version 4.0.0 (20220529.0937) and then on the next line: 0. Likewise if I do print(os.system('ls'))

Is this kind of system command impossible for a cgi script? Is there a way I can coerce the script to report the result of such a system command?

jjon
  • 680
  • 1
  • 8
  • 23
  • The return value of `os.system()` is the exit status of the program. `0` means that the program terminated without an error. Why do you think that it's a problem if it returns 0? – Barmar Jun 09 '22 at 23:47
  • I don't. The problem is that when the cgi calls `os.system('twopi -V')`, it doesn't also return `twopi - graphviz version 4.0.0 (20220529.0937)` – jjon Jun 10 '22 at 00:08
  • you would have to run one of the functions in module `subprocess` to catch displayed text `twopi - graphviz version 4.0.0 (20220529.0937)` – furas Jun 10 '22 at 00:42
  • when you run `os.system()` then it runs system shell which runs program and shell displays its result - not Python. Python displays only exit code - `0`. – furas Jun 10 '22 at 00:45
  • see ie, `subprocess,run()` or [subprocess,check_output()](https://docs.python.org/3/library/subprocess.html#subprocess.check_output). It runs program and it can catch text displayed in shell. And when you get this text then you can use `print()` to display it on page. – furas Jun 10 '22 at 00:54
  • Thanks @furas, that's very helpful. What worked under python3 was `subprocess.getoutput('twopi -V')` but I still haven't found a way to get a python2 cgi script, called via http, to report the shell's reply to `subprocess.run` or `subprocess.check_output`. All it ever gives me is the exit status. – jjon Jun 11 '22 at 19:48
  • I have no idea what you try to do and why you use Python 2 for this. You should use only Pyhton 3. – furas Jun 11 '22 at 23:03
  • Agreed. I’m trying to refactor an existing web app that works with a python2 cgi script, so I’m trying to get that script to report to me some facts about the environment it’s working in, ie. what version of graphviz/twopi it is accessing. – jjon Jun 12 '22 at 00:10

1 Answers1

0

In case anyone is similarly confused about subprocess:

Thanks to the observations of @furas and a great deal of messing about with subprocess I finally figured out an incantation that would compel my python2.7 cgi script to give me the shell output of the command twopi -V. A comment from @tripleee in this thread was the key. For Python 3.7.9 and up: "capture_output is a shorthand for the option combination stdout=supprocess.PIPE, stderr=subprocess.PIPE

p = subprocess.Popen(['twopi', '-V'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
print("stderr:  " + p.stderr.read())
print("stdout:  " + p.stdout.read())
# with the result:
stderr:  twopi - graphviz version 4.0.0 (20220529.0937)
stdout:  

The actual shell output was going to stderr. The subprocess module is byzantine! It's a little better under python3, but not much.

jjon
  • 680
  • 1
  • 8
  • 23