【问题标题】:Running script through shell_exec not giving the same output is when running on the server通过 shell_exec 运行脚本没有给出相同的输出是在服务器上运行时
【发布时间】:2015-07-29 03:05:35
【问题描述】:

我在 PHP 中使用 shell_exec 运行脚本时遇到了问题。 当我登录到服务器并运行脚本时,我得到了正确的输出,但是当我通过网页运行它时,它似乎没有完成命令。

该脚本是使用 openssl 从 .crt 和 .key 文件创建 .pem、.pfx 和 .p12 文件。

Bash 脚本如下:

#!/bin/bash
#Script to create all the SSL certs needed from the .key and .crt files

set -o errexit

echo "Starting script....<br><br>"
echo "openssl pkcs12 -export -in $1.crt -inkey $1.key -out $1.p12 -passout pass:$2"
openssl pkcs12 -export -in $1.crt -inkey $1.key -out $1.p12 -passout pass:$2
echo "P12 Complete.<br><br>"
openssl pkcs12 -in $1.p12 -nodes -out $1.pem -passin pass:$2 -passout pass:$2
echo "PEM Complete.<br><br>"
openssl pkcs12 -inkey $1.pem -in $1.crt -export -out $1.pfx -passout pass:$2
echo "PFX complete.<br><br>"
mkdir $1_certs
mv $1.key $1_certs/$1.key
mv $1.crt $1_certs/$1.crt
mv $1.pem $1_certs/$1.pem
mv $1.p12 $1_certs/$1.p12
mv $1.pfx $1_certs/$1.pfx
echo "Password: " $2 >> $1_certs/password.txt
echo "ZIPing files.<br><br>"
zip $1_certs.zip $1_certs
echo "COMPLETE<br><br>"

PHP 如下:

<?php
if (isset($_GET['cert_name'])) {
$cert_name = $_GET['cert_name'];
$password = $_GET['password'];
echo "/home/<username>/ssl $cert_name $password <br><br>";
$message=shell_exec("/home/<username>/ssl $cert_name $password");
echo $message;
}
?>

两者中大量的回声有助于排除故障。

网页是一个带有 2 个输入和一个提交按钮的基本表格。

当我在网页中运行它时,它会使用 openssl 命令创建 .p12 并失败。

如果我删除set -o errexit 以便它完全运行而不管错误我可以看到它甚至没有尝试创建目录或移动文件,我只是看到所有的回声。就好像它只是运行回声并忽略命令。

我在创建 p12 文件的命令之前有一个回显,它表明它正在获取所有正确的详细信息。

我不知道从这里去哪里。任何帮助,将不胜感激。

【问题讨论】:

  • 这听起来像是权限问题。当你从 shell 运行它时,它会像你自己一样运行。当网络服务器运行它时,它以网络服务器的用户身份运行。

标签: php bash shell-exec


【解决方案1】:

来自shell_exec的手册

返回值

执行命令的输出或NULL(如果发生错误或命令不产生输出)。

注意:

当发生错误或程序没有输出时,此函数可以返回NULL。使用此功能无法检测执行失败。当需要访问程序退出代码时,应使用 exec()。

在调试中,echoprint/print_r 变体不是很有帮助,因为它们将 null 类型转换为字符串。相反,您可以使用var_dump,它保证每个输入的输出,即使它是null


为什么它失败了,有一种方法可以通过将STDERR 重定向到STDOUT 来从STDERR 取回任何信息。

$message = shell_exec("/home/<username>/ssl $cert_name $password 2>&1");

还需要注意的是,您应该转义通过 escapeshellarg 传递给 shell 的任何参数

如果我不得不猜测它失败的原因,我最好的猜测是无论 PHP 是在哪个用户下运行(例如,如果你通过你的 Web 服务器执行此操作,并且使用带有 mod_php 的 Apache httpd,它可能不会'没有必要的权限来执行/home/&lt;username&gt;/ssl。您应该能够通过检查文件的权限并从shell返回STDERR信息确认来确定这一点。

【讨论】:

  • 感谢您的帮助,使用 var_dump2&gt;$1 使我能够看到实际的错误消息。 string(115) "Error opening input file testing_ssl.crt testing_ssl.crt: No such file or directory unable to write 'random state' " 现在来解决这个问题。
  • 您应该使用这些文件的绝对路径,因为相对路径可能无法从网络上下文中确定。
猜你喜欢
  • 1970-01-01
  • 2014-05-25
  • 1970-01-01
  • 1970-01-01
  • 2017-05-16
  • 1970-01-01
  • 2014-05-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多