(教材)02【ディレクトリ操作の補足】
以下の説明ではカレントディレクトリ (現在のディレクトリ) の場所を指定していない. ホームディレクトリ (ログインした直後のディレクトリ) で操作することは可能だが,ここではホームディレクトリの直下に Temp という名前のディレクトリを作成し,そこをカレントディレクトリにしよう.そうすれば,他のファイルやディレクトリが存在しないので,操作の結果を確認しやすい.
具体的な方法は以下のとおりである.
code:▼はEnter
$ cd▼ (ホームディレクトリに戻る)
$ mkdir Temp▼ (Temp ディレクトリを作成)
$ cd Temp▼ (Temp ディレクトリに移動)
◆コピーおよび移動の際のファイル名の指定
<準備と確認>
カレントディレクトリに d1, d2, d3,d4 というディレクトリが存在し, d1 には aaa というファイルが存在するという状態にする. もしこれらのファイルやディレクトリがないなら,自分で作成する.
(他のファイルやディレクトリが存在しても構わないが,結果の確認の際には注意が必要である.)
<ファイル名を省略してのコピー>
ファイル名を変更しないならば,コピー先にファイル名は指定(記述)しなくてもよく,ディレクトリ名でだけでよい,次のようにしてみよう.
code:▼はEnter
$ cp d1/aaa d2▼
これにより d1 にある aaa が d2 にコピーされる. ls -l で確認してみよう.※"-l"は,数字の1ではなくアルファベットの"l(エル)"
code:▼はEnter
$ ls -l d2▼
<ファイル名を変更してのコピー>
コピーの際にはファイル名を変更することができる.たとえば, d1 の aaa を d2 へ bbb という名前でコピーすることができる.次のようにしてみよう.
code:▼はEnter
$ cp d1/aaa d2/bbb▼
d2 に bbb があることを確認してみよう.
code:▼はEnter
$ ls -l d2▼
d1 の aaa と d2 の bbb は,ファイル名は異なるが両者は同じものである(cat で同じかどうか確認してみよう).
<カレントディレクトリへのコピー>
カレントディレクトリは「.」 (半角のピリオド1つ) で表される. コピー先がカレントディレクトリの場合は,たとえば,以下のようにすればよい.次のようにしてみよう.
code:▼はEnter
$ cp d1/aaa .▼
カレントディレクトリに aaaがあることを確認してみよう.
code:▼はEnter
$ ls -l▼
<親ディレクトリへのコピー>
同様に,コピー先が親ディレクトリ (1つ上のディレクトリ) の場合は,親ディレクトリを示す「..」 (半角のピリオド2つ) を用いればよい.このことを試すために,まず, d2 ディレクトリに移動させよう.
code:▼はEnter
$ cd d2▼
そして,以下のようにすれば,d2にある bbb が d2 の親ディレクトリにコピーされる.次のようにしてみよう.
code:▼はEnter
$ cp bbb ..▼
d2 の親ディレクトリに移動して bbb があることを確認しよう.
code:▼はEnter
$ cd ..▼
$ ls -l▼
なお,この場合,親ディレクトリに移動せずに ls -l ..▼ としても同じことが確認できる(その方が手数は少ない) が,ここでは親ディレクトリに移動した方が分かりやすいので移動させている.
<同じレベルの他のディレクトリへのコピー>
d1と d2 は同じ親ディレクトリの下にあり,このようなディレクトリは同じレベル(階層)にあるというもし今 d2 ディレクトリにいる状態で, d2 の bbbをd1にコピーするにはどうしたらいいだろうか.
まず,d2に移動してみよう.
code:▼はEnter
$cd d2▼
ここで, d1 は親ディレクトリの直下にあることから, 「../d1」と現すことができる.この表現を使えば, d2 の bbb を d1 にコピーできる.次のようにして d1 に bbb があることを確認してみよう.
code:▼はEnter
$ cp bbb ../d1▼
$ cd ..▼
$ ls -l d1▼
<ファイル名を省略してのファイルの移動>
移動に関してもまったく同様である. 以下の例のとおりにして, d1 の aaa を d3 に移動させ, aaa が移動したことを確認しよう (d1 にはないことも確認する).
code:▼はEnter
$ mv d1/aaa d3▼
$ ls -l d3▼
$ ls -l d1▼
<ファイル名を変更しての移動>
以下の例のとおりにして, d2 の aaa を ccc という名前にして d3 に移動させ,そのことを確認してみよう (d2にはないことも確認する).
code:▼はEnter
$ mv d2/aaa d3/ccc▼
$ ls -l d3▼
$ ls -l d2▼
<カレントディレクトリへのファイルの移動>
以下の例のとおりにして, d3 の ccc をカレントディレクトリに移動させ, ccc があることを確認しよう.
code:▼はEnter
$ mv d3/ccc▼
$ ls -l▼
<親ディレクトリへのファイルの移動>
以下の例のとおりにして, d4 の ddd を d4 の親ディレクトリに移動させ, ddd があることを確認しよう.
code:▼はEnter
$ cp d3/aaa d4/ddd▼ (ファイルの準備)
$ cd d4▼
$ mv ddd ..▼
$ cd▼
$ ls -l▼
<同じレベルの他のディレクトリへの移動>
以下の例で,d3にある aaaを同じ階層にある d4 に移動させ, aaaがあることを確かめてみよう.
code:▼はEnter
$ cd d3▼
$ mv aaa ../d4▼
$ cd ..▼
$ ls -l d4▼
★解説:mv でファイル名を変更できる理由★
mv は move という語の省略形であることからも分かるように,本来は「移動」のためのコマンドである.しかし, mv はファイル名を変更する際にも用いる.このことはファイル名を変更しての移動の特別な場合と考えることができる.
まず,ファイル名を変更しての移動の通常の場合は
code:▼はEnter
mv d1/aaa d2/bbb▼
というようになるが,ここで移動先が同じディレクトリならば,
code:▼はEnter
mv d1/aaa d1/bbb▼
となり, d1 の aaaが消えて d1 に同じ内容の bbb が現れる.結果的に aaa という名前が bbb に変更されたことになる.
一方,コピー先が同じディレクトリの場合は,
code:▼はEnter
cp d1/aaa d1/bbb▼
となり, d1 には aaa が残ったまま d1 に同じ内容の bbb が現れる.これは単なるコピーである.
このような cp と mv の役割の違いをしっかりと理解しておこう.
<コピーや移動などで複数のファイルを指定する方法>
先に存在しているディレクトリ d1 に対して,コピーしようとするファイルが複数ある場合には,それらをスペースで区切って一度に指定することが可能である.たとえば, cp aaa bbb ccc d1というようにすれば,複数のファイルが同時にコピーされる.
このことは,ファイルの移動 mv でも同様である.また,複数のファイルやディレクトリの指定はファイルの削除 rm においても,ディレクトリの作成 mkdir においても可能である.簡単なサンプルを用意して各自確認しておくとよいだろう.
ちなみに,ワイルドカードを使用するということは,実は複数のファイルの指定を行っているということにもなる.逆にいえば,複数のファイルの指定が可能な場合には,ワイルドカードを使うことができるということでもある.
◆コピー先や移動先に指定したディレクトリがない場合
<準備と確認>
カレントディレクトリに aaa, bbb, ccc, ddd というファイルが存在する状態にする.また, d5,d6 というディレクトリが存在しないことを確認する.
(他のファイルやディレクトリが存在しても構わないが,結果の確認の際には注意が必要である.)
<指定したディレクトリがない場合のコピー>
ファイル名を変更しないならば,コピー先のディレクトリ名だけを記述すればよいが,もしその名前のディレクトリが存在しなかったらどうなるだろうか.次のようにしてみよう.
code:▼はEnter
$ cp aaa d5▼
こうやってもエラーメッセージは出ない.何が起きたのだろうか. ls -l で確認してみると, d5 というファイル(ディレクトリではなく)が作られていることが分かる.つまり, aaa が d5 という名前のファイルにコピーされたのである.つまり,コンピュータ(シェル)は,d5 というのはファイル名だと解釈してコピーしたのである.
また,もしd5 という名前のファイルが先に存在していたとしても, シェルのやることは同じである.たとえば, cp bbb d5 とすれば, bbb というファイルが d5 に上書きされるだけである.実際に確認してみよう.上書きの際に確認のメッセージが出た場合,「y」を入力する.
ここで,d5 は後の操作にじゃまなので,削除しておこう.
code:▼はEnter
$ rm d5▼
rm: remove regular file d5? y▼ ← これがでたら"y"と入力
では,d5 がディレクトリであることを知らせるならば,どうなるだろうか.
ディレクトリ名の後ろに「/」を付けることで,それがディレクトリであることを示すことできる.次のようにしてみよう.
code:▼はEnter
$ cp aaa d5/▼
こうすると, d5 というディレクトリはないため,エラーメッセージが出て, ファイルのコピーは行われない.
では,ちゃんとコピーされるように,以下のようにして, ファイルがコピーされることを確認しよう.
code:▼はEnter
$ mkdir d5▼
$ cp aaa d5/▼
$ ls -l d5▼
以上のことから分かるように,ディレクトリにコピーする場合は,ディレクトリ名をよく確認することが必要である.しかし,勘違いやタイプミスの可能性はあるので,ディレクトリ名の後ろに「/」に付けておけば,間違ったコピーがされてしまうことは防げる.
<指定したディレクトリがない場合の移動>
移動に関してもまったく同様である. 以下の例のとおりにして, ccc が d6 というファイル名に変更されることを確認しよう.
code:▼はEnter
$ mv ccc d6▼
$ ls -l▼
ここで, d6 は後の操作にじゃまなので,削除しておこう(確認のメッセージには「y」を入力する).
code:▼はEnter
$ rm d6▼
次に,以下の例のとおりにして,エラーメッセージが出ることを確認しよう.
code:▼はEnter
$ mv ddd d6/▼
そして,以下の例のとおりにして, ddd がディレクトリ d6に正しく移動することを確認しよう.
code:▼はEnter
$ mkdir d6▼
$ mv ddd d6/▼
$ ls -l d6▼
◆コピー先や移動先に指定したディレクトリが既にある場合
<ディレクトリごとのコピーや移動>
一方,ディレクトリごとコピーしたり移動させたりする場合は,コピー先や移動先にはディレクトリが存在している必要はない.教科書の例においても存在しないことを前提に記されている.
しかし,先にディレクトリが存在していない場合と存在している場合とでは,操作結果が異なるので注意が必要である.
まず,先にディレクトリが存在していない場合について確認してみよう.ディレクトリごとコピーするためには, cp には -r というオプションが必要である.以下の例のとおりにすれば,新たに d7 というディレクトリが作成され,それは d6 がディレクトリごとコピーされたものであることが分かるはずである.
code:▼はEnter
$ cp -r d6 d7▼
$ ls -l d7▼
移動の場合も同様である.ただし, mv にはオプションは不要なので注意が必要である.以下の例のとおりにすれば,新たに d8 というディレクトリが作成され,それは d6 がディレクトリごと移動したものであることが分かるはずである.この場合,同じディレクトリのもとで移動したため,実質的にはディレクトリの名前が d6 から d8に変更されことになる.
code:▼はEnter
$ mv d6 d8▼
$ ls -l d8▼
次に,先にディレクトリが存在している場合について確認してみよう. コピー先として指定されたディレクトリが存在している場合には,そのディレクトリの下にコピー元のディレクトリがディレクトリごとコピーされる. 以下の例のとおりにして, d8 の下に d5 というディレクトリがあることを確認しよう.
code:▼はEnter
$ cp -r d5 d8▼
$ ls -l d8▼
移動の場合も同様である.移動先として指定されたディレクトリが存在している場合には,そのディレクトリの下に移動元のディレクトリがディレクトリごと移動する. 以下の例のとおりにして, d8 の下に d7 というディレクトリがあることを確認しよう.
code:▼はEnter
$ mv d7 d8▼
$ ls -l d8▼
ここで, d8 は後の操作にじゃまなので,削除しておこう(確認のメッセージには「y」を入力する).
code:▼はEnter
$ rm -r d8▼
◆コピーや移動の際のファイルの上書き
<準備と確認>
カレントディレクトリに aaa というファイル, d7 と d8 というディレクトリが存在し, d7 と d8 にはどちらにも aaa というファイルが存在するという状態にする. もしこれらのファイルやディレクトリがないなら,自分で作成する.
(他のファイルやディレクトリが存在しても構わないが,結果の確認の際には注意が必要である.)
<コピー先にコピー元のファイルと同じ名前のファイルがある場合>
カレントディレクトリとディレクトリ d7 にはどちらも同じ名前の aaa というファイルがある. カレントディレクトリの aaa をd7 にコピーしたらどうなるか,確認してみよう.
$ cp aaa d7/aaa▼
「上書きしてよいか」のメッセージのメッセージが出てくるので,「y」を入力する.
同じファイル名なので分かりにくいが上書きされている (catで内容を確認してみよう)つまり,コピー先に元々あった aaaは消えてしまったことになる.
このことは cp aaa d7 のように,コピー先のファイル名を省略した場合でも同じで,d7 に aaa というファイルがもしあれば上書きされてしまう.一般的には cp コマンドでコピーする際には上書きは警告されないので注意が必要である.
(確認のメッセージが出るように設定されているシステムもある)
<移動先に移動元のファイルと同じ名前のファイルがある場合>
移動に関してもまったく同様である. カレントディレクトリとディレクトリ d8 にはどちらも同じ名前の aaa というファイルがある. カレントディレクトリの aaa を d8 に移動したらどうなるか,確認してみよう.
$ mv aaa d8/aaa▼
コピーの場合と同様,「上書きしてよいか」のメッセージのメッセージが出てくるので,「y」を入力する. 本当に移動したかどうか確認してみよう.
$ ls -l aaa▼
そのようなファイルはないというメッセージが出る. では, d8 の aaa を確認してみよう.
$ ls -l d8/aaa▼
aaa は移動したことが分かる.つまり,移動先に元々あった aaa は消えてしまったことになる.このことは mv aaa d8 のように,移動先のファイル名を省略した場合でも同じで, d8 に aaa というファイルがもしあれば上書きされてしまう.通常 mv コマンドで移動する際には上書きは警告されないので注意が必要である.
※cp 同様,システムのデフォルト設定によって異なる.たとえば本学の実習用PCにインストールされたUbuntuでは確認のメッセージが出る
以上.
2023/6/22