Linux repositories inspector
2014-06-13

manpages-ja-dev

Japanese version of the manual pages (for developers)

man-pages-ja

Japanese man (manual) pages from the Japanese Manual Project

manpages-dev

Manual pages about using GNU/Linux for development

man-pages

Linux kernel and C library user-space interface documentation

名前

system - シェルコマンドの実行

書式

#include <stdlib.h>

int system(const char *command);

説明

system() ライブラリ関数は、fork(2) を使って子プロセスを作成し、その子プロセスは以下のように command で指定されたシェルコマンドを execl(3) を使って実行する。
execl("/bin/sh", "sh", "-c", command, (char *) 0);
system() が返るのはコマンドが完了した後である。
コマンドの実行中は、 system() を呼び出したプロセスでは、 SIGCHLD はブロックされ、 SIGINTSIGQUIT は無視される (command を実行する子プロセスでは、これらのシグナルはデフォルトの処理方法にしたがって処理される)。
command が NULL の場合、 system() はそのシステムでシェルが利用可能かを示すステータスを返す。

返り値

system() の返り値は以下のいずれかである。
* command が NULL の場合、 シェルが利用可能ならゼロ以外の値、利用不可なら 0。
* 子プロセスを作成できなかった場合、または子プロセスのステータスを取得できなかった場合、 返り値は -1 である。
* 子プロセスでシェルを実行できなかった場合、 返り値は子プロセスがステータス 127 で _exit(2) を呼び出して終了したのと同じになる。
* システムコールがすべて成功した場合、 返り値は command を実行するのに使用された子プロセスのシェルの終了ステータスとなる (シェルの終了ステータスはそのシェルが実行した最後のコマンドの終了ステータスである)。
最後の 2 つの場合、返り値は "wait status" であり、 waitpid(2) に書かれているマクロ (つまり WIFEXITED() や WEXITSTATUS() などのマクロ) を使って検査することができる。
system() は他の子プロセスのウエイトステータスには影響を与えない。

属性

マルチスレッディング (pthreads(7) 参照)

関数 system() はスレッドセーフである。

準拠

C89, C99, POSIX.1-2001.

注意

system() により簡便性と利便性がもたらされる。この関数は fork(2), execl(3), waitpid(2) の呼び出しにおける詳細をすべて行うとともに、 シグナルの適切な処理も行う。 また、シェルは command に対して通常の置換 (substitutions) と I/O リダイレクトを行う。 system() を使用することによる主なコストは非効率性である。 シェルを実行するプロセスを作成するためとそのシェルを実行するために、余計にシステムコールが必要となる。
(「どの」ヘッダーファイルをインクルードするよりも前に) 機能検査マクロ _XOPEN_SOURCE が定義された場合には、 waitpid(2) で説明されているマクロ群 (WEXITSTATUS() 等) が <stdlib.h> をインクルードすると利用可能になる。
既に述べたように、 system() は SIGINTSIGQUIT を無視する。 よってループから system() を呼ぶプログラムは、 以下の例のように子プロセスの終了状態を自分でチェックしておかないと、 中断できなくなるかもしれない。

while (something) { int ret = system("foo");
if (WIFSIGNALED(ret) && (WTERMSIG(ret) == SIGINT || WTERMSIG(ret) == SIGQUIT)) break; }
set-user-ID や set-group-ID の特権をもつプログラムの中では system() を使ってはいけない。なぜなら、ある環境変数の未知の値によって システムの安全が損なわれるからである。代わりに exec(3) 関連の関数群の中で execlp(3) と execvp(3) 以外の関数を使用すべきである。 実際のところ、 system() は /bin/sh が bash バージョン 2 であるシステムでは、 set-user-ID や set-group-ID の特権を持つプログラムからは正しく動作しない。 なぜなら、bash バージョン 2 はスタートアップ時に特権を落とすからである。 (Debian では、sh として起動された時にはこのような動作を行なわないように 修正された bash を用いている)
glibc 2.1.3 より前のバージョンでは、 command が NULL の場合に /bin/sh が利用可能かどうかのチェックは実際には行わず、 いつでも利用可能であるとみなしていた。 system() はこの場合に常に 1 を返していた。 POSIX.1-2001 ではシェルが提供されているという標準に準拠した実装を 要求しているが、glibc 2.1.3 以降ではシェルのチェックを実行している。 なぜなら、呼び出し元のプログラムが system() を呼び出すより前に (POSIX.1-2001 では規定されていない) chroot(2) を呼び出していた時には、シェルが利用可能でない場合や実行可能ファイル でない場合があるからである。
シェルコマンドがステータス 127 で終了することもある。 この場合、system() の返り値は、子プロセスでシェルが実行できなかった場合と区別できない。

この文書について

この man ページは Linux man-pages プロジェクトのリリース 3.79 の一部 である。プロジェクトの説明とバグ報告に関する情報は http://www.kernel.org/doc/man-pages/ に書かれている。
⇧ Top