1. Overview

The MIME type is an important topic in web technology.

In this tutorial, we are going to discuss what a MIME type is and learn how to get the MIME type of a file using Linux command-line utilities.

2. MIME Types

The abbreviation MIME stands for Multi-purpose Internet Mail Extensions. MIME types form a standard way of classifying file types on the internet.

First, let’s have a look at a common MIME type for an example:

text/html

A MIME type consists of two parts: a type and a subtype.

In this example, the type is “text“, and the subtype is “html“.

Currently, there are ten registered types: application, audio, example, font, image, message, model, multipart, text, and video.

Let’s see some other common MIME types:

multipart/form-data
text/xml
text/csv
text/plain
application/xml
application/zip
application/pdf

In MIME types, the type and subtype are case-insensitive.

A subtype usually consists of a media format, such as “xml” or “pdf” in the above example. However, it can contain other content as well, such as a tree prefix or suffix, depending on the different rules in registration trees.

A complete MIME type format looks like:

type "/" [tree "."] subtype ["+" suffix]

Let’s see another MIME type example:

application/vnd.api+json

This is an API-specific MIME type, and it refers to JSON API.

In this example, we have “application” as the type and “api” as the subtype. The “vnd.” is the vendor prefix while the “+json” is the suffix, indicating that it can be parsed as JSON.

3. Determine the MIME Type of a File

The MIME type provides a standard way to name a type. However, the MIME type of a file is not stored on the Linux filesystem.

There are two ways to determine the MIME type of a file:

  • Looking at the file extension
  • Looking at the file content

Next, let’s take a look at two ways to determine the MIME type of a file.

3.1. By File Extension

A MIME type can sometimes be determined by the extension, but not always.

If a file doesn’t have an extension or has an incorrect extension, we cannot determine the MIME type by the file extension. For example, we can rename a JPG image file so that it has a ZIP file extension.

3.2. By File Content

Another way to get the MIME type of a file is by reading its content.

We can determine the MIME type according to specific characteristics of the file content. For example, a JPG starts with the hex signature FF D8 and ends with FF D9.

This is slower than the file extension approach due to the extra I/O efforts. However, it can be more reliable.

3.3. Combining the Two Ways

In the real world, programs often use a combination of the two ways to determine the MIME type of a file. For example, the shared-mime-info by freedesktop.org maintains a MIME-type database and allows other programs, such as GNOME, KDE, and Xfce, to use this database to find the corresponding MIME types by file extensions or contents.

Let’s see an example of the MIME type “image/png“defined in shared-mime-info:

<?xml version="1.0" encoding="UTF-8"?>
<mime-info xmlns="http://www.freedesktop.org/standards/shared-mime-info">
    <mime-type type="image/png">
        <comment xml:lang="en">PNG image</comment>
        <comment xml:lang="af">png beeld</comment>
        ...
        <magic priority="50">
            <match type="string" value="\x89PNG" offset="0"/>
        </magic>
        <glob pattern="*.png"/>
    </mime-type>
</mime-info>

In the above “image/png” example, the tag defines the rule to recognize PNG files by their contents. However, the tag defines the file extensions to determine the MIME type.

4. Linux Command-Line Tools

Now, let’s see how we can get the MIME type of a file using Linux command-line tools. In this section, we’ll see two utilities: the file command and the xdg-mime command.

4.1. The xdg-mime Command

The xdg-mime command is a member of the xdg-utils package from freedesktop.org. This package is preinstalled in almost all Linux distros with a desktop environment.

The xdg-mime command uses the shared-mime-info database to determine MIME types. It will first try to recognize the MIME type by file extension. If it fails, it will look at the content of the file.

The syntax of using the xdg-mime command to get the MIME type of a file is:

xdg-mime query filetype INPUT_FILE

Let’s prepare a JPG image file (onePicture.jpg) and see if the xdg-mime command can get the MIME type:

$ xdg-mime query filetype onePicture.jpg
image/jpeg

Next, let’s play a little trick with the xdg-mime command. Let’s change the file extension and see what result the xdg-mime command will give us:

$ mv onePicture.jpg onePicture.zip

$ xdg-mime query filetype onePicture.zip
application/zip

Oops! The xdg-mime command tells us a wrong MIME type. This is because the xdg-mime command first attempts to find a MIME type by file extension in the database.

Now, let’s remove the file extension entirely and see what happens:

$ mv onePicture.zip onePicture

$ xdg-mime query filetype onePicture
image/jpeg

We get the correct result again. This is because if the xdg-mime command cannot find a MIME type by file extension, it will then try to find the MIME type by the file content.

4.2. The file Command

Most free operating systems, such as FreeBSD and Linux, ship with the file command by default. We’ll use the command with the option –mime-type to get the MIME type of a file.

Let’s see if the file command can get the MIME type of the same JPG file:

$ file --mime-type onePicture.jpg
onePicture.jpg: image/jpeg

Now, let’s do the same change on the file extension and see if the file can still report the right result:

$ mv onePicture.jpg onePicture.zip

$ file --mime-type onePicture.zip
onePicture.zip: image/jpeg

Great! Even if we try to trick the file command by changing the file extension, it can still tell the correct MIME type. This is because the file command doesn’t rely on file extensions to determine file MIME types. Instead, it looks at the actual file contents. Therefore, it is more reliable in this case.

Finally, we delete the file extension and hope the file command can still work correctly:

$ mv onePicture.zip onePicture

$ file --mime-type onePicture
onePicture: image/jpeg

As we expected, it gives the right result again.

5. Conclusion

In this article, we talked about what is a MIME type and how a MIME type is named. Then, we discussed the common approaches to determine the MIME type of a file in Linux.

Finally, we learned two Linux commands to get the MIME type of a file: the file and xdg-mime commands. Through some examples, we discussed why the two commands could behave differently on the same file.