与手动执行相比,通过PhP执行bash脚本会产生不同的结果

时间:2015-09-22 18:19:09

标签: php bash apache shell raspberry-pi

正如标题所说,当我尝试通过双击并通过终端执行来手动执行脚本时。它工作正常

然而,当我运行我的PHP脚本或在终端窗口中输入php

/usr/bin/php start_cam.php

它锁定(命令没有完成" $"," $"没有显示在终端窗口中显示它已结束任务和它没有正常工作

下面是我的php脚本

<?php
        $command =escapeshellcmd("/bin/bash cmd_start_cam.sh");
        $output = shell_exec($command);
        echo $output;
        echo  "php_startcam2";

?>

下面是我的bash脚本(cmd_start_cam.sh)

!/bin/bash

echo 'running start camera script' 
cd
sudo chmod 755 /etc/rc.local
cd 
cd RPi_Cam_Web_Interface 
sudo chmod u+x RPi_Cam_Web_Interface_Installer.sh

sudo ./RPi_Cam_Web_Interface_Installer.sh stop 
sudo ./RPi_Cam_Web_Interface_Installer.sh start
echo 'complete start camera script' 

注意:我使用cd来确保我的根目录下的文件所在的位置。由于它通过手动执行工作,不认为存在路径问题? 任何帮助是极大的赞赏。谢谢

更新:这是终端命令窗口输出的错误:

我认为我在bash脚本命令echo 'complete start camera script'

之后遇到了管道损坏

终端窗口输出cmd_start_cam.sh: line 12: echo: write error: Broken Pipe并且在正常执行时不会像$那样结束

顺便说一下,这是在raspberry pi 2上运行的

  

更新已解决/解决方案:

感谢@ikra洞察检查apache日志文件,这让我发现根本原因是权限访问。需要将www-data添加到sudoers文件中。

  1. 备份和编辑sudoers文件的说明:http://raspbypi.com/enabling-the-sudo-command-for-a-new-user/
  2. sudo visudo
  3. 在文件末尾添加此项www-data ALL =(ALL)NOPASSWD:ALL
  4. 按CTRL + X并按是
  5. 登录并注销以确保现在已设置权限。
  6. 如果您的sudoer文件已损坏:请在终端窗口中输入此内容以修复您错误输入的任何文字pkexec visudo。(来源:https://askubuntu.com/questions/73864/how-to-modify-a-invalid-etc-sudoers-file-it-throws-out-an-error-and-not-allowi

4 个答案:

答案 0 :(得分:1)

感谢@ikra洞察检查apache日志文件,这让我发现根本原因是权限访问。需要将www-data添加到sudoers文件中。

  1. 备份和编辑sudoers文件的说明:http://raspbypi.com/enabling-the-sudo-command-for-a-new-user/
  2. sudo visudo
  3. 在文件末尾添加此项www-data ALL =(ALL)NOPASSWD:ALL
  4. 按CTRL + X并按是
  5. 登录并注销以确保现在已设置权限。
  6. 如果您的sudoer文件已损坏:请在终端窗口中输入此内容以修复您错误输入的任何文字for f in "/a/given/path"/*.bam;do echo $(basename "$(dirname "$f")")/$(basename "$f" .bam);done 。(来源:https://askubuntu.com/questions/73864/how-to-modify-a-invalid-etc-sudoers-file-it-throws-out-an-error-and-not-allowi

答案 1 :(得分:1)

我最近发布了一个项目,允许PHP获取真正的Bash shell并与之交互(如果需要,可以作为root),它解决了exec()和shell_exec()的限制。在此处获取:https://github.com/merlinthemagic/MTS

下载后,您只需使用以下代码:

$shell    = \MTS\Factories::getDevices()->getLocalHost()->getShell('bash', true);
$return1  = $shell->exeCmd('php start_cam.php');
//the return will be a string containing the return of the command
echo $return1;

您可以维护bash脚本并像我的示例一样触发它。但是看到脚本只是一堆bash命令,为什么不直接将它们触发到shell中,这样就可以处理返回和任何异常。

就安全性而言,这比以root身份运行apache或在解决方案更新中列出的开放式sudo权限要好得多。但让PHP靠近root,总是很棘手。

我构建的项目以两种方式之一实现了root bash shell:

1)你允许apache权限sudo python。

OR

2)每次需要具有root设置的shell时,都会将根凭据传递给对象。

选择你的毒药。 :)阅读文档。

答案 2 :(得分:0)

您应该检查:

  • SUID您的shell脚本,使用sudo
  • 运行
  • 并确保PHP脚本的当前目录(和PATH)一切正常。

答案 3 :(得分:0)

尝试将您的脚本与php-cli一起使用,并将此行放在开头,看看发生了什么。

#!/usr/bin/php -ddisplay_errors=E_ALL

chmod 700 myscript.php

以这种方式运行

$ ./myscript.php

如果你想在apache服务器下运行它,只需在打开php标签后插入这个函数:

error_reporting(E_ALL);

也会这样做。

要将密码传递给sudo命令,请在脚本shell中使用sudo -S *command* < <(echo -e "*pass*\n")。但是,这是一个坏主意,因为每个可以访问您脚本的人都可以获得您的密码。

我猜你的脚本会启动你的摄像头,如果sudo ./RPi_Cam_Web_Interface_Installer.sh start是一个流资源,那么问题是shell_exec(./myscript.sh)的缓冲区值有限,因此它无法处理脚本shell的响应

尝试使用popen()代替shell_exec()

我发现了一个有趣的链接,它解决了与您https://stackoverflow.com/a/20109859/5280812

有些相似的问题