I am trying to run a local CGI server on my raspberry pi to host a webpage with a single link, that link is to a CGI script which is supposed to trigger another script and then print HTML code to redirect back to the starting page (so that it doesn't hang)
in the servers root directory i have:
index.html
favicon.ico
Server.py
cgi-bin
my server is set up to use the cgi-bin folder for cgi-scripts.
the issue i am having is i cannot seem to make the scripts callable, is so instead of typing "python Server.py" i should be able to type "Server.py"
in order to do this i have tried multiple shebangs:
#!/usr/bin/env python
#!/usr/bin/python
and then called chmod a+x Server.py to mark it as executable, to no avail.
to clarify i am using:
python 2.7.3rc2
standard raspi linux distro "wheezy"
i read in some of the help docs that if the file has DOS style newlines it interferes with the shebang, so i have ensured that they are now MAC style newlines, this still did not work.
to test further i have made a simple python file which contains:
#!/usr/bin/python
print "Hello World!"
saved it as test.py, marked it as executable, and tried:
/test.py
from the command line and i get:
print: bad interpreter: No such file or directory
can someone please tell me where i'm going wrong?
Thanks
James
Try to remove windows line endings in the script. This made it work for me.
E.g. see How to convert Windows end of line in Unix end of line (CR/LF to LF)
For more possible causes of this problem have look at my answer here https://stackoverflow.com/a/65249192/1150303
Related
I'm going through the "Linux Fundamentals" section on TryHackMe, and I was asked to start a web server using Python's "HTTPServer" module and download a file from said server. My first line of code was python3 -m http.server to initiate the server, then in the Linux terminal all I had was a blank line, no directory or prompt or anything. I input wget http://ip.address:port/filename with the correct IP address, port, and filename but nothing ran. It took me opening another terminal window in order to download the file, is this correct or have I missed something? This is my first introduction to Linux so I apologise if I've missed something simple.
Trying to run python cgi server from within Eclipse on a Mac Air and display hello world in Firefox, two problems. Here is the code to be run in a file run_server.py
from http.server import HTTPServer
from http.server import CGIHTTPRequestHandler
def run_server(handler_class,server_class=HTTPServer ):
server_address = ('', 8000)
httpd = server_class(server_address, handler_class)
httpd.serve_forever()
def main():
run_server(CGIHTTPRequestHandler)
if __name__ == '__main__':
main()
Directory structure under project directory
analytics
\
run_server.py
cgi-bin
\
index.py
index.py
#!/usr/bin/env python
print('Content-type: text/html;\n\n')
print('<h1>Hello, world!</h1>')
From a command line in the project directory, you can run with
$ python -m analytics.run_server
Be sure to have a __init__.py in the analytics directory to use -m option. Now try loading the page
http://localhost:8000/cgi-bin/index.py
In Chrome, things work. So what's the problem?
In Firefox, the url is never found.
On a Mac also, if you run the server from inside the Eclipse IDE, the cgi tries to run python 3 code with OS installed python 2
Firefox 404s, times out, presents a blank page, or if the url problem is solved, tries to save the file. It doesn't serve static content as well, when the url problem exists.
The Eclipse console in running the cgi, will display the stack trace of a syntax error from the python lib site.py print statement, tipping off the nature of the problem. See What's New in Python 3
Old: print >>sys.stderr, "fatal error"
New: print("fatal error", file=sys.stderr)
Simple solutions to both follow, in the answer section below.
Add to or create file /etc/localhosts , as in sudo vi /etc/localhosts, or editor of your choice.
127.0.0.1 localhost
This fixes a known bug (link below) from two years ago, closed two months ago as a duplicate, and contains the above workaround, very near the bottom.
https://bugzilla.mozilla.org/show_bug.cgi?id=1433933
There is an active bug opened 5 years ago, updated 6 days ago, April 10, 2020, looks very near completion. https://bugzilla.mozilla.org/show_bug.cgi?id=1220810 Whenever it's done, you'll still have to update Firefox.
For the conflict of python versions, running the server from the command line presents no problem in executing the cgi, index.py However, trying to run the server inside Eclipse doesn't work, when the shebang path #! (etymology sharp bang, or shell bang) is
#!/usr/bin/env python
On a Mac, it picks up the default python 2 installation, but is trying to run python 3 code (assuming you've upgraded since python 2 is past end of life). Apple, despite OS updates has kept python 2 around for backwards compatability, though it's days are numbered. Eventually the OS and applications will no longer rely on any OS installed python.
Not sure of exact mechanism where Eclipse picks up python 2 when server runs script, though interpreter is 3. Setting path to #!/usr/bin/env python3 doesn't work, nor does #!/usr/bin/python3. What does? Find the absolute path to your python 3 and use that, it should appear in the error stack trace even, but here is an exampe from my setup.
#!/Library/Frameworks/Python.framework/Versions/3.6/bin/python3
I setup Ubuntu server 18.04 LTS, LAMP, and mod_mono (which appears to be working fine alongside PHP now by the way.) Got python working too; at first it gave an HTTP "Internal Server Error" message. sudo chmod +x myfile.py fixed this error and the code python generates is displayed fine. But any time the execute permission is removed from the file (such as by uploading a new version of the file), the execute bit is stripped and it breaks again.
A work-around was implemented with incrontab, where the cgi-bin folder was monitored for changes and any new writes caused chmod +x %f to be ran on them. This worked for awhile, then stopped, and seems a hokey solution at best. Perl, PHP, even ASPX do not need to be marked executable - only python.
Is there any way Apache can "run" python without the file marked as executable?
The reason PHP works, is because the interpreter is loaded into Apache. So Apache interprets the code.
For your Python, it runs as a CGI, so the interpreter is outside of Apache.
In your Python script, you probably have a #!/usr/bin/python first line (or something similar). This tells the script to run using this interpreter. This requires executable permission on the .py file, and allows you to call myfile.py directectly.
Instead run it like this: /usr/bin/python myfile.py. This way the interpreter is the executable, and it will run myfile.py as the code.
Examples
You want to run the py file "alone":
file.py
#!/usr/bin/python
print("Hello")
Running it:
./file.py
You want to run it via the python executable, like you want via Apache:
file.py
print("Hello")
Running it:
/usr/bin/python file.py
I don't think Apache is capable of serving executed python scripts without the execute bit set on the .py file.
But here is a work-around: simply leave that file marked executable, but import a second python file. That second file does not need to be marked executable.
myfile.py (marked as executable and read-only - use this with apache):
#!/usr/bin/python3
# enable debugging
# helper to run the other, non-executable file
# do not add .py to the import "filename"
import myfile2
myfile2.py (marked RW only, edit this file freely):
# this is the code which can change frequently
# and does not need to be marked executable...
print("Content-type: text/html\n\n")
print("<html><head><title>Python</title></head>")
print("<body>Hello, World!</body></html>")
I am trying to use a CGI script written in Python to execute a bash script, however it only works correctly when I run the script python manually. When I run via Browser, the CGI execution returns 200, however the bash script does not run.
Here's an example of what I'm trying to do, but using two simple scripts just to explain, okay?
The cgi script was created in the following apache directory and is accessible without problems:
/var/www/cgi-bin/raf_teste.cgi
Below is the content of the raf_teste.cgi script:
#!/usr/bin/python3.5
import subprocess
import cgi, cgitb
cgitb.enable()
print ("Content-type:text/html\r\n\r\n")
command = ['./raf.sh']
subprocess.Popen(command)
Within the same directory "/var/www/cgi-bin/" a BashScript named raf.sh was created:
/var/www/cgi-bin/raf.sh
Below is the content of the raf.sh script:
#!/bin/bash
echo "rafael" > "/tmp/rafael.txt"
Note: In the test I did using the python subprocess module to run linux command, everything worked perfectly, but in this case I am trying to run another script through a python CGI, it is not working and no error message is displayed.
Could you help me please?
Okay, pretty sure I've got it.
The problem is that you ran your script by hand before you ran it on the web.
That caused "/tmp/rafael.txt" to be created, owned by your user. Now, no other user (including the web server user) can write to that file because the file already exists, owned by you, and that's how /tmp works.
The solution is easy: delete "/tmp/rafael.txt". Then I bet your script works.
This question already has answers here:
Why do people write #!/usr/bin/env python on the first line of a Python script?
(22 answers)
Closed 8 years ago.
http://www.tutorialspoint.com/python/python_cgi_programming.htm
#!/usr/bin/python
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 '</body>'
print '</html>'
What is the significance of #!/usr/bin/python
It says to save file as hello.py and save it to /var/www/cgi-bin directory but I don't have this directory, should I create one?
Before running your CGI program, make sure you have change mode of file using chmod 755 hello.py UNIX command to make file executable.
but where to (how to) execute this chmod command? should I include $chmod 755 "/location of hello(.py).../" in hello.py?
You have to include the #!/usr/bin/python line on *nix systems to tell the shell how to interpret this script and where your interpreter is in the system. This is called the shebang line.
The chmod 755 hello.py command is a unix shell command to change the permissionson of the file and make it executable. Doing this you can run the script without having to do python hello.py but instead ./hello.py .
From my understanding you are a windows user. In this case, you don't have to do all of this. Just save the file as hello.py and that's it.
This post on tutorialspoint.com implies that you already have an HTTP server running that supports cgi and has a default web directory of /var/www/
The line #!/usr/bin/python is a signal to the shell (the program that handles your keyboard input and runs commands for you) that this file is a script that can be handled by the program shown. It's called a 'shebang' or sometime 'hashbang'.
In this case the shebang tells your shel to run the program it finds at /usr/bin/python and submit this script to it. There's more here
chmod is a general command for setting permissions on files. You execute it from the command line like any other command. The numerical values for the permissions can be a bit cryptic, but they're made up of binary bits that indicate certain permissions. Changing a permission to 755 specifically indicates that the owner of the file can execute this as a program, rather than just treating it as a block of text. Personally I prefer the mor descriptive chmod u+x filename - add execute for the user.
You can find a fuller description of chmod here