この文書の URL は http://www.cc.kyoto-su.ac.jp/~mtkg/lecture/comp_A/2012/07.html です。

テキストファイルをみるコマンド

テキストファイルを読むには lvless というコマンドを使います。

mtkg@ubuntu:~$ lv ~mtkg/comp_A/ogura.txt

としてファイルを表示させてみましょう。

などが使えます。

ユーザ・グループ・パーミッション

ユーザとグループ

Linux (UNIX) のユーザには

という2つの情報があります。 ユーザ名やグループ名は数値で表される識別子 (ID) がつけられています。 ユーザ名や所属しているグループ名を知るには id コマンドを使います。

mtkg@ubuntu:~$ id
uid=4987(mtkg) gid=100(teach) 所属グループ=100(teach)

表示される情報は次のようになります。

ユーザは複数のグループに所属することができ、その場合には groups に複数のグループ ID が表示されます。

mtkg@ubuntu:~$ id locadmin
uid=7000(locadmin) gid=7000(locadmin) 所属グループ=4(adm),20(dialout),24(cdrom),46(plugdev),105(lpadmin),119(admin),122(sambashare),7000(locadmin)

ファイルの所有者とパーミッション

UNIX ではファイルに対するアクセス権(パーミッション)を

  1. owner (所有者)
  2. group (所有者の属するグループ)
  3. other (他人)

に分けて管理しており、それぞれの区分に対して「読み取り許可 (r)」、「書き込み許可 (w)」、「実行許可 (x)」を設定することができます。 ディレクトリの場合、実行許可はそのディレクトリをカレントディレクトリにできるかどうかを示します。

ファイルに設定されているパーミッションを調べるには ls コマンドに -l オプションを付けて実行します。

mtkg@ubuntu:~$ ls -l ~mtkg/comp_A/ogura.txt
-rw-r--r-- 1 mtkg teach 6792 2012-05-17 13:26 /NF/home/kyoin0/mtkg/comp_A/ogura.txt
^^^^^^^^^^

下波線を付けた部分(10文字)がパーミッションを示しています。 最初の1文字が "d" ならディレクトリ、"-" ならファイルであることを示します。 それ以降は3文字で1セットになっており、それぞれ owver, group, other に対する許可を示します。

d/-   owner   group   other
----------------------------------
-     rw-     r--     r--

各セットの意味は

となります。

パーミッションは r = 4, w = 2, x = 1, - = 0 という数字の和として表されることがあります。

r w x -
4 2 1 0

例えば -rw-r--r-- であれば

owver: rw- = 4 + 2 + 0 = 6
group: r-- = 4 + 0 + 0 = 4
other: r-- = 4 + 0 + 0 = 4

644 と表現されます(先頭の1文字は評価しません)。

-rwxr-xr-x  =>  755  (所有者は読み書き実行可能、それ以外は読み取り実行可能・書き込み不可)
-rw-------  =>  600  (所有者だけが読み書き可能)

パーミッションの変更

パーミッションを変更するには chmod コマンドを使います。

$ chmod パーミッション ファイル名1 ファイル名2 ...

設定するパーミッションは次のように表現します。

ユーザの表記
    u: owver (所有者)
    g: group (グループ)
    o: other (他人)
    a: all   (すべて)
権限の指定
    +: 権限の付加
    -: 権限の削除
    =: 権限の変更
権限表記
    r: 読み取り許可
    w: 書き込み許可
    x: 実行許可

使用例

owver に実行許可 (x) を与える場合
$ chmod u+x ファイル名
group に書き込み許可 (w) を与える場合
$ chmod g+w ファイル名
other から読み取り許可 (r) を削除する
$ chmod o-r ファイル名
全員から実行許可を削除する
$ chmod a-x ファイル名

次のコマンドを実行してパーミッションを確認してください。

$ ls -l ~mtkg/comp_A/unvisible.txt
$ lv ~mtkg/comp_A/unvisible.txt

ディレクトリの場合はどうでしょうか。

$ ls -dl ~mtkg/secret
$ cd ~mtkg/secret

パイプとリダイレクト

UNIX では小さなコマンドをたくさん組み合わせていろいろな作業をこなします。 そこで重要になるのが「パイプ」と「リダイレクト」です。

標準入力・標準出力・標準エラー出力

UNIX の各プログラム(正確にはプロセス)は標準入力・標準出力・標準エラー出力という3つのデータの出入り口を持っています。 例えば a2ps というコマンドは標準入力からテキストファイルを読み込み、標準出力からポストスクリプト形式のデータを出力します。 特に指定しない限り

となります。

リダイレクト

標準出力をターミナルの画面ではなくファイルに出力することができます。 ターミナルから次のコマンドを試してみましょう。

$ date                      画面に出力
$ date > date.log           date.log というファイルにリダイレクト
$ cat date.log              date.log の中身を画面に表示

このように「>」を使うことによって標準出力をファイルに書き込むことができます。 これを標準出力の「リダイレクト」といいます。 すでに存在するファイルを指定すると上書きされるので注意しましょう。

$ date >> date.log

のように「>>」を使うと、コマンドの出力をファイルの最後に追加することができます(ファイル date.log が存在しない場合は「>」と同じ動作)。

同様にして、標準入力をリダイレクトすることもできます。

$ cat < date.log

$ cat date.log」と似ていますが、違います。

パイプ

パイプを使うとコマンドの標準出力を別のコマンドの標準入力に(ファイルを経由せず)直接送ることができます。 例えば

$ ls -al /etc

とするとファイルとディレクトリが多すぎて一度に表示できません。 そこで

$ ls -al /etc | less

とすれば ls の結果を less コマンドを使ってみることができます(C-n で次の行、C-p で前の行に移動できます。C-n はコントロールキーを押しながら n を押す)。 このように「|」を使った標準入出力のやり取りを「パイプ」といいます。

パイプの威力を実感するために、次のような例を考えてみましょう。 「ホームディレクトリの容量を各ディレクトリごとに計算し、その結果を大きい順に並び替え、上位10個を表示する」というかなり複雑な操作が、パイプを利用すると1行でできてしまいます。

$ du -k ~ | sort -nr | head -10

各コマンドの意味は次のようになっています。

標準入力からデータを読んで、標準出力にデータを書き出すプログラムを「フィルタプログラム」あるいは単に「フィルタ」と呼ぶことがあります。 UNIX 上のコマンドの多くはフィルタとして使われることを意識して作られています。

基本的なフィルタコマンド

以下はテキストを処理するための基本的なコマンドです。 どのコマンドもファイルの代わりに標準入力を受け取ることができます(フィルタとして使える)。

コマンド名 内容 使用例 重要なオプション
head ファイルの先頭部分を出力する head -10 ファイル名 -数字
tail ファイルの終端部分を出力する tail -n 10 ファイル名 -n
sort ファイル内容をソートする sort ファイル名 -n -r
uniq ファイルの重複行を削除する uniq ファイル名
grep 文字列を検索する grep 検索文字列 ファイル名 -v

以下に例をあげますので、試してみましょう。

# "nico" を含む単語を抜き出す
$ grep nico /usr/share/dict/words

# "nico" を含む単語の数を数える
$ grep nico /usr/share/dict/words | wc -l

# "zo" で始まる単語で "a" を含まないものを抜き出す(-v は条件の否定)
$ grep ^zo /usr/share/dict/words | grep -v a

# ファイル date1, date2 を作成し、それを連結したファイル file3 を作る
$ date > date1
(1秒待つ)
$ date > date2
$ cat date1 date2 > date3
$ cat date3

プロセス

UNIX では同時に複数のプログラムを実行することが可能です。 これらのプログラムは「プロセス」という単位で処理されています。 プロセスに関する情報は ps コマンドで調べることができます。

$ ps
  PID TTY          TIME CMD
24533 pts/4    00:00:00 emacs
25103 pts/4    00:00:02 bash
26845 pts/4    00:00:00 ps
27420 pts/4    00:00:00 bash

各プロセスには「プロセスID」 (pid) という番号が付けられています。

ファイルと同様、プロセスにも所有者が決められています(通常はプロセスを起動したユーザが所有者になる)。 プロセスの所有者に関する情報は ps u で調べられます。

$ ps u
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
mtkg     24533  0.0  0.4  16448  9320 pts/4    T    13:23   0:00 emacs -nw
mtkg     25103  0.0  0.2  10656  4988 pts/4    SL   13:38   0:02 -bash
mtkg     26892  0.0  0.0   4000   952 pts/4    R+   14:26   0:00 ps u
mtkg     27420  0.0  0.1   7084  3820 pts/4    Ss   May15   0:00 -bash

もっと詳しい情報を得るには次のようにします。 試してみましょう。

$ ps uxw           (w: ワイド表示)
$ ps auxw          (a: 他人のプロセスも表示)

kill

kill コマンドを使うとプロセスを強制終了することができます。 xload というプログラムを実行し、それを強制終了してみましょう。

$ xload & [RET]              & を付けて実行すること
$ ps x
  PID TTY      STAT   TIME COMMAND
 9930 pts/5    Ss     0:00 -bash
 9959 pts/5    S      0:00 xload
 9976 pts/5    R+     0:00 ps x
$ kill 9959 [RET]            ps で表示された xload の pid を指定する

プログラムが暴走したときは kill コマンドでも終了できないことがあります。 その場合は -HUP オプションを付けて実行してみます。

$ kill -HUP pid

それでもダメなら -KILL オプションを使います。

$ kill -KILL pid

ジョブ

xload を & を付けないで実行してみましょう。

$ xload [RET]

こうすると端末にはプロンプトが帰ってこず、その端末は入力を受け付けない状況になります。 これは xload の「プロセスがフォアグラウンド (foreground) で実行されている」状況です。 フォアグラウンドで実行されているプロセスのことを「フォアグラウンドジョブ」といいます。

フォアグラウンドジョブを終了するにはキーボードから C-c (コントロールキーを押しながら c を押す)とします。 xload を C-c で終了してみてください。

次に xload を & を付けて実行してみましょう。

$ xload & [RET]
$

この場合は端末にプロンプトが表示されます。 このように & を付けてコマンドを実行するとプロセスをバックグラウンド (background) に送ることができ、複数の作業を同時に行うことができるようになります。 バックグラウンドで動いているプロセスのことを「バックグラウンドジョブ」といいます。

ジョブに関する情報は jobs コマンドで調べることができます。

$ jobs [RET]
[1]+  実行中               xload &

xload がジョブ番号 1 で動いていることがわかります。 kill コマンドにはジョブ番号を使うこともできます。 その場合は % にジョブ番号を付けて指定します。

$ kill %1

fg コマンドと bg コマンドを使ってジョブをフォアグラウンドにしたりバックグラウンドにしたりすることができます。 xload を & なしで実行してみましょう。

$ xload [RET]

C-z を押す(コントロールキーを押しながら z を押す)とフォアグラウンドジョブを一時停止することができます。

$ xload
^Z[1]   終了しました      xload

[2]+  停止                  xload

bg コマンドを使うとバックグラウンドで実行を再開させることができます。

$ jobs
[1]+  停止                  xload
$ bg %1
[1]+ xload &

逆に fg %(ジョブ番号) とするとバックグラウンドジョブをフォアグラウンドに移すことができます。

プロセスの稼働状況を一覧するには top コマンドが便利です。

ワイルドカード

複数のファイルをまとめて処理する場合、ワイルドカードと呼ばれる文字(* と ?)を使うと便利なことがあります。

? は任意の1文字を表現することができます。 したがって kadai1.txt, kadai2.txt, kadai3.txt というファイルを kadais というディレクトリにコピーするには次のように指定することができます。

$ cp kadai?.txt kadais/

* は任意の文字列(複数の文字)を表現することができます。 したがって kadai.tex, kadai.dvi, kadai.pdf というファイルを kadais というディレクトリにコピーするには次のように指定することができます。

$ cp kadai.* kadais/

kadais ディレクトリの kadai で始まるファイルを削除するには

$ rm kadais/kadai*

とします。 これにより kadai1.txt, kadai2.txt, kadai3.txt, kadai.tex, kadai.dvi, kadai.pdf を一度に削除することができます。

ワイルドカードは便利ですが、予期しないファイルを処理してしまうこともあります。 rm コマンドとあわせて使う時は十分注意しましょう。

エイリアス

エイリアス (alias) とは「別名」のことです。 alias コマンドを使うと、コマンドに別名を設定することができます。 現在設定されている別名をみるには alias コマンドを引数なしで実行します。

$ alias
alias egrep='egrep --color=auto'
alias fgrep='fgrep --color=auto'
alias grep='grep --color=auto'
...

新たな別名を設定するには次のようにします。

$ alias 別名='本来のコマンド名とオプションなど'

次のように ls2 という別名を定義してみましょう。

$ alias ls2='sl && ls --color=auto'
$ ls2 [RET]

別名を無効にするには unalias コマンドを使います。

$ unalias ls2

よく使うエイリアスは $HOME/.bashrc に書いておきましょう。 ログイン時に自動的に設定することができます。

本日の課題

ワイルドカード

次のコマンドを実行すると test101 というディレクトリができます。

$ ~mtkg/comp_A/test101.sh

中には test0.dat, test1.dat, ..., test100.dat という 101 のファイルができています。 次のコマンドを実行してワイルドカードの意味を確認しましょう。

$ cd test101
$ ls test?.dat
$ ls test??.dat
$ ls test???.dat
$ ls test*.dat

確認できたら rm コマンドで掃除しておきましょう。

$ cd ..
$ rm -rf test101

パーミッションの変更

test101.sh というファイルを自分のホームディレクトリにコピーしてパーミッションを変更してみましょう。

$ cd
$ cp ~mtkg/comp_A/test101.sh ./
$ chmod u-x test101.sh                (所有者の実行権限を削除)
$ ls -l test101.sh

実行できなくなったことを確認しましょう。

$ ./test101.sh

所有者(自分)に実行権限を与えてから再度実行してみましょう。

$ chmod 755 test101.sh                (パーミッションを rwxr-xr-x に設定)
$ ls -l test101.sh
$ ./test101.sh