「sedを使ってechoコマンドを少しずつ作る」で作ったニセechoコマンドmyechoに、オプション処理を追加します。追加するオプションは、-n、改行しないオプションです。
では現在のソースを確認します。
takk@takk:~$ cat -n myecho.c 1 #include <stdio.h> 2 int 3 main (int argc, char *argv[]) 4 { 5 while (--argc) 6 printf ("%s%s", *++argv, argc == 1 ? "\n" : " "); 7 } takk@takk:~$
edを開きます。
takk@takk:~$ ed myecho.c 128
全体を表示します。さきほどのcatと同じですね。
,n 1 #include <stdio.h> 2 int 3 main (int argc, char *argv[]) 4 { 5 while (--argc) 6 printf ("%s%s", *++argv, argc == 1 ? "\n" : " "); 7 }
include行(1行目)をコピーします。
1t1
コピーされたか1〜3行目を表示してみましょう。
1,3n 1 #include <stdio.h> 2 #include <stdio.h> 3 int
新たにunistd.hをincludeしたいので、2行目のstdioをunistdに置換します。
2s/stdio/unistd #include <unistd.h>
置換されました。
次にgetoptの戻り値を格納する変数を追加します。
ついでにnオプションのフラグ変数も追加します。
3回Enterを押して、mainの後の{を見つけましょう。
int main (int argc, char *argv[]) {
ここに行を追加するため、aコマンドを使います。a、Enterと入力します。
a
変数定義を追加したら、.(ピリオド)、Enterで、入力モードを抜けます。
int nflag; .
複写しましょう。
t.
nflagをoptに置換します。
s/nflag/opt int opt;
ソース全体を見てみましょう。
,n 1 #include <stdio.h> 2 #include <unistd.h> 3 int 4 main (int argc, char *argv[]) 5 { 6 int nflag; 7 int opt; 8 while (--argc) 9 printf ("%s%s", *++argv, argc == 1 ? "\n" : " "); 10 }
次は7行目の後からgetopt処理を追加していきます。後でソース整形するので、インデントは気にせず入力します。
7a while((opt=getopt(argc,argv,"n")) != -1){ switch(opt){ case 'n': nflag=1; break; } } .
nflagの初期値を0にしておきます。
6s/;/=0;
全体を見てみましょう。
,n 1 #include <stdio.h> 2 #include <unistd.h> 3 int 4 main (int argc, char *argv[]) 5 { 6 int nflag=0; 7 int opt; 8 while((opt=getopt(argc,argv,"n")) != -1){ 9 switch(opt){ 10 case 'n': 11 nflag=1; 12 break; 13 } 14 } 15 while (--argc) 16 printf ("%s%s", *++argv, argc == 1 ? "\n" : " "); 17 }
オプション処理した分だけ、argcとargvを進めます。
14行目の後からこの処理を追加します。
14a argc-=optind; argv+=optind; .
Enterを、1回押して、次のwhile分を表示します。
while (--argc)
argcとargvを進めたので、コマンド名とオプションを含まない引数の最初からargv[0]に格納されています。argcも引数の数になっていますので、–argcをargc–、++argvもargv++に置換します。
s/--argc/argc-- while (argc--)
Enterを、1回押して、次のprintfへ。
printf ("%s%s", *++argv, argc == 1 ? "\n" : " ");
s/++argv/argv++ printf ("%s%s", *argv++, argc == 1 ? "\n" : " ");
s/1/0 printf ("%s%s", *argv++, argc == 0 ? "\n" : " ");
一旦保存してedを終了しましょう。
wq 283 takk@takk:~$
ビルドは通るでしょうか。
takk@takk:~$ gcc -o myecho myecho.c takk@takk:~$
通りました。確認します。
takk@takk:~$ ./myecho {1..10} 1 2 3 4 5 6 7 8 9 10 takk@takk:~$ ./myecho takk@takk:~$ ./myecho {1..10} -n 1 2 3 4 5 6 7 8 9 10 takk@takk:~$
おっと、肝心な-nオプションの処理を忘れてしました。
再度edでmyecho.cを開きます。
takk@takk:~$ ed myecho.c 283
printfの行を表示します。pr,Enterと入力。
/pr printf ("%s%s", *argv++, argc == 0 ? "\n" : " ");
nオプションが指定されたら改行しないようにする修正です。
s/argc/(nflag == 0 \&\& argc printf ("%s%s", *argv++, (nflag == 0 && argc == 0 ? "\n" : " "); s/0 ?/0) ? printf ("%s%s", *argv++, (nflag == 0 && argc == 0) ? "\n" : " "); wq 299
ビルドして確認しましょう。
takk@takk:~$ !gc gcc -o myecho myecho.c takk@takk:~$ ./myecho {1.10} {1.10} takk@takk:~$ !! -n ./myecho {1.10} -n {1.10} takk@takk:~$
うまく-nオプションが効きました。
コメント