Home / Alt manpages / mimetype(1p)

  • mimetype(1p)
  • POSIX command
  • linux

Identify File Types Reliably with mimetype

mimetype tells you what a file actually is, which matters the moment its extension is lying to you. This guide covers checking content over filename, producing compact output for a script, and reading from a pipe or a list of names. The examples use mimetype 0.34 from the Debian package libfile-mimeinfo-perl 0.34-1.

Allow about ten minutes. You need a shell and a readable file. The normal checks are read-only and do not need sudo. This command consults the shared MIME-info database, so a missing or inaccessible database is an environment problem, not a reason to guess from a filename.

1. Check one file in the normal mode

Run mimetype with the path you want to inspect:

$ mimetype /tmp/mimetype-sample.txt
/tmp/mimetype-sample.txt: text/plain

Default output is the filename, a colon, then the MIME type. The database can use both the name and the file's contents, so the exact result depends on the installed shared MIME-info data; compare the type against what the file is actually expected to contain.

Checkpoint

Repeat the command with a real path, not the example path. If the command cannot read the file or the database, keep the error text for diagnosis rather than treating an empty result as a useful type.

2. Ignore a misleading extension

Use --magic-only when the suffix is not trustworthy. It disables checks based on extensions, globs and inode type, and looks at content magic instead:

$ cp /tmp/mimetype-sample.txt /tmp/mimetype-sample.png
$ mimetype /tmp/mimetype-sample.png
/tmp/mimetype-sample.png: image/png
$ mimetype --magic-only /tmp/mimetype-sample.png
/tmp/mimetype-sample.png: text/plain

This example deliberately gives plain text a misleading .png name: the first result shows how a name-based match can be deceived, the second is the content-based answer. Copying the file creates temporary state, so clean it up once you have finished:

$ rm -- /tmp/mimetype-sample.txt /tmp/mimetype-sample.png

That cleanup is safe only for the example paths; do not substitute a directory or a path you have not checked.

3. Choose a compact output form

  • --brief drops the filename, for a script that only needs the type.
  • --describe prints the database description instead of the MIME type, for a human-facing report.
  • --mimetype selects types explicitly; it is the default unless file compatibility mode is active.
$ mimetype --brief /path/to/input
text/plain
$ mimetype --describe /tmp/mimetype-sample.txt
/tmp/mimetype-sample.txt: Plain text document

A custom separator helps when another program consumes the filename and type as two fields:

$ mimetype --separator=' | ' /tmp/mimetype-sample.txt
/tmp/mimetype-sample.txt |  text/plain

Note the double space after the separator on this installed version. For a strict machine-readable format, use --output-format instead:

$ mimetype --output-format='%f|%m|%d' /tmp/mimetype-sample.txt
/tmp/mimetype-sample.txt|text/plain|Plain text document

The supported substitutions are %f for filename, %m for MIME type and %d for description. There is no alignment with this format, which helps you avoid parsing padding.

4. Inspect standard input

Use --stdin when content arrives through a pipe rather than a path:

$ printf 'plain text\n' | mimetype --stdin
STDIN: text/plain

Standard-input detection uses magic typing only, and is less powerful than checking a normal file because it cannot use a filename. The manpage also records an IO::Scalar dependency for this option; if your installation reports the module missing, repair the package install or use a readable temporary file instead.

Warning

Do not pipe secrets into a diagnostic command on a shared system. The content is being inspected by a process, and a verbose or debug run may reveal details about how the result was reached.

5. Read many paths from a name file

Use --namefile when a list of paths already exists, one name per line:

$ printf '%s\n' /path/to/first /path/to/second > /tmp/mimetype-names
$ mimetype --namefile /tmp/mimetype-names
/path/to/first: text/plain
/path/to/second: application/octet-stream

Names from that file are read before any paths given directly on the command line. Treat the list as data, not shell syntax: mimetype does not expand wildcards inside it. Delete the temporary list afterwards if it contains private paths:

$ rm -- /tmp/mimetype-names

A symbolic link is classified as a link by default. Add --dereference to follow it and inspect its target:

$ ln -s /path/to/input /tmp/mimetype-link
$ mimetype /tmp/mimetype-link
/tmp/mimetype-link: inode/symlink
$ mimetype --dereference /tmp/mimetype-link
/tmp/mimetype-link: text/plain
$ rm -- /tmp/mimetype-link

Following a link reads the target, so check the target path before using this on untrusted input; it modifies neither path.

An empty type or description usually means the file does not exist, its name matched no known glob, or no description is available in the requested language. The command is also documented to return a non-zero status for command-line errors, missing dependencies or an inaccessible database, so check it straight after the run:

$ mimetype --magic-only /path/to/input
$ status=$?
$ printf 'mimetype exit status: %s\n' "$status"

If a result surprises you, add --debug: it is for investigation, not for a stable parser. Use --language=CODE with a two-letter language code for a localised description, and remember an unavailable translation can produce an empty one.

Done means

  • Normal identification works. You recognise the filename-plus-type output.
  • Extensions distrusted correctly. You use --magic-only when a suffix could be false.
  • Output shaped for the consumer. You can pick brief, descriptive or explicitly formatted output.
  • Standard input understood. It uses content magic only and cannot use a filename.
  • Links handled deliberately. You dereference on purpose and check the exit status straight away.