Contents

检查文件在Bash中是否可执行

1. 概述

每个操作系统都执行以文件形式存在的程序。在 Linux 中,我们运行二进制可执行文件和许多类型的脚本。

因此,可执行文件以特殊方式标记,以便系统识别它们。然而,一个完全不同的事情是检查文件是否真的包含可执行内容。

在本教程中,我们将学习如何处理这两个问题。

2. 检查文件是否可执行

**在 Linux 系统中,我们应该查找文件的x位。**让我们使用ls 命令来做到这一点:

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

通过读取x位,我们发现文件a.out可能由其所有者joejoe组的成员和其他人执行。

现在让我们执行类似的检查,但是使用test 命令:

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

因此,testx标志证明文件是否存在且可执行。

3.排除目录

现在让我们注意testx检查本身会表明文件夹foo是一个可执行文件:

$ 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

在这种情况下,x位表示可搜索的属性。

因此,让我们首先使用*f for file *标志来改进我们的检查:

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

4. 处理符号链接

现在让我们对指向可执行脚本的符号链接进行测试

$ 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

接下来,让我们清除脚本的执行权限:

$ 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

所以我们要正确检查文件,而不是链接本身。

5. 检查文件内容

请注意,检查文件是否可执行并不意味着它是可运行的。事实上,我们可以在任何文件中设置x位,而无需深入了解其内容的细节。

**有关文件内容的更可靠信息,我们应该使用file 命令。**那么,让我们来看一些可执行文件的例子:

$ 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

因此,我们将获得人类可读的描述和文件的详细信息。 最后,file来自同名包。

6. file命令的魔术文件

让我们了解该命令通过读取文件的一些初始字节来对文件进行分类。然后,它将这个块与一组模式进行比较。魔术文件 存储块的初始位置、模式和结果信息。

让我们注意到这个想法是模仿系统在尝试运行文件时如何识别文件。

例如,file将 Bash 脚本标识为以*#!/bin/bash* shebang开头的文本文件。

现在让我们注意到魔术文件位于*/usr/share/misc目录中。此外,我们可以提供一个魔术文件$HOME/.magic*以优先于系统文件。

最后,我们可以在环境变量*$MAGIC中设置默认的 magic 文件名。在这种情况下,不使用$HOME/.magic*。