基本的な使い方
system()関数は、引数に文字列で渡したコマンドやシェルスクリプトをシェル(通常 /bin/sh)経由で実行するために使われます。
たとえば system("ls") とすれば、ターミナル上で ls を実行するのと同じような結果になります。
以下は、hello.sh というシェルスクリプトを実行するサンプルです。サンプルコードをコンパイルして実行すると、次のような出力が得られます。
出力
シェルスクリプト hello.sh を実行します:
Hello from shell script!
Sun May 18 05:33:04 UTC 2025
system() の戻り値: 0
<サンプルコード>
hello.sh
#!/bin/sh
echo "Hello from shell script!"
date
sample.c
#include <stdio.h>
#include <stdlib.h>
int main() {
printf("シェルスクリプト hello.sh を実行します:\n");
int status = system("./hello.sh");
printf("\nsystem() の戻り値: %d\n", status);
return 0;
}
エラーになるパターン
system()
関数に類似した関数としてexecvp()
関数 がありますが、以下のような違いがあります。
-
execvp()
:コマンドとコマンドライン引数を分けて指定できる。 -
system()
:コマンドとコマンドライン引数を1つの文字列として渡す必要がある(分離不可)。
そのため、以下に示すコード内のNGのような書き方をするとコンパイルエラーが発生します。
info.c
#include <stdio.h>
#include <unistd.h>
int main() {
char *args[] = {"./info.sh", "Alice", "25", "Tokyo", NULL};
execvp("./info.sh", args); // OK
system(args); // NG
// execvpが失敗した場合のみここに来る
perror("execvp failed");
return 1;
}
コンパイル
[root@85110ffae5b1 workspace]# gcc -g info.c -o info
execvp_info.c: In function ‘main’:
execvp_info.c:9:12: warning: passing argument 1 of ‘system’ from incompatible pointer type [-Wincompatible-pointer-types]
system(args);
^~~~
In file included from execvp_info.c:2:
/usr/include/stdlib.h:781:32: note: expected ‘const char *’ but argument is of type ‘char **’
extern int system (const char *__command) __wur;
~~~~~~~~~~~~^~~~~~~~~
複数のパラメーターを渡したい場合
上記のことから、system()
関数には以下のようにコマンドとコマンドライン引数を1つの文字列として渡します。
system_info.c
#include <stdio.h>
#include <stdlib.h>
int main() {
const char *name = "Alice";
const char *age = "25";
const char *city = "Tokyo";
char command[256];
// コマンドを文字列として組み立てる(引数付き)
snprintf(command, sizeof(command), "./info.sh %s %s %s", name, age, city);
printf("実行するコマンド: %s\n", command);
int status = system(command);
printf("system() の戻り値: %d\n", status);
return 0;
}
実行結果
root@85110ffae5b1 workspace]# ./system_info
実行するコマンド: ./info.sh Alice 25 Tokyo
Name: Alice
Age: 25
City: Tokyo
system() の戻り値: 0
以上です。最後までお読みいただきありがとうございました!