POSIX system()
の 2004 年版 ドキュメントには、popen()
に適用される可能性が高い根拠があります。 同じように。 system()
に記載されている制限に注意してください 、特に「プロセス ID が異なる」と述べているもの:
根拠
...
system() 関数には 3 つのレベルの指定があります。 ISO C 標準は最も基本的なものです。関数が存在する必要があり、アプリケーションがコマンド言語インタープリターが存在するかどうかを照会する方法を定義します。コマンド言語やコマンドが解釈される環境については何も述べていません。
IEEE Std 1003.1-2001 は、system() に追加の制限を課しています。コマンド言語インタープリターが存在する場合、環境は fork() および exec によって指定されたとおりでなければなりません。これにより、たとえば、close-on-exec が機能すること、ファイル ロックが継承されないこと、プロセス ID が異なることが保証されます。また、コマンド ラインを実行できる場合の system() からの戻り値も指定するため、コマンドの完了ステータスに関する情報がアプリケーションに提供されます。
最後に、IEEE Std 1003.1-2001 では、IEEE Std 1003.1-2001 の Shell and Utilitiesvolume で定義されているシェル コマンド言語でコマンドを解釈する必要があります。
「ISO C標準」への複数の参照に注意してください。 C 標準の最新バージョンでは、コマンド文字列がシステムの「コマンド プロセッサ」によって処理される必要があります。
<ブロック引用>
7.22.4.8 system
関数
あらすじ
#include <stdlib.h>
int system(const char *string);
説明
string
の場合 null ポインター、system
関数は、ホスト環境にコマンド プロセッサがあるかどうかを判断します。 string
の場合 null ポインターではなく、system
関数は string
が指す文字列を渡します 実装が文書化する方法で実行されるコマンド プロセッサ。これにより、プログラムが system
を呼び出す可能性があります 不適合な方法で行動する、または終了する。
返品
引数が null ポインターの場合、system
function は、コマンド プロセッサが使用可能な場合にのみ、0 以外を返します。引数が NULL ポインタではなく、system
関数が返す場合、実装定義の値を返します。
C 標準では、システムの「コマンド プロセッサ」を system()
に使用する必要があるため、 電話、私はそれを疑う:
popen()
を結び付ける POSIX の要件がどこかにあります system()
に 実装。したがって、これは 2 回削除された Glib の回答です。
シェルを呼び出すと、シェルで実行できるすべてのことを実行できます。たとえば、
FILE *fp = popen("ls *", "r");
popen()
で可能です (現在のディレクトリ内のすべてのファイルを展開します)。以下と比較してください:
execvp("/bin/ls", (char *[]){"/bin/ls", "*", NULL});
ls
を実行することはできません *
で exec(2)
のため、引数として *
を解釈します
同様に、パイプ (|
)、リダイレクト (>
、 <
、 ...) などは popen
で可能です .
そうでなければ、popen
を使用する理由はありません シェルが必要ない場合 - それは不要です。余分なシェル プロセスが発生し、シェルで問題が発生する可能性があるすべてのことがプログラムでも問題になる可能性があります (たとえば、渡すコマンドがシェルによって正しく解釈されず、一般的なセキュリティの問題が発生する可能性があります)。 popen()
そのように設計されています。 fork
+ exec
シェルに関連する問題がなく、ソリューションはよりクリーンです。
glib の答えは、POSIX 標準 ( http://pubs.opengroup.org/onlinepubs/9699919799/functions/popen.html ) がそう言っているからです。というか、コマンド引数が解釈のために /bin/sh に渡されるかのように振る舞うべきだと言っています。
したがって、準拠する実装には、原則として、別のシェルプロセスをフォークして実行することなくシェルコマンドを解釈する内部ライブラリ関数もあると思います。私は実際にそのような実装を認識していません.すべてのコーナーケースを正しくするのはかなり難しいと思います.