如何在Bash中检查文件是否可执行
如何检查Bash中的文件是否可执行
在Bash中,无需解析ls
的输出即可检查文件是否可执行。Shell提供了内置的-x
选项来进行检查。使用-x
选项,可以将循环重写为:
for file in "$1"/*; do [[ -x "$file" ]] && rm -- "$file" done
参考链接:
- 正如Charles所建议的 - 为什么不应该解析ls(1)的输出
- BashFAQ/087 - 如何在不解析ls -l输出的情况下获取文件的权限(或其他元数据)
"$1"/*
,你的意思是(处理目录名称中的空格)。而且rm -- "$file"
,如果我们想处理$1
是以破折号开头的目录名称的情况。
如何在Bash中检查文件是否可执行
您可以使用以下代码来检查文件是否可执行:
if [ -x "$file" ]; then # do something fi
您还可以通过`man`命令获取更多的文件测试选项:
~]# man test .... -x FILE FILE exists and execute (or search) permission is granted
以下代码可以实现上述功能:
~]# find $1 -type f | while IFS='' read -r -d '' p; do if [ -x "$p" ]; then echo "removing $p"; rm "$p"; fi; done
`find`命令获取目录`$1`中的所有文件(包括`.`)。`while`循环读取每个文件,`if then`语句使用`-x`选项检查每个文件是否具有可执行权限。
编辑后,以下是更快的示例:
find "$1" -type f -executable -exec rm -- {} \;
如果`$file`是一个空字符串,则`[ -x $file ]`会错误地返回true,因为它会运行`[ -x ]`,这会测试`-x`是否为空字符串(由于它非空,返回true)。请使用引号:`[ -x "$file" ]`。
这也没有正确/鲁棒地检索文件名(`for val in `ls $1` `存在已知问题:无法正确处理包含空格的名称,非打印字符的行为在平台之间有所不同,包含换行符的文件名的行为是完全未定义的等)。
解析`find`的输出在解析`ls`的输出会失败,而且这并不必要。您可以使用`-perm`选项选择可执行文件,然后使用`-exec rm -- {} \;`(或`-delete`,如果支持)来删除它们。
引号!`find "$1" -type f -executable -exec rm -- {} +` - 如果没有引号包围`$1`,则名为`./My Directory`的目录将作为两个参数传递,即`./My`和`Directory`。
此外,`-exec rm -- {} \;`是低效的,每找到一个文件就运行一次`rm`,而`-exec rm -- {} +`尽可能少地调用`rm`,将多个文件名放在每次调用的命令行上。
如果您确实想从`find`中进行管道传输,可以使用以下命令:`find "$1" -type f -print0 | while IFS='' read -r -d '' p; do` - 这样您可以正确处理包含字面反斜杠、以空格结尾的名称以及包含字面换行符的名称,而当前的`find ... | while read`则无法处理这些情况。另请参阅UsingFind中的“批量操作”部分。