目的のコマンドを探すには? [1993.11]

ファイル操作やデータ操作が必要になったとき,UNIX での作法は使い捨てプログラムを書くことではなく,まず用途にあったコマンドを探してみることである.だが,何百ものコマンドから目的のものを探すのは難しい.

まず試みるのは,man -k keyword である.マニュアルページの1行ずつの説明をまとめたデータベース (whatis) を keyword で検索してくれる.ただし,そのマシンで whatis ファイルが作られている必要がある.なければ管理者に頼んで作ってもらおう.作成には catman コマンドを使う.その名も whatis や,apropos といったコマンドが存在していることもあるが,これらは同じコマンドである (ls -li で man whatis apropos の i ノード番号を見れば,ファイル実体としても同じであることがわかる.どの名前で実行されたかを調べて動作を変えているのだ).

だが,whatis はあまりにも簡単すぎる.cat コマンドの whatis は「繋げて表示する」としか出ない.cat が行番号をふったり,複数行の空行を1行にまとめるオプションをもっていることがどうして知れよう.残念ながら,標準のツールでこういったことを知るのに役立つものはない.コマンドの名前も用途に結びつく情報は得られない.nl ln nm ul ls … 結局,あたりをつけて man してみる,としか答えられない.逆に,便利なコマンドを知るには,マニュアルを通して見ていくしかない.このための,オプションと用途だけを簡潔にまとめた薄いマニュアルが望まれる (共立出版 から出ていたコマンドノートは実に役だった).また,man ページの roff ファイルがあるディレクトリ man1 man2 と同じところに,cat1 cat2 … といったディレクトリを作って書き込み可能としておくと,man コマンドで読まれたファイルの roff を通した出力を cat ディレクトリに保持するので,2度目からは高速に表示されるようになる.

man ページをプリントアウトするには,無名 ftp で入手できる thack プログラムが便利である.これは troff の写植機用コマンドを PostScript に変換してくれる.よって,

troff -t -man man.1 | thack | lpr -Ppostscript

で,きれいな出力が得られる.オンラインも手軽ではあるが,便利なコマンドを発見したり,新しい使い方を知るのには印刷されたマニュアルが役立つ.最良のオンラインマニュアルは,よく知っている人自身である.こういう人に聞くのがもっとも早いが,2度同じことを聞くのはやめてほしいものだ.


† 最近 (例えば FreeBSD 4.8-RELEASE) は別のコマンドになっている. whatis と apropos はハードリンクされていた.[2003.5.24]
‡ FreeBSD 4.8R の man は groff を呼び出している. 次のようにして別のソフトウェアを使わなくても PostScript プリンタに出力できる.[2003.5.24]

man -t man | lpr -Ppostscript


ファイルの許可モードについて教えてください [1993.12]

-rwxr-xr-x といった表示はいかにも UNIX で心安まるものがある.もちろん,ディレクトリ内容の表示コマンド ls での出力で,左端がエントリの種類,残る 9文字は 3文字を 1組としては所有者,同グループ,その他の,ユーザの許可モードである.1組の 3文字は左から読込み,書込み,実行の許可を示す.- は不許可である.これを 8進表示して 755 と指定することもある (tahoe の ls の man ページでは,モードは 11文字とある?!)

所有者やグループの実行許可に出てくる s は,所有者 (グループ) ID セットモード (SetUID, SetGID) と呼ばれている.SetUID モードのファイルのコードを実行するプロセスは,そのファイルの所有者の ID (UID) で実行される. passwd コマンドはその例である.パスワードの変更には,スーパーユーザにしか書込み許可がない /etc/passwd ファイルを変更しなければならない.だが,root 所有で SetUID モードの passwd コマンドは一般の人が実行しても root 権限で走るので,/etc/passwd ファイルに書くことができる. パスワード変更という単機能コマンドであるから,root で走ってもそれを悪用することはできない.なお,安全のため,スーパーユーザ以外が ID セットモードに書込むと,s ビットは消される.

右端に出てくる t (その他の実行許可の位置.もとが許可 x なら t, 不許可 - なら T) は sticky ビットと呼ばれている.このモードの共有実行ファイルは,実行しているプロセスがなくなってもそのコード部分がスワップ領域から消去されない.これにより,次にそのファイルを実行するときの立上がりが速くなる.とはいえ,最近はこれによる恩恵はあまりない.また,実行ファイルではなく,ディレクトリに sticky ビットがセットされていると,そのディレクトリに作られたファイルは,所有者とスーパユーザ以外には,消去したり,名前を変えることができない.メールボックスを置くディレクトリなどにセットされている.

許可モードとファイルの内容とは無関係である.単なるデータファイルに実行許可を与えることもできる.キーボードから打ち込むべきコマンドを並べたテキストファイルに実行許可を与えれば,そのファイルは確かに実行できるようになる.これは,ユーザからの入力を受取るシェルが解釈して実行している.以前にも書いたが,このようなテキストファイルを SetUID モードにしてはいけない.特にスーパーユーザが所有しているときには厳禁である.


アカウントはあるのに ftp できないのですが? [1994.3]

「アカウントがあれば login や ftp ができる」というのは,正確ではない.telnet でその計算機を呼び出したり,シリアル回線を接続したとき,login プロンプトが表示される.ここでアカウント名を入れ,パスワードを入れたとき,実行されるのは,/etc/passwd ファイルの (コロンで区切られた) 第7欄に書いてあるプログラムである.一般ユーザは,ここに /bin/csh とか /bin/tcsh のように書いてある.これがログインシェルで,ファイルの実行や入出力の切替え,パイプの処理をやってくれる.入出力中の行や過去に入れたコマンドを編集できる機能のあるシェルも多い.だが,この第7欄にシェルでないプログラムも指定できる.この場合,アカウント名とパスワードを打ったところで,そのプログラムが起動され,そのプログラムが終了すると,いわばログアウトとなり,login プロンプトが再び表示される.UUCP を利用していれば,uucico が起動されるように記述してあるだろう.アカウントを作っても利用を制限するといったことがこれでできる.

ftp でホストを呼び出したときは,別の処理の流れとなる.呼び出されたホストで処理するのは,ftpd と呼ばれるデーモンプログラムである.login プロンプトを出したり,パスワードを尋ねて照合するのは,このプログラムが行なう.パスワードが合っていれば,そのまま ftpd が処理を続行する./etc/passwd ファイルの第 7欄のプログラムが実行されるわけではない.そうすると,第 7欄にシェルでないプログラム名を記述して,利用を制限しているアカウントでも,ftp が利用できることになる.これを避けるため,ファイル /etc/shells を参照する ftpd がある.ftp でログイン要求されたとき,アカウント名の /etc/passwd の第7欄に書いてあるプログラム名が /etc/shells に記述されているときだけ,ftp でのログインを許可する./etc/shells には,/bin/csh など,シェルプログラムのパス名を記述する.例えば GNU プロジェクトの bash など,フリーで入手できる新しいシェルプログラムをインストールして,/etc/passwd の第7欄に指定したときは,/etc/shells に追加しないと ftp ログインができない.

フリーのプログラムファイルなどを提供するために,誰にでも ftp ログインできる機能が ftpd に備わっている.ただし,利用側のホストがネームサーバに登録されていなかったり,IPアドレスからホスト名への逆引きのデータ (PTR リソースレコード) がないと,接続を拒否されることがある.身元を明らかにしていないホストとみなされるわけである.


ディスクフルに悩まされているのですが… [1994.4]

実装した容量にかかわらず,使用量は必ずその 90% を常に越えているといわれるのがディスクだ.ディスクフルには 2種類ある.ファイルの数が多くなって,i-node が足りなくなった場合と,ディスク容量が一杯になった場合だ.

i-node とは,ファイルやディレクトリ,デバイススペシャルファイル等の管理テーブルで,その数はファイルシステムを作るとき (man mkfs 参照) に決まる.また,テーブル自体がディスクに置かれている.総数はコマンド df -i で表示される.ネットワークニュースのようにファイルが大量に作られるときによく不足する.ファイルを消すこと,ファイルシステムを作り直すこと以外には解消できない.

ディスクの容量の使用状況はオプションなしの df コマンドで表示される.日常の使用状況で使用量が変化するのは,メール (ニュース) のスプール,tmp, 利用者のホーム,種々のログの置き場である.スプール,tmp は一時的に使用量が上ることがよくある.ログやホームは,周期が長めだ.スプールや tmp がルートパーティションに含まれているホストは注意が必要である.ルートパーティションは小さく作ることが多いのであふれやすい.ログは定期的に古いものを消去するように cron 等で設定してあるが,wtmp, pacct といったログインログアウトや投入コマンドのログは忘れがちである.ネットワークのケーブルが外れたようなときも,大量のログがファイルに書かれることが多い.

ホームは個人のマナーによる部分が多いが,たいていはごく小数の人でほとんどのディスクを占めているので,気をつけるのも容易である.ホームを集めたディレクトリ,例えば,/home で

du -s * | sort -nr | head -10

のようにすればよい.

find . -name '*core' -print

で残っているコアファイルもチェックしよう.シェルの limit コマンドでコアファイルを作らない設定も可能である.ls -ltu でファイルに最後にアクセスした日付時刻が表示されるので,使わないファイルは消すか圧縮してもらおう.また,ls -l で表示されるファイルサイズはディスク使用量とは必ずしも一致しない.ファイルの一部にディスクブロックが割り当てられていないことがある.ls -s で実際の使用量がわかる.

ディスクにはスーパユーザやその権限で実行しているデーモンプログラムのために容量を予約している.デフォルトは 10% であるが,最近の大容量ディスクではこの値は大き過ぎる.ファイルシステムを作るとき,tunefs といったコマンドでこの値を小さくすることができる.


† 最近の FreeBSD のデフォルトは 8% である.[2003.7.12]


インストールしたコマンドが見つからないのですが [1994.5]

UNIX のコマンドには,シェルの組み込みコマンドと,ファイルとなっているものの 2 種類がある.シェル組み込みにはシェルの変数の設定やコマンドの別名の作成に使うもの,繰り返しや条件判断などの制御構造を作るもの,高速化のため組み込みとなっているもの (echo や test など) がある.これらは直接シェルが実行するが,それ以外のコマンドはファイルになっている.実行ファイルは,UNIX の慣習により,/bin や /usr/bin などに置かれている./bin/ls ではなく,単に ls とだけ打ってもよいのは,コマンドが置かれているディレクトリ名をシェルに知らせてあるからだ.シェルはディレクトリのリストを path または PATH といった変数に格納している.コマンド名に / が含まれないとき,PATH のディレクトリを順番に探索してコマンドを見つける.コンパイルが成功したはずの実行ファイルが,command not found になるときには,ファイルを置いたディレクトリがパスにあるかどうかをまずチェックしよう. printenv や echo $path などと打てば表示される.一時的にパスを追加するなら,set path=(/local/bin $path) や PATH=/local/bin:$PATH などと打てばよい.さらに,csh では実行ファイルの探索に内部ハッシュ表を使って高速化を計っている.実行ファイルをパスのディレクトリに置いてもハッシュ表を更新しないとやはりコマンドは見つからない.シェル組み込みの rehash コマンドを実行しよう. コマンド探索はパスのディレクトリの順に行なって,最初に見つかったものを実行するので,同じ名前のファイルがパスにあると,目的のものと違うコマンドが実行されるので注意すること.

パスに . (ピリオド,カレントディレクトリを表わす) をいれるかどうかについては議論がある.特に,パスの先頭に . があるとき,例えば /tmp に su や rm といったファイルが置かれているとしよう./tmp の不要なファイルを消すため,cd /tmp して rm を実行したら,それは /tmp/rm が走ることになる./tmp/rm に悪意がないとはいえない.パスに . がないとき,カレントディレクトリのプログラムを実行するには ./file と打たなければならない../ に慣れれば . を取り去るのがもっともよい.

PATH 以外にも,MANPATH (マニュアルページのファイルのあるディレクトリ),LD_LIBRARY_PATH (動的リンクするライブラリファイルのあるディレクトリ) などのディレクトリリストが使われている.これらが適切に設定されているマシンは快適である.


UNIX カーネルの役割は? [1994.7]

ルートにある unix とか vmunix のファイルが UNIX カーネルと呼ばれるプログラムのファイルだ.マシンの立上げ時にこのファイルのデータ部,コード部は計算機のメモリに読み込まれ,計算機の動作中ずっと存在し続ける.ここには,ハードウェアの扱いやプロセスの生成といったサービスのルーティンがつまっている.

カーネルの仕事は,プロセス管理 (生成,実行順序制御,消滅後の後始末),ファイル管理 (作成,消去,ファイルへの読み書き),記憶領域管理,周辺装置 (ディスクや端末) とのやりとり,通信管理 (パイプもここ),ネットワーク制御,プロセスのトレース,時計,課金,と多岐にわたる. UNIX で走るプログラムで,カーネルの世話にならないプログラムは存在しない.サービスルーティンを呼び出すことが主であるプログラムはいくらでもある.

伝統的 UNIX のカーネルは,モノシリック (一枚岩) 構造であるといわれる.それは,すべての仕事をカーネルそのものが行なうからである.ディスク装置を扱うプロセス,メモリ管理を行なうプロセスといったものはない.さらに,UNIX には,カーネルのプロセスといった特別なプロセスもない.メモリ上のカーネルコードは,受動的な存在で,このコードはユーザプロセスそのものが実行する.カーネルが共通業務を請け負うと言っても,受付 (システムコールの発行がこれにあたる) にお願いすればすむのではなく,受付の奥まで自分ではいっていって,ひとまわり処理をしてくるのである.ただし,受付での身分チェック (スーパーユーザ資格か否か,など) や,カーネル内での行列まち,といったことはすべてカーネルコードに従うので,他のプロセスに迷惑をかけたり,勝手なことができるわけではない.システムコールの発行状況は trace コマンドで見ることができる.trace date と打ってみればいかにシステムコールが多く発行されるかがよくわかる

カーネルそのものはプロセスではないが,プロセスなしでは UNIX は働けない.システム動作のためにいくつものプロセスが常時存在している.プロセス番号1番をもつプロセス init はその代表でこれがすべてのプロセスの祖先である.このプロセスはマシンの立上げ時にカーネル内でいわば手づくりされる.このプロセスで /etc/rc 等の設定ファイルを解釈実行するプロセスを作り,システムの環境を整え,端末ごとにユーザのログインを待つプロセスを生成し,利用できる状態とする.近代的な UNIX では,init 以外にもプロセス番号の決まったプロセスがあって,システム動作を担っている.


FreeBSD 4.8 RELEASE では,trace コマンドは備わっていない.代わりに ktrace があるが,これはトレース結果をファイルに残す.よって,

ktrace date
kdump

のように実行する.

truss が trace にあたる.[2003.10.17]


   タイトル一覧  ホーム
webmaster