0

次のように、popen を使用してシステム スクリプトを実行しています。

snprintf(cmd, MAX_PATH, "/myscript -q | grep -i %s", deviceName);
FILE *res = popen(cmd, "r");

スクリプトが見つからない場合、プログラムは順調に進みます。ただし、「ファイルまたはディレクトリが見つかりません」というメッセージが表示されます。これは、意図した使用法ではエラーではありませんが、エラーのようです。

このメッセージを黙らせる方法はありますか? または、ls | grep -i myscriptこの行を実行する前に電話する必要がありますか?

4

2 に答える 2

2

POSIX シェル、またはかなり最近の Bourne シェル バリアントであると仮定すると/bin/sh、実際のコマンドを実行する前に、コマンド内の標準出力をリダイレクトできます。exec 2>/dev/null ;実行したいコマンドの前に追加するだけです。

私が個人的にこれを行う方法は次のとおりです。

/* Shell syntax for redirecting standard error to /dev/null, to
 * silence any errors. If /bin/sh does not support this, you can
 * simply replace it with an empty string.
*/
#define  POPEN_STDERR_NULL "exec 2>/dev/null ;"

...

snprintf(cmd, MAX_PATH, POPEN_STDERR_NULL "/myscript -q | grep -i -e '%s'", deviceName);
FILE *res = popen(cmd, "r");

popen()コマンドは、指定された/bin/shコマンドを実行するために内部的に使用します。上記は/bin/sh、Linux や SunOS 5.10 を含む、私がテストできるすべてのバリアントで機能するため、移植性が高いはずです。(つまりdash、、、bashおよび SunOS 5.10shはすべて正常に動作します。)

非標準システムではアプリケーションを再コンパイルする必要があるため、いつでもマクロを編集してプレフィックスを省略できます。(そのようなシステムを見つけた場合、必要に応じてテストをマジックに簡単に追加して、Makefile自動的に省略することができます。)

snprintf()呼び出しでパラメーター置換を変更したことに注意してください。一重引用符を含まないものに対してdeviceName機能します。内の一重引用符は、呼び出しの前に文字列に置き換える必要があります。deviceName'"'"'snprintf()

質問?

于 2012-09-27T15:08:54.240 に答える
0

あなたがメッセージを抑圧できるかどうか、私にはよくわかりません。エラーは、標準エラー ストリームに出力される標準 Linux エラーです。標準エラーのファイル記述子である FD '2' を保持できます。というわけで、この FD を閉じることができるかもしれません。

ただし、これにより、プログラムの残りの部分でエラーが出力されなくなることを警告する必要があります。

より良い方法は、次のようにすることです: snprintf(cmd, MAX_PATH, "/myscript -q | grep -i %s 2> dummyfile", deviceName);

これにより、すぐに削除するダミー ファイルにエラーがリダイレクトされます。

したがって、注意して、何をしたいのかを決めてください...

乾杯、VSN

于 2012-09-27T14:31:51.450 に答える