如何在Linux中的某个目录下仅找到可执行文件?


156

如何在Linux中的某个目录下仅找到可执行文件?


这是一种BASH脚本,我可以说这还不错:) stackoverflow.com/a/20209457/2067125
AjayKumarBasuthkar 2014年

使用标准file命令呢?
突破2014年

4
对于任何想要在Mac上执行此操作(在OS X 10.9.5上进行测试)的人: ls -l | egrep '^[^d]..x..x..x.*$' 上面的内容将列出当前目录中的所有可执行文件(对于all / user和group)。 注意:该-executable选项在Mac上不起作用,因此可以使用上述解决方法。
techfoobar 2014年


1
@techfoobar:问题不明确:是指包含可执行代码的文件,还是意味着具有可执行权限的文件?但是,即使我们假设需要可执行权限(就像大多数响应所希望的那样),问题也不是说world-executable。您的解决方案将找到具有世界执行权限但不是750(-rwxr-x---)的文件(以及fifos,套接字,符号链接等),但某些用户仍然可以执行。
G-Man

Answers:


157

可以使用-perm(不推荐)或-executable(推荐,因为它考虑了ACL )来检查可执行文件。要使用该-executable选项:

find <dir> -executable

如果只想查找可执行文件而不是可搜索目录,请结合使用-type f

find <dir> -executable -type f

23
shebang并不意味着它们是可执行的。它仅告诉我们要使用哪个口译员。根据Linux的定义,“可执行文件”是设置了可执行(x)位的文件
knittl

2
find的哪个版本支持-type?男人在我的系统上找到列表b,c,d,p,f,l,s和D。
innaM

2
同样在这里,我的发现也没有-type x
davr

7
如果您使用的是find的旧版本(可能在4.3.8之前),而缺少-executable的使用find。-perm / u = x,g = x,o = x。
路德维希·韦恩泽尔

8
find: invalid predicate -executable'在RHEL上
SSH

33

使用查找-perm选项。这将在当前目录中找到可由其所有者,组成员或其他人可执行的文件:

find . -perm /u=x,g=x,o=x

编辑:

我只是找到了至少在GNU find 4.4.0中存在的另一个选项:

find . -executable

因为还考虑了ACL,所以它应该可以更好地工作。


2
这仅适用于较新版本的find。CentOS默认附带的一个给出错误find: invalid mode / u = x,g = x,o = x'`
davr

12
然后,您应该尝试使用GNU find中不推荐使用的“ -perm +”版本:find。
烫发

似乎-perm /111是最便携的版本。
斯科特

12

我知道这个问题专门针对Linux,但是由于它是Google的第一个结果,因此我只想添加我一直在寻找的答案(例如,如果您-现在像我一样-被您的雇主强迫使用非GNU / Linux系统)。

macOS 10.12.5 上测试

find . -perm +111 -type f

1
也可以在RHEL 5中使用。
何塞托马斯腌肠

这是我可以在OS X 10.14,thx上工作的唯一变体
Justin

3

我有另一种方法,以防万一,您真正想要的只是对可执行文件做一些事情,而不必强迫自己进行过滤:

for i in `find -type f`; do [ -x $i ] && echo "$i is executable"; done

我更喜欢这样做,因为它不依赖于-executable特定于平台的内容。并且它并不依赖于-perm哪个有点神秘,特定于平台,并且如上所述,要求文件对所有人(不仅仅是您)都可执行。

-type f之所以重要,是因为* nix目录中的文件必须是可执行文件才能被遍历,并且find命令中查询的次数越多,命令的内存使用效率就越高。

无论如何,仅提供另一种方法,因为* nix是十亿种方法的领域。


(0)您更喜欢哪个,奥秘而又正确或直觉又有缺陷?我喜欢正确的。(1)  innaM的answer,具有find -perm,查找设置了任何执行许可权的文件。(2)相反,此答案仅查找当前用户具有执行权限的文件。当然,这可能是OP想要的,但尚不清楚。…(续)
斯科特

(续)…(3)为清楚起见,您可能需要更改`…`$(…)—看到这个以及这个。(4)但不要这样做for i in $(find …); do …;它在包含空格的文件名上失败。相反,请执行find … -exec …。(5)而且,当您使用shell变量时,请始终用双引号引起来,除非您有充分的理由不这样做,并且您确定自己知道自己在做什么。
斯科特

@scott好,我的立场是正确的:)我读的-perm论点是要求全部三个,而不是三个。另外,感谢您提供有关保护shell参数的输入,这些都是我所不知道的。
马克·麦肯纳

@MarkMcKenna您有错字:for i in find。类型f ; do [ -x $i ] && echo "$i is executable"; done; 您缺少<dir>部分,我使用了点号(。)
Devy

2

标有可执行文件的文件不必是可执行文件或可加载文件或对象。

这是我使用的:

find ./ -type f -name "*" -not -name "*.o" -exec sh -c '
    case "$(head -n 1 "$1")" in
      ?ELF*) exit 0;;
      MZ*) exit 0;;
      #!*/ocamlrun*)exit0;;
    esac
exit 1
' sh {} \; -print

2
这是做什么的?
DerMike

@DerMike,这是在当前目录(包括.so文件)中查找可执行文件的方法之一,即使未将文件标记为可执行文件也可以发现。
AjayKumarBasuthkar

好吧,我是说,它是怎么做到的?
DerMike 2015年

它从文件的头读取以发现,每个二进制文件或脚本文件都有头。
AjayKumarBasuthkar

据我所知,-name "*"它没有任何作用find-它通常会找到所有未被测试消除的文件。
G-Man

1

作为一个班轮的粉丝...

find /usr/bin -executable -type f -print0 | xargs file | grep ASCII

使用'xargs'获取find命令的输出(使用print0以确保正确处理带空格的文件名)。现在,我们有了可执行文件的列表,并逐一提供它们作为“文件”命令的参数。然后使用grep表示ASCII来忽略二进制文件。请在find命令中将-executable替换为您喜欢的样式(请参见前面的答案)或在您的'NIX OS上有效的样式

我需要上述内容才能在root拥有的脚本中找到带有eval的文件,因此创建了以下内容以帮助发现priv升级弱点,其中root用户使用不安全的参数运行脚本...

echo -n "+ Identifying script files owned by root that execute and have an eval in them..."
find /  -not \( -path /proc -prune \)  -type f -executable -user root -exec grep -l eval {} \; -exec file {} \; | grep ASCII| cut -d ':' -f1 > $outputDir"/root_owned_scripts_with_eval.out" 2>/dev/null &

如果脚本包含非ASCII字符,则无法使用。file报告编码,因此python脚本可以报告为a /usr/bin/python script, UTF-8 Unicode text executablefind ... | xargs file -b | grep -v '^ELF'可以更好地发现非二进制文件。
xenoid

0

~/.bashrc今晚创建了一个函数,以查找不在系统路径而非目录中的可执行文件:

# Quickly locate executables not in the path
xlocate () {
    locate -0r "$1" | xargs -0 -I{} bash -c '[[ -x "$1" ]] && [[ ! -d "$1" ]] \
        &&  echo "executable: $1"'  _  {}
} # xlocate ()

这样做的好处是它将在一秒钟之内搜索三个Linux发行版和一个Windows安装,而find命令将花费15分钟。

例如:

$ time xlocate llocate
executable: /bin/ntfsfallocate
executable: /home/rick/restore/mnt/e/bin/llocate
executable: /mnt/clone/bin/ntfsfallocate
executable: /mnt/clone/home/rick/restore/mnt/e/bin/llocate
executable: /mnt/clone/usr/bin/fallocate
executable: /mnt/e/bin/llocate
executable: /mnt/old/bin/ntfsfallocate
executable: /mnt/old/usr/bin/fallocate
executable: /usr/bin/fallocate

real    0m0.504s
user    0m0.487s
sys     0m0.018s

或对于整个目录及其所有子目录:

$ time xlocate /mnt/e/usr/local/bin/ | wc -l
65

real    0m0.741s
user    0m0.705s
sys     0m0.032s
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.