通过PID获取流程资源

时间:2015-03-16 23:30:04

标签: php shell sockets proc-open

我想编写Web SSH控制台,我发现了两个问题。

我想做什么。首先,我想执行具有以下代码的start.php文件。

$process = proc_open('start', array(
    0 => array("pipe", "r"), 
    1 => array("pipe", "w"), 
    2 => array("pipe", "a")
), $pipes);

其次我想在command.php文件中运行start.php运行命令的文件,并从中获取结果。

$pid = 12345;
print_r(process_command('ping google.com', $pid));

我只想访问过去创建的进程(cmd),向其发送命令并获得结果。

为什么这是问题,如果我可以为每个command.php执行创建新进程?因为新进程是新会话,如果我在过去的command.php执行中登录到mysql,在下次执行时我必须再次登录到mysql,因为新进程不记得我被记录了。

Windows上的示例。

  1. 我在PHP中创建了新进程(cmd),我当前的目录是C:\WebServ\
  2. enter image description here

    1. 我写了cd /命令,我当前的目录是C:\
    2. enter image description here

      这只是一个例子,我不想只改变目录,这对我来说不是问题。

      问题是如何在下一个PHP文件执行中创建一个进程并访问它 - 如果我想要记住mysql会话?

      1. 我可以通过proc_open函数创建流程。
      2. 我可以通过get_process_status获取PID,但是如何在执行当前PHP文件之前创建进程资源?
      3. 接下来的问题是,如果可以访问过去创建的进程,如何将新命令写入已创建的进程?

        我不想使用PHP扩展。 但如果在这种情况下需要这样做,每个答案都会对我有帮助。

        如果无法访问在其他PHP执行中创建的进程,我希望在PHP执行开始时使用while(1)来控制创建的进程 - 但我希望在这种情况下不需要这样做。 然后我希望有人知道,如何编写新命令来创建cmd进程。


        如果我的问题的解决方案有问题,我会接受答复,告诉我如何将命令发送到cmd.exe打开的shell_exec进程,以及如何接收每个命令的响应。< /强>

3 个答案:

答案 0 :(得分:0)

proc_open()会返回资源类型。资源无法序列化,因此您无法保存以供日后使用。除了持久数据库连接之外,它们在脚本执行结束时被释放。

答案 1 :(得分:0)

我想我明白你现在在问什么。试试这个:

<?php
$fd = array(
0 => array("pipe", "r"),  // stdin
1 => array("pipe", "w"),  // stdout
2 => array("file", "error.txt", "a") // stderr
);

$process = proc_open("cmd.exe", $fd, $pipes);

echo "Welcome to this interactive CMD shell. Please type your commands below\n";
while(is_resource($process) {
  $input = readline(); //Get user input
  $input .= "\n";      //Need newline to press ENTER on CMD

  if($input == "exit\n") {

    fwrite($pipes[0], $input);
    break; //End BOTH this program AND cmd
  }

 fwrite($pipes[0], $input);
}

fclose($pipes[0]);
echo file_get_stream($pipes[1]); //print all the output from CMD

//Cleanup
fclose($pipes[2]);
proc_close($process); //Should already be closed!

注意,在关闭STDIN($ pipes [0])之前,你无法从子节点获取数据....意味着在完成发送命令之前你无法获得子输出。

答案 2 :(得分:0)

这种非常幼稚的方法怎么样:

1)您的start.php脚本会轮询文件资源,例如传入命令的/tmp/commands.in。当然,只要你的PHP设置max_execution_time允许,脚本只能这样做,所以一定要调用set_time_limit(0);来删除限制。如果在文件中找到命令,则脚本将通过其进程管道将其执行到cmdbash或用作shell的任何内容,并将输出写入/tmp/commands.out。 / p>

2)然后,您的command.php会将命令写入/tmp/commands.in并阅读/tmp/commands.out的内容并在浏览器中显示。

*)天真,因为这种方法显然会出现并发性,安全性和许多其他问题。因此,必须使用文件锁,ACL等处理这些问题。