Provided by: manpages-ja-dev_0.5.0.0.20131015+dfsg-2_all
名前
system - シェルコマンドの実行
書式
#include <stdlib.h> int system(const char *command);
説明
system() は command で指定したコマンドを /bin/sh -c command の形で実行する。指定したコマ ンドが終了すればこの関数も終了する。 コマンド実行中は、 SIGCHLD はブロックされ、 SIGINT と SIGQUIT は無視される。
返り値
エラーが発生した場合 (fork(2) に失敗した場合など)、-1 を返す。 そうでなければ、コマンドの ステータスを返す。 後者の場合、ステータスは wait(2) で定義されているフォーマットで返って くる。 従って、コマンドの終了コードは WEXITSTATUS(status) で得ることが出来る。 /bin/sh が 実行出来なかった場合、 終了ステータスはコマンドが exit(127) を実行した場合と同じになる。 command の値が NULL のときは、 system() はシェルが利用可能ならゼロ以外の値を返し、利用不 可ならゼロを返す。 system() は他の子プロセスのウエイトステータスには影響を与えない。
準拠
C89, C99, POSIX.1-2001.
注意
(「どの」ヘッダファイルをインクルードするよりも前に) 機能検査マクロ _XOPEN_SOURCE が定義 された場合には、 wait(2) で説明されているマクロ群 (WEXITSTATUS() 等) が <stdlib.h> をイン クルードすると利用可能になる。 既に述べたように、 system() は SIGINT と SIGQUIT を無視する。 よってループから 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 (/bin/sh の呼び出しに失敗した時に返す値) を返すことも考えられ る。 そのため、プログラムは (リターンコードを見るだけでは) execve(2) の呼び出しが失敗し たことを確実に知ることはできない。
関連項目
sh(1), signal(2), wait(2), exec(3)
この文書について
この man ページは Linux man-pages プロジェクトのリリース 3.54 の一部 である。プロジェクト の説明とバグ報告に関する情報は http://www.kernel.org/doc/man-pages/ に書かれている。 2010-09-10 SYSTEM(3)