2009年06月19日 情報科学類 コンピュータリテラシ 筑波大学 システム情報工学研究科 コンピュータサイエンス専攻, 電子・情報工学系 新城 靖 <yas@is.tsukuba.ac.jp>
このページは、次の URL にあります。
http://www.coins.tsukuba.ac.jp/~yas/coins/literacy-2009/2009-06-19
あるいは、次のページから手繰っていくこともできます。
http://www.coins.tsukuba.ac.jp/~yas/
http://www.cs.tsukuba.ac.jp/~yas/
別名。1つのものに2つ以上の名前をつける。
例:ls -l
の代わりに ll
というコマンドを使えるようにする。
% ls -l
total 80
-rw-r--r-- 1 yas prof 281 Jun 22 13:14 Imakefile
-rw-r--r-- 1 yas prof 1072 Jun 22 13:31 Makefile
-rw-r--r-- 1 yas prof 14044 Jun 22 13:31 index.html
-rw-r--r-- 1 yas prof 10681 Jun 22 13:30 index.html-m4
-rw-r--r-- 1 yas prof 10129 Jun 22 13:14 index.html-m4.~1~
% ll
tcsh: ll: Command not found.
% alias ll ls -l
% ll
total 80
-rw-r--r-- 1 yas prof 281 Jun 22 13:14 Imakefile
-rw-r--r-- 1 yas prof 1072 Jun 22 13:31 Makefile
-rw-r--r-- 1 yas prof 14044 Jun 22 13:31 index.html
-rw-r--r-- 1 yas prof 10681 Jun 22 13:30 index.html-m4
-rw-r--r-- 1 yas prof 10129 Jun 22 13:14 index.html-m4.~1~
%
alias の機能
% alias
% alias ll
% unalias ll
~/.cshrc
(csh run command) に含まれて
いる命令を実行する。
alias の定義は、tcsh (csh) が終了すると、消えてしまう。 複数の端末で、複数の tcsh を実行しても、定義した端末だけ有効になるだけである。 他の端末では、定義されない。
毎回手作業で定義したくないなら、ファイル~/.cshrc
に定義を含める
とよい。csh は、実行されると、まずそのファイルに含まれているコマンドを
実行する。
tcsh は、csh にコマンドラインの編集機能がついたものである。tcsh は、
csh 用の設定ファイル ~/.cshrc
を参照する。
#
# standard ~/.cshrc for coins users
#
if( -r /usr/local/lib/standard/cshrc ) then
source /usr/local/lib/standard/cshrc
endif
演習などで、このファイルを消してしまった時には、次のようにすると回復できる。
% cd ~
% mv .cshrc cshrc-bad
% cp /usr/local/lib/standard/cshrc-home .cshrc
%
path の設定には気をつける。講義などで独自の path にあるコマンドを実行す
る必要がある時には、標準のものに「追加」する形にすることを進める。
以下の例では、/usr/local/xxx/bin を追加している。
#
# standard ~/.cshrc for coins users
#
if( -r /usr/local/lib/standard/cshrc ) then
source /usr/local/lib/standard/cshrc
endif
# source の後で、$path を使いながら独自に設定する。
path = ($path /usr/local/xxx/bin)
独自に設定する方法では、問題が生じることがある。
悪い例1: 独自に設定する。目的のディレクトリだけを書く。/bin など大事な ものがない。
path = (/usr/local/xxx/bin)
悪い例2: 独自に設定する。coins でよく使う/sw/bin や /opt/local/bin,
/usr/sbin などが抜けている。
path = (/usr/local/bin /bin /usr/bin /usr/X11R6/bin /usr/local/xxx/bin)
/usr/local/xxx/bin)
'\!*'
」のよ
うに書く。「\」は、「\」か「¥」(ASCII で 5c(16進数))
例:引数で与えられたディレクトリを ls -l -t で調べて、そのうちの先頭の 10行だけを表示する。
% alias new10 'ls -l -t \!* | head'
% new10 /bin
total 8824
-rwxr-xr-x 1 root wheel 40408 Feb 19 18:09 launchctl
-r-xr-xr-x 1 root wheel 896720 Aug 23 2005 ksh
-rwxr-xr-x 2 root wheel 491340 Aug 23 2005 zsh
-rwxr-xr-x 2 root wheel 491340 Aug 23 2005 zsh-4.2.3
-r-sr-xr-x 1 root wheel 24736 Aug 22 2005 rcp
-r-xr-xr-x 1 root wheel 14440 Aug 22 2005 domainname
-r-xr-xr-x 2 root wheel 18104 Aug 22 2005 [
-r-xr-xr-x 2 root wheel 18104 Aug 22 2005 test
-r-xr-xr-x 1 root wheel 13964 Aug 22 2005 sleep
%
「!*
」と書きたいが、単に「!
」を使うと、ヒストリが展開されてしまうので、
「\!
」と書く。また、「*
」がファイル名に展開されないように、
シングルクォート「''
」で括る。
「\!:1
」のように、引数を区別する機能もある。
alias では、パイプ「|」もよく使われる。
% which md
/usr/bin/md
% man md
md(1) BSD General Commands Manual md(1)
NAME
md -- process raw dependency files produced by cpp -MD
SYNOPSIS
md [-d] [-f] [-m makefile] [-u makefile] [-o outputfile] [-v] [-x]
[-D c|d|m|o|t|D]
...
% alias md mkdir
% which md
md: aliased to mkdir
%
alias を無効にして、元のコマンドを使いたい時には、コマンド名の
前に「\」をつける。または、コマンド名をフルパスで打つ。
% md
usage: mkdir [-pv] [-m mode] directory ...
% \md
usage: md -f -Dcdmot -m makefile -o outputfile -v ...
% /usr/bin/md
usage: md -f -Dcdmot -m makefile -o outputfile -v ...
%
% alias ls ls -F
しかし、行の先頭以外では、Alias loop というエラーになる。
% alias ls 'dirs; ls \!*'
% ls
tcsh: Alias loop.
%
この時には、alias を展開させないために、コマンド名の前に「\」を使う。
% alias ls 'dirs; \ls \!*'
% ls
~/public_html/coins/literacy-2006/2006-06-23
Imakefile index.html index.html-m4.~1~
Makefile index.html-m4
%
コマンド名をフルパスで書く方法もある。
% alias ls 'dirs; /bin/ls \!*'
% ls
~/public_html/coins/literacy-2006/2006-06-23
Imakefile index.html index.html-m4.~1~
Makefile index.html-m4
%
tcsh は、csh に terminal での編集機能や補完機能を付けたもの。シェル・ スクリプトを書く時には、多くのシステムで備わっている /bin/csh を使うこ とが多い。(csh はあるが tcsh がないシステムもある。)
#!/bin/csh
や #!/bin/csh -f
と書き加える。
chmod +x
で実行可能属性を付ける
~/bin
に置く)
csh
ではなくて、sh
(/bin/sh
)で実
行される。sh
と csh
は、文法に共通性もあるので、問題ない
場合も多い。
問題がある場合、どうしても csh
で実行させたい場合、テキスト・エ
ディタで、行の先頭に「#!/bin/csh
」と書き、csh で実行させる。
#!/bin/csh -f
」と、-f
を付けると、~/.cshrc
を読
み込まないので速くなる。ただし、~/.cshrc で定義した設定(aliasや環境変数
の設定)は効かないことがある。
ただし、環境変数は、今の状態を引き継ぎたいことが多いので、
~/.cshrc
を読み込ませない方が都合がよいことが多い。
% cat add
#!/bin/csh -f
@ x = $1 + $2
echo $x
% ./add 10 20
30
% ./add 100 200
300
%
引数は、$1,$2,...
や $argv[1],$argv[2],...
で参照でき
る。$*
では、全ての引数を参照できる。shift
コマンドで
引数をずらすことができる。$#
で引数の数がわかる。
csh では @
で簡単な計算ができる。空白で区切る必要がある。
The Unix Super Text 39.3節 参照。
-x
オプションを付けて実行すると、画面にスクリプトを表示さ
ながら実行する。
% csh -f -x run
-n
オプションを付けて実行して、構文のチェックだけ行う。
シェルに1行ずつ与えて実行してみる方法もある。
~/.cshrc
などを設定して、~/bin
をpath シェル変数(PATH
環境変数)に含まれるようにすることを奨める。そして自分で作成したプログ
ラムやスクリプトを、~/bin
に置くと./
などで実行する必
要はない。
coins では、標準で ~/bin
が path
に含まるように設定されている。
ただし、ファイルを作成し、chmod +x
した後で、1度だけ
rehash
コマンドを打つ必要がある。rehash
と打たれるまで、
tcsh
は、コマンドが追加されたことに気がつかない。
% emacs ~/bin/newcommand
% chmod +x ~/bin/newcommand
% rehash
% newcommand
% emacs ~/bin/newcommand
% newcommand
% emacs ~/bin/newcommand
% newcommand
%
chmod
も rehash
も、シェルごとに1度だけやればよい。端末
をたくさん開いていた時には、作成したスクリプトをすぐに使いたい時にはそ
れぞれのシェルで rehash
コマンドを実行する。
rehash
は、「ハッシュ表を作り直す」ことを意味する。csh は、コマ
ンドを打つたびにpath
で指定されたディレクトリにあるコマンドを探
すのではなく、ハッシュ表と呼ばれる、高速に検索するための仕組みを使って
検索している。
rehash
は、新しいシェルが実行される時には自動的に行われている。
次にログインした時、chmod +x
した後に開いた端末では
rehash
を実行する必要はない。
/bin/sh
) は、Bourne SHell と呼ばれる。対話的な利用では、csh
を使う人でも、シェルスクリプトを作成する時には、sh を使う人も多い。
実際には、Unix オリジナルの sh ではなく、bash (GNU Bourne-Again SHell) という高機能のプログラムが広く使われている。
例: 大量のファイルを削除する
% rm -rf dir &
[1] 7433
%
コマンドの末尾に 「&」を付けると、バックグランドで実行され
る。ジョブ番号とプロセス番号が表示され、すぐにプロンプトが洗われる。
終了すると次のような表示がなされる。
[1] Done rm -rf dir
% who; date; sleep 10; date; who
yas ttyp0 Jun 18 12:39 (sharon.hlla.is.t)
Thu Jun 18 13:12:00 JST 2009
Thu Jun 18 13:12:10 JST 2009
yas ttyp0 Jun 18 12:39 (sharon.hlla.is.t)
%
例: /bin と /usr/bin にあるファイルをしらべてホーム・ディレクトリにある commands というファイルに保存する。
% cd
% (cd /bin; ls; cd /usr/bin; ls ) > commands
% ls -ld /
drwxrwxr-t 34 root wheel 1190 May 12 09:34 /
% echo $status
0
% ls -ld /aaaa
ls: /aaaa: No such file or directory
% echo $status
1
%
コマンドが成功したか失敗したかを調べ、その結果に応じて次のコマンドを実
行するかしないかを決めたい。
command1 が成功したら、command2 を実行する。 (できれば、両方とも実行したい。)
command1 && command2
command1 が失敗したら、command2 を実行する。
(どちらか一方が実行できればよい)
command1 || command2
% lv ~/.cshrc
% lv ~/.cshrc
% lv /usr/local/lib/standard/cshrc
この cshrc で path にどのようなディレクトリを設定しているか調べなさい。
また、現在実行中のシェルの path の値と比較しなさい。
% echo $path
% printenv PATH
% echo $PATH
シェル変数 path、または、環境変数 PATH に含まれているディレクトリには、
どのようなコマンドがあるかを調べなさい。例えば、/usr/local/bin を調べる
には、次のようにする。
% ls /usr/local/bin
path 以外にどのような
シェル変数と環境変数
が設定されているかを調べなさい。
まず、端末で何かコマンドを実行しなさい。以下の例では、 /Applications/Calculator.app を実行している。
% open /Applications/Calculator.app
(^p で1行もどす。^a で、行頭に移動して echo と打ち、^e して > run-calc と打つ)
% echo open /Applications/Calculator.app > run-calc
% csh run-calc
%
tcsh の機能で、^p (Control+P) で1行戻して、echo でファイルに落とす。
「|」があれば、「'シングルクォート'」で括る(
'|'
) などして、エスケープする 。
いちいち csh と打たないでもいいようにするために、chmod
コマンドで
実行可能属性をつける。
% chmod +x run-calc
% ./run-calc
%
必要ならば、エディタで1行目に「#!/bin/csh」か「#!/bin/sh」を入れる。
#!/bin/csh
open /Applications/Calculator.app
echo
でファイルに落すのではなく、alias
コマンドでエイリアスを定義する。
~/.cshrc
に Emacs 等のテキスト・エディタで
alias のコマンド行を追加する。
echo
コマンドではなく、history
コ
マンドを使う。
% history -h
(ヒストリの表示して、何行必要か数える。history コマンドの分、1行多く保存する。)
% history -h 5 > run-xxx
% emacs run-xxx
(最後の history コマンドをテキスト・エディタで削る。)
そのプログラムが、一般のプログラム(機械語)かシェル・スクリプトかは、 file コマンドを使うと調べることができる。
% file /usr/bin/apropos
/usr/bin/apropos: Bourne shell script text executable
% ls -l /usr/bin/apropos
-rwxr-xr-x 1 root wheel 2408 Aug 22 2005 /usr/bin/apropos
% lv /usr/bin/apropos
%
if
, if then else endif
foreach
while
switch
exec
eval
exit
source
次の機能を確認しなさい。
jobs
コマンド
fg
コマンド
bg
コマンド
%
によるジョブの指定方法
stop
コマンド (%
による指定)
kill
コマンド (%
による指定)
% l2 file.tex
% lpshow file.tex
(画面には、file.pdf が Preview.app で表示される)
ヒント: 拡張子 .pdf を持つファイルを open コマンドで開くと、
標準では Preview.app が動作するが、他のプログラムにも変更できる。
この課題でも他のプログラムを使ってもよい。
% ls-c ~/syspro/file/
fd-print.c
file-copy.c
mmap-head.c
stdio-thru.c
utmp-print.c
wtmp-last10.c
ystat.c
ystat.h
ヒント:ls の結果から、egrep で .c や .h で終わるものを抜き出す。ある
いは、シェルのパタン・マッチの機能を使って、*.c や *.h だけを取り出す。
余裕があれば、-l などのオプションが付けられるようにしなさい。
% ls-dot ~
.
..
.cshrc
.emacs
.login
%
ヒント:ls に -a オプションを付けると、全てのファイルを表示する。
先頭が「.」のものを抜き出す。
csh, tcsh, sh で 「.*」と指定して探す方法もある。
余裕があれば、-l などのオプションが付けられるようにしなさい。
% ls-dir ~
Mail
lib
syspro
tmp
%
ヒント:ls -l で、d から始まる行だけを抜き出す。あるいは、csh の -d や
test の -d でディレクトリだけを選びだす。
できるだけ上のようにディレクトリの名前だけ表示するようにしなさい。 モードや日付は表示しないようにしなさい。
余裕があれば、-l などのオプションが付けられるようにしなさい。
% ls-size ~yas/syspro/www
-rwxr-xr-x 1 yas prof 27056 Jun 12 11:54 cgi-printarg.cgi
-rwxr-xr-x 1 yas prof 18376 Jun 19 01:29 cgi-hello.cgi
-rw-r--r-- 1 yas prof 5287 Jun 12 11:54 cgi-printarg.c
-rw-r--r-- 1 yas prof 1579 Sep 26 2002 get.c
-rwxr-xr-x 1 yas prof 985 May 20 17:17 cgi-printarg-ruby.cgi
-rw-r--r-- 1 yas prof 486 Jun 11 21:20 cgi-hello.c
-rw-r--r-- 1 yas prof 297 Sep 22 2003 Makefile
drwxr-xr-x 5 yas prof 170 Jun 19 01:27 CVS
-rw-r--r-- 1 yas prof 54 Feb 14 2004 data
total 128
%
ヒント:ls -l の出力を sort コマンドでソートする。
ソートは、第5フィールドで行う。
% wc-lines *.c
85 228 1836 proc-uid-print.c
75 187 1156 pipe-rw-dup.c
50 152 1141 vaddr-print.c
46 140 1071 proc-create.c
67 161 1014 pipe-rw-nodup.c
38 93 819 signal-int.c
50 98 802 setjmp-longjmp.c
32 90 561 run-n.c
27 66 535 home-print.c
20 50 424 cont-1.c
20 50 424 cont-0.c
25 60 419 t-system.c
20 40 384 exec-date.c
14 49 370 arg-print.c
15 44 355 env-print.c
12 32 305 cont-2.c
13 16 174 fork-hello.c
4 10 60 main-return.c
%
この課題では、合計(Total)は表示されなくてもよい。
ヒント:wc の出力を sort コマンドでソートする。foreach か for で1つず つ wc コマンドを実行して、全体の結果を sort するか、引数 $* で wc した 後、sort して、合計(Total)の行を削る。
% ps aux
USER PID %CPU %MEM VSZ RSS TT STAT STARTED TIME COMMAND
root 1 0.0 -0.0 28340 540 ?? S<s 6Jun06 0:22.58 /sbin/laun
root 52 0.0 -0.0 27256 156 ?? Ss 6Jun06 0:00.00 /sbin/dyna
root 58 0.0 -0.2 30632 3536 ?? Ss 6Jun06 0:08.21 kextd
root 91 0.0 -0.0 28240 624 ?? Ss 6Jun06 0:00.03 /usr/sbin/
...
root 52 0.0 -0.0 27256 156 ?? Ss 6Jun06 0:00.00 /sbin/dyna
root 58 0.0 -0.2 30632 3536 ?? Ss 6Jun06 0:08.21 kextd
root 91 0.0 -0.0 28240 624 ?? Ss 6Jun06 0:00.03 /usr/sbin/
root 92 0.0 -0.2 28360 3624 ?? Ss 6Jun06 9:41.29 /usr/sbin/
%
そのうち、メモリのサイズ(RSS)が大きいプロセスを 10 個だけ表示するシェル・
スクリプトを作りなさい。
% ps-rss-top10
USER PID %CPU %MEM VSZ RSS TT STAT STARTED TIME COMMAND
root 239 0.0 -0.9 62428 18316 ?? Ss 6Jun06 2:16.88 /System/Li
security 21102 0.1 -0.8 247056 15876 ?? S Sat04PM 5:17.79 /System/Li
windowse 21096 0.1 -0.5 203808 11108 ?? Ss Sat04PM 4:32.14 /System/Li
daemon 242 0.0 -0.4 73932 9280 ?? Ss 6Jun06 1:41.18 /System/Li
root 115 0.0 -0.4 39260 7920 ?? Ss 6Jun06 1:50.21 /System/Li
root 104 0.0 -0.2 34128 5100 ?? Ss 6Jun06 2:47.36 /usr/sbin/
root 92 0.0 -0.2 28360 3624 ?? Ss 6Jun06 9:41.81 /usr/sbin/
root 58 0.0 -0.2 30632 3536 ?? Ss 6Jun06 0:08.21 kextd
root 132 0.0 -0.2 31460 3372 ?? Ss 6Jun06 1:21.59 /usr/sbin/
root 21094 0.0 -0.1 205696 2924 ?? Ss Sat04PM 0:00.19 /System/Li
ヒント:1行目は、そのまま表示する。
RSS の順(第6フィールド)に sort して head する。
余裕があれば、VSZ の順、CPU 時間の順に表示するスクリプトを作りなさい。
類似のことを実行するプログラムとして top がある。
% diff-backup *.c
ヒント:foreach または for 文で、引数のファイルについて、
"$file"~ のような名前のファイルが存在するかを調べる。
存在すれば、diff コマンドで表示する。
余裕があれば、比較しているファイルの名前を表示したり、ファイルごとに停 止する、引数を取る、diff に対するオプションを取る、などの工夫をしなさ い。
% mv-lower [A-Z]*
ヒント:ファイル名を echo して、tr で小文字にして、それを `` でシェル変数に入れる。元の名前から小文 字の名前に mv で変える。
余裕があれば、大文字と小文字を変換することで、ファイルが上書きされる時 には警告を出したり、ユーザに問い合わせたりするようにしなさい。
% countdown 5
5
4
3
2
1
0
%
ヒント:sleep 1 で、1ごとに止める。
% show-n-m 10 20 filename
余裕があれば、-n オプションを付けなさい。これは、ファイルに行番号を振 るものである。nl コマンドを使うとよい。(cat -n が使えるシステムもある。)
(1) csh (tcsh) のエイリアスを定義しなさい。エイリアスは、~/.cshrc に保 存しなさい。定義したエイリアスについて、次のことを書きなさい。
(2) 次のような条件を満たすシェル・スクリプトを作成しなさい。
~/bin
に起きなさい。
作成したシェル・スクリプトについて、次のことを書きなさい。
授業で例題として示したものとは別のシェル・スクリプトを作成しなさい。
(3) The Unix Super Text の次の部分を読みなさい。
(4) [加点] 制御構造 if, foreach, while, switch のうちいくつかを含むシェ ル・スクリプトを作成しなさい。この基準を満たしていれば、練習問題のうち の何れかを解いてもよい。