システムプログラミング 情報工学科 篠埜 功 情報工学科 3 年生対象 専門科目 第5回 シェルスクリプトの続 き レポート課題 main 関数の引数 usage メッセージ
今日の内容 expr コマンド ヒアドキュメント レポート課題出題 C プログラムの main 関数の引数について Usage メッセージについて
expr 文 四則演算をシェルスクリプトで行う場合、 expr コ マンドを用いる。 expr コマンドは結果を標準出力 に出す。 (例) sh-3.2$ i=3 sh-3.2$ j=4 sh-3.2$ expr $i + $j 7 sh-3.2$ i=`expr $i + 1` sh-3.2$ echo $i 4 (注意) 演算子の左右の空白は必ず必要。 足し算 + 引き算 – かけ算 ¥* 割り算 / 剰余 %
while 文 while commands; do commands; done 構文 意味 while の隣に書かれた commands( の最後のコマン ド ) の終了 status が 0 である間 do 以下の commands を 実行。 commands: コマンドをセミコロンで区切ったもの セミコロンは改行で置き換えてよい。 while 文はコマンドであり、コマンドが書けるところには自 由に書くことができる。
while 文の例 (打ち込んで確認) #!/bin/sh i=1 while test $i -le 5 do echo test $i i=`expr $i + 1` done exit 0
ヒアドキュメント シェルスクリプト内部で、コマンドへのキーボードからの 入力を シェルスクリプト内に直接書いておくことができる。 コマンド << str ……… str のように、 << の右に区切り文字列を(自分で決めて)書き、 その次の行から、指定した文字列が最初に現れるまでの部 分を、ファイルからコマンドへ < でリダイレクトしたのと 同等の効果がある。
ヒアドキュメントの例1(打ち込んで 確認) #!/bin/sh cat << EOF hello EOF 上記のようにある程度長いメッセージ を出力したい場合、ヒアドキュメント を使うときれいに書ける。
ヒアドキュメントの例2(打ち込んで 確認) #!/bin/sh cat sample.c #include int main (void) { printf ("test\n"); return 0; } EOF gcc -o sample sample.c./sample これはシェルスクリプト内で C のファイルを作 成し、コンパイルして実行する例である。
レポート課題2 課題 2-1, 2-2, 2-3 の3つの課題(後述)の シェルスクリプトを kadai2-1.sh, kadai2- 2.sh, kadai2-3.sh というファイル名で作成 せよ。
レポートの提出方法 □ 下記のファイルを作成し、提出 kadai2-1.sh, kadai2-2.sh, kadai2-3.sh, kadai2.txt □ 提出方法 システムプログラミング講義用の課題提出用フォルダ 内にある kadai2 というフォルダの中に自分の学籍番号 を名前とするフォルダを作成し、その中に上記ファイ ルを置く。 kadai2.txt 内に学籍番号、氏名、日付、およ び作成したプログラムの簡単な説明を記載する。 □ 提出期限 11 月 13 日 23:59 まで。締め切り後に提出した場合、成 績への反映を保証しない。
課題 2-1 ファイルの存在確認は、 test コマンドを用い て、 test –f ファイル名 で行うようにせよ。コマンド “test –f ファイ ル名 ” の終了 status は、そのファイルが存在 して通常のファイルなら真、そうでなければ 偽である。 テキストファイルのファイル名をシェルスクリプトの 引数として受け取り、そのファイルが存在すればファ イルの中身を表示し、存在しない場合には、 ファイル名 : No such file exists. と表示して終了するようにせよ。実行方法は、 $./kadai2-1.sh test.txt のようにファイル名を引数として与える。この場合、 test.txt というファイルが存在すれば中身を表示する ( 表示は cat コマンドを使えばよい ) 。存在しなければ上 記のメッセージを表示する。
課題 2-2 課題 2-1 のプログラムに,引数の個数チェッ クを行う処理を追加し、ファイル名が引数 に与えられなかった場合、 $./kadai2-2.sh Usage :./kadai2-2.sh filename のようにエラーメッセージを表示するよう にせよ。 引数の個数は $# という変数に入っており、 test コマン ドで test $# -eq 0 (あるいは [ $# -eq 0 ] ) により、引数が 0 個かどうかを判定できる。 起動したコマンド名(この場合は./kadai2-2.sh )は $0 に入っているのでそれを使う。
課題 2-3 以下の例のように * で埋め尽くされた長方形を画面に表示 するシェルスクリプトを作成せよ。ただし、シェルスクリ プトの第一引数に縦の長さ、第二引数に横の長さを受け取 るようにせよ。 $./kadai2-3.sh 3 5 ***** $ echo コマンドでメッセージ表示後に改行しないようにす るには echo –n …. のようにすればよい。また、 * は特別な意味を持つので、 echo で * を表示する場合は * をダブルクォートで囲む。
C の main 関数の引数について /* コマンド名および引数を表示 */ #include int main (int argc, char *argv[ ]) { for ( ; *argv; argv++) printf ("%s\n", *argv); return 0; } $ gcc 1.c $./a.out abc 234./a.out abc 234 $ (実行例)
main 関数の第3引数 main 関数は第3引数に環境変数の情報の配列が渡される 場合がある。( ISO 規格で定められているわけではなく、 処理系依存。) #include int main (int argc, char *argv[ ], char *envp[ ]) { for ( ; *envp; envp++) printf ("%s\n", *envp); return 0; } 演習室の環境では第3引数を受け取れる。第3引数は なくてもよい。環境変数はライブラリ関数 getenv() で 取得できるのでそれを使えばよい。
スタートアップルーチン C 言語プログラムは、実行形式ファイルにするときにス タートアップルーチンとリンクされる。 スタートアップルーチンは、 /usr/lib64/crt1.o にある。 $ gcc -print-file-name=crt1.o で crt1.o の場所が表示される。 $ nm /usr/lib64/crt1.o で crt1.o の中身を確認する。この出力結果に U main という行が含まれており、スタートアップルーチンが main 関数を呼び出していることがここに反映されている。 U は main が未定義であることを表す (main 関数は別のファ イルで定義される ) 。 スタートアップルーチン部分で引数の個数、引数の文字 列配列、環境変数配列を main 関数に渡す。
コマンドのオプションについて オプションはハイフンのあとに1文字 (-o な ど ) オプションのあとにオプションの引数がある こともある – (例) gcc –o main main.c など。 いくつかのオプションをまとめて記述するこ ともある – 例 ls -la は、 ls -l -a をまとめて書いたものである 。 --help のように、ハイフンが2つの場合もあ る。(これは -h -e -l -p を -help と書いた場合 との区別のため)
Usage メッセージ (1) オプションが正しく与えられなかった場 合 (2) コマンドの引数に過不足があった場合 このような場合にメッセージを出すのが普 通。これを Usage メッセージという。 例えば、 $ cp のように cp コマンドを引数無 しで実行すると、 Usage メッセージが表 示される。
例(打ち込んで確認) /* Usage メッセージを表示するだけのプログラム */ #include int main (int argc, char * argv[]) { if (argc!=2) fprintf (stderr, "Usage: %s filename\n", argv[0]); return 0; } (実行例) $ gcc usage.c $./a.out Usage:./a.out filename