2015-02-11 190 views
5

我有一台运行在Linux上的服务器,它执行12个节点(12台运行Linux的计算机)的命令。我最近在服务器上下载了PHP,通过打开特定的PHP文件来创建可以执行命令的网页。在PHP中打开Linux终端命令

我用exec(),passthru(),shell_​exec()system()system()是唯一一个返回我的代码的一部分。我希望PHP在Linux中像开放性的termainal命令一样行事,我无法弄清楚如何做到这一点!

这是现在发生的事情(Linux的直接与PHP)的例子: 当使用直接Linux开放源终端命令:

[email protected]:/home/hyperwall/Desktop> /usr/local/bin/chbg -mt 

我得到的输出:

The following settings will be used: 
    option = mtsu COLOR = IMAGE = imagehereyouknow! 
    NODES = LOCAL 
and additional code to send it to 12 nodes. 

现在用PHP:

switch($_REQUEST['do']) 
{ case 'test': 
    echo system('/usr/local/bin/chbg -mt'); 
    break; 
} 

输出:

The following settings will be used: 
    option = mtsu COLOR = IMAGE = imagehereyouknow! 
    NODES = LOCAL 

并停止!任何人都有解释发生了什么?以及如何解决它?只有系统显示部分代码,其他功能不显示任何内容!

+1

您是否使用过'strace'来确定它卡住了什么?以调试模式运行Web服务器以将其限制为单个进程。 – 2015-02-15 16:59:10

+3

你正在运行哪个Web服务器?在哪个用户的网络服务器上运行?如果它运行在“nobody”或类似环境下,您确定该用户可以执行chbg命令​​吗? – 2015-02-15 17:10:59

+2

什么是“以及将其发送到12个节点的附加代码”。 ??它来自哪里? – Nimrod007 2015-02-15 17:40:00

回答

4

我首先想到的是它可以是关于性病和输出错误。有些软件会转储一些标准错误信息。如果不是将std错误重定向到标准输出,大多数系统调用仅返回标准输出部分。这听起来就是你为什么在终端看到整个输出并且不能在系统调用中看到的原因。通过 也为临时工作,你可以尝试一些其他的东西: 因此,与

/usr/local/bin/chbg -mt 2>&1 

编辑尝试。例如输出重定向旁边的脚本文件,并执行命令后阅读其内容,这样您就可以使用exec:

exec("usr/local/bin/chbg -mt 2>&1 > chbg_out"); 
//Then start reading chbg_out and see is it work 

EDIT2 此外,它没有意义,为什么别人不工作您。 例如,用c编写的这段代码在stderr中转储了一个字符串,并且在stdout中存在其他字符。

#include <stdio.h> 
#include<stdlib.h> 
int main() 
{ 

    fputs("\nerr\nrro\nrrr\n",stderr); 
    fputs("\nou\nuu\nuttt\n",stdout); 
    return 0; 
} 

这个PHP脚本,尝试通过exec来运行:

<?php 

exec("/tmp/ctest",&$result); 

foreach ($result as $v) 
{ 
echo $v; 
} 
#output ouuuuttt 
?> 

看到它仍然转储出的标准输出。但它没有收到stderr。 现在考虑这个:

<?php 

exec("/tmp/ctest 2>&1",&$result); 

foreach ($result as $v) 
{ 
    echo $v; 
} 
//output: errrrorrrouuuuttt 
?> 

看,这一次我们得到了整个输出。

此时系统:

<?php 
    echo system("/tmp/ctest 2>&1"); 
    //output: err rro rrr ou uu uttt uttt 
?> 

等等...

+0

很好的答案,很好的备份与例子。 – 2015-02-21 20:42:22

+0

:)谢谢@scrowler – madz 2015-02-22 08:21:45

2

也许您的chbg -mt将其他代码写入stderr而不是stdout?尝试执行你的脚本PHP内部像这样:

/usr/local/bin/chbg -mt 2>&1 
1

我认为,执行的结果,可以在用户之间变化。 首先,尝试直接运行PHP脚本到你的终端php yourScript.php
如果运行正常,去你的Apache服务和更新它用自己的凭据运行

2

其他的反应是好普通的通知。但在这种特定情况下,您似乎试图在桌面上更改背景。这需要因“用户上下文”有特殊的考虑:

  • 首先,你的Web服务器可能运行作为不同的用户,所以也就没有权限更改您的桌面。

  • 其次,该程序可能需要您的用户环境中的一些环境变量。例如,X程序需要DISPLAY变量,ssh-agent需要SSH_AGENT_PIDSSH_AUTH_SOCK等。我对改变背景知之甚少,但我猜测它涉及D-Bus,可能需要诸如DBUS_SESSION_BUS_ADDRESSKONSOLE_DBUS_SERVICEKONSOLE_DBUS_SESSIONKONSOLE_DBUS_WINDOW。可能还有很多其他的。请注意,这些变量中的一些会在您每次登录时发生变化,因此您无法在PHP端对它们进行硬编码。

对于测试,从用户会话启动自己的Web服务器可能会更简单。 (即不要使用系统,它必须像你一样运行,你需要在备用端口上运行它,比如8080)。您手动启动的Web服务器将拥有所需的所有“上下文”。我会提到websocketd,因为它刚刚出来,看起来很整齐。

对于“生产”,您可能需要始终在用户上下文中运行守护进程,并让Web服务器与该守护进程对话以在用户上下文中“完成任务”。

+0

对我而言,“桌面”问题与假设无关,可能只是示例问题的一部分。真正的问题是关于为什么Linux命令行和PHP执行的Linux命令之间存在不一致。我认为你首先想到的是,一个不同的用户正在使用PHP来运行你通常在Linux控制台中使用的事实,这是最谨慎和重要的一点。为了保持一致性,可能需要运行你的Linux命令,因为运行PHP的用户可以进一步模拟PHP系统调用的行为。 – 2015-02-21 20:48:50

1

您正尝试更改当前登录用户的背景......当他们使用桌面时。就像我输入这条消息一样。我最小化浏览器,'我的桌面背景不同'。希望这是对重要的东西,当反应堆或过热时它会变红。

反正我的回答:

,而不是试图远程连接和运行的项目,如个人用户。设置每个用户在重复定时器上运行bash脚本(在他们自己的帐户中,在他们自己的shell中)。每10分钟说一次。让它从网络位置选择SAME文件.. /somenetworkshare/backgrounds/images/current.png

然后,您可以通过更改/ somenetworkshare/backgrounds中的图像本身来更新所有节点(1到100万) /images/current.png

+0

“许多一次请求”方法的缺点是,你需要引入1到100万次所需的处理时间并以保证的速度降低您的整体性能,而“一对多推动”方法只在需要时降低。 – 2015-02-21 20:44:35

1

前段时间我写了一些东西 - 你可以运行命令解释器(/ bin/sh),发送命令,回读回应,发送更多命令等。使用proc_open()打开一个子进程并与之通话。

这是在http://github.com/andrasq/quicklib,Quick/Proc/Process。PHP

使用它会看起来像(容易,如果你有一个灵活的自动加载;我写的那些太Quicklib之一):

include 'lib/Quick/Proc/Exception.php'; 
include 'lib/Quick/Proc/Exists.php'; 
include 'lib/Quick/Proc/Process.php'; 

$proc = new Quick_Proc_Process("/bin/sh"); 
$proc->putInput("pwd\n"); 
$lines = $proc->getOutputLines($nlines = 10, $timeoutSec = 0.2); 
echo $lines[0]; 
$proc->putInput("date\n"); 
$lines = $proc->getOutputLines(1, 0.2); 
echo $lines[0]; 

输出

/home/andras/quicklib 
Sat Feb 21 01:50:39 EST 2015 

通信之间单元PHP和过程是换行符终止行。所有命令必须以换行符终止,并且所有响应都以行为单位进行检索。不要忘记换行符,事后很难识别。

+0

这是作为你工作的脚本的广告而不是 – 2015-02-21 20:46:01

+0

这个问题的答案,是的,我回答说:“我希望PHP在Linux下像打开termainal命令一样行动”而不滚动阅读其余部分详细。我认为这会有所帮助;没有意识到这不是问题。 – Andras 2015-02-21 21:51:50

2

PHP的system只返回执行的最后一行:

返回值:成功则返回命令输出的最后一行,并FALSE的失败。

您很可能会想要使用execpassthruexec有一个可选参数可将输出放入数组中。你可以将输出内爆并用它来回应它。

switch($_REQUEST['do']) 
{ case 'test': 
    exec('/usr/local/bin/chbg -mt', $output); 
    echo implode('\n', $output); // Could use <br /> if HTML output is desired 
    break; 
} 
0

我正在使用机器A上的终端A输出到机器B上的终端B,现在都使用Linux。我没有看到提到它,但也许你可以在你的网络服务器使用重定向,像这样:

switch($_REQUEST['do']) 
{ case 'test': 
    #process ID on the target (12345, 12346 etc) 
    echo system('/usr/local/bin/chbg -mt > /proc/<processID>/fd/1'); 
    #OR 
    #device file on the target (pts/0,tty0, etc) 
    echo system('/usr/local/bin/chbg -mt > /dev/<TTY-TYPE>/<TTYNUM>'); 
    break; 
} 

绝对需要的权限,这个工作要正确设置。终端中的命令“mesg y”也可以帮助...希望有所帮助。