Provided by: manpages-ja-dev_0.5.0.0.20180315+dfsg-1_all bug

名前

       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()  の返り値は、子プ
       ロセスでシェルが実行できなかった場合と区別できない。

関連項目

       sh(1), sigaction(2), sigprocmask(2), fork(2), wait(2), exec(3), signal(7)

この文書について

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

                                            2014-06-13                                  SYSTEM(3)