シェル


シェルの定義はさまざまですが, それは置いときましょう. ここでいうシェルは, UNIX のシェルのことです.

シェルが大好きな私ですが, そうはいっても, 別にシェルマスターというわけではありません. 私は情報科学という学科の出身なので, そういう最強に強まったシェル使いの人 をたくさん知っていますから, そんな事を名乗るわけにはまいりませんよ.

だいいち, このテーマに関しては, 優れた本があります.

UNIX プログラミング環境

という本です. しかも, 著者は, UNIX の作者たちだ. 俺なんかに習うより, こいつらに習うのが, 一番だぜ. 買え. そして読め. 出版社忘れた. すまん.

この本には, 練習問題があるんだぜ. こんな感じ.

  1. ファイル名 "*" のファイルを作れ.
  2. それを消せ.

どうだ. いかすだろ. 読んでみたくなっただろ. ところで, これで正直に

hoge:~% rm *
とやって, 死んだ人は何人いるのかな? このギャグが判んない奴は, 実際に自分のホームでやってみろ. コマンドはこれだ.
hoge:~% rm -fr *
今やれ. すぐやれ. ほれほれ.

まあしかし, Linux のおかげで, UNIX もけっこう普及してるみたいだし, そのわりには, 見た目が派手で楽しげなプログラムは使っても, コマンドラインから使う, 地味で渋いが強力きわまりないプログラムというのは, あまり使われていないようである. つうか, 存在すら知られていないようなんで, ちょっとそいつらの宣伝を, ここでしましょう. こういう小さいプログラムを "|"とか"`"とかで組合せて うまく使ってこそ UNIX ですぜ. それに, こいつらを使いこなすのが, UNIX ダー クサイド(なんじゃそりゃ?)への入口なんだぜ. この記事読んで, 俺もシェルをマスターしたい! と思った人は, あの本で修行してくれ.

それじゃあ, 行ってみよう.

grep

grep hoge file.name で file.name というファイルの中で, "hoge" と いう文字列が含まれている行を, 画面に表示する. 検索プログラムですね. file.name を指定しないと, 標準出力を検索する. だから, パイプで繋い で必要な情報だけを取り出すのだ. 例えば, 自分(me)の起動しているプロセス だけを見たければ, ps -auxw | grep me でいいわけだ.
grep には, いろんなオプションがある. "-v" はパターンと一致しない 行を出力する. つまり, ps -auxw | grep -v me で, 自分以外のプロセ スをみることが出来る. さて, ここで問題です. 上で挙げた 2つのコマ ンドは, ここで意図している結果が必ずしも得られるわけではありません. どういう場合でしょう?
検索文字列は, 「正規表現」というもので与える. これは, あるパター ンの文字列を表現するための, 約束だ. 正規表現とかを学ばずして, 何が コンピュータか?! である. 正規表現は, 東工大の情報科学の大学院の入試とかに, たまに出る, コン ピュータにとって, 非常に重要な概念つうか, 理論つうか, やりかたつうか, そういうもんなんで, せっかく UNIX 使うんだから, これくらい勉強しよう. だから, grep のマニュアル 95行以降を読 めよ.

sed

stream editor である. せど である. 「せどかー」という声が聞こえて きたぞ. せどは, 実際にコマンドラインで使う事は少ないが, tcpdump という悪魔のツールの出力結果を編集したい(つまり, 要るパケッ トだけを見たい)という場合なんかに, 必須のツール.
これもまた, 正規表現で文字列を与え, それを操作するプログラムで, ほっとくと, 標準入力から読み込んで標準出力に表示するという点で, grep と同じだ. つまり, パイプシンボル "|" が使えるプログラムですね.
たとえば, システムを shutdown できれば, インストーラで起動して, ハードドライブをマウントし, /etc/shadow を sed で編集して, root のパスワードを初期化するなんてことは, sed と "|" やら ">" やらを使 えば楽勝だ. じゃあ, 次はどうやって shutdown するかなー. 知りたいひとは, こちら.

awk

sed の高等な奴. 実際は, 非常に高等なんだが, さすがにこれくらい高等 になると, 私程度では, 週に一回使うかどうかです. sed で出来る事は, これでできまして, さらに, 表計算みたいなこともできます. たとえば, du というプログラムは, ファイルの大きさを標準出力に出しますが, その出力の1番目のフィールドを全部足す. というのをやれば, ファイル の合計のサイズが判るわけです. sukebe.jpg と dosukebe.jpg と, ero.jpg とがあり, それ以外に *jpg が存在しない時, スケベ画像の合計 サイズは, どうやって求めればいいかな?
awk のマニュアルは, man するよりも, info gawk とやった方がいいの だ. 入門と具体例のところだけでも, 相当に便利な技が書いてあるぞ.

sort

辞書順にソートしてくれるプログラム. これも, 標準出力系. -n オプションで, 数値順でソートしてくれる.
du -s /home/* | sort -n | tail 
で, /home の大きいディレクトリ上位 10個が表示されるわけです. ユーザ名ぽいディレクトリで一番でかいやつ が, root 君のディレクトリだ!そいつのパスワードを破れ!

tail

これも標準入出力系. 入力の最後10行を見る. "-f" オプションで, ファ イル名を指定すると, そのファイルが変更されて, 最後に追加されると, それを反映して尻尾を追い続けてくれる. システムの log を追い続ける 時に便利. サーバを設定する時はこれで, 動作状況を見ながら作業すると, らくちんだ.
先頭を見るのは, head だ. おお, head は /bin だが, tail は /usr/bin だぞ. どういうことだ. 両方とも gnu のプログラムなのに. 俺は, てっきり tail は head への symbolic link だと思ってたよ. 根 拠なく.
uniq
sort と一緒に使う. sort された入力で, 同じ行が続いたら, 一行だけ 残す. たとえば, こんなコマンドで, 自分にメールをくれた人のアドレス を重複なく(同じ人が何通もメールをくれるはずだ) address.list という ファイルにセーブできる.
 grep From: ~/Mail/*/* | sort | uniq | sed 's/From://' > address.list
ちゃんと アルファベット順にソートされているところとかが, いかすじゃ ないか.
wc
wc は word count(er) だ. これも "|"と一緒に使えるプログラムだ. こういう, "|" と一緒に使えるプログラムを, 一般に「フィルタ」とい う. 必要なものだけを漉して捉える事が出来るからだろうか. 今, あなたのシステムに, 何人ログインしているか, 数えるのは,
who | wc -l
	  
です. インストールしてから今まで, 何回再起動したかは,
grep Calibrating /var/log/messages | wc -l 
	  
という感じ. じゃあ, 問題です. 何回 root になろうとしたか. そして, そのうち何回失敗したかをどうやって数えればいいでしょう?
シェルは, 一般にメタキャラクタというのを持っている. さっきの
rm -fr *
の * もそうだ. このメタキャラクタを, メタじゃなくするのが, エスケープ文字とよばれるメタキャラクタだ. 通常バックスラッシュ "\" です. これを使って, メタキャラクタをサーバが起動する cgi への引数として渡す というのが, 一般的な cgi アタックの手法です. cgi がシェルスクリプトだったばあいは, この技を用いて, 任意のコマンドを サーバで実行できたりする場合があります. だから, メタキャラクタをどう使うか. あるいはそれをどうエスケープするか, という工夫と知識は, 保安と利便性を両立する上で, 欠かせない知識です. シェルを理解するには, 正規表現とエスケープだと言って良いでしょう. では, ためしに空白を含んだ名前のファイル 「fuck you」を作ってみよう. それができたら, 次は消してみよう(そんなファイルがあっても, 何も良い事無 いからな. ). おいおい, tcsh の補完機能を使うのは反則だ.

それでは, 最後にわしの .tcshrc を一部公表しよう. 俺の tcshrc が参考になるようでは, まだまだだぜ.