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
4. Dealing With Symbolic Links
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.
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.