Home / Alt manpages / mimetype(1p)

  • mimetype(1p)
  • POSIX command
  • linux

Identify File Types Reliably with mimetype

You will finish with a practical way to identify a file's MIME type, check its contents when the name is untrustworthy, and produce predictable output for a shell script. 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 rather than 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

The default output includes the filename, a colon separator and the MIME type. The database can use both the name and the file's contents. The exact result depends on the installed shared MIME-info data, so compare the type with 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 examines 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 why a name-based match can be deceptive. The second is the content-based result. Copying the file creates temporary state, so remove these two example files when 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

For a script that only needs the type, --brief removes the filename:

$ mimetype --brief /path/to/input
text/plain

For a human-facing report, --describe prints the database description instead of the MIME type:

$ mimetype --describe /tmp/mimetype-sample.txt
/tmp/mimetype-sample.txt: Plain text document

Use --mimetype to select types explicitly. It is the default unless file compatibility mode is active. A custom separator is useful when another program consumes the filename and type as two fields:

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

Notice that this output contains two spaces after the separator on this installed version. If you need 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 the filename, %m for the MIME type and %d for the description. Alignment is not available with this format, which is useful when you want to avoid parsing padding.

4. Inspect standard input

Use --stdin when the 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. In particular, it cannot use the input's filename. The manpage also records an IO::Scalar dependency for this option; if your installation reports that the module is missing, repair the package installation or use a readable temporary file instead.

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, with 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

The names from that file are read before any paths written directly on the command line. Treat the list as data, not shell syntax: mimetype does not expand wildcards inside it. Delete the temporary list after checking it 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 option on untrusted input. It does not modify either path.

An empty type or description usually means that 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. Verify a status immediately after the command:

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

If you need to understand a surprising result, add --debug. Debug output is for investigation, not for a stable parser. Use --language=CODE with a two-letter language code when you need a localised description, and remember that an unavailable translation can produce an empty description.

Done means

  • You can identify a normal file and recognise the filename-plus-type output.
  • You can use --magic-only when an extension may be false.
  • You can select brief, descriptive or explicitly formatted output for the consumer.
  • You know that standard input uses content magic and cannot use a filename.
  • You can follow a symbolic link deliberately and check the command status immediately.