呼び出されたコマンドの出力を取得したい場合は、C ++でサブプロセスを実行するための最良の方法

呼び出されたコマンドの出力を取得したい場合は、C ++でサブプロセスを実行するための最良の方法

私はC ++でアプリケーションを書いています。私のコードのいくつかの場所でsystem()関数を使用していくつかのコマンドを実行します。これがエレガントな解決策であるかどうかはわかりません。この関数をサブプロセスを呼び出す別の方法に置き換えたいと思います。

考慮すべき2つの重要な問題があります。

  1. まず、サブプロセスの実行が完了するのを待ってから戻りコードを確認したいと思います。
  2. 第二に、時々、これらのコマンドは端末にいくつかの重要な情報を印刷します。この情報を読んで保存したいですrsyslog。私のアプリケーションはいくつかのイベントロギングを使用していますsyslog(LOG_INFO, "%s", "Some event occured.")。同様の方法で子プロセスの出力を記録できますか?

答え1

私のコードのいくつかの場所でsystem()関数を使用していくつかのコマンドを実行します。

これは良い兆候ではありません!system実際によく使うべきです。 C++ 関数でもなく、システム呼び出しでもなく、コマンドを実行するためにシェルを開く C ライブラリです (まあ、に包まれているが<cstdlib>まだ)。たくさんほとんどの場合、これはオーバーヘッドであるだけでなく、プログラムにセキュリティ抜け穴をもたらす一般的な方法でもあります。その振る舞いはとても驚きです。あなたの環境によって、シェルは興味深い方法で動作する可能性があります。

だからsystemあなたじゃないならそれを使わないで本物〜したい

  1. /bin/sh プログラムを探す
  2. 走る、
  3. 対応するパラメータ(argv)を次に設定します。-c what you passed to system()

ポイント3は、他の実行ファイルだけでなく、他の実行ファイルを実行する場合にのみ意味があります。シェルコマンドつまり、まずプログラムに論理的に統合できるのです。

これがエレガントな解決策であるかどうかはわかりません。この関数をサブプロセスを呼び出す別の方法に置き換えたいと思います。

もちろん、いくつかの方法があり、実際にすべきことは、電話の内容、理由、頻度によって異なります。

まず、サブプロセスの実行が完了するのを待ってから戻りコードを確認したいと思います。

systemちなみに、 を使ってこれを行うこともできますWEXITSTATUS。詳細についてはを参照してください man 2 waitpid。とにかく上記のように使用をお勧めしませんsystem

時々、これらのコマンドは端末にいくつかの重要な情報を出力します。 rsyslogがこの情報を読み取って保存できることを願っています。

当然だとは言えませんが、これらのコマンドを独自に記録する必要がありますか?

とにかく生成されたプロセスの出力をキャプチャするには、libc / posixを使用しますpopen

もう一度申し上げますが、外部コマンドを呼び出して実行中の作業を既存のライブラリで実行できるかどうかを調べて、OSに要求して少しぎこちないバイパスをする必要がないことを強くお勧めします。他のプロセスを実行して通信します。

答え2

C++のケースは確認できませんでしたが、@Marcusはこれがpopen()可能だと答えました。これにより、アプリケーションに呼び出されたコマンドの内容をFILE *読み取ることができるオブジェクトが提供されます。stdout

logger標準入力をシステムログに送信するスタンドアロンコマンドもあります。

アプリケーションの標準エラーをロガーパイプにリダイレクトできるようにpopen呼び出してコマンドラインを実行します。/bin/shこれは、Bashプロセスの交換を使用するためにコマンドをラップする必要があることを意味する可能性があります。したがって、popenコマンドは次のようになります(テストされていません)。

fp = popen ("bash -c 'myApp myArgs 2>( logger -opts )'", "r");

関連情報