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:
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:
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 <magic> tag defines the rule to recognize PNG files by their contents. However, the <glob> tag defines the file extensions to determine the MIME type.
4. Linux Command-Line Tools
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.
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.