第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.2.13. tmpfs
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.2. "$LANG" 変数
1.5.3. "$PATH" 変数
1.5.4. "$HOME" 変数
1.5.5. コマンドラインオプション
1.5.6. シェルグロブ
1.5.7. コマンドの戻り値
1.5.8. 典型的なコマンドシーケンスとシェルリディレクション
1.5.9. コマンドエリアス
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 に関する文書だけに頼ることは、有用な情報を見逃すことになるので止めましょう。

[注記] 注記

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

X Window システムgdm3 等のディスプレーマネージャーとともにインストールした場合以外には、システム起動の際に文字の 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 jessie/sid foo tty1
foo login: penguin
Password:
Last login: Mon Sep 23 19:36:44 JST 2013 on tty3
Linux snoopy 3.11-1-amd64 #1 SMP Debian 3.11.6-2 (2013-11-01) 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:~$

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

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

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

次の「仮想コンソール」も参照下さい。

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

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

  • ファイルパーミッションによらずシステム上の任意ファイルに関しての、読出し・書込み・削除

  • システム上のいかなるファイルに関して、ファイルの所有者やパーミッション設定

  • システム上の非特権ユーザーのパスワードを設定

  • パスワード無しに任意アカウントへの login

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

[警告] 警告

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

[注記] 注記

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

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

[警告] 警告

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

[警告] 警告

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

デフォールトの 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

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

通常のマルチユーザーモードからのシステムのシャットダウンがコマンドラインから出来ます。

# shutdown -h now

シングルユーザーモードからのシステムのシャットダウンがコマンドラインから出来ます。

# poweroff -i -f

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

「SSH 上のリモートシステムをシャットダウンする方法」を参照下さい。

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

# apt-get update
 ...
# apt-get install mc vim sudo
 ...

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


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


これらのパッケージの一部を次のようにしてインストールします。

# apt-get install package_name

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

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

これに代え、次のようにして非特権ユーザー penguin にパスワード一切無しに管理者権限を与えることもよくあります。

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

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

[警告] 警告

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

[注意] 注意

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

[注意] 注意

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

[注記] 注記

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

[注記] 注記

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

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

These files and directories can be spread out over several devices. mount(8) serves to attach the filesystem found on some device to the big file tree. Conversely, umount(8) detaches it again. On recent Linux kernels, mount(8) with some options can bind part of a file tree somewhere else or can mount filesystem as shared, private, slave, or unbindable. Supported mount options for each filesystem are available in "/usr/share/doc/linux-doc-*/Documentation/filesystems/".

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

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

[注記] 注記

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

[注記] 注記

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

[注記] 注記

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

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


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

Each file, directory, named pipe (a way two programs can share data), or physical device on a Debian GNU/Linux system has a data structure called an inode which describes its associated attributes such as the user who owns it (owner), the group that it belongs to, the time last accessed, etc. The idea of representing just about everything in the filesystem was a Unix innovation, and modern Linux kernels have developed this idea ever further. Now, even information about processes running in the computer can be found in the filesystem.

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

[ヒント] ヒント

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

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)

  • ファイルの名前


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

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

例えば次のようにするとディレクトリーツリーの所有者をユーザー foo に変更しグループ bar で共有できます。

# 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) を使って実行ファイルを実行することを許可されます。これらの設定はセキュリティーを破壊するリスクを引き起こすので、これらのビットを有効にするには特別な注意が必要です。

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

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

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

$ ls -l /etc/passwd /etc/shadow /dev/ppp /usr/sbin/exim4
crw------T 1 root root   108, 0 Oct 16 20:57 /dev/ppp
-rw-r--r-- 1 root root     2761 Aug 30 10:38 /etc/passwd
-rw-r----- 1 root shadow   1695 Aug 30 10:38 /etc/shadow
-rwsr-xr-x 1 root root   973824 Sep 23 20:04 /usr/sbin/exim4
$ ls -ld /tmp /var/tmp /usr/local /var/mail /usr/src
drwxrwxrwt 14 root root  20480 Oct 16 21:25 /tmp
drwxrwsr-x 10 root staff  4096 Sep 29 22:50 /usr/local
drwxr-xr-x 10 root root   4096 Oct 11 00:28 /usr/src
drwxrwsr-x  2 root mail   4096 Oct 15 21:40 /var/mail
drwxrwxrwt  3 root root   4096 Oct 16 21:20 /var/tmp

chmod(1) を用いて、ファイルパーミッションを記述するためのもう一つの数字モードが存在します。この数字モードは8進数を使った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 0 Oct 16 21:39 bar
-rw-r--r-- 1 penguin penguin 0 Oct 16 21:35 foo
[ヒント] ヒント

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

特定のユーザーにグループ許可を適用するには、/etc/group に関しては "sudo vigr" と /etc/gshadow に関しては "sudo vigr -s" を用いて、そのユーザーをグループのメンバーにする必要があります。新規のグループ設定を有効にするにはログアウト後ログイン (もしくは "exec newgrp" を実行) する必要があります。

[注記] 注記

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

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

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


[ヒント] ヒント

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

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


システムが供給するユーザーやグループの完全なリストは、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) を参照下さい。

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


[注記] 注記

ctime はファイル作成日時ではありません。

  • ファイルが上書きされると、ファイルの mtimectimeatime の属性すべてが変更されます。

  • ファイルの所有者やパーミッションの変更をすると、ファイルの ctimeatime アトリビュートを変えます。

  • ファイルを読むとファイルの atime が変更されます。

[注記] 注記

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

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

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

$ LANG=fr_FR.UTF-8  ls -l foo
-rw-rw-r-- 1 penguin penguin 0 oct. 16 21:35 foo
$ LANG=C  ls -l foo
-rw-rw-r-- 1 penguin penguin 0 Oct 16 21:35 foo
[ヒント] ヒント

"ls -l" の出力のカスタム化は「時間と日付のカスタム化表示」を参照下さい。

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

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

$ umask 002
$ echo "Original Content" > foo
$ ls -li foo
1449840 -rw-rw-r-- 1 penguin penguin 17 Oct 16 21:42 foo
$ ln foo bar     # hard link
$ ln -s foo baz  # symlink
$ ls -li foo bar baz
1449840 -rw-rw-r-- 2 penguin penguin 17 Oct 16 21:42 bar
1450180 lrwxrwxrwx 1 penguin penguin  3 Oct 16 21:47 baz -> foo
1449840 -rw-rw-r-- 2 penguin penguin 17 Oct 16 21:42 foo
$ rm foo
$ echo "New Content" > foo
$ ls -li foo bar baz
1449840 -rw-rw-r-- 1 penguin penguin 17 Oct 16 21:42 bar
1450180 lrwxrwxrwx 1 penguin penguin  3 Oct 16 21:47 baz -> foo
1450183 -rw-rw-r-- 1 penguin penguin 12 Oct 16 21:48 foo
$ cat bar
Original Content
$ cat baz
New Content

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

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

[注意] 注意

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

[注記] 注記

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

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

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

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

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

例えば、次を試してみて下さい:

$ cd; mkfifo mypipe
$ echo "hello" >mypipe & # put into background
[1] 8022
$ ls -l mypipe
prw-rw-r-- 1 penguin penguin 0 Oct 16 21:49 mypipe
$ cat mypipe
hello
[1]+  Done                    echo "hello" >mypipe
$ ls mypipe
mypipe
$ rm mypipe

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

2タイプのデバイスファイルがあります。

  • 文字デバイス

    • 1文字毎にアクセス可能

    • 1文字 = 1 バイト

    • 例: キーボードデバイス、シリアルポート等

  • ブロックデバイス

    • 比較的大きなブロック単位でアクセス可能

    • 1 ブロック > 1 バイト

    • 例: ハードディスク等

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

[注記] 注記

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

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

$ ls -l /dev/sda /dev/sr0 /dev/ttyS0 /dev/zero
brw-rw---T  1 root disk     8,  0 Oct 16 20:57 /dev/sda
brw-rw---T+ 1 root cdrom   11,  0 Oct 16 21:53 /dev/sr0
crw-rw---T  1 root dialout  4, 64 Oct 16 20:57 /dev/ttyS0
crw-rw-rw-  1 root root     1,  5 Oct 16 20:57 /dev/zero
  • "/dev/sda" はメジャーデバイス番号8 とマイナーデバイス番号0 を持ちます。これは disk グループに所属するユーザーにより、読出し / 書込みアクセスが可能です。

  • "/dev/sr0" はメジャーデバイス番号11 とマイナーデバイス番号0 を持ちます。これは cdrom グループに所属するユーザーにより、読出し / 書込みアクセスが可能です。

  • "/dev/ttyS0" はメジャーデバイス番号4 とマイナーデバイス番号64 を持ちます。これは dialout グループに所属するユーザーにより、読出し / 書込みアクセスが可能です。

  • "/dev/zero" はメジャーデバイス番号1 とマイナーデバイス番号5 を持ちます。これは誰によっても読出し / 書込みアクセスが可能です。

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

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

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

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

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

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

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

tmpfs仮想記憶 中にすべてのファイルを保持する一時的なファイルシステムです。メモリー上のページキャッシュ中にある tmpfs のデーターは必要に応じてディスク上の swap 空間 へと書き出せます。

"/run" ディレクトリは初期ブートプロセスに tmpfs としてマウントされます。こうすることで "/" が読み取り専用でマウントされていてもそこへの書き込みが可能です。これは過渡的な状態ファイルの保管のための新たな場所で、Filesystem Hierarchy Standard のバージョン 2.3に規定されたいくつかの場所を置き換えます:

  • "/var/run" → "/run"

  • "/var/lock" → "/run/lock"

  • "/dev/shm" → "/run/shm"

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

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

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

$ sudo apt-get install mc

Debian システムを探検するために mc(1) コマンドを使います。これは学習するための最良の方法です。カーソールキーとエンターキーを使うだけで興味深い場所をちょっと探検します。

  • "/etc" とサブディレクトリー

  • "/var/log" とサブディレクトリー

  • "/usr/share/doc" とサブディレクトリー

  • "/sbin" と "/bin"。

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) をほとんどのシステム管理業務のために使い続けられます。

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

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 や他のエギゾチックな符号化方式 (エンコーディング) のテキストを正しく扱えます。それにはUTF-8ロケール中のX環境で、必要なプログラムとフォントをインストールをするのが賢明です。マルチバイトテキストに関するそれぞれの文書を参照下さい。

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

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

表1.16 基本の 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 / ディレクトリーをルートディレクトリーに変更
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>" を作成
xz <foo> Lempel–Ziv–Markov鎖アルゴリズムを用いて "<foo>" を圧縮し "<foo>.xz" を作成 (bzip2 より高圧縮率)
unxz <foo>.xz "<foo>.xz" を解凍して "<foo>" を作成
tar -xvf <foo>.tar "<foo>.tar" アーカイブからファイルを展開
tar -xvzf <foo>.tar.gz gzip 圧縮された "<foo>.tar.gz" アーカイブからファイルを展開
tar -xvjf <foo>.tar.bz2 "<foo>.tar.bz2" アーカイブからファイルを展開
tar -xvJf <foo>.tar.xz "<foo>.tar.xz" アーカイブからファイルを展開
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" アーカイブに圧縮アーカイブ
tar -cvJf <foo>.tar.xz <bar>/ フォルダ "<bar>/" の内容を "<foo>.tar.xz" アーカイブに圧縮アーカイブ
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 パッケージを "apt-get 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

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

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

  1. 変数代入 (任意)

  2. コマンド名

  3. 引数 (任意)

  4. リダイレクト (任意: >>><<< 等。)

  5. 制御演算子 (任意: &&|| と <改行> と ;& ())

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

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

  • gdm3 のようなディスプレーマネージャーは環境変数を再設定します。

  • "~/.bash_profile" や "~/.bashrc" にあるシェル起動コードの中でシェルは環境変数を再設定します。

"$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" です (「符号化方式の基本」参照下さい)。


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

$ 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" 値で実行されます。

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

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

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

$ export LANG
[注記] 注記

典型的なコンソールターミナルを用いる際には、"$LANG" 環境変数は通常デスクトップ環境によって export されるように設定されています。上記例は export の効果を検証するあまりいい例ではありません。

[ヒント] ヒント

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

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

[注記] 注記

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

次に挙げるシェルコマンドの一部として一行でタイプするシェルコマンドの慣用句を覚えましょう。

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

コマンドの慣用句 説明
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 を実行 (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 の標準入力を "delimiter" に出会うまでのこれに続く行からリダイレクト (ヒアドキュメント)
command <<- delimiter command の標準入力を "delimiter" に出会うまでのこれに続く行からリダイレクト (ヒアドキュメント、行頭のタブ文字は入力から削除)

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

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


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

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

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

[注記] 注記

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

[注記] 注記

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

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

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

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


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
[ヒント] ヒント

「着色化されたコマンド」を参照下さい。

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

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

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

$ sed -i -e 's/FROM_REGEX/TO_TEXT/g' file

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 です。

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行のシェルスクリプトは find(1)xargs(1) を使って非常に複雑な操作を多くのファイルに繰り返し実行できます。「ファイル選択の慣用句」「ファイルに関してループしながらコマンドを反復実行」を参照下さい。

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