php程序开放';su:必须从终端运行';

php程序开放';su:必须从终端运行';,php,shell,ubuntu-12.04,proc-open,Php,Shell,Ubuntu 12.04,Proc Open,我在个人Ubuntu服务器机器中有以下PHP代码: $cmd = 'su testuser'; $descriptorspec = array( array('pipe', 'r'), array('pipe', 'w'), array('pipe', 'w') ); $pipes = array(); $process = proc_open($cmd, $descriptorspec, $pipes);

我在个人Ubuntu服务器机器中有以下PHP代码:

$cmd = 'su testuser'; $descriptorspec = array( array('pipe', 'r'), array('pipe', 'w'), array('pipe', 'w') ); $pipes = array(); $process = proc_open($cmd, $descriptorspec, $pipes); fwrite($pipes[0], 'password\r'); fclose($pipes[0]); $string = array(stream_get_contents($pipes[1]), stream_get_contents($pipes[2])); proc_close($process); echo exec('whoami') . "\n"; print_r($string); $cmd='sutestuser'; $descriptorspec=数组( 数组('pipe','r'), 数组('pipe','w'), 数组('pipe','w') ); $pipes=array(); $process=proc_open($cmd,$descriptorspec,$pipes); fwrite($pipes[0],'password\r'); fclose($pipes[0]); $string=array(stream\u get\u contents($pipes[1]),stream\u get\u contents($pipes[2]); 过程结束($过程); echo exec(“whoami”)。“\n”; 打印(字符串); 我从PHP得到这样的回答:

www-data Array ( [0] => [1] => su: must be run from a terminal ) www数据 排列 ( [0] => [1] =>su:必须从终端运行 )
很明显,我想更改活动用户,但是有没有办法从php执行此操作?

su命令只会在bash shell仍在运行时更改当前用户。即使您要执行$cmd='bash-c“sudo su testuser”(将按预期执行),在执行proc_close之前,您也只会更改当前用户,因此exec('whoami')将始终为您提供最初启动php脚本的用户的用户名。但是您可以使用粗体命令来执行一个bashshell,它将以testuser的身份执行,然后通过管道将命令传递给它。例如,如果使用管道“whoami”而不是“nirvana3105\r”,则whoami应返回“testuser”。希望有帮助

请尝试此代码(将密码替换为您的密码):



如果要运行特定命令或脚本,请使用
sudo
或设置
粘性位。但是在脚本上要小心,因为它们可能会被中断,并且您仍然有底层解释器/shell+环境+环境变量。您不能更改当前进程的活动用户,只能在新进程中切换到另一个用户。如果在bash中使用
su
,您可以看到它对
psf
的实际作用:这是一个全新的shell。同样,您不能更改php运行时的进程,但您可以启动一个子进程(尽管我通常在Web服务器中避免这样做)。根据您对其他用户的需要,像
suphp
或使用
SuExec
这样的软件包可能是解决您问题的可能方法。另一个选项是使用正确的用户运行像gearmand这样的deamon,它遵从来自www-data的请求。当我从终端运行它时,该代码起作用。既然在您的上述问题中whoami返回了www数据,我想您是通过apache运行它的吧?如果是这样,您需要使用“sudo adduser www data sudo”将www数据添加到sudo组。但是,请注意,可能不建议这样做,因为您不希望ApacheWeb用户拥有这种权限。如果这只是针对您拥有的本地intranet站点或类似的站点,那么应该可以,否则这会对您的系统造成一点安全威胁。
<?php
    $cmd = "sudo -S su testuser";

    echo $cmd;

    $desc = array(array('pipe', 'r'), array('pipe', 'w'), array('pipe', 'w'));
    $pipes = array();

    $process = proc_open($cmd, $desc, $pipes);
    fwrite($pipes[0], "password\n");
    fwrite($pipes[0], "whoami");
    fclose($pipes[0]);
    $string = array(stream_get_contents($pipes[1]), stream_get_contents($pipes[2]));
proc_close($process);

    print_r($string);
 ?>