file コマンド入門 - 拡張子に頼らずファイル種別を見抜く
この記事でわかること
fileコマンドが 拡張子ではなく中身を見て ファイル種別を判定する仕組み- 拡張子を書き換えても
fileが 本当の正体を見抜く 理由 file -iで MIME タイプ を調べる方法-bや圧縮ファイル対応など よく使うオプション
結論(先に要点)
file ファイル名で、そのファイルが何者かを一発で判定できる- 判断材料は 拡張子ではなく中身の先頭バイト列(マジックナンバー)
- 拡張子を
.txtに変えても、中身が JPEG ならfileは JPEG と答える
前提(対象環境)
- OS: Ubuntu / 一般的な Linux
fileは標準でインストール済み(coreutilsとは別パッケージfile)
1. file コマンドとは?拡張子と何が違う?
結論:
fileはファイルの中身を読んで種別を判定するコマンド。拡張子という「自己申告」ではなく、実体で判断する。
photo.jpg みたいに拡張子を見ればわかりますよね?file は中身そのものを読んで判定するコマンドだよ。file はそこを読んでいる。file report.pdf
report.pdf: PDF document, version 1.7
file の判定は /usr/share/misc/magic(コンパイル済みは magic.mgc)に登録されたパターン集(libmagic)に基づく。何千もの形式の目印が登録されている。
2. なぜ拡張子は当てにならないのか?
結論: 拡張子は名前の一部にすぎず、中身を保証しない。
fileは中身で判断するため、偽装された拡張子に騙されない。
.txt にしてしまった場合。Windows からもらったファイルで拡張子が消えている場合もある。そんなとき中身を確認したいよね。.txt に変えてみますね。mv penguin.jpg penguin.txt file penguin.txt
penguin.txt: JPEG image data, JFIF standard 1.01, resolution (DPI), 72x72
.txt なのに、ちゃんと JPEG だって見抜いた!3. file コマンドの基本的な使い方は?
結論:
file ファイル名が基本形。複数指定やワイルドカードで、まとめて種別を確認できる。
* でまとめても判定してくれるよ。file notes.txt file *
notes.txt: ASCII text archive.tar.gz: gzip compressed data, original size modulo 2^32 10240 script.sh: Bourne-Again shell script, ASCII text executable image.png: PNG image data, 800 x 600, 8-bit/color RGBA, non-interlaced
ディレクトリやシンボリックリンク、空ファイルもそれぞれ directory / symbolic link to ... / empty と表示される。
4. MIME タイプを調べるには?(-i)
結論:
file -iでtext/plain; charset=utf-8のような MIME タイプと文字コードを取得できる。スクリプトでの判定に向く。
text/plain みたいな表記は、file で出せますか?-i(--mime)を付けると MIME タイプ形式で出る。プログラムから扱いやすい形だよ。文字コード(charset)も一緒に表示される。file -i notes.txt file -i report.pdf
notes.txt: text/plain; charset=utf-8 report.pdf: application/pdf; charset=binary
MIME タイプだけ・文字コードだけが欲しいときは --mime-type / --mime-encoding を使う。
file --mime-type photo.png
photo.png: image/png
5. よく使うオプションは?
結論:
-b(ファイル名省略)、-L(リンク先を辿る)、-z(圧縮の中身)、-s(デバイスファイル)あたりを押さえれば十分。
| オプション | 意味 |
|---|---|
-b / --brief |
ファイル名を出力せず種別だけ表示 |
-i / --mime |
MIME タイプ形式で出力 |
-L |
シンボリックリンクのリンク先を判定 |
-z |
圧縮ファイルの中身まで覗いて判定 |
-s |
ブロック / キャラクタデバイスを読んで判定 |
-k |
最初の一致で止めず候補を出し続ける |
-b はどんなときに便利ですか?-b が楽だよ。file -b script.sh
Bourne-Again shell script, ASCII text executable
-z を使うと .gz などを展開せずに「中身が何の圧縮か+元ファイルの種別」まで確認できる。
file -z logs.tar.gz
6. 実務ではどんな場面で使う?
結論: ダウンロードファイルの正体確認、テキストかバイナリかの判別、展開前のアーカイブ確認などで活躍する。
curl で落としたファイルが本当に目的のものか確認するとき。HTML のエラーページが落ちてきていないか file で一発チェックできる。curl -sL https://example.com/app.tar.gz -o app.tar.gz file app.tar.gz
app.tar.gz: gzip compressed data, ...
ここで HTML document と出たら、アーカイブではなくエラーページを落としている。展開前に気づけるのが file の価値。
7. つまずきやすいポイントは?
結論:
fileの判定は推定であり 100% ではない。シンボリックリンクは-L、デバイスファイルは-sを忘れると意図と違う結果になる。
file の出力はあくまで 推定。マジックナンバーを持たない独自形式や、内容が短すぎるファイルは data や ASCII text と曖昧に出ることがある。重要な判定は他の手段(stat / チェックサム等)と併用する。
file したら、リンクそのものの情報しか出ませんでした。-L を付ける。file -L /usr/bin/python3
8. ミニ課題
結論: 手を動かすと定着する。拡張子を変えても
fileが見抜くことを自分で確かめよう。
やってみよう
- 適当なテキストを作る:
echo "hello" > sample.txt - 種別を確認:
file sample.txt - 名前を変える:
mv sample.txt sample.bin - もう一度判定:
file sample.bin—— 拡張子が変わっても結果はどうなる?
解答例
sample.bin: ASCII text と表示される。中身は変わっていないので、file の判定(ASCII text)も変わらない。拡張子に依存していない証拠。