怎樣在php中執行python script?

來源:互聯網
上載者:User
PHP Python SSH2

想通過php ssh到遠程伺服器,然後執行伺服器上的一個python檔案,獲得結果,然後從php中列印出來。
My Code如下:

$connection = ssh2_connect('remote-server',22);ssh2_auth_password($connection, 'root','pwd');$string = ssh2_exec($connection, 'python pythonfile.py; sleep 20');stream_set_blocking($string,true);echo stream_get_contents($string);


但是php中列印出來的是空值。
如果我把
$string = ssh2_exec($connection, 'python pythonfile.py; sleep 20')
替換為
$string = ssh2_exec($connection, 'ls -l')
則沒有問題,程式正常輸出。

遠程伺服器中的python檔案運行一般需要15秒,所以我設定了sleep 20,但還是擷取不到結果。
想問是不是代碼哪裡有錯?要怎麼改正呢?


回複討論(解決方案)

為何要sleep?遠端sleep有意義嗎?

把sleep去掉,因為stream_set_blocking($string,true);已經設定為阻塞模式了,也就是會等待shell執行完畢才會擷取執行的結果

把sleep去掉,因為stream_set_blocking($string,true);已經設定為阻塞模式了,也就是會等待shell執行完畢才會擷取執行的結果

文章中的問題已經解決了,返回為空白是因為python檔案的路徑給的不對,python path/to/python/file,我當時在path前多加了一個/,所以程式沒法找到檔案來執行。

現在程式可以返回我要的結果,但還有一個小小的問題,希望大家可以幫忙解決,可以追加分數。
$string = ssh2_exec($connection, 'cd a/b/c; python discovery.py > /root/output.txt;');
stream_set_blocking($string,true);
sleep(20)

$stream = fopen("ssh2.sftp://$sftp/root/output.txt",'r');
$contents = fread($stream,filesize("ssh2.sftp://$sftp/root/output.txt"));
echo $contents;
fclose($stream);

這是我現在的代碼,通過遠程ssh,我先進入到c檔案夾,然後從中執行discovery.py檔案,將結果輸出到root下的output.txt中。
但是正如我上文所說,這個python檔案的執行一般需要15秒來返回結果,所以這裡必須加一個sleep(20),不然的話程式就會報錯說“fopen(): Unable to open ssh2.sftp://Resource id #5/root/output.txt on remote host in /var/www/html/test/ssh.php on line 20”,我估計是因為時間太短所以程式還沒能產生"output.txt"這個檔案。

但hnxxwyq,如果如你所說,stream_set_blocking()會等shell執行完畢才會擷取結果,為什麼output檔案還沒產生程式就已經執行到fopen了呢?
雖然現在的代碼可以獲得我想要的結果,但我覺得人工設定sleep()不是最優方法,因為你沒法正確估計output.txt產生所需的時間,如果15秒就能產生結果檔案,而我讓程式sleep(20)的話,就浪費了時間,所以有沒有辦法讓程式在output.txt產生後馬上執行fopen()那一行?
貌似stram_set_blocking()沒有這個功能。。我對php不是太熟悉,各位指教

解決了,我把代碼又改了下
$stream = ssh2_exec($connection, 'cd DCA_automation/main/QAUtilities/Utils; python cluster_discovery.py');
stream_set_blocking($stream, true);

$string = stream_get_contents($stream);
echo $string;

不再把python結果輸出到檔案,直接讓$stream擷取,因為"In non-blocking mode an fgets() call will always return right away while in blocking mode it will wait for data to become available on the stream",所以,如果用之前的代碼的話,一旦output.txt檔案產生,哪怕結果還沒寫上去,$stream已經獲得了資料,所以stream_set_blocking()會自動終止。但如果我將python產生結果直接寫到stream上的話,結果沒有完全產生前進程會一直block。
不知道我解釋的對不對?不恰當的地方歡迎大家指正。。

解決了,我把代碼又改了下
$stream = ssh2_exec($connection, 'cd DCA_automation/main/QAUtilities/Utils; python cluster_discovery.py');
stream_set_blocking($stream, true);

$string = stream_get_contents($stream);
echo $string;

不再把python結果輸出到檔案,直接讓$stream擷取,因為"In non-blocking mode an fgets() call will always return right away while in blocking mode it will wait for data to become available on the stream",所以,如果用之前的代碼的話,一旦output.txt檔案產生,哪怕結果還沒寫上去,$stream已經獲得了資料,所以stream_set_blocking()會自動終止。但如果我將python產生結果直接寫到stream上的話,結果沒有完全產生前進程會一直block。
不知道我解釋的對不對?不恰當的地方歡迎大家指正。。

沒有錯,是stream接收到shell返回的資料時,才會觸發stream返回結果,從而執行stream_get_contents

  • 聯繫我們

    該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

    如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.