检查文件是否可执行
检查文件是否可执行
在编写脚本时,有时需要检查一个文件是否可执行。这意味着文件是否存在并且具有执行(或搜索)权限。在不同的shell脚本中,可以使用不同的方式来实现这个检查。
在BASH、Bourne、Ksh和Zsh脚本中,可以使用如下语法来检查文件是否可执行:
if [[ -x "$file" ]] then echo "文件 '$file' 是可执行的" else echo "文件 '$file' 不可执行或未找到" fi
在TCSH或CSH脚本中,可以使用如下语法来检查文件是否可执行:
if ( -x "$file" ) then echo "文件 '$file' 是可执行的" else echo "文件 '$file' 不可执行或未找到" endif
另外,可以使用`file`命令来确定文件的类型。可以解析`file`命令的输出,以查看文件的具体类型。在不同的操作系统上,`file`命令的输出可能会有所不同,但是都会包含`executable`这个关键词和架构信息。
例如,在Mac上运行`file /bin/ls`命令的输出如下所示:
/bin/ls: Mach-O universal binary with 2 architectures /bin/ls (for architecture x86_64): Mach-O 64-bit executable x86_64 /bin/ls (for architecture i386): Mach-O executable i386
在Linux上运行相同的命令的输出如下所示:
/bin/ls: ELF 64-bit LSB executable, AMD x86-64, version 1 (SYSV), for GNU/Linux 2.6.9, dynamically linked (uses shared libs), stripped
在Solaris上运行相同的命令的输出如下所示:
/bin/ls: ELF 32-bit MSB executable SPARC Version 1, dynamically linked, stripped
无论是哪个操作系统,在输出中都会包含`executable`关键词和架构信息(如`x86-64`、`i386`或`SPARC`)。
如果要检查一个文件是否可执行,可以结合使用`-x`选项和`file`命令的输出,进行字符串匹配。下面是一个示例,在BASH脚本中实现这个检查的代码:
if [ -x "$file" ] && file "$file" | grep -q "Mach-O" then echo "这是一个可执行的 Mac 文件" elif [ -x "$file" ] && file "$file" | grep -q "GNU/Linux" then echo "这是一个可执行的 Linux 文件" elif [ -x "$file" ] && file "$file" | grep q "shell script" then echo "这是一个可执行的 Shell 脚本" elif [ -x "$file" ] then echo "这个文件标记为可执行,但是具体类型未知" else echo "这个文件没有标记为可执行" fi
上述代码首先使用`-x`选项检查文件是否可执行,然后使用`file`命令获取文件的详细信息,并使用`grep`命令进行字符串匹配。如果系统不支持`grep -q`,可以尝试使用`grep "regex" > /dev/null 2>&1`来替代。
需要注意的是,不同的系统上,`file`命令的输出可能会有所不同,因此需要根据实际情况验证代码是否适用。另外,上述代码还会检查文件的可执行位,如果一个二进制可执行文件没有设置可执行位,也会被认为不可执行。
最后,如果要检查文件是否对任何人可执行,可以使用`-r`选项来检查文件是否可读取。
问题:如何检查一个文件是否可执行?
解决方法:
1. 在Linux上,可以使用以下命令来测试文件、目录和符号链接:
if [[ -f "$file" && -x $(realpath "$file") ]]; then .... fi
2. 在OS X上,可以使用homebrew安装coreutils,并使用grealpath命令。
定义isexec函数:
isexec() { if [[ -f "$1" && -x $(realpath "$1") ]]; then true; else false; fi; }
或者简化为:
isexec() { [[ -f "$1" && -x $(realpath "$1") ]]; }
然后可以使用以下命令进行测试:
if `isexec "$file"`; then ... fi
注意事项:
- 在第一个版本中,应该使用`return true`而不是`echo true`。
- 在单行代码的末尾括号之前添加分号(至少bash需要这样,`]]; }`)。
- 在`if`语句中不需要使用反引号。
- 在zsh中,使用第一个版本中的`return true`会出现问题,可以使用`true`来替代。