问题
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
来源:https://stackoverflow.com/questions/19331969/running-system-calls-from-webserver