% cp file1.txt file2.txtのようにコマンドを実行するとき、file1.txt, file2.txtの ような引数を取ることがあるが、それをC言語で処理する方法がある。
(余談) なお、我々がよく実行する「./a.out」と、上の「cp」などのコマンドの間に 質的な違いはなく、どちらも実行ファイルである。cpコマンドの実体のありかは 「which cp」とすれば分かり、大抵は「/bin/cp」にある。 cpなどのコマンドが「./」を付けなくても実行できるのは、 ディレクトリ「/bin」が「パス」に登録されているため。パスは 「echo $PATH」などとすると見ることが出来る。
int main(void) { ... ... }のように書いていたが、引数を処理したい場合は
int main(int argc, char *argv[]) { ... ... }のように書く。
後者の書き方の場合、
#include <stdio.h> int main(int argc, char *argv[]) { int i; for (i=0; i<argc; i++) { printf("%s\n", argv[i]); } return 0; } |
% ./showargv hoge fuga ./showargv hoge fuga %のようになる。
(余談)
#include <stdio.h> int main(int argc, char *argv[]) { while (*argv != NULL) { printf("%s\n", *(argv++)); } return 0; } |
これを使った、例えばcatコマンドとほぼ同じ動作をするプログラムは、 次の通り。
#include <stdio.h> int main(int argc, char *argv[]) { int i, c; FILE *fp; for (i=1; i<argc; i++) { fp = fopen(argv[i], "r"); if (fp == NULL) { fprintf(stderr, "%s: No such file or directory\n", argv[i]); continue; } while (1) { c = getc(fp); if (c == EOF) break; putchar(c); } fclose(fp); } return 0; } |
このように、UNIXのコマンドは非常に簡単なCのプログラムで作られているものも多い。
int main(void) { ... ... return 0; }のように無条件で0を返すようなプログラムを書いていた。
慣習として、 そのプログラムが正常に終了した場合は0、何か異常が 発生して正常に終了しなかった場合は0以外の値を返すことになっている。
int main(void) { ... ... if (...) { fprintf(stderr, "error!\n"); return 1; } ... ... return 0; }のような感じ。
(以下はあまり理解出来なくてもよい。CというよりはOSの使い方の問題なので。)
これにどんな意味があるかと言えば、 shell scriptの中でその値(終了コード)を利用することが出来る。 例えば、 error0.c、 error1.cの2つを使って、
#! /bin/sh ./error0 echo $? ./error1 echo $?のようなshell scriptを実行すると、
0 1と表示され、$?で終了コードを参照できていることが分かる。