正如一些评论者所建议的,您可以使用 Apache cgi 功能来直接执行您的 test.sh 文件(1),但既然你说你正在使用支持 Php 的 Apache 服务器,那么你有一个替代的、更简单的 Php 选项,你已经部分尝试过(2)。在这两种情况下,您都需要注意 bash 脚本的权限和所有权及其执行环境,以使其产生与命令行相同的结果(3).
1. CGI
CGI 代表通用网关接口。它允许 Web 服务器执行可在主机上执行的程序,并与 Web 服务器交互。那是一个协议per se,而CGI不仅可以用来execute程序,还用于创建动态站点。您可以用任何语言编写动态网站,前提是可执行文件被编程为通过标准输入从服务器接收数据并解释标头,正确解码任何内容,并且程序可以通过标准输出将正确的动态数据返回到服务器,并使用适当的方法。标题、内容类型等
许多语言都有帮助完成此任务的库(对于 C,Perl 在核心模块等中有一个 CGI 模块,甚至对于Bash http://bashlib.sourceforge.net/).
在 Linux 上,要将 CGI 与 Apache 2 一起使用,您需要确保您的 Apache 配置加载支持它所需的模块,并选择允许您的 Web 服务器执行程序的目录:
# uncomment or add the directive for the module
LoadModule cgid_module modules/mod_cgid.so
# one way to allow the server to execute cgi programs is to
# set a ScriptAlias directive to a directory dedicated to CGI programs
ScriptAlias "/cgi-bin/" "/var/www/html/cgi-bin/"
你把你的test.sh
脚本在/var/www/html/cgi-bin/
,并且浏览器可以指向http://localhost/cgi-bin/test.sh
直接执行脚本。还有其他可能的配置,请参阅此Apache CGI 教程 http://httpd.apache.org/docs/current/en/howto/cgi.html.
如果您需要执行 Bash 程序并希望 CGI 向浏览器发送任何内容,则 Bash 脚本发送的第一个回显应为以下输出:
Content-type: text/html
接下来是您想要生成的任何动态 html。
2. Php
实际上,所有这些复杂性可能都没有必要,因为您说您使用支持 Php 的 Apache 服务器,并且您可能不希望 Bash 脚本直接将 html 发送到浏览器。
在这种情况下,shell_exec() http://php.net/manual/en/function.shell-exec.php命令或反引号运算符 http://php.net/manual/en/language.operators.execution.php,将允许您运行 Bash 脚本并在 Php 变量中获取其输出,并在 Php 中对其执行任何您想要执行的操作。
你说你已经尝试过使用exec http://php.net/manual/en/function.exec.php命令,它也应该起作用,除了您得到一个状态代码作为响应,而不是程序输出。
如果您的执行命令根本不起作用,这可能是因为权限、所有权或执行环境问题。
3. 权限、所有权和执行环境
查看您的 Apache 日志,了解由以下各项产生的错误:exec
or shell_exec
命令。
该脚本需要具有执行权限,并且需要能够被Web服务器读取和执行。
例如,在 Debian 上,Apache Web 服务器作为用户 www-data 运行,因此脚本需要由该用户拥有并可执行:
chown www-data:www-data test.sh
chmod u+x test.sh
您可以通过检查(以 root 身份)以下结果来找到 Apache 日志的位置以及 Web 服务器在 Apache 配置文件中运行的用户和组:
apachectl -S
另一个可能的问题是 Apache 运行脚本的环境。该环境可能包含也可能不包含相同的环境变量,$PATH 将有所不同,并且可能不包含“普通”用户在控制台上执行相同脚本时可用的所有目录。
再次检查日志中是否有错误。
最常见的失败原因是未找到 Bash 命令,因为它不在 Apache 进程的 $PATH 中。然后,快速修复方法是更改脚本以使用其完整路径作为命令前缀。
所以,举例来说,如果你的test.sh
使用一个名为validjson
,以可以正确执行脚本的用户身份打开终端,并检查它在哪里:
$ which validjson
validjson: /usr/local/bin/validjson
而不是打电话validjson
在脚本中假设它位于 $PATH 中,则使用其完整路径来调用它/usr/local/bin/validjson
由which命令报告。
如果您正在调用其他脚本或程序,它们可能会遇到相同的问题,请检查该问题,直到调试完脚本的执行为止。