【问题标题】:proc_open interactionproc_open 交互
【发布时间】:2012-04-23 13:57:43
【问题描述】:

这是我想要实现的目标:打开一个 shell(korn 或 bash,没关系),从那个 shell,我想打开一个 ssh 连接(ssh user@host)。在某些时候,可能会提示我输入密码,或者可能会询问我是否确定要连接(有问题的键)。

在有人问之前:是的,我知道有一个用于 ssh2 exec 调用的插件,但我正在使用的服务器不支持它,而且不太可能这样做。

这是我迄今为止尝试过的:

$desc = array(array('pipe','r'),array('pipe','w'));//used in all example code
$p = proc_open('ssh user@host',$desc,$pipes);
if(!is_resource($p)){ die('@!#$%');}//will omit this line from now on
sleep(1);//omitting this,too but it's there every time I need it

然后我尝试读取控制台输出 (stream_get_contents($pipes[1])) 以查看我接下来要传递的内容(密码,是或返回 'connection failed: '.stream_get_contents($pipes[1]) 和 proc_close $p。

这给了我以下错误:

不会分配伪终端,因为 stdin 不是终端。

所以,我虽然在php:// io-stream 上下文中调用了 ssh,但似乎是对上述错误的合理解释。

下一步:我想到了my first SO question,并决定先打开一个 bash/ksh shell 可能是个好主意:

$p = proc_open('bash',$desc,$pipes);

然后从那里获取它,但我得到了完全相同的错误消息,只是这一次,脚本停止运行但 ssh 确实运行了。所以我充满希望,然后感到愚蠢,最终绝望:

$p=proc_open('bash && ssh user@host',$desc,$pipes);

等待几秒钟后,我收到以下错误:

PHP 致命错误:允许的内存大小为 134217728 字节已用尽(尝试分配 133693440 字节)

即使在我最后一次绝望的尝试中,调用堆栈也会不断调出 stream_get_contents 行:

#!/path/to/bin/php -n
<?php
    $p = proc_open('bash && ssh user@host',array(array('pipe','r'),array('pipe','w')),$ps);
    if (!is_resource($p))
    {
        die('FFS');
    }
    usleep(10);
    fwrite($ps[0],'yes'."\n");
    fflush($ps[0]);
    usleep(20);
    fwrite($ps[0],'password'."\n");
    fflush($ps[0]);
    usleep(20);
    fwrite($ps[0],'whoami'."\n");
    fflush($ps[0]);
    usleep(2);
    $msg = stream_get_contents($ps[1]);
    fwrite($ps[0],'exit'."\n");
    fclose($ps[0]);
    fclose($ps[1]);
    proc_close($p);
?>

我知道,它一团糟,很多fflush 和冗余,但重点是:我知道这个连接会首先提示我输入违规密钥,然后询问密码。我的猜测是 $pipes[1] 中的流包含 ssh 连接,因此它的内容很大。那么我需要的是管道内的管道......这甚至可能吗?我一定是错过了什么,如果这是不可能的,那么管道有什么用...... 我的猜测是 proc_open 命令一开始是错误的,(错误:断管)。但我真的看不到第一个错误的任何其他方式......有什么想法吗?如果上述咆哮完全不明确(可能不是),或者跟进问题。

【问题讨论】:

    标签: ssh pipe php proc-open


    【解决方案1】:

    在有人问之前:是的,我知道有一个用于 ssh2 exec 的插件 调用,但我正在处理的服务器不支持它,并且是 不太可能这样做。

    实际上有两个。 PECL 模块,这是一个大多数服务器都没有安装的 PITA 和phpseclib, a pure PHP SSH2 implementation。其使用示例:

    <?php
    include('Net/SSH2.php');
    
    $ssh = new Net_SSH2('www.domain.tld');
    if (!$ssh->login('username', 'password')) {
        exit('Login Failed');
    }
    
    echo $ssh->exec('pwd');
    echo $ssh->exec('ls -la');
    ?>
    

    【讨论】:

    • 谢谢,有趣的库,但我想知道:它仍然支持吗?从代码来看,我会说它是用 PHP4 编写的,而且谷歌上的第一批点击已经超过一年了......不过,我会试一试。如果它有效,它有效,我会告诉你
    • 三天前有一个提交到它的 SVN 仓库,作者昨天发了一个帖子来帮助别人。我认为该库的目标是同时兼容 PHP4 和 PHP5。使用 private / public 而不是 var 使代码仅 PHP5 但并没有真正增加很多否则恕我直言。
    • 抱歉,虽然这个库很好,但与远程主机上的进程交互仍然有点禁忌,不是吗?例如$ssh-&gt;exec('su'); 会挂起,因为我似乎找不到传递密码的方法。
    • 试试 $ssh->read() 和 $ssh->write()。以下是如何使用 sudo 执行此操作的示例:phpseclib.sourceforge.net/documentation/net.html#net_ssh_sudo
    • 谢谢...愚蠢的我没有多花 5 分钟检查 sourceforge。不过,我还是有点担心接连打来的电话……但是,嘿,我会去那里的。再次感谢
    猜你喜欢
    • 1970-01-01
    • 2013-11-26
    • 2013-09-20
    • 2018-01-12
    • 2013-09-15
    • 2019-10-27
    • 1970-01-01
    • 2022-01-05
    • 1970-01-01
    相关资源
    最近更新 更多