Linux / コマンド / file - ファイルの種類と形式の確認

fileは、ファイルの拡張子だけでなく、ファイルシステム情報、内容の固有のバイトパターン、テキストの特徴を検査してファイル形式を推定するコマンドです。名前が間違っているファイルや拡張子がないファイルでも、実際の形式、実行ファイルの種類、文字エンコーディング、データ形式を表す MIME(Multipurpose Internet Mail Extensions)タイプを確認できます。

この記事では、基本的な使い方からMIME出力、シンボリックリンクや圧縮ファイルの処理、複数ファイルの検査、シェルスクリプトの活用および結果解釈時の注意点について説明します。

fileコマンドとは?

fileは、引数として受け取った各パスを検査し、人が読みやすいファイルの種類の説明を表示します。

file README.md
file photo.jpg
file /usr/bin/ls

結果はシステム、fileのバージョン、および判定ルールを集めた magic データベースによって少しずつ異なる場合があります。一般的な出力形式は次の通りです。

README.md: Unicode text, UTF-8 text
photo.jpg:  JPEG image data, JFIF standard 1.01
/usr/bin/ls: ELF 64-bit LSB pie executable, x86-64, dynamically linked

fileは内容を変更せずに読み取り、分類します。ただしファイルにアクセスする権限が必要であり、検査方式によってアクセス時間が更新されることがあります。

fileがファイル形式を判別する原理

一般的なfileの実装は、次の検査を順番に実行し、最初に成功した検査結果を基本説明として使用します。

  1. ファイルシステムの検査: ディレクトリ、シンボリックリンク、ソケット、先入れ先出し方式の名前付きパイプ(FIFO)、空のファイルなどの種類をメタデータで確認します。
  2. マジック検査: ファイルの特定の位置にある固有のバイトパターンをマジックデータベースと比較します。
  3. テキストと言語の検査: 文字エンコーディングと内容の特徴からテキスト形式や作成言語を推定します。

PNG、JPEG、PDF や ELF(Executable and Linkable Format)実行ファイルのように形式に固定された識別情報があるファイルは、拡張子がなくても分類できます。一方、固有のパターンがない場合や内容が短すぎて曖昧な場合は、単にdataと表示されることがあります。

基本的な文法と使い方

以下の名前は例なので、読み取り権限がある自分の実在するファイルに置き換えてください。ELF の出力例は Linux の実行ファイルの例であり、アーキテクチャ・実装・対象ファイルによって結果は変わります。

file [オプション] ファイル ...

ファイル1つだけでなく、複数のパスを一度に検査することもできます。

file report.pdf
file image.png archive.tar.gz script.sh
file /etc /dev/null /usr/bin/env

空白やシェル特殊文字が含まれるパスは引用符で囲み、ハイフンで始まるファイル名の前にはオプション終了表示--を使用します。

file "annual report.pdf"
file -- -sample.bin

インストール済みのバージョンとサポートされているオプションは、次のコマンドで確認できます。

file --version
file --help
man file

拡張子と実際のファイル形式を比較する

拡張子がなくても形式を確認する

Linuxの実行ファイルやコマンドスクリプトには拡張子がない場合が多いです。fileは名前の代わりに内容を検査するので、形式を確認できます。

file /usr/bin/bash
file /usr/bin/python3
file ./run-backup

スクリプトにシバン(shebang、先頭の #! でインタプリタを指定する行)がある場合、インタプリタ情報が結果に含まれることがあり、コンパイル済みプログラムではELF形式やアーキテクチャ、動的リンクの有無などが表示されることがあります。

拡張子が間違っているファイルを確認する

ダウンロードしたり受け取ったファイルの拡張子が実際の内容と一致しない場合にも有用です。

file download.dat
file attachment.bin

結果が画像や圧縮形式を示していても、名前は自動で変更されません。必要なプログラムや業務ルールを確認したうえで、拡張子を決めてください。

よく出る結果の解釈

代表的な表現 意味
directory 一般ファイルではなくディレクトリです。
symbolic link to ... 他のパスを指すシンボリックリンクです。
empty サイズが0バイトの空の一般ファイルです。
ASCII text 主にASCII範囲の印刷可能な文字で構成されたテキストです。
Unicode text, UTF-8 UTF-8でエンコードされたユニコードテキストと判断されました。
ELF ... executable Linuxなどで使用されるELF形式の実行ファイルです。
shared object 共有ライブラリまたは位置独立実行形式と判断される場合があります。
data 既知の形式やテキストでは十分に識別できなかったバイナリデータです。
cannot open パスがないか権限などによりファイルを開くことができませんでした。

結果はファイルの信頼性や安全性を保証するものではありません。特定の形式として認識されたという事実と、マルウェアが存在しないという判断は別の問題です。

MIMEタイプと文字エンコーディングを確認する

-iでMIMEタイプとエンコーディングを一緒に表示

-iまたは--mimeは、人が読む長い説明の代わりにMIMEタイプと文字エンコーディングを出力します。

file -i index.html
file --mime README.md

テキストファイルは次のようにMIMEタイプとcharsetが一緒に表示されることがあります。

index.html: text/html; charset=utf-8

タイプまたはエンコーディングだけを表示する

--mime-typeはMIMEタイプのみ、--mime-encodingはエンコーディング情報のみを表示します。

file --mime-type image.webp
file --mime-encoding README.md

ファイル名なしで値だけが必要な場合は、-bを一緒に使用します。

file -b --mime-type image.webp
file -b --mime-encoding README.md

ウェブサーバー設定やアップロードチェックで参考にできますが、クライアントが送信したMIME値やfileの結果だけでファイルが安全であると判断してはいけません。

出力でファイル名と整列間隔を調整する

-bで説明だけを出力する

基本出力はファイル名: 説明形式です。-bまたは--briefはファイル名の接頭辞を省略します。

file -b archive.tar.gz
file -b --mime-type photo.jpg

スクリプト変数に結果だけを保存する場合に便利です。

-Nと-Fで複数ファイルの出力を整える

複数のファイルをチェックすると、ファイル名が同じ幅に揃えられることがあります。-Nはこの余白を削除し、-Fはファイル名と結果の間の区切りを変更します。

file -N file1 file-with-long-name.bin
file -F ' => ' file1 file2

ファイル名に区切り文字や改行が含まれる可能性がある自動化では、人が読む出力形式を直接解析するよりも、NUL区切りオプションと安全なファイルリスト処理を検討してください。

シンボリックリンクを確認する

リンク自体を確認する

通常は シンボリックリンクをたどらず、リンク自体と対象を表示します。この動作を明示するには、-hまたは--no-dereferenceを使用します。

file -h current.log

環境変数POSIXLY_CORRECTの設定によって基本動作が変わる可能性があるため、スクリプトでは必要なオプションを明示する方が安全です。

-Lでリンク先を確認する

-Lまたは--dereferenceはシンボリックリンクをたどり、実際の対象ファイルの形式を検査します。

file -L current.log
file --dereference latest-image

壊れたリンクは対象ファイルを開けないため、リンクまたはエラーに関する結果が表示されます。

圧縮ファイルと内部データを検査する

基本状態で圧縮形式を確認する

オプションなしで検査すると、通常 gzip、xz、bzip2 などの外側の圧縮形式を説明します。

file backup.tar.gz
file archive.xz

-z で圧縮を解凍して内部形式を確認する

-z または --uncompress は、サポートされている圧縮形式のデータを解凍して内部内容も検査します。

file -z backup.tar.gz
file --uncompress archive.xz

解凍過程には追加の時間とリソースが必要です。出所が信頼できない大容量ファイルや圧縮爆弾の可能性があるファイルは、隔離された環境と別の制限ポリシーで扱う必要があります。

複数のファイルとファイルリストを検査する

シェルのグロブで複数ファイルを指定する

現在のディレクトリの特定の拡張子ファイルを一度に検査することができます。

file *.jpg
file *.sh

globと一致するファイルがない場合、シェルの設定によってはパターン文字列がそのまま渡されることがあります。ファイル名が非常に多い場合、コマンドラインの長さ制限を超える可能性もあります。

-fでファイル名のリストを読み込む

-fまたは--files-fromは1行に1つずつ書かれたパスの一覧を読み込んで検査します。

file -f files-to-check.txt
file -F ' => ' -f files-to-check.txt

-fは該当オプションに出会った時点でリストを処理するため、-Fのように出力に影響を与えるオプションは前に配置する必要があります。

標準入力とfindの結果を検査する

標準入力のデータ形式を確認する

ファイル名としてハイフン一つ-を指定すると、標準入力からデータを読み込みます。

printf '%s\n' 'hello' | file -

標準入力は再度読み込むことが難しい場合があるため、実際のファイルを検査した場合と結果の詳細度が異なることがあります。

find -execで再帰検査する

サブディレクトリまで一般ファイルを再帰的に検査するには、findと組み合わせることができます。

find ./uploads -type f -exec file -- {} +

{} +は見つけたパスを可能な範囲でまとめてfileに渡し、スペースが含まれるファイル名も安全に処理します。検査対象が多い場合は、パスと深さを制限してください。

シェルスクリプトでMIMEタイプを活用する

ファイル名なしで MIME タイプだけを受け取り、条件分岐できます。この file の通常設定では、存在しないパスのエラーを結果として出力し、終了状態が成功になることがあります。以下は -E と終了状態の確認を使い、読み取り失敗と形式の分岐を分けています。検査用コピーを upload.bin として同じディレクトリに用意し、コードを check-image-type.sh として保存して bash check-image-type.sh で実行します。対応する画像ならメッセージを表示し、非対応形式または読み取り失敗なら状態 1 で終了します。

path='upload.bin'
mime_type=$(file -E -b --mime-type -- "$path") || {
  printf '%s\n' 'ファイル形式を確認できませんでした。' >&2
  exit 1
}

case "$mime_type" in
  image/jpeg|image/png|image/webp)
    printf '%s\n' 'サポートされている画像形式です.'
    ;;
  *)
    printf '%s\n' "サポートされていない形式: $mime_type" >&2
    exit 1
    ;;
esac

この検査は高速な分類に便利ですが、セキュリティ検証の代わりにはなりません。実際のアップロード処理では、ファイルサイズ制限、安全なデコーダ、保存パスの分離、実行権限の削除と必要に応じたマルウェア検査を併用する必要があります。

主なオプションまとめ

オプション 説明
-b, --brief 出力でファイル名の接頭辞を省略します。
-i, --mime MIMEタイプと文字エンコーディングを出力します。
--mime-type MIMEタイプのみを出力します。
--mime-encoding 文字エンコーディング情報のみを出力します。
-L, --dereference シンボリックリンクをたどって対象ファイルを検査します。
-h, --no-dereference シンボリックリンクをたどらずにリンク自体を確認します。
-z, --uncompress サポートされている圧縮ファイルを解凍し内部形式も検査します。
-k, --keep-going 最初の一致の後も他のmagic一致を続けて検査します。
-f ファイル 指定したファイルから検査するパスの一覧を読み取ります。
-F 文字列 ファイル名と結果の間の区切り文字を変更します。
-N, --no-pad 複数の結果のファイル名の整列のための余白を削除します。
-p, --preserve-date サポートされているシステムで、検査前のファイルアクセス時間を保持しようとします。
-s, --special-files ブロック・文字デバイスのような特殊ファイルも読み取って検査します。デバイスアクセスのリスクを理解している場合のみ使用します。
-E ファイルシステムエラーを通常の結果として処理し続けず、エラーメッセージと失敗状態で終了させます。
-- オプション処理を終了し、ハイフンで始まるファイル名を安全に渡します。

file 結果を使用する際の注意点

判定結果は推定値です

fileは既知のパターンとヒューリスティックに基づいて分類します。破損したファイル、新規または珍しい形式、複数の形式が混在するファイルは、あいまいな結果や予想と異なる結果が出ることがあります。

ファイル形式と安全性は異なります

画像や文書として識別されても、内部に悪意のあるデータがないという意味ではありません。セキュリティ境界では、拡張子、MIMEタイプ、magic判定を併せて参照しつつ、専用パーサーとポリシーベースの検証を使用する必要があります。

特殊ファイルや大容量入力に注意する

-sでデバイスファイルを読み取ったり、-zで圧縮データを検査すると、通常のファイル検査よりもリスクとコストが大きくなる可能性があります。対象の出所とサイズを確認し、最小権限で実行してください。

FAQ

fileコマンドはファイル拡張子を確認しますか?

主要な判定は、ファイルシステム情報と内容のmagicパターン、文字エンコーディング、およびテキスト特性を利用します。したがって、拡張子がない、または間違っていても、実際の内容に基づいて形式を推定できます。

MIMEタイプだけをファイル名なしで出力するにはどうすればよいですか?

file -b --mime-type ファイル名を使用します。-bはファイル名の接頭辞を省略し、--mime-typeはMIMEタイプのみを選択します。

シンボリックリンク先のファイル形式を確認するにはどうすればいいですか?

file -L リンク名を使用します。リンク自体の情報を確認するにはfile -h リンク名を使用してください。

fileの結果がdataだけになる理由は何ですか?

magicデータベースと一致する既知のパターンがなく、テキストとしても判別されなかった可能性があります。ファイルが破損しているか、内容が短すぎるか、インストールされたmagicデータベースがその形式を認識できない場合があります。

参考資料