Every Linux File Has an Execute Bit. Here’s What That Means


Summary

  • The execute bit determines whether or not permission is granted to run a file as a program or script.
  • Setting the execute bit on a directory decides access ability, permitting entry and access to files.
  • Understanding and manipulating file permissions using commands like stat and chmod are essential for Linux users.

The basic Linux file permission system is simple and robust, and it’s no surprise that it’s survived intact for over 50 years. But the execute bit is a confusing element, one that is worth understanding in detail.

What Is the Execute Bit and How Can I See What It Is?

Every file on a Linux system has a set of permissions that control what can be done with it: can it be read, written, or executed? There are three levels of user, each with its own set of permissions: the owner of the file (user), members of the group that owns the file, and everyone else (other). These three actions and three types of users give us a total of nine permissions for each file:

An example of Linux file mode, as reported by ls. Nine letters, in groups of three, represent whether the user, group, or other can read, write, or execute the file.

Remember that, on Unix & Linux, directories are files too. They have the same permission data as other files, although the meanings of these permissions are slightly different.

The read and write permissions are fairly self-explanatory, but the “execute bit” is a bit more mysterious, magical even. Once you understand it, however, it’s fairly straightforward and particularly useful when you need it.

You can examine a file’s permissions using a tool like ls or stat. Try running ls -l against a file on your system, and you’ll see something like the following:

The Linux ls command, with the -l option, shows a file's permissions at the beginning of each line.

There’s a lot of information about the file here, but the permissions are just the set of letters at the beginning. In this case, “rwxr-xr-x” means that, while only the file’s owner can write to it, everyone else can read and execute it. You’ll hear the term “execute bit” but, really, there are three execute bits per file.

What Does the Execute Bit Do to a File?

The main purpose of the execute bit is to control whether or not you can run a file as a program or script. If you enter the name of a file on your command line, your shell will attempt to execute it. Trying to execute a data file like a document or an image will produce a permission error:

Trying to execute an image file produces a "Permission denied" error

This is because the execute bit is not set on such a file. However, the execute bit is not magic; you cannot wave your chmod wand at an image file and turn it into an executable program:

A Linux terminal showing unusual characters and error messages when trying to execute an image file.

You can only execute a file if it’s of a certain type. Broadly speaking, there are two types of files you can run directly on Linux:

  • A binary executable: This is a file that has been compiled from source code and packaged for a specific architecture, using machine code instructions to carry out its task. You might compile such a program from source, download it, or install it using a package manager.
  • A script file: This is a text file written in a human-readable language that can be run with another program, an interpreter. It might be a shell script or a program in a scripting language like Perl or PHP.

When you run a script file directly, by typing its path, your shell decides which interpreter to use based on the script’s shebang line. For example, a Python script may begin with this line:

        #!/usr/bin/python

This reinforces the fact that the execute bit is about permissions and nothing more. It’s what lets the shell decide whether you should be allowed to try to run a file as a program, not whether running it actually makes any sense.

It’s important to understand that the execute bit isn’t a foolproof way of preventing execution. Take this shell script as an example:

        #!/bin/sh
echo "pretend this script does something dangerous like rm -rf / ..."

You might think that removing the execute permission keeps you safe:

Removing execute permission from a file then trying to run it produces an error reading "Permission denied."

However, consider the following case:

Running a Linux script by passing its filename to the sh command.

Disaster! The script now runs because:

  • Everyone can execute the /bin/sh program.
  • The sh program will try to run the filename passed as its argument, without checking its execute bit.

So, running a program involves two separate aspects. The file’s permissions determine whether you can try to run it by typing its path. The file’s contents determine whether it actually does something when executed. Ultimately, the execute bit is a safety mechanism to prevent you from accidentally running a file.

What Does the Execute Bit Do to a Directory?

The execute bit works very differently when you set it on a directory. After all, a directory cannot be a program, so it makes no sense to execute one. Instead, the execute bit determines whether you can enter a directory and access its files.

With the execute bit set on a directory, you can use the cd command to enter it and the ls command to display details of its contents:

Using the cd command to enter a directory with execute permission and the ls command to list details of files inside it.

However, if you remove that permission, you’ll no longer be able to enter that directory or display the details of files inside it:

Removing execute permission on a directory prevents it from being entered and detailed information about its contents being displayed.

Note that the ls command still displays a long-listing, but it replaces most of the data with question marks, indicating that it cannot read it. The actual names of files inside a directory are stored as part of that directory, so read permission grants access to them. But any other data, like a file’s size or its modification date, is inaccessible without execute permission on the directory.

This can lead to confusing errors if you have a command aliased. For example, on my Ubuntu system, ls is aliased to ls –color, which uses certain file data to colorize its output. On a non-executable directory, this produces errors:

An aliased ls showing permission errors on a directory that is not executable.

But, without that option, ls works fine on such a directory since all it needs to display is file names.

How Can I Use and Change the Execute Bit?

If you ever need to focus just on a file’s permissions, you can use stat to get more fine-grained results than ls. The stat program’s -c option lets you specify a format to extract the exact metadata you need. For example, to show just a file’s permissions alongside its name, use this format:

        stat -c "%a %n"
    

You’ll need to tweak this command on macOS which uses a BSD version of stat rather than the Linux GNU version:

If you want just the permission string, you can drop the “%n” i.e.:

        stat -c "%a"
    

This can be useful for scripting. For example, you can use this one-liner to get summary information of the different permission settings for all files in a directory:

        stat -c "%a" ~/home/projects/all

Related


How to Use the stat Command on Linux

More details than ls.

You can alter a file’s permissions using the chmod command. The full syntax of chmod is quite complicated because it’s a powerful tool. However, if you remember the basic letter-based actions and the abbreviations (u=user/owner, g=group, o=other, a=all) it’s easy to use.

To make a file executable by anyone, use this command:

        chmod a+x file

To remove the executable permission from all users, type this:

        chmod a-x file
    

Related


How to Use the chmod Command on Linux

Learn how Linux file permissions work and how to use the chmod command.



Source link

Previous articleBuy the Dip for Maximum BTC Bull Potential?