【问题标题】:Get process resource by PID通过PID获取进程资源
【发布时间】:2015-03-16 23:30:04
【问题描述】:

我想写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\

  1. 我写cd /命令,我的当前目录是C:\

这只是示例,我不想只更改目录,这对我来说不是问题。

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

  1. 我可以通过proc_open函数创建进程。
  2. 我可以通过get_process_status获取PID,但是如何获取当前PHP文件执行之前创建的进程资源?

下一个问题,如果可以访问过去创建的进程,如何将新命令写入创建的进程?

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

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


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

【问题讨论】:

  • 文件如何获取命令?作为争论还是通过包含文件和调用函数/设置变量?
  • 这只是代码示例,我只想在后台运行cmd进程,向它发送命令并接收响应。
  • 请查看我的更新答案。这将读取输入,并将命令发送到cmd,直到您输入exit

标签: php shell sockets proc-open


【解决方案1】:

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

【讨论】:

    【解决方案2】:

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

    1) 您的 start.php 脚本将轮询文件资源,例如/tmp/commands.in 用于传入命令。当然,脚本只能在您的 PHP 设置 max_execution_time 允许的情况下执行此操作,因此请务必调用 set_time_limit(0); 以取消限制。如果在文件中找到命令,脚本将通过其进程管道将其执行到 cmdbash 或任何用作 shell 的命令,并将输出写入 /tmp/commands.out

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

    *) 很幼稚,因为这种方法显然会带来并发性、安全性和许多其他问题。所以这些问题必须通过使用文件锁、ACL等来处理。

    【讨论】:

    • 执行过去的所有推荐,在每个下一个要处理的请求中,花费更多时间。
    【解决方案3】:

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

    <?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])...之前,您无法从孩子那里获取数据。这意味着在您完成发送命令之前,您无法获得孩子的输出。

    【讨论】:

      猜你喜欢
      • 2011-05-10
      • 2014-12-28
      • 1970-01-01
      • 2013-02-05
      • 1970-01-01
      • 2011-07-01
      • 1970-01-01
      相关资源
      最近更新 更多