Running system calls from webserver

2019-09-02 06:53发布

问题:

I am trying to run a standard python os.system call from a cgi python script. This is part of a tutorial so the script is quite simple. I am trying to take a picture with the Raspberry Pi camera and display it in a webpage.

import os, sys

os.system('raspistill -o /var/www/images/image.jpg')

print "Content-type:text/html\r\n\r\n"
print '<html>'
print '<head>'
print '<title>Hello Word - First CGI Program</title>'
print '</head>'
print '<body>'
print '<h2>Hello Word! This is my first CGI program</h2>'
print '<img src="/var/www/images/image.jpg"/>'
print '</body>'
print '</html>'

The error I get when running the system command (opening in a browser) is:
* failed to open vchiq instance"

I have seen another question on this and it said something about the http deamon running as the wrong user, but I am not sure what that meant. The scripts runs fine when I am running it as the standard user.

回答1:

I fixed it.

The web server had access to the raspistill command, but that command used a video device that it did not have access to. I added the www-data user to the video and the audio group so I could both play audio and take pictures. I also had to change some groups for some folders in my web-directory. The last thing I had to fix was that the os.system() call returned something and that gave the browser some problems with displaying the webpage. It only displayed text. I now use the subprocess module and the initial code seems to work. My simple test code is here:

import os, sys

import subprocess

#output = subprocess.check_output("raspistill -o /var/www/images/image.jpg",     shell=True)
#os.system('raspistill -v -o /var/www/images/image.jpg')

# Import modules for CGI handling
import cgi, cgitb

# Create instance of FieldStorage
form = cgi.FieldStorage()

output = ""
output2 = ""
# Get data from fields
if form.getvalue('speak_en'):
   output = subprocess.check_output("espeak \"%s\"" % (form.getvalue('speak')), shell=True)

if form.getvalue('picture'):
   output2 = subprocess.check_output("raspistill -o /var/www/images/image.jpg", shell=True)


print """\
Content-type:text/html\n
<html>
<head>
<title>Hello Word - First CGI Program</title>
</head>
<body>
<h2>Select photo or speak</h2>
<form action=\"/cgi-bin/hello.py\" method=\"post\">
<input type=\"checkbox\" name=\"speak_en\" value=\"on\" />
Speak: <input type=\"text\" name=\"speak\"><br />
Take picture:
<input type=\"checkbox\" name=\"picture\" value=\"on\" />
<br />
<input type=\"submit\" value=\"Submit\" />
</form>
<img src=\"../images/image.jpg\" width=640 height=480>
<p>Speak output: %s</p>
<p>Picture output: %s</p>
</body>
</html>
""" % (output, output2)


回答2:

Most web servers run with a user for the webserver. Apache2 runs as www-data, for instance. All files in the computer have ownership and permission data for them that would allow or disallow certain operations from different users - for instance only the superuser (root) can run the poweroff application to turn off the computer.

What you should do is locate the executable you're trying to run which raspistill. This will return the location of the executable file. Next you should check the file permissions using ls -l `which raspistill` and see the owner data and file permissions which are displayed as -rwxr-xr-- (This is a common permission set, yours might vary). The 1st 3 represent Read-Write-eXecute permissions for the file owner, the next 3 chars represent only Read and eXecute permissions for the user group and the last 3 chars represent only Read permissions for the "other" users.

If the owner of the file is not www-data you could do several things such as change the ownership information for the file using chown <user> <file> which I don't recommend or adding execution privileges to the "other" user set with chmod o+x `which raspistill`.

If the problem is indeed with the permissions - this should solve your problem.

Additional information:

http://www.computerhope.com/unix/uchmod.htm

http://www.ss64.com/bash/chmod.html