Presentation is loading. Please wait.

Presentation is loading. Please wait.

システムプログラミング 第3回、第4回、第5回、第6回 情報工学科 篠埜 功 makeコマンド 動的リンクライブラリ シェルスクリプト

Similar presentations


Presentation on theme: "システムプログラミング 第3回、第4回、第5回、第6回 情報工学科 篠埜 功 makeコマンド 動的リンクライブラリ シェルスクリプト"— Presentation transcript:

1 システムプログラミング 第3回、第4回、第5回、第6回 情報工学科 篠埜 功 makeコマンド 動的リンクライブラリ シェルスクリプト
情報工学科 3年生対象 専門科目 システムプログラミング 第3回、第4回、第5回、第6回 makeコマンド 動的リンクライブラリ シェルスクリプト 情報工学科 篠埜 功

2 開発支援ツール make コンパイルを要するソースファイルの数が多くなった場合,手間がかかる
1つのヘッダファイルを複数のソースファイルで使用している場合,ヘッダファイルの修正→ 関連する全てのソースファイルの際コンパイル makeを使用 ファイルの変更をした場合、その影響を受けるファイルを再コンパイルする。(不要な再コンパイルをしない) ファイルの日付情報を用いる。

3 Makefile (例) ファイルの作成方法を記述したルール main : main.o add.o mult.o
コロンの右にコロンの左のファイルを作るために必要なファイルをスペースで区切って並べる 次の行以下にそのファイルを作るためのコマンドをTABキーを押したあとに記述。2つ以上のコマンドを書いてもよい。 (例) main : main.o add.o mult.o gcc -o main main.o add.o mult.o main.o : main.c addmult.h gcc -c main.c add.o : add.c gcc -c add.c mult.o : mult.c gcc -c mult.c TAB

4 make さきほどの例を内容とするMakefileというファイルを作成し、 main : main.o add.o mult.o
gcc -o main main.o add.o mult.o main.o : main.c addmult.h gcc -c main.c add.o : add.c gcc -c add.c mult.o : mult.c gcc -c mult.c

5 make さきほどの例で、add.cやaddmult.hなど、ソースファイルの内容を変更し(スペースやコメントを入れるなど)、 $ make
を実行して何が起きるか確認せよ。 (参考) touchコマンドを使うと、中身を変えずにファイルの時刻情報のみ更新できる。 $ touch add.c など。

6 make main : main.o add.o mult.o gcc -o main main.o add.o mult.o
$ make add.o などと、コロンの左側のものをmakeの引数に与えると、それを作成しようとする。 main : main.o add.o mult.o gcc -o main main.o add.o mult.o main.o : main.c addmult.h gcc -c main.c add.o : add.c gcc -c add.c mult.o : mult.c gcc -c mult.c

7 Makefile test1: ls –l test2: ps –ef | grep sasano $ make test1
コロンの左に書くのはファイル名でなくてもよい。 test1: ls –l test2: ps –ef | grep sasano $ make test1 とするとファイル一覧が表示され、 $ make test2 とするとプロセス一覧からsasanoを含む行を抜き出したものが表示される。

8 make main : main.o add.o mult.o gcc -o main main.o add.o mult.o
clean というターゲットを作っておき、実行コマンドとして不要なファイルを削除するコマンドを書いておくということがよく行われる。 $ make clean とすると、ソースファイルではないファイルが削除されてディレクトリがきれいになる。 main : main.o add.o mult.o gcc -o main main.o add.o mult.o main.o : main.c addmult.h gcc -c main.c add.o : add.c gcc -c add.c mult.o : mult.c gcc -c mult.c clean : rm –f main main.o add.o mult.o rm に-fオプションは強制削除のオプションであり、存在しないファイルが引数にあたえられてもメッセージが出ない。

9 Makefileの名前について Makefileの名前は”Makefile”でなくてよい。
makeコマンド(GNU make)はdefaultでは”GNUmakefile”, “makefile”, “Makefile”をこの順で探し、最初に見つかったもので実行する。これ以外のものを使いたい場合は-fオプションで指定する。たとえばmyMakefileという名前でMakefileを作成したときは、 $ make –f myMakefile のように実行すればよい。

10 練習問題 前回のlibaddmult.aを作ってからmainを作成する手順をmakeコマンドで行えるようにMakefileを作成せよ。

11 マニュアル表示コマンド man (例) gcc, ar, makeコマンドについて調べたい $ man gcc $ man ar
$ man make コマンドの処理内容,様々なオプションの解説が書かれている。 manコマンドについては $ man man で調べる。

12 共有ライブラリ(shared library)
動的リンクライブラリ(dynamic link library)とも言う。 実行形式ファイルにはライブラリの中身は含まれず、実行時にリンクされる。 実行形式ファイルのサイズの削減 ライブラリを修正する場合、ライブラリファイルのみ修正すればよく、リンク作業が不要。

13 共有ライブラリ作成例 さきほどのadd, mult関数の例で共有ライブラリを作成する。
$ gcc –shared –o libaddmult.so add.c mult.c これでadd, mult関数が共有ライブラリとしてlibaddmult.soに作成される。 $ gcc –L. –o main main.c –laddmult (あるいは $ gcc –o main main.c libaddmult.so と明示的に指定) これでlibaddmult.soが実行時にリンクされるようになる。  $ ./main を実行する前に、 $ setenv LD_LIBRARY_PATH . を実行しておく。(シェルがtcshの場合。シェルがbashの場合は、 $ LD_LIBRARY_PATH=.; export LD_LIBRARY_PATH とする。) add.cを変更してlibaddmult.soを作り直し、mainを実行すると、mainを作成しなおさなくても変更が反映されていることが分かる。  $ ldd main (lddはlist dynamic depencenciesの略) で、mainが動的にリンクするファイル一覧が表示される。

14 補足 -lxxx でリンクする際には、libxxx.soが先に検索される。
(例)/usr/lib/libm.so, /usr/lib/libm.aのように両方ある場合は/usr/lib/libm.soが(defaultで)使われる。

15 レポート課題1 配列を関数に渡すとき、長さをもう一つの引数として渡す。
長さnのint型の配列の各要素に1から100までの整数をランダムに作成して代入する関数randAssignを定義したファイルrandAssign.c 長さnのint型の配列を受け取り、要素を小さい順に並べ替える関数sortを定義したファイルsort.c randAssign関数のプロトタイプ宣言を記述したファイルrandAssign.h sort関数のプロトタイプ宣言を記述したファイルsort.h 以下の内容のmain関数を記述したmain.c 長さnの配列を作成し、それをrandAssign関数に渡して整数をランダムに格納させ、sort関数に渡してソートをさせ、その結果を画面に出力するプログラム。長さnの値はmain.cに直接書いてよい。キーボードから入力するようにしてもよい。 main関数の先頭部分でrandAssign.h, sort.hを読み込む。 Makefile 実行形式ファイル(mainとする)をmakeコマンドで作成できるように作成する。 配列を関数に渡すとき、長さをもう一つの引数として渡す。

16 レポートの提出方法 □ 下記のファイルを作成し、提出
randAssign.c, randAssign.h, sort.c, sort.h, main.c, Makefile, kadai1.txt □ 提出方法 システムプログラミング講義用の課題提出用フォルダ内にあるkadai1というフォルダの中に自分の学籍番号を名前とするフォルダを作成し、その中に上記ファイルを置く。kadai1.txt内に学籍番号、氏名、日付、および作成したプログラムの簡単な説明を記載する。 □ 提出期限   10月27日の講義開始時間まで。締め切り後に提出した場合、成績への反映を保証しない。 □ アーカイブを作る必要はありません(作ってもいいですが)。 □ 動的リンクにするか静的リンクにするかについても自由。

17 前回の補足 共有ライブラリを作る時、gccのオプションで-fPICをつけた方がよい。 (例)
$ gcc –fPIC -shared –o libaddmult.so add.c mult.c その他の部分は同じ。

18 シェルスクリプト シェルに対する命令をファイルに記述したもの シェルとは
コマンドインタプリタ。UNIX系OSではシェルはユーザプログラムであり、自分でシェルを作成することもできる。

19 シェル(/bin/sh)に直接打ち込む例
~]$ sh sh-2.05b$ A=ls sh-2.05b$ $A <lsの実行結果> sh-2.05b$ シェルスクリプトは、シェル(通常は/bin/sh)に対する命令列をファイルに格納したものである。ここではファイルに入れずにシェル(/bin/sh)上で直接実行してみる。 (補足) shと打つことによって、shというファイルが環境変数PATHに入っているディレクトリから検索され、その結果/bin/shが見つかり、それが実行される。 A=ls などのように、変数名=文字列 の形で、変数を定義できる。=の前後にスペースを入れてはいけない。スペースを入れると、この場合、Aをコマンド名として解釈しようとしてcommand not foundになる。 変数の値の参照は、$変数名とすればよい。

20 (参考) /bin/tcshの場合 [sasano@oli004 4kai]$ set A=ls
4kai]$ $A <lsの実行結果が表示される> 4kai]$ /bin/tcsh では、上記のように、set A=lsの形で、setコマンドを用いてシェル変数を定義する。(ここでは=の前後にスペースがあってもよい。) シェル変数の一覧は $ set で画面に表示される。(shでもsetで一覧表示。)

21 環境変数 /bin/shや/bin/bashの場合: $ export シェル変数名
のようにすることにより、シェル変数が同一の変数名で環境変数となる。たとえば、 $ A=test $ export A など。環境変数の一覧は $ printenv で表示される。個々の環境変数の値は $ printenv A のように、環境変数名をprintenvコマンドの引数に与えると表示される。 /bin/tcshの場合: $ setenv A test のように、setenvコマンドを用いる。(=はないことに注意) 環境変数一覧、個々の値の表示については/bin/shと同じ。環境変数の値も$環境変数名で参照できるが、同じ名前のシェル変数がある場合、そちらが優先される。

22 環境変数の例 dateコマンド(日時の表示)を実行すると [sasano@oli004 4kai]$ date
2009年 10月 6日 火曜日 13:45:42 JST のようになるが、 4kai]$ setenv LANG C のようにすると、 Tue Oct 6 13:47:27 JST 2009 のように英語表示になる。 (/bin/shの場合は、LANG=Cとしてからdateを実行すればよい)

23 シェル変数の例 PATH, HOME, USER, HOSTNAMEなどのシェル変数が通常使われている。 $ echo $PATH
$ echo $HOME $ echo $USER $ echo $HOSTNAME などで確認できる。 /bin/shでも/bin/tcshでも同じ。

24 シェルスクリプト ファイルにシェルに対する命令(スクリプト)を書いたもの。
1行目に#!/bin/sh と書く。これによって、/bin/shがスクリプトを実行することになる。 #!/bin/bash, #!/bin/tcshなど、他のシェルを指定してもよいが、その場合はスクリプトの書き方は異なる。 ファイルの属性を、実行を許可するように変更する必要がある。 $ chmod 755 test.sh などのようにして変更できる。

25 例1(打ち込んで確認) (1)以下を中身とするtest1.shというファイルを作成 #!/bin/sh ls -l
(2)ファイルの属性を変更 $ chmod 755 test1.sh (3)実行 $ ./test1.sh これによって、ls –lが実行される。あるいは、 $ /bin/sh test1.sh でもよい。 (4) カレントディレクトリのファイルリストが表示されることを確認。

26 シェル変数の使用(打ち込んで確認) (1)以下を中身とするtest2.shというファイルを作成 #!/bin/sh A=ls B=-l
$A $B (2)ファイルの属性を変更 $ chmod 755 test2.sh (3) 実行 $ ./test2.sh (4) カレントディレクトリのファイルリストが表示されることを確認。(例1と同じ)

27 for文(例1)(打ち込んで確認) #!/bin/sh for i in 1 2 4 1 do 2 echo $i 4 done
と表示されればOK。 echoは引数に与えられた文字列を表示するコマンド。$iが文字列に展開されてから表示される。

28 for文の構文、意味 構文 for variable in wordlists; do commands; done
wordlistsの要素を左から順番に変数variableに代入し、commandsを実行する。 セミコロンは改行で置き換えてよい。 for文はコマンドであり、コマンドが書けるところには自由に書くことができる。例えばfor文の本体部分にfor文を書いてもよい。

29 for文の例2(打ち込んで確認) #!/bin/sh バッククオート`でコマンドを囲むと、その部分がコマンドの実行結果で置き換えられる。
for D in `date` do echo $D done バッククオート`でコマンドを囲むと、その部分がコマンドの実行結果で置き換えられる。 dateコマンの出力結果にはスペースが含まれており、スペースで区切られた一つ一つがDに代入され、echoで1つずつ表示される。

30 for文の例3(打ち込んで確認) #!/bin/sh *はカレントディレクトリのファイルがスペースで区切られたものに展開される。
for L in * do echo $L done *はカレントディレクトリのファイルがスペースで区切られたものに展開される。 $ echo * で確認できる。 Lにはカレントディレクトリのファイル名が一つずつ代入され、それがechoで表示される。

31 for文の例4(打ち込んで確認) #!/bin/sh
for F in * do cp $F $F.bak done Fにはカレントディレクトリのファイルのファイル名が一つずつ代入され、それがcpで.bakつきのファイルにコピーされる。

32 for文の例5(打ち込んで確認) #!/bin/sh for F in *.c do echo $F cp $F $F.bak done
*.cは、カレントディレクトリにおいて、ファイル名の最後の部分が.cになっているファイルのファイル名がスペースで区切られたものに展開される。 Fにはカレントディレクトリの.cで終わるファイル名が一つずつ代入され、それがechoで表示されたのち、.bakつきのファイルにコピーされる。 第一回目に書いたシェルスクリプトは、上記のシェルスクリプトの最後にexit 0を加えたもの。

33 if文 構文 if condition; then commands; [elif condition; then commands;]… [else commands;] fi condition: 条件 commands: コマンドをセミコロンで区切る。 [ ] はオプション(なくてもよいという意味)。 conditionの終了statusが0なら真、0以外は偽。 意味 conditionの終了statusが0ならthenパートを実行。そうでなければelif以下、あるいはelseパートを(もしあれば)実行。 セミコロンは改行で置き換えてよい。 if文はコマンドであり、コマンドが書けるところには自由に書くことができる。例えばif文のelseパートにif文を書いてもよい。

34 終了status コマンドは終了statusを返す。
シェルスクリプトではexit 0 等、exitの右に書く数によって終了statusを指定する。 Cのプログラムでは、main関数のreturn文あるいはexitシステムコールの引数によって終了statusを指定する。 コマンドの終了statusはシェルが受け取り、$?という変数に保持している。 (例) $ ls aaa $ echo $? もしaaaというファイルがなければlsコマンドの終了statusが1になっている。

35 if文の例1(打ち込んで確認) #!/bin/sh if test $1 -le $2 then
echo $1 is less than or equal to $2. else echo $1 is greater than $2. fi testは比較などさまざまな判定を行うコマンド。オプションによりさまざまな判定が行える。 test arg1 –le arg2 は、arg1がarg2より小さいかどうか判定。 $1はシェルスクリプトの1番目の引数、 $2はシェルスクリプトの2番目の引数を表す。

36 if文の例2(打ち込んで確認) #!/bin/sh if diff $1 $2 > /dev/null then
echo No differences were found between $1 and $2. else echo Some differences were found between $1 and $2. fi diffは2つのファイルの比較を行うコマンド。 終了statusは、同じとき0, 異なるとき1である。 diffコマンドの標準出力への出力は/dev/nullへリダイレクトされるので捨てられる。(リダイレクトについて後日解説する)

37 testコマンドについて testコマンドは大小比較などさまざまな判定に使われる。
数値比較、文字列比較、ファイル形式の判定、ファイルの修正時刻の比較などがある。さらに、条件をand, or, notで組み合わせることもできる。 testコマンドは非常によく使われるので略記法がある。 test …は [ … ] と略記してよい。 例えば、test $1 –le $2は、[ $1 –le $2 ]と書ける。 [の次の空白と、]の手前の空白は省けないので注意。

38 if文の例3(打ち込んで確認) #!/bin/sh if [ $1 -le $2 ] then
echo $1 is less than or equal to $2. else echo $1 is greater than $2. fi 例1におけるtest $1 –le $2を[ $1 –le $2 ]で置き換えたもの。

39 ヒアドキュメント シェルスクリプト内部で、コマンドへのキーボードからの入力を シェルスクリプト内に直接書いておくことができる。
コマンド << str ……… str のように、<<の右に区切り文字列を(自分で決めて)書き、その次の行から、指定した文字列が最初に現れるまでの部分を、ファイルからコマンドへ < でリダイレクトしたのと同等の効果がある。

40 ヒアドキュメントの例1(打ち込んで確認) #!/bin/sh cat << EOF <html>
<body> hello </body> </html> EOF 上記のようにある程度長いメッセージを出力したい場合、ヒアドキュメントを使うときれいに書ける。

41 ヒアドキュメントの例2(打ち込んで確認) #!/bin/sh cat << EOF > sample.c
#include <stdio.h> int main (void) { printf ("test\n"); return 0; } EOF gcc -o sample sample.c ./sample これはシェルスクリプト内でCのファイルを作成し、コンパイルして実行する例である。

42 レポート課題2 課題2-1, 2-2, 2-3の3つの課題(後述)のシェルスクリプトをkadai2-1.sh, kadai2-2.sh, kadai2-3.shというファイル名で作成せよ。

43 レポートの提出方法 □ 下記のファイルを作成し、提出
kadai2-1.sh, kadai2-2.sh, kadai2-3.sh, kadai2.txt □ 提出方法 システムプログラミング講義用の課題提出用フォルダ内にあるkadai2というフォルダの中に自分の学籍番号を名前とするフォルダを作成し、その中に上記ファイルを置く。kadai2.txt内に学籍番号、氏名、日付、および作成したプログラムの簡単な説明を記載する。 □ 提出期限   11月17日の講義開始時間まで。締め切り後に提出した場合、成績への反映を保証しない。

44 課題2-1 テキストファイルのファイル名をシェルスクリプトの引数として受け取り、そのファイルが存在すればファイルの中身を表示し、存在しない場合には、   ファイル名: No such file exists. と表示して終了するようにせよ。実行方法は、 $ ./kadai2-1.sh test.txt のようにファイル名を引数として与える。この場合、test.txtというファイルが存在すれば中身を表示する(表示はcatコマンドを使えばよい)。存在しなければ上記のメッセージを表示する。 ファイルの存在確認は、testコマンドを用いて、 test –f ファイル名 で行うようにせよ。コマンド “test –f ファイル名” の終了statusは、そのファイルが存在して通常のファイルなら真、そうでなければ偽である。

45 課題2-2 課題2-1のプログラムに,引数の個数チェックを行う処理を追加し、ファイル名が引数に与えられなかった場合、
$ ./kadai2-2.sh Usage:./kadai2-2.sh filename のようにエラーメッセージを表示するようにせよ。 引数の個数は$#という変数に入っており、testコマンドで test $# -eq 0 (あるいは [ $# -eq 0 ]) により、引数が0個かどうかを判定できる。 起動したコマンド名(この場合は./kadai2-2.sh)は$0に入っているのでそれを使う。

46 課題2-3 テキストファイルのファイル名とキーワードをキーボードから受け取り、指定した文字列を含む行を表示するシェルスクリプトをgrepコマンドを用いて作成せよ。 (実行例) text.txtのファイルの中にThis is a test. という行がある場合、 $ ./kadai2-3.sh Enter filename: test.txt Enter keyword: es This is a test. キーボードからの入力はreadコマンドで受け取る。 (例) read x とすると、変数xにキーボードからの入力が入る。 メッセージ表示後に改行しないようにするには echo –n …. のようにすればよい。表示する文字列の最後に空白を入れたい場合、表示する文字列を””で囲めばよい。 赤字の部分はキーボードからの入力

47 補足1 前回紹介したifコマンドはネストしてよい。例えば、elseパート有りのifコマンドをネストして、 if … then … else

48 補足2 さきほどのifコマンドのネストは のように書いてもよい。この場合はifコマンドのネストではなく、1つのifコマンドである。 if …
then elif … else fi のように書いてもよい。この場合はifコマンドのネストではなく、1つのifコマンドである。


Download ppt "システムプログラミング 第3回、第4回、第5回、第6回 情報工学科 篠埜 功 makeコマンド 動的リンクライブラリ シェルスクリプト"

Similar presentations


Ads by Google