2

引数を渡すことで別の期待スクリプトを実行するためのphpスクリプトがあります。

$output = shell_exec("expect login_script.tcl '$user' '$host' '$port' '$password'");

shell_exec の使用は、スクリプトがバックグラウンドまたは php スクリプト内で実行されるため機能しません。ユーザーの対話性を可能にするために、フォアグラウンドで実行する必要があります。これを行うエレガントな方法はありますか。さまざまなスクリプト言語を使用する必要があるため、すでに面倒になっています。php スクリプトを呼び出すシェル スクリプトで 2 つのスクリプトをラップし、結果を変数 (コマンド) として割り当て、それに対して sh を実行してみました。ただし、スクリプトがバックグラウンドで実行され、ユーザーの対話操作によって停止/フリーズが発生するという同じ問題が再び発生します。この状況では、shell exec を呼び出すときに php が「終了」しても問題ありません。すなわち。php が停止し、呼び出されたかのように実行されることを期待します。(出力されたコマンドをコピーして端末に貼り付けた場合と同じです)。


更新 php で次のコマンドを使用すると、はるかにうまくいきます。

shell_exec("gnome-terminal -e 'bash -c \"expect ~/commands/login_script.tcl; exec bash\"' &");

しかし、二次スクリプト(login_script)が終了した直後にシェルを閉じないようにするために、これを改善することはできますか?


更なるアップデート

回答を読んで、人々が「より複雑な」問題を想定しているように見えるので、物事を明確にする必要があると思います。

  • 2 つのプロセスは相互に通信する必要はありません。混乱を招いていると思われるため、$output = shell_execこの例にを入れるべきではなく、単独で使用するべきでした。shell_exec

  • php スクリプトは、いくつかの cli パラメータ (my-script 'param1' 'param2' など) を使用して Expect スクリプトを開始するだけでよく、完全に「非同期」と考えることができます。これは、'launchy' や 'synapse' などのランチャー プログラムの動作によく似ており、他のプログラムを起動できますが、それらに影響を与える必要はありません。また、二次プログラムが終了/終了するのも待ちません。

  • 「shell_exec」が機能しないと言うのは間違いでした。私が言うべきだったのは、「これまでのところ shell_exec の使用に成功していません」が、shell_exec("gnome-terminal -e 'bash -c \"expect ~/commands/login_script.tcl; exec bash\"' &");「機能している」が、expect スクリプトに引数を渡すことができる正しい引用符の組み合わせを見つけようとしているということです。

4

4 に答える 4

1

タスク管理は興味深いが難しい仕事です。

ユーザーはタスク中に移動できるため(セッションのフリーズやプロセスからの不完全な作業など、予期しない結果につながる可能性があるため)、バックグラウンドで実行する必要があります。ユーザーとプロセスの間でやり取りする必要がある場合は、通信する方法を作成する必要があります。

(私が思うに)最も簡単な方法は、ユーザーセッションとタスクの間で共有されるファイルを使用することです。

ここに画像の説明を入力してください

同時に多数のユーザーがいて、ユーザーとプロセス間で多くの通信を行う場合は、パーティションをメモリにマウントして、読み取り/書き込み操作を最適化できます。

あなたのfstabでは、次のような行があります:

tmpfs /memory       tmpfs defaults,uid=www-data,gid=www-data,size=128M 0 0

または、スクリプトで、次のことを実行できます。

#!/bin/sh
mkfs -t ext2 -q /dev/ram1 65536
[ ! -d /memory ] && mkdir -p /memory
mount /dev/ram1 /memory
chmod -R 777 /memory

あなたはたくさんのことに気を配る必要があるでしょう:

  • ファイルアクセス(Webアプリケーションとプロセス間の同時実行を回避するため)
  • 時間(ゾンビや無駄な長時間実行スクリプトを回避するため)
  • セキュリティ(このような操作は慎重に設計する必要があります)
  • リソース管理(10000プロセスが同時に実行されることを回避するため)
  • ..。
于 2013-01-24T22:34:08.777 に答える
1

最後に、3 番目の引用符タイプを追加することで機能させることができました: ` (「tack」と呼ばれていると思いますか?)。これにより、最初のスクリプトから次のスクリプトに引数を渡すことができました。

私のphpスクリプトに必要なコマンドは次のとおりです。

$command = `gnome-terminal -e 'bash -c "expect ~/commands/login_script.tcl \"$user\" \"$host\" \"$port\" \"$password\"; exec bash"' &`;
shell_exec($command);

引用符の種類を交換すると機能しなくなる可能性があるため、すべての引用符を正しく取得するのに時間がかかりました。

これが最終結果を示すビデオです

于 2013-01-27T02:11:36.167 に答える
1

あなたが探しているのはproc_open()コマンドだと思います。バックグラウンド プロセスの stdin/stdout ストリームにアクセスできます。$descriptorSpecパラメーターで独自の stdin/stdout ストリームを新しいプロセスに渡すことができます。これにより、バックグラウンド プロセスがユーザーと対話できるようになります。

「フォアグラウンド」アプリケーションは、バックグラウンド プロセスが終了するまで待機する必要があります。私は実際に PHP でこれを行ったことはありませんが、$pipesを監視して、いつ閉じられるかを確認する必要があると思います。そうすれば、バックグラウンド プロセスが終了し、プロセス リソースを削除して、フォアグラウンド プロセスが必要とする処理を続行します。

于 2013-01-24T22:49:37.440 に答える
1

使用する:

pcntl_exec("command", array("parameter1", "parameter2"));

たとえば、次のような現在の php プロジェクトのパラメーターを使用して mysql コマンドを開始するスクリプトがあります。

pcntl_exec("/usr/bin/mysql", array(
    "--user=".$params['user'],
    "--password=".$params['password'],
    "--host=".$params['host'],
    $params['dbname']
));

これは gnome 端末などに依存せず、PHP を呼び出したプログラムに置き換えます。

コマンドのフル パスを知る必要がありますが、これはプラットフォームによって異なる可能性があるため面倒ですが、ほとんどのシステムenvで利用可能なコマンド コマンドを使用し/usr/bin/envて、コマンドを見つけることができます。上記の例は次のようになります。

pcntl_exec("/usr/bin/env", array(
    "mysql",
    "--user=".$params['user'],
    "--password=".$params['password'],
    "--host=".$params['host'],
    $params['dbname']
));
于 2013-02-01T18:01:21.337 に答える