简体   繁体   English

与手动执行相比,通过PhP执行bash脚本可得到不同的结果

[英]Executing bash script via PhP gives a different result compared to executing manually

As the title says, when i try manually executing the script by double clicking and pressing execute through terminal. 如标题所述,当我尝试通过双击并通过终端按执行来手动执行脚本时。 It works correctly 它正常工作

However when i run my php script or typing the php into the terminal window 但是,当我运行我的PHP脚本或在终端窗口中输入php时

/usr/bin/php start_cam.php

It locks up (the command doesn't finish with the "$", "$" does not show in terminal window to show it has ended the task and it doesn't work correctly 它锁定(命令未以“ $”结尾,“ $”未显示在终端窗口中以表明其已结束任务且无法正常工作

Below is my php script 下面是我的PHP脚本

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

?>

Below is my bash script(cmd_start_cam.sh) 以下是我的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' 

Note: I use cd to ensure that im at my root directory as there where the files are. 注意:我使用cd来确保im在我的根目录中以及文件所在的位置。 As its working via manual execution, do not think there a path issue? 由于它是通过手动执行工作的,因此不认为存在路径问题吗? Any help is greatly appreciated. 任何帮助是极大的赞赏。 thank you 谢谢

Update: this is the error im experiencing output by the terminal command window: 更新:这是终端命令窗口出现输出错误:

i think i am experiencing a broken pipe as after my bash script command echo 'complete start camera script' 我认为我的bash脚本命令echo 'complete start camera script'后遇到管道破裂echo 'complete start camera script'

terminal window output cmd_start_cam.sh: line 12: echo: write error: Broken Pipe and doesn't end with a $ like it should on normal execution 终端窗口输出cmd_start_cam.sh: line 12: echo: write error: Broken Pipe ,并且没有以正常执行时的$结尾

By the way this is running on raspberry pi 2 顺便说一下,这是在树莓派2上运行

Update Solved/Solution: 更新解决方案/解决方案:

Thanks to @ikra insight on checking the apache log file, which lead me to discover that the root cause was permission access. 感谢@ikra对检查apache日志文件的见解,这使我发现了根本原因是权限访问。 www-data needs to be added to the sudoers file. www-data需要添加到sudoers文件中。

  1. Instructions on backing up and editing sudoers file : http://raspbypi.com/enabling-the-sudo-command-for-a-new-user/ 有关备份和编辑sudoers文件的说明: http : //raspbypi.com/enabling-the-sudo-command-for-a-new-user/
  2. sudo visudo 苏多维苏多
  3. add this at the end of the file www-data ALL=(ALL) NOPASSWD: ALL 将其添加到文件www-data ALL的末尾ALL =(ALL)NOPASSWD:ALL
  4. Press CTRL+X and press yes 按CTRL + X,然后按yes
  5. login and logout to ensure permission is now set. 登录和注销以确保现在已设置权限。
  6. If your sudoer file gets corrupted: type this in terminal window to fix whatever text you have typed wrongly pkexec visudo .(Source: https://askubuntu.com/questions/73864/how-to-modify-a-invalid-etc-sudoers-file-it-throws-out-an-error-and-not-allowi ) 如果您的sudoer文件损坏:请在终端窗口中键入此命令以修复错误输入的任何文本pkexec visudo 。(来源: https : pkexec visudo sudoers文件将其抛出错误而不是不允许

Thanks to @ikra insight on checking the apache log file, which lead me to discover that the root cause was permission access. 感谢@ikra对检查apache日志文件的见解,这使我发现了根本原因是权限访问。 www-data needs to be added to the sudoers file. www-data需要添加到sudoers文件中。

  1. Instructions on backing up and editing sudoers file : http://raspbypi.com/enabling-the-sudo-command-for-a-new-user/ 有关备份和编辑sudoers文件的说明: http : //raspbypi.com/enabling-the-sudo-command-for-a-new-user/
  2. sudo visudo 苏多维苏多
  3. add this at the end of the file www-data ALL=(ALL) NOPASSWD: ALL 将其添加到文件www-data ALL的末尾ALL =(ALL)NOPASSWD:ALL
  4. Press CTRL+X and press yes 按CTRL + X,然后按yes
  5. login and logout to ensure permission is now set. 登录和注销以确保现在已设置权限。
  6. If your sudoer file gets corrupted: type this in terminal window to fix whatever text you have typed wrongly pkexec visudo .(Source: https://askubuntu.com/questions/73864/how-to-modify-a-invalid-etc-sudoers-file-it-throws-out-an-error-and-not-allowi ) 如果您的sudoer文件损坏:请在终端窗口中键入此命令以修复错误输入的任何文本pkexec visudo 。(来源: https : pkexec visudo sudoers文件将其抛出错误而不是不允许

I recently published a project that allows PHP to obtain and interact with a real Bash shell (as root if requested), it solves the limitations of exec() and shell_exec(). 我最近发布了一个项目,该项目允许PHP获取和与真实的Bash shell(如果需要,请作为根)进行交互,它解决了exec()和shell_exec()的局限性。 Get it here: https://github.com/merlinthemagic/MTS 在这里获取它: https : //github.com/merlinthemagic/MTS

After downloading you would simply use the following code: 下载后,您只需使用以下代码:

$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;

You can maintain the bash script and simply trigger it like my example. 您可以维护bash脚本并像我的示例一样简单地触发它。 However seeing the script is just a bunch of bash command, why not trigger them directly into the shell, that way you can handle the return and any exceptions. 但是,看到脚本只是一堆bash命令,为什么不直接将它们触发到shell中,那样您就可以处理return和任何异常。

In terms of security this is far better than running apache as root or the wide open sudo permissions you list in your solution update. 在安全性方面,这比以root用户身份运行apache或您在解决方案更新中列出的sudo广泛开放权限要好得多。 But letting PHP anywhere near root is always tricky. 但是让PHP靠近root总是很棘手。

The project i built achieves a root bash shell in one of 2 ways: 我构建的项目通过以下两种方式之一实现了root bash shell:

1) You allow apache the right to sudo python. 1)您允许apache拥有sudo python的权利。

OR 要么

2) You pass root credentials to the object every time you need a shell with root setup. 2)每次需要带有root设置的shell时,都将root凭据传递给对象。

Pick your poison. 选择你的毒药。 :) Read the documentation. :)阅读文档。

You should either check: 您应该检查:

  • SUID your shell-scripts, which are run with sudo SUID您的shell脚本(使用sudo运行)
  • and make sure everything is OK with current directory (and PATH ) for your PHP script. 并确保您的PHP脚本的当前目录(和PATH )都正常。

Try to use your script with php-cli and put this line at the beginning to see what is happening. 尝试将您的脚本与php-cli一起使用,并将此行放在开头,以了解发生了什么。

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

Do

chmod 700 myscript.php

and run it this way 并以这种方式运行

$ ./myscript.php

If you want to run it under your apache server, just insert this function after the opening php tag: 如果要在apache服务器下运行它,只需在打开php标签后插入此函数:

error_reporting(E_ALL);

will do the same. 会做同样的。

To pass your password to the sudo command, use sudo -S *command* < <(echo -e "*pass*\\n") in your script shell. 要将密码传递给sudo命令,请在脚本外壳程序中使用sudo -S *command* < <(echo -e "*pass*\\n") However, that is a bad idea, because everyone who can access your script can get your password. 但是,这不是一个好主意,因为可以访问您的脚本的每个人都可以获取您的密码。

I guess your script starts your camera, if sudo ./RPi_Cam_Web_Interface_Installer.sh start is a stream resource, then the issue is that shell_exec(./myscript.sh) has a limited buffer value, thus it can't handle the response of your script shell. 我猜你的脚本启动了相机,如果sudo ./RPi_Cam_Web_Interface_Installer.sh start是流资源,那么问题是shell_exec(./myscript.sh)的缓冲区值有限,因此它无法处理您的响应脚本外壳。

Try to use popen() instead of shell_exec() 尝试使用popen()而不是shell_exec()

I found an interesting link, which addresses an issue that is somewhat similar to yours https://stackoverflow.com/a/20109859/5280812 我找到了一个有趣的链接,该链接解决的问题与您的https://stackoverflow.com/a/20109859/5280812有点相似

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM