本記事には広告(アフィリエイトリンク)が含まれます。

ファイル操作とFHS LinuC101 第7回

広告

新卒インフラエンジニア向けLinuC 101 試験対策シリーズの第7回です。前回はパッケージという「ソフトウェアの単位」を扱いました。今回は ファイルそのものの操作に降りていきます。

cp mv rm find。新卒1日目から触る基本コマンドですが、「動いた」と「正しい」は別物です。本番で rm -rf を打って取り返しがつかなくなる事故、リンクの仕組みを誤解してデータを失う事故、設定ファイルのパーミッションを失うコピー操作 — どれも基本コマンドの周りで起きます。本記事では、これらを「なぜそうなるか」から理解し直します。

環境前提

  • ディストリビューション: AlmaLinux 9.6(Sage Margay)
  • カーネル: 5.14.0-570.12.1.el9_6.x86_64
  • ユーザー: developer(sudo NOPASSWD設定済み)
  • 関連VM: linuc-alma(10.0.10.132)
  • 本記事で導入するパッケージ: mlocate(演習で locate 確認後に削除)
  • 演習用ディレクトリ ~/linuc-fileops/ を作成 → 末尾でクリーンアップ
広告

今ここマップ

LinuC 101 試験対策シリーズ(全12回)

  第1回 Linuxの起動・接続・停止
  第2回 ブートプロセスの仕組み
  第3回 systemdマスター講座
  第4回 プロセス管理とハードウェア基礎
  第5回 仮想マシンとコンテナの基礎
  第6回 パッケージ管理マスター
▶ 第7回 ファイル操作の実践    ← いまここ
  第8回 パーミッション・所有者・特殊権限
  第9回 コマンドライン・リダイレクト・パイプ
  第10回 テキスト処理(grep / sed / awk)
  第11回 vi/vim 入門
  第12回 ディスク・パーティション・ファイルシステム

この記事で身につくこと

  1. cp / mv / rm / mkdir / rmdir / touch の主要オプション(-r / -p / -f / -i / -v / -a)を使い分けられる
  2. ハードリンクとシンボリックリンクの違いを inode の観点で説明し、ln / ln -s で作成できる
  3. find で「名前・種別・更新時刻・サイズ」による条件検索ができ、-exec でアクションを連結できる
  4. which / whereis / locate で実行ファイルや任意ファイルを検索できる
  5. FHS の主要ディレクトリ(/bin / /sbin / /etc / /var / /opt / /usr / /tmp / /run)の役割を説明できる

第1章:ファイル操作はなぜ難しいのか

「ファイルをコピーする」「移動する」「消す」。日本語で言うと当たり前に聞こえますが、Linux ではこれらの操作の裏側で 取り返しのつかない結果が起き得ます。

  • rm にはゴミ箱が無い。打った瞬間に消える
  • mv で同名ファイルがあれば黙って上書きされる(オプション無しの場合)
  • cp で属性(パーミッション・所有者・タイムスタンプ)を保持しないと、運用設計が狂う
  • シンボリックリンクの先を rm したつもりが、リンク自体だけが消える

誰のために慎重に操作するか

  • サービスを止めない自分:本番環境で動いている nginx の設定を、無自覚なコピーで属性を失わせない
  • 過去の自分の作業を読み直す自分:「3カ月前に置いたバックアップ」が見つかる命名規則を持つ
  • あとから加わるチームメンバー:監査ログ、命名規則、リンクの使い方が一貫していれば、引き継ぎが半日で済む

「動かす」だけのファイル操作と、「3年後の自分が読み直しても破綻しない」ファイル操作の差は、オプションの選択と命名の習慣に表れます。本章以降、その視点で各コマンドを見ていきます。

第2章:基本7コマンドのオプション戦略

まず演習用のディレクトリを作ります。本章以降で繰り返し使います。linuc-almaで実行:

$ rm -rf ~/linuc-fileops
$ mkdir -p ~/linuc-fileops/{src,dst,backup}
$ touch ~/linuc-fileops/src/file{1..3}.txt

{src,dst,backup} はブレース展開。3つのサブディレクトリが一発で作れます。file{1..3}.txt も同じ仕組みで file1.txt file2.txt file3.txt に展開されます。

linuc-almaで実行:

$ ls -lR ~/linuc-fileops/

実行結果:

/home/developer/linuc-fileops/:
合計 0
drwxr-xr-x. 2 developer developer  6  5月 10 07:40 backup
drwxr-xr-x. 2 developer developer  6  5月 10 07:40 dst
drwxr-xr-x. 2 developer developer 57  5月 10 07:40 src

/home/developer/linuc-fileops/backup:
合計 0

/home/developer/linuc-fileops/dst:
合計 0

/home/developer/linuc-fileops/src:
合計 0
-rw-r--r--. 1 developer developer 0  5月 10 07:40 file1.txt
-rw-r--r--. 1 developer developer 0  5月 10 07:40 file2.txt
-rw-r--r--. 1 developer developer 0  5月 10 07:40 file3.txt

2.1 cp — オプションが本質

オプション意味使いどころ
-r または -R再帰コピー(ディレクトリごと)必須。ディレクトリは -r なしではコピーできない
-p属性保持(パーミッション・所有者・タイムスタンプ)本番環境のバックアップ
-aアーカイブモード(-dpR 相当)「とりあえず属性ごと丸ごと」
-i上書き前に確認誤操作防止
-v詳細表示(何をコピーしたか)監査ログ・スクリプトデバッグ

linuc-almaで実行:

$ cp -av ~/linuc-fileops/src ~/linuc-fileops/backup/src.20260510

実行結果:

'/home/developer/linuc-fileops/src' -> '/home/developer/linuc-fileops/backup/src.20260510'
'/home/developer/linuc-fileops/src/file1.txt' -> '/home/developer/linuc-fileops/backup/src.20260510/file1.txt'
'/home/developer/linuc-fileops/src/file2.txt' -> '/home/developer/linuc-fileops/backup/src.20260510/file2.txt'
'/home/developer/linuc-fileops/src/file3.txt' -> '/home/developer/linuc-fileops/backup/src.20260510/file3.txt'

-a でディレクトリ丸ごと、-v で何が何にコピーされたかを表示。バックアップ先は日付付きの命名(src.20260510にすると、複数世代を並べたときに時系列が一目で分かります。

2.2 mv — リネームと移動の二役

mv はファイル名変更とディレクトリ間移動を1コマンドで担います。同じファイルシステム内ではメタデータの更新だけで瞬時に終わりますが、別のファイルシステム間ではコピー+削除になり時間がかかります。

linuc-almaで実行:

$ cp -p ~/linuc-fileops/src/file1.txt ~/linuc-fileops/src/copy1.txt
$ mv ~/linuc-fileops/src/copy1.txt ~/linuc-fileops/src/renamed.txt
$ ls ~/linuc-fileops/src/

実行結果:

file1.txt  file2.txt  file3.txt  renamed.txt

cp -p でタイムスタンプ・パーミッションを保ったままコピー → mv でリネーム。mv -i を習慣化しておくと、同名ファイルへの上書き直前に確認が出るので事故を防げます。

2.3 rm — 削除には常に緊張感を

rm はゴミ箱に入れません。打った瞬間に消えます

  • -r 再帰削除(ディレクトリごと)
  • -f 強制(確認スキップ・存在しなくてもエラーにしない)
  • -i 確認付き

rm -rf は強力な削除であり、同時に重大な事故装置でもあります。シェル変数を使うときは特に注意が必要 — 第8章で実例を扱います。

2.4 mkdir / rmdir — ディレクトリ専用

linuc-almaで実行:

$ mkdir -p ~/linuc-fileops/dst/a/b/c
$ ls -R ~/linuc-fileops/dst/

実行結果:

/home/developer/linuc-fileops/dst/:
a

/home/developer/linuc-fileops/dst/a:
b

/home/developer/linuc-fileops/dst/a/b:
c

/home/developer/linuc-fileops/dst/a/b/c:

mkdir -p親ディレクトリも作成-p 無しだと「親が無い」とエラーになります。rmdir空のディレクトリのみ削除可能で、中身があれば rm -r を使います。

2.5 touch — ファイル作成と mtime 更新

touch foo.txt は、foo.txt が無ければ空ファイルとして作成し、あれば最終更新時刻(mtime)を「今」に更新します。バックアップスクリプトの完了マーカーやテスト用ファイルの一括作成に使います。

2.6 file — 中身で判定

Linux のファイル名は拡張子に依存しない。「.sh がついているからシェルスクリプト」と決めつけず、中身を確認するのが file コマンド。

linuc-almaで実行:

$ file /etc/hostname /usr/bin/ls

実行結果:

/etc/hostname: ASCII text
/usr/bin/ls:   ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=215d223c8282b6787e65aed9bef550ece6da6d3c, for GNU/Linux 3.2.0, stripped

/etc/hostname は普通のテキスト、/usr/bin/ls は ELF(Linux のバイナリ実行形式)であることが分かります。

📖 試験Tipsボックス:基本コマンドの主要オプション

主題:1.02.2(重要度:高)
出題パターン:「再帰コピーは?」「属性保持コピーは?」「親ディレクトリも作成は?」「上書き確認は?」

暗記ポイント

  • cp -r 再帰 / -p 属性保持 / -a アーカイブ(=-dpR
  • rm -r 再帰 / -f 強制 / -i 確認
  • mkdir -p 親ディレクトリも作成(頻出
  • rmdir は空ディレクトリのみ。中身があれば rm -r
  • touch は新規作成と mtime 更新の二役
  • file <path> は中身で種別判定(拡張子に依存しない)

第3章:リンクの仕組み — inode で理解する

3.1 ファイルシステムの3つの構成要素

「ファイル」と一口に言いますが、ファイルシステム上では3つの要素に分かれて格納されています。

Linuxファイルシステムの3層構造図。最上位の③ディレクトリエントリ(『名前→inode番号』の対応表)から、② inode(メタデータ:所有者・属性・タイムスタンプ・ハードリンク数・データブロックへのポインタ)を経由し、① データブロック(ファイルの実体)へとポインタで指し示す関係を縦に表現
図 07-01. ファイルシステムの3層構造(ツリー構造)

つまり 「ファイル名」と「実体」は別管理。リンクの仕組みはここを起点に理解します。

3.2 ハードリンク — 同じ inode に別の名前を貼る

ln でハードリンクを作ると、同じ inode に別のディレクトリエントリ(名前)が追加されます。実体はひとつ、名前は複数。

linuc-almaで実行:

$ cd ~/linuc-fileops/src
$ echo 'content of file1' > file1.txt
$ ln file1.txt hardlink1.txt
$ ls -li

実行結果:

合計 8
67240919 -rw-r--r--. 2 developer developer 17  5月 10 07:41 file1.txt
67240920 -rw-r--r--. 1 developer developer  0  5月 10 07:40 file2.txt
67240921 -rw-r--r--. 1 developer developer  0  5月 10 07:40 file3.txt
67240919 -rw-r--r--. 2 developer developer 17  5月 10 07:41 hardlink1.txt
67242091 -rw-r--r--. 1 developer developer  0  5月 10 07:40 renamed.txt

注目すべき2点:

  • file1.txthardlink1.txt左端の inode 番号が同じ(67240919)
  • 2列目(リンク数)が 2 になっている。他の単独ファイルは 1

同じ実体に2つの名前。詳細は stat でも確認できます。linuc-almaで実行:

$ stat file1.txt

実行結果(抜粋):

  File: file1.txt
  Size: 17        	Blocks: 8          IO Block: 4096   通常ファイル
Device: fd00h/64768d	Inode: 67240919    Links: 2
Access: (0644/-rw-r--r--)  Uid: ( 1000/developer)   Gid: ( 1000/developer)

Inode: 67240919 Links: 2 がリンクの本質を示しています。

3.3 シンボリックリンク — パスを指す軽量なファイル

シンボリックリンク(symlink、シムリンク)は仕組みが違います。独自の inode を持ち、中身は「リンク先のパス文字列」

linuc-almaで実行:

$ ln -s file1.txt symlink1.txt
$ ls -li

実行結果:

合計 8
67240919 -rw-r--r--. 2 developer developer 17  5月 10 07:41 file1.txt
67240920 -rw-r--r--. 1 developer developer  0  5月 10 07:40 file2.txt
67240921 -rw-r--r--. 1 developer developer  0  5月 10 07:40 file3.txt
67240919 -rw-r--r--. 2 developer developer 17  5月 10 07:41 hardlink1.txt
67242091 -rw-r--r--. 1 developer developer  0  5月 10 07:40 renamed.txt
67484038 lrwxrwxrwx. 1 developer developer  9  5月 10 07:41 symlink1.txt -> file1.txt

symlink1.txt の特徴:

  • inode 番号が 別(67484038)
  • パーミッション表示が l で始まる(lrwxrwxrwx
  • サイズが 9 バイト(file1.txt という9文字のパス文字列だけが入っている)
  • 末尾に -> file1.txt でリンク先を表示

linuc-almaで実行:

$ readlink symlink1.txt

実行結果:

file1.txt

readlink でリンク先を取り出せます。

3.4 元ファイルを削除すると何が起きるか

本質的な違いはここで現れます。file1.txt を削除してみます。linuc-almaで実行:

$ rm file1.txt
$ ls -li

実行結果:

合計 4
67240920 -rw-r--r--. 1 developer developer  0  5月 10 07:40 file2.txt
67240921 -rw-r--r--. 1 developer developer  0  5月 10 07:40 file3.txt
67240919 -rw-r--r--. 1 developer developer 17  5月 10 07:41 hardlink1.txt
67242091 -rw-r--r--. 1 developer developer  0  5月 10 07:40 renamed.txt
67484038 lrwxrwxrwx. 1 developer developer  9  5月 10 07:41 symlink1.txt -> file1.txt

hardlink1.txt は inode 67240919 を維持し、リンク数が 2 → 1 に減っただけ。中身は読めます。

linuc-almaで実行:

$ cat hardlink1.txt
$ cat symlink1.txt

実行結果:

content of file1
cat: symlink1.txt: そのようなファイルやディレクトリはありません

ハードリンクは独立した実体として残り、シンボリックリンクは「リンク切れ(dangling link)」になる。これがリンクの最も重要な区別です。

ハードリンクとシンボリックリンクを左右で比較する図。ハードリンクは元ファイルとリンクが同じinode(共有)でデータ実体に到達するため、元削除後もリンクからデータが読める。シンボリックリンクは別inodeで「パス文字列」を保持するだけのため、元削除後はdangling(リンク切れ)になりcatでエラー
図 07-02. ハードリンク vs シンボリックリンク

3.5 比較表

観点ハードリンクシンボリックリンク
作成コマンドln 元 リンクln -s 元 リンク
inode元と同じ独立(別 inode)
ファイル種別(ls -l普通のファイル -リンク l
元削除時の挙動実体が残る(リンク数が減るだけ)dangling(リンク切れ)
ファイルシステム跨ぎ不可
ディレクトリへのリンク不可(root を除く)
サイズ元と同じパス文字列の長さだけ
主な用途同一データの別名管理パス参照、バージョン切り替え(current -> v2.1 等)

📖 試験Tipsボックス:ハードリンク vs シンボリックリンク

主題:1.02.3(重要度:高)
出題パターン:「ハードリンクの inode は元と同じか?」「シンボリックリンクはファイルシステム跨ぎ可能か?」「ディレクトリにハードリンクできるか?」

暗記ポイント

  • ハードリンク:ln 元 リンク、同一 inode、FS内のみ、ファイルのみ、元削除でも実体残る
  • シンボリックリンク:ln -s 元 リンク、別 inode、FS跨ぎ可、ディレクトリ可、元削除で dangling
  • ls -l で先頭文字:通常ファイル - / シンボリックリンク l / ディレクトリ d
  • リンク数の確認:ls -l の2列目、または statLinks
  • シンボリックリンク先の確認:readlink

第4章:find — 条件検索の言語

find は単なる検索ツールではなく、「条件指定 → アクション」の小さな言語です。基本構文は次の通り。

find <検索開始パス> <式(条件)> <アクション>

4.1 名前と種別

linuc-almaで実行:

$ find ~/linuc-fileops -name '*.txt'

実行結果:

/home/developer/linuc-fileops/src/file2.txt
/home/developer/linuc-fileops/src/file3.txt
/home/developer/linuc-fileops/src/renamed.txt
/home/developer/linuc-fileops/src/hardlink1.txt
/home/developer/linuc-fileops/src/symlink1.txt
/home/developer/linuc-fileops/backup/src.20260510/file1.txt
/home/developer/linuc-fileops/backup/src.20260510/file2.txt
/home/developer/linuc-fileops/backup/src.20260510/file3.txt

-name はワイルドカード(シェルのグロブ)が使えます。シェル展開を防ぐためクォート必須

linuc-almaで実行:

$ find ~/linuc-fileops -type f
$ find ~/linuc-fileops -type l

実行結果(-type l の方):

/home/developer/linuc-fileops/src/symlink1.txt

-type f でファイルのみ、-type d でディレクトリのみ、-type l でシンボリックリンクのみ。第3章で作った symlink1.txt がここでだけヒットします。

4.2 時刻とサイズ

-mtime N は更新時刻条件。N は日数で、-N は「N日以内」、+N は「N日より前」、N は「ちょうどN日前」。

linuc-almaで実行:

$ find ~/linuc-fileops -type f -mtime -1 | head -3

実行結果:

/home/developer/linuc-fileops/src/file2.txt
/home/developer/linuc-fileops/src/file3.txt
/home/developer/linuc-fileops/src/renamed.txt

「24時間以内に更新されたファイル」が出ています。

-size N はサイズ条件。+100M(100MB超)、-1k(1KB未満)、+0c(0バイトより大きい)など。

linuc-almaで実行:

$ find ~/linuc-fileops -type f -size +0c

実行結果:

/home/developer/linuc-fileops/src/hardlink1.txt

中身があるのは hardlink1.txtfile1.txt のハードリンクとして 17 バイトを保持)だけ、ということが分かります。

4.3 -exec — 結果に対してコマンドを実行

-execfind の結果を別のコマンドに渡す仕組み。{} がプレースホルダ、終端は \;(バックスラッシュ+セミコロン)。

linuc-almaで実行:

$ find ~/linuc-fileops/src -name '*.txt' -exec ls -l {} \;

実行結果:

-rw-r--r--. 1 developer developer 0  5月 10 07:40 /home/developer/linuc-fileops/src/file2.txt
-rw-r--r--. 1 developer developer 0  5月 10 07:40 /home/developer/linuc-fileops/src/file3.txt
-rw-r--r--. 1 developer developer 0  5月 10 07:40 /home/developer/linuc-fileops/src/renamed.txt
-rw-r--r--. 1 developer developer 17  5月 10 07:41 /home/developer/linuc-fileops/src/hardlink1.txt
lrwxrwxrwx. 1 developer developer 9  5月 10 07:41 /home/developer/linuc-fileops/src/symlink1.txt -> file1.txt

各ファイルに対して ls -l が実行されます。\; の代わりに + を使うと「複数のファイルをまとめて1回のコマンド実行」になり高速化されます(xargs と同等の動き)。

📖 試験Tipsボックス:find の主要オプション

主題:1.02.4(重要度:高)
出題パターン:「名前検索のオプションは?」「7日以内に更新は?」「ファイル種別の指定は?」「結果に対してコマンド実行は?」

暗記ポイント

  • -name 'pattern'(必ずクォート)
  • -type f(ファイル)/ -type d(ディレクトリ)/ -type l(シンボリックリンク)
  • -mtime -N(N日以内)/ +N(N日より前)
  • -size +100M / -size -1k(単位:c=バイト/k=KB/M=MB/G=GB)
  • -perm 644(完全一致)/ -perm /u+x(少なくとも u に x)
  • -exec cmd {} \;(1ファイルごと)/ -exec cmd {} +(まとめて)
  • 論理演算:-and(既定)/ -or / -not / 括弧 \( \)

第5章:locate / which / whereis — 検索の使い分け

5.1 which — $PATH から実行ファイルを探す

linuc-almaで実行:

$ which ls

実行結果:

alias ls='ls --color=auto'
	/usr/bin/ls

対話シェルでは which は「エイリアスがあれば併記」する作りなので、alias ls='ls --color=auto' も出てきます。実体は /usr/bin/ls

5.2 whereis — バイナリ+man+ソースを横断検索

linuc-almaで実行:

$ whereis ls

実行結果:

ls: /usr/bin/ls /usr/share/man/man1/ls.1.gz

whereis はバイナリ・manページ・ソースをまとめて検索。「コマンドの man ページがどこにあるか」を素早く知りたいときに便利です。

5.3 locate — DB 事前構築型の高速検索

locate は事前にビルドしたDBから検索するため、ファイルシステム全体を走査する find よりはるかに速い。代わりにDBが古いと最近のファイルは出てきません。

AlmaLinux 9 の minimal install には mlocate が入っていないので、まず導入します。linuc-almaで実行:

$ sudo dnf install -y mlocate

実行結果(末尾のみ):

インストール済み:
  mlocate-0.26-30.el9.x86_64

完了しました!

続いてDBを構築します。linuc-almaで実行:

$ sudo updatedb

(完了まで数秒〜数十秒。検証VMは小さいので 1 秒以内)

linuc-almaで実行:

$ locate hostname | head -5

実行結果:

/etc/hostname
/usr/bin/hostname
/usr/bin/hostnamectl
/usr/bin/nmtui-hostname
/usr/lib/dracut/modules.d/01systemd-hostnamed

hostname という文字列を含むファイル」が瞬時に出ます。本番環境では updatedbcron で毎日定期実行される設定が一般的(/etc/cron.daily/mlocate など)。

5.4 find / locate / which / whereis の使い分け

用途ツール特徴
$PATH 上の実行ファイルwhichシェルのエイリアスも表示(対話時)
バイナリ+man+ソースwhereis定型的な4箇所をまとめて
パス文字列でファイル検索locateDB事前構築・高速・古い可能性
条件指定で精密検索findリアルタイム・遅い・式が強力

第6章:FHS — Linux ファイルシステム階層の地図

FHS(Filesystem Hierarchy Standard)は Linux ディストリビューションが従う「ディレクトリ配置の決まり」。これを知っているかどうかで、初めて触るシステムに対する解像度が大きく変わります。

linuc-almaで実行:

$ ls /

実行結果:

afs  boot  etc	 lib	media  opt   root  sbin  sys  usr
bin  dev   home  lib64	mnt    proc  run   srv	 tmp  var
FHS(Filesystem Hierarchy Standard)主要ディレクトリ階層図。/(ルート)から /bin(→/usr/binリンク)/etc(設定)/home(ユーザーホーム)/var(可変データ。配下に /var/log /var/lib /var/spool)/usr(プログラム実体)/tmp(一時、再起動で消える)/run(実行時PID/ソケット、tmpfs)/opt(第三者アプリ)/srv(サービスデータ)/boot(ブートローダ・カーネル)/proc・/sys(仮想FS)/dev(デバイス)が枝分かれ
図 07-03. FHS 主要ディレクトリ階層

6.1 主要ディレクトリの役割

ディレクトリ役割
/bin /sbin起動時から必須のコマンド(usrmerge後は /usr/bin /usr/sbin へのリンク)ls cp shutdown
/usr/bin /usr/sbin通常時のコマンド本体大半の実行ファイル
/etcシステム全体の設定ファイル/etc/hostname /etc/passwd /etc/yum.repos.d/
/var可変データ(ログ・スプール・キャッシュ・DB)/var/log /var/lib /var/spool
/var/logログファイルmessages secure cron
/tmp一時ファイル(再起動で消える前提)各種テンポラリ
/run実行時データ(PID、ソケット)。tmpfs/run/sshd.pid
/home一般ユーザーのホーム/home/developer
/rootroot のホーム(/home/root ではない)
/optサードパーティアプリの追加配置場所/opt/google/chrome/
/srvサービス提供データWeb/FTP のドキュメントルート
/procプロセス情報の仮想ファイルシステム/proc/cpuinfo(第4回で確認)
/sysカーネル・デバイス情報の仮想ファイルシステム/sys/class/net/
/devデバイスファイル/dev/null /dev/sda
/bootブートローダ・カーネル(第2回で扱った)vmlinuz-* grub2/

6.2 usrmerge — /bin と /usr/bin の関係

第6回で dpkg -S /bin/cat が失敗するのを見ました。原因は usrmerge — 現代の Linux では /bin /sbin/usr/bin /usr/sbin へのシンボリックリンクです。

linuc-almaで実行:

$ ls -ld /bin /sbin /usr/bin /usr/sbin

実行結果:

lrwxrwxrwx. 1 root root     7 10月  3  2024 /bin -> usr/bin
lrwxrwxrwx. 1 root root     8 10月  3  2024 /sbin -> usr/sbin
dr-xr-xr-x. 2 root root 20480  5月 10 07:41 /usr/bin
dr-xr-xr-x. 2 root root 12288  5月 10 00:26 /usr/sbin

/bin/sbinシンボリックリンク(先頭が l)。第3章で学んだリンクの仕組みが OS の根本構造で活用されています。

6.3 /run は tmpfs — 再起動で消える

linuc-almaで実行:

$ df -h /var /tmp /run /

実行結果:

ファイルシス               サイズ  使用  残り 使用% マウント位置
/dev/mapper/almalinux-root    45G  2.1G   43G    5% /
/dev/mapper/almalinux-root    45G  2.1G   43G    5% /
tmpfs                        783M  8.5M  774M    2% /run
/dev/mapper/almalinux-root    45G  2.1G   43G    5% /

注目は /runtmpfs。これはメモリ上のファイルシステムで、再起動するとすべて消えます。PIDファイル・ソケット・ロックファイルなど「再起動時に古い情報が残ると困る」ものを置く場所として最適です。

本番環境では /var/home を別パーティションにする設計が一般的ですが、検証VMはシンプルな単一ファイルシステム構成です。

📖 試験Tipsボックス:FHS主要ディレクトリの役割

主題:1.02.4(重要度:高)
出題パターン:「設定ファイルが置かれる場所は?」「ログはどこ?」「PIDファイルはどこ?」「rootのホームは?」

暗記ポイント

  • /etc 設定ファイル / /var/log ログ / /var/lib 永続データ
  • /run 実行時データ(tmpfs・再起動で消える)/ /tmp 一時
  • /home/<user> 一般ユーザー / /root root のホーム/home/root ではない)
  • /opt サードパーティ追加 / /srv サービス提供データ
  • /proc /sys 仮想ファイルシステム / /dev デバイス / /boot ブート
  • usrmerge:/bin /sbin/usr/bin /usr/sbin へのシンボリックリンク

第7章:現場での使いどころ

  • 設定ファイルバックアップsudo cp -a /etc/nginx/nginx.conf{,.20260510} のブレース展開で「同じパス+日付サフィックス」を一発生成。複数世代を時系列に並べられる
  • 古いログ整理find /var/log -name '*.log' -mtime +30 -delete で30日より前のログを削除(cron で定期実行)
  • 巨大ログ調査find /var/log -size +100M でディスクを圧迫しているログを特定
  • 一括権限修正find . -type f -name '*.sh' -exec chmod +x {} + でシェルスクリプトに一括で実行権限
  • シンボリックリンクで切り替え/opt/myapp/current -> /opt/myapp/v2.1 のリンクで本番アプリのバージョン切り替え。ロールバックは ln -sfn v2.0 current 一発
  • 古いカーネル整理find /boot -name 'vmlinuz-*' | sort で多世代インストール状態を確認、不要分を dnf remove

第8章:ヒヤリハット — シェル変数の罠

⚠️ rm -rf $foo/$foo が空 → rm -rf / 直行

新人G君は、後片付けスクリプトの中で rm -rf $WORKDIR/ という処理を書きました。テストでは動いたものの、本番投入後に WORKDIR 変数の取得処理がエラーになって $WORKDIR が空文字列に。結果、シェルが解釈したコマンドは rm -rf / となり、サーバーのルートから順に削除が走り始めました。1分以内にサービスが応答停止、復旧にはバックアップからの復元で半日。

教訓

  • シェル変数を使う rm では必ず空チェック[ -n "$WORKDIR" ] && rm -rf "$WORKDIR"/
  • 変数は必ずダブルクォートで囲む:"$WORKDIR"
  • スクリプト先頭に set -u(未定義変数で停止)set -e(エラーで停止)を入れる
  • 削除前に echo でドライランする習慣:echo rm -rf "$WORKDIR"/ で確認してから実行
  • 現代の rm には --preserve-root がデフォルト有効で rm -rf / は止められるが、rm -rf /*rm -rf /home/user/ + 空変数(/home/user//)は止められない

類似事例mv $A $B$A がディレクトリで $B も既存ディレクトリの場合、意図と違う場所に移動。cp -r で同名ディレクトリへの上書きで子ファイルが消失。変数を使うファイル操作は、必ず実行前にエコーで確認するのが鉄則です。

やってみよう

linuc-alma にログインしている前提で、演習1〜4を順に実行してください。

演習1:基本コマンドで演習用ディレクトリを構築

  1. rm -rf ~/linuc-fileops(古いものをクリーン)
  2. mkdir -p ~/linuc-fileops/{src,dst,backup}
  3. touch ~/linuc-fileops/src/file{1..3}.txt
  4. cp -av ~/linuc-fileops/src ~/linuc-fileops/backup/src.20260510
  5. ls -lR ~/linuc-fileops/ で確認

演習2:ハードリンクとシンボリックリンクの観察

  1. cd ~/linuc-fileops/src
  2. echo 'content of file1' > file1.txt
  3. ln file1.txt hardlink1.txt でハードリンク
  4. ln -s file1.txt symlink1.txt でシンボリックリンク
  5. ls -li で inode 番号とリンク数を確認
  6. stat file1.txtLinks: 2 を確認
  7. rm file1.txt で元を削除
  8. cat hardlink1.txt → 内容が読める
  9. cat symlink1.txt → 「No such file or directory」(dangling)

演習3:find で条件検索

  1. find ~/linuc-fileops -type f(ファイルのみ)
  2. find ~/linuc-fileops -type l(シンボリックリンクのみ)
  3. find ~/linuc-fileops -name '*.txt' -mtime -1(24時間以内更新の .txt)
  4. find ~/linuc-fileops -size +0c(中身があるファイル)
  5. find ~/linuc-fileops/src -name '*.txt' -exec ls -l {} \;(結果に ls -l

演習4:locate と FHS 探検 → クリーンアップ

  1. sudo dnf install -y mlocate
  2. sudo updatedb
  3. locate hostname | head -5
  4. which locate && whereis locate で違いを観察
  5. ls / で FHS 最上層を確認
  6. ls -ld /bin /sbin /usr/bin /usr/sbin で usrmerge を確認
  7. df -h /var /tmp /run //run が tmpfs であることを確認
  8. クリーンアップrm -rf ~/linuc-fileops / sudo dnf remove -y mlocate

分からないオプションは man findman cpman lnman hier(FHS)で調べる習慣を身につけてください。man hier は FHS の概要が読める優れた man ページです。

理解度チェック

○か×で答えてください。回答と解説は次回冒頭で振り返ります。

  1. cp -p はファイルの所有者・パーミッション・タイムスタンプを保持してコピーする。
  2. ハードリンクは元ファイルとは異なる inode を持つ。
  3. シンボリックリンクはファイルシステムを跨いで作成できるが、ハードリンクは同一ファイルシステム内に限られる。
  4. find /var/log -name '*.log' -mtime +30 -delete は、/var/log 配下で30日より前に更新された .log ファイルを削除する。
  5. FHS において、PID ファイルやソケットは /var 配下に置くのが標準である。

解答

  • 1.  -p(preserve)で所有者・パーミッション・mtime を保持。-a はさらにシンボリックリンクや再帰も含む
  • 2. × ハードリンクは元と同じ inode。別 inode はシンボリックリンク
  • 3.  シンボリックリンクは別 inode でパス参照だけなので跨げる。ハードリンクは同一ファイルシステム内のみ
  • 4.  -mtime +30 は「30日より前に更新」、-delete はアクション。実運用では事前に -print で確認するのが安全
  • 5. × PID ファイルやソケットは /run(tmpfs)が現代の標準。/var/run/run へのシンボリックリンク

次回予告

第8回は「パーミッション・所有者・特殊権限(SUID/SGID/Sticky)」です。今回は ls -l で「-rw-r–r–」のような表示を何度か見ましたが、その意味を本格的に扱います。chmod でのパーミッション変更、chown での所有者変更、そして SUID / SGID / Sticky bit という特殊権限の仕組みまで。FHS で「/tmp は誰でも書ける」という性質を支えているのが Sticky bit、という伏線回収もします。

LinuC 101 試験対策シリーズ 全12回

広告
Linux
スポンサーリンク