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)