file Command Examples

Determine File Type and Content Classification

About file Command

The file command is a fundamental Linux utility that determines the type of a file by examining its contents, not just its extension. Unlike operating systems that rely solely on filename extensions, UNIX/Linux systems use magic numbers and content patterns to accurately identify files. This makes file an essential tool for system administrators, developers, and security analysts.

Originally developed in the early days of UNIX, the file command uses a sophisticated database of "magic numbers" - specific byte patterns that identify file types. It can recognize hundreds of file formats including executables, scripts, archives, images, documents, and data files. The command is particularly useful when dealing with files without extensions, suspicious files, or when verifying file integrity.

How file Command Works

The file command performs three types of tests in order:

  1. Filesystem tests: Checks if file is empty, a special file (device, socket), or a symbolic link
  2. Magic tests: Examines file contents for known magic numbers and patterns (from /usr/share/misc/magic)
  3. Language tests: If text, attempts to determine the language or character encoding

This multi-stage approach provides accurate file identification regardless of filename or extension.

Example 1: Basic File Type Identification
The simplest use of the file command is identifying the type of a single file. This works on any file regardless of whether it has an extension.
file document.pdf
document.pdf: PDF document, version 1.7, 25 pages
file image.jpg
image.jpg: JPEG image data, JFIF standard 1.01, resolution (DPI), density 72x72, segment length 16, baseline, precision 8, 1920x1080, components 3
file script.sh
script.sh: Bourne-Again shell script, ASCII text executable
file /bin/ls
/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]=2f15ad836be3339dec0e2e6a3c637e08e48aacbd, for GNU/Linux 3.2.0, stripped

Understanding Output Format:

  • Filename: The file command always shows the filename first, followed by a colon
  • File type: Primary classification (PDF document, JPEG image, shell script, executable)
  • Detailed info: Additional specifics like version, dimensions, architecture, encoding
  • PDF details: Version number and page count when available
  • Image details: Format, resolution, dimensions, color components
  • Script identification: Detects shell type from shebang line (#!/bin/bash)
  • Binary executables: Shows architecture (64-bit), format (ELF), linking type (dynamic), target platform
  • Magic database: All identification comes from pattern matching in /usr/share/misc/magic
Pro Tip: The file command doesn't care about file extensions. A file named "photo.txt" containing JPEG data will correctly be identified as a JPEG image, not a text file. This makes it invaluable for detecting misnamed or suspicious files.
Example 2: Check Multiple Files at Once
You can pass multiple filenames to the file command, and it will identify each one. This is useful for quickly surveying a directory's contents.
file report.docx data.csv backup.tar.gz notes.txt
report.docx: Microsoft Word 2007+ data.csv: CSV text backup.tar.gz: gzip compressed data, was "backup.tar", last modified: Mon Nov 04 15:30:22 2024, from Unix, original size modulo 2^32 10240000 notes.txt: ASCII text, with CRLF line terminators
file *
archive.zip: Zip archive data, at least v2.0 to extract, compression method=deflate config.json: JSON data database.db: SQLite 3.x database, last written using SQLite version 3040001, page size 4096, file counter 1, database pages 250, cookie 0x1, schema 4, UTF-8, version-valid-for 1 installer.exe: PE32+ executable (console) x86-64, for MS Windows photo.png: PNG image data, 2560 x 1440, 8-bit/color RGB, non-interlaced README.md: ASCII text, with very long lines (500) script.py: Python script, ASCII text executable spreadsheet.xlsx: Microsoft Excel 2007+ video.mp4: ISO Media, MP4 Base Media v1 [IS0 14496-12:2003]

Multiple File Inspection:

  • Batch processing: Single command checks all specified files
  • Wildcard support: Use * to check all files in current directory
  • Pattern matching: Can use *.txt, *.log, or other glob patterns
  • Office formats: Correctly identifies modern Office formats (docx, xlsx, pptx)
  • Compressed files: Shows compression method and original filename for archives
  • Text encoding: Detects line endings (CRLF for Windows, LF for Unix)
  • Database files: Identifies SQLite and other database formats with version info
  • Executables: Distinguishes between Windows PE and Linux ELF formats
Useful Pattern: To find all executable files in a directory: file * | grep executable. To find all text files: file * | grep text.
Example 3: Brief Output Mode (-b)
The -b (brief) option suppresses the filename, showing only the file type. This is useful for scripting or when processing file command output.
file -b image.png
PNG image data, 1920 x 1080, 8-bit/color RGBA, non-interlaced
file -b /usr/bin/python3
ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=abc123..., for GNU/Linux 3.2.0, stripped
for f in *.jpg; do echo "$f: $(file -b $f)"; done
photo1.jpg: JPEG image data, JFIF standard 1.01, resolution (DPI), density 72x72, baseline, precision 8, 3264x2448, components 3 photo2.jpg: JPEG image data, Exif standard: [TIFF image data, little-endian], baseline, precision 8, 4032x3024, components 3 photo3.jpg: JPEG image data, progressive, precision 8, 1920x1080, components 3

Brief Mode Applications:

  • Cleaner output: No filename prefix, just the file type information
  • Script-friendly: Easier to parse in shell scripts and automation
  • Variable assignment: TYPE=$(file -b filename) stores just the type
  • Conditional logic: Makes it easier to test file types in if statements
  • Report generation: Better for formatted output when you control the filename display
  • Piping: Simplifies pipeline operations where filename is redundant
  • Logging: Cleaner log entries when filename is already known from context
Scripting Example: Check if file is a PDF: if [[ $(file -b file.pdf) == PDF* ]]; then echo "Valid PDF"; fi
Example 4: MIME Type Output (-i)
The -i option outputs the MIME type instead of the human-readable description. This is essential for web development and email handling.
file -i document.pdf
document.pdf: application/pdf; charset=binary
file -i image.jpg
image.jpg: image/jpeg; charset=binary
file -i script.sh
script.sh: text/x-shellscript; charset=us-ascii
file -i index.html
index.html: text/html; charset=utf-8
file -i data.json
data.json: application/json; charset=utf-8
file -i archive.tar.gz
archive.tar.gz: application/gzip; charset=binary

MIME Type Information:

  • Standard format: MIME types follow RFC 2046 (type/subtype)
  • Charset included: Shows character encoding (utf-8, us-ascii, binary)
  • Web server config: Used to set Content-Type HTTP headers
  • Email attachments: Essential for proper email MIME encoding
  • application/*: Binary data, executables, archives, PDFs
  • text/*: Human-readable text in various formats
  • image/*: Image formats (jpeg, png, gif, svg)
  • video/*: Video formats (mp4, avi, webm)
  • audio/*: Audio formats (mp3, wav, ogg)
Web Development: Use with -b for clean MIME output: MIME=$(file -bi file.jpg) then set as Content-Type header in web responses. Essential for correct browser file handling.
Example 5: Follow Symbolic Links (-L)
By default, file reports on symbolic links themselves. The -L option makes file follow the link and report on the target file instead.
ls -l mylink
lrwxrwxrwx 1 user group 15 Nov 04 10:30 mylink -> /usr/bin/python3
file mylink
mylink: symbolic link to /usr/bin/python3
file -L mylink
mylink: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, stripped
ln -s /var/log/syslog loglink
file loglink
loglink: symbolic link to /var/log/syslog
file -L loglink
loglink: ASCII text

Symbolic Link Handling:

  • Default behavior: Reports link itself, shows target path
  • With -L flag: Follows link and reports on actual target file
  • Broken links: Without -L shows "symbolic link"; with -L shows error
  • Chain following: -L follows entire chain of links to final target
  • Security: Default behavior prevents issues with malicious links
  • Filesystem traversal: -L can cross filesystem boundaries
  • Use case: Essential when you need to know actual file type, not link type
  • Script safety: Be careful with -L in scripts processing untrusted links
Practical Use: When checking configuration files that might be symlinks: file -L /etc/localtime reveals it's a timezone data file, not just a link. Useful for debugging symlink chains.
Example 6: Recursive Directory Inspection
While file doesn't have a built-in recursive option, combining it with find creates a powerful tool for analyzing entire directory trees.
find /home/user/documents -type f -exec file {} \;
/home/user/documents/report.pdf: PDF document, version 1.4 /home/user/documents/data/sales.xlsx: Microsoft Excel 2007+ /home/user/documents/data/backup.tar.gz: gzip compressed data /home/user/documents/notes.txt: UTF-8 Unicode text /home/user/documents/scripts/deploy.sh: Bourne-Again shell script, ASCII text executable /home/user/documents/images/logo.png: PNG image data, 512 x 512, 8-bit/color RGBA /home/user/documents/.hidden_config: ASCII text
find . -type f -exec file -i {} \; | grep "image/"
./photos/vacation.jpg: image/jpeg; charset=binary ./graphics/banner.png: image/png; charset=binary ./icons/app_icon.svg: image/svg+xml; charset=us-ascii
find /var/log -name "*.log" -exec file {} \; | head -5
/var/log/syslog: ASCII text /var/log/auth.log: UTF-8 Unicode text /var/log/kern.log: ASCII text, with very long lines /var/log/dpkg.log: UTF-8 Unicode text /var/log/apache2/error.log: ASCII text

Recursive Analysis Patterns:

  • find + file combo: Most common pattern for recursive file type checking
  • -type f: Only process regular files, skip directories and special files
  • -exec file {} \; Runs file command on each found file
  • Filter by MIME: Pipe to grep to find specific file types
  • Hidden files: find catches hidden files (starting with .) that ls might miss
  • Log analysis: Useful for finding binary data in log directories
  • Security audits: Find executables: find . -exec file {} \; | grep executable
  • Performance: For many files, use find -exec file {} + (passes multiple files at once)
Security Audit: Find all executable files in home directory: find ~ -type f -executable -exec file {} \;. Look for unexpected scripts or binaries that might be malware.
Example 7: Reading from Standard Input (-)
The file command can read data from standard input using the special filename "-". This is useful for checking piped data or clipboard contents.
cat unknown_file | file -
/dev/stdin: ELF 64-bit LSB executable, x86-64, version 1 (SYSV)
curl -s https://example.com/data | file -
/dev/stdin: JSON data
echo "Hello World" | file -
/dev/stdin: ASCII text
base64 -d encoded.txt | file -
/dev/stdin: gzip compressed data, was "archive.tar", from Unix
wget -qO- https://cdn.example.com/image | file -
/dev/stdin: PNG image data, 1024 x 768, 8-bit/color RGBA, non-interlaced

Standard Input Processing:

  • Dash notation: Single "-" tells file to read from stdin instead of a file
  • Pipeline integration: Check file type before saving downloaded/processed data
  • URL content checking: Verify remote file type without downloading to disk first
  • Decode and check: Examine base64-encoded or compressed data in transit
  • Network security: Verify downloaded content matches expected type before execution
  • No temporary files: Avoids creating temp files just for type checking
  • Stream processing: Can check data mid-pipeline before further processing
  • /dev/stdin label: Output always shows /dev/stdin as the "filename"
Security Check: Before executing a downloaded script: curl -s https://site.com/install.sh | tee >(file -) | less. This shows file type AND lets you review content before running. Never pipe directly to bash without checking!
Example 8: Compressed File Inspection (-z)
The -z option attempts to look inside compressed files and report on their contents, not just the compression format.
file backup.tar.gz
backup.tar.gz: gzip compressed data, was "backup.tar", last modified: Mon Nov 04 15:30:22 2024, from Unix
file -z backup.tar.gz
backup.tar.gz: POSIX tar archive (GNU) (gzip compressed data, was "backup.tar", last modified: Mon Nov 04 15:30:22 2024, from Unix)
file script.sh.gz
script.sh.gz: gzip compressed data, was "script.sh", from Unix
file -z script.sh.gz
script.sh.gz: Bourne-Again shell script, ASCII text executable (gzip compressed data, was "script.sh", from Unix)
file -z document.pdf.bz2
document.pdf.bz2: PDF document, version 1.7 (bzip2 compressed data, block size = 900k)

Compressed File Analysis:

  • Double inspection: Reports both compression format and contents
  • Supported formats: Works with gzip, bzip2, compress, pack, and some others
  • Tar archives: Can see tar format inside gzip/bzip2 compression
  • Original filename: Often shows the pre-compression filename
  • Timestamp info: Displays compression date when available
  • Nested inspection: Looks at actual content without decompressing to disk
  • Performance: Slightly slower as it must decompress data in memory
  • Limitations: May not work with all compression formats (e.g., some zip variants)
Archive Verification: Quickly verify backup contents without extracting: file -z *.tar.gz. Useful for checking backup integrity and content type before restoration.
Example 9: Special Files and Devices
The file command can identify special files like devices, sockets, and FIFOs, which is useful for system administration and debugging.
file /dev/null
/dev/null: character special (1/3)
file /dev/sda
/dev/sda: block special (8/0)
file /dev/zero
/dev/zero: character special (1/5)
mkfifo testpipe
file testpipe
testpipe: fifo (named pipe)
file /var/run/docker.sock
/var/run/docker.sock: socket
file /proc/self/fd/0
/proc/self/fd/0: symbolic link to /dev/pts/0

Special File Types:

  • Character special: Device that handles data character-by-character (terminals, null, zero)
  • Block special: Device that handles data in blocks (hard drives, SSDs)
  • FIFO/Named pipe: Inter-process communication mechanism
  • Socket: Unix domain socket for local IPC (common for Docker, MySQL, etc.)
  • Major/minor numbers: Device identifiers shown in parentheses (major/minor)
  • /dev hierarchy: Most special files live in /dev directory
  • /proc filesystem: Virtual filesystem exposing kernel and process information
  • System debugging: Understanding special files is crucial for troubleshooting
System Investigation: Check all special files in /dev: file /dev/* | grep -E "(block|character|socket)". Useful for understanding device configuration and finding IPC sockets.
Example 10: Detecting File Encoding and Language
The file command can detect character encoding (ASCII, UTF-8, ISO-8859, etc.) and even attempt to identify the human language for text files.
file ascii_file.txt
ascii_file.txt: ASCII text
file utf8_file.txt
utf8_file.txt: UTF-8 Unicode text
file utf16_file.txt
utf16_file.txt: UTF-16 Unicode text, little-endian
file windows_file.txt
windows_file.txt: ASCII text, with CRLF line terminators
file spanish.txt
spanish.txt: UTF-8 Unicode text, with very long lines
file binary_data.dat
binary_data.dat: data
file mixed_content.txt
mixed_content.txt: UTF-8 Unicode text, with CRLF, LF line terminators

Encoding Detection Details:

  • ASCII text: Pure 7-bit ASCII characters (0-127), most basic encoding
  • UTF-8 Unicode: Modern standard supporting all characters, backward compatible with ASCII
  • UTF-16: Wide character encoding, common in Windows and Java
  • ISO-8859-*: Various single-byte encodings for different languages
  • Line terminators: CRLF (Windows \\r\\n), LF (Unix \\n), CR (old Mac \\r)
  • Mixed line endings: File has inconsistent line termination (often from editing across platforms)
  • Very long lines: Warning that file has lines exceeding typical length
  • "data" classification: Binary data that doesn't match any known text encoding
Cross-Platform Development: Check text file encoding before commits: file *.txt *.sh *.py. Mixing encodings or line endings causes issues in version control and cross-platform development. Convert with dos2unix or iconv.

Additional file Command Information

🔮 Magic Database

The file command's power comes from its "magic" database located in /usr/share/misc/magic. This database contains thousands of patterns that identify file types:

  • Magic numbers: Specific byte sequences at file start (e.g., 0x7F454C46 for ELF executables)
  • String patterns: Text signatures like "#!/bin/bash" for shell scripts
  • Compiled format: The .mgc file is compiled from human-readable magic files for speed
  • Custom magic: You can add custom patterns to ~/.magic for specialized detection
  • Update frequency: Updated with package updates to recognize new file formats
  • Viewing magic: See raw patterns with cat /usr/share/misc/magic

📊 Common File Type Recognition

Category Formats Detected Example Output
Documents PDF, DOC, DOCX, ODT, RTF PDF document, version 1.7
Images JPEG, PNG, GIF, BMP, TIFF, SVG, WebP PNG image data, 1920 x 1080
Archives tar, gz, bz2, xz, zip, rar, 7z gzip compressed data
Executables ELF, PE, Mach-O, scripts ELF 64-bit LSB executable
Audio MP3, WAV, FLAC, OGG, AAC, M4A Audio file with ID3 version 2.4.0
Video MP4, AVI, MKV, MOV, WebM, FLV ISO Media, MP4 Base Media v1
Databases SQLite, MySQL, PostgreSQL dumps SQLite 3.x database
Code C, Python, Perl, Shell scripts Python script, UTF-8 Unicode text

🛠️ Useful file Command Options

Option Description Use Case
-b Brief mode (no filename) Scripting, variable assignment
-i Output MIME type Web development, email headers
-L Follow symbolic links Check link targets, not links themselves
-z Look inside compressed files Archive content verification
-0 Use null character as separator Works with xargs -0 for filenames with spaces
-f file Read filenames from file Process large lists of files
-k Keep going, don't stop at first match Get multiple classification results
-s Read block/character special files Device content inspection (rarely used)

💡 Practical Use Cases

Security Analysis:

  • Detect files with misleading extensions: find . -name "*.txt" -exec file {} \; | grep -v "text"
  • Find hidden executables: file * | grep executable
  • Verify downloads: Check file type before opening/executing downloaded files
  • Malware detection: Identify suspicious files masquerading as documents

System Administration:

  • Log file analysis: Identify binary data in log directories
  • Backup verification: Confirm backup archives are valid before disaster strikes
  • Disk forensics: Identify files on recovered filesystems
  • Migration tasks: Inventory file types before data migration

Development:

  • Build verification: Ensure compiled outputs match expectations
  • Test data validation: Confirm test files are correct format
  • Cross-platform compatibility: Check line endings and encoding
  • Asset pipeline: Verify media files in web/mobile development

🔍 Troubleshooting Tips

Problem: file reports "data" for known file type

Solution: File may be corrupted, or it's a format not in the magic database. Try updating file: sudo apt update && sudo apt upgrade file. For proprietary formats, check vendor documentation.

Problem: Incorrect MIME type for web serving

Solution: file's MIME database may differ from web server's. Compare with mimetype command (from File::MimeInfo). Configure web server MIME types explicitly for critical formats.

Problem: file -z fails on some compressed files

Solution: Some compression formats not fully supported. Try zcat file.gz | file - or decompress manually to examine contents.

Problem: Performance issues with large files

Solution: file only reads first ~1MB by default. For huge files, it's already optimized. If processing many files, use find -exec file {} + (plus instead of semicolon) to batch process.

📚 Related Commands

  • mimetype: Alternative MIME type detection using different database
  • strings: Extract printable strings from binary files
  • xxd / hexdump: View raw binary data in hex format
  • stat: Display detailed file metadata (size, timestamps, permissions)
  • identify: Detailed image information (ImageMagick tool)
  • mediainfo: Comprehensive audio/video file analysis
  • binwalk: Firmware and embedded file system analysis
  • exiftool: Read and write EXIF metadata in images

🎓 Historical Context

The file command dates back to the earliest days of UNIX in the 1970s. It was created because UNIX doesn't rely on filename extensions to determine file type - the operating system needs a reliable way to identify file contents regardless of naming. The "magic number" concept comes from the practice of putting special byte sequences at the beginning of files to identify their type.

The magic database has grown from a few dozen patterns to thousands, reflecting the explosion of file formats over five decades. Modern implementations include support for character encoding detection, MIME types, and specialized formats. The file command remains an essential tool for system administrators, security analysts, and anyone working with files in UNIX/Linux environments.