2012-04-11 71 views
2

下面是我想要實現的:從該shell打開一個shell(korn或bash,無所謂),我想打開一個ssh連接(ssh [email protected])。在某些情況下,它很可能會發生,我將被提示輸入密碼,或者我可能會詢問是否確定要連接(有問題的密鑰)。proc_open交互

之前有人問:是的,我知道有一個用於ssh2 exec調用的插件,但我正在使用的服務器不支持它,並且不太可能這樣做。

這裏是我試過到目前爲止:

$desc = array(array('pipe','r'),array('pipe','w'));//used in all example code 
$p = proc_open('ssh [email protected]',$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 。

這給了我以下錯誤:

Pseudo-terminal will not be allocated because stdin is not a terminal.

所以,我雖然SSH被稱爲在php:// IO-流C ontext,似乎是上述錯誤的合理解釋。

下一頁:我雖然對my first SO question,並決定它可能是一個好主意,先打開一個bash/ksh的殼:

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

並把它從那裏,但我得到了確切的相同的錯誤消息,只這一次腳本停止運行,但ssh運行。所以,我希望,然後就覺得自己很笨,最終絕望:

$p=proc_open('bash && ssh [email protected]',$desc,$pipes); 

幾秒鐘後,等待,我得到了以下錯誤:

PHP Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 133693440 bytes)

調用堆棧不斷造就了stream_get_contents線,即使在我的最後願望:

#!/path/to/bin/php -n 
<?php 
    $p = proc_open('bash && ssh [email protected]',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中的stream [1]擁有ssh連接,因此它的內容非常龐大。我需要的是管道內的管道......這甚至有可能嗎?我必須錯過一些東西,如果這是不可能的,管道有什麼好處...... 我的猜測是proc_open命令是錯誤的,以(錯誤:Broken pipe)開頭。但我真的無法看到第一個錯誤的任何其他方式......任何想法?或者如果上述咆哮不是很清楚(可能不是),那麼就可以跟進問題。

回答

1

Before anyone asks: yes, I am aware there is a plugin for ssh2 exec calls, but the servers I'm working on don't support it, and are unlikely to do so.

其實有兩個。 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'); 
?> 
+0

感謝,有趣的lib,但我想知道:它仍然支持?根據代碼判斷,我認爲它是用PHP4編寫的,而且第一批谷歌搜索已經超過一年了......儘管如此,我還是會試試看。如果它有效,它會起作用,我會讓你知道的 – 2012-04-11 17:41:20

+1

三天前有人向其SVN回購提交了一份提交,並且作者昨天在幫助某人發表了一篇文章。我認爲該庫的目標是兼容PHP4和PHP5。使用private/public而不是var會使代碼僅爲PHP5,但不會真正添加很多其他的imho。 – neubert 2012-04-11 20:02:17

+0

對不起,雖然這個lib很好,但是與遠程主機上的進程交互還是有點難,不是嗎? '$ ssh-> exec('su');'例如,會掛起,因爲我似乎無法找到傳遞密碼的方法。 – 2012-04-12 10:28:58