1. Overview

Each operating system executes programs, which exist in the form of files. In Linux, we run binary executables and many types of scripts.

Hence, the executable files are marked in a special way for the system to recognize them. However, a quite different matter is to check if the file actually contains executable content.

In this tutorial, we’ll learn how to deal with both of these issues.

2. Checking if the File Is Executable

In Linux systems, we should look up the x bit of the file. Let’s do that with the ls command:

$ ls -all a.out
-rwxrwxr-x. 1 joe joe 24072 May 12 10:35 a.out

We found, reading the x bits, that the file a.out may be executed by its owner, joe, the members of the joe group, and others.

Now let’s perform a similar check, but with the test [ command:

$ if [ -x a.out ]; then echo "File is executable"; else echo "File is not executable"; fi
File is executable

So, the test‘s x flag proves if the file exists and is executable.

3. Ruling out the Directories

Now let’s notice that the test‘s x check alone would suggest that a folder foo is an executable file:

$ mkdir foo
$ ls -dall foo
drwxrwxr-x. 1 joe joe 0 May 13 02:01 foo

$ if [ -x foo ]; then echo "File is executable"; else echo "File is not executable"; fi
File is executable

In such a case, the x bit means searchable property.

Hence, let’s refine our check using the f for file flag first:

$ if [ -f foo ] && [ -x foo ]; then echo "File is executable";
  else echo "File is not executable"; fi
File is not executable

Now let’s apply test to the symbolic link pointing to the executable script:

$ ln -s ./script ./link_to_script

$ ls -all link_to_script
lrwxrwxrwx. 1 joe joe 8 May 13 02:17 link_to_script -> ./script

$ if [ -x link_to_script ]; then echo "File is executable";
  else echo "File is not executable"; fi
File is executable

Next, let’s clear the execution permission on script:

$ chmod u-x script
$ if [ -x link_to_script ]; then echo "File is executable";
  else echo "File is not executable"; fi
File is not executable

So we’re going to correctly check the file, not the link itself.

5. Examining the File’s Content

Let’s notice that checking if a file is executable doesn’t mean it’s runnable. In fact, we may set x bit at any file without going into details of its content.

For more reliable information about the file content, we should use the file command. So, let’s go through some examples of executables:

$ file a.out # on 64-bit executable

a.out: ELF 64-bit LSB executable, x86-64, version 1 (SYSV),
  dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2,
  BuildID[sha1]=fbd0c111dbca2b187d6869ff292a0a8ba2360fc5, for GNU/Linux 3.2.0, not stripped

$ file a32.out # on 32-bit executable

a32.out: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV),
  dynamically linked, interpreter /lib/ld-linux.so.2,
  BuildID[sha1]=261b97649683fd8061116853c862d1f09923ede2, for GNU/Linux 3.2.0, not stripped

$ file script # on bash script

script: Bourne-Again shell script, ASCII text executable

So we’re going to obtain a human-readable description and the file’s details.

Finally, file comes in the package of the same name.

6. magic File of the file Command

Let’s learn that the command classifies the file by reading some number of its initial bytes. Then, it compares this chunk against a set of patterns. The magic file stores the initial position of the chunk, pattern, and the resulting information.

Let’s notice that the idea is to mimic how the system recognizes files when attempting to run them.

As an example, file identifies the Bash script as a text file starting with the #!/bin/bash shebang.

Now let’s notice that the magic file is located in the /usr/share/misc directory. In addition, we can provide a magic file $HOME/.magic to be preferred over the system one.

Finally, we may set the default magic file name in the environmental variable $MAGIC. In such a case, $HOME/.magic is not used.

7. Conclusion

In this tutorial, we learned how to check if the Linux system regards a file as executable. So, we used the test command in the context of files, directories, and symbolic links.

Next, we checked the file’s content to obtain more detailed information about its application by means of the file command.

Comments are closed on this article!