質問
C ++プログラムを作成したいのですが、ここでは関数 popen
を使用して、コマンドをUnixのコマンドラインに送信しています。正常に動作しますが、 cd directory
を呼び出しても、ディレクトリは変わりません。スクリプトディレクトリパスの変更が完了した後、スクリプトで cd directory
を実行しようとしても同じことです。したがって、スクリプトはのように実行する必要があります。 ./script.sh
は ./ sript.sh
ではなく、 popen
関数でそれを行う方法ですか? "を追加しようとしました。 "
は popen
の最初の引数の前にありますが、"を実行しています。 ls"
はエラーになります。
コード:
cout << "@ Command from " << session->target().full() << ": " << message.body() << endl;
//cout << "Prisla zprava" << endl;
//m_session->send( "Hello World", "No Subject" );
//system( message.body().c_str() );
//if ( message.body() == "" )
FILE* outp;
char buffer[100];
string outps = "";
outp = popen( message.body().c_str(), "r" );
while ( !feof(outp) )
{
fgets( buffer, 100, outp );
outps = outps + buffer;
}
pclose(outp);
cout << "& Output from command: " << outps << endl;
m_session->send( outps.c_str(), "Output" );
message.body();
は、実行したい string
です( XMPP
から受け取っています)。たとえば、 string
が&quot; ls&quot;
の場合、実際のディレクトリ内のファイルのリストとともに string
を返します。しかし、メッセージが&quot; cd directory&quot;
の場合、スクリプトでディレクトリを変更しようとしても何も起こりません。
解決
通常、popen()コマンドがコマンドを実行する方法はシェル経由です。したがって、パイプを開き、分岐します。子は配管を行い(パイプをフラグに応じて標準入力または標準出力に接続)、実行します
execl("/bin/sh", "/bin/sh", "-c", "what you said", (char *)0);
したがって、すべての動作は主な環境変数、特にPATHに依存します。
現在のディレクトリでスクリプトを実行する場合、次のオプションのいずれか:
outp = popen("./script.sh", "r");
outp = popen("sh -x ./script.sh", "r");
outp = popen("sh -c './script.sh arg1 arg2'", "r");
「 ls
」コマンドを実行する場合:
outp = popen("/bin/ls /the/directory", "r");
そして、何かを実行する前にディレクトリを変更したい場合:
outp = popen("cd /somewhere/else; ./script", "r");
など...
popen()を使用しているプログラムのディレクトリを変更する場合は、 'chdir()'システムコール(またはfchdir())を使用する必要があります。開始した場所に戻りたいと思う場合は、次を使用します。
int fd = open(".", O_RDONLY);
chdir("/some/where/else");
...do stuff in new directory
fchdir(fd);
(明らかに、そのロットでいくつかのエラーチェックが必要です。)
他のヒント
理解できないコードが少しあるようです。パイプである outp
から読み取りしています。 input パイプに outp
という名前を付けるのはかなり混乱します。次に、読み込んだ文字列を取得して、 m_session-&gt; send()
に渡します。
このプロセス全体のどこでも、Unixコマンドラインと対話することはありません。特に、 popen()
はそうではありません。