CGI 脚本不执行 bash 命令,例如 'CP'

CGI script not executing bash commands such as 'CP'

我设置了一个 Web 服务器 (apache2) 来执行文件扩展名为 .cgi 的文件。这适用于某些命令。但是,我需要它将文件 /var/www/on.html 复制到 /var/www/a1.html.

的位置

我正在使用 Debian Linux。脚本如下:

#!/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>"

我正在使用 cp 复制一个绿色背景的 html 网页来替换一个黑色背景的文件。这个用来表示LED a1(列a行1)的状态。

echo "$(cp /var/www/on.html /var/www/a1.html)"

$( ... ) 是 运行 括号内的命令,并被 output 替换(到 stdout) 的那个命令。成功的 cp 没有任何输出。失败的 cpstderr 提供错误消息,而不是 stdout。在这两种情况下,效果都是 echo "" (输出一个空行,即一个换行符),可能还有复制文件的额外副作用。该副本是 运行 作为 www-data 用户(运行 宁你的网络服务器)....如果 /var/www/ 不可写(在我的系统 /var/www/root:root 所有,并且不是世界可写的,所以 www-data 不能写入)。

因此,不需要在特定的 cp 行上添加 echo。您可以将其替换为 cp /var/www/on.html /var/www/a1.html ; logger cp got $?(但使用 cp 不是很好,请参见下文)

顺便说一句,cp 不是原子操作。如果两个这样的 CGI 进程同时 运行ning 会发生什么情况并没有明确定义。也许您想用 ln -f 强制 link ( 原子操作)而不是 cp

您可以让 /var/www/www-data 所有,或者全世界可写。在这两种情况下,这都是一个安全漏洞(您可以在专用的 内部 网络服务器上负担得起,只能从您的家庭网络访问)。如果您负担得起用 /var/www/mydir/on.html/var/www/mydir/a1.html 替换 /var/www/on.html/var/www/a1.html(因此更改引用它们的 HTML 代码),您可以简单地使用 /var/www/mydir/ 拥有的目录 and/or 可由 www-data

写入

您可以将 shell 脚本包装在 setuid executable (e.g. code a small C program which would execve(2) 您的脚本中)和 chmod u+srx 已编译的可执行文件。

您可以将一些 logger(1) command to your script (and/or some syslog(3) 添加到包装它的 C 程序中(至少为了简化调试),然后查看 /var/log/

下的消息

顺便说一句,在 Rasberry Pi 上,您可以用专用的 C 程序替换您的 apache 网络服务器(例如,使用一些像 libonion 这样的 HTTP 服务器库)

也许还可以考虑 AJAX techniques (perhaps combined with websockets) 在浏览器端。