基本ファイル管理 - cp/mv/rm/touch とワイルドカード【LPIC-1 103.3】
この記事で達成できること
cp/mv/rmの主要オプション(-r-a-i-p-u-f)を使い分けられるtouchで空ファイルを作成し、タイムスタンプを更新できるmkdir -p/rmdirでディレクトリを安全に作成・削除できる- ワイルドカード(
*?[ ][!...])とブレース展開({ })を正しく書ける - グロブを展開するのはコマンドではなくシェルだと説明できる
LPIC-1 主題 103.3「基本的なファイル管理を行う」の中核。日常作業の 8 割を占めるファイル操作を、事故なく確実に行う型を押さえる。
どのコマンド・オプションを選ぶか
ファイル操作は「何をしたいか」と「事故をどう防ぐか」で選ぶ。下表が判断の起点になる。
| やりたいこと | コマンド | 事故防止の定番 |
|---|---|---|
| コピー | cp |
-i(上書き確認) |
| バックアップ(属性保持) | cp -a |
-a = 再帰+属性保持 |
| 移動・リネーム | mv |
-i(上書き確認) |
| 削除 | rm |
-i(1件ずつ確認) |
| 空ファイル作成・更新 | touch |
既存は中身を壊さない |
| ディレクトリ作成 | mkdir -p |
親ごと一括作成 |
| 空ディレクトリ削除 | rmdir |
空でなければ失敗で安全 |
迷ったら「破壊系(rm / mv の上書き)には -i を付ける」を基本姿勢にする。rmdir が空でないと失敗するのは欠点ではなく、誤削除を防ぐ安全弁だと理解しておく。
cp / mv / rm の使い方
cp - コピーとオプションの違い
cp はファイル・ディレクトリを複製する。ディレクトリには -r(再帰)が必須。バックアップ用途では属性まで保持する -a を使う。
cp file1.txt file2.txt cp -r src/ backup/ cp -a src/ archive/
$ ls -l file2.txt -rw-r--r-- 1 user user 0 May 30 10:00 file2.txt
主要オプションの意味は次のとおり。GNU coreutils の cp を前提とする。
| オプション | 意味 |
|---|---|
-r, -R |
ディレクトリを再帰的にコピー |
-a |
アーカイブモード。-dR --preserve=all と同等(属性保持) |
-i |
上書き前に確認を求める |
-p |
更新時刻・所有者・パーミッションなどの属性を保持 |
-u |
コピー先が古い、または存在しない場合のみコピー(更新) |
-r は「中身ごとコピー」、-a は「中身ごと+属性・シンボリックリンク・タイムスタンプも丸ごと保持」。単純な複製は -r、バックアップは -a と覚える。
-u(update)は差分同期に便利。cp -au src/ dst/ で「新しいものだけを属性保持でコピー」になり、簡易バックアップに使える。
mv - 移動とリネーム
mv は移動とリネームを兼ねる。同じディレクトリ内での mv old new がリネーム、別ディレクトリへの mv file dir/ が移動。上書きが怖い場面では -i を付ける。
mv draft.txt report.txt mv report.txt /home/user/docs/ mv -i report.txt /home/user/docs/
$ mv -i report.txt /home/user/docs/ mv: overwrite '/home/user/docs/report.txt'? n
| オプション | 意味 |
|---|---|
-i |
上書き前に確認を求める |
-f |
確認せず強制的に上書き(-i を打ち消す) |
mv は cp と違い、ディレクトリ移動に -r は不要。同一ファイルシステム内ならデータの実体は動かさずパス情報だけ書き換えるため高速。
rm - 削除と -rf の危険性
rm はファイルを削除する。ディレクトリ削除には -r、確認なしの強制削除には -f を使う。rm に「ゴミ箱」はなく、削除即消滅と考える。
rm unwanted.txt rm -i unwanted.txt rm -r olddir/
$ rm -i unwanted.txt rm: remove regular file 'unwanted.txt'? y
| オプション | 意味 |
|---|---|
-r, -R |
ディレクトリを再帰的に削除 |
-f |
存在確認・確認プロンプトを抑止し強制削除 |
-i |
削除前に1件ずつ確認を求める |
rm -rf は確認なしでディレクトリツリーを一括削除する。引数の打ち間違い(例: rm -rf / tmp/foo のように / の後ろにスペースが入る)でシステム全体を破壊しうる。実行前に必ず対象パスを目視確認し、不安なら -i を併用する。
touch / mkdir / rmdir / file
touch - 空ファイル作成とタイムスタンプ更新
touch は存在しないファイルを空で作成し、既存ファイルにはアクセス時刻・更新時刻を現在時刻に更新する(中身は変えない)。
touch newfile.txt touch existing.txt touch -c missing.txt
$ ls -l --time-style=+%H:%M newfile.txt -rw-r--r-- 1 user user 0 10:05 newfile.txt
| オプション | 意味 |
|---|---|
-a |
アクセス時刻のみ更新 |
-m |
更新時刻(modification time)のみ更新 |
-c |
ファイルが存在しなければ作成しない |
-t |
指定した日時([[CC]YY]MMDDhhmm[.ss])に設定 |
既存ファイルに touch してもデータは消えない。ビルドの再実行を促す(make のタイムスタンプ判定)など、更新時刻の操作目的でも使う。
mkdir / rmdir - ディレクトリの作成と削除
mkdir はディレクトリを作る。途中の親ディレクトリがない深い階層は -p で一括作成する。rmdir は空のディレクトリだけを削除する。
mkdir project mkdir -p project/src/lib rmdir project/src/lib
$ rmdir project rmdir: failed to remove 'project': Directory not empty
-p がないと、存在しない親の下にはディレクトリを作れずエラーになる。rmdir が「空でないと失敗」するのは安全機構で、中身ごと消したいなら rm -r を使う(その分だけ危険も増す)。
file - 中身からファイル種別を判定する
file は拡張子ではなく中身を調べてファイルの種別を判定する。拡張子が偽っていても実体を見抜ける。
file report.pdf script.sh archive.gz photo
report.pdf: PDF document, version 1.7 script.sh: Bourne-Again shell script, ASCII text executable archive.gz: gzip compressed data photo: JPEG image data, JFIF standard 1.01
拡張子のない photo でも JPEG と判定できる。cat で開いて文字化けする前に file で種別を確認するのが安全な習慣。
ワイルドカードとシェル展開
ワイルドカード(グロブ)はファイル名のパターンを一括指定する仕組み。重要なのは、展開するのは cp や rm ではなくシェルだという点。シェルがパターンを実ファイル名に置き換えてからコマンドに渡す。
| パターン | マッチ対象 | 例 |
|---|---|---|
* |
任意の0文字以上の文字列 | *.txt → すべての .txt |
? |
任意の1文字 | file?.txt → file1.txt, fileA.txt |
[abc] |
角括弧内のいずれか1文字 | file[12].txt → file1.txt, file2.txt |
[a-z] |
範囲内のいずれか1文字 | [a-c]* → a/b/c で始まる名前 |
[!abc] |
角括弧内以外の1文字 | file[!0].txt → file0.txt 以外 |
ブレース展開 { } はグロブと別物で、既存ファイルの有無に関係なく文字列を機械的に生成する。
echo file{A,B,C}.txt
echo {1..3}.log
mkdir -p project/{src,test,docs}fileA.txt fileB.txt fileC.txt 1.log 2.log 3.log
{A,B,C} はカンマ区切りの列挙、{1..3} は連番。mkdir -p project/{src,test,docs} で 3 ディレクトリを一発生成できる。
ブレース展開はファイルが存在しなくても文字列を作る(生成系)。一方グロブ * ? [ ] は既存ファイル名へのマッチ(検索系)。*.txt は .txt が1つもなければマッチせず、デフォルトの bash ではパターン文字列がそのままコマンドに渡る点に注意。
ls *.nonexistent echo *.nonexistent
ls: cannot access '*.nonexistent': No such file or directory *.nonexistent
グロブが0件のとき、bash はデフォルトでパターンをそのまま渡す(echo はその文字列を表示し、ls は「そんなファイルはない」と言う)。これは shopt -s nullglob を設定すると「0件なら空に展開」へ変えられる。
よくあるミスと対処
実務・試験の両方でつまずきやすい点を整理する。
cpでディレクトリに-rを付け忘れる:cp dir/ dst/はomitting directoryエラー。ディレクトリコピーは常に-rか-a。-rと-aを混同する: 単純複製は-r、所有者・パーミッション・リンク・時刻まで保持するバックアップは-a。-rだけだと属性が変わる。mvで無確認に上書きする: デフォルトのmvは既存ファイルを黙って上書きする。重要ファイルには-iを習慣化する。rm *をルートや重要ディレクトリで実行: グロブを展開するのはシェル。実行前にecho rm *のようにechoを前置して、何に展開されるか確認すると安全。rmdirで「空でない」エラーに戸惑う: 仕様どおりの安全動作。中身ごと消すならrm -r、ただし対象を必ず確認。
トラブルシューティング
症状: cp で「omitting directory」と出てコピーされない
原因: ディレクトリを -r(または -a)なしでコピーしようとしている
確認:
file src
対処: ディレクトリなら cp -r src/ dst/、属性も保つなら cp -a src/ dst/ を使う。
症状: rm -rf を実行したらファイルが消えてしまった
原因: rm -rf は確認なしで再帰削除する。rm に削除取り消しはない
確認:
echo rm -rf target/
対処: 実行前に echo を前置して展開結果を目視する。不安なら -i を併用(rm -ri)。消えたファイルはバックアップからのみ復旧可能。
症状: ワイルドカードを書いたのにマッチしない/パターンがそのまま表示される
原因: 一致するファイルが0件。bash はデフォルトでパターン文字列をそのまま渡す
確認:
shopt nullglob ls -d *.txt
対処: 対象ディレクトリと拡張子を見直す。0件時に空展開させたい場合は shopt -s nullglob を設定する。
作業完了チェックリスト
- [ ]
cp -r/cp -aの違いを説明して使い分けた - [ ]
mv -i/rm -iで上書き・削除前の確認を有効にした - [ ]
touchで空ファイル作成とタイムスタンプ更新を確認した - [ ]
mkdir -pとrmdirの挙動の違いを確認した - [ ]
*?[ ]とブレース展開{ }を書き分けた - [ ] グロブを展開するのがシェルだと理解した
まとめ
| 場面 | コマンド | ポイント |
|---|---|---|
| コピー | cp -r / cp -a |
-a は属性まで保持 |
| 移動・リネーム | mv -i |
デフォルトは黙って上書き |
| 削除 | rm -ri |
取り消し不可、-rf は最大注意 |
| 作成・更新 | touch / mkdir -p |
既存の中身は壊さない |
| 空ディレクトリ削除 | rmdir |
空でなければ失敗(安全) |
| 種別判定 | file |
拡張子でなく中身で判定 |
| 一括指定 | * ? [ ] { } |
展開するのはシェル |
基本ファイル管理は LPIC-1 で最も使用頻度が高い領域。ここを固めたら、ファイルの実体を指すリンク機構や、FHS とファイル検索へ進むと体系が完成する。