ls -la の出力を1列ずつ解剖
ls -la が読めればパーミッション事故もリンク切れも即座に切り分けられる。実際の出力を1列ずつ分解し、種別文字とrwxの8進数対応から、ディレクトリのサイズやハードリンク数が意味するものまで読み解く。
- 先頭1文字はファイルの種別で、-は通常ファイル、dはディレクトリ、lはシンボリックリンクを表す。続く9文字は所有者・グループ・その他の3組に分かれ、r=4・w=2・x=1を足した値が8進数表記になる。rw-r--r--なら644だ。
- ディレクトリではrwxの意味が変わる。xは中に入って個々のエントリのメタデータを引く権限、rは名前一覧を読む権限、wはエントリの作成・削除の権限だ。ファイル自体の書き込み権限とは無関係に、親ディレクトリのwがあれば削除できる。
- 第2列は同じinodeを指す名前の数。ディレクトリは自身の.と親からの登録で2から始まり、子が増えるたび..の分が加算される。第5列は中身の合計ではなくディレクトリエントリ表自体の大きさだ。
このコマンドは何を見せているか
ls はエントリを並べるだけに見えるが、-l を付けた瞬間に性格が変わる。名前からinodeを引き、そこに記録された種別・パーミッション・リンク数・所有者・サイズ・時刻を表に組み直す、ファイルシステムのメタデータビューアになる。-a はドットで始まるエントリも隠さず出す指定で、この2つを合わせた ls -la がトラブルシュートの初手として定着している。
肝心なのは、この表がinodeの写しだという点だ。ディレクトリが持つのは「名前とinode番号の対応表」でしかなく、サイズも所有者もパーミッションも、すべてinode側に書かれている。各列の意味に迷ったら、この分業を思い出すと大半は解ける。詳しくはファイルシステムにある。
日時の書式やソート順はロケールに左右され、total の単位も既定は1KiBブロックだが POSIXLY_CORRECT が効くと512バイトになる。列の意味は変わらないが、字面を前提にした自動処理は避けたい。
横にスクロール
1列ずつ解剖
題材は、デプロイ用ディレクトリを覗いた出力だ。
$ ls -la /srv/app
total 104
drwxr-xr-x 5 deploy deploy 4096 Jul 14 09:12 .
drwxr-xr-x 12 root root 4096 Jun 2 17:03 ..
-rw-r--r-- 1 deploy deploy 220 Nov 3 2025 .env.example
drwxr-xr-x 8 deploy deploy 4096 Jul 14 09:12 .git
lrwxrwxrwx 1 deploy deploy 10 Jul 14 09:12 current -> releases/7
-rwxr-xr-x 1 deploy deploy 1842 Jul 10 21:47 deploy.sh
-rw-rw-r-- 2 deploy staff 5120 Jul 13 14:05 notes.md
-rwsr-xr-x 1 root root 68208 Nov 3 2025 runner
drwxrwsr-x 3 deploy staff 4096 Jul 12 08:30 shared
drwxrwxrwt 2 root root 4096 Jul 14 10:00 tmp
先頭の total 104 は、一覧のエントリが実際に占めるディスクブロックの合計で、既定は1KiB単位。第5列のサイズ合計とは一致しない。以下、1行を左から7つの列に分けて読む。
第1列の先頭1文字 — ファイルの種別
モード文字列は10文字あり、1文字目だけが独立して種別を表す。サンプルには3種類が現れている。
| 文字 | 種別 | サンプル中の例 |
|---|---|---|
| - | 通常ファイル | deploy.sh、notes.md、runner |
| d | ディレクトリ | .、..、.git、shared、tmp |
| l | シンボリックリンク | current |
ほかに /dev ではブロックデバイスの b とキャラクタデバイスの c、名前付きパイプの p、UNIXドメインソケットの s が並ぶ。いずれもinodeの型フィールドを文字にしたもので、拡張子とは無関係だ。
第1列の残り9文字 — rwxの3組と8進数
2文字目以降の9文字は3文字ずつ3組に割れる。左から所有者・グループ・その他だ。各組は読み取り r、書き込み w、実行 x の順に固定で、権限がなければ - が入る。位置が意味を持つので、r-x の中央の - は「書き込みだけがない」と読む。8進数との対応は単純な足し算で、r=4、w=2、x=1を組ごとに合計する。
| モード文字列 | 8進数 | 読み方 |
|---|---|---|
| rw-r--r-- | 644 | 所有者は読み書き、他は読むだけ |
| rwxr-xr-x | 755 | 所有者は全部、他は読めて実行できる |
| rw-rw-r-- | 664 | グループにも書き込みを許す |
| rwx------ | 700 | 所有者以外は一切触れない |
chmod 644 file と chmod u=rw,go=r file が同じ結果になるのはこのためだ。判定に使う組は1つだけで、アクセスするユーザーが所有者なら所有者の3文字だけで決まり、下の組へフォールバックはしない。所有者に ---、その他に rwx を与えれば、所有者「だけ」が読めない状態すら作れる。
第1列に現れる s と t — setuid・setgid・スティッキービット
runner は -rwsr-xr-x で、所有者の実行ビットが x ではなく s だ。これがsetuidで、誰が起動してもプロセスの実効ユーザーIDは所有者の root になる。passwd が一般ユーザーから /etc/shadow を書き換えられるのはこの仕組みによる。
shared の drwxrwsr-x はグループ側の s、ディレクトリのsetgidだ。この下に作られたファイルは、作成者のプライマリグループではなくディレクトリのグループ staff を継承する。tmp の drwxrwxrwt は末尾の t、スティッキービットで、誰でも書けるディレクトリにおいて自分が所有していないファイルの削除と改名を禁じる。/tmp が1777なのはこのためだ。
特別ビットは8進数の4桁目に載る。setuidが4、setgidが2、スティッキーが1で、runner は4755、shared は2775、tmp は1777だ。
| 表示 | 位置 | 8進数 | 意味 |
|---|---|---|---|
| s | 所有者のx | 4000 | setuid。実効ユーザーIDが所有者になる |
| s | グループのx | 2000 | setgid。ディレクトリでは配下がグループを継承する |
| t | その他のx | 1000 | スティッキー。他人のファイルを消させない |
| S / T | 同じ位置の大文字 | 同上 | 特別ビットは立つが下地のxが無い状態 |
大文字の S や T は要注意で、特別ビットは立つのに下地の実行ビットが無い状態だ。-rwSr--r-- のsetuidは事実上機能せず、設定ミスの疑いが濃い。setuidに頼らず権限を分割する仕組みはLinuxケーパビリティにある。
第2列 — ハードリンク数
第2列は、そのinodeを指す名前がいくつあるかという数だ。ファイルの実体はinodeであり、名前は参照にすぎない。-s なしの ln で作るハードリンクは同格の名前をもう1つ増やす操作で、この数が0になって初めて実体が解放される。notes.md の 2 は別の名前がどこかにある証拠で、片方を rm しても中身は消えず数が1に減るだけだ。
ディレクトリの数字は別の理屈で決まる。tmp が 2 なのは、親からの tmp という登録と、自分自身の中の . の2本が最初から存在するためだ。子ディレクトリが増えるごとに、その子の中の .. が親を指すので1ずつ加算される。. の行が 5 なのは2+子3つで、実際 .git・shared・tmp が並ぶ。この数から2を引けばサブディレクトリの数がわかる。
第3列と第4列 — 所有者とグループ
第3列が所有者、第4列がグループだ。inodeに入っているのは数値のUIDとGIDで、ls が名前解決して文字列に直している。失敗すれば数字がそのまま出る。コンテナからホストのボリュームを見て見知らぬ数字が並ぶのはこれで、UIDに対応する名前がコンテナ内に無いだけだ。疑うなら ls -ln で数値のまま照合する。
第5列 — サイズ
通常ファイルの第5列はバイト単位のファイルサイズだ。ディレクトリの 4096 は中身の合計ではなく、エントリ表そのものに割り当てられたブロックの大きさで、最小1ブロックの4096バイトから始まり、エントリが入りきらなくなったときにだけ大きくなる。配下の実サイズを知りたいなら du -sh を使う。シンボリックリンクの current が 10 なのは、リンク先の文字列 releases/7 がちょうど10バイトだからで、リンク先のファイルサイズではない。
第6列 — 日時
第6列は既定で更新時刻、すなわちmtimeだ。GNU lsはこれが半年以内なら「月 日 時:分」、古ければ「月 日 年」と書式を変える。.env.example と runner だけ年で出ているのはこの切り替えで、時刻が消えても異常ではない。秒まで要るなら ls -l --time-style=full-iso を使う。inodeには3つの時刻が記録されている。
| 時刻 | 更新される条件 | lsでの出し方 |
|---|---|---|
| mtime | 中身を書き換えたとき | 既定 |
| atime | 中身を読んだとき | ls -lu |
| ctime | inodeが変わったとき。chmod、chown、リンク数の増減、改名など | ls -lc |
ctimeはcreate timeではなくchange timeで、作成時刻ではない。chmod しただけならmtimeは動かずctimeだけが変わるため、「中身は触っていないのに何かされた」を追うときはctimeを見る。作成時刻はファイルシステム次第で stat から見える。
第7列 — 名前、. と .. とリンク先
最後の列が名前だ。-a を付けたことで .env.example と .git が現れている。ドットファイルが隠れるのはファイルシステムの機能ではなく、ls が先頭ドットのエントリを既定で飛ばしているだけの慣習だ。
先頭2行の . と .. は、ディレクトリが必ず持つエントリで、それぞれ自分自身と親を指す。ルートでは .. が自分自身を指す。. と .. を省きたいなら ls -lA を使う。
シンボリックリンクの行にだけ矢印が続き、current -> releases/7 のように参照先の文字列が出る。これは登録された文字列そのままで、リンク先の存在は検証されない。壊れたリンクも同じ見た目になるため、ls -la だけでは切れているか判断できない。実体を見たいなら ls -laL で辿らせる。
つまずきやすい点
第一に、ディレクトリのサイズは中身の合計ではない。4096 は表そのものの大きさで、その下に何GBあろうと変わらない。配下を含む容量を知る道具は du、ファイルシステム全体は df であり、ls は最初からその質問に答えていない。
第二に、ディレクトリのハードリンク数。「なぜ空のディレクトリが2なのか」は . と親からの登録の2本と理解すればよく、異常ではない。逆にこの数が多いなら、サブディレクトリが隠れている。
第三に、rwxのディレクトリでの意味。ファイルと同じ字面でありながら、意味は別物だ。
| ビット | ファイルでの意味 | ディレクトリでの意味 |
|---|---|---|
| r | 中身を読める | 名前の一覧を取れる |
| w | 中身を書き換えられる | 中のエントリを作成・削除・改名できる |
| x | プログラムとして実行できる | 通り抜けて中のエントリのメタデータを引ける |
ここで効くのが x だ。ディレクトリの x はパスを通り抜ける権限で、無ければ中のファイル名を知っていても開けない。逆に r だけで x が無いと、名前は列挙できるのに ls -l が行ごとに権限エラーになる。列挙だけで足りる場面は稀で、実務では r と x をセットで扱う。
ファイルを削除できるかどうかは、そのファイル自身のパーミッションではなく、置かれているディレクトリの w と x で決まる。-r--r--r-- の読み取り専用ファイルでも、親ディレクトリに書き込めるなら消せてしまう。/tmp にスティッキービットが要る理由はここにある。
まとめ
ls -la の1行は、種別1文字と権限9文字、リンク数、所有者、グループ、サイズ、日時、名前に分かれ、そのほぼ全部がinodeの写しだ。r=4・w=2・x=1の足し算、特別ビットの4・2・1、ディレクトリではxが通行許可になること。押さえるのはこの3つでいい。あとはサイズと日時が「何のサイズ・何の時刻か」を毎回確かめれば、ls -la は雄弁な診断ツールになる。同じ流儀の設定ファイル編はnginx.confを1行ずつ解剖にある。
コマンド出力の読み方の記事ガイド
ls -la の出力を1列ずつ解剖を実務で読む
TL;DRは入口です。実際に選ぶ・使う段階では、何を解決するか、何と比較するか、導入後にどこで詰まるかまで見る必要があります。
解決すること
コマンド出力
比較で見る軸
難易度: advanced / カテゴリ: コマンド出力の読み方 / タグ数: 4
導入後に効く点
ディレクトリではrwxの意味が変わる。xは中に入って個々のエントリのメタデータを引く権限、rは名前一覧を読む権限、wはエントリの作成・削除の権限だ。ファイル自体の書き込み権限とは無関係に、親ディレクトリのwがあれば削除できる。
先に潰すリスク
用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。
- 難易度
- advanced
- カテゴリ
- コマンド出力の読み方
- タグ数
- 4
判断チェックリスト
- 自社の用途が「コマンド出力 / Linux」に近いか確認する。
- 強みである「先頭1文字はファイルの種別で、-は通常ファイル、dはディレクトリ、lはシンボリックリンクを表す。続く9文字は所有者・グループ・その他の3組に分かれ、r=4・w=2・x=1を足した値が8進数表記になる。rw-r--r--なら644だ。」が本当に評価軸になるか確認する。
- 注意点の「用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。」を運用で吸収できるか確認する。
- 公開値や仕様値は、対象プラン・対象機種・対象リージョンまで確認する。
- 既存システム、ID、ネットワーク、監視、バックアップとの接続方法を先に洗い出す。
- 小さく試してから、本番移行、権限設計、障害時手順、コスト監視を決める。