I have a web server (apache2) set up to execute files with a .cgi file extension. This works for some commands. However, I need it to copy the file /var/www/on.html to the location of /var/www/a1.html.
I am using Debian Linux. The script is as follows:
#!/bin/bash echo "Content-type: text/html" echo "<html><head><title>Light on" echo "</title>" echo "<meta http-equiv='refresh' content='1; url=http://86.11.221.243' />" echo "</head><body>" echo "$(gpio mode 8 out) #this turns the light on" echo "$(cp /var/www/on.html /var/www/a1.html)" echo "</body></html>"
I am using cp to copy a html webpage with a green background to replace a file which has a black background. This is used to indicate the status of the LED a1 (column a row 1).
Advertisement
Answer
echo "$(cp /var/www/on.html /var/www/a1.html)"
The $(
… )
is running the command inside the parenthesis and is replaced by the output (to stdout) of that command. A successful cp
does not have any output. A failing cp
is giving an error message to stderr, not stdout. In both cases the effect is that of echo ""
(outputs an empty line, i.e. a single newline), with perhaps an additional side effect of copying the file. And that copy is run as the www-data
user (the one running your web server) …. so would fail if /var/www/
is not writable by it (on my system /var/www/
is owned by root:root
and is not world writable, so www-data
cannot write in it).
So, no need to have echo
on that particular cp
line. You could replace it with cp /var/www/on.html /var/www/a1.html ; logger cp got $?
(but using cp
is not very good, see below)
BTW, the cp
is not an atomic operation. What would happen if two such CGI processes are running concurrently is not exactly defined. Perhaps you want to force a hard link with ln -f
(that is an atomic operation) instead of cp
You could make /var/www/
owned by www-data
, or world-writable. In both cases, that is a security hole (which you might afford on a dedicated internal webserver, accessible only from your home network). If you can afford replacing /var/www/on.html
and /var/www/a1.html
by /var/www/mydir/on.html
and /var/www/mydir/a1.html
(so change the HTML code refering to them) you could simply have a /var/www/mydir/
directory owned and/or writable by www-data
You could wrap your shell script in a setuid executable (e.g. code a small C program which would execve(2) your script) and chmod u+srx
the compiled executable.
You might add (at least to ease debug) some logger(1) command to your script (and/or some syslog(3) to your C program wrapping it), then look into messages under /var/log/
BTW, on a Rasberry Pi, you might replace your apache web server with a dedicated C program (e.g. using some HTTP server library like libonion)
Consider perhaps also AJAX techniques (perhaps combined with websockets) on the browser side.