Dem*_*emi 2 bash find executable
我正在寻找所有不在我的$PATH.
目前我正在这样做
find / \( -path "/opt" -prune -o -path "/var" -prune -o -path "/bin" -prune -o -path "/sbin" -prune -o -path "/usr" -prune -o -path "/opt" \) -o -type f -executable -exec file {} \;
Run Code Online (Sandbox Code Playgroud)
我觉得有更好的方法,我尝试使用 for 循环IFS=:将 的不同部分分开,PATH但无法使其工作。
编辑:我应该指定我不想为此使用脚本。
假设 GNUfind和bashshell(如问题中所用),这是一个简短的脚本,可以完成您要执行的操作:
#!/bin/bash
IFS=:
set -f
args=( -false )
for dirpath in $PATH; do
args+=( -o -path "$dirpath" )
done
find / \( \( "${args[@]}" \) -o \
\( -type d \( ! -executable -o ! -readable \) \) \) -prune -o \
-type f -executable -exec file {} +
Run Code Online (Sandbox Code Playgroud)
这首先创建数组args,由动态构造的参数组成find。它通过拆分$PATH冒号的值来实现,即我们赋予IFS变量的值。当我们$PATH在循环头中使用unquoted时,就会发生拆分。
通常,shell 会在从 的拆分中生成的每个单词上调用文件名通配$PATH,但我正在使用set -f关闭文件名通配,以防万一 中的任何目录路径$PATH包含通配符(这些仍然是有问题的,因为-path的操作数find会将它们解释为模式)。
如果我的PATH变量包含字符串
/usr/bin:/bin:/usr/sbin:/sbin:/usr/X11R6/bin:/usr/local/bin:/usr/local/sbin
Run Code Online (Sandbox Code Playgroud)
然后args将是以下列表(这里的每一行都是数组中的一个单独元素,这实际上不是一组带有换行符的字符串):
-false
-o
-path
/usr/bin
-o
-path
/bin
-o
-path
/usr/sbin
-o
-path
/sbin
-o
-path
/usr/X11R6/bin
-o
-path
/usr/local/bin
-o
-path
/usr/local/sbin
Run Code Online (Sandbox Code Playgroud)
这个列表被插入到find命令调用中,在括号中。没有必要对-prune每个目录重复,因为你可以像我上面一样使用它一次。
我选择修剪任何不可执行或不可读取的目录。这应该可以消除您无法访问或列出其内容的目录的许多权限错误。你想find通过删除这个位来简化命令,使用
find / \( "${args[@]}" \) -prune -o \
-type f -executable -exec file {} +
Run Code Online (Sandbox Code Playgroud)
此外,我正在file批量运行找到的路径名,而不是每个路径名一次。