SSH 似乎无法在通过 Web 服务器调用的 Bash 脚本中运行

SSH 似乎无法在通过 Web 服务器调用的 Bash 脚本中运行

我有一个简单的 shell 脚本:

  1. 在远程机器上创建一个目录。
  2. 将 .epub 文件复制到远程机器的新目录。
  3. 运行 kindlegen 将 .epub 转换为 .mobi。
  4. 远程服务器将新的.mobi 文件复制回原始服务器。

两台服务器都配置了通过公钥进行 SSH 无密码登录。

在命令行运行脚本效果很好。从服务器上使用 PHP shell_exec 命令运行它将执行脚本,但 ssh 和 scp 命令似乎没有执行,或者至少没有输出任何内容,即使我使用 -v 标志。

以下是调用 shell 脚本的 PHP 函数:

function mobi_watermark($userid, $email, $epubpath)
{

    $outpath = "/tmp/epub$userid/"; # the book gets marked for each user, store each epub under a unique work folder to avoid collision
    shell_exec("chmod -R 777 ".$outpath); # web server creates files under user "nobody".
    shell_exec("del.sh"); # deletes old files if they exist
    shell_exec("rep.sh $userid $email $epubpath"); # creates the initial .epub and tmp dir
    shell_exec("chmod -R 777 ".$outpath); 
    shell_exec("kindle.sh $outpath"); # this is the mobi conversion, where the problem is
    $this->mobi_ufa_download('ufa-187.mobi',$outpath);
}

下面是包含失败命令的 shell 脚本:[ kindle.sh ]

#!/usr/local/bin/bash
# uses the same /tmp$userid path as the other scripts, but on the remote server
TMPPATH=$1 
cd $TMPPATH
# create remote dir
ssh -v user@server 'mkdir -v '$TMPPATH
# copy the source epub file to remote
scp -v $TMPPATHfile-name.epub user@server:$TMPPATH
# perform the conversion and copy the .mobi result back to originating server
/usr/bin/ssh -v user@server 'cd '$TMPPATH'; /home/username/kindlegen/kindlegen ./file-name.epub; scp -v file-name.mobi user@originating-server:'$TMPPATH';rm -rf '$TMPPATH 

如果我自己从脚本文件或从命令行以单独的命令运行这一系列命令,那么一切都能完美运行。

当通过 php 脚本运行时,如果我决定回显测试命令,我可以看到脚本输出,如果我破坏源文件名,scp 将报告错误,但如果 scp 或 ssh 命令正确,则不会发生任何事情。 -v 标志甚至没有任何详细的调试输出。

我肯定忽略了一些显而易见的东西?我猜是因为 PHP 使用了 SSH 不喜欢的用户“nobody”。如果这是问题所在,有办法解决这个问题吗?

答案1

您可能想尝试添加

 </dev/null

在有问题的命令的末尾,以防命令以某种方式需要输入。

答案2

私有 ssh 密钥存储在哪里,在您以该用户身份运行命令的 ~/.ssh/id_... 文件中吗?

如果是这样,那么 apache 就不是以您的用户身份运行的。Apache 需要能够访问 ssh 密钥的副本。您还可以将 -i 添加到 ssh 和 scp 命令中,这样它就不必存在于 apache 的主目录中。

答案3

shell_exec() 函数可能会给你一些你忽略的信息,因为你没有收集这些信息。尝试

$info=shell_exec("kindle.sh $outpath");
echo "<pre>$output</pre>";

这就是我开始调试这个问题时要做的事情。

编辑:

将 .ssh 和 id_rsa 的权限设置为 777 会给您带来大麻烦,因为如果权限太宽松,ssh 会拒绝工作。请分别将它们重新设置为 700 和 600。

我不明白为什么你没有看到任何结果,试试

$info=shell_exec("kindle.sh 2>&1 $outpath");
echo "<pre>$output</pre>";

这也应该强制将 stderr 输出到 std out。

答案4

当我在从 httpd 和 php 进程执行外部脚本时遇到麻烦时,我尝试在与 httpd 进程相同的用户下手动运行。

su nobody

很有可能 nobody 用户没有设置 shell,您需要启用 shell 才能su使用它。

相关内容