SSブログ
前の10件 | -

出力リダイレクトによくある問題 [概論・概要]

 前回アーティクルからの続き。

 今回は、「出力リダイレクト」によくある問題を取り上げたい。ほんのちょっとだけ敷居が高くなる(かもしれない)が、がんばって理解に努めてほしい。

その1:標準出力と、標準エラー出力とを「同じファイル」に出力したい。
 前回のアーティクルで、wcコマンドの出力結果を「wckekka.txt」と「wcerror.txt」と、異なるファイルに出力した。
 その時のコマンド入力はこうだった。

 wc -l bindir.txt > wckekka.txt 2> wcerror.txt

 時には、この両方の結果を「同じファイルに出力したい」という要望に遭遇する事がありうる。
 その場合は、標準出力と標準エラー出力とを同じファイルに出力するように指定することで解決ができる。難しい話ではない。

 wc -l bindir.txt > wckekka.txt 2> wckekka.txt

 ただ、この方法で指定する人はほとんどいないのである。なぜなら、同じファイル名を2回も記述していてスマートでは無いからである。
 このサンプルの場合は、相対パス指定でファイル名しか指定していないが、時と場合によっては絶対パス指定で深いディレクトリの中に記録したい場合とか現れてしまったら…

 wc -l /home/piro791/stdio/bindir.txt > /var/tmp/fukai/fukai/directory/no/sarani/oku/wckekka.txt 2> /var/tmp/fukai/fukai/directory/no/sarani/oku/wckekka.txt

 などということになってしまい、全くもって面倒臭いことになってしまうから。
 そこで、UNIX時代の偉い人は、

 以下同文

 的な指定方法を編み出してくれたのであった。ありがたやありがたや…。
 それが、

 &1
 と
 &2

 という記号なのでした。この記号をつかって、標準出力と標準エラー出力とを同じwckekka.txtに記録するという場合はこうなる。

 wc -l bindir.txt > wckekka.txt 2> &1

 と、指定することになる。すると、
 ・標準出力は「wckekka.txt」に出力
 ・標準エラー出力は標準出力と同じ場所に出力
 ということになる。これなら簡単だ。ありがたやありがたや…。

 ところで、この指定方法には1つ注意すべき落とし穴がある。それを紹介しておく。
 通常、標準出力の出力先を指定する記号と、標準エラー出力の出力先を指定する記号は、どちらを先に指定しても構わないのである。例えば、

 wc -l bindir.txt > wckekka.txt 2> wcerror.txt

 は、

 wc -l bindir.txt 2> wcerror.txt > wckekka.txt

 と、書いても一向に構わないのが原則なのだ。「それじゃあ…」とばかりに、

 wc -l bindir.txt > wckekka.txt 2> &1

 を

 wc -l bindir.txt 2> &1 > wckekka.txt

 と、書いてしまうと、望んだ通りの結果にならないのである。(ただし、エラーにはならない

 どういうことかー?

 実は、&1 とか&2 とかいう記号が登場した場合、その時点で指定されている出力先に変更するという意味を持っているから。
 通常、入力されたコマンドは、左から右に向かって解釈される。つまり、

① wc -l bindir.txt
 →ふむふむ。bindir.txtのファイルの行数を数えればいいのね…
 ※この時点では標準出力も標準エラー出力も「画面に出力する」という状態になっている。

② 2> &1
 →ふむふむ。標準エラー出力は、標準出力と同じ所に出力すればいいのね。今の標準出力の出力先は「画面に出力」か。じゃあ標準エラー出力は「画面に出力」すればいいのね。

③ > wckekka.txt
 →標準出力はファイル「wckekka.txt」に出力するのね。了解した。

 …という具合に解釈されてしまい、標準エラー出力と標準出力とは異なる出力先に出力されてしまうことになる。
 これが正しい順序で指定されていた場合はどうなるのかといえば、

 wc -l bindir.txt > wckekka.txt 2> &1

①wc -l bindir.txt
 →ふむふむ。bindir.txtのファイルの行数を数えればいいのね…
 ※この時点では標準出力も標準エラー出力も「画面に出力する」という状態になっている。

② > wckekka.txt
 →標準出力はファイル「wckekka.txt」に出力するのね。了解した。

③ 2> &1
 →ふむふむ。標準エラー出力は、標準出力と同じ所に出力すればいいのね。今の標準出力の出力先はファイル「wckekka.txt」に出力か。じゃあ標準エラー出力も「wckekka.txt」に出力するぞ。

 …と、なるのであった。これは重要な問題なのでよーく覚えておくように。

 ちなみに、「&2」はというと、これは「標準エラー出力と同じ」という意味になる。標準出力を「標準エラー出力と同じ」場所に出力したい場合に使う。つまり…

 wc -l bindir.txt 2> wckekka.txt > &2

 というような使い方をすることになるのだが、こんな指定をする人はまず変態だと思って差し支えないと思われる。…というくらいドマイナーな使い方だということ。(笑)

その2:標準出力と、標準エラー出力を破棄したいが、ファイルも残したくない。
 標準出力や標準エラー出力をファイルに記録するようにリダイレクトすると、コマンド自体は無言で実行されることになる。出力結果がどうであれ、あるいはエラーが有ろうが無かろうが、その結果は全てファイルに記録されるので、画面上には何も表示されないことになる。
 ある種の処理を実施する場合、このように無言で動作してくれることが望ましいという場合もある。
 かといって、いちいちファイルに出力されては後始末も面倒くさい。なにか良い方法はないものか?

 と、お嘆きのアナタ!そんなアナタにピッタリのリダイレクト先があります!!
 それが…

 /dev/null

 というファイルです。
 この「/dev/null」というファイルは、非常に特殊なファイルで、特に「デバイスファイル」という分類に属します。laコマンドでちょっと確認してみましょう。
[piro791@urd stdio]$ ls -l /dev/null
crw-rw-rw- 1 root root 1, 3 11月  9 19:05 2012 /dev/null
[piro791@urd stdio]$

 ファイルサイズの部分がなんだか変です。「1,3」とかいう謎の表示になっています。これは、「デバイス番号」という特殊な情報を示していますが、今はまあ「そういう物があるんだ…」程度の理解で一向に構いません。
 このファイルをcatコマンドで覗いてみましょう。すると…
[piro791@urd stdio]$ cat /dev/null
[piro791@urd stdio]$

 中身はカラッポです。

 では、試しにlsコマンドの結果を/dev/nullに出力するようにしてみましょう。
[piro791@urd stdio]$ ls -la /bin > /dev/null 2>&1
[piro791@urd stdio]$

 lsコマンドが無言です。
 では、再度/dev/nullをcatコマンドで覗いてみます。
[piro791@urd stdio]$ cat /dev/null
[piro791@urd stdio]$

 なんと、やっぱりカラッポじゃないですか。
 このように、/dev/nullは何でも吸い込んでしまい、何も出てこられないUNIX/Linux界のブラックホール的な存在になっています。(笑)

その3:標準出力や標準エラー出力の内容をファイルに「追加」したい。
 実は、これまでに説明した出力リダイレクトというものは、コマンドを実行する度にファイルを上書きしてしまうものでした。
 例えば、(lsコマンドで試すと長くて判りにくいので)サーバの日時を表示するdateコマンドで解説すると…
[piro791@urd stdio]$ date > hiduke.txt
[piro791@urd stdio]$ date > hiduke.txt
[piro791@urd stdio]$ date > hiduke.txt
[piro791@urd stdio]$ cat hiduke.txt
2012年 11月 15日 木曜日 15:06:20 JST
[piro791@urd stdio]$

 dateコマンドを3回、同じファイルに出力するように指定して実行しているが、cat コマンドで確認が出来るのは最後の1回分だけになっている。つまり、dateコマンドを実行する度にhiduke.txtファイルを上書きしてしまっているということになる。
 しかし、時と場合によっては「追加で書き込みがしたい」ということもあり得る。そのような場合はどうすればよいだろう?

 答えは、「>」を2個重ねて指定するのである。つまり、

 >>
 とか、
 2>>

 とかいう具合に記述すると、その時は「ファイルに追加書き込み」が行われるのである。(※なお、指定されたファイルが存在しない場合は、新しく作成して先頭から書き込みが行われるという親切設計である。
[piro791@urd stdio]$ ls -la
合計 20
drwxrwxr-x 2 piro791 piro791 4096 11月 15 15:06 2012 .
drwx------ 3 piro791 piro791 4096 11月 15 10:19 2012 ..
-rw-rw-r-- 1 piro791 piro791 6497 11月 15 10:59 2012 bindir.txt
-rw-rw-r-- 1 piro791 piro791   43 11月 15 15:06 2012 hiduke.txt
[piro791@urd stdio]$

 このような状態の時に、dateコマンドを3回実行して、「hiduke2.txt」に追加書き込みで出力してみる。すると…
[piro791@urd stdio]$ date >> hiduke2.txt
[piro791@urd stdio]$ date >> hiduke2.txt
[piro791@urd stdio]$ date >> hiduke2.txt
[piro791@urd stdio]$ cat hiduke2.txt
2012年 11月 15日 木曜日 15:11:34 JST
2012年 11月 15日 木曜日 15:11:38 JST
2012年 11月 15日 木曜日 15:11:42 JST
[piro791@urd stdio]$

 …と、確かに3回分のdateコマンドの結果が出力されていることが判る。
 なお、標準エラー出力も全く同じ要領なので、ここでは省略する。


 次回のアーティクルは、標準出力と標準入力とを連結する手法「パイプ」について説明したい。

標準入力と標準出力、そして標準エラー出力 [概論・概要]

 概論・概略的なお話が続くと、どーしても退屈で眠くなるものですが、UNIX/Linuxを理解する上ではどーしても避けて通れないものなので、もうちょっと我慢しましょう。(笑)

 今回は、「標準入力」「標準出力」「標準エラー出力」について解説します。

 まず、passwdコマンドを思い出してもらいたい。
 passwdコマンドは、ログインパスワードを変更するコマンドだったが、
Changing password for user piro791.
Changing password for piro791
(current) UNIX password:

 というように、「パスワードを変更しますよ。現在のパスワードを入力してください。」  というような表示を画面上に出力をしている。そして、現在のパスワードや新しいパスワードをキーボードから入力している。
 lsコマンドのように、キーボードからの入力を必要としないコマンドもあるが、多くのコマンドは

 ・入力
 ・出力

 を伴う物がほとんどだ。
 そして、ほとんどのケースでは「入力」と言えばキーボードからするものと相場が決まっているし、「出力」といえば画面にするものだと相場が決まっている。
 ところが、

 ・何度も同じ入力をするのが面倒臭い
 ・コマンドの出力結果をメモするのが面倒くさい

 …というような要求が出現することも少なくない。そのような場合の操作について、今回は解説を加えておきたいと思う。

 「標準エラー出力」はちょっと別格として、今は横に置いておく。

 「標準入力」と、「標準出力」は、UNIX/Linuxが標準的に用意している入力経路・出力経路のことを言う。誰にとって「標準的」なのかといえば、それはそれぞれのコマンドから見て標準的な入力、標準的な出力なんだ…ということになる。
 つまり、通常、なにがしかのコマンドが

 「あー。ここで入力して欲しいものがあるんだよなー」

 …と思えば、それは標準入力から入力してもらうようにコマンド(プログラム)を作成しておけば、あとはUNIX/Linuxがうまいこと取りはからってくれる事が約束されている。
 一方で、

 「あー。今ここで出力したい事があるんだよなー」

 …ということになれば、その内容を標準出力に出力するようにコマンド(プログラム)を作成しておけば、あとはUNIX/Linuxが上手いこと取りはからってくれる事が約束されているのである。

 「標準入力」からの入力、あるいは「標準出力」への出力 について、コマンド(プログラム)内部でどのように扱うのかは、それぞれのコマンド(プログラム)が好きに扱って良いことになっている。一方でコマンド(プログラム)の外側での振る舞いは、ユーザーの要望を受けてUNIX/Linuxが適切に取り扱うのであって、コマンド(プログラム)から振る舞いを指定することができない。

 どういうことか?
 例えば、そのサーバの時計を表示するコマンドで試してみる。コマンドプロンプトから、dateとコマンドを入力してみよう。すると…
[piro791@urd stdio]$ date
2012年 11月 15日 木曜日 10:48:04 JST
[piro791@urd stdio]$

 現在の日時が出力される。この結果はdateコマンドの内部で「2012年 11月 15日 木曜日 10:48:04 JST」という文字を「標準出力」に出力するようにプログラミングされているのである。そして、その「標準出力」に出力された内容をUNIX/Linuxが受け取って、画面上に表示していることになる。

 この「標準出力」の出力先を変更する方法がある。これが今回のメインテーマなのだ。

 では、今度はdateコマンドをこのように入力してみてもらいたい。

 date > hiduke.txt

 するとこうなる…
[piro791@urd stdio]$ date > hiduke.txt
[piro791@urd stdio]$

 画面上には何も表示されなくなった。あの日時の表示はどこにいったのか??
 それは、「hiduke.txt」というファイルに出力されたのである。
 lsコマンドで確認してみよう。すると…
[piro791@urd stdio]$ ls -la
合計 12
drwxrwxr-x 2 piro791 piro791 4096 11月 15 10:53 2012 .
drwx------ 3 piro791 piro791 4096 11月 15 10:19 2012 ..
-rw-rw-r-- 1 piro791 piro791   43 11月 15 10:53 2012 hiduke.txt
[piro791@urd stdio]$

 確かに、「hiduke.txt」というファイルが存在している。このファイルをcatコマンドで覗いてみると
[piro791@urd stdio]$ cat hiduke.txt
2012年 11月 15日 木曜日 10:53:39 JST
[piro791@urd stdio]$

 dateコマンドが出力したであろう結果がファイルの中に書き込まれている。
 このように、「>」記号を使うと、「標準出力」の出力先が画面上から指定されたファイルへと変更されていることがわかる。

 lsコマンドでも試してみよう。今度は

 ls -la /bin > bindir.txt

 としてみる。すると…
[piro791@urd stdio]$ ls -la /bin > bindir.txt
[piro791@urd stdio]$

 lsコマンドの結果は画面上には何も表示されていないが、これは「bindir.txt」というファイルの中に記録されているはずである。
[piro791@urd stdio]$ ls -la
合計 20
drwxrwxr-x 2 piro791 piro791 4096 11月 15 10:59 2012 .
drwx------ 3 piro791 piro791 4096 11月 15 10:19 2012 ..
-rw-rw-r-- 1 piro791 piro791 6497 11月 15 10:59 2012 bindir.txt
-rw-rw-r-- 1 piro791 piro791   43 11月 15 10:53 2012 hiduke.txt
[piro791@urd stdio]$

 「bindir.txt」というファイルが確かに存在している。では、中身を確認してみよう。
[piro791@urd stdio]$ cat bindir.txt
合計 7684
dr-xr-xr-x.  2 root root   4096  9月 17 03:42 2012 .
dr-xr-xr-x. 22 root root   4096 11月 11 04:22 2012 ..
-rwxr-xr-x.  1 root root    123 11月 24 23:50 2010 alsaunmute
-rwxr-xr-x   1 root root  27808  3月 26 07:03 2011 arch
lrwxrwxrwx.  1 root root      4 12月 17 13:19 2011 awk -> gawk
-rwxr-xr-x   1 root root  26264  3月 26 07:03 2011 basename
-rwxr-xr-x   1 root root 938672  5月 27 00:46 2011 bash
-rwxr-xr-x   1 root root  51344  3月 26 07:03 2011 cat

 (※途中省略※)

-rwxr-xr-x   1 root root 772040  2月 26 00:33 2011 vi
lrwxrwxrwx.  1 root root      2 12月 17 13:19 2011 view -> vi
lrwxrwxrwx.  1 root root      8 12月 17 13:19 2011 ypdomainname -> hostname
-rwxr-xr-x.  1 root root     62 11月 23 16:26 2010 zcat
[piro791@urd stdio]$

 …と、なっている。なお、「ls -la /bin」とだけ実行してみると、これと全く同じ結果になることが判ると思う。

 このように、「>」記号を使うことで、標準出力の出力先を画面上からファイルに変更することが可能になるのだった。

 次に、「標準入力」をキーボードからの入力ではなく、ファイルからの入力に変更してみる。
 こちらは、標準出力の「逆向きの記号」つまり…

 <

 を使う。
 まだ説明はしていないが、ここでは「wcコマンド」(トイレではない)を使ってみることにする。

 まず、「wc -l」と、コマンドを入力してみよう。すると…
[piro791@urd stdio]$ wc -l

 と、プロンプトが表示されず、コマンドを入力した次の行でカーソルが止まっている様子がわかるだろう。
 実はコレ、wcコマンドが標準入力からの入力を待ち構えているのである。

 ではここで、「abcdefg(Enterキー)」と3回ほど繰り返してみる。するとこうなる。
[piro791@urd stdio]$ wc -l
abcdefg
abcdefg
abcdefg

 入力したとおりに3行表示されている。
 ここで、「Ctrl+D」(Ctrlキーを押しながらDキー)を押してみよう。すると…
[piro791@urd stdio]$ wc -l
abcdefg
abcdefg
abcdefg
3
[piro791@urd stdio]$

 と、「3」と新たに表示された後に、コマンドプロンプトが返ってきた。

 wcコマンドとは、「文字数(バイト数)」「単語数」「行数」などを数えてくれるコマンドで、今回は「-l」というオプションを付けているので、「行数を数えている」のである。「abcdefg」と入力して「Enter」キーを押しているので、入力した行数は3行。だから「3」という結果が標準出力に出力されているのだ。
 ほとんどの場合、キーボードから入力してwcコマンドで数えさせるなんてことはしない。普通やらない。というか、そんなのはこういうサンプル以外では見たことが無い。(笑)

 よくある使い方としては…
[piro791@urd stdio]$ ls -la
合計 20
drwxrwxr-x 2 piro791 piro791 4096 11月 15 10:59 2012 .
drwx------ 3 piro791 piro791 4096 11月 15 10:19 2012 ..
-rw-rw-r-- 1 piro791 piro791 6497 11月 15 10:59 2012 bindir.txt
-rw-rw-r-- 1 piro791 piro791   43 11月 15 10:53 2012 hiduke.txt
[piro791@urd stdio]$ wc -l bindir.txt
109 bindir.txt
[piro791@urd stdio]$

 このように、wcコマンドでファイル名を指定して、そのファイルの行数を数える…的な使い方が一般的ではある。しかし、場合によっては標準出力からファイルの内容を与えて行数を数えさせる事もありうるのであった。
[piro791@urd stdio]$ wc -l < bindir.txt
109


 wc -l < bindir.txt

 ファイル「bindir.txt」の中身を標準入力としてwcコマンドに与えている。この時、wcコマンドとしてはその内容がキーボードから入力されたのと同じ振る舞いをすることになる。wcコマンドには、その入力内容がキーボードから入力されたのか、ファイルから入力されたのかは判らないし、そもそも気にすることもない。

 この「標準入力」の使いどころとしては、「入力する内容が物凄く沢山あってキーボードから入力とかあり得ない」とか、「毎回毎回同じ事を入力するのは本当に面倒臭い」とか、「絶対にミスできない入力を事前に用意しておいて、再三チェックしてから入力したい」とか、そんな場合で大活躍するはずだ。

 続いて、別格扱いをした「標準エラー出力」について説明する。

 先ほどの例で、「bindir.txt」の行数を数えるwcコマンドの例で、「wc -l bindir.txt」という形式でコマンドを実行していた部分を再度思い出して欲しい。
[piro791@urd stdio]$ wc -l bindir.txt
109 bindir.txt
[piro791@urd stdio]$

 ファイルbindir.txtは109行あるということが判る。この出力結果を画面上ではなく「wckekka.txt」というファイルに保存するとしよう。復習になるが、こんな感じでよいはずだ。

 wc -l bindir.txt > wckekka.txt

 試してみよう。
[piro791@urd stdio]$ wc -l bindir.txt > wckekka.txt
[piro791@urd stdio]$ cat wckekka.txt
109 bindir.txt
[piro791@urd stdio]$

 wcコマンドは無言で終了し、ファイル「wckekka.txt」にはwcコマンドで表示された内容が記録されている。
 次に、wcコマンドで指定したファイル「bindir.txt」のファイル名をわざと間違えてみることにする。するとどうなるだろうか…
[piro791@urd stdio]$ wc -l bakaahomanuke.txt > wckekka2.txt
wc: bakaahomanuke.txt: そのようなファイルやディレクトリはありません
[piro791@urd stdio]$

 「bakaahomanuke.txt」というファイルは存在しないので、wcコマンドとしては何を数えたら良いのかさっぱりわからない。よって、「そんなファイルはねーよ!」というたぐいのエラーメッセージを出力している。
 ところが、標準出力は「wckekka2.txt」というファイルに記録するように、出力先を変更しているにもかかわらず、画面上に『wc: bakaahomanuke.txt: そのようなファイルやディレクトリはありません』などと出力されているではないか。
 この時、wckekka2.txtはどうなっているのかというと…
[piro791@urd stdio]$ ls -la wckekka2.txt
-rw-rw-r-- 1 piro791 piro791 0 11月 15 12:59 2012 wckekka2.txt
[piro791@urd stdio]$

 なんと、ファイルが作成されている。
 ファイルの大きさは「0バイト」…つまりからっぽということになっている。これは、wcコマンドが実行はされた物の\指定されたファイルが正しくなかったので何も出力しないで終了したということになる。

 そう…つまり、「そのようなファイルやディレクトリは…」というエラーメッセージは標準出力に出力された物ではないのである。

 このようなエラーメッセージは、そのまま標準出力に出力されてしまうと、コマンドを実行しようとしている人に見落とされてしまうリスクがある。そこで、標準出力とは別の経路を用意しておき、オペレーターに警告を伝える必要がある。その「別の経路」こそが、

 標準エラー出力

 なのである。
 ところが、

 ・エラーが出ても無視したい

 とか、

 ・エラーメッセージこそ、ファイルに記録しておきたい

 …というケースもゼロではないので、これも出力先を変更する方法が存在する。そのために用いる記号が、

 2>

 である。数字の「2」が付いている点が重要なポイント。実際の使い方として、wcコマンドのエラーメッセージをファイルに保存する方法で例示するとこうなる。

 wc -l bakaahomanuke.txt 2> wcerror.txt

 確認してみよう。
[piro791@urd stdio]$ wc -l bakaahomanuke.txt 2> wcerror.txt
[piro791@urd stdio]$ cat wcerror.txt
wc: bakaahomanuke.txt: そのようなファイルやディレクトリはありません

 wcコマンド自体は無言で終了していることが判る。本来ならエラーメッセージが出力されたはずだ。しかし今回は「標準エラー出力」の出力先をファイルに変更しているので、その結果は「wcerror.txt」というファイルに記録されることとなる。
 catコマンドで内容を確認すると、確かにエラーメッセージが記録されていることが判る。

 なお、標準出力と、標準エラー出力とを同時に変更することも出来る。
 例えば、wcコマンドの出力結果について、

 ・実行結果を「wckekka.txt」に記録する
 ・エラーメッセージを「wcerror.txt」に記録する

 ということも可能だ。入力すべきコマンドは次のようになる。

 wc -l bindir.txt > wckekka.txt 2> wcerror.txt

 要するに、「>」と「2>」とを単純に並べて書いたらOKなのだ。
 それでは試してみよう。
[piro791@urd stdio]$ wc -l bindir.txt > wckekka.txt 2> wcerror.txt
[piro791@urd stdio]$ cat wckekka.txt
109 bindir.txt
[piro791@urd stdio]$ cat wcerror.txt
[piro791@urd stdio]$

 今回のwcコマンドは特にエラー等起こすこと無く実行が完了しているので、「wckekka.txt」の中にその実行結果が記録され、「wcerror.txt」は空っぽ(catコマンドで何も表示されない)になっていることが判る。

 ちなみに、「>」とか、「2>」とかで出力先を変更することを、「出力リダイレクト」といい、「<」で入力元を変更することを「入力リダイレクト」といいます。

 次回のアーティクルでは、「出力リダイレクト」についてありがちな問題について解説したいと思います。

『コピー』と『リンク』 [概論・概要]

 本人でさえもその存在を忘れるくらい、超ご無沙汰をしていました。(大笑)
 久しぶりにこっちのblogも更新~ってことで。

 さて、今度はUNIX/Linuxで必修の知識の一つである、『コピー』と『リンク』について触れておきます。

 UNIX/Linuxの超基礎コマンドの一つに、ファイルをコピーするコマンド「cp」というコマンドがあります。そりゃもう、頻繁に使うコマンドなのですが、これとよく似たコマンドに、「ln」というコマンドも存在するのです。
 まず、両方のコマンドを実際に試してみましょう。

 まず、ここではサンプルとして、original.txtというテキストファイルを作成します。苦労して練習したであろうviコマンドを使って、皆さんも作成してみましょう。
[piro791@urd copy_and_link]$ cat original.txt
オリジナルのファイルです。
こんにちは
こんばんわ
魔法の…(古いネタを引っ張るなあ
[piro791@urd copy_and_link]$


 続いて、このファイルをcpコマンドでコピーしてみます。cpコマンドの使い方は、基本型としては

 cp コピー元のファイル コピー先のファイル

 というように指定します。今回は「original.txt」というファイルを、「copy.txt」というファイルにコピーしてみましょう。この場合は

 cp original.txt copy.txt

 と、実行すれば、所定の目的は達成出来そうです。
 では、レッツ・トライ!
[piro791@urd copy_and_link]$ ls -la
合計 12
drwxrwxr-x 2 piro791 piro791 4096 11月 14 17:04 2012 .
drwx------ 3 piro791 piro791 4096 11月 14 17:04 2012 ..
-rw-rw-r-- 1 piro791 piro791  121 11月 14 17:04 2012 original.txt
[piro791@urd copy_and_link]$ cp original.txt copy.txt
[piro791@urd copy_and_link]$ ls -la
合計 16
drwxrwxr-x 2 piro791 piro791 4096 11月 14 17:08 2012 .
drwx------ 3 piro791 piro791 4096 11月 14 17:04 2012 ..
-rw-rw-r-- 1 piro791 piro791  121 11月 14 17:08 2012 copy.txt
-rw-rw-r-- 1 piro791 piro791  121 11月 14 17:04 2012 original.txt
[piro791@urd copy_and_link]$

 ご無沙汰していましたが、lsコマンドの使い方・見方をちゃんと思い出してくださいよ?
 まず最初(コピーを実行するにlsコマンドで確認してみると、「original.txt」というファイルしか存在していないことが確認できます。
 そして、先ほど確認したcpコマンドを実行し、再度lsコマンドで確認をしています。すると今度は、「original.txt」というファイルに加えて「copy.txt」というファイルが存在していることが判ります。これでファイルがコピーされていることが判ります。

 念のため、両方のファイルの中身を確認してみましょうか。「cat」コマンドでファイルの中を見ることが出来ます。
[piro791@urd copy_and_link]$ cat original.txt
オリジナルのファイルです。
こんにちは
こんばんわ
魔法の…(古いネタを引っ張るなあ
[piro791@urd copy_and_link]$ cat copy.txt
オリジナルのファイルです。
こんにちは
こんばんわ
魔法の…(古いネタを引っ張るなあ
[piro791@urd copy_and_link]$


 全く同じ内容が表示されていますね。このように、cpコマンドでファイルの複製を作ることが出来ます。
 サーバ管理者として「よくある」使い方は、ファイルのバックアップを取得するなんていうケースでしょうね。サーバの設定をするファイルを編集するに、そのファイルをコピーして名前を変えて保存しておく…という使い方はごくごく一般的でごくごく初歩的なオペレーションです。例えば…

 cp httpd.conf httpd.conf.bak

 なんていうコマンドでサーバの設定ファイル(上記の例ではWebサーバの設定ファイル)をバックアップしておき、設定が間違っていた時にはファイルのコピーを逆向きに指定して再度実行すれば、たちまち変更前の状態に復帰することができます。

 さて。冒頭でもう一つ『リンク』なるものに言及していましたが、こちらもサンプルを見ておきましょう。こちらは使用するコマンドがlnになります。
 使い方はcpコマンドと大体一緒なので、先ほどの操作と同じようにこのコマンドを試してみます。なお、先ほどは「copy.txt」と指定した箇所について、今度は「link.txt」と指定することにします。つまり…

 ln original.txt link.txt

 と、します。
 さっそくレッツトライ。
[piro791@urd copy_and_link]$ ls -la
合計 16
drwxrwxr-x 2 piro791 piro791 4096 11月 14 17:08 2012 .
drwx------ 3 piro791 piro791 4096 11月 14 17:04 2012 ..
-rw-rw-r-- 1 piro791 piro791  121 11月 14 17:08 2012 copy.txt
-rw-rw-r-- 1 piro791 piro791  121 11月 14 17:04 2012 original.txt
[piro791@urd copy_and_link]$ ln original.txt link.txt
[piro791@urd copy_and_link]$ ls -la
合計 20
drwxrwxr-x 2 piro791 piro791 4096 11月 14 17:20 2012 .
drwx------ 3 piro791 piro791 4096 11月 14 17:04 2012 ..
-rw-rw-r-- 1 piro791 piro791  121 11月 14 17:08 2012 copy.txt
-rw-rw-r-- 2 piro791 piro791  121 11月 14 17:04 2012 link.txt
-rw-rw-r-- 2 piro791 piro791  121 11月 14 17:04 2012 original.txt
[piro791@urd copy_and_link]$

 cpコマンドの時と同じように、lnコマンドの実行前と後にlsコマンドを実行しています。
 original.txtの他にcopy.txtファイルがありますが、まあこれは先ほどcpコマンドを試したときの残骸ですから気にしないでください。
 lnコマンドの実行前には無かった、「link.txt」というファイルが新たに登場していることがわかりますね?

 では、これもcpコマンドの時と同じように、それぞれの中身を覗いてみましょう。
[piro791@urd copy_and_link]$ cat original.txt
オリジナルのファイルです。
こんにちは
こんばんわ
魔法の…(古いネタを引っ張るなあ
[piro791@urd copy_and_link]$ cat link.txt
オリジナルのファイルです。
こんにちは
こんばんわ
魔法の…(古いネタを引っ張るなあ
[piro791@urd copy_and_link]$

 なんと、original.txtとlink.txtの中身が一緒で、cpコマンドの時と結果が一緒じゃないですか!!

 つまらんつまらん…

 と、がっかりしたあなた。でもこれ、実はcpコマンドと結果が違うんですよ。

 まず、もう一度lsコマンドの実行結果をよ~く見てみましょう。
[piro791@urd copy_and_link]$ ls -la
合計 20
drwxrwxr-x 2 piro791 piro791 4096 11月 14 17:20 2012 .
drwx------ 3 piro791 piro791 4096 11月 14 17:04 2012 ..
-rw-rw-r-- 1 piro791 piro791  121 11月 14 17:08 2012 copy.txt
-rw-rw-r-- 2 piro791 piro791  121 11月 14 17:04 2012 link.txt
-rw-rw-r-- 2 piro791 piro791  121 11月 14 17:04 2012 original.txt
[piro791@urd copy_and_link]$

 ファイル名とタイムスタンプが違う…というのはこの際横に置いておくとして、他に違いがあることに気がつきませんか?

 …「-rw-rw-r--」という表示の右側に注目しましょう。copy.txtは「1」になっているのに対して、link.txtとoriginal.txtは「2」になっていることが判りますね?ここにその「理由」が隠されています。

 では、見た目的に判りやすい方法で解説します。
 では、viコマンドを使って、「original.txt」ファイルの中身を変更してみましょう。
[piro791@urd copy_and_link]$ cat original.txt
オリジナルのファイルです。
こんにちは
こんばんわ
魔法の言葉で
ぽぽぽぽーん!
[piro791@urd copy_and_link]$

 …と、このように変更してみました。catコマンドで確認していますが、確かに変更されています。
 ここで今度は先ほど作成した、「copy.txt」と「link.txt」の中身をそれぞれ確認してみましょう。(copy.txtとlink.txtは変更していない事に注意!
 まずは、copy.txtをcat コマンドで確認すると…
[piro791@urd copy_and_link]$ cat copy.txt
オリジナルのファイルです。
こんにちは
こんばんわ
魔法の…(古いネタを引っ張るなあ
[piro791@urd copy_and_link]$

 変更前の状態のままだということが判ります。ところが、link.txtを見ると…
[piro791@urd copy_and_link]$ cat link.txt
オリジナルのファイルです。
こんにちは
こんばんわ
魔法の言葉で
ぽぽぽぽーん!
[piro791@urd copy_and_link]$

 link.txtは変更していないのに、original.txtと全く同じ内容に変更されているではありませんか。

 …これが、『コピー』と『リンク』の違いです。

  『コピー』とは、ファイルの「複製」を作ります。だから、内容は同じでもそれぞれは別の物です。

 ところが、『リンク』というのは、既存のファイルに別名を付けるイメージにるのです。同じ物に違う名前を付けるだけなのです。
 例えば、衣類の種類に、「オーバーオール」というものがありますが、全く同じ物でも「サロペット(ジーンズ)」という人もいます。(詳しくはwikipediaで確認してみてください。)この時、「オーバーオール」「サロペット」は同じ物を指し示していますね?『リンク』はこれと全く同じような振る舞いをするのです。

 ちょっと先走りますが、original.txtとlink.txtは実際には「同じ物」で、copy.txtは実際には「違う物」だということを確認してみましょう。statというコマンドでそれが確認できます。(表示内容は難しいですが、ちょっと試してみてください)
[piro791@urd copy_and_link]$ stat original.txt
  File: `original.txt'
  Size: 113             Blocks: 8          IO Block: 4096   通常ファイル
Device: fd00h/64768d    Inode: 1706896     Links: 2
Access: (0664/-rw-rw-r--)  Uid: (  500/ piro791)   Gid: (  500/ piro791)
Access: 2012-11-14 17:32:04.969622598 +0900
Modify: 2012-11-14 17:31:59.442859522 +0900
Change: 2012-11-14 17:32:00.425099552 +0900
[piro791@urd copy_and_link]$ stat copy.txt
  File: `copy.txt'
  Size: 121             Blocks: 8          IO Block: 4096   通常ファイル
Device: fd00h/64768d    Inode: 1706895     Links: 1
Access: (0664/-rw-rw-r--)  Uid: (  500/ piro791)   Gid: (  500/ piro791)
Access: 2012-11-14 17:12:16.514622280 +0900
Modify: 2012-11-14 17:08:40.033622485 +0900
Change: 2012-11-14 17:08:40.033622485 +0900
[piro791@urd copy_and_link]$ stat link.txt
  File: `link.txt'
  Size: 113             Blocks: 8          IO Block: 4096   通常ファイル
Device: fd00h/64768d    Inode: 1706896     Links: 2
Access: (0664/-rw-rw-r--)  Uid: (  500/ piro791)   Gid: (  500/ piro791)
Access: 2012-11-14 17:32:04.969622598 +0900
Modify: 2012-11-14 17:31:59.442859522 +0900
Change: 2012-11-14 17:32:00.425099552 +0900
[piro791@urd copy_and_link]$

 3つのファイルそれぞれに対して、statコマンドを実行しています。注目してほしい場所は「Inode:」という項目です。

 original.txtは 1706896
 copy.txtは 1706895
 link.txtは 1706896

 と、表示されています。なんと、original.txtとlink.txtとは同じ番号が与えられています。「Inode」(アイノードと読みます)とは、ファイルの管理情報を管理しているテーブルのことで、1個のファイルにつき1個のInodeが与えられます。
 cpコマンドは、ファイルの中身を複製し、そして新しいInodeを作成します。だから、新しく作成されたファイル「copy.txt」はInode番号が他と違っているのです。Inode番号が他と違うと言うことは、ファイルの物のが別に存在しているということになるのですね。
 一方でlnコマンドは、新しくInodeを作成しません。既存のInodeに、新しく別の名前を割り当てて終了となるのです。Inodeが同じということは、そのInodeが管理しているファイルの中身は同じ物を使うということになるのです。


 このようなリンクのことを、特にハードリンクと呼びます。

 さて、ハードリンクなんていう単語が登場したということは、お約束事項としてはハードじゃないリンクが存在するのか!?  という疑問も湧いてきませんか?


 …湧きますよね?


 ここは大人の対応をするところですよ?^-^

 実は、存在します。(笑)
 ハードじゃないリンクのことは、ソフトリンクまたは、シンボリックリンクと呼びます。おそらく、後者の方が一般的な呼び方のはずです。

 シンボリックリンクは、先ほど登場したlnコマンドに、「-s」オプションを付けて実行することで作成されるものです。ちょっと試してみましょう。
[piro791@urd copy_and_link]$ ls -la
合計 20
drwxrwxr-x 2 piro791 piro791 4096 11月 14 17:32 2012 .
drwx------ 3 piro791 piro791 4096 11月 14 17:32 2012 ..
-rw-rw-r-- 1 piro791 piro791  121 11月 14 17:08 2012 copy.txt
-rw-rw-r-- 2 piro791 piro791  113 11月 14 17:31 2012 link.txt
-rw-rw-r-- 2 piro791 piro791  113 11月 14 17:31 2012 original.txt
[piro791@urd copy_and_link]$ ln -s original.txt symlink.txt
[piro791@urd copy_and_link]$ ls -la
合計 20
drwxrwxr-x 2 piro791 piro791 4096 11月 14 18:05 2012 .
drwx------ 3 piro791 piro791 4096 11月 14 17:32 2012 ..
-rw-rw-r-- 1 piro791 piro791  121 11月 14 17:08 2012 copy.txt
-rw-rw-r-- 2 piro791 piro791  113 11月 14 17:31 2012 link.txt
-rw-rw-r-- 2 piro791 piro791  113 11月 14 17:31 2012 original.txt
lrwxrwxrwx 1 piro791 piro791   12 11月 14 18:05 2012 symlink.txt -> original.txt
[piro791@urd copy_and_link]$

 「symlink.txt」というリンクを作成しています。なんだか今まで見たことの無い表示になっているではありませんか。
 catコマンドでsymlink.txtの中身を覗いてみましょう。
[piro791@urd copy_and_link]$ cat symlink.txt
オリジナルのファイルです。
こんにちは
こんばんわ
魔法の言葉で
ぽぽぽぽーん!
[piro791@urd copy_and_link]$

 先ほど変更したoriginal.txtと同じ内容です。
 これもリンクなので、original.txtを変更すれば、symlink.txtも(そしてlink.txtも)内容が変化するはずです。(copy.txtは変わらないはずです)試してみましょう。
[piro791@urd copy_and_link]$ cat original.txt
オリジナルのファイルです。
こんにちは
こんばんわ
魔法の言葉で
ぽぽぽぽーん!
えーしー!
[piro791@urd copy_and_link]$

 末尾に、「えーしー!」という行を追加しています。
 では、copy.txt、link.txt、symlink.txtをそれぞれ中身を覗いてみましょう。
[piro791@urd copy_and_link]$ cat copy.txt
オリジナルのファイルです。
こんにちは
こんばんわ
魔法の…(古いネタを引っ張るなあ
[piro791@urd copy_and_link]$ cat link.txt
オリジナルのファイルです。
こんにちは
こんばんわ
魔法の言葉で
ぽぽぽぽーん!
えーしー!
[piro791@urd copy_and_link]$ cat symlink.txt
オリジナルのファイルです。
こんにちは
こんばんわ
魔法の言葉で
ぽぽぽぽーん!
えーしー!
[piro791@urd copy_and_link]$

 予定通り、copy.txtは変わらない、link.txtとsymlink.txtは変わっています。
 link.txtが変わっている理由はすでに説明しました。Inodeを参照しているので、実体は同じ物だからです。
 では、シンボリックリンクの方は?というと…
[piro791@urd copy_and_link]$ stat original.txt
  File: `original.txt'
  Size: 129             Blocks: 8          IO Block: 4096   通常ファイル
Device: fd00h/64768d    Inode: 1706896     Links: 2
Access: (0664/-rw-rw-r--)  Uid: (  500/ piro791)   Gid: (  500/ piro791)
Access: 2012-11-14 18:08:37.216622801 +0900
Modify: 2012-11-14 18:08:32.427885831 +0900
Change: 2012-11-14 18:08:33.292733204 +0900
[piro791@urd copy_and_link]$ stat symlink.txt
  File: `symlink.txt' -> `original.txt'
  Size: 12              Blocks: 0          IO Block: 4096   シンボリックリンク
Device: fd00h/64768d    Inode: 1706897     Links: 1
Access: (0777/lrwxrwxrwx)  Uid: (  500/ piro791)   Gid: (  500/ piro791)
Access: 2012-11-14 18:05:01.708608811 +0900
Modify: 2012-11-14 18:05:00.291622399 +0900
Change: 2012-11-14 18:05:00.291622399 +0900
[piro791@urd copy_and_link]$

 なんと、Inode番号が違うじゃないですか!
 …しかし、今回も、lsコマンドの結果をよーく見ていただきたい。今回の注目ポイントは、一番左側の情報とファイルサイズの情報です。

lrwxrwxrwxと、書いてあります。先頭のlが大注目ポイントです。実はコレ、ファイルにまつわる情報の記事内でしれっと説明済みなんですが(笑)、これがこのファイルが「リンク」で有ることを示しているのです。
 そして、ファイルのサイズにも注目。
-rw-rw-r-- 2 piro791 piro791  129 11月 14 18:08 2012 link.txt
-rw-rw-r-- 2 piro791 piro791  129 11月 14 18:08 2012 original.txt
lrwxrwxrwx 1 piro791 piro791   12 11月 14 18:05 2012 symlink.txt -> original.txt

 ハードリンクの時は、ファイルのサイズはオリジナルのファイルと同じ値でした。
 なぜなら、「Inode」が全く同じだからです。(ファイルのサイズに関する情報もInodeの中に入っています)

 ところが、シンボリックリンクの場合は、同じInodeを使っている訳では無いので、ファイルのサイズが「12」バイトしかありません。

 これはなんでか…?

 ここで、「copy.txt」のシンボリックリンクを作成してみましょう。ここで気がつく人が出たらあなたは鋭い。(笑)
-rw-rw-r-- 1 piro791 piro791  121 11月 14 17:08 2012 copy.txt
-rw-rw-r-- 2 piro791 piro791  129 11月 14 18:08 2012 link.txt
-rw-rw-r-- 2 piro791 piro791  129 11月 14 18:08 2012 original.txt
lrwxrwxrwx 1 piro791 piro791   12 11月 14 18:05 2012 symlink.txt -> original.txt
lrwxrwxrwx 1 piro791 piro791    8 11月 15 10:04 2012 symlink_copy.txt -> copy.txt

 …と、こういう結果になりました。

 ln -s original.txt symlink.txt  で12バイト。
 ln -s copy.txt symlink_copy.txt  で8バイトです。

 さあ!この「差」は一体!?







































 答えは、「オリジナルのファイルの『名前』の長さの差」なんですね!!
 文字数を数えてみましょう。「original.txt」は12文字、「copy.txt」は8文字です。(ピリオドもちゃんと数える!)
 そうなのです。シンボリックリンクの中身の実体は、「リンク元のファイルの名前」が入っているのです。そして、そのファイルに「リンクです」という属性を付けて(一番左端の「l」)リンクに見立てている…と、こういう寸法なのです。

 「ハードリンク」と「シンボリックリンク(ソフトリンク)」と、同じような事をするのにどうして2種類存在しているのでしょうか?
 ここには…

 きわめて重大な問題・違い・原因がある

 ということだけ、今は覚えておけば十分じゃないかなーと。この内容については追々解説していきたいと思います。

「絶対パス」と「相対パス」(「+α」もあるよ!) [概論・概要]

 さて。
 lsコマンドでもちらっと登場し、あまりきちんと説明していなかった問題にここで触れねばならない。「絶対パス」と「相対パス」の問題。(そして+αもあるよ!)

 UNIX/Linuxを利用するに当たって必ず正しく理解しなければならない問題がある。それが「パス」(「パス名」)の問題である。

 「パス」(「パス名」)とはなにか。それは、「ファイルやディレクトリの所在位置を表すキーワード」のこと。

 たとえば、lsコマンドを用いて次のコマンドを表示させてみよう。

 「ls -l /bin/ls

 これを実行すると、lsコマンドの実行ファイルが表示される。
[piro791@kagami ~]$ ls -l /bin/ls
-rwxr-xr-x 1 root root 95116 10月 27 11:12 /bin/ls


 また、 「ls -l ../../bin/ls」と実行してみるとどうだろうか。
[piro791@kagami ~]$ ls -l ../../bin/ls
-rwxr-xr-x 1 root root 95116 10月 27 11:12 ../../bin/ls

 ※注釈※ 使用しているサーバによってはエラーになる場合もある。その場合は、「ls -l ../../../bin/ls」を試してみてもらいたい。その場合でもエラーになるときは、サーバ管理者に問い合わせてみて欲しい
 表示される結果は微妙に異なっているが、実は両方とも同じファイルを表示しているのである。

 まず、最初の例では「/bin/ls」このように指定した。これを「絶対パス指定」という。一方、2つめの例では「../../bin/ls」と指定している。これを「相対パス指定」という。

 「絶対パス指定」とは、UNIX/Linuxにおける、ルートディレクトリを基点としてディレクトリをたどっていった場合のファイルやディレクトリの所在地を現す方式のことをいう。
 たとえて言うならば、「正式な住所」を表現していると考えてもらうとわかりやすい。「東京都千代田区永田町一丁目11番1号」というような感じ。

 他方、「相対パス指定」とは、現在のディレクトリ(カレントディレクトリ)を基点としてディレクトリをたどっていった場合のファイルやディレクトリの所在地を表す方式をいう。
 たとえて言うならば、『誰かに道案内をするとき』のことを想像してもらうとわかりやすい。「ここ(今いる場所)から最寄の駅に行くにはどうしたらいいですか?」と道を尋ねられた場合に、たとえば、『今来た道を戻って、2つ目の信号のある交差点を左に曲がり、その道をまっすぐ歩いて3つ目の交差点を右に曲がると、左手に駅が見えますよ』というような案内をした場合が、「相対パス指定」の発想に近いといえる。

 絶対パス指定相対パス指定との見分け方は簡単で、パス(パス名)の先頭が、「/」ではじまっているか、いないかで見分けることが出来る。
 絶対パス指定の場合は「/」で始まっているし、相対パス指定の場合は「/」以外の文字で始まっている。

 実は、lsコマンドの解説(その前のviの使い方などでも…)で絶対パス指定相対パス指定と両方使っていたのであった。

 絶対パス指定の例としては、「ls -l /bin」というコマンドを使ったのを覚えているだろうか。これは、ルートディレクトリの中に有る「bin」というディレクトリを指定している。
 一方、相対パス指定の例としては、「ls -l hoge」というコマンドを使っている。これは、「hoge」というファイルだけを処理対象にした例であったが、実はこれは現在のディレクトリ(カレントディレクトリ)を基点に、そこにある「hoge」というファイルであることを意味していたのである。

 このように、ファイルやディレクトリの指定に絶対パス指定相対パス指定は欠かせない非常に重要な要素なのである。これに対する正しい理解を深めることもまた大変に重要なことであるので、こってりと説明をしておきたい。(笑)

1:「ルートディレクトリ」とディレクトリ区切り記号
 UNIX/Linuxのファイル(システム)は、「ディレクトリ・ツリー構造」と呼ばれる仕組みを採用している。「ツリー構造」というくらいなので、ツリー(木)に似た構造をしているということ。
 木は、幹の部分があり、その上に枝分かれした部分がある。この「幹の部分」そして分かれた「枝」の形が「ディレクトリ・ツリー構造」の要素になる。
 幹の部分は全ての枝の「根幹」にあたる部分。枝の先端から逆に辿れば必ず幹にたどり着く。そのような幹の部分に相当するディレクトリを、UNIX/Linuxでは「ルートディレクトリ」と呼ぶ。
 「ルートディレクトリ」は、「/」と表す。「ルートディレクトリ」もディレクトリの一つなので、中をのぞいてみることが出来る。さっそく見てみることにしよう。
[piro791@kagami ~]$ ls -la /
合計 162
drwxr-xr-x 22 root root  4096  2月  2 10:06 .
drwxr-xr-x 22 root root  4096  2月  2 10:06 ..
-rw-r--r--  1 root root     0  2月  2 10:06 .autofsck
-rw-r--r--  1 root root     0 11月 19 17:15 .autorelabel
drwxr-xr-x  2 root root  4096  1月 19 04:09 bin
drwxr-xr-x  4 root root  1024  1月 15 10:31 boot
drwxr-xr-x  9 root root  3420  2月  2 10:06 dev
drwxr-xr-x 83 root root  4096  2月  2 10:06 etc
drwxr-xr-x  3 root root  4096  1月  6 12:46 home
drwxr-xr-x 13 root root  4096  1月 22 04:02 lib
drwx------  2 root root 16384 11月 20 02:07 lost+found
drwxr-xr-x  2 root root  4096  3月 10  2009 media
drwxr-xr-x  2 root root  4096 10月 27 09:37 misc
drwxr-xr-x  3 root root  4096 12月  8 19:30 mnt
drwxr-xr-x  2 root root  4096  3月 10  2009 opt
dr-xr-xr-x 51 root root     0  2月  2  2010 proc
drwxr-x---  2 root root  4096 12月  8 22:56 root
drwxr-xr-x  2 root root 12288  1月 19 04:09 sbin
drwxr-xr-x  2 root root  4096 11月 19 17:06 selinux
drwxr-xr-x  2 root root  4096  3月 10  2009 srv
drwxr-xr-x 11 root root     0  2月  2  2010 sys
drwxrwxrwt  3 root root  4096  2月  2 10:06 tmp
drwxr-xr-x 14 root root  4096 11月 19 17:10 usr
drwxr-xr-x 21 root root  4096 11月 20 12:06 var

 こんな感じに見えると思う。もしかしたら多少ディレクトリが多かったりすることもあるかもしれない。
 (※なお、サーバ管理者のポリシーによっては、ルートディレクトリが上記のように見えないこともある。管理者のポリシーによっては「偽物のルートディレクトリ」までしかアクセスを許していないケースも考えられる。詳しくはサーバ管理者に問い合わせてもらいたい。)

 「ルートディレクトリ」は非常に重要なディレクトリであるから、サーバの利用者はこのディレクトリに対して自分のファイルを作成したりコピーしたり保存したりしてはいけない。(サーバ管理者がここに置くように指示してき時は別。)

 「ルートディレクトリ」にあるそれぞれのディレクトリを指し示す際には、「ルートディレクトリ」であることを示す「/」に続けて、それぞれのディレクトリの名前を記述する。たとえば、「ルートディレクトリ」の中に見える、「bin」というディレクトリを指し示したい場合には…

 /bin

 という具合になるし、「tmp」というディレクトリならば

 /tmp

 という具合になる。

 「bin」や「tmp」がディレクトリである…というその証拠は、ファイルにまつわる情報の中で説明している。
 lsコマンドの表示で、「bin」や「tmp」の名前の表示の先頭に、「drwxr-xr-x」という表示がある。この「d」が、「これはディレクトリですよ」と主張しているのである。よくおぼえていなかった人はおさらいをしておいてもらいたい。


 「/bin」や「/tmp」もディレクトリなので、当然lsコマンドで中を見ることができる。「/bin」ディレクトリを見てみよう。
[piro791@kagami ~]$ ls -la /bin
合計 7440
drwxr-xr-x  2 root root    4096  1月 19 04:09 .
drwxr-xr-x 22 root root    4096  2月  2 10:06 ..
-rwxr-xr-x  1 root root    4988  9月  4 04:55 arch
lrwxrwxrwx  1 root root       4 11月 19 17:09 awk -> gawk
-rwxr-xr-x  1 root root   18484 10月 27 11:12 basename
-rwxr-xr-x  1 root root  735004  1月 22  2009 bash
-rwxr-xr-x  1 root root   23132 10月 27 11:12 cat
-rwxr-xr-x  1 root root   41828 10月 27 11:12 chgrp
-rwxr-xr-x  1 root root   38564 10月 27 11:12 chmod
-rwxr-xr-x  1 root root   44020 10月 27 11:12 chown
-rwxr-xr-x  1 root root   71524 10月 27 11:12 cp

 長いので後ろの方は省略しているが、このように、「/bin」ディレクトリの中身が見えている。この中に、「cat」というファイル(コマンド)があるのだが、このファイルを指し示したい場合(つまり、「ルートディレクトリの中にあるbinディレクトリの中に有るcatというファイル」)は、次のようなルールで表現される。

 /bin/cat

 ちょっとカラフルな表現になってしまったが(笑)、先頭の赤い「/」は、ルートディレクトリを意味する記号。続けてディレクトリの「bin」と並んでいるが、ディレクトリの「bin」と、ファイル名の「cat」との間に再度「/」が現れていることが判る。この「/」は、ディレクトリ区切り記号の意味を持ち、先頭の赤い「/」とは全く意味合いが異なっていることに注意して欲しい。
 ディレクトリの中にあるさらに別のディレクトリの中に…みたいなことになってくる場合も、ディレクトリとディレクトリとの名前を「/」で区切って並べることになる。たとえば、

 /home/piro791/lesson1.txt

 という指定をした場合は、「ルートディレクトリの中にあるhomeディレクトリの中にあるpiro791ディレクトリの中にあるlesson1.txtというファイル」を指し示していることになる。

2:「現在のディレクトリ」(カレントディレクトリ/ワーキングディレクトリ)

 ここまで、たびたび「現在のディレクトリ」という言葉が登場してきたが特に説明をしてこなかった。
 実は、サーバにログインしている間はサーバ利用者は常に「どこかのディレクトリ」に立っているということになっている。その「現在、立っている場所(=ディレクトリ)」が「現在のディレクトリ」ということになる。

 「現在のディレクトリ」を表す記号もあるので覚えておいてもらいたい。それは、ピリオド「.」である。

 lsコマンドの説明の際に、ファイル「hoge」を表示するとき、「ls -l hoge」と入力したのを覚えているだろうか。このコマンドによって、「現在のディレクトリにあるファイルhoge」が表示された。よって、基本的には現在のディレクトリを表す「.」は省略可能である。ちなみに、省略せずに表記した場合は

 ./hoge

 という表記方法を取ることとなる。

 ところがどっこい。このピリオドはそこらじゅうで大活躍するのである。基本的には省略可能ではあるものの、省略できない場面も少なくないのである。ピリオドを馬鹿にしてはいけないのである。(笑)


 それでは、「現在のディレクトリ」がどこにあるのか。それを調べるためのコマンドを紹介する。
 ものすごく簡単で…

 「pwd

 とだけ入力する。このコマンドにはオプションも無ければ引数も無い。無害なコマンドなのでさっそく試してみよう。
[piro791@kagami ~]$ pwd
/home/piro791

 この場合、「現在のディレクトリ」は、「/home/piro791」ですよ…と、言っている。そういえば、先ほど「ルートディレクトリの中身を見てもらったときに、「homeという表示が見えたことを思い出してもらいたい。

 「現在のディレクトリ」にあるファイル「hoge」を指し示すときに、

 hoge
 ./hoge

 上記2つの表記方法と、

 /home/piro791/hoge

 この表記方法とは、まったく同じファイルを意味しているということになる。
 なぜなら、「現在のディレクトリ」は「/home/piro791」であり、また「現在のディレクトリ」は「.」でもあるからだ。

 そして、冒頭の説明に戻るが、前者のピリオドを使った(り、または省略したりする)ファイルやディレクトリの表記方法が、「相対パス指定」であり、後者のルートディレクトリを基点とした表記方法が、「絶対パス指定」になるのである。(ふう…。長かった…)

3:「現在のディレクトリ」を移動する

 今度は「現在のディレクトリ」を実際に移動してみよう。
 ディレクトリを移動するコマンドがある。「cd」コマンドである。このコマンドは、多くの場合は引数を記述するが、引数を指定しないでただ単に「cd」とだけ実行することも少なくない。また、オプションを指定することも可能だが、あまりにもドマイナーすぎて知らない人も多いかもしれないというくらい、滅多に使わない。(私も年に1回あるかないか…じゃないかな??)

 lsコマンドの時のように、処理対象…つまり移動先となるディレクトリを指定すると、そのディレクトリに移動することが出来る。なお、コマンドの特性上、lsコマンドと違い、cdコマンドで指定できる処理対象はディレクトリのみとなる。ファイルを指定することは出来ない。(だって、「ディレクトリを移動する」と言っているのだから、ファイルを指定しても意味無いでしょ!?)

 では、ためしに「ルートディレクトリ」に移動してみよう。

 cd /

 と、実行する。
 すると…
[piro791@kagami ~]$ cd /

 コマンドを入力するプロンプトが微妙に変化したことがわかるだろうか。
 今までずーっと「~」という表示だったその場所が「/」と変わった。しかしコマンドは無言で終わっちゃうし、本当に移動できたのか良くわからないので、策ほど説明した「pwd」コマンドで、「現在のディレクトリ」が変化しているかどうか調べてみよう。
[piro791@kagami ~]$ cd /
[piro791@kagami /]$ pwd
/

 というわけで、確かに変わっていることが判った。「現在のディレクトリ」は「ルートディレクトリ」にあることになった。
 つまり、「.」と、「/」とは、同じディレクトリを指し示していることになる。(判りますか!?)

 ということは、先ほどlsコマンドで「/bin」ディレクトリの中身を覗いたときの操作は

 ls -l /bin

 と、

 ls -l bin
 ls -l ./bin

 とは、全く同じディレクトリを指し示し、同じ内容が表示されることになる。(判りますか!?大丈夫ですか!?)

 一方で、ファイル「hoge」を表示した際に、「ls -l hoge」と実行したアレ。どうなるか判りますか?
[piro791@kagami /]$ ls -l hoge
ls: hoge: そのようなファイルやディレクトリはありません

 こういうことになる。(理由は判りますか!?)

 だって、「現在のディレクトリ」が移動してしまったのだもの。先ほどは「現在のディレクトリ」が違うところにあって、その場所にファイル「hoge」があったのに、今は「ルートディレクトリ」に移動してしまったのだから、「現在いる場所」にそんなファイルは無いよ!…ということになるのであった。

 では、どうすればよい!?方法は2つある。
  ①絶対パスで指定する
  ②相対パスで指定する

 (あまり面白くないな…)

 「絶対パス」で指定するならば、先ほどディレクトリを移動する前に「pwd」コマンドで表示されたディレクトリをファイル名の先頭につけて指定することになる。

 この記事のサンプルでは先ほど「pwd」を実行したときには、「/home/piro791」であった。このディレクトリの中に有るファイル「hoge」を表示したいのなら…

 ls -l /home/piro791/hoge

 とすればよいことになる。試してみる。
[piro791@kagami /]$ ls -l /home/piro791/hoge
-rw-rw-r-- 1 piro791 piro791 7  1月 15 13:02 /home/piro791/hoge

 表示された。


 もう一つ。「現在のディレクトリ」から相対的にディレクトリを辿っていく方法も残されている。
 「現在のディレクトリ」の中にあるhomeディレクトリの、そのまた中にあるpiro791ディレクトリの、そのまた中にあるファイルhoge…ということなので、

 home/piro791/hoge
 あるいは
 ./home/piro791/hoge
 ということでも良い。
 試してみると…
[piro791@kagami /]$ ls -l home/piro791/hoge
-rw-rw-r-- 1 piro791 piro791 7  1月 15 13:02 home/piro791/hoge
[piro791@kagami /]$ ls -l ./home/piro791/hoge
-rw-rw-r-- 1 piro791 piro791 7  1月 15 13:02 ./home/piro791/hoge

 同じものが見えているのであった。

4:「上位ディレクトリ」

 「絶対パス指定」と「相対パス指定」との違いが微妙にでも判ってきただろうか。
 それでは、今度は「現在のディレクトリ」をもっと他の場所に移動して試してみることにしよう。

 cd /usr/local

 と、実行してみてもらいたい。ついでに、pwdコマンドで、移動できたことも確認しよう。
[piro791@kagami /]$ cd /usr/local
[piro791@kagami local]$ pwd
/usr/local

 さて。この場所から、たとえば「/bin/ls」ファイルを相対パス指定で指し示したいとしたらどうすればよいか…。

 これまでのこのアーティクルの中では、「いきなり幹を指し示す」(つまり「/」)か、または枝の末端方向に向かって進む方法しか説明してこなかったので、ここでは「相対的に幹の方向に戻る方法」が必要となってくる。

 それはずばり、「..」という記号を用いる。ピリオド2個ね。

 この「..」を用いると、ディレクトリ1段階分、幹の方向に移動することが出来る。「親ディレクトリと呼ぶことも多い。
 さきほど「/usr/local」というディレクトリに移動してもらったが、この状態で「..」を指定すると、「/usr」というディレクトリを指し示すこととなる。

 cdコマンドで、「..」を指定してディレクトリを移動、移動後にpwdコマンドで確認してみよう。すると…
[piro791@kagami local]$ pwd
/usr/local
[piro791@kagami local]$ cd ..
[piro791@kagami usr]$ pwd
/usr

 と、このように幹の方向に1段階戻ることができた。この指定方法は、同じレベルの隣のディレクトリへの移動等には特に重宝する。
 たとえば、先ほど移動してもらった「/usr/local」というディレクトリは、「/usr」というディレクトリの中にあるが、このディレクトリには「local」のほかに「bin」や「etc」、「lib」などといったディレクトリも存在している。同じレベルのとは、同じ「/usr」の中にある別々のディレクトリを言っている。
 再度「/usr/local」に移動してもらい、その状態から「/usr/bin」に移動する場合。

 cd /usr/bin  と指定するのは絶対パス指定の方法。
 cd ../bin  と指定するのが相対パス指定の方法になる。

 ちなみに、この記述方法は複数使っても良い。
 現在のディレクトリが /usr/bin の状態で、
 ../ → 1段階幹に戻った状態 → /usr
 ../../ → 2段階幹に戻った状態 → /

 ということになる。



 えらい長くなったが、重要なことなので次のアーティクルで再度説明を続けたい。

ディレクトリの中身をリストする (lsコマンド) [ファイル操作・管理]

 さて。

 概略的な話が長引いたので、気分転換(??)にコマンドの紹介をしてみる。

 ファイル操作・管理系のコマンドとして基本中の基本であるところの、「ls」コマンドから。実はすでに何度と無く使用しているのだけども。(笑)
 このコマンドの「書式」は次のとおり。

 ls [オプション] [対象となるファイルやディレクトリ...]

 lsコマンドに続けて、オプションや処理対象が指定できる。ただし、オプションも処理対象も省略可能。両方記述することも、両方省略することも、どちらか一方だけ指定することも自由自在に可能となっている。

 それでは、実際にコマンドを使用してみよう。(…とはいっても実は実際に使っていたのだが)

 まず、何も指定せずにlsコマンドだけで実行すると…
[piro791@kagami ~]$ ls
hoge  lesson1.txt

 lsコマンドに、処理対象となる引数を何も指定しなかった場合は、「現在のディレクトリ」が処理対象となる。「現在のディレクトリ」は「カレントディレクトリ」とも呼ばれる。なお、「現在のディレクトリ」という用語についてはこの後のアーティクルで説明したい。

 lsコマンドに何もオプションを指定しなかった場合は、「表示可能なファイルの名前」のみを表示する。「表示可能なファイルの名前」とは、ファイルの名前がピリオドで始まるファイル以外のことをいう。

 lsコマンドのオプションのうち、よく使われるものを紹介する。

 まずは「-l」オプション。これは、ファイルの一覧表示に詳細な情報をあわせて表示する。表示される内容は、ファイルのモード、リンクの数(後述)、所有者名、グループ名、ファイルの(バイト単位の)大きさ、タイムの最終更新日時、そしてファイルの名前である。また、ファイルの一覧表示に先立って、そのディレクトリが使用しているディスク容量の合計を集計表示する。「total blocks」あるいは「合計」という内容がそれである。が、今は気にしなくても良い。

 試してみよう。
 さきほどオプションも引数も何も指定しないでlsコマンドを実行したが、今度は「-l」オプションを実際につけて実行してみよう。
[piro791@kagami ~]$ ls
hoge  lesson1.txt
[piro791@kagami ~]$ ls -l
合計 8
-rw-rw-r-- 1 piro791 piro791 7  1月 15 13:02 hoge
-rw-rw-r-- 1 piro791 piro791 7  1月 15 15:14 lesson1.txt

 ファイルが2個あるが、「-l」オプションをつけてからは、それぞれのファイル名に加えていろいろな情報が追加表示された。これが「-l」オプションの効能である。

 続いて、「-a」オプション。これは、ファイル名がピリオド「.」で始まるファイル名も表示の対象に含める…というもの。なお、Windows(やMS-DOS等)にはファイルの属性に「隠しファイル」なるものがあるが、UNIX/Linuxにはそういった発想が無い。そのかわり、ファイル名がピリオド「.」で始まるファイル名については「隠しファイル」に準じる動作をするようになっている。(歴史的な経緯が…って奴ね)

 では、こちらも試してみよう。
 lsコマンドをオプション何もなしで実行したときと、「-a」オプションを指定したときとでの違いを見てみよう。
[piro791@kagami ~]$ ls
hoge  lesson1.txt
[piro791@kagami ~]$ ls -a
.  ..  .bash_history  .bash_logout  .bash_profile  .bashrc  .lesshst  hoge  lesson1.txt

 このように、「-a」オプションのある・なしで表示されるファイルの数が変動していることがわかる。

 オプション類は、その動作が矛盾しない限り、複数のオプションを同時に指定することが出来る。
 「-l」オプションと「-a」オプションとは動作が矛盾しないので同時に指定することが出来る。
 こんな具合になる。
[piro791@kagami ~]$ ls -l -a
合計 40
drwx------ 2 piro791 piro791 4096  1月 18 11:58 .
drwxr-xr-x 3 root    root    4096  1月  6 12:46 ..
-rw------- 1 piro791 piro791  836  1月 19 17:20 .bash_history
-rw-r--r-- 1 piro791 piro791   33  1月  6 12:46 .bash_logout
-rw-r--r-- 1 piro791 piro791  176  1月  6 12:46 .bash_profile
-rw-r--r-- 1 piro791 piro791  124  1月  6 12:46 .bashrc
-rw------- 1 piro791 piro791   35  1月 19 17:18 .lesshst
-rw-rw-r-- 1 piro791 piro791    7  1月 15 13:02 hoge
-rw-rw-r-- 1 piro791 piro791    7  1月 15 15:14 lesson1.txt

 ファイルについて詳しい情報が表示される…という「-l」オプションの効能と、ファイル名がピリオド「.」で始まるファイルも表示内容に含める…という「-a」オプションの効能とが同時に発揮されていることがわかる。

 また、時と場合によって重宝するオプションとしては、「-r」オプションがある。これは、ファイルの一覧を表示する際、一定の法則でソート(並び替え)をして表示されるのだが、そのソートを逆順にソートして出力する…というもの。

 「一定の法則で」とぼかして書いたが、ソートの法則を決めるオプションを別途指定したときにその法則が利いてくる。それらのオプションを省略した場合は、通常ファイル名の順番で表示される。(つまり、abc...の順)

 試してみよう。「-l」オプションだけで実行した場合と、「-l」オプションと「-r」オプションを組み合わせたときの表示結果。
[piro791@kagami ~]$ ls -l
合計 8
-rw-rw-r-- 1 piro791 piro791 7  1月 15 13:02 hoge
-rw-rw-r-- 1 piro791 piro791 7  1月 15 15:14 lesson1.txt
[piro791@kagami ~]$ ls -l -r
合計 8
-rw-rw-r-- 1 piro791 piro791 7  1月 15 15:14 lesson1.txt
-rw-rw-r-- 1 piro791 piro791 7  1月 15 13:02 hoge

 「-l」だけの場合は、hoge → lesson1.txtの順で表示されている。ABC順ではhがlよりも先にくるからである。
 一方で「-l」と「-r」とを組み合わせた場合はlesson1.txt → hogeの順に表示されている。ABCの順序が逆に並べなおされていることが判るだろう。

 ファイルのソート順を変更するオプションも一緒に紹介しよう。「-t」オプションは、ファイルを表示する際にファイルの最終更新日時の新しい順に表示するようになる。

 「-l」と「-a」オプションを同時に指定した場合と、さらに「-t」オプションを追加した場合を見てみよう。
[piro791@kagami ~]$ ls -l -a
合計 40
drwx------ 2 piro791 piro791 4096  1月 18 11:58 .
drwxr-xr-x 3 root    root    4096  1月  6 12:46 ..
-rw------- 1 piro791 piro791  836  1月 19 17:20 .bash_history
-rw-r--r-- 1 piro791 piro791   33  1月  6 12:46 .bash_logout
-rw-r--r-- 1 piro791 piro791  176  1月  6 12:46 .bash_profile
-rw-r--r-- 1 piro791 piro791  124  1月  6 12:46 .bashrc
-rw------- 1 piro791 piro791   35  1月 19 17:18 .lesshst
-rw-rw-r-- 1 piro791 piro791    7  1月 15 13:02 hoge
-rw-rw-r-- 1 piro791 piro791    7  1月 15 15:14 lesson1.txt
[piro791@kagami ~]$ ls -l -a -t
合計 40
-rw------- 1 piro791 piro791  836  1月 19 17:20 .bash_history
-rw------- 1 piro791 piro791   35  1月 19 17:18 .lesshst
drwx------ 2 piro791 piro791 4096  1月 18 11:58 .
-rw-rw-r-- 1 piro791 piro791    7  1月 15 15:14 lesson1.txt
-rw-rw-r-- 1 piro791 piro791    7  1月 15 13:02 hoge
drwxr-xr-x 3 root    root    4096  1月  6 12:46 ..
-rw-r--r-- 1 piro791 piro791   33  1月  6 12:46 .bash_logout
-rw-r--r-- 1 piro791 piro791  176  1月  6 12:46 .bash_profile
-rw-r--r-- 1 piro791 piro791  124  1月  6 12:46 .bashrc

 表示の順序が変化しているのがわかる。「-t」オプションをつけた場合、ファイル名の並びという観点ではバラバラになっているように見えるが、日付・時刻のところに着目すると、新しいファイルが上に、古いファイルが下に表示されるようになっていることがわかる。

 これを「-r」オプションをつけてさらに試してみる。すると…
[piro791@kagami ~]$ ls -l -a -t -r
合計 40
-rw-r--r-- 1 piro791 piro791  124  1月  6 12:46 .bashrc
-rw-r--r-- 1 piro791 piro791  176  1月  6 12:46 .bash_profile
-rw-r--r-- 1 piro791 piro791   33  1月  6 12:46 .bash_logout
drwxr-xr-x 3 root    root    4096  1月  6 12:46 ..
-rw-rw-r-- 1 piro791 piro791    7  1月 15 13:02 hoge
-rw-rw-r-- 1 piro791 piro791    7  1月 15 15:14 lesson1.txt
drwx------ 2 piro791 piro791 4096  1月 18 11:58 .
-rw------- 1 piro791 piro791   35  1月 19 17:18 .lesshst
-rw------- 1 piro791 piro791  836  1月 19 17:20 .bash_history

 表示結果がまた変化した。今度は日付・時刻が古いファイルが上に、新しいファイルが下に表示されるようになった。

 他にもファイルの状態を変更した日時とか、ファイルにアクセス(読み取り)した日時とかでもソートできるが、ここでの説明はひとまず割愛する。

 続いてよく使うオプションに「-d」オプションがある。これは、ディレクトリの「中身」ではなく、他のファイルと同様にディレクトリそのものを表示する…というもの。

 オプションを全て省略した場合と、「-d」オプションのみをつけた場合とで比較してみよう。
[piro791@kagami ~]$ ls
hoge  lesson1.txt
[piro791@kagami ~]$ ls -d
.

 「-d」オプションを指定した場合、ただ1文字ピリオド「.」のみが表示された。
 なんのこっちゃ?   という人もいるかもしれないが、続けて「-l」オプションをつけて試してみよう。
 すると…
[piro791@kagami ~]$ ls -l
合計 8
-rw-rw-r-- 1 piro791 piro791 7  1月 15 13:02 hoge
-rw-rw-r-- 1 piro791 piro791 7  1月 15 15:14 lesson1.txt
[piro791@kagami ~]$ ls -l -d
drwx------ 2 piro791 piro791 4096  1月 18 11:58 .

 表示された内容が変化していることは判るが、これでも「なんのこっちゃ?」という人がいるかもしれない。実は、このピリオド「.」だけの表示が『現在のディレクトリ』そのものを示しているのであった。「-d」オプションを省略した場合、lsコマンドはこのアーティクルのタイトルにあるような動作…つまり「ディレクトリの中身をリストする」という動作をする。しかし、「-d」オプションをつけた場合は中身ではなくディレクトリそのものをリストするのであった。

 たとえ話に置き換えると…
   「10番の引き出しを見せて~!」と依頼したとする。

 「-d」オプションが無い場合は、10番の引き出しの中身がずらっと見えるということ。(引き出しを開ける)
 「-d」オプションが有る場合は、10番の引き出しの外側が見えるということに。(引き出しを開けない)

 この違いが判ってもらえるだろうか。引き出しを開けるのか開けないのかの違い…と理解してもらうのが手っ取り早いと思う。




 オプションに続いて、引数の部分について解説する。
 lsコマンドには、どのファイルやディレクトリを処理すべきか指示を与えることが出来る。上記のオプションの解説については全て省略してきた。この場合はすでに述べたとおり「現在のディレクトリ」が処理対象となる。
 一方、処理すべきファイルやディレクトリが与えられた場合はそのファイルやディレクトリについてファイルの一覧や詳細な情報を表示するようになる。
 ファイルを指定してみよう。「-l」オプションを併用しているが、ファイルを何も指定しなかった場合と、ファイル「hoge」を指定した場合との違いを見て欲しい。
[piro791@kagami ~]$ ls -l
合計 8
-rw-rw-r-- 1 piro791 piro791 7  1月 15 13:02 hoge
-rw-rw-r-- 1 piro791 piro791 7  1月 15 15:14 lesson1.txt
[piro791@kagami ~]$ ls -l hoge
-rw-rw-r-- 1 piro791 piro791 7  1月 15 13:02 hoge

 「hoge」を指定した場合、そのファイルしか表示されなくなった。

 また、引数にファイルではなくディレクトリを与えた場合はどうか。ここでは、もともとUNIX/Linuxに備わっているディレクトリである、「/bin」というディレクトリを指定してみよう。「-l」オプションを併用している。すると…
[piro791@kagami ~]$ ls -l /bin
合計 7424
-rwxr-xr-x 1 root root    4988  9月  4 04:55 arch
lrwxrwxrwx 1 root root       4 11月 19 17:09 awk -> gawk
-rwxr-xr-x 1 root root   18484 10月 27 11:12 basename
-rwxr-xr-x 1 root root  735004  1月 22  2009 bash
-rwxr-xr-x 1 root root   23132 10月 27 11:12 cat
-rwxr-xr-x 1 root root   41828 10月 27 11:12 chgrp
-rwxr-xr-x 1 root root   38564 10月 27 11:12 chmod
-rwxr-xr-x 1 root root   44020 10月 27 11:12 chown
-rwxr-xr-x 1 root root   71524 10月 27 11:12 cp

 実際にはもっと沢山表示されるのだが、長すぎるので省略している。実際の表示結果については各自で試してみてもらいたい。
 とにかく、今まで見たことも無いファイルがずら~っと表示されたことには違いない。これは、「/bin」というディレクトリに保存されているファイルの一覧なのである。

 では、ここで「-d」オプションも試してみよう。先ほどの「ls -l /bin」に「-d」オプションをつけてみる。すると…
[piro791@kagami ~]$ ls -l -d /bin
drwxr-xr-x 2 root root 4096  1月 19 04:09 /bin

 このように、/binというディレクトリそのものが表示された。この違いが、引き出しを開けた/開けないの違いにあるということ。判ったかな?


まとめ:
 ・lsコマンドは、「ディレクトリの中身をリスト(一覧表示)する」コマンドである。

 ・lsコマンドでよく使うオプションは…
  
-lファイル名の他にファイルの詳しい情報も一緒に表示する
-aピリオドで始まるファイル(通常は表示されない)も表示する
-tファイル名の順でなく、ファイルの最終更新日時の新しい順にソートして表示する
-rソートの順番を逆にする
-dディレクトリの中身ではなく、ディレクトリそのものを表示する


 ・lsコマンドに引数を指定した場合、その指定したファイルやディレクトリが表示の対象となる。
 ・lsコマンドの処理対象はファイルでもディレクトリでも構わない。

コマンド入力の基本 [概論・概要]

 さて。
 これまで、何度と無くコマンドを入力してもらってきたが、「コマンド入力」の方法についても基本的に押さえておきたい点があるので説明しておく。

 まず、コマンド名。これは正確に入力すること。(当たり前)
 たとえば、「passwd」コマンドを使うつもりで「password」なんて入力したりすると、当然のごとくエラーになる。
[piro791@kagami ~]$ password
-bash: password: command not found

 「command not found」…コマンドが見つかりませんというエラー。

 次に、多くのコマンドは「オプション」と「引数」をとる。
 「オプション」とは、そのコマンドの動作を変化させる場合に指定するもので、多くの場合は「-」(ハイフン)に続けてアルファベットや数字をとる。また、「--」(ハイフン2個)に続けて何らかの単語・キーワードを指定することもある。
 「オプション」はほとんど例外なく省略可能で、特に凝ったことを要求しない場合などは省略することが多い。

 それでは、「オプション」を取ったり付けたりすることでコマンドの動作が変化するという実例を見てみることにしよう。

 前アーティクルで使った「ls」コマンド。ろくすっぽ説明していないが、詳しいことはまた別アーティクルで説明する。
 この「ls」コマンドには、「オプション」をつけて実行している。コマンド名の「ls」に続けて「-la」と入力した部分。これが「オプション」に該当する。
 「-la」をつけて実行した時はこんな風に表示された。
[piro791@kagami ~]$ ls -la
合計 40
drwx------ 2 piro791 piro791 4096  1月 18 11:58 .
drwxr-xr-x 3 root    root    4096  1月  6 12:46 ..
-rw------- 1 piro791 piro791  149  1月 15 19:24 .bash_history
-rw-r--r-- 1 piro791 piro791   33  1月  6 12:46 .bash_logout
-rw-r--r-- 1 piro791 piro791  176  1月  6 12:46 .bash_profile
-rw-r--r-- 1 piro791 piro791  124  1月  6 12:46 .bashrc
-rw------- 1 piro791 piro791   35  1月 18 13:45 .lesshst
-rw-rw-r-- 1 piro791 piro791    7  1月 15 13:02 hoge
-rw-rw-r-- 1 piro791 piro791    7  1月 15 15:14 lesson1.txt

 前アーティクルまでで見た内容のままである。
 続いて、「オプション」を変えてみよう。「-la」とした部分を「-l」にしてみる。(「a」を省略する)
[piro791@kagami ~]$ ls -l
合計 8
-rw-rw-r-- 1 piro791 piro791 7  1月 15 13:02 hoge
-rw-rw-r-- 1 piro791 piro791 7  1月 15 15:14 lesson1.txt

 表示内容が変化した。いくつかのファイルが表示されなくなったことがわかるだろうか。これが、「コマンドの動作が変化」したということ。
 では、「-l」も省略したらどうかるだろうか。(オプションそのものを省略した場合)
[piro791@kagami ~]$ ls
hoge  lesson1.txt

 表示内容がさらに劇的に変化した。ファイルのモードとか所有者とかファイルの大きさとか全部ばっさり省略され、ファイル名しか表示されなくなっていることがわかる。

 今度は、「-la」の「l」を省略し、「-a」だけに指定してみよう。すると…
[piro791@kagami ~]$ ls -a
.  ..  .bash_history  .bash_logout  .bash_profile  .bashrc  .lesshst  hoge  lesson1.txt

 このように、表示されるファイルの数が増えたが、ファイルの詳しい情報は表示されていない。

 lsコマンドでは、「l」と「a」とでそれぞれ異なる機能を持っていて、それを付けたり外したり組み合わせたりすることで、コマンドの動作結果を変化させることが出来ていることがわかる。

 「オプション」は、今例示したlsコマンドのように、ハイフンに続けて複数のオプション指定をまとめることも出来る。逆に、それぞれのオプション指定にハイフンをつけてバラバラに指定することもできる。
 lsコマンドの場合、「-la」と指定したが、これを「-l -a」というように、「l」と「a」とを分けて記述することもできるという意味。
 試してみよう。
[piro791@kagami ~]$ ls -la
合計 40
drwx------ 2 piro791 piro791 4096  1月 18 11:58 .
drwxr-xr-x 3 root    root    4096  1月  6 12:46 ..
-rw------- 1 piro791 piro791  149  1月 15 19:24 .bash_history
-rw-r--r-- 1 piro791 piro791   33  1月  6 12:46 .bash_logout
-rw-r--r-- 1 piro791 piro791  176  1月  6 12:46 .bash_profile
-rw-r--r-- 1 piro791 piro791  124  1月  6 12:46 .bashrc
-rw------- 1 piro791 piro791   35  1月 18 14:13 .lesshst
-rw-rw-r-- 1 piro791 piro791    7  1月 15 13:02 hoge
-rw-rw-r-- 1 piro791 piro791    7  1月 15 15:14 lesson1.txt
[piro791@kagami ~]$ ls -l -a
合計 40
drwx------ 2 piro791 piro791 4096  1月 18 11:58 .
drwxr-xr-x 3 root    root    4096  1月  6 12:46 ..
-rw------- 1 piro791 piro791  149  1月 15 19:24 .bash_history
-rw-r--r-- 1 piro791 piro791   33  1月  6 12:46 .bash_logout
-rw-r--r-- 1 piro791 piro791  176  1月  6 12:46 .bash_profile
-rw-r--r-- 1 piro791 piro791  124  1月  6 12:46 .bashrc
-rw------- 1 piro791 piro791   35  1月 18 14:13 .lesshst
-rw-rw-r-- 1 piro791 piro791    7  1月 15 13:02 hoge
-rw-rw-r-- 1 piro791 piro791    7  1月 15 15:14 lesson1.txt

 このように、「-la」と「-l -a」とは同じ動作をしている。

 なお、コマンドによっては「--」(ハイフン2個)でオプションを指定するケースもある。lsでも可能なので、その例を示しておく。「-la」と全く同じことをするオプションを「--」(ハイフン2個)で指定すると…
[piro791@kagami ~]$ ls --format=long --all
合計 40
drwx------ 2 piro791 piro791 4096  1月 18 11:58 .
drwxr-xr-x 3 root    root    4096  1月  6 12:46 ..
-rw------- 1 piro791 piro791  149  1月 15 19:24 .bash_history
-rw-r--r-- 1 piro791 piro791   33  1月  6 12:46 .bash_logout
-rw-r--r-- 1 piro791 piro791  176  1月  6 12:46 .bash_profile
-rw-r--r-- 1 piro791 piro791  124  1月  6 12:46 .bashrc
-rw------- 1 piro791 piro791   35  1月 18 14:13 .lesshst
-rw-rw-r-- 1 piro791 piro791    7  1月 15 13:02 hoge
-rw-rw-r-- 1 piro791 piro791    7  1月 15 15:14 lesson1.txt

 「-l」の代わりに「--format=long」と書き、「-a」の代わりに「--all」と書いている。まあ、めったにこんな書き方はしないと思うけどもね…

 続いて、コマンドに指定する「引数」の方。
 これは、多くの場合はコマンドが処理する対象となるファイルや情報をコマンドに通知する際に指定するように用いる。

 すでに「vi」コマンドを練習したときにこの「引数」を指定している。「vi」コマンドに続けて指定した、「lesson1.txt」というファイル名がソレである。「引数」として「lesson1.txt」を指定することで、viコマンドはどのファイルを編集すればよいか判るのであった。

 ちなみに、lsコマンドも「引数」を取ることが出来る。たとえば、viと同じようにlsコマンドに「引数」として「lesson1.txt」と指定してみよう。
[piro791@kagami ~]$ ls lesson1.txt
lesson1.txt

 このように、lsコマンドが処理をすべき対象が特定されることになる。lsコマンドは「引数」として指定されたファイル「のみ」を対象として処理を行っている。

 「オプション」と「引数」とは組み合わせて用いることもできる。lsコマンドで、
  ・「-l」オプションの機能
  ・lesson1.txt のみを対象とする
 というような処理を行いたい場合、「オプション」と「引数」と、両方を指定すればよい。
[piro791@kagami ~]$ ls -l lesson1.txt
-rw-rw-r-- 1 piro791 piro791 7  1月 15 15:14 lesson1.txt

 このようになる。
 なお、「オプション」と「引数」とは、通常「オプション」→「引数」の順に記述するのが一般的である。ただし、「オプション」の一部のパラメータとして先頭にハイフンが付かない記述をすることもあるので注意が必要である。

ファイルにまつわる情報 [ファイル操作・管理]

 さて。
 開始早々viの使い方を説明した。慣れない内は相当苦戦すると思うので、出来るだけ積極的に使って慣れるようにしておいてほしい。

 では、いよいよ本題に進むことにする。

 「サーバ管理者」の役割ってなんですか?

 という問いかけを突き詰めると、「ファイルを管理することですよ」と答えることができるかもしれない。まあ、他にも
  ・ユーザーアカウントの管理
  ・プロセスの管理
  ・OSやアプリケーション(ミドルウェア・デーモンプロセス)の管理
  ・ハードウェア・ディスクの管理
 とかいろいろ挙げられるけども、もっとも大きなウェイトを占めるのは「ファイルの管理」ではないかと思う。つまり、この「ファイルの管理」という役割を果たすために必要な操作、つまり「ファイルの操作」の知識はサーバ管理者として最も重要な知識であると言っても過言ではない。

 よって、まず最初にこの「ファイルの操作」についてみっちり覚えてもらわなければならない。

1.ファイルにまつわる情報~lsコマンドで確認できること~

 それでは、サーバにログインしたら、ターミナルから「ls -la」とコマンドを実行してもらいたい。
[piro791@kagami ~]$ ls -la
合計 36
drwx------ 2 piro791 piro791 4096  1月 15 15:14 .
drwxr-xr-x 3 root    root    4096  1月  6 12:46 ..
-rw------- 1 piro791 piro791  149  1月 15 19:24 .bash_history
-rw-r--r-- 1 piro791 piro791   33  1月  6 12:46 .bash_logout
-rw-r--r-- 1 piro791 piro791  176  1月  6 12:46 .bash_profile
-rw-r--r-- 1 piro791 piro791  124  1月  6 12:46 .bashrc
-rw-rw-r-- 1 piro791 piro791    7  1月 15 13:02 hoge
-rw-rw-r-- 1 piro791 piro791    7  1月 15 15:14 lesson1.txt

 こんな内容が表示されたのではないかと思う。表示される情報はもっと多かったり少なかったりするかもしれないが、とりあえず数行表示されればOK。

 各行ではなく、各カラムごとに注目してみよう。
 まず、一番左側(各行の最初のカラム)の固まりから。
  「drwx------」とか、「-rw-------」とか、「-rw-r--r--」とか、「-rw-rw-r--」とかいう表示が見える。この部分は、「ファイルのモード・権限情報」を記号で表している部分。この表示内容によって、
  ・それはファイルですか?ディレクトリですか?
  ・そのファイルを読める人は誰ですか?書き込める人は誰ですか?
 というような情報を読み取ることができるようになる。

 空白を置いてから、数字がポロッとある。上記の表示例では「2」とか「3」とか「1」とか出ている部分。これは、「リンク数」という情報を示している。「リンク」については別途アーティクルを改めて紹介するので、今はそれほど気にしなくても良い。

 さらに空白を置いてから表示されているのは、「ファイルの所有者」である。このファイルの持ち主がここでわかる。
 上記の表示例では、同じ名前が2回続けて表示されているが、最初のもの(左側のもの)が今紹介した「ファイルの所有者」で、その後(右側)に表示されているのが「グループ名」である。今はアカウント名(所有者名)とグループ名が同一のものになっているが、サーバ管理者の管理ポリシーによってはグループ名は他の表示になっているかもしれない。

 空白を置いてからさらに表示されているのは、「ファイルのサイズ(バイト数)」である。ファイルの大きさがここでわかるのである。

 サイズの後ろには、そのファイルの「タイムスタンプ」が表示される。「タイムスタンプ」とは、そのファイルが作成されたり、最後に更新されたりした日時のことである。

 そして、空白を置いて最後に表示されているのは「ファイルの名前」である。これは見れば判ると思うが。

2.ファイルのモードと権限の情報について~いわゆる「パーミッション」~

 lsコマンドでざっとファイルの状態を見てもらったが、先ほどの表示内容の中でとても重要な情報として「ファイルのモード・権限情報」が挙げられる。この部分の読み方をきちんと覚えてもらう必要がある。

 まず、先頭の1文字と、後ろの9文字とに分けることができる。色分けするとこんな感じ。

 「-rw-r--r--

 先頭の1文字(上記表示例で赤い部分)は、ファイルのモードをあらわしている。

 ごく普通のファイル-
 ディレクトリd
 リンクファイルl
 ブロックデバイスb
 キャラクタデバイスc

 ざっとこんな感じになっている。多いのは「-」「d」「l」くらいか。
 先ほどのlsコマンド実行例の場合、最初の2行「.」と「..」だけこの部分が「d」と表示されていた。これによって、「.」と「..」はディレクトリであることがわかる。

 続く9文字の部分(上記表示例で青い部分)は、そのファイル(やディレクトリやリンクファイル…)に対するアクセスの許可情報をあらわしている。この9文字の部分は、さらに3文字ずつ3分割して見る必要がある。

 「rw-r--r--

 最初の3文字(青い部分)は、ファイルの持ち主に許されたファイルへのアクセス権限である。続く3文字(緑色の部分)は、ファイルのグループ名表示と同じグループに所属する人に許されたファイルへのアクセス権限である。そして最後の3文字(ピンク色の部分)は、アカの他人に許されたファイルへのアクセス権限となっている。

 そして、それぞれの人が何を出来るのか…という情報がこの3文字に込められている。
 この3文字の中に登場する情報としては、
 そのファイルを読めるr
 そのファイルに書き込めるw
 そのファイルを「実行」できるx
 という意味がある。
 たとえば3文字の表示が「r--」だった場合、その人はそのファイルに対して
  ・そのファイルを読める
  ・そのファイルには書き込めない
  ・そのファイルは実行できない
 という許可情報を持っていることになるし、「rw-」だった場合は、その人はそのファイルに対して
  ・そのファイルを読める
  ・そのファイルに書き込める
  ・そのファイルは実行できない
 という許可情報を持っていることになる。「---」だった場合は、その人はそのファイルに対して
  ・そのファイルは読めない
  ・そのファイルには書き込めない
  ・そのファイルは実行できない
 と、要するに「アクセス禁止」状態にあることになる。

 ところで、「実行できる」とか「実行できない」とか何なんだろうか?
 これは、そのファイルが「実行可能ファイル」という形式のファイル、または「シェルスクリプト」とか「perlスクリプト」とかいった、何らかのプログラムされたファイルである場合に意味を持つ。

 UNIX/Linuxの場合、多くのコマンドはこうした「実行可能ファイル」の形式で提供されている。OSはこれを読み込んでメモリの上に展開し、それを実行することで様々な機能を提供している。たとえば今回使った「ls」コマンドも、前回使った「vi」コマンド、そしてその前に使った「passwd」コマンドなども全て「実行可能ファイル」の形式で提供されている。
-rwxr-xr-x 1 root root  95116 10月 27 11:12 /bin/ls
-rwxr-xr-x 1 root root 594740  9月 20 06:24 /bin/vi
-rwsr-xr-x 1 root root  22984  1月  7  2007 /usr/bin/passwd

 1行目のlsコマンドは許可情報が「rwxr-xr-x」と表示されている。「x」が付いているので、コマンドとして実行できるファイルであることがわかる。viもpasswdも同様。(passwdには見慣れない「s」が付いているが、今は気にしないように)

 一方で、前アーティクルまででviの練習で使用していた「lesson1.txt」というファイルはというと…
-rw-rw-r-- 1 piro791 piro791    7  1月 15 15:14 lesson1.txt

 これはごく普通のファイルなので(コマンドではないので)「x」がそもそも付いていない。よって、「ls」とか「vi」とかのようにコマンドとして入力しても実行されないのである。
[piro791@kagami ~]$ ./lesson1.txt
-bash: ./lesson1.txt: 許可がありません

 このように、「実行権が無い」のでエラーになってしまう。

 許可情報の部分的な見方がわかったところで、おさらいしてみよう。

 「-rw------- 1 piro791 piro791 149 1月 15 19:24 .bash_history」
 このファイルは、
  ・piro791さん(所有者)は読める / 書き込める / 実行はできない
  ・piro791グループに所属するpiro791さん(所有者)以外の人は、読めない / 書き込めない / 実行できない
  ・その他の人は、読めない / 書き込めない / 実行できない

 ということが判る。要するに、piro791さん(所有者)だけがアクセスできるファイルですよ…ということ。

 「-rw-r--r-- 1 piro791 piro791 124 1月 6 12:46 .bashrc」
 このファイルは、
  ・piro791さん(所有者)は読める / 書き込める / 実行はできない
  ・piro791グループに所属するpiro791さん(所有者)以外の人は、読める / 書き込めない / 実行できない
  ・その他の人は、読める / 書き込めない / 実行できない

 ということに。要するに、誰でも読めるが書き込めるのはpiro791さん(所有者)だけよ…ということ。

 「-rwxr-xr-x 1 root root 95116 10月 27 11:12 /bin/ls」
 このファイルは、
  ・rootさん(所有者)は読める / 書き込める / 実行できる
  ・rootグループに所属するrootさん(所有者)以外の人は、読める / 書き込めない / 実行できる
  ・その他の人は、読める / 書き込めない / 実行できる

 ということに。まあ、lsコマンドそのものなので、誰でも実行できる(実行するためには読み取れる必要がある)けど、変更できるのはrootさん(所有者)だけよ…ということ。

 コマンドのファイルを知らない人に書きかえられちゃうととんでもないことになるからね!!

いきなりの難問の続き~続・viの操作に慣れてもらおう~ [ファイル操作・管理]

 さて。
 続けてviの操作編。前アーティクルで、文字の追加と削除、ファイルの保存とエディタの終了について説明した。とりあえず、その操作だけでも出来ればがんばればどうにかなるのだが、正直なところちょっと大変過ぎるので(大笑)、もう少しだけ、viのコマンド・操作について覚えておいて欲しい。

 それでは、前アーティクルで作成した「lesson1.txt」で練習を再開することにしよう。コマンドプロンプトから、「vi lesson1.txt」でファイルを開こう。

 今度は前回と少しだけ表示が異なっていることが判る。
20100115_vi編集開始直後.jpg ←viコマンド開始直後の状態。ターミナルの一番下の行で、前回「New File」とい表示があった場所に、「1L, 7C」という表示が見える。これは、そのファイルの行数文字(キャラクター)数を示している。1行・7文字のファイルですよと言っているのである。

 「7文字?」画面上には「6文字」しか見えないけど?

 これは、画面上では見えないが、「ABCXYZ」のさらに後ろに、改行コードが入っている場合、その改行コードそのものもカウントされているからの他ならない。このように、文字(キャラクター)数は、人間の目に見える文字だけとは限らないことに留意してほしい。


・行の末尾に文字を追加する

 前アーティクルで、「a」コマンドを説明した。これはカーソルの後ろに文字を追加するコマンドであった。viでファイルを開いた直後、カーソルは先頭の「A」の上に表示される。この時点で「a」を押すと、カーソルの後ろに文字が追加されることになるので、「A」と「B」との間に文字が挿入されることはわかるだろうか。

 このような時に、「a」の代わりに、大文字アルファベットの「A」(Shiftキー+aキー)を押すと、カーソルがある行の末尾に文字が追加されるようになる。先ほどの、viコマンドでファイルを開いた直後の状態から、「A」を押すと…
20100115_viA.jpg ←このように、カーソルキーが「Z」の後ろに移動した上でターミナルの一番下の行に「-- INSERT --」と表示され、エディットモードになっていることがわかる。これで、行の末尾にどんどん追記することができるようになる。

20100115_viA追記.jpg ←こんな具合に。


 ちなみに、Enterキーを押すまでが「一行」なので、ターミナル内で折り返している行があっても、Enterキーが押された位置までカーソルは移動する。
 たとえば…
20100115_viじゅげむ1.jpg ←「すごく長い1行」の例。ファイルの中には、「じゅげむじゅげむ…」をローマ字で書いた行がある。ターミナル内では3行にわたっているが、Enterキーは3行目の末尾部分で1回押しただけ。カーソルは行の先頭(ターミナル内1行目の先頭)にある。
 この状態で「A」を押すと…

20100115_viじゅげむ2.jpg ←このように、「見た目の1行」でなく、長い行の末尾にカーソルが移動していることがわかる。


・行のコピーとペースト

 1行をまるまるコピー&ペーストすることができる。ちなみに、viの文化(?)では、コピーといわずに「ヤンク」と言うらしい。わりとどうでも良いことだけども。。。。

 まず、コピーしたい行にカーソルを移動させる。(といっても、今は1行しかないのだけども)カーソルのカラム位置はどこにあっても構わない。要するにカーソルが「その行」にいればよい。

 その状態でキーボードの「y」キーを2回、つまり「yy」とタイプする。この状態で、1行丸ごとバッファに保存(コピー)される。Windowsでいうところの「クリップボード」って奴。

 そして、キーボードの「p」キーまたは「P」キーを押すと、今コピーした行がペーストされる。小文字のpと大文字のPとでは、ペーストされる位置が異なる。小文字の「p」は、今カーソルのある行の下の行にペーストされ、大文字の「P」は、今カーソルのある行の上の行にペーストされる。
 前アーティクルで作成したファイルは1行しかないのでわかりづらいと思うので、下にサンプル画像を用意したので、こちらを見てもらいたい。
20100115_viペースト例1.jpg ←今、カーソルはアスタリスクが6個書かれている行の上にある。ちなみに、この行に移動する前に「ABCXYZ」の行で「yy」を実行し、バッファに保存した状態になっている。
 この状態で、アルファベット小文字の「p」を押すと…

20100115_viペースト例2.jpg ←このように、カーソルがいたアスタリスクの行の下の行にペーストされた。一方、先ほどの状態から、アルファベット大文字の「P」を押した場合は…

20100115_viペースト例3.jpg ←このように、カーソルがいたアスタリスクの行の上の行にペーストされた。
 このように、小文字と大文字とで動作が微妙に異なるので気をつけてもらいたい。


・行を丸ごと削除する

 こんどは、1行丸ごと削除するコマンド。「yy」と似ているが、キーボードの「d」キーを2回押す。つまり、「dd」と入力することになる。「yy」コマンドと同じように、カーソルが現在位置している行が削除される対象となり、カラム位置はどこにあっても構わない。
20100115_vidd前.jpg ←たとえば、3行のデータがあるファイルを想定したとして、今カーソルは真ん中の2行目、アスタリスクの行に位置している。ここで「dd」と入力すると、この行が消えるはず。

20100115_vidd後.jpg ←このように、アスタリスクの行が消えて、3行目だった行が2行目になっている。

なお、「dd」コマンドで削除した行も「yy」コマンドと同じくバッファに保存されるため、「p」または「P」でペーストすることが出来る。
 先ほどの例でアスタリスクの行を削除した状態で、カーソルが2行目「DEFUVW」の行にある。ここで「p」を押すとカーソルのある行の下、つまり「DEFUVW」の次の行に先ほど削除した行が表示されるのである。
20100115_vidd後p.jpg ←こんな具合。行の移動とか、間違って削除した行の復活とかに使えるのであった。


・文字・文字列の書き換え

 とりあえず、「x」と「i」または「a」さえ知っていればどうにかできる範疇のものではあるけども、これを知っているのと知らないのとでは便利さが結構違うのでついでに紹介しておく。

 カーソルが今いる位置の文字を1文字書き換えたい…というときには、キーボードの「r」を押す。すると、今カーソルがいる位置の文字を1個だけ書き換えることが出来る。1文字書き換えると自動的にコマンドモードに復帰する。

 たとえば、「ABCXYZ」の「X」を「D」に書き換えるとしよう。(結果的に「ABCDYZ」にしたい)
 カーソルを「X」の上に移動する。
20100115_viXの上.jpg ←この状態から、キーボードの「r」キーを押してから「D」を入力すると…

20100115_vir.jpg ←このように、「X」が「D」に置き換わる。

 なお、大文字の「R」を押すと、1文字だけでなく文字列の書き換えを行うことが出来る。たとえば、「ABCXYZ」を「ABCDEF」に書き換えたい場合、「X」の上にカーソルを移動したら、「R」を押し、続けて『DEF』と入力すると、XYZの部分を書き換えることができる。「R」で書き換えを行う場合は、「Esc」キーを押すまでずーっとエディットモードに入ったままになるので注意が必要。

・カーソルを移動する

 ぶっちゃけ、いまどきのLinuxな環境ならコマンドモードでもエディットモードでもカーソルキーを押せばカーソルを移動することができるので、あまり深く考える必要は無いのだが、ごくまれに、キーボードの設定が壊れたり消えたりしてカーソルキーが使えない…なんてこともありうる。そのような場合にも対応できるよう、コマンドモードでカーソル移動をする方法を覚えておこう。

 キーボードの「h」「」「k」「l」を使う。これらのキーはそれぞれ、「」「」「」「」に対応している。

 これ、苦手な人多いみたいね…(笑)

 なお、カーソルを大して移動しない場合なら、こうしたキーでちまちま移動しても構わないが、すごく大きなファイルで、ファイルの一番最後に移動したいとか、一番先頭に移動したいとか、「じゅげむじゅげむ…」ばりに長い行の先頭・末尾にカーソルを移動したいとかいうこともあると思う。このような場合には、それぞれ以下のようなコマンドを使うと良い。

 ファイルの先頭に移動する … 「:1
 ファイルの指定行に移動する … 「:行番号
 ファイルの最終行に移動する … 「:$
 その行の先頭に移動する … 「0
 その行の末尾に移動する … 「$

 指定行に移動するコマンドは、「:」(コロン)で始まるコマンドなので、Enterキーを押す必要があることは言うまでもない。

 他にも便利な機能は沢山あるのだけども、今回はひとまず、ここで紹介した機能さえ使えればどうにかなるので、ここで一旦終了したい。
 viについて興味がある人は、「オライリー・ジャパン」から出版されている解説書を読んでもらいたい。

いきなりの難問で申し訳ないが…~viエディタに慣れてもらおう!~ [ファイル操作・管理]

 さて。
 ログインしてパスワード変更をしてログアウトする手順についてみてもらった、UNIX/Linux管理者のタマゴな人たちに、いきなり「vi」の説明をしなければならないのが心苦しいのだが(笑)、コレが使えないとどうしようもないので、思い切っていきなり最初に練習してしまおうと思うので、覚悟していただきたい。(笑)

 「vi」とは、テキストエディタである。UNIXの時代から続く古式ゆかしいエディタである。まあ、今でこそ他にもっと便利なエディタが使えるようになっているものの、サーバ障害などでにっちもさっちもいかなくなってしまった場合などでviしか使えない!!…というケースに陥ることもゼロではないので、最後の頼みの綱として活躍することもある。そんなことになって初めて慣れない「vi」で四苦八苦するよりも、できれば日常的に、少なくともUNIX/Linuxサーバの上では使い続けることで、習熟しておいたほうが良いのではないかと思う。

 と、前置きが長くなってしまったが、それでは「viエディタ」の使用方法について、解説しつつ練習してもらうことにする。

 コマンドは「vi」である。このコマンドに続けて、作成したいファイル名・編集したいファイル名を指定する。
 たとえば、「lesson1.txt」というファイル(今はまだ無い)を新しく作成する場合は…

 vi lesson1.txt

 と、コマンドを実行することとなる。
 このコマンドを実行すると、ターミナルソフトの画面が全体的に書き換わる。たとえば↓みたいな感じ。
20100115_vi新規.jpg 画面全体がエディタになる。一番下の行は、ステータスが表示されたり、エディタコマンドを入力するための領域として使用されたりする。サンプルで表示している画像では、ウィンドウの一番下に
 "lesson1.txt"
とか、
 [New File]
とか、表示されているのがわかる。この場合は読んで字のごとく、lesson1.txtという新しいファイルを編集(作成)してますよ…ということを意味しているのである。

 さて。Windowsに標準で添付されている「メモ帳」とか、利用者の多いことで名高い「秀丸エディタ」、私が個人的にイチオシする「TeraPad」などのような、GUI環境で動作するテキストエディタと決定的に異なるのが、「vi」には「モード」という概念が存在する。この、「モード」には大きく分けて
 1.コマンドモード
 2.エディットモード
の2つがあって、コマンドモードでは押したキーに応じてカーソルが移動したり、文字や行をコピーしたり削除したりペーストしたり、ファイルを保存したり文字の置換をしたり…といった振る舞いをする。一方エディットモードでは押したキーがそのままテキストデータとしてファイルの書き込まれることとなる。キー操作によってコマンドモードエディットモードとを切り替えながら使うのが、この「vi」の特徴であるといっても良いかもしれない。

 で、先ほど見てもらったviの画面では、エディタはコマンドモードになっている。このまま入力したい文字のキーを押したところで、文字は入力されない

 まずは簡単なところから紹介しよう。コマンドモードからエディットモードへモードを切り替えるコマンドから。

 コマンドモードで、キーボードの「i」を押す。すると、エディットモードに切り替わる。

20100115_vi挿入.jpg 先ほどまで、ファイル名が表示されていたターミナルの一番下の行が、「-- INSERT --」という表示になった。今
エディタのモードはエディットモードになっていることがこれで判る。今から押したキーはコマンドとして解釈されず、ファイルの中身として画面上に表示されるようになる。

 ためしに、「ABCXYZ」とでも入力してみようか。
20100115_vi挿入ABCXYZ.jpg このように、今度は入力したキーがそのまま画面に表示された。先ほどコマンドモードの時に入力した「i」は画面に表示されなかったことと比較してほしい。
 キーを入力し誤った場合などはBackSpaceキーで遠慮なく修正してもらいたい。なお、そのサーバ管理者が特に古風なその筋の人の場合、BackSpaceキーのかわりにDeleteキーを使うように設定されていることもあるので、そのあたりは驚かないように。サーバ管理者から説明があるかもしれないので、その場合はサーバ管理者の指示に従ってもらいたい。


 こんどは、エディットモードからコマンドモードに切り替える方法を説明する。こっちは非常に簡単で、単にキーボードの「Esc」キーを1回押せばよい。すると、ターミナルの一番下の行に表示されていた「-- INSERT --」の表示が消えることが判る。これでコマンドモードに戻ったのである。
 なお、この「Esc」キーをしてコマンドモードに戻る方法は、エディットモードからの復帰だけでなく、コマンドモードで何らかの長めのコマンドを入力している時にその入力をやめる際とかにも使える。「Esc」キーを押せば必ずコマンドモードになるので、操作中に訳がわからなくなったケース等では「Esc」キーをバシバシ叩いておけば、とりあえずコマンドモードに戻れるということを覚えておいてほしい。

 ちなみに、コマンドモードからエディットモードへモードを切り替えるコマンドとしてはキーボードの「a」を押す方法もある。キーボードの「a」キーを押してもキーボードの「i」キーを押したときと同様に、エディットモードになってターミナルの一番下の行に「-- INSERT --」という表示が出る。しかし両者には微妙な違いがあるので気をつけてほしい。

 例として、今入力した「ABCXYZ」という文字列の、「ABC」と「XYZ」との間に『DEF...UVW』という文字を挿入してみようと思う。
 コマンドモードになっている状態で、キーボードの「h」キー、またはカーソルキーの「←」キーを押して、カーソルを「x」の文字の上に移動する。
20100115_viXの上.jpg ←こんな感じになったら、ここでさきほど使ったキーボードの「i」キーでエディットモードにモードを切り替える。

20100115_viXの上でi.jpg ←こうしてエディットモードに切り替えるが、この状態でそのまま『DEF...UVW』と入力する。

20100115_viXの上でi2.jpg ←するとこのように文字が追加されるのである。

 では、「微妙に動作が異なる」という、キーボードの「a」キーだとどうなるか。
 さきほどと同じように、ABCXYZという文字列が表示されている状態でカーソルを「x」の上に移動したところから、キーボードの「a」キーを押してエディットモードに切り替えてそのまま『DEF...UVW』と入力すると…
20100115_viXの上でi3.jpg ←と、このようにDEF...が入力される位置が違うことが判る。


 つまり、
  i…カーソルのに挿入
  a…カーソルの後ろに挿入(というか追加…append)
 ということだと理解してもらうとよいだろう。

 文字の追加に続いて、文字の削除も押さえておこう。
 文字を削除するための一番基本的なコマンドは、コマンドモードで、キーボードの「x」キーを押す。1回押すと、今カーソルがある位置の文字が1文字削除される。
 先ほど、「ABCDEF...UVWXYZ」とした文字列を、再び「ABCXYZ」に戻してみよう。

 コマンドモードでカーソルを「D」の上に移動してから、キーボードの「x」キーを9回押すと…(面倒くさいのでスクリーンショットは省略)

 めでたく「ABCXYZ」に戻っていることだろう。

 ということで、文字の追加と文字の削除とが出来れば、必要最低限のことはどうにかなるので、しっかり覚えておいてほしい。

 で、アーティクルがずいぶんと長くなってしまったが、あとどうしても覚えておいて欲しいことが残っているので、それも一緒に説明する。

 viコマンドを終了させる方法だ。

 ファイルの編集が出来るようになっても、エディタが終了できなければ意味が無い。(笑)その方法を説明する。
操作は全てコマンドモードで行う。キーボードの「:」(コロン)キーを押すところからはじまる。
20100115_viXの上.jpg ←たとえば、この状態から「:」(コロン)キーを押すと…

20100115_viコロンキー.jpg ←このように、ターミナル画面の一番下の行に「:」とカーソルが表示されるようになる。この状態になったところで、エディタを終了するためのコマンドを入力するのである。

 ファイルをそのまま保存する場合(Windowsでいうところの「上書き保存」) … 「:w」 (まだviは終了しない)
 別の名前をつけて保存する場合(Windowsでいうところの「名前をつけて保存」) … 「:w File名」 (まだviは終了しない)

 ファイルをそのまま保存して終了する場合(「上書き保存」してから「終了」を同時に) … 「:wq

 ファイルを保存しないで終了する場合 … 「:q
  ※なお、開いたファイルを編集しているにもかかわらず、保存しないまま終了しようとするとエラーになるので、↓のコマンドを実行する必要がある

 編集済みのファイルを保存しないで終了する場合 … 「:q!
  ※強制的に終了するが、Windowsみたいに「本当によいですか?」みたいな確認はしてこないので要注意。

 なお、「:」(コロン)で始まるコマンドは、Enterキーを押して有効になる。モードを切り替える際のコマンドはワンキーで直ちに切り替わったことと比べて欲しい。「:」(コロン)で始まるコマンドをキャンセルしたい場合も、「Esc」キーを押せばコマンドモードに復帰するようになっている。

 それでは、今作成したファイル「lesson1.txt」には「ABCXYZ」と記述されている状態で保存し終了してもらいたい。コマンドは「:wq」と入力してからEnterキーを押す。すると、Linuxのコマンドプロンプトが表示される、viが終了したことがわかる。

※※まとめ※※
 ・viはテキストエディタである。
 ・viには、「コマンドモード」と「エディットモード」とがある。
 ・コマンドモードで「i」キーを押すと、「コマンドモード」から「エディットモード」に切り替わり、カーソルの前に文字が挿入される。
 ・コマンドモードで「a」キーを押すと、「コマンドモード」から「エディットモード」に切り替わり、カーソルの後ろに文字が挿入される。
 ・コマンドモードで「x」キーを押すと、カーソルがある位置の文字が1文字消える。
 ・エディットモードで「Esc」キーを押すと、コマンドモードに切り替わる。
 ・コマンドモードで「:」(コロン)に続けて「w」「wq」「q」「q!」と入力するとファイルを保存したり、viを終了したりすることができる。

一番最初のLinux ~ログインしてみる~ [概論・概要]

 さて。
 今、君の前にLinuxの環境がある。しかしGUIは無い。
 GUI、つまり、WindowsXPだのVistaだの7だのみたいな、マウスでほとんどの操作が出来てしまうような環境は存在していない。話はここから始まるのである。

 ではどうするのか。それは、君がこれから行う操作は全てキーボードを使って一つ一つ命令を下していくことになるのである。そういう環境が君を待っている。


 …そう思ってもらいたい。

 かつて、Linuxが隆盛を誇る前は、「UNIX」の練習をするところからはじまった。かつてのUNIXは、とても一般人の手に届かないような高価なマシンの上で華麗に動くOSという印象が強かったのではないだろうか。それこそ、会社や学校…学校といっても、専門学校や大学、というような専門性の高い学校でなければ触れる機会はほとんど無かったかもしれない。

 その「UNIX」の練習・学習をするにあたって、最初にすることは

 ログイン

 である。(雑誌ではない)

 UNIXサーバにログインするには、これまた高価なターミナルの前に座り、普段と違うキーボードにビクビクしながら操作をしたものであった。(笑)

 ターミナルには、ただ一言(?)。

login:


 とだけ表示された画面が。生まれて初めてUNIXに触れる人間を威圧するに十分すぎる画面を見て、恐る恐る操作をしたものであった。

 時代は下り、今はLinuxが大量繁殖。安価なPCでも快適にLinuxを使用することが出来るような次代になった。しかしそれでも、Linuxサーバにログインする時は…

login:


 というUNIX時代とは何も変わっていないシンプルすぎるプロンプトが表示されるのみである。

 ただし、UNIX時代と異なるのは、今このようなプロンプトを目撃するのはおそらくサーバのコンソール画面からのみではないかという点。UNIXの時はほとんどコレだったのに。(笑)

 Linuxサーバのコンソール画面からの「ログイン」操作について、ちょっと見てもらうことにしよう。

 まずLinuxサーバのコンソールをサーバ管理者の人にお願いして見せてもらうと、このような感じになっていることだろう。

20100106コンソールログイン画面.jpg 最初の2行「CentOS…」と「Kernel…」という表示は、いわばサーバの自己紹介みたいなものだ。OSの種類やカーネルのバージョンが表示される。
 1行間を置いて、「kagami login:」という行。最初の「kagami」はサーバの名前である。このサーバの名前は「kagami」というのである。
 その後ろの「login:」という表示。これはUNIX時代から綿々と続く歴史ある表示である。(笑)
 これは、「ログインプロンプト」と呼ばれる表示である。この表示が出ている間、Linuxは利用者がログインするのを待っている状態にある。

 ログインすることから、サーバの操作が開始されるのである。(←ここ重要)

 なお、職場や学校のサーバを利用できる人の場合、サーバ管理者から(ログイン)アカウントと、その(ログイン)パスワードが支給されるはずである。この二つの情報はとっても重要なので忘れないように。

 さて。ログインプロンプトが表示されている状態で、まずは(ログイン)アカウントを入力し、Enterキーを押す。
 続いて、「Password: 」という表示が出るので、(ログイン)パスワードを入力し、Enterキーを押す。なお、Windows文化になれた人の多くはここで戸惑うことになるかもしれない。というのも、パスワードを入力しても、画面には何も表示されないのである。Windows文化では、「●」とか「*」とかいう記号がキー入力に応じて表示されることがほとんどであるのに、Linuxのログインパスワードはそれすら表示されないのである。

 これはこれで正常なので、安心して(?)パスワードを正確に入力してもらいたい。

 で、アカウントとパスワードとの照合が正常に行われると、いよいよLinuxサーバにログインできるのである。ログインに成功すると、こんな感じになる。

20100106コンソールログインしたところ.jpg 職場や学校のLinuxサーバはもっと違う表示になっているかもしれない。ログイン時に何らかのメッセージ(注意事項とか連絡事項とかそういう情報等)が表示されることもあるかもしれないが、基本は全く一緒である。
 ログインすると、「Last login: …」という表示が出る。(初回は出ないこともある。出ることもある。)君が今使用したアカウントで、前回最後にログインした日時を表示しているのである。ハッキング防止…みたいな気分で表示される。まあ、学習過程においてはここを神経質になってチェックする必要性はほとんど無いと言っても差し支えないかもしれない。
 続く表示は「(コマンドライン)プロンプト」と呼ばれる表示である。この部分については、エントリーを改めてきちんと説明したい。今はその名前だけ覚えておいて欲しい。

 これで、Linuxサーバにログインし、様々な命令を下す準備が出来たことになる。





 が、しかし。こういう風にログインすることは極めて稀かもしれない。(笑)

 まず、サーバのコンソールを直接操作することからして稀なことという状況なのであったりする。ほとんどはリモートでログインし操作することが大半という時代なのである。というわけで、ごく一般的なリモートログインの風景を見てもらうことにしよう。

20100106kagami接続.jpg ここでは(個人的な好みの問題であるが)TeraTermを使用している。他のソフトが好きだという人、あるいは他のソフトを使わされている人は適宜読み替えてもらいたい。
 まずは、Linuxサーバに接続するところから。サーバ管理者から、サーバのIPアドレスまたはホスト名を教えてもらう必要がある。


20100106kagamiアカウント入力.jpg サーバに接続すると、「login: 」プロンプトの代わりにアカウントとパスワードを入力する画面になる。ここでのパスワード入力についてはWindows文化のままなので、「*」が表示される。


20100106kagamiログイン.jpg ログインに成功すると、プロンプトが表示される。


 これならば、Windows文化に慣れ親しんだ人も安心?

 では、ここで2つのコマンドを紹介することにする。まずは、サーバ管理者から通知されたパスワードを変更するコマンドである。

 passwdコマンド

 では、passwdコマンドを使ってみる。
 使い方は簡単。コマンドラインプロンプトが表示されている状態で、「passwd」と入力しEnterキーを押す。このコマンドを実行すると、3つのステップでパスワードが変更される。すなわち、

ステップ1 : 今使用しているパスワードを入力する
ステップ2 : 新しく使用したいパスワードを入力する
ステップ3 : 新しく使用したいパスワードをもう一度入力する

 新しいパスワードは2回入力することになる。ステップ2とステップ3とで入力したパスワードが完全に一致しなければパスワードは変更されないことに注意が必要。

 また、ステップ1~3のパスワードは、コンソールからのログインの際にパスワードを入力した時と同じく、キー入力をしても何も表示されないので驚かないこと。

 パスワードを変更した操作を見ると、こんな感じになっているだろう。
[piro791@kagami ~]$ passwd
Changing password for user piro791.
Changing password for piro791
(current) UNIX password:
New UNIX password:
Retype new UNIX password:
passwd: all authentication tokens updated successfully.
[piro791@kagami ~]$

 パスワードを入力した箇所には何もあとが残っていない。

 なお、サーバ管理者によっては次のような制限を設けている場合があるので、自分のパスワードを管理する際にはサーバ管理者からの指示に従って注意するように。

①サーバ管理者によっては、パスワードの有効期限を設けている場合がある。この場合、有効期限が切れそうになるとログインした際に警告メッセージが表示されるかもしれない。

②サーバ管理者によっては、パスワードには一定以上の複雑性を要求している場合があるかもしれない。たとえば、「パスワードは○文字以上の長さが必要」とか、「パスワードにはアルファベット・数字・記号を必ず混ぜること」とか、そんな具合に。要求される複雑性についてはサーバ管理者に問い合わせてもらいたい。

③サーバ管理者によっては、パスワードの変更履歴をチェックしている場合がある。怠け者の利用者になると、パスワードを定期的に変更するといっても、AパターンとBパターンのパスワードを交互に変更するだけの人もいるかもしれない。それを防止するために、過去○世代のパスワードは使用禁止みたいな制限をかけていることがある。

 なお、Linuxのパスワードに限った話ではないが、くれぐれも、パスワードを忘れたり、メモに残したり、付箋紙に書いてディスプレイの横に貼り付けたりしないように!
 次回ログインする際からは、今設定したパスワードを使用してサーバにログインすることになる。



 本エントリー最後に紹介するコマンドは、「logout」である。(笑)

 サーバ上での操作が終了した場合は、すみやかにサーバからしなければならない。  ログインしっぱなしにするばか者もよく見かけるが、それは許されないのである!!!  サーバからログアウトする際には、コマンドラインプロンプト上で、単に「logout」と入力してEnterキーを押す。それだけ。  リモートログインしている場合はターミナルソフトも終了することと思う。(しない場合もある。それは設定しだい)  最後にきちんとログアウトする癖をつけるように。
前の10件 | -

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。