電 子 計 算 機 基 礎 論 実 習 計 算 機 基 礎 論 3 B 金沢大学理学部数学教室 1996年05月22日(水) 44.はじめに このプリントは5月29日分のつもりですが,5月22日にやっても構いません。 前々回まではパソコンで MS-DOS を使い,前回は数学教室の WS で電子メールの練習な どをしました。今回は,unix におけるファイル・ディレクトリ操作と,パソコンと WS との間でのファイル転送について学びます。 その前に訂正と補足です。 その1.sieve.c では「int a[10000+1];」を main() の前に書きましたが,それ以外の プログラムでは変数の宣言は main や他の関数の第一行目にありました。その点を説明 するのを忘れていましたので,次のひな型で説明します。 int a[10000+1]; /* この変数は main でも f でも使える */ int main() { int i; /* この変数は main の中でのみ使える */ .... } int f(int n) { int i, p; /* この変数は f の中でのみ使える */ .... } この点からすれば sieve.c の「int a[10000+1];」は main の中に置いてもよかったの ですが,非常に大量の変数を関数の中で宣言するとスタックオーバーフローという現象 が起きてプログラムが正しく動かない場合があるのです。 いまのところは,大量の変数のみ main の外側で宣言する,と理解しておけばいいでし ょう。 その2.前回のプリントで「ユーザ ID」と書いたのは全て「ユーザ名」の間違いでし た。「ユーザ ID」というものは別にあります。 その3.プリント 33 ページの最後に 「.kanazawa-u.ac.jp」を取り除いたものを「~t」のあとに書くようにしないとメ ールが着かない。これはバグである。 と書いたのは 「.s.kanazawa-u.ac.jp」を取り除いたものを「~t」のあとに書くようにしないと メールが着かない。これはバグである。 の誤りでした。すみません。訂正しておいてください。 - 34 - 45.unix の階層ディレクトリ構造 WS ではディスクの中に大量のファイルが置かれますので,ディスクを小部屋のように区 切って使っています。その一つ一つが「ディレクトリ」です。ディレクトリはツリー状 につながっています。 数学教室の WS のディレクトリ構造の一部を示します。 / -+- etc | +- home -+- member -+- iwase | +- student | +- ugrad -+- zzh00000 --- mail | +- zzj95... --- mail | 一番左の「/」は「ルート」あるいは「ルートディレクトリ」と呼ばれ,根にあたりま す。そのすぐ下に etc や home があり,home の下には member, student, ugrad があ る,という具合です。 ※ なぜかルートの方向を上,その反対方向を下という習慣になっている。:-) ルート以外のディレクトリを「サブディレクトリ」と呼ぶことがあります。 WS を使っているときには常にどこか一つのディレクトリが「カレントディレクトリ」に なっています。 ugrad の下にはみなさんのユーザ名を名前にもつディレクトリがあり,ログインした直 後にはそこがカレントディレクトリになるよう設定してあります。そこを「ホームディ レクトリ」といいます。そこにはみなさんのアカウントのための初期設定ファイル,前 回の課題で作ってもらった profile というファイルなどが置かれています。 ディレクトリやファイルの指定のしかたには「絶対パス指定」と「相対パス指定」の二 つがあります。 「/」で始まれば絶対パス指定です。/home/ugrad/zzh00000 は上の図に出ているディレ クトリの例,/home/ugrad/zzh00000/profile はそのディレクトリに置かれたファイルの 例です。(後者は上の図には書かれてはいません。) 「/」で始まっていなければカレントディレクトリからの相対パス指定です。例えばカレ ントディレクトリが /home/ugrad のとき,zzh00000/profile はいま上で説明したファ イルを指します。 いくつかのディレクトリ名は特別な意味をもっています。 . カレントディレクトリ .. 親ディレクトリ(一つ上のディレクトリ) ~ 自分のホームディレクトリ ~username そのユーザのホームディレクトリ 例えばみなさんのホームディレクトリがカレントディレクトリのとき,「..」は /home/ugrad を表わし,「../zzh00000」は /home/ugrad/zzh00000 を表わします。 また,「~/mail」は自分のホームディレクトリの下の mail というディレクトリ, 「~zzh00000/profile」はユーザ zzh00000 のホームディレクトリにある profile とい うファイルを表わします。 - 35 - 46.unix のディレクトリ操作のコマンド 「pwd」はカレントディレクトリを表示させるコマンドです。 「cd」はディレクトリを移るときのコマンドです。下の例で一般の場合を推測して理解 してください。 「cd /home/ugrad」 そのディレクトリに移る(絶対パス指定) 「cd mail」 そのディレクトリに移る(相対パス指定) 「cd ..」 親ディレクトリに移る 「cd」 自分のホームディレクトリに帰る 「cd ~」 自分のホームディレクトリに帰る 「cd ~username」 そのユーザのホームディレクトリに移る 「mkdir dirname」で,カレントディレクトリのすぐ下に dirname というサブディレク トリを新しく作ります。 ※ カレントディレクトリに書き込みパーミッション(後述)がないと作れない。さ しあたってはホームディレクトリで実験するとよい。 「rmdir dirname」で,カレントディレクトリのすぐ下のサブディレクトリ dirname を 削除します。 ※ もしもディレクトリが空でないと警告が出て削除は行なわれない。 「mv olddirname newdirname」で,カレントディレクトリのすぐ下のサブディレクトリ olddirname を newdirname という名前に改名します。 47.unix のファイル操作コマンド(ls, cp, mv, rm, cat, more) 「ls」は,カレントディレクトリのファイル一覧を見るコマンドです。 total 13 drwxr-xr-x 3 zzj88023 ugrad 512 May 11 16:00 ./ drwxr-xr-x 86 root daemon 2048 May 15 12:39 ../ -rw-r--r-- 1 zzj88023 ugrad 2999 May 11 16:00 .cshrc -rw-r--r-- 1 zzj88023 ugrad 29 May 11 16:00 .emacs -rw-r--r-- 1 zzj88023 ugrad 2574 May 11 16:00 .login -rw-r--r-- 1 zzj88023 ugrad 645 May 11 16:00 .logout -rw-r--r-- 1 zzj88023 ugrad 350 May 11 16:00 .mailrc -rwxr-xr-x 1 zzj88023 ugrad 24576 May 15 11:16 a.out* drwx------ 2 zzj88023 ugrad 512 May 11 16:00 mail/ -rw-r--r-- 1 zzj88023 ugrad 115 May 15 11:00 profile -rw-r--r-- 1 zzj88023 ugrad 63 May 15 11:15 test.c ↑ ↑ ↑ ↑ ↑ ↑ ↑ パーミッション 所有者 グループ バイト数 日付 時刻 ファイル名 上に示したのは架空のユーザ zzj88023 がホームディレクトリで ls を実行した例で す。MS-DOS の dir と異なり,出力は必ずファイル名のアルファベット順になります。 「パーミッション」についてはすぐ後で説明します。「所有者」はファイル・ディレク トリの所有者です。WS のディスクは全員で一つのものを使いますが,個々のファイル・ ディレクトリは所有者がはっきり決まっています。「グループ」はそのファイル・ディ レクトリにアクセスできるグループを示しますが,あまり有効には使われていないそう です。なお,みなさんは ugrad グループに属しています。 「バイト数」「日付」「時刻」については MS-DOS の場合と同じですから説明の必要は ないでしょう。 「ファイル名」の欄で,「./」はそのディレクトリ自身,「../」は親ディレクトリを表 - 36 - わしています。その次の5つは「.」で始まっていますが,MS-DOS と違って拡張子とい うものがないのでこういう名前も許されます。これらは私が作っておいた初期設定用の ファイルです。さしあたっては気にしなくて構いません。「a.out*」のように「*」がつ いているのは実行ファイルです。この「*」はファイル名には含まれません。「mail/」 のように「/」がついているのはこのすぐ下にあるサブディレクトリです。この「/」も ファイル名には含まれません。「profile」は前回の課題で作った,普通のファイルで す。 MS-DOS と違って8文字より長い名前も許されますが,MS-DOS で使っていた“普通の名 前”は OK のようなので,さしあたってはそういう名前だけをつけるようにすればよい でしょう。 ファイルが多すぎて画面が流れるときは「ls | more」としてください。「--More--」が 出て止まったらスペースで次の画面,「q」で中止です。 「ls file1」とすればそのファイルについてだけ見ることができます。 「cp file1 file2」でファイルの複写を行ないます。 「mv file1 file2」でファイル名の変更を行ないます。「mv file1 dirname」でファイ ル file1 をディレクトリ dirname に移動します。 「rm file1」でファイルの削除を行ないます。 ※ 以上のコマンドで,file1 はファイル名だけでもよいし,相対パス指定つきでも よいし,絶対パス指定されていてもよい。dirname も同じ。 ※ 本来の ls はファイル名のみを出力するので,あまり使いやすくない。また,本 来の cp, mv はファイルを上書きする場合の警告を出さないし,本来の rm は確 認メッセージを出さないので危険である。そこで,諸君のアカウントでは alias という機能を使い,ls, cp, mv, rm と打つと ls -algF, cp -i, mv -i, rm -i が実行されるようにしてある。よその WS を使うときは注意されたい。 「cat file1」で file1 の内容を画面に出力します。「more file1」だと一画面ずつ見 ることができます。「--More--」が出て止まったらスペースで次の画面,「q」で中止で す。 いろいろなディレクトリを動き回わって,いろいろなファイルを見てみましょう。 前回メールを送るときに使ったファイル mail/a は,実はディレクトリ ~/mail 内の a というファイルだったということがわかったと思います。新着でないメールはこのサブ ディレクトリ内の mbox という名前のファイルにたまっています。 ※ 新着メールは /var/spool/mail というディレクトリの,自分のユーザ名と同じ名 前のファイルにたまっている。このファイルにはいつ新着メールが付加されるか わからないので,emacs に読み込んだ場合,絶対にセーブしてはならない。その ようなことをすると読み込んでからセーブするまでの間に着いたメールが失われ るからである。more で見るか,mail コマンドで自分のディレクトリに移してか ら emacs で読めば安心である。 48.unix におけるファイル・ディレクトリのパーミッション 「パーミッション」というのは,ファイルやディレクトリに対する読み書きの許可のこ とです。 ls コマンドの説明のところの出力例のパーミッションと書かれた部分を見てください。 最初の1文字(「d」や「-」)は抜かすことにして,次の9文字は 最初の3つの rwx ……所有者 zzj88023 自身に対して 次の3つの rwx ……グループ ugrad のメンバーに対して 最後の3つの rwx ……すべての人に対して - 37 - のパーミッションを示しています。rwx は r ... 読み取り許可 w ... 書き込み許可 x ... 実行許可 の意味です。例えばファイルが「-rw-r--r--」だった場合,所有者は読み書き可,グル ープのメンバーと他人は読み取りのみ可,となります。ディレクトリの場合は少々違っ た意味になります。 それらの正確な意味を知るよりは,具体例を通してどのようなファイル・ディレクトリ にどのようなパーミッションを与えるべきかを理解するほうが実用的だと思います。 パーミッションを数で表現することもあります。その場合は左から順に r ... 400 w ... 200 x ... 100 r ... 40 w ... 20 x ... 10 r ... 4 w ... 2 x ... 1 と対応させ,「-」でない部分だけ足し合わせます。くり上がりはないから簡単です。上 の例は「644」になります。 パーミッションを変えるには chmod コマンドを使います。例えば「chmod 600 tegami」 とすればファイルまたはディレクトリ tegami のパーミッションが 600 になります。 よく見かけるパーミッションの例をあげます。 ファイルの場合: 644 ... 所有者は読み書き可。他の人は読むだけ。普通のファイル。 600 ... 所有者だけ読み書き可。秘密のファイル。 755 ... 所有者は読み書き実行可。他の人は読むと実行だけ。実行ファイル。 ディレクトリの場合: 755 ... 誰でもはいれる。所有者は書き込める。普通のディレクトリ。 700 ... 所有者だけがはいれて書き込める。秘密のディレクトリ。 ※ たいていの場合,グループに対するパーミッションとすべての人に対するパーミ ッションは同じにする。つまり,2ケタ目と3ケタ目は同じ数字になる。 自分のホームディレクトリを見て,“秘密”のファイルが他人に見えてないかチェック しましょう。:-) メールを送るときに作ったファイル mail/a そのもののパーミッションは 644 ですが, ディレクトリ mail が 700 なので他の人には見えません。mail/mbox も同じです。 49.unix のCコンパイラ,実行ファイル 「CC test.c」で C のソースファイル test.c のコンパイルができます。 ※ 「CC」が大文字であることに注意。 できた実行ファイルは常に a.out となります。それを動かすときは「a.out」です。 - 38 - ※ ホームディレクトリではなくその下のサブディレクトリに a.out を作った場合は 「./a.out」としないと動かないかも知れない。これは「カレントディレクトリの a.out」という意味である。 MS-DOS では拡張子を .exe 以外にすると動きませんでしたが,unix ではどんな名前に 改名しても動きます。 ※ プログラムが動いている途中,CTRL+C で中止させることができる場合がある。ま た,一時停止させるときは CTRL+S を押す。停止中に CTRL+Q を押せばまた動き 出す。MS-DOS と違って CTRL+Q でなければ動き出さないので注意。 ※ いままでプリントに書いておいたプログラムはどれもそのまま unix でも動くは ずである。できた実行ファイルは MS-DOS と unix とで全く違うのだが,同じソ ースファイルが使えるのは便利である。これはC言語の規格化がしっかりしてい るためである。 50.MS-DOS の階層ディレクトリ構造 MS-DOS も階層ディレクトリ構造をもっています。unix との違いだけを説明します。 ・「/」の代わりに「\」(半角の「¥」)を使う。 ・dir コマンドで見たとき, . そのディレクトリ自身 .. 親ディレクトリ