1-2. ファイル操作 - cp, mv, rm, find, ln

所要時間: 25-50分(がっつりなら2セッション分) ゴール: ファイルを「コピー・移動・削除・検索」できる。シンボリックリンクが何か分かる コミット内容: 今日の操作履歴を ~/log/linux_day02.log に保存

この章が終わるとできること

  • cp -r でディレクトリ丸ごとコピー、-a で属性も保持できる
  • mv で「移動」と「リネーム」が同じコマンドということを理解している
  • rm -rf の危険性を後輩に1分で説明できる
  • find . -name '*.log' -mtime +30 のような条件付き検索が書ける
  • シンボリックリンクが何かを答えられ、ln -s で作れる

Day 1 とのつながり

  • 昨日学んだ pwd / ls / cd「現在地を意識する」 ためのコマンドだった
  • 今日の rmその意識が無いと事故る コマンド。Day 1 の習慣がそのまま安全装置になる
  • 昨日の ls -l で読めた「権限・所有者」は、今日の cp -p(属性保持)で再登場する

これができると何が嬉しいか

  • 「100個のログを30日以前で削除」みたいな定型処理が1行で済む
  • 本番でうっかり rm する前に「あ、危ない」と気づける感覚が身につく
  • リンクが分かると /etc/alternatives/node_modules/.bin/ の謎が解ける

大前提: ファイル操作は「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.log

1. cp - コピー

cp (copy) は ファイルまたはディレクトリを複製するコマンド。元のファイルは残り、新しいファイルが増える。ディレクトリをコピーするには -r(再帰)が必須。

# 単純なコピー
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 の -r -p -a どう違う?

ざっくり言うと

cp だけだと 「単純コピー」しかできない。ディレクトリも丸ごと欲しい、更新日時も保ちたい、リンクもそのままにしたい――要求が増えるたびにオプションが必要になる。

まず普通のパターン

cp memo.txt memo_copy.txt

ファイル1個 → 単なる複製。これは何の問題もない。

困るのはディレクトリをコピーした瞬間

cp project/ backup/

→ エラー: cp: project is a directory (not copied).

「ディレクトリは中に何個もファイルあるけど、それ全部やるの?」とコマンドが確認してくる感覚。-r で「全部やって」と明示しないと進まない。

解決策① -r(recursive)

cp -r project/ backup/

イメージ: -r = ディレクトリの中身も再帰的に複製してね

これだけで「ディレクトリ丸ごとコピー」は片付く。ただし、コピー後のファイルは:

  • 更新日時 = (コピー時刻)
  • 権限 = umask で決まるデフォルト
  • シンボリックリンク = 実体に置き換わる場合あり

ここから「もうちょっと元のまま欲しい」が始まる。

解決策② -p(preserve)

cp -p memo.txt memo_copy.txt

イメージ: -p = 元の更新日時・権限・所有者を「保存」してコピー

「コピー時刻が今になっちゃう」を防ぐ。バックアップ用途では必須。

解決策③ -a(archive)

cp -a src/ dst/

イメージ: -a = -r + -p + リンクもそのまま、の全部入りバックアップ用

これ1つで「ディレクトリ丸ごと、属性も維持、リンクも維持」が叶う。バックアップなら cp -a 一択

対比表

オプション何をしてくれるいつ使う
cpファイル1個を複製普通の複製
cp -rディレクトリも複製フォルダごとコピーしたい
cp -p属性も保持元ファイルの履歴を残したい
cp -a全部入り(-r + -p + リンク維持)バックアップ
cp -i上書き前に確認本番で事故防止

一番覚えやすい説明

  • -r は「中身も全部」(フォルダコピーの必須札)
  • -p は「履歴も保つ」(時刻・権限保持)
  • -a は「全部おまかせバックアップ」(迷ったらこれ)

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 (move) は ファイル・ディレクトリを別の場所に移すコマンド。同じディレクトリ内で実行すると「リネーム」として機能する(Unix では移動とリネームが同じ操作)。

# 移動
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 だけで「移動」も「リネーム」もできるのか?

ざっくり言うと

Unix では ファイル名 = アドレスの一部。だから「名前を変える = アドレスを書き換える = 別の場所に動かす」が、内部的にはぜんぶ同じ操作になる。

まず普通のパターン

mv a.txt b.txt        # ← これは「リネーム」と感じる
mv a.txt /tmp/        # ← これは「移動」と感じる

人間にとっては別の操作。でも mv はどちらも同じコマンド1つで処理する。なぜ?

Unix のファイルの住所

Unix では、ファイルの正体は「パス全体」。

/Users/takato/a.txt
└─────┬─────────┘
  これがファイルの住所

つまり:

  • a.txtb.txt に変える = 住所が /Users/takato/a.txt/Users/takato/b.txt に変わる
  • a.txt/tmp/ に動かす = 住所が /Users/takato/a.txt/tmp/a.txt に変わる

どっちも「住所を書き換える」操作。だから1コマンドで両方できる。

図で見る

リネーム:
/Users/takato/a.txt ──→ /Users/takato/b.txt
              ↑                    ↑
         パスの最後だけ変わる

移動:
/Users/takato/a.txt ──→ /tmp/a.txt
              ↑                ↑
            パスの途中が変わる

Unix から見ると、どちらも「パスの一部を書き換えただけ」。

イメージ

mv = ファイルの住所を書き換えるコマンド (その結果として、人間は「リネームした」「移動した」と感じる)

Windows との違い

Windows では「Rename」と「Move」は別操作。これは設計思想の違い:

UnixWindows
ファイル名の位置づけパスの一部メタデータ(属性の1つ)
移動とリネーム同じ操作別操作
コマンドmv ひとつrenmove

一番覚えやすい説明

mv は「ファイルの住所を変えるコマンド」。

  • 住所の最後だけ変える = リネーム
  • 住所の途中を変える = 移動
  • 中身は何もいじってない

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 (remove) は ファイル・ディレクトリを削除するコマンド。Unix にはゴミ箱の概念がないため、削除すると復元はほぼ不可能。特に -rf の組み合わせは強力すぎるので慎重に。

# 単純削除
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 のような変数の書き方は Linux 2-2 で詳しくやる。今は「中身に文字列が入る入れ物」くらいのイメージでOK)、変数 $PROJECT_DIR が空文字だと:

rm -rf /build  # 実質ルート近くから消す

という事故になる。スクリプト書く時は set -u(未定義変数を使ったらエラーで止める bash の安全装置。Linux 2-2 で扱う)で予防するのが定石。

対策

  • 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「指定した場所から再帰的にファイル/ディレクトリを探し、見つけたものに任意の操作を実行する」コマンド。単なる「検索ツール」ではなく、「条件マッチ + アクション」を1コマンドで完結できる小さな処理エンジンに近い。

「名前で探す」「サイズで絞る」「更新日時で絞る」「種類で絞る」と条件を組み合わせ、-delete-exec で「見つけたものを一括処理」までできるので、バッチ処理・クリーンアップ・調査の主力になる。

実務で頻出するシーン:

  • 古いログ・一時ファイルの一括削除: find /var/log -name "*.log" -mtime +30 -delete
  • 巨大ファイル探し: find / -size +1G 2>/dev/null でディスク食ってる犯人を特定
  • 特定の設定ファイルだけ集めて確認: find /etc -name "*.conf"
  • node_modules の根絶: HDD 圧迫の最大要因をまとめて消す

Spotlight や Finder の検索と違って 「条件付き + 一括処理」が無理なくでき、サーバー上でも動く のが強み。

# 名前で検索(カレントディレクトリ以下)
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 は「3部構成」のコマンド

ざっくり言うと

find「どこで」「何を」「どうする」 の3部構成。この3つを順番に並べるだけ。一見複雑だが、構造を覚えれば全パターンが同じ型で書ける。

まず普通のパターン

find . -name "*.log"

これだけ見ると複雑に見える。でも分解するとシンプル:

find    .     -name "*.log"   (アクション省略)
└┬─┘   └┬┘   └─────┬─────┘
コマンド どこ  何を(条件)

3部構成を図で見る

find <検索場所> <検索条件>      <アクション>
     ─────────  ────────────   ────────────
        ↑           ↑              ↑
     ここから    こういうやつを    こうする
     探して      
部分役割
検索場所. /var/log ~/Documents「どこから探すか」
検索条件-name "*.log" -type f -mtime +30「何を探すか」
アクション(省略)-delete -exec ... \;「見つけたらどうするか」

段階的に組み立てる

ステップ1: 場所だけ指定

find .

→ カレント以下、全部のファイル/ディレクトリを表示。これだけだとほぼゴミ。

ステップ2: 条件を足す

find . -name "*.log"

→ 「.log で終わるファイルだけ」に絞り込み。検索らしくなる。

ステップ3: 複数条件を組み合わせる

find . -name "*.log" -type f -mtime +30

→ 「.log で終わる、ファイル種別、30日以上前のもの」と AND 条件で絞る。

ステップ4: アクションを足す

find . -name "*.log" -type f -mtime +30 -delete

→ 条件にマッチしたものを 削除まで一発

イメージ

find = 漁網のようなコマンド

  • どこで網を投げるか
  • 目の細かさ(条件)
  • 獲った魚をどうするか

主要な「条件」と「アクション」の早見表

検索条件:

書き方意味
-name "*.log"名前パターン(クォート必須)
-iname "readme*"大文字小文字無視
-type fファイルだけ
-type dディレクトリだけ
-size +10M10MB超
-mtime -77日以内に更新
-mtime +3030日以上前

アクション:

書き方意味
(省略)パスを表示するだけ
-delete見つけたものを削除
-exec cmd {} \;各ファイルに対してコマンド実行
-exec cmd {} +複数ファイルをまとめて1回で処理(速い)

一番覚えやすい説明

find「どこで」「何を」「どうする」 の3部構成。

  • 場所 → 条件 → アクション の順に書く
  • アクション省略 = ただの一覧表示
  • 条件は AND で重ねがけできる

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 (link) は 「あるファイル/ディレクトリへの別名(ショートカット)を作るコマンド。macOS の「エイリアス」、Windows の「ショートカット」と発想は同じだが、Unix のリンクはより低レベルでファイルシステムに組み込まれており、アプリ側からは「実体と区別がつかない」ような透過的なアクセスができる。

実務で頻出するシーン:

  • dotfiles 管理: ~/.zshrc を Git 管理したリポ内のファイルへの symlink にして、複数マシン間で設定共有
  • 本番デプロイ: current/ を最新リリースディレクトリへの symlink にしておき、リリース切替を「symlink 張り替え」1秒で行う(Capistrano など)
  • 言語バージョン切替: /usr/local/bin/python -> python3.12 のように symlink で実体を切り替え
  • 巨大データの参照: 別ドライブにある大量データを ~/data 配下に symlink で見せる

種類は2つあり、シンボリックリンク(ln -s)が99%の用途で正解、ハードリンク(-s なし)は特殊用途。普段使うのは前者だけと覚えればOK。

# シンボリックリンク(こっちが普段使うやつ)
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 の管理: ~/.zshrcgit 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 で見える化
#    (`$(pwd)` は「カレントディレクトリの絶対パス」を返す呪文。詳しくは Level 2 で扱う)
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. セッション録画を終了

exit

2. 今日の発見

このノートに追記:

- 一番「これ便利」だったコマンド:
  findコマンド
- find でこういう使い方ができそう、と思ったケース:
  同じ拡張子のいらないファイルをいっきに削除できるのはかなり楽
- ヒヤッとした操作(あれば):
  rm -rfはスクリプト内では危険なため、必ず削除対象のディレクトリに中身があるか確認する
- 明日やりたいこと:
  普段の操作から積極的コマンドをつかっていきたい

チェックリスト

  • 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 の パーミッション に進む準備が整っている。


アンチパターン / 初心者やらかし事例

NG 1: rm -rf / 一族の事故

DIR=/var/www/myapp
rm -rf $DIR/*   # $DIR が空のままだと `rm -rf /*` になる

→ 対策: スクリプト内で rm -rf を使う時は 必ず変数が空でないことを確認 する。set -u(未定義変数で停止)か : "${DIR:?DIR not set}" で防ぐ。

NG 2: mv で「先にディレクトリが無い」ことに気づかず上書き

mv report.txt backup    # backup ディレクトリが無いと、report.txt が「backup」という名前にリネームされる

→ 対策: ディレクトリへ移動したい時は 末尾に / を付ける: mv report.txt backup/。無ければエラーになる。

NG 3: find -delete をテストせずに本番で実行

find / -name "*.tmp" -delete   # 範囲が広すぎて取り返しがつかない

→ 対策: まず -delete を付けずに実行 → 削除対象一覧を目視確認 → 問題なければ -delete を付け直す。

cd ~/work
ln -s ../config.yml link   # ~/work から見て ../config.yml = ~/config.yml
# このシンボリックリンクを別の場所に移すと「相対の意味」が変わって壊れる

→ 対策: 移動する可能性がある symlink は 絶対パスで作る: ln -s "$(pwd)/config.yml" link


自己評価チェックリスト

  • cp mv rm find ln の5つを、迷わず使える
  • rm -rf を打つ前に、対象パスを声に出して読むクセがついた
  • find-name -type -mtime を組み合わせられる
  • シンボリックリンクと「コピー」の違いを後輩に説明できる
  • Day 1 で学んだ pwd の重要性が、Day 2 でさらに強まった実感がある

次のレッスン: Day 3 - パーミッション

明日は ls -l の左端で何度も見てきた rwxr-xr-x の正体に踏み込む。

今日まで「ファイルを動かす・消す」をやってきたが、本番では 「動かそうとしたら permission denied」 が頻発する。なぜ拒否されるか、どう許可するか、を chmod / chown / sudo で学ぶ。

Day 1 で ls -l の見方を覚え、Day 2 でファイルを操作した。Day 3 では 「誰が・何を・できるか」 を制御する側に回る。

Day 3: パーミッション