ホームページ > バックエンド開発 > PHPチュートリアル > PHPでPythonスクリプトを実行するにはどうすればよいですか?

PHPでPythonスクリプトを実行するにはどうすればよいですか?

WBOY
リリース: 2016-06-23 14:14:14
オリジナル
1047 人が閲覧しました

PHP Python SSH2

php を介してリモートサーバーに ssh 接続し、サーバー上で python ファイルを実行し、結果を取得し、php から出力したいと考えています。
私のコードは次のとおりです:

$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に出力されるのはnull値です。
$string = ssh2_exec($connection, 'python pythonfile.py; sleep 20')

$string = ssh2_exec($connection, 'ls -l')
に置き換えると、問題はなく、プログラムは正常に出力されます。

リモートサーバーで Python ファイルを実行するには通常 15 秒かかるため、スリープを 20 に設定しましたが、それでも結果は得られません。
コードに何か問題があるかどうかお聞きしたいのですが?それを修正するにはどうすればよいですか?

ディスカッションへの返信(解決策)

なぜ寝るのですか?リモートスリープは意味があるのでしょうか?

stream_set_blocking($string,true); がブロッキング モードに設定されているため、スリープを削除します。つまり、実行結果を取得する前にシェルの実行が完了するまで待機します

stream_set_blocking($string,true) のため、スリープを削除します); ブロッキング モードに設定されています。つまり、実行結果を取得する前にシェルの実行が完了するまで待機します。Python ファイルへのパスが空であるため、投稿の問題は解決されました。は間違っています。python path/to/python/ file。パスの前に余分な / を追加したため、プログラムは実行するファイルを見つけることができませんでした。


これでプログラムは私が望む結果を返すことができましたが、まだ小さな問題が残っていますので、皆さんが解決してポイントを追加できるようにしていただければ幸いです。
$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 ファイルを実行して、結果 ルートの下のoutput.txtに移動します。
しかし、上で述べたように、この Python ファイルの実行は結果を返すまでに通常 15 秒かかるため、ここに sleep(20) を追加する必要があります。そうしないと、プログラムは「fopen(): 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() は結果を取得する前にシェルの実行が完了するのを待ちます。なぜ出力ファイルが生成される前に fopen が実行されるのでしょうか。
現在のコードでは希望通りの結果が得られますが、output.txt の生成にかかる時間を正確に見積もることができないため、sleep() を手動で設定するのは最適な方法ではないと感じます。 , プログラムを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 が直接取得できるようになりました。ブロッキング モードでは fgets() 呼び出しは常にすぐに戻りますが、ブロッキング モードではストリームでデータが利用可能になるまで待機します。そのため、前のコードを使用する場合、output.txt ファイルが生成されると、結果がが書き込まれていない場合、$stream はデータを取得したため、stream_set_blocking() は自動的に終了します。ただし、Python で生成された結果をストリームに直接書き込むと、結果が完全に生成されるまでプロセスがブロックされます。
私の説明が正しいかわかりませんが?不適切な場合は修正していただければ幸いです。 。

解決しました、コードを再度変更しました
$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 が直接取得できるようになりました。これは、「非ブロッキング モードでは fgets() 呼び出しが常にすぐに返されるためです。データがストリーム上で利用可能になるまで待機します。」 したがって、前のコードを使用すると、output.txt ファイルが生成されると、結果が書き込まれていなくても、$stream はすでにデータを取得しているため、stream_set_blocking()自動的に終了します。ただし、Python で生成された結果をストリームに直接書き込むと、結果が完全に生成されるまでプロセスがブロックされます。
私の説明が正しいかわかりませんが?不適切な場合は修正していただければ幸いです。 。

そうです、ストリームがシェルによって返されたデータを受信すると、ストリームは結果を返すようにトリガーされ、stream_get_contents が実行されます

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート