第1章 GNU/Linuxチュートリアル

目次

1.1. コンソールの基礎
1.1.1. シェルプロンプト
1.1.2. Xの下でのシェルプロンプト
1.1.3. rootアカウント
1.1.4. rootシェルプロンプト
1.1.5. GUIのシステム管理ツール
1.1.6. 仮想コンソール
1.1.7. コマンドプロンプトからの退出方法
1.1.8. シャットダウンの方法
1.1.9. まともなコンソールの回復
1.1.10. 初心者向け追加パッケージの提案
1.1.11. 追加のユーザアカウント
1.1.12. sudoの設定
1.1.13. お遊びの時間
1.2. Unix-likeファイルシステム
1.2.1. Unixファイルの基礎
1.2.2. ファイルシステムの内側
1.2.3. ファイルシステムのパーミッション
1.2.4. 新規作成ファイルのパーミッションのコントロール:umask
1.2.5. ユーザのグループ(group)のパーミッション
1.2.6. タイムスタンプ
1.2.7. リンク
1.2.8. 名前付きパイプ(FIFO)
1.2.9. ソケット
1.2.10. デバイスファイル
1.2.11. 特別なデバイスファイル
1.2.12. procfsとsysfs
1.3. ミッドナイトコマンダー(MC)
1.3.1. MCのカスタム化
1.3.2. MCの始動
1.3.3. MCのファイルマネージャ
1.3.4. MC のコマンドライントリック
1.3.5. MCの内部エディタ
1.3.6. MCの内部ビューア
1.3.7. MCの自動起動機能
1.3.8. MCのFTP仮想ファイルシステム
1.4. 基本のUnix的作業環境
1.4.1. loginシェル
1.4.2. Bashのカスタム化
1.4.3. 特別のキーストローク
1.4.4. Unix流のマウス操作
1.4.5. ページャ
1.4.6. テキストエディタ
1.4.7. デフォルトのテキストエディタの設定
1.4.8. Vimのカスタム化
1.4.9. シェル活動の記録
1.4.10. 基本Unixコマンド
1.5. シェルプロンプト
1.5.1. コマンド実行と環境変数
1.5.1.1. "$LANG"変数
1.5.1.2. "$PATH"変数
1.5.1.3. "$HOME"変数
1.5.2. コマンドラインオプション
1.5.3. シェルグロブ
1.5.4. コマンドの戻り値
1.5.5. 典型的なコマンドシーケンスとシェルリディレクション
1.5.6. コマンドエリアス
1.6. Unix的テキスト処理
1.6.1. Unixテキストツール
1.6.2. 正規表現
1.6.3. 置換表現
1.6.4. 正規表現を使ったグローバル置換
1.6.5. テキストファイルからのデータ抽出
1.6.6. コマンドをパイプするためのスクリプト断片

コンピュータシステムを学ぶことは新しい外国語を学ぶことに似ていると考えます。チュートリアルブックは有用ですが、実際に自ら使って学ぶことが必要です。円滑なスタートが出きるように、いくつかの基本的なポイントを説明します。

Debian GNU/Linux の強力なデザインは マルチユーザマルチタスク という Unix オペレーティングシステムに由来します。これら Unix と GNU/Linux の特徴や類似点の強力さを活用することを覚えましょう。

Unix対象の文書を避けたり、GNU/Linuxに関する文書だけに頼ることは、有用な情報を見逃すことになるので止めましょう。

一般的なシステム管理に関する良好なオンラインリソースは、Debianのnon-freeアーカイブにrutebookパッケージ (popcon: I:0.2)としてある"Ruteユーザのためのチュートリアルと解説書(Rute User's Tutorial and Exposition)" が提供しています。

[注意] 注意

Unix 的システムをコマンドラインツールで少々使った経験があれば、私がここで説明することはすべてご存知でしょう。リアリティーチェックと記憶を呼び戻すのにこれを使ってください。

1.1. コンソールの基礎

1.1.1. シェルプロンプト

X Windowシステムgdm等のディスプレイマネージャとともにインストールした場合以外には、システム起動の際に文字のloginスクリーンが現れます。あなたのホスト名がfooと仮定すると、loginプロンプトは次です:

foo login:

GNOMEKDEのようなGUI環境をインストールした場合には、Ctrl-Alt-F1とすることでloginプロンプトが出て、Alt-F7とすることでGUI環境に戻れます(詳細は下記の「仮想コンソール」参照)。

loginプロンプトであなたのユーザ名(例えばpenguin)を打鍵しEnterキーを押します。さらにあなたのパスワードを打鍵しEnterキーを再び押します。

[注意] 注意

Unixの伝統に従い、Debianシステムではユーザ名とパスワードに関して大文字小文字の区別をします。ユーザ名は通常小文字のみから選ばれます。最初のユーザアカウントは通常インストールの際に作られます。追加のユーザアカウントはrootによってadduser(8)を用いて作られます。

"/etc/motd" (本日のメッセージ:Message Of The Day)に保存されている歓迎メッセージとコマンドプロンプトで次のように表示しシステムが起動されます。

Debian GNU/Linux lenny/sid foo tty1
foo login: penguin
Password:
Last login: Sun Apr 22 09:29:34 2007 on tty1
Linux snoopy 2.6.20-1-amd64 #1 SMP Sun Apr 15 20:25:49 UTC 2007 x86_64

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
foo:~$

ここで、歓迎メッセージの主要部分は"/etc/motd.tail"ファイルを編集することでカスタマイズできます。最初の行は"uname -snrvm"用いたシステム情報から生成されます。

これであなたはシェルの中にいます。シェルはあなたからのコマンドを解釈します。

1.1.2. Xの下でのシェルプロンプト

インストールの際に"Desktop environment"タスクを選定しGNOMEgdmとともにX Windowシステムをインストールした場合には、システムの起動するとグラフィカルなloginプロンプトのスクリーンが表示されます。あなたのユーザ名とパスワードを入力することで非特権ユーザアカウントにloginできます。タブ(tab)を用いたりマウスの第一クリックを用いるとユーザ名とパスワードの間を行き来できます。

gnome-terminal(1)やrxvt(1)やxterm(1)のようなx-terminal-emulatorプログラムをXの下で起動するとシェルプロンプトが得られます。GNOMEデスクトップ環境下では、"Applications" → "Accessories" → "Terminal"とクリックしてもうまくいきます。

次の「仮想コンソール」も参照ください.

デスクトップ環境(例えばfluxbox)次第ではメニューの起点がよく分からないことがあります。そんな時はスクリーンの中央を(右)クリックしてメニューが表示されることを期待しましょう。

1.1.3. rootアカウント

rootアカウントはスーパーユーザとか特権ユーザとも呼ばれます。このアカウントからは次のようなシステム管理活動ができます:

  • ファイルのパーミッションによらずシステム上の任意ファイルに関しての、読み・書き・削除
  • システム上のいかなるファイルに関して、ファイルの所有者やパーミッション設定
  • システム上の非特権ユーザのパスワードを設定
  • パスワード無しに任意アカウントへのlogin

rootアカウントの権限を使うには、この無制限の権限ゆえ配慮と責任ある行動が求められます。

[警告] 警告

rootのパスワードを他人に決して教えてはいけない。

[注意] 注意

ファイル(Debianシステムにとってはファイルの一種であるCD-ROM等のハードウエアデバイスも含む)のパーミッションは、非rootユーザによるそのファイルの使用やアクセスをできなくなくすることがあります。この様な状況の下ではrootアカウントを使うことが簡便なテスト法ですが、問題解決はファイルのパーミッションとユーザのグループのメンバーシップを適切に設定する必要があります(「ファイルシステムのパーミッション」参照)。

1.1.4. rootシェルプロンプト

rootのパスワードを使ってrootのシェルプロンプトを使えるようにする基本的な方法を次に記します。

  • 文字ベースのloginプロンプトで、単にrootと入力します。
  • GNOMEデスクトップ環境下で、"Applications" → "Accessories" → "Root Terminal"とクリックします。
  • 何らかのユーザのシェルプロンプトから、"su -l"と入力します。(現ユーザの環境を一切引き継がない。)
  • 何らかのユーザのシェルプロンプトから、"su"と入力します。(現ユーザの環境をある程度引き継ぐ。)

1.1.5. GUIのシステム管理ツール

デスクトップのメニューがGUIのシステム管理ツールを適切な権限とともに自動的に起動しない場合、gnome-terminal(1)やrxvt(1)やxterm(1)のようなXターミナルエミュレータのrootシェルプロンプトから起動できます。

[警告] 警告

gdm(1)等のディスプレイマネージャのプロンプトにrootと入力して、Xディスプレイ/セッションマネージャをrootアカウントのもとで決して起動してはいけません。

[警告] 警告

クリチカルな情報が表示されている際には、あなたのXスクリーンを覗き見られるかもしれないのでリモートの信頼できないGUIプログラムを決して実行してはいけません。

1.1.6. 仮想コンソール

デフォルトのDebianシステムでは、6つの切り替え可能なVT100様の文字コンソールがあり、Linuxホスト上で直接コマンドシェルを起動できるようになっています。GUI環境下でない場合は、Left-Alt-keyF1F6の中の一つのキーを同時に押すことで仮想コンソール間の切り替えができます。仮想ターミナルそれぞれに独立したアカウントでログインすることができ、。マルチユーザ環境を提供します。このマルチユーザ環境はUnixの偉大な機能で、癖になります。

X Windowシステムの下では、Ctrl-Alt-F1キーを押す、つまりleft-Ctrl-keyleft-Alt-keyF1-keyキーを同時に押すと文字コンソール1にアクセスできます。通常仮想コンソール7で実行されているX WindowシステムへはAlt-F7を押すことにより戻れます。

これとは別の方法もあります。今と違う仮想ターミナルへ、例えば仮想ターミナル1への変更は次でできます:

# chvt 1

1.1.7. コマンドプロンプトからの退出方法

コマンドプロンプトでCtrl-D、つまりleft-Ctrl-keyd-keyの同時押しをするとシェルでのアクティビティーを終了できます。文字コンソールの場合は、こうするとloginプロンプト戻ります。これらのコントロール文字は通常"control D"と大文字を使って表記されますが、Shiftキーを押す必要はありません。またCtrl-Dに関する簡略表記^Dも使われます。この代わりに"exit"とタイプすることができます。

x-terminal-emulator(1)にあっては、このようにすることでx-terminal-emulator のウインドーが閉じることができます。

1.1.8. シャットダウンの方法

ファイル操作の際にパーフォーマンス向上のためにメモリへのデータのキャッシュがされる他の現代的なOSと同様に、Debianシステムでも電源を安全に切る前に適切なシャットダウン手順を取る必要があります。これはすべてのメモリ上の変更を強制的にディスクに書き出しすことで、ファイルの完全性を維持するためです。ソフトウエアによる電源コントロールができる場合、シャットダウン手続きはシステムの電源を自動的に落とします。(これがうまくいかない時には、シャットダウン手続きの後で数秒間電源ボタンを押す必要があるかもしれません。)

通常のマルチユーザモード下では、rootコマンドプロンプトから次によってシステムのシャットダウンをします:

# shutdown -h now

シングルユーザモード下では、rootコマンドプロンプトから次によってシステムのシャットダウンをします:

# poweroff -i -f

この他に、"/etc/inittab"に"ca:12345:ctrlaltdel:/sbin/shutdown -t1 -a -h now"と書かれていれば、Ctrl-Alt-Delete(left-Ctrl-keyleft-Alt-KeyDeleteの同時押し)を入力するシャットダウン方法もあります。

1.1.9. まともなコンソールの回復

例えば"cat <some-binary-file>"のような変な事をした後でスクリーンが無茶苦茶になった場合、コマンドプロンプトに"reset"と入力してください。このときコマンドを入力してもスクリーンには読み取れる表示がされないかもしれません。"clear"とすればスクリーンが消去できます。

1.1.10. 初心者向け追加パッケージの提案

デスクトップ環境タスク抜きの最小限インストレーションDebianシステムですら基本的なUnix機能は提供されますが、コマンドラインやcursesに基づくmcvim等のいくつかの文字ターミナルパッケージをaptitude(8)を使って追加インストールすることを初心者の最初の一歩としてお薦めします。

# aptitude update
...
# aptitude install mc vim sudo
...

既にこれらのパッケージがインストールされている場合には何もインストールされません。

表1.1 興味あるテキストモードのプログラムパッケージのリスト。

パッケージ popcon サイズ 説明
mc V:12, I:27 6364 テキストモードの全画面ファイルマネージャ
sudo V:44, I:74 592 ユーザに限定的なroot権限を与えるプログラム
vim V:14, I:30 1740 UnixテキストエディタVi IMproved(改良版Vi)、プログラマーのためのテキストエディタ(標準版)
vim-tiny V:18, I:90 828 UnixテキストエディタVi IMproved(改良版Vi)、プログラマーのためのテキストエディタ(軽量版)
emacs21 V:3, I:7 8176 GNUプロジェクトEmacs、Lispに基づく拡張可能なテキストエディタ(21版)
emacs22 V:4, I:7 11032 GNUプロジェクトEmacs、Lispに基づく拡張可能なテキストエディタ(22版)
w3m V:23, I:85 1968 テキストモードWWWブラウザ
gpm V:3, I:5 564 テキストコンソール上のUnix式のカットアンドペースト(daemon)

いくつかの参考資料を読むのも良いことです。

表1.2 有用な文書パッケージのリスト。

パッケージ popcon サイズ 説明
doc-debian I:83 376 Debianプロジェクトの文書、(Debian FAQ)他
debian-policy I:2 2740 Debianポリシーマニュアルと関連文書
developers-reference I:1.2 1348 Debian開発者のためのガイドラインと情報
maint-guide I:0.9 644 Debian新メンテナ向けガイド
debian-history I:0.4 2544 Debianプロジェクトの歴史
debian-faq I:45 1190 Debian FAQ(よくある質問集)
doc-linux-text I:83 8616 Linux HOWTOとFAQ(テキスト版)
doc-linux-html I:1.0 62564 Linux HOWTOとFAQ(HTML版)
sysadmin-guide I:0.3 964 Linuxシステム管理者ガイド
rutebook I:0.2 8264 Linux: Ruteユーザのためのチュートリアルと解説書(non-free)

これらのパッケージはrootのシェルプロンプトから次のコマンドを発行すればインストールできます。

# aptitude install package_name

1.1.11. 追加のユーザアカウント

次の練習のためにあなたのメインのユーザアカウントを使いたくない場合には、例えばfishという追加のユーザアカウントを作成できます。rootシェルプロンプトで次のように入力します。

# adduser fish
  • すべての質問に返事をする

こうすることでfishという名前の新しいアカウントが作られます。練習の後で、このユーザとそのホームディレクトリは次のようのすれば削除できます:

# deluser --remove-home fish

1.1.12. sudoの設定

ラップトップPC上のデスクトップのDebianシステム等のような典型的単一ユーザワークステーションでは次のような単純なsudo(8)の設定をして、非特権ユーザ(例えばpenguin)に管理者権限を(rootパスワードではなく)ユーザ自身のパスワードで与えることがよくあります。

# echo "penguin  ALL=(ALL) ALL" >> /etc/sudoers

このトリックの使用は、単一ユーザワークステーション上であなた自身が管理者でユーザである際のみに限るべきです。

[警告] 警告

システムセキュリティ上非常に悪い事態を招くので、マルチユーザワークステーション上の通常ユーザアカウントに対してこの様な設定をしてはいけません。

[注意] 注意

上記例のようなpenguinのパスワードとアカウントはrootパスワードやrootアカウント同様の保護が必要です。

[注意] 注意

この文脈上の管理者権限はワークステーションに関するシステム管理業務をする権限を与えられた人に属します。そのような権限と能力を持っていなければ、あなたの会社の管理部門の管理職や上司とはいえこのような権限を与えてはいけません。

[注意] 注意

特定デバイスや特定ファイルへのアクセスの権限を与えるには、sudo(8)をつかって得たroot権限を用いるのではなく、groupを使って限定的アクセス与えることを考えるべきです。

[注意] 注意

sudo(8)を使ってもう少し工夫された注意深い設定をすれば、共有システム上の他のユーザにrootパスワードを教えること無く限定的管理権限を許可することができます。こうすることは、誰が何をしたかを明らかにするので、複数の管理者がいるホストにおける責任の所在を明らかにします。ただ、誰にもそんな権限を与えたく無いかもしれません。

1.1.13. お遊びの時間

非特権ユーザアカウントを使う限り全くリスク無くDebianシステムでお遊びをする準備万端です。

何故なら、たとえデフォルトのインストール後ですらDebianシステムは非特権ユーザがシステムに損害を与えられないように的確なファイルパーミッションが設定されているからです。もちろん悪用可能な穴が残っているかもしれませんが、こんな問題まで心配する人はこのセクションを読んでいるべきではなく、Securing Debian Manualを読むべきです。

DebianシステムをUnix的システムとして以下で学びましょう:

1.2. Unix-likeファイルシステム

GNU/Linuxや他のUnix的オペレーティングシステムでは、ファイルディレクトリに整理されています。すべてのファイルやディレクトリは、"/"を根(root)に持つ一本の大きな木(ツリー)のようにアレンジされています。

この様なファイルやディレクトリはいくつかのデバイスに展開することができます。あるデバイス上にあるファイルシステムを大きなファイルツリーにマウントするのにmount(8)が使われます。その逆に、それを切り離すのにumount(8)が使われます。最近のLinuxカーネルでは、mount(8)をオプションとともに用いると、ファイルツリーの一部を別のところと結びつけたり、共有・非共有・従属・バインド不可としてファイルシステムをマウントもできます。各ファイルシステムごとの使用可能なマウントオプションは"/share/doc/linux-doc-2.6.*/Documentation/filesystems/"にあります。

Unixシステム上のディレクトリは、一部の他システム上ではフォルダと呼ばれます。Unixシステム上では"A:"のようなドライブというコンセプトが無いこと覚えておいてください。単一のファイルシステムがあって、そこにすべてが含まれています。これはWindowsと比べた際の大きな利点です。

1.2.1. Unixファイルの基礎

Unixファイルの基礎は以下です:

  • ファイル名は大文字と小文字を区別します。"MYFILE"と"MyFile"は異なるファイルです。
  • rootディレクトリはフィルシステムの根(root)を意味して、単に"/"と記載されます。これをrootユーザのhomeディレクトリ"/root"とは混同しないでください。
  • 全てのディレクトリには"/"以外の文字・記号からなる名前がついています。rootディレクトリは例外で、その名前は"/"("スラッシュ"とか"rootディレクトリ"と読まれます)でその名前を変えることはできません。
  • 各ファイルやディレクトリは、たどっていくとファイルに到達するディレクトリの列が示される、完全に記述したファイル名とか絶対ファイル名とかパスにより指定されます。これらの3つの表現は同義語です。
  • 全ての完全に記述したファイル名は"/"ディレクトリで始まり、ファイル名中の各ディレクトリやファイル名の間には"/"がはさまります。最初の"/"は ディレクトリ名です。その他の"/"は、次のサブディレクトリとの区別をします。そして最後には実際のファイルの名前がきます。ちょっと混乱しそうですので、次の完全に記述したファイル名 の例をご覧ください: "/usr/share/keytables/us.map.gz"。 一方このベース名である、"us.map.gz"だけをファイル名と呼ぶ人もあります。
  • root ファイルシステムは"/etc/"や"/usr/"のような複数の枝を持ちます。これらのサブディレクトリもまた"/etc/init.d/"や"/usr/local/"のように、さらにサブディレクトリに枝別れします。これらの全体をまとめてディレクトリツリーと呼びます。絶対ファイル名はツリーの根元("/")から枝の先 (ファイル) までの経路として考えることもできます。また、あたかもディレクトリツリーを家系図のように人が話すのを聞いたことがあるでしょう。あたかもそれぞれのサブディレクトリにがあるとし、パスはファイルの完全な祖先の系図のように表現します。root ディレクトリではない他の場所から始まる相対パスもあります。ディレクトリ"../"は親ディレクトリを参照していることを覚えておきましょう。このような呼び方はディレクトリのような構造を持つ他の階層的ツリー状のデータ構造体でもよく使われます。
  • ハードディスクのような物理デバイスに対応したパス名の要素は存在しません。ここが、パス名に"C:\"のようなデバイス名が含まれるRT-11CP/MOpenVMSMS-DOSAmigaOSMicrosoft Windowsと違う点です。(但し、通常のファイルシステム中に物理デバイスを示すディレクトリ項目はあります。「ファイルシステムの内側」参照。)
[注意] 注意

ほとんど全ての文字や記号をファイル名中に使えますが、実際そうすることは賢明ではありません。スペースやタブや改行や他の特殊文字:{ } ( ) [ ] ' ` " \ / > < | ; ! # & ^ * % @ $はコマンドラインで特別な意味を持つので避けるべきです。名前の中の単語間には、ピリオドやハイフンや下線を選んで区別しましょう。各語頭を"LikeThis"のように語頭を大文字にすることもできます。経験を積んだLinuxのユーザはファイル名中にスペースが入ることを避けます。

[注意] 注意

"root"と言う言葉は"rootユーザ"と言う意味でも"rootディレクトリ"意味でも使われます。それがいずれかは使われている文脈から明かです。

[注意] 注意

パスと言う言葉は上述の完全に記述したファイル名に関して使われるばかりではなくコマンドサーチパスにも使われます。どちらの意味かは文脈から明かです。

ファイル階層について詳細に学ぶ最も良い方法は、Filesystem Hierarchy Standard("/usr/share/doc/debian-policy/fhs/fhs-2.3.txt.gz"やhier(7))に記述されています。手始めとして次の事実を覚えるべきです。

表1.3 重要ディレクトリの使い方のリスト。

ディレクトリ 使い方
/ "/"だけだとrootディレクトリを表します。
/etc/ ここはシステム全体の設定ファイルを置く場所です。
/var/log/ ここはシステムのログファイルを置く場所です。
/home/ ここは全ての非特権ユーザのホームディレクトリがあるディレクトリです。

1.2.2. ファイルシステムの内側

Unix の伝統に従い、Debian/Linux システムはハードディスクや他のストレージデバイス上に存在する物理データを表すファイルシステムを提供し、コンソールスクリーンやリモートのシリアルコンソールなどのハードウェアデバイスとの相互作用が"/dev/"の下に統一された形式で表されています。

Debian/Linuxシステム上の、各々のファイルやディレクトリや名前付きパイプ(2つのプログラムがデータを共有する方法)や物理デバイスは、それぞれの所有者(owner)やデータが所属するグループ(group)や最終アクセス時間などの付帯属性(attribute)を記述するinodeと呼ばれるデータ構造を持ちます。 Debian GNU/Linux システムでの inode 構造 の正確な定義を知るには、"/usr/include/linux/fs.h" をご覧ください。 ほとんど全てをファイルシステム表現しようというアイデアはUnixの発明でしたし、現代的なLinuxカーネルはこのアイデアを一歩進めています。コンピュータ上で実行されているプロセス情報さえファイルシステム中に見つけられます。

このような物理的実体と内部プロセスの抽象的かつ統一された表現は非常にパワフルなので、多くの全く異なるデバイスに同じコマンドを使用して同種の操作が行えます。実行中のプロセスに繋がった特殊なファイルにデータを書き込むことでカーネルが如何に動作するかまで変更できます。

[ティップ] ティップ

ファイルツリーや物理的実体の間の関係を確認する必要がある際には、mount(8)を引数無しで実行してください。

1.2.3. ファイルシステムのパーミッション

Unix的システムのファイルシステムのパーミッションは次の3つの影響されるユーザのカテゴリのために定義されています:

  • ファイルを所有するユーザ(user)(u)
  • ファイルが所属するグループ(group)中の他ユーザ(g)
  • "世界"や"全員"とも呼ばれる、全他ユーザ(other)(o)

ファイルでは、それぞれに対応するパーミッションは次のようになります:

  • 読み(read) (r): ファイル内容確認可能
  • 書き(write) (w): ファイル内容変更可能
  • 実行(execute) (x): ファイルをコマンド実行可能

ディレクトリでは、対応するパーミッションはそれぞれ次のようになります:

  • 読み(read) (r): ディレクトリ内容リスト可能
  • 書き(write) (w): ディレクトリへのファイルの追加削除可能
  • 実行(execute) (x): ディレクトリ内のファイルへのアクセス可能

ここで、ディレクトリに関する実行(execute)許可とはディレクトリ内のファイルへの読みを許可するのみならず、サイズや変更時間のようなアトリビュート閲覧を許可します。

ファイルやディレクトリのパーミッション情報他を表示するには、ls(1)が使われます。"-l"オプション付きでこれを実行すると、次の情報がこの順序で表示されます:

  • ファイルのタイプ(最初の文字)
  • ファイルのアクセスパーミッション(次の9文字。ユーザとグループと他者の順にそれぞれに対して3文字から構成されている)
  • ファイルへのハードリンク数
  • ファイルを所有するユ-ザー(user)の名前
  • ファイルが所属するグループ(group)
  • ファイルのサイズ(文字数、バイト)
  • ファイルの日時(mtime)
  • ファイルの名前

表1.4 "ls -l"の出力の最初の文字のリスト

文字 意味
- 通常ファイル
d ディレクトリ
l シムリンク
c 文字デバイス名
b ブロックデバイス名
p 名前付きパイプ
s ソケット

rootアカウントからchown(1)を使用することでファイルの所有者を変更します。ファイルの所有者又はrootアカウントからchgrp(1)を使用することでファイルのグループを変更します。ファイルの所有者又はrootアカウントからchmod(1)を使用することでファイルやディレクトリのアクセス権を変更します。fooファイルの操作の基本的文法は次の通り:

# chown <newowner> foo
# chgrp <newgroup> foo
# chmod  [ugoa][+-=][rwxXst][,...] foo

例えば、ディレクトリツリーの所有者をユーザfooに変更し、グループbarで共有する場合、rootアカウントから次のコマンドを実行します:

# cd /some/location/
# chown -R foo:bar .
# chmod -R ug+rwX,o=rX .

更に特殊なパーミッションビットが3つ存在します:

  • セットユーザID (ユーザのxに代えてsS)。
  • セットグループID (グループのxに代えてsS)。
  • スティッキビット (他ユーザのxに代えてtT)。

ここで、これらのビットの"ls -l"のアウトプットはこれらの出力によってかくされた実行ビットが非設定(unset)の場合大文字となります。

セットユーザIDを実行ファイルにセットすると、ユーザはファイルの所有者ID(例えば、root) を使って実行ファイルを実行することを許可されます。同様に、セットグループIDを実行ファイルにセットすると、ユーザはファイルのグループID(例えば、root) を使って実行ファイルを実行することを許可されます。これらの設定はセキュリティを破壊するリスクを引き起こすので、これらのビットを有効にするには特別な注意が必要です。

セットグループIDsをディレクトリに対して有効にすると、ディレクトリに作成した全ファイルがディレクトリのグループに所属するというBSD的ファイル生成手法が有効になります。

スティッキビットをディレクトリに対して有効にすると、ディレクトリにあるファイルがファイルの所有者以外から削除されるのを防ぎます。"/tmp"やグループの書き込み可能なディレクトリなどのworld-writable なディレクトリにあるファイルの内容を安全にするためには、書き込みパーミッションを無効にするだけでなく、ディレクトリにスティッキビットもセットする必要があります。さもなければ、ディレクトリに書き込みできるユーザにより、ファイルが削除され、同じ名前で新しいファイルが作成されることを許してしまいます。

ファイルパーミッションの興味ある例を次にいくつか示します。

$ ls -l /etc/passwd /etc/shadow /dev/ppp /usr/sbin/exim4
crw------- 1 root root   108, 0 2007-04-29 07:00 /dev/ppp
-rw-r--r-- 1 root root     1427 2007-04-16 00:19 /etc/passwd
-rw-r----- 1 root shadow    943 2007-04-16 00:19 /etc/shadow
-rwsr-xr-x 1 root root   700056 2007-04-22 05:29 /usr/sbin/exim4
$ ls -ld /tmp /var/tmp /usr/local /var/mail /usr/src
drwxrwxrwt 10 root root  4096 2007-04-29 07:59 /tmp
drwxrwsr-x 10 root staff 4096 2007-03-24 18:48 /usr/local
drwxrwsr-x  4 root src   4096 2007-04-27 00:31 /usr/src
drwxrwsr-x  2 root mail  4096 2007-03-28 23:33 /var/mail
drwxrwxrwt  2 root root  4096 2007-04-29 07:11 /var/tmp

chmod(1)を用いて、ファイルパーミッションを記述するためのもう一つの数字モードが存在します。この数字モードは8進数を使った3桁から4桁の数字を用います。

表1.5 chmod(1)コマンドで用いられるファイルパーミッションの数字モード。

数字 意味
1桁目(任意) セットユーザID (=4)とセットグループID (=2)とスティキービット (=1)の和
2桁目 ユーザに関して、読み(read) (=4)と書き(write) (=2)と実行(execute) (=1)ファイル許可の和
3桁目 グループに関して、同上
4桁目 ユーザに関して、同上

これは複雑に聞こえるかもしれませんが、実際は本当にシンプルです。"ls -l"コマンドの出力の最初の数列(2〜10列)を見て、それをファイルパーミッションのバイナリ表記(2進数)("-"を"0"、"rwx"を"1""-")として読むと、この数字モードの値はファイルパーミッションの8進数表現として意味を持ちます。例えば、次を試してみてください:

$ touch foo bar
$ chmod u=rw,go=r foo
$ chmod 644 bar
$ ls -l foo bar
-rw-r--r-- 1 penguin penguin 17 2007-04-29 08:22 bar
-rw-r--r-- 1 penguin penguin 12 2007-04-29 08:22 foo
[ティップ] ティップ

シェルスクリプトから"ls -l"で表示される情報にアクセスする必要がある際には、test(1)やstat(1)やreadlink(1)のような適切なコマンドの使用を考えるべきです。シェル組込みコマンドの"["や"test"を使うのも手です。

1.2.4. 新規作成ファイルのパーミッションのコントロール:umask

新規作成ファイルのやディレクトリに適用されるパーミッションはumaskシェル組込みコマンドを使うことにより制限できます。dash(1)かbash(1)かbuiltins(7)をご覧ください。

 (file permissions) = (requested file permissions) & ~(umask value)

表1.6 umask値の例。

umask 使い方 作成されるファイルパーミッション 作成されるディレクトリパーミッション
0022 ユーザのみにより書込み可 -rw-r--r-- -rwxr-xr-x
0002 グループにより書込み可 -rw-rw-r-- -rwxrwxr-x

Debianシステムはユーザ専用グループ(UPG)方式がデフォルト方式です。新しいユーザがシステムに追加される毎にUPGは作成されます。UPGはそのグループを作成したユーザと同じ名前を持ち、そのユーザがUPGの唯一のメンバーです。UPG方式では、全ユーザが各自専用のグループを持つのでumaskを0002と設定しても安全です。(一部Unix系システムでは全一般ユーザを1つのusersグループに所属させることがよく行われます。そのような場合には安全のため0022とumaskを設定しましょう。)

1.2.5. ユーザのグループ(group)のパーミッション

グループのパーミッションを特定ユーザに適用するには、"sudo vigr"を用いてそのユーザをグループのメンバーにする必要があります。

[注意] 注意

もし"auth optional pam_group.so"行が"/etc/pam.d/common-auth"に書き加えれ、"/etc/security/group.conf"に対応する設定がされていれば、実際のユーザのグループメンバーシップは動的に割り当てられます。(4章認証参照。)

ハードウエアデバイスはDebianシステム上では一種のファイルでしかありません。CD-ROMやUSBメモリスティックのようなデバイスをユーザアカウントからアクセスするのに問題があった場合にはそのユーザを適切なグループのメンバーにしましょう。

いくつかのシステムが供給するグループはそのメンバーにroot権限無しに特定のファイルやデバイスにアクセスすることを可能にします。

表1.7 ファイルアクセスのためにシステムが供給する特記すべきグループのリスト。

グループ アクセスできるファイルやデバイス
dialout シリアルポート ("/dev/ttyS[0-3]")への全面的かつ直接のアクセス。
dip 信頼できるピアーにダイヤルアップIP接続をするためのシリアルポートへの制限付きアクセス。
cdrom CD-ROMやDVD+/-RWのドライバ。
audio 音声デバイス。
video 映像デバイス。
scanner スキャナ。
adm システムモニタのログ。
staff 下級管理業務のためのディレクトリ:"/usr/local"、"/home"。

[ティップ] ティップ

モデムの設定をしたりどこにでも電話したり等するにはdialoutグループに所属する必要があります。もし信頼できるピアーに関する事前定義された設定ファイル"/etc/ppp/peers/"がrootによって作成されていると、dipグループに属するだけでpppd(8)やpon(1)やpoff(1)コマンドを用いてダイヤルアップIP接続が作成できます。

いくつかのシステムが供給するグループはそのメンバーにroot権限無しに特定のコマンドを実行することを可能にします。

表1.8 特定コマンド実行のためにシステムが供給する特記すべきグループのリスト。

グループ 実行可能なコマンド
sudo パスワード無しにsudoを実行。
lpadmin プリンターのデータベースからプリンターを追加・変更・削除するコマンドの実行。
plugdev USBメモリのような着脱可能なデバイスに関してpmount(1)を実行。

システムが供給するユーザやグループの完全なリストは、base-passwdパッケージが供給する"/usr/share/doc/base-passwd/users-and-groups.html"の中にある最新バージョンの"Users and Groups"文書を参照ください。

ユーザやグループシステムを管理するコマンドはpasswd(5)やgroup(5)やshadow(5)やnewgrp(1)やvipw(8)やvigr(8)やpam_group(8)を参照ください。

1.2.6. タイムスタンプ

GNU/Linuxファイルのタイムスタンプには3種類あります。

表1.9 タイムスタンプのタイプのリスト。

タイプ 意味
mtime ファイル内容変更時間(ls -l)
ctime ファイル状態変更時間(ls -lc)
atime ファイル最終アクセス時間 (ls -lu)

ctimeはファイル作成日時でないことに注意しましょう。

  • ファイルが上書きされると、ファイルのmtimectimeatimeの属性すべてが変更されます。
  • ファイルの所有者や許可の変更をすると、ファイルのctimeatime アトリビュートを変えます。
  • ファイルを読むとファイルのatimeが変更されます。Debianシステム上のファイルを単に読むだけでinode中のatime情報を更新する書込みオペレーションが通常引き起こされることを覚えておいてください。ファイルシステムを"noatime"や"relatime"オプションを用いてマウントすることでシステムはこのようなオペレーションをしなくなるので、ファイルへの読みアクセスを高速化できます。ハードディスクの活動を抑えパワーの節約ができるのでこの様な設定はラップトップに推奨されます。mount(8)参照下さい。

既存ファイルのタイムスタンプを変更するにはtouch(1)コマンドを使ってください。

タイムスタンプに関して、現代の英語ロケール("en_US.UTF-8")では古い英語ロケール("C")と違った文字列がlsコマンドから出力されます。

$ LANG=en_US.UTF-8  ls -l foo
-rw-r--r-- 1 penguin penguin 3 2008-03-05 00:47 foo
$ LANG=C  ls -l foo
-rw-r--r-- 1 penguin penguin 3 Mar  5 00:47 foo
[ティップ] ティップ

"ls -l"の出力のカスタマイズは「Customized display of time and date」参照下さい。

1.2.7. リンク

"foo"というファイルを異なるファイル名"bar"に結びつけるのには2つの方法があります。

  • ハードリンクは既存のファイルに対する重複した名前です(ln foo bar)。
  • シンボリックリンクまたは"シムリンク"は名前により他のファイルを指し示す特別なファイルです(ln -s foo bar)。

リンク数の変化とrmコマンドの結果の微妙な違いについての次の例をご覧ください。

$ echo "Original Content" > foo
$ ls -li foo
2398521 -rw-r--r-- 1 penguin penguin 17 2007-04-29 08:15 foo
$ ln foo bar     # hard link
$ ln -s foo baz  # symlink
$ ls -li foo bar baz
2398521 -rw-r--r-- 2 penguin penguin 17 2007-04-29 08:15 bar
2398538 lrwxrwxrwx 1 penguin penguin  3 2007-04-29 08:16 baz -> foo
2398521 -rw-r--r-- 2 penguin penguin 17 2007-04-29 08:15 foo
$ rm foo
$ echo "New Content" > foo
$ ls -li foo bar baz
2398521 -rw-r--r-- 1 penguin penguin 17 2007-04-29 08:15 bar
2398538 lrwxrwxrwx 1 penguin penguin  3 2007-04-29 08:16 baz -> foo
2398540 -rw-r--r-- 1 penguin penguin 12 2007-04-29 08:17 foo
$ cat bar
Original Content
$ cat baz
New Content

ハードリンクは同一ファイルシステム内に作れ、ls(1)コマンドに"-i"オプションを使って表示されるinode番号が同じです。

シンボリックリンクは上の例に示したように、常にファイルアクセスパーミッション"rwxrwxrwx"を持ちますので、シンボリックリンクが指すファイルのアクセスパーミッションが有効ファイルアクセスパーミッションとなります。

[注意] 注意

もし特段の理由がないなら複雑なシンボリックリンクやハードリンクを作らない方が一般的には良いでしょう。シンボリックリンクの論理的組み合わせがファイルシステム中でループになっているという悪夢を引き起こすかもしれません。

[注意] 注意

もしハードリンクを使う特段の理由がなければ、ハードリンクよりシンボリックリンクを使う方が一般的には良いでしょう。

"."ディレクトリは、それ自身が中にあるディレクトリとリンクしていますので、新しいディレクトリリンク数は2から始まります。".."ディレクトリは親ディレクトリとリンクしているので、ディレクトリのリンク数は新しいサブディレクトリの増加に伴い増加します。

もし最近あなたがWindowsからLinuxに移動してきたなら、Unixのファイル名のリンクはWindows上でもっとも似ている"shortcuts"との比較で如何にうまくできているかにすぐ気づくでしょう。ファイルシステム中に実装されているのでアプリケーションからはリンクされたファイルなのかオリジナルなのかの区別がつきません。ハードリンクの場合は実際全く違いはありません。

1.2.8. 名前付きパイプ(FIFO)

名前付きパイプは、パイプのように働くファイルです。何かをファイルに入れると、もう一方の端からそれが出てきます。こうしてこれはFIFOまたはFirst-In-First-Out(先入れ先出し)と呼ばれます。つまり、最初にパイプに入れられたものが最初にもう一方の端から出てきます。

名前付きパイプに書き込んむ場合、パイプに書き込んむプロセスは情報がパイプから読み出されるまで終了しません。名前付きパイプから読み出す場合、読み出すプロセス何か読み込むものが無くなるまで終了するのを待ちます。パイプのサイズは常に 0 です。 -- 名前付きパイプはデータを保存せず、 シェルの"|"のように2つのプロセスをリンクするだけです。しかし、このパイプは名前を持つので、2つのプロセスは同じコマンドラインになくても良いし、同じユーザにより実行される必要さえありません。パイプはUnixの非常に影響力ある発明でした。

次を実行して試してください:

$ cd; mkfifo mypipe
$ echo "hello" >mypipe & # put into background
[1] 8022
$ ls -l mypipe
prw-r--r-- 1 penguin penguin 0 2007-04-29 08:25 mypipe
$ cat mypipe
hello
[1]+  Done                    echo "hello" >mypipe
$ ls mypipe
mypipe
$ rm mypipe

1.2.9. ソケット

ソケットはインターネットのコミュニケーションやデータベースやオペレーティングシステム自身によって頻繁に使われます。ソケットは名前つきパイプ(FIFO)に似ており、異なるコンピュータ間でさえプロセス間の情報交換を可能にします。ソケットにとって、これらのプロセスは同時に実行する必要も、同じ祖先プロセスの子供である必要もありません。これはプロセス間通信(IPC)の終端点です。ネットワーク越しで異なるホストの間で情報の交換をすることも可能です。2つの典型的なソケットは、インターネットソケットUnixドメインソケットです。

[ティップ] ティップ

"netstat -an"を実行すると特定のシステム上のソケットの全般状況がよく分かります。

1.2.10. デバイスファイル

デバイスファイルは、システム上のハードディスク、ビデオカード、ディスプレイ、キーボードなどの物理デバイス又は仮想デバイス等を意味します。仮想デバイスの例として"/dev/console"として表されるコンソールがあります。

表1.10 デバイスのタイプ

デバイスのタイプ 意味
文字デバイス 一度に1つの文字づつアクセスする、デバイスから書き込みや読み込みを行うデータの最小単位が文字(バイト)であるデバイスです。
ブロックデバイス ブロックと呼ばれる複数の文字を含む比較的大きな大きな単位でアクセスされるデバイスです。ハードディスクはブロックデバイスです。

デバイスファイルの読み書きが可能ですが、人間にとっては意味不明のバイナリデータがファイル中に多分含まれています。データを直接デバイスファイルに書き込むことは時々ハードウェアの接続に関するトラブルシュートに役立ちます。例えば、プリンタデバイス"/dev/lp0"にテキストファイルをダンプしたり、 適切なシリアルポート"/dev/ttyS0"にモデムコマンドを送ることができます。しかし、注意深くやらないと、大災害をもたらすことがあります。くれぐれも気をつけてください。

[注意] 注意

通常のプリンターへのアクセスはlp(1)を使いましょう。

ls(1)を次のように実行するとデバイスノード番号が表示されます:

$ ls -l /dev/hda /dev/ttyS0 /dev/zero
brw-rw---- 1 root cdrom   3,  0 2007-04-29 07:00 /dev/hda
crw-rw---- 1 root dialout 4, 64 2007-04-29 07:00 /dev/ttyS0
crw-rw-rw- 1 root root    1,  5 2007-04-29 07:00 /dev/zero

上記で:

  • "/dev/hda"はメジャーデバイス番号3とマイナーデバイス番号0を持ちます。これはdiskグループに所属するユーザにより、読み書きアクセスが可能です。
  • "/dev/ttyS0" はメジャーデバイス番号4とマイナーデバイス番号64を持ちます。これはdialoutグループに所属するユーザにより、読み書きアクセスが可能です。
  • "/dev/zero" はメジャーデバイス番号1とマイナーデバイス番号5を持ちます。これは誰によっても読み書きアクセスが可能です。

Linux 2.6システムでは、"/dev/"の下のファイルはudev(7)メカニズムで自動的に生成されます。

1.2.11. 特別なデバイスファイル

いくつかの特別なデバイスファイルがあります。

表1.11 スペシャルなデバイスファイルのリスト。

デバイスファイル アクション レスポンス
/dev/null 読み "行末(EOF)文字"を返します。
/dev/null 書き 底なしのデータのゴミ捨て場です。
/dev/zero 読み "\0 (NUL)文字"を返します(ASCIIの数字のゼロとは違います)。
/dev/random 読み 真の乱数発生機から真のエントロピーのあるランダムな文字を返す。(遅い)
/dev/urandom 読み 暗号学的にセキュアな擬似乱数発生機からランダムな文字を返す。
/dev/full 書き ディスクフル(ENOSPC)エラーを返す。

以上はシェルのリディレクションとともによく使われます。(「典型的なコマンドシーケンスとシェルリディレクション」参照)。

1.2.12. procfsとsysfs

procfssysfsは"/proc"や"/sys"上にマウントされる仮想ファイルシステムであり、カーネルの内部データ構造をユーザスペースにさらけ出します。言い換えると、オペレーティングシステムのオペレーションへの便利なのぞき窓となると言う意味で仮想といえます。

"/proc"ディレクトリ中には、システム上で実行されている各プロセスに対応したそのプロセスID(PID)の名前がついたサブディレクトリ他があります。プロセス情報をアクセスするps(1)のようなシステムユーティリティはこのディレクトリ構造からその情報を得ています。

"/proc/sys/"の下のディレクトリには実行時のカーネル変数を変更するインターフェースがあります。(専用のsysctl(8)コマンドもしくはその起動/設定ファイル"/etc/sysctrl.conf"によっても同様のことができます。)

[注意] 注意

Linuxカーネルが"Too many open files"とエラーを出力することがあります。rootのシェルから、例えば"echo "65536" > /proc/sys/fs/file-max"等と"file-max"の値をより大きな値に増加することで解決できます。(古いカーネルではこれが必要でした。)

特にあるファイル - "/proc/kcore" - に気づくと、パニックになる人がよくいます。これは一般に巨大です。これは(おおよそ)コンピュータのメモリの内容のコピーです。これは kernel をデバッグするのに用いられます。コンピュータのメモリを指す仮想ファイルなので、そのサイズに関して心配する必要は全くありません。

"/sys"の下のディレクトリはカーネルから引き出されたデータ構造、その属性、それらの関連を含んでいます。一部カーネル変数を実行時に変更する機構もまた含まれたりします。

linux-doc-2.6.*パッケージで供給されるLinuxカーネル文書("/usr/share/doc/linux-doc-2.6.*/Documentation/filesystems/*")中の"proc.txt(.gz)"や"sysfs.txt(.gz)"や関連する他の文書を参照下さい。

1.3. ミッドナイトコマンダー(MC)

Midnight Commander (MC)はLinux コンソールや他の端末環境のためのGNU製"スイス軍ナイフ"です。標準Unixコマンドを習うよりもより簡単なメニューを使ったコンソール経験が初心者にもできます。

"mc"と名づけられた Midnight Commanderパッケージをインストールする必要があります。

$ sudo aptitude install mc

Debian システムを探検するためにmc(1)コマンドを使いましょう。これは学習するための最良の方法です。カーソルキーとエンターキーを使うだけでいくつかの主要な場所を探検してください。

  • "/etc"とサブディレクトリ。
  • "/var/log"とサブディレクトリ。
  • "/usr/share/doc"とサブディレクトリ。
  • "/sbin"と"/bin"。

1.3.1. MCのカスタム化

終了時に作業ディレクトリをMCに変更させそのディレクトリへcdさせるためには、"~/.bashrc"を次を含むように変更しましょう:

. /usr/share/mc/bin/mc.sh

この理由はmc(1) ("-P"オプション項目) を参照下さい(今言っていることがよく分からないなら、これは後日しても大丈夫です。)

1.3.2. MCの始動

MCは次のようにして始動できます:

$ mc

MCを使うとメニューを通じた最小限のユーザの努力で全てのファイル操作の面倒が見られます。ヘルプ表示を出すには、ただF1を押すだけです。カーソルキーとファンクションキーの操作だけでMCを使えます。

[注意] 注意

gnome-terminal(1)のようなコンソールでは、ファンクションキーのキーストロークがコンソールプログラムに横取りされる事があります。gnome-terminalの場合、"Edit" → "Keyboard Shortcuts"とするとこの機能を無効にできます。

もし文字化け表示がされる文字エンコーディング問題に出会った際には、MCのコマンドラインに"-a"を加えると解消する事があります。

これでもMCの表示の問題が解消しない際には、「ターミナルの設定」を参照下さい。

1.3.3. MCのファイルマネージャ

2つのディレクトリパネルがありそれぞれファイルリストを含むのが標準です。他の便利なモードとしては、右側のウィンドウを"information" とセットしてファイルアクセス権情報などを表示するモードがあります。次にいくつかの不可欠なキーストロークを示します。gpm(8)デーモンを実行すると、Linuxの文字ターミナルでマウスも使えます。(MC で通常の挙動のカットアンドペーストをさせるには、shiftキーを押してください。)

表1.12 MCのキーバインディング

キー キーバインディング
F1 ヘルプメニュー
F3 内部ファイルビューア
F4 内部エディタ
F9 プルダウンメニューを有効にする
F10 MCを終了する
Tab 二つのウィンドウの間を移動する
InsertもしくはCtrl-T コピーのような複数ファイル操作のため、ファイルにマークをする
Del ファイルの削除 (気をつけましょう -- MCを安全削除モードに設定)
カーソルキー 自明

1.3.4. MC のコマンドライントリック

  • cdコマンドは選択されたスクリーンに表示されたディレクトリを変更します。
  • Ctrl-EnterAlt-Enterはファイル名をコマンドラインにコピーします。コマンドライン編集と一緒にcp(1)やmv(1)コマンドで御使用ください。
  • Alt-Tabはシェルファイル名の自動展開の選択肢を表示します。
  • MCの引数で両ウインドウの開始ディレクトリを指定できます。例えば"mc /etc /root"。
  • Esc + n-keyFn (つまり、Esc + 1F1、等々、Esc + 0F10)
  • Escをキーの前に押すのはAltをキーと同時に押すのと同様の効果があります。つまり、Esc + cAlt-Cと同じです。Escはメタキーとよばれ時々"M-"と表記されます。

1.3.5. MCの内部エディタ

MC の内部エディタは興味深いカットアンドペースト機構を持ちます。F3キーを押すと、選択範囲の開始としてマークし、次にF3を押すと、選択範囲の終了としてマークし、選択範囲を強調します。そしてカーソルを動かすことができます。F6を押すと、選択範囲はカーソルの位置に移動します。F5を押すと、選択範囲はコピーされ、カーソルの位置に挿入されます。F2を押すとファイルをセーブします。F10を押すと選択範囲はなくなります。ほとんどのカーソルキーは直感的に働きます。

このエディタは直接ファイルに関しても起動できます:

$ mc -e filename_to_edit
$ mcedit filename_to_edit

これはマルチモードエディタではありませんが、複数の Linux コンソール上で使用すると同じ効果を発揮させされます。ウィンドウ間のコピーを行うには、 Alt-<n>キーを押して仮想コンソールを切替えて、"File→Insert file"や"File→Copy to file"を用いてファイルの一部を他のファイルに動かします。

この内部エディタはお好きな他の外部エディタと置き換えが可能です。

また、多くのプログラムは使用するエディタを決定するために環境変数"$EDITOR"や"$VISUAL"を使用します。最初vim(1)やnano(1)が使いにくい場合には"~/.bashrc"に次に示す行を追加してエディタを"mcedit"に設定するのも一計です。

...
export EDITOR=mcedit
export VISUAL=mcedit
...

できればこれは"vim"に設定することを推奨します。

vim(1)が使いにくい場合には、mcedit(1)をほとんどのシステム管理業務のために使い続けられます。

1.3.6. MCの内部ビューア

非常に小さなビューアです。文書内の単語を検索するための素晴らしいツールです。私は"/usr/share/doc"ディレクトリ内のファイルに対していつもこれを使います。これは 大量にあるLinux情報を閲覧するための最速の方法です。このビューアはこのように直接起動できます。

$ mc -v path/to/filename_to_view
$ mcview path/to/filename_to_view

1.3.7. MCの自動起動機能

ファイルの上でEnterを押すと、適切なプログラムがファイル内容を処理します(「Customizing program to be started」参照)。これは非常に便利な MC の機能です。

表1.13 キー入力へのMCの反応

ファイルタイプ enterキーへの反応
実行ファイル コマンド実行
manファイル ビューアソフトに内容をパイプする
htmlファイル ウエッブブラウザに内容をパイプする
"*.tar.gz"や"*.deb"ファイル サブディレクトリであるかのように内容を表示

これらのビューアや仮想ファイルの機能を有効にするためには、閲覧可能なファイルには実行可能と設定されていてはいけません。chmod(1)コマンドを使うか、MC のファイルメニュー経由で状態を変更してください。

1.3.8. MCのFTP仮想ファイルシステム

MCをInternet越しでのFTPを用いたファイルアクセスに使えます。F9を押してメニューに行き、"p"を押してFTP仮想ファイルシステムを有効にします。"username:passwd@hostname.domainname"の形式でURLを入力すると、あたかもローカルにあるかのようにリモートディレクトリを取得します。

"[http.us.debian.org/debian]"をURLとしてDebianアーカイブを閲覧しましょう。

1.4. 基本のUnix的作業環境

MCはほとんど全てのことを可能にしますが、シェルプロンプトから実行されるコマンドラインツールの使用方法について学び、Unix的な作業環境に親しむのは非常に重要なことです。

1.4.1. loginシェル

ログインシェルはchsh(1)を使えば選択できます。

表1.14 シェルプログラムのリスト。

パッケージ popcon サイズ POSIXシェル 説明
bash V:91, I:99 1336 はい Bash:GNU Bourne Again SHell(事実上の標準シェル)
tcsh V:8, I:55 736 いいえ TENEX C Shell:拡張バージョンのBerkeley csh
dash V:3, I:12 236 はい DebianのAlmquistシェル。シェルスクリプトに好適。
zsh V:2, I:5 12752 はい Z shell:多くの拡張された標準シェル。
pdksh V:0.3, I:1.2 464 はい A public domain version of the Kornシェル.
csh V:0.6, I:1.8 404 いいえ OpenBSDのCシェル、Berkeley cshの1バージョン。
sash V:0.2, I:1.0 836 はい 組み込みコマンド付きの独立シェル。(標準の"/bin/sh"には向きません。)
ksh V:0.4, I:1.5 2860 はい 真のAT&TバージョンのKornシェル
rc V:0.09, I:0.7 204 いいえ AT&T Plan 9rcシェルの実装。
posh V:0.01, I:0.14 232 はい ポリシー準拠の通常シェル。pdkshの派生。

このチュートリアル章内では、インタラクティブなシェルは常にbashです。

1.4.2. Bashのカスタム化

bash(1)の動作は"~/.bashrc"でカスタマイズできます。例えば次を"~/.bashrc"に加えます:

# CD upon exiting MC
. /usr/share/mc/bin/mc.sh

# set CDPATH to good one
CDPATH=.:/usr/share/doc:~/Desktop/src:~/Desktop:~
export CDPATH

PATH="${PATH}":/usr/sbin:/sbin
# set PATH so it includes user's private bin if it exists
if [ -d ~/bin ] ; then
  PATH=~/bin:"${PATH}"
fi
export PATH

EDITOR=vim
export EDITOR
[ティップ] ティップ

bashに関する更なるカスタマイズ方法は、9章System tips中の「Colorized commands」等にあります。

1.4.3. 特別のキーストローク

Unix的環境下では、特別の意味を持ったいくつかのキーストロークがあります。通常のLinuxの文字ターミナルでは左側のCtrlAltキーのみが期待にそって機能することに配慮下さい。次に特記すべき暗記するべきキーストロークを記します。

表1.15 Bashのキーバインディングのリスト。

キー キーバインディング
Ctrl-U カーソルの前の1行を消去します。
Ctrl-H カーソルの前の1文字を削除します。
Ctrl-D 入力を終了します。(シェルを使用中の場合、シェルを終了します)
Ctrl-C 実行中のプログラムを終了します。
Ctrl-Z 一時的にプログラムをバックグラウンドジョブに入れ停止します。
Ctrl-S スクリーンへの出力を停止します。
Ctrl-Q スクリーンへの出力を再開します。
Ctrl-Alt-Del システムをリブート/停止します、inittab(5)を参照下さい。
Left-Altキー (もしくは、Windowsキー) Emacsおよび同様のUIでのメタキー
Up-arrow bashでコマンド履歴検索を開始します。
Ctrl-R bashでインクリメンタルなコマンド履歴検索を開始します。
Tab bashのコマンドラインでファイル名の入力を完結します。
Ctrl-V Tab bashのコマンドラインでTabを展開することなく入力します。

[ティップ] ティップ

ターミナルのCtrl-S機能はstty(1)で無効にできます。

1.4.4. Unix流のマウス操作

Unix流のマウス操作は3ボタンマウスが基本です。

表1.16 Unix流のマウス操作のリスト

アクション レスポンス
マウスの左クリックアンドドラッグ 選択とクリップボードへのコピー。
左クリック 選択開始点の選択。
右クリック 選択終了点の選択とクリップボードへのコピー。
中クリック クリップボードをカーソル位置に挿入。

最近のホイールマウスの真ん中のホイールは中マウスボタンと見なされ、中クリックに使えます。2ボタンマウス状況では左右のボタンの同時押しが中クリックとして使えます。Linuxの文字コンソールでマウスを使うにはgpm(8)をデーモンで実行する必要があります。

1.4.5. ページャ

less(1)は機能拡張されたページャ(ファイル内容のブラウザ)です。"h" と入力するとヘルプが表示されます。これは、more(1) よりもはるかに機能があり、"eval $(lesspipe)"または"eval $(lessfile)"とシェルの開始スクリプト中で実行することで更に機能拡充されます。詳しくは、"/usr/share/doc/lessf/LESSOPEN"を参照下さい。"-R"オプションを用いると生の option allows raw文字出力が許可され、ANSIカラーエスケープシーケンスが有効になります。less(1)参照下さい。

1.4.6. テキストエディタ

Unix的システムで人気のある、VimEmacsプログラムのいずれかのバリアントに習熟するべきです。

著者としてはVimコマンドに慣れることは正しいことだと考えています。なぜならViエディタはLinux/Unixの世界では必ず存在するからです。(実際はオリジナルのviか、新しいnviがどこででも見つけられるプログラムです。これにもかかわらずVimを著者が初心者のために選んだのは、より強力かつ動作が充分似ているのと、F1キーを通じてヘルプが表示されるからです。)

これとは違い、EmacsXEmacsをエディタとして選ぶのも、特にプログラムをするには、非常に良い選択です。Emacsには、ニュースリーダ機能、ディレクトリの編集機能、メール機能他の、過多な機能があります。プログラミングやシェルスクリプトの編集に使うときは、作業中のフォーマットをインテリジェントに認識し助力をしようとします。Linux上で必要なプログラムはEmacsだけと考える人もいます。Emacsを今10分間学ぶことは将来何時間もの節約になります。Emacsを学ぶ際にはGNUのEmacsマニュアルを持っておくことを高く推薦します。

これら全てのプログラムには練習しながら学べるようにチュータリングプログラムが普通付いてきます。Vimを"vim"とタイプして起動し、F1キーを押しましょう。最初の35行を読みましょう。カーソルを"|tutor|"に移動しCtrl-]を押してオンラインの訓練コースを始めましょう。

[注意] 注意

VimやEmacsのような良いエディタは、正しいフォント設定がされたUTF-8ロケールの下の正しいオプションを使ったx-terminal-emulatorを使うと、UTF-8や他のエギゾチックなエンコーディングのテキストを正しく扱えます。マルチバイトテキストに関するそれぞれの文書を参照下さい。

1.4.7. デフォルトのテキストエディタの設定

Debianにはいくつかの異なったエディタがあります。上述のようにvimパッケージをインストールすることを推薦します。

Debianではシステムのデフォルトのエディタへの統一されたアクセスを"/usr/bin/editor"コマンドを通じて提供しているので、他のプログラム(例えばreportbug(1)等)が起動できます。設定変更は:

$ sudo update-alternatives --config editor

著者が"/usr/bin/vim.tiny"より"/usr/bin/vim.basic"を初心者に推薦するのはシンタクスハイライトをサポートしているからです。

[ティップ] ティップ

多くのプログラムは"$EDITOR"か"$VISUAL"という環境変数を使ってどのエディタを使うかを決めます(「MCの内部エディタ」「Customizing program to be started」参照)。Debianシステムの整合性のために、これらを"/usr/bin/editor"と設定しましょう。(歴史的には"$EDITOR"は"ed"で、"$VISUAL"は"vi"でした。)

1.4.8. Vimのカスタム化

vim(1)の挙動は"~/.vimrc"を使ってカスタマイズできます。例えば著者は次を使ってます:

" -------------------------------
" Local configuration
"
set nocompatible
set nopaste
set pastetoggle=<f2>
syn on
if $USER == "root"
 set nomodeline
 set noswapfile
else
 set modeline
 set swapfile
endif
" filler to avoid the line above being recognized as a modeline
" filler
" filler

1.4.9. シェル活動の記録

シェルコマンドの出力はスクリーンから押し出されると永久に無くなってしまうかもしれません。シェルでの活動を後で見直せるようにファイルに記録しておくのは良いことです。この種の記録は何らかのシステム管理作業をする際には非常に重要です。

シェル活動の記録の基本方法はscript(1)の下で実行することです。

$ script
Script started, file is typescript
  • 何らかのシェルコマンドの実行 …
  • Ctrl-Dを押してscriptから脱出。
$ vim typescript

「Recording the shell activities cleanly」参照下さい。

1.4.10. 基本Unixコマンド

基本的Unixコマンドを学びましょう。ここでは一般的意味で"Unix"を使っています。いかなるUnixクローンのOSも等価なコマンドを提供します。Debianシステムも例外ではありません。今一部コマンドが思うように機能しなくても心配しないで下さい。エアリアスがシェルで使われた場合は、対応するコマンドの出力は変わります。次は順番に実行すると言う意味の例ではありません。

非特権ユーザのアカウントから次のコマンドを全て実行しましょう:

表1.17 基本のUnixコマンドのリスト。

コマンド 説明
pwd カレント/ワーキングディレクトリの名前を表示。
whoami 現在のユーザ名を表示します。
id 現在のユーザのアイデンティティ(名前とuidとgidと関連するgroup)を表示します。
file <foo> "<foo>"ファイルのファイルタイプを表示します。
type -p <commandname> "<commandname>"コマンドのファイルの位置を表示します。
which <commandname> , ,
type <commandname> "<commandname>"コマンドに関する情報を表示します。
apropos <key-word> "<key-word>"に関連したコマンドを見つけます。
man -k <key-word> , ,
whatis <commandname> "<commandname>"コマンドに関する1行の説明を表示します。
man -a <commandname> "<commandname>"コマンドに関する説明を表示します。(Unixスタイル)
info <commandname> "<commandname>"コマンドに関する比較的長い説明を表示します。(GNUスタイル)
ls ディレクトリの内容をリストします。(非ドットファイルおよびディレクトリ)
ls -a ディレクトリの内容をリストします。(全ファイルおよびディレクトリ)
ls -A ディレクトリの内容をリストします。(ほとんど全ファイルおよびディレクトリ、".."と"."をスキップ)
ls -la ディレクトリの内容を詳細情報とともにリストします。
ls -lai ディレクトリの内容をinode番号と詳細情報とともにリストします。
ls -d 現ディレクトリの中の全ディレクトリをリストします。
tree ファイルツリーの内容を表示します。
lsof <foo> "<foo>"ファイルのオープンの状態をリスト。
lsof -p <pid> プロセスID: "<pid>"によってオープンされたファイルをリストします。
mkdir <foo> 現ディレクトリ中に"<foo>"という新規ディレクトリを作る。
rmdir <foo> 現ディレクトリ中の"<foo>"というディレクトリを削除します。
cd <foo> 現ディレクトリ中もしくは"$CDPATH"変数中にリストされたディレクトリ中の"<foo>"というディレクトリにディレクトリを変更します。
cd / ディレクトリをrootディレクトリに変更します。
cd 現在のユーザのホームディレクトリにディレクトリを変更します。
cd /<foo> 絶対ディレクトリパス"/<foo>"にディレクトリを変更する。
cd .. 親ディレクトリにディレクトリを変更します。
cd ~<foo> ユーザ"<foo>"のホームディレクトリにディレクトリを変更します。
cd - 一つ前のディレクトリにディレクトリを変更します。
</etc/motd pager "/etc/motd"の内容をデフォルトのページャで表示します。
touch <junkfile> 空ファイル"<junkfile>"を作成します。
cp <foo> <bar> 既存のファイル"<foo>"を新規ファイル"<bar>"にコピーします。
rm <junkfile> ファイル"<junkfile>"を削除します。
mv <foo> <bar> 既存のファイル"<foo>"の名前を新しい名前"<bar>"に変更します。ディレクトリ"<bar>"が存在してはいけません。
mv <foo> <bar> 既存のファイル"<foo>"を新しい場所"<bar>/<foo>"に移動します。ディレクトリ"<bar>"が存在しなければいけない。
mv <foo> <bar>/<baz> 既存のファイル"<foo>"を新しい場所の新しい名前のファイル"<bar>/<baz>"に移動します。ディレクトリ"<bar>"が存在しなければいけないが、ディレクトリ"<bar>/<baz>"は存在してはいけない。
chmod 600 <foo> 既存のファイル"<foo>"を他の人から読みも書きもできないようにします。(全ての人にとって実行不可)
chmod 644 <foo> 既存のファイル"<foo>"を他の人からは読めるが書けるようにします。(全ての人にとって実行不可)
chmod 755 <foo> 既存のファイル"<foo>"を他の人からは読めるが書けるようにします。(全ての人にとって実行可能)
find . -name <pattern> シェルで"<pattern>"にマッチするファイル名を探す。(比較的遅い)
locate -d . <pattern> シェルで"<pattern>"にマッチするファイル名を探す。(定期的に生成されるデータベースを使い比較的早い)
grep -e "<pattern>" *.html 現ディレクトリにある".html"で終わる全ファイルから"<pattern>"のパターンを検索し、該当する全ファイルを表示します。
top フルスクリーンを用いてプロセス情報を表示します。"q"を押して終了します。
ps aux | pager 起動中の全プロセスの情報をBSDスタイルの出力を用いて表示します。
ps -ef | pager 起動中の全プロセスの情報をSystem-Vスタイルの出力を用いて表示。
ps aux | grep -e "[e]xim4*" "exim"もしくは"exim4"の起動中の全プロセスを表示。
ps axf | pager 起動中の全プロセスの情報をASCIIアート出力を用いて表示。
kill <1234> プロセスID"<1234>"により識別されるプロセスを殺す。
gzip <foo> Lempel-Zivコーディング(LZ77)を用いて"<foo>"を圧縮し"<foo>.gz"を作成します。
gunzip <foo>.gz "<foo>.gz"を解凍して"<foo>"を作成します。
bzip2 <foo> Burrows-Wheelerブロックソートテキスト圧縮アルゴリズムとHuffmanコーディングを用いて"<foo>"を圧縮し"<foo>.bz2"を作成します。(gzipより高圧縮率)
bunzip2 <foo>.bz2 "<foo>.bz2"を解凍して"<foo>"を作成します。
tar -xvf <foo>.tar "<foo>.tar"アーカイブからファイルを展開します。
tar -xvzf <foo>.tar.gz gzip圧縮された"<foo>.tar.gz"アーカイブからファイルを展開します。
tar -xvf -j <foo>.tar.bz2 "<foo>.tar.bz2"アーカイブからファイルを展開します。
tar -cvf <foo>.tar <bar>/ フォルダ"<bar>/"の内容を"<foo>.tar"アーカイブにアーカイブします。
tar -cvzf <foo>.tar.gz <bar>/ フォルダ"<bar>/"の内容を"<foo>.tar.gz"アーカイブに圧縮アーカイブします。
tar -cvjf <foo>.tar.bz2 <bar>/ フォルダ"<bar>/"の内容を"<foo>.tar.bz2"アーカイブに圧縮アーカイブします。
zcat README.gz | pager 標準のページャを用いて圧縮された"README.gz"の内容を表示します。
zcat README.gz > foo "README.gz"の内容を解凍してファイル"foo"を作成します。
zcat README.gz >> foo 圧縮された "README.gz"の内容をファイル"foo"の末尾に追加します。(ファイルが存在しない場合は事前に作成される。)

[注意] 注意

Unixは"."で始まるファイル名を隠す伝統があります。それらは伝統的には特定の設定情報やユーザの嗜好を含むファイルです。

[注意] 注意

cdコマンドに関してはbuiltins(7)を参照下さい。

[注意] 注意

最小限のDebianシステムのデフォルトのページャはmore(1)で、スクロールバックができません。lessパッケージを"aptitude install less"と言うコマンドラインでインストールすると、less(1)が デフォルトのページャになりカーソルキーでスクロールバック出来るようになります。

[注意] 注意

上記の"ps aux | grep -e "[e]xim4*""コマンド中に現れる正規表現中の"["と"]"はgrepが自分自身にマッチするのを避けることを可能とします。正規表現中の"4*"は数字"4"の0回以上の繰り返しを意味するので、grepが"exim"と"exim4"の両方にマッチすることが可能になります。 "*"はシェルのファイルネームのグロブでも正規表現ででも使われますが、これらの意味は異なります。grep(1)から正規表現を学びましょう。

上記のコマンドを訓練として用いて、ディレクトリを渡り歩き、システムの中を覗き込んでください。コンソールのコマンドに関して質問がある場合は、必ずマニュアルページを読んでみてください。例えば、これらのコマンドは良い開始点でしょう:

$ man man
$ man bash
$ man builtins
$ man grep
$ man ls

マンページのスタイルは慣れるのに少々大変かもしれません。なぜなら特に比較的古い非常に伝統的なマンページは比較的言葉が少ないからです。しかし一旦慣れるとその簡潔さの良さが分かります。

GNUやBSD由来を含む多くのUnix的なコマンドは次のように起動すると簡単なヘルプ情報を表示します。(場合によっては一切の引数無しで):

$ <コマンド名> --help
$ <コマンド名> -h

1.5. シェルプロンプト

Debianシステムの使い方が少し分かったでしょう。Debianシステム上でのコマンド実行のメカニズムを掘り下げましょう。初心者のためにちょっと簡略化してみました。正確な説明はbash(1)を参照下さい。

シンプルなコマンドは、次のシーケンスとなります:

  1. 変数代入(任意)
  2. コマンド名
  3. 引数(任意)
  4. リダイレクト(任意:>>><<<等。)
  5. 制御演算子(任意:&&||と<改行>と;&())

1.5.1. コマンド実行と環境変数

環境変数の値はUnixコマンドの挙動を変えます。

環境変数のデフォルト値はPAMシステムが初期設定されます。その後次のような何らかのアプリケーションプログラムにより再設定されているかもしれません。

  • gdmのようなディスプレイマネージャによって再設定される。
  • "~/bash_profile"や"~/.bashrc"にあるシェル起動コードの中でシェルにより再設定される。

1.5.1.1. "$LANG"変数

"$LANG"変数に与えられる完全なロケール値は3つの部分からなります:"xx_YY.ZZZZ"。


言語コードと国コードは"info gettext"中の該当記述を参照下さい。

最近のDebianシステム上では、十分な理由と必要な知見をもって歴史的なコードセットを特段希望しない限り、常にコードセットをUTF-8と設定すべきです。

ロケールの詳細に関しては、「ロケール」を参照下さい。

[注意] 注意

"LANG=en_US"は、"LANG=C"でも、"LANG=en_US.UTF-8"でもありません。それは"LANG=en_US.ISO-8859-1"です(「Basics of encoding」参照)。

表1.19 推奨ロケールのリスト。

言語(地域) 推奨ロケール
英語(米国) en_US.UTF-8
英語(英国) en_GB.UTF-8
フランス語(フランス) fr_FR.UTF-8
ドイツ語(ドイツ) de_DE.UTF-8
イタリア語(イタリア) it_IT.UTF-8
スペイン語(スペイン) es_ES.UTF-8
カタラン語(スペイン) ca_ES.UTF-8
スウェーデン語(スウェーデン) sv_SE.UTF-8
ポルトガル語(ブラジル) pt_BR.UTF-8
ロシア語(ロシア) ru_RU.UTF-8
中国語(中華人民共和国) zh_CN.UTF-8
中国語(台湾_R.O.C.) zh_TW.UTF-8
日本語(日本) ja_JP.UTF-8
韓国語(大韓民国) ko_KR.UTF-8
ベトナム語(ベトナム) vi_VN.UTF-8

典型的なコマンドの実行は次のようなシェル行のシーケンスを用います:

$ date
Sun Jun  3 10:27:39 JST 2007
$ LANG=fr_FR.UTF-8 date
dimanche 3 juin 2007, 10:27:33 (UTC+0900)

以上で、date(1)プログラムはフォアグラウンドのジョブとして実行されます。環境変数"$LANG"は:

  • 最初のコマンドに関しては、システムのデフォルトロケール(設定次第ですがここでは"en_US.UTF-8")に設定されています。
  • 2番目のコマンドに関しては、"fr_FR.UTF-8"(システム上に存在すればフランス語のUTF-8ロケール)に設定されています。

ほとんどのコマンド実行は頭に環境変数定義をつけないのが普通です。上記の例の代わりに次のように実行します:

$ LANG=fr_FR.UTF-8
$ date
dimanche 3 juin 2007, 10:27:33 (UTC+0900)

ここで確認できるように、コマンドの出力は環境変数に影響されフランス語の出力となっています。もし環境変数を(例えばシェルスクリプトを呼んでいて)サブプロセスに引き継ぎたい際には、次のように環境変数を"export"(エクスポート)しなければいけません。

$ export LANG
[ティップ] ティップ

バグ報告をする際には、非英語環境を使っているなら、プログラムを"LANG=en_US.UTF-8"の下で実行し確認することが望ましいです。

"$LANG"とこれに関連した環境変数に関しては、locale(5)とlocale(7)を参照下さい。

[注意] 注意

特段必要がなければ"$LC_*"変数を避けて、"$LANG"変数のみを用いてシステム環境設定する事をお薦めします。

1.5.1.2. "$PATH"変数

シェルにコマンドを打ち込んだ際に、シェルは"$PATH"環境変数にリストされたディレクトリのリストから検索します。"$PATH"環境変数の値は、シェルの検索パスとも呼ばれます。

標準のDebianインストールでは、ユーザアカウントの"$PATH"環境変数には"/sbin"や"/usr/sbin"が含まれないかもしれません。例えば、ifconfigコマンドは"/sbin/ifconfig"とフルパスを使って実行する必要があります。(類似のipコマンドは"/bin"にあります。)

Bashシェルの"$PATH"環境変数は、"~/.bash_profile"か"~/.bashrc"ファイルで変更できます。

1.5.1.3. "$HOME"変数

多くのコマンドはユーザ特定の設定をホームディレクトリに保存し、その内容でコマンドの挙動が変わります。ホームディレクトリは"$HOME"環境変数で指定されます:

表1.20 "$HOME"の値のリスト。

プログラム実行状況 "$HOME"の値
initプロセスが実行するプログラム(デーモン) /
通常のrootシェルから実行されるプログラム /root
通常のユーザシェルから実行されるプログラム /home/<normal_user>
通常のユーザのGUIデスクトップメニューから実行されるプログラム /home/<normal_user>
"sudo program"を用いてrootとして実行されるプログラム /home/<normal_user>
"sudo -H program"を用いてrootとして実行されるプログラム /root

[ティップ] ティップ

シェルは、"~/"を現ユーザのホームディレクトリである"$HOME/"へと展開します。シェルは、"~foo/"をユーザfooのホームディレクトリである"/home/foo/"へと展開します。

1.5.2. コマンドラインオプション

プログラムコマンドによっては引数があります。引数は"-"か"--"で始まり、オプションと呼ばれ、コマンドの挙動をコントロールします。

$ date
Mon Oct 27 23:02:09 CET 2003
$ date -R
Mon, 27 Oct 2003 23:02:40 +0100

上記で、コマンドライン引数"-R"がdate(1)の挙動をRFC2822準拠の日付文字列出力と変えています。

1.5.3. シェルグロブ

ファイル名を全てタイプせずにファイルのグループをコマンド処理したいことがよくあります。シェルのグロブ(ワイルドカードとも時々呼ばれる)を用いたファイル名のパターン展開を用いるとこのニーズに答えられます。

表1.21 シェルグロブパターン

シェルグロブパターン マッチ
* "."で始まらない任意のファイル(部分)名にマッチします。
.* "."で始まる任意のファイル(部分)名にマッチします。
? 任意の 1 文字にマッチします。
[…] 括弧中の 1 文字にマッチします。
[a-z] "a"と"z"の範囲にある文字とマッチする。
[^…] 括弧内( "^"以外)に含まれる文字以外の文字にマッチ。

例えば、次の例を試してみて、自分で考えてみましょう:

$ mkdir junk; cd junk; .[^.]*touch 1.txt 2.txt 3.c 4.h .5.txt ..6.txt
$ echo *.txt
1.txt 2.txt
$ echo *
1.txt 2.txt 3.c 4.h
$ echo *.[hc]
3.c 4.h
$ echo .*
. .. .5.txt ..6.txt
$ echo .*[^.]*
.5.txt ..6.txt
$ echo [^1-3]*
4.h
$ cd ..; rm -rf junk

詳細はglob(7)を参照下さい。

[注意] 注意

通常のシェルのファイル名の展開と違い、find(1)が"-name"テスト他でシェルパターン"*"をテストする際にはファイル名先頭の"."ともマッチします。(新POSIX機能)

[注意] 注意

BASHはshopt組み込みオプションで"dotglob"や"noglob"や"nocaseglob"や"nullglob"や"nocaseglob"や"extglob"などとすることでグロブ挙動を色々変更できます。bash(1)参照下さい。

1.5.4. コマンドの戻り値

各コマンドは終了ステータスを戻り値(変数:"$?")として返します。

表1.22 コマンドの終了コード。

コマンドの終了状態 戻り値の数値 戻り値の論理値
成功 ゼロ、0
失敗 非ゼロ、-1

つまり:

$ [ 1 = 1 ] ; echo $?
0
$ [ 1 = 2 ] ; echo $?
1
[注意] 注意

シェルの論理的な観点では、成功は、0(ゼロ)の値を持つ論理的として扱われることに注意してください。少々これは非直感的なのでここで再確認する必要があります。

1.5.5. 典型的なコマンドシーケンスとシェルリディレクション

次に挙げるシェルコマンドの慣用句を覚えてみましょう。

表1.23 シェルコマンドの慣用句。

コマンドの慣用句(1行入力) 説明
command & commandバックグラウンドでサブシェルの中で実行されます。
command1 | command2 command1の標準出力がcommand2の標準入力に継ぎ込まれます。両方のコマンドが同時進行で実行されるかもしれません。
command1 2>&1 | command2 command1の標準出力と標準エラー出力がcommand2の標準入力に継ぎ込まれます。両方のコマンドが同時進行で実行されるかもしれません。
command1 ; command2 command1を実行し、後に続いてcommand2が実行されます。
command1 && command2 command1が実行されます。もし成功したら、後に続いてcommand2が実行されます。
command1 || command2 command1が実行されます。もし成功しなかったら、後に続いてcommand2が実行されます。command1 command2のどちらかが正常終了した場合に正常終了を返します。
command > foo commandの標準出力をfooファイルにリダイレクト (上書き) します。
command 2> foo commandの標準エラー出力をfooファイルにリダイレクト (上書き) します。
command >> foo commandの標準出力をfooファイルにリダイレクト (追記) します。
command 2>> foo commandの標準エラー出力をfooファイルにリダイレクト (追記) します。
command > foo 2>&1 commandの標準出力と標準エラー出力をfooファイルにリダイレクトします。
command < foo commandの標準入力をfooファイルからリダイレクトします。
command << delimiter commandの標準入力を"終端文字列"に出会うまでのこれに続く行からリダイレクトします。(ヒアドキュメント)
command <<- 終端文字列 commandの標準入力を"終端文字列"に出会うまでのこれに続く行からリダイレクトします。行頭のタブ文字は入力から落とされます。(ヒアドキュメント)

Debianシステムはマルチタスクシステムです。バックグラウンドジョブを使うと単一シェルの下で複数プログラムを実行可能にします。バックグラウンドジョブの管理にはシェル内部組み込みコマンドのjobsfgbgkillを使います。bash(1)マンページ中の"SIGNALS"と"JOB CONTROL"セクションやbuiltins(1)を参照下さい。

リディレクションの簡単な例を試してみましょう:

$ </etc/motd pager
$ pager </etc/motd
$ pager /etc/motd
$ cat /etc/motd | pager

4つ全ての例が全く同じ表示をしますが、最後の例は余計なcatコマンドを実行するので理由なくリソースの無駄遣いをします。

シェルではexec組み込みコマンドを任意のファイルディスクリプタとともに使いファイルをオープンすることができます。

$ echo Hello >foo
$ exec 3<foo 4>bar  # open files
$ cat <&3 >&4       # redirect stdin to 3, stdout to 4
$ exec 3<&- 4>&-    # close files
$ cat bar
Hello

上記で、"n<&-"と"n>&-" はファイルディスクリプタ"n"をクローズするという意味です。

ファイルデスクリプタの0-2は事前定義されています。

表1.24 事前定義されたファイルデスクリプタ

デバイス 説明 ファイルデスクリプタ
stdin 標準出力 0
stdout 標準出力 1
stderr 標準エラー出力 2

1.5.6. コマンドエリアス

良く使うコマンドにエイリアスを設定できます。例えば:

$ alias la='ls -la'

こうすると、"la"が"ls -la"の短縮形として機能し、全てのファイルを長いリスト形式でリストします。

既存の全エアリアスは次のようにするとリストできます:

$ alias

type内部コマンドを使うと正確なパスやコマンドの正体を識別できます。例えば:

$ type ls
ls is hashed (/bin/ls)
$ type la
la is aliased to ls -la
$ type echo
echo is a shell builtin
$ type file
file is /usr/bin/file

上記で、lsは最近探索されましたが"file" は最近探索されていませので、"ls"は"ハッシュされた"つまりシェルには"ls"コマンドの場所を高速アクセスのために内部記録していると表示されます。

[ティップ] ティップ

「Colorized commands」参照下さい。

1.6. Unix的テキスト処理

Unix的作業環境では、テキスト処理はテキストを標準テキスト処理ツールの連鎖パイプを通す行います。これは決定的なUnixの発明です。

1.6.1. Unixテキストツール

Unix的システムでしばしば使われる標準テキスト処理ツールがいくつかあります。

  • 正規表現無使用:

    • cat(1)はファイルをつなぎ合わせ全てを出力します。
    • tac(1)はファイルをつなぎ合わせ逆順で出力します。
    • cut(1)は行の一部を選択し出力します。
    • head(1)はファイルの最初の部分を選択し出力します。
    • tail(1)はファイルの最後の部分を選択し出力します。
    • sort(1)は行を順番に並び替えます。
    • uniq(1)は順番に並べられたファイルから重複行を削除します。
    • tr(1)は文字を変換削除します。
    • diff(1)は1行ごとにファイルを比較します。
  • 基本正規表現(BRE)使用:

    • egrep(1)はテキストのパターンマッチをします。
    • ed(1)は原始的な行エディタ。
    • sed(1)はストリームエディタ。
    • vim(1)はスクリーンエディタ。
    • emacs(1)はスクリーンエディタ。(ちょっと拡張されたBRE)
  • 拡張正規表現(ERE)使用:

    • egrep(1)はテキストのパターンマッチをします。
    • awk(1)は単純なテキスト処理をします。
    • tcl(3tcl)は考え得る全てのテキスト処理をします:re_syntax(3)。時々tk(3tk)とともに使用されます。
    • perl(1)は考え得る全てのテキスト処理をします。perlre(1).
    • pcregrepパッケージのpcregrep(1) はテキストのパターンマッチをPerl互換正規表現(PCRE)パターンを使ってします。
    • reモジュールとともに使うことでpython(1)は考え得る全てのテキスト処理をします。"/usr/share/doc/python/html/index.html"参照下さい。

もしこれらのコマンドが正確にどう動作するかを確認したいなら、"man command"を使って自分で見つけましょう。

[注意] 注意

ソート順や範囲表現はロケールに依存します。コマンドの伝統的挙動を得たい際には、"LANG=C"をコマンドの前に付けてUTF-8ロケールではなくCロケールでコマンドを使いましょう。(「"$LANG"変数」「ロケール」を参照)。

[注意] 注意

Perl正規表現(perlre(1))とPerl互換正規表現(PCRE)reモジュールで提供されるPython正規表現はEREに多くの共通の拡張をしています。

1.6.2. 正規表現

正規表現は多くのテキスト処理ツールで使われています。シェルグロブに類似していますがより複雑で強力です。

正規表現はマッチするパターンを表現し、テキスト文字とメタ文字からなっています。

メタ文字は特別な意味を持った文字です。上記のようにテキストツールによって、BREEREの2つの主要なスタイルがあります。

表1.25 BREとEREのメタ文字。

BRE ERE 正規表現の意味
\ . [ ] ^ $ * \ . [ ] ^ $ * 共通のメタ文字
\+ \? \( \) \{ \} \|   "\"でエスケープされた、BREのみで用いるメタ文字
  + ? ( ) { } | "\"でエスケープされ無い、EREのみで用いるメタ文字
c c 非メタ文字 "c"をマッチします。
\c \c 当該シーケンスは、c"自身がメタ文字でも"c"というそのままの文字とマッチします。
. . 改行を含めた如何なる文字ともマッチします。
^ ^ 文字列の最初とマッチします。
$ $ 文字列の最後とマッチします。
\< \< 単語先頭とマッチします。
\> \> 単語末尾とマッチします。
\[abc…\] [abc…] この文字リストは"abc…"のいずれかの文字にマッチします。
\[^abc…\] [^abc…] この否定の文字リストは"abc…"以外の文字にマッチします。
r* r* "r"という正規表現の0回以上にマッチ。
r\+ r+ "r"という正規表現の1回以上にマッチ。
r\? r? "r"という正規表現の0回か1回にマッチ。
r1\|r2 r1|r2 "r1"か"r2"という正規表現のいずれかにマッチ。
\(r1\|r2\) (r1|r2) "r1"か"r2"という正規表現のいずれかにマッチし、それを括弧で囲まれた正規表現として扱う。

emacsの正規表現は、ERE同様の"+"と"?"をメタ文字と扱う拡張をしてはありますが、基本的にBREです。これら文字をemacsの正規表現で"\"でエスケープする必要はありません。

例えば、grep(1)をつかうと正規表現を使って文字列探索ができます:

$ egrep 'GNU.*LICENSE|Yoyodyne' /usr/share/common-licenses/GPL
GNU GENERAL PUBLIC LICENSE
GNU GENERAL PUBLIC LICENSE
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
[ティップ] ティップ

「Colorized commands」参照下さい。

1.6.3. 置換表現

置換表現の場合、次の文字には特別な意味があります

表1.26 置換表現

文字 意味
& 正規表現がマッチしたものを示す。(emacsでは\&を使用)
\n n番目の括弧で囲まれた正規表現にマッチしたものを示す。("n" は数字)

Perlの置換表現では、"\n"の代わりに"$n"をつかい、"&"には特段の意味はありません。

例えば:

$ echo zzz1abc2efg3hij4 | \
sed -e 's/\(1[a-z]*\)[0-9]*\(.*\)$/=&=/'
zzz=1abc2efg3hij4=
$ echo zzz1abc2efg3hij4 | \
sed -e 's/\(1[a-z]*\)[0-9]*\(.*\)$/\2===\1/'
zzzefg3hij4===1abc
$ echo zzz1abc2efg3hij4 | \
perl -pe 's/(1[a-z]*)[0-9]*(.*)$/$2===$1/'
zzzefg3hij4===1abc
$ echo zzz1abc2efg3hij4 | \
perl -pe 's/(1[a-z]*)[0-9]*(.*)$/=&=/'
zzz=&=

ここで、括弧で囲まれた正規表現のスタイルと、マッチした文字列が異なるツール上でテキスト置換処理にどう使われるかとに注目下さい。

これらの正規表現は一部エディタ内でカーソルの動きやテキスト置換アクションに対しても使えます。

シェルコマンドラインの行末のバックスラッシュ"\"は改行をホワイトスペース文字としてエスケープするので、シェルコマンドライン入力を次行に継続させます。

これらのコマンドを習うために、関連するマニュアルページを全て読んでください。

1.6.4. 正規表現を使ったグローバル置換

ed(1)コマンドは次のようにすると"file"中に存在する全ての"FROM_REGEX"を"TO_TEXT"で置換する:

$ ed file <<EOF
,s/FROM_REGEX/TO_TEXT/g
w
q
EOF

vim(1)コマンドはex(1)コマンドを使い次のようにすると"file"中に存在する全ての"FROM_REGEX"を"TO_TEXT"で置換する:

$ vim '+%s/FROM_REGEX/TO_TEXT/gc' '+w' '+q' file
[ティップ] ティップ

上記の"c"フラグをにより各置換毎に対話型の確認をします。

複数ファイル("file1"と"file2"と"file3")をvim(1)やperl(1)で同様に正規表現を用いて処理できます:

$ vim '+argdo %s/FROM_REGEX/TO_TEXT/ge|update' '+q' file1 file2 file3
[ティップ] ティップ

上記の"e"フラグをにより"No match"エラーでマッピングが停止することを防ぎます。

$ perl -i -p -e 's/FROM_REGEX/TO_TEXT/g;' file1 file2 file3

perl(1)の例中で、"-i"はその場での編集、"-p"はファイルに関する暗黙的なループを意味します。

[ティップ] ティップ

"-i"の代わりに"-i.bak"という引数を用いるとオリジナルファイル名に".bak"をつけたファイル名でオリジナルファイルが保管されます。複雑な置換のエラーからの復帰が簡単にできます。

[注意] 注意

ed(1)やvim(1)はBREですが、perl(1)はEREです。

1.6.5. テキストファイルからのデータ抽出

2004年以前の元Debianリーダの名前と就任日がスペースで分割されたフォーマットでリストされている"DPL"と呼ばれるファイルを考えてみましょう。

Ian     Murdock   August  1993
Bruce   Perens    April   1996
Ian     Jackson   January 1998
Wichert Akkerman  January 1999
Ben     Collins   April   2001
Bdale   Garbee    April   2002
Martin  Michlmayr March   2003
[ティップ] ティップ

最新のDebianのリーダーの歴史に関しては、"A Brief History of Debian"を参照下さい。

こういったタイプのファイルからデータを抽出するのはAwk が良く使われます:

$ awk '{ print $3 }' <DPL                   # month started
August
April
January
January
April
April
March
$ awk '($1=="Ian") { print }' <DPL          # DPL called Ian
Ian     Murdock   August  1993
Ian     Jackson   January 1998
$ awk '($2=="Perens") { print $3,$4 }' <DPL # When Perens started
April 1996

Bash などのシェルもこれらのファイルを解釈するのに使えます:

$ while read first last month year; do
    echo $month
  done <DPL
  • 最初の Awk の例と同じ出力。

ここで、read組込みコマンドは"$IFS"(内部フィールドセパレータ) を用いて行を単語単位で分割します。

"$IFS"を":"に変更すると、"/etc/passwd"をシェルでうまく解読できます:

$ oldIFS="$IFS"   # save old value
$ IFS=':'
$ while read user password uid gid rest_of_line; do
    if [ "$user" = "bozo" ]; then
      echo "$user's ID is $uid"
    fi
  done < /etc/passwd
bozo's ID is 1000
$ IFS="$oldIFS"   # restore old value

(同じことを Awk を使って行うには、フィールドセパレータ設定は"FS=':'"としましょう。)

IFSはパラメータ展開、コマンド置換、数式展開の結果を分割するためにもシェルにより使われます。これはダブルクォートやシングルクォートされた単語内では発生しません。IFSの標準値は<space>と<tab>と<newline>の組合せです。

シェルのIFSトリックを注意深く使ってください。シェルがスクリプトの一部を入力として解釈した場合に、奇妙なことが起きるかもしれません。

$ IFS=":,"                        # use ":" and "," as IFS
$ echo IFS=$IFS,   IFS="$IFS"     # echo is a Bash builtin
IFS=  , IFS=:,
$ date -R                         # just a command output
Sat, 23 Aug 2003 08:30:15 +0200
$ echo $(date -R)                 # sub shell --> input to main shell
Sat  23 Aug 2003 08 30 36 +0200
$ unset IFS                       # reset IFS to the default
$ echo $(date -R)
Sat, 23 Aug 2003 08:30:50 +0200

1.6.6. コマンドをパイプするためのスクリプト断片

次のスクリプトはパイプの一部として素晴らしいことをします。

表1.27 コマンドをパイプするためのスクリプト断片のリスト。

スクリプト断片(1行入力) コマンドの効果
find /usr -print "$HOME"の値。
seq 1 100 1から100までプリント。
| xargs -n 1 <command> パイプからの各項目を引数としてコマンドを繰り返し実行します。
| xargs -n 1 echo パイプからのホワイトスペースで分離された項目を行に分割します。
| xargs echo パイプからの全ての行を1行にマージします。
| grep -e <regex_pattern> <regex_pattern>を含む行を取り出します。
| grep -v -e <regex_pattern> <regex_pattern>を含まない行を取り出します。
| cut -d: -f3 - ":"で区切られた3番目のフィールドを取り出します(passwdファイルなど)。
| awk '{ print $3 }' ホワイトスペースで区切られた3番目のフィールドを取り出します。
| awk -F'\t' '{ print $3 }' タブで区切られた3番目のフィールドを取り出します。
| col -bx バックスペースを削除し、タブをスベースに変換します。
| expand - タブをスベースに変換します。
| sort| uniq 入力をソートし重複箇所を削除します。
| tr 'A-Z' 'a-z' 大文字を小文字に変換します。
| tr -d '\n' 複数の行を1行につなげます。
| tr -d '\r' キャリッジリターンを削除します。
| sed 's/^/# /' 各行頭に"#"を追加します。
| sed 's/\.ext//g' ".ext"を削除します。
| sed -n -e 2p 2番目の行を表示します。
| head -n 2 - 最初の2行を表示します。
| tail -n 2 - 最後の2行を表示します。

1行のシェルスクリプトはfind(1)やxargs(1)を使って非常に複雑な操作を多くのファイルに繰り返し実行できます。「Idioms for the selection of files」「Repeating a command looping over files」を参照下さい。

シェルの対話モードを使うのが複雑過ぎるようになったときには、シェルのスクリプトを書くのも一計です(「シェルスクリプト」参照)。