1-2. ファイル操作 - cp, mv, rm, find, ln
所要時間: 25-50分(がっつりなら2セッション分) ゴール: ファイルを「コピー・移動・削除・検索」できる。シンボリックリンクが何か分かる コミット内容: 今日の操作履歴を
~/log/linux_day02.logに保存
大前提: ファイル操作は「GUIでもできる」のになぜコマンドでやるか
Finderでドラッグ&ドロップしてもコピー・移動できます。でも:
- 100個のファイルを「ファイル名末尾に
_oldを付ける」処理 → Finderだと地獄、コマンドだと1行 - 「3日以上前に更新されたログ」だけ消す → Finderだと不可能、コマンドだと1行
- サーバー上で操作 → そもそもFinderが無い
つまり、条件付き・大量処理・リモート の3つでコマンドが圧勝。これがバックエンドエンジニアがコマンドを離れない理由。
そして、これらの操作は 取り返しがつかない 場合がある(特に rm)。理屈を理解せず叩くと事故るので、各コマンドの「落とし穴」を意識しながら進める。
セッション①: cp / mv / rm(25-30分)
0. 録画スタート&作業ディレクトリ
mkdir -p ~/log ~/learn/linux/day02
cd ~/learn/linux/day02
script ~/log/linux_day02.log1. cp - コピー
# 単純なコピー
cp memo.txt memo_copy.txt
# 別のディレクトリへコピー
cp memo.txt ~/Documents/
# ディレクトリごとコピー(-r が必須)
cp -r project/ project_backup/
# 上書き前に確認する
cp -i memo.txt other.txt
# 属性も保持してコピー(更新日時、権限など)
cp -p memo.txt memo_preserved.txt
# 全部入り(再帰+属性保持+シンボリックリンクも保持)
cp -a src/ dst/
cp(copy)の本質ファイルを 2つに増やす コマンド。元のファイルは残る。シンプル。
ただしオプションがいくつかあって、これを使い分けないと地味に困る。
重要オプション
-r(recursive): ディレクトリをコピーする時に必須。-r無しでディレクトリをcpするとエラー(「ディレクトリは無視する」と言われる)-i(interactive): 上書きする前に「いいの?(y/n)」と聞いてくれる。本番では入れておきたい-p(preserve): 元ファイルの更新日時・権限・所有者をそのままコピー。デフォルトだと「コピー時刻 = 今」になってしまう-a(archive):-r+-p+ シンボリックリンク維持。バックアップ用途の鉄板
cpの実務ユースケース
- 設定ファイル編集前のバックアップ:
cp /etc/nginx/nginx.conf{,.bak}(ブレース展開でファイル名末尾に.bakを付ける)- テンプレートから新規作成:
cp template.html new_page.html編集する前にコピーで雛形化- ディレクトリ全体の複製:
cp -a project/ project_2026-05-14/(日付付きスナップショット)
cpの落とし穴
- デフォルトは上書き確認なし: 同名ファイルがあると問答無用で上書き。
-iを癖にすると安全-r忘れ: ディレクトリのコピーでエラー出たら、まず-rを疑う- 末尾スラッシュの罠:
cp -r src/ dst/とcp -r src dst/で挙動が違う場合がある(中身だけコピー vs ディレクトリごとコピー)。慣れるまでtree dst/で確認する癖を
2. mv - 移動・リネーム
# 移動
mv memo.txt ~/Documents/
# リネーム(実は移動と同じコマンド)
mv old_name.txt new_name.txt
# ディレクトリも -r 無しで移動できる(cp と違う!)
mv project/ ../backup/
# 複数ファイルを別ディレクトリへ
mv a.txt b.txt c.txt ~/archive/
mv(move)の本質と「リネーム」の謎Unix では 「移動」と「リネーム」は同じ操作。なぜなら、ファイル名はそのファイルの「アドレス」の一部だから。
mv a.txt b.txt= 「a.txt を b.txt という名前のアドレスに移動」=結果としてリネームmv a.txt /tmp/= 「a.txt を /tmp/ 配下のアドレスに移動」= 移動同じディレクトリ内で実行すればリネーム、別ディレクトリを指定すれば移動。コマンドは1つで両方できる。
Windowsで「Rename」と「Move」が別操作なのは思想の違い(Windowsは「ファイル名はメタデータ」、Unixは「ファイル名はパスの一部」)。
mvの実務ユースケース
- 間違って作ったファイル名を直す:
mv typo.txt correct.txt- ログローテーション:
mv app.log app.log.$(date +%Y%m%d)で日付付きログにする- ステージング → 本番:
mv staging/new_feature.html public/feature.html
mvの落とし穴
- 上書き確認なし:
mv a.txt b.txtで既存の b.txt があると 無言で上書き。-iで確認モードに- 空きディスク不足: 別ドライブへの
mvは内部的に「コピー+削除」になる。途中で容量切れすると半端な状態に- ワイルドカードの罠:
mv *.log /backup/で1個もマッチしないと、変なエラーが出るかコマンド自体が失敗する
3. rm - 削除
# 単純削除
rm tmp.txt
# 確認しながら削除
rm -i important.txt
# ディレクトリを削除(-r 必須)
rm -r old_project/
# 確認なしで強制削除(危険)
rm -f stubborn_file.txt
# ディレクトリ+強制(最も危険な組み合わせ)
rm -rf old_backup/
rm(remove)の本質ファイル/ディレクトリを 消す コマンド。シンプル。
ただし Unix のターミナルにゴミ箱は無い。
rmしたファイルは原則として復元できない。Finder の Cmd+Delete とは違う。
-r(recursive): ディレクトリ削除に必須-f(force): 「本当に消す?」の確認も、書き込み権限が無いファイルの警告もすべてスキップ-i(interactive): 1ファイルずつ確認
rmの実務ユースケース
- ビルド成果物のクリーンアップ:
rm -rf node_modules/ dist/- 古いログ削除: 後で
findと組み合わせて自動化- 不要なバックアップを整理:
rm -r project_backup_2024_*/
rm -rf /は伝説の事故コマンド「ルートディレクトリから全部削除」= OSを破壊する。Linuxではガード機能があるが、それでも事故例は多い。
特にスクリプト内で
rm -rf $PROJECT_DIR/buildのような書き方をしていて、変数$PROJECT_DIRが空文字だと:rm -rf /build # 実質ルート近くから消すという事故になる。スクリプト書く時は
set -uで未定義変数をエラーにするのが定石。対策
alias rm='rm -i'を.zshrcに書いておく(rmが常に確認モード)- 危険な操作の前に
pwdで現在地を確認lsで消す対象を先に見てからrmするtrashコマンド(brew install trash)でゴミ箱送りにする運用も検討
削除前の安全確認パターン
# 1. まず ls で何が消えるか目視 ls old_* # 2. find で対象を絞り込んで確認 find . -name "old_*" -type f # 3. 問題なければ削除 rm old_*「ls → 確認 → rm」を癖にする。
セッション②: find / ln(25-30分)
4. find - 検索の最強コマンド
# 名前で検索(カレントディレクトリ以下)
find . -name "*.md"
# 大文字小文字無視
find . -iname "readme*"
# ディレクトリだけ
find . -type d
# ファイルだけ
find . -type f
# サイズ条件(1MB以上)
find . -size +1M
# 更新日時(3日以内に更新)
find . -mtime -3
# 見つけたものを削除
find . -name "*.tmp" -delete
# 見つけたものに何か実行
find . -name "*.log" -exec ls -lh {} \;
findは「検索 + 一括処理」エンジン単なる検索コマンドではなく、条件にマッチしたファイル群に対して操作も実行できる 強力ツール。
基本構造:
find <検索場所> <検索条件> <アクション>
- 検索場所:
.(カレント)、/var/logのような絶対パスもOK- 検索条件:
-name,-type,-size,-mtimeなどを組み合わせる- アクション: 何も指定しないと「マッチしたパスを表示」。
-deleteで削除、-execで任意コマンド実行
findの主要オプション
オプション 意味 例 -nameファイル名(パターン可) -name "*.log"-iname大文字小文字無視の名前 -iname "readme*"-typeファイル種別 -type f(ファイル)/-type d(ディレクトリ)/-type l(リンク)-sizeサイズ -size +10M(10MB超)/-size -1k(1KB未満)-mtime更新日時 -mtime -7(7日以内)/-mtime +30(30日以上前)-empty空のファイル/ディレクトリ (単独で使う) -delete見つけたものを削除 (条件の後に付ける) -exec各ファイルに対してコマンド実行 -exec mv {} /tmp/ \;
findの実務ユースケース
- 巨大ファイル探し:
find / -size +1G 2>/dev/nullで1GB超のファイル一覧- 古いログの自動削除:
find /var/log -name "*.log" -mtime +30 -delete(30日以上前のログ削除、cronで定期実行)- 特定の設定ファイルを全部見る:
find /etc -name "*.conf" -type f- node_modules を一掃:
find . -name "node_modules" -type d -prune -exec rm -rf {} +(HDD圧迫の最大要因)
findの落とし穴
-nameはワイルドカードに引用符が必要:find . -name *.logだとシェルが*.logを先に展開してエラーになることがある。必ず"*.log"のようにクォート-deleteは問答無用: 確認なしで削除される。事前に-deleteを外して結果を目視確認 → OKなら-delete付けて実行、という2段階運用-execの\;を忘れがち: コマンドの終わりに\;が必要(エスケープしたセミコロン)。+で代用すると複数ファイルを一括処理できて速い- 検索が遅い: 巨大なディレクトリだと数十秒かかる。
locateコマンド(DBベース)の方が速い場合も
パイプとの組み合わせ(次の章への布石)
findの結果を|(パイプ)で別のコマンドに渡せる:# マッチした数を数える find . -name "*.md" | wc -l # 一覧をファイルに保存 find . -type f -mtime -1 > today_files.txt
|の仕組みは Day5: パイプとリダイレクト で詳しくやる。今は「コマンドAの結果をBに渡せる」とだけ覚えればOK
5. ln - リンクを作る
# シンボリックリンク(こっちが普段使うやつ)
ln -s ~/Documents/notes ~/notes
# ハードリンク
ln file.txt hardlink.txt
# 作ったリンクの確認
ls -l ~/notes
# lrwxr-xr-x 1 takato staff 20 May 14 16:00 /Users/takato/notes -> /Users/takato/Documents/notesリンクとは「ファイルへのショートカット」
1つのファイル/ディレクトリに別の名前/場所からアクセスできる仕組み。Macの「エイリアス」、Windowsの「ショートカット」と似ているが、Unix のリンクの方が機能的に統合されている。
2種類ある:
- シンボリックリンク(symlink, ソフトリンク): 「あっちのファイル見て」という案内板。リンク先のパスを保持
- ハードリンク: 同じファイルに別の名前を付ける(実体は1つ)
99%の場面でシンボリックリンク(
ln -s)を使う。ハードリンクは特殊用途。
シンボリックリンク(
ln -s)の本質ln -s 元のパス リンクの名前
元のパスへの案内板をリンクの名前として作る。ls -lで見ると左端がlで、-> 元のパスと表示される。挙動
- リンクを開く = 元ファイルにアクセス
- リンクを編集 = 元ファイルを編集
- リンクを削除(
rm symlink)= リンクだけ消える(元は残る)- 元を削除 = リンクは「壊れたリンク」になる(broken symlink)
シンボリックリンクの実務ユースケース
- dotfiles の管理:
~/.zshrcをgit cloneしたリポの設定ファイルへの symlink にして、設定をバージョン管理- 複数バージョンの切替:
/usr/local/bin/python -> python3.12(バージョン切替時にリンクだけ張り替える)- 巨大データの参照: 別ドライブにあるデータを
~/data/配下から symlink で参照- 本番デプロイ:
current/を新リリースの symlink にして、戻したくなったら symlink を旧バージョンに張り替えるだけ(Capistrano等が使う手法)
シンボリックリンクの落とし穴
- 相対パスと絶対パス:
ln -s ./file.txt linkのように相対パスで作ると、リンク自体を移動した時に壊れる。特に理由がなければ絶対パス推奨cp -Lでリンクを辿る: 普通のcpだとリンクのまま複製する。中身(実体)をコピーしたい場合はcp -L- リンク先が消えても警告ゼロ: 黙って broken に。
ls -lで-> /path/to/somethingが見えるが、その先が無い状態。readlinkで確認可能rmでリンク削除は安全:rm symlinkしてもリンク先の実体は残る。ただしrm -rf symlink_to_dir/のように末尾スラッシュ付きで実行すると、リンク先のディレクトリ中身まで消えるので注意
ハードリンクは「めったに使わない」
同じデータに複数の名前。ディスク容量は1つ分。
制約として:
- ディレクトリには張れない
- 別ファイルシステム(別ドライブ)には張れない
普段使う場面はほぼない。「シンボリックリンクとは違うもの」だと知っておくだけでOK。
6. 実践課題
# 1. 練習用フォルダを準備
mkdir -p ~/learn/linux/day02/practice/{src,backup,trash}
# 2. ダミーファイルを作成
cd ~/learn/linux/day02/practice
touch src/file_{01..05}.txt
echo "important data" > src/important.txt
echo "old log" > src/app_2024.log
# 3. find で .log ファイルを探す
find . -name "*.log"
# 4. .log ファイルを backup/ にコピー(バックアップ)
find . -name "*.log" -exec cp {} backup/ \;
# 5. 確認
ls backup/
# 6. src/ の中身を symlink で見える化
ln -s "$(pwd)/src" ~/learn/linux/day02/src_link
ls -l ~/learn/linux/day02/src_link
# 7. trash/ にいらないファイルを移して、まとめて削除
mv src/file_01.txt src/file_02.txt trash/
rm trash/*
ls trash/ # 空のはず締め: 振り返り(10分)
1. セッション録画を終了
exit2. 今日の発見
このノートに追記:
- 一番「これ便利」だったコマンド:
- find でこういう使い方ができそう、と思ったケース:
- ヒヤッとした操作(あれば):
- 明日やりたいこと:
3. デイリーノートにコピー
デイリー/2026-05-15.md のようにテンプレを複製して記録。
チェックリスト
-
cp -rでディレクトリをコピーできた -
mvでファイルをリネームできた -
rm -iで確認しながら削除した -
find . -name "*.md"で検索できた -
ln -sでシンボリックリンクを作ってls -lで確認した -
rm -rfの危険性を声に出して説明できる
詰まった時のチートシート
| やりたいこと | コマンド |
|---|---|
| ファイル複製 | cp <元> <先> |
| ディレクトリ複製 | cp -r <元> <先> |
| バックアップ作成 | cp file.txt{,.bak} |
| 名前変更 | mv <旧> <新> |
| 移動 | mv <元> <先ディレクトリ>/ |
| 削除(ファイル) | rm <ファイル> |
| 削除(ディレクトリ) | rm -r <ディレクトリ> |
| 安全な削除 | rm -i <パス> |
| 名前で検索 | find . -name "パターン" |
| 種類で絞る | find . -type f(ファイル)/ -type d(ディレクトリ) |
| 古いファイル探す | find . -mtime +30 |
| シンボリックリンク作成 | ln -s <元の絶対パス> <リンク名> |
| リンク先を確認 | readlink <リンク> |
「実務OK」基準
cp -r/mv/rm -rが無意識に出るrm -rfの前に必ず一呼吸置くfind . -name "..."でファイル探しができる- シンボリックリンクが何かを後輩に1分で説明できる
ここまで来たら、Day3 の パーミッション に進む準備が整っている。
次のレッスン
level1_03_permissions.md をまだ生成していなければ、Claude Code に頼んで作る:
バックエンドマスター/Linux/level1_03_permissions.md を、
level1_02_file_operations.md と同じフォーマットで作って。
内容は chmod / chown / ユーザー・グループ概念 / sudo / .ssh の権限など、
権限まわりを「これは何か」「いつ使うか」「落とし穴」付きで詳しく。