我可以在Unix find
命令中使用哪种类型的参数/标志,以便搜索可执行文件?
答案 0 :(得分:147)
在GNU版本的find上,您可以使用-executable
:
find . -type f -executable -print
对于BSD版本的find,您可以将-perm
与+
和八进制掩码一起使用:
find . -type f -perm +111 -print
在此上下文中,“+”表示“任何这些位都置位”,111是执行位。
请注意,这与GNU find中的-executable
谓词不同。特别是,-executable
测试文件可以由当前用户执行,而-perm +111
只测试是否设置了任何执行权限。
较旧版本的GNU find也支持-perm +111
语法,但从4.5.12开始,不再支持此语法。相反,您可以使用-perm /111
来获取此行为。
答案 1 :(得分:29)
向@ gniourf_gniourf提出澄清基本误解的提示。
此答案尝试提供概述现有答案,并讨论其细微之处和相对优点以及提供背景信息,尤其是可移植性。
查找可执行文件可以参考两个不同的用例:
请注意,在任一方案中,使用find -L ...
而不仅仅是find ...
才有意义同时找到< em>符号链接到可执行文件。
请注意,最简单的以文件为中心的案例 - 查找具有为所有三个安全主体(用户,组,其他)设置的可执行权限位的可执行文件 - 通常,但不一定产生与以用户为中心的场景相同的结果 - 理解差异非常重要。
-executable
) accepted answer值得推荐-executable
,IF GNU find
可用。
find
附带大多数 Linux 发行版
-executable
仅匹配当前用户可以执行的文件(有边缘情况。 [1] )。接受的答案提供的 BSD find
替代方法-perm +111
回答不同< / em>, file -centric question (正如答案本身所述)。
-perm
来回答用户中心问题是不可能 ,因为我们需要的是将文件的用户和组标识与当前用户的相关联,而-perm
只能测试文件的权限
仅使用POSIX find
features,如果不涉及外部实用程序,则无法回答问题。因此,最佳-perm
可以(单独)完成-executable
的近似 。 可能更接近近似值-perm +111
<{1}} ,以便找到为所有安全主体设置可执行位的文件(用户,组) ,其他) - 这让我觉得这是一个典型的现实场景。作为奖励,它也恰好符合POSIX(使用-perm -111
包含符号链接,请参阅下面的解释):
find -L
gniourf_gniourf's answer 使用find . -type f -perm -111 # or: find . -type f -perm -a=x
提供真实,可移植的等效-executable
,尽管 at绩效费用。
将 -exec test -x {} \;
与-exec test -x {} \;
结合使用(即,至少有一个可执行位集的文件)可以帮助提高性能{ {1}}不需要为每个文件调用(以下使用符合POSIX标准的BSD等效查找-perm +111
/ GNU查找exec
;请参见下文作为解释):
-perm +111
-perm /111
)find . -type f \( -perm -u=x -o -perm -g=x -o -perm -o=x \) -exec test -x {} \; -print
主< / strong>(在GNU查找术语中称为 test )。
-perm
允许您测试任何文件权限,而不仅仅是可执行性。-perm
),而符号模式是字符串(例如,-perm
)。111
(用户),a=x
(组)和u
(其他)或g
指的是这三个。例如,权限表示为可执行文件的o
,并使用运算符a
,x
和=
分配给主体;对于完整讨论,包括八进制模式,请参阅the POSIX spec for the chmod
utility 。+
的上下文中:
-
(例如,find
)添加模式意味着:匹配 all 指定权限的文件(但匹配的文件可能有其他权限)。-
)表示:匹配具有此完整,完全权限集的文件。-ug=x
755
[2] 以文件为中心的命令示例
注意:
+
或/
。+
表示NOT(GNU查找和BSD查找也允许/
);请注意,示例中使用!
以保护-not
免受shell历史记录扩展的影响\!
用于AND(GNU查找和BSD查找也允许!
)-a
用于OR(GNU查找和BSD查找也允许-and
)-o
,-or
和-
运算符可以互换使用
(例如,=
相当于+
- 除非您稍后申请-u=x
,但这样做没有意义。)-u+x
加入部分模式; AND逻辑暗示;例如,-x
表示必须设置用户和组可执行位。,
表达式与NOT primary -u=x,g=x
。-perm
或!
;也称为操作和测试GNU find中的是隐式与-print
(逻辑AND),-perm
和可能的括号(转义为-a
和{{实现OR逻辑需要1}} for shell。-o
而不仅仅是\(
用于将符号链接与可执行文件相匹配
\)
指示find评估符号链接的目标而不是符号链接本身;因此,如果没有find -L ...
,find ...
将完全忽略符号链接。-L
[1]从-L
开始,-type f
对GNU的描述发现4.4.2:
匹配可执行文件和可搜索的目录(在文件名解析意义上)。这考虑了访问权限 控制列表和其他权限人工制品 - -perm测试忽略。此测试使用access(2)系统调用,因此可以 被执行UID映射(或根压缩)的NFS服务器所欺骗,因为许多系统在客户端的内核中实现了访问(2),所以不能 利用服务器上保存的UID映射信息。因为此测试仅基于access(2)系统调用的结果,所以 不能保证实际执行此测试成功的文件。
[2] GNU查找版本早于4.5.12 也允许使用前缀# Match files that have ALL executable bits set - for ALL 3 security
# principals (u (user), g (group), o (others)) and are therefore executable
# by *anyone*.
# This is the typical case, and applies to executables in _system_ locations
# (e.g., /bin) and user-installed executables in _shared_ locations
# (e.g., /usr/local/bin), for instance.
find -L . -type f -perm -a=x # -a=x is the same as -ugo=x
# The POSIX-compliant equivalent of `-perm +111` from the accepted answer:
# Match files that have ANY executable bit set.
# Note the need to group the permission tests using parentheses.
find -L . -type f \( -perm -u=x -o -perm -g=x -o -perm -o=x \)
# A somewhat contrived example to demonstrate the use of a multi-principial
# mode (comma-separated clauses) and negation:
# Match files that have _both_ the user and group executable bit set, while
# also _not_ having the other executable bit set.
find -L . -type f -perm -u=x,g=x \! -perm -o=x
,但这首先被弃用并最终删除,因为将-executable
与man find
结合使用由于被解释为精确权限掩码,符号模式可能会产生意外结果。 如果你(a)在之前运行 4.5.12 并且(b)将自己限制在 octal 模式只有,你可以使用+
和两个 GNU find和BSD find,但这不是一个好主意。
答案 2 :(得分:9)
您可以使用-executable
测试标记:
-executable
Matches files which are executable and directories which are
searchable (in a file name resolution sense).
答案 3 :(得分:8)
以便有另一种可能 1 来查找当前用户可执行的文件:
find . -type f -exec test -x {} \; -print
(这里的测试命令是在PATH中找到的,很可能是/usr/bin/test
,而不是内置的。
1 仅在-executable
的{{1}}标志不可用时才使用此项!这与find
解决方案略有不同。
答案 4 :(得分: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
答案 5 :(得分:2)
find . -executable -type f
并不能保证文件是可执行的,它会找到设置了执行位的文件。如果你这样做
chmod a+x image.jpg
上面的发现会认为image.jpg是一个可执行文件,即使它实际上是一个设置了执行位的jpeg图像。
我通常会解决这个问题:
find . -type f -executable -exec file {} \; | grep -wE "executable|shared object|ELF|script|a\.out|ASCII text"
如果您希望find实际打印有关可执行文件的圆顶信息,您可以执行以下操作:
find . -type f -executable -printf "%i.%D %s %m %U %G %C@ %p" 2>/dev/null |while read LINE
do
NAME=$(awk '{print $NF}' <<< $LINE)
file -b $NAME |grep -qEw "executable|shared object|ELF|script|a\.out|ASCII text" && echo $LINE
done
在上面的示例中,文件的完整路径名在最后一个字段中,并且必须使用awk“NAME = $(awk'{print $ NF}'&lt;&lt;&lt;&lt; $ LINE)”来反映您查找的位置 如果文件名在查找输出字符串中的其他位置,则需要将“NF”替换为正确的数字位置。如果您的分隔符不是空格,您还需要告诉awk您的分隔符是什么。
答案 6 :(得分:1)
这是非常容易的荒谬 ...更不用说旁边不可能了。举起手来,我顺从Apple / Spotlight ......
mdfind 'kMDItemContentType=public.unix-executable'
至少它有效!
答案 7 :(得分:1)
简单的答案是:“您的可执行文件位于PATH变量中包含的目录中”,但是它实际上找不到您的可执行文件,并且可能会错过很多可执行文件。
我不太了解mac,但我认为“mdfind'kMDItemContentType = public.unix-executable'”可能会错过像解释脚本这样的东西
如果您可以找到设置了可执行位的文件(无论它们是否实际可执行),那么就可以了
find . -type f -perm +111 -print
支持“-executable”选项将进一步过滤查看acl和其他权限工件但技术上与“-pemr +111”没有太大区别。
也许将来find会支持“-magic”并让你明确查看具有特定魔法id的文件......但是你必须指定精确所有可执行格式的魔法id。
我不知道在unix上有一个技术上正确的简单方法。
答案 8 :(得分:0)
我有同样的问题,答案在dmenu source code:为此目的而制作的最佳实用程序。你可以编译&#39; stest.c&#39;和&#39; arg.h&#39;文件,它应该工作。有一个使用的手册页,我为方便起见放在那里:
STEST(1) General Commands Manual STEST(1)
NAME
stest - filter a list of files by properties
SYNOPSIS
stest [-abcdefghlpqrsuwx] [-n file] [-o file]
[file...]
DESCRIPTION
stest takes a list of files and filters by the
files' properties, analogous to test(1). Files
which pass all tests are printed to stdout. If no
files are given, stest reads files from stdin.
OPTIONS
-a Test hidden files.
-b Test that files are block specials.
-c Test that files are character specials.
-d Test that files are directories.
-e Test that files exist.
-f Test that files are regular files.
-g Test that files have their set-group-ID
flag set.
-h Test that files are symbolic links.
-l Test the contents of a directory given as
an argument.
-n file
Test that files are newer than file.
-o file
Test that files are older than file.
-p Test that files are named pipes.
-q No files are printed, only the exit status
is returned.
-r Test that files are readable.
-s Test that files are not empty.
-u Test that files have their set-user-ID flag
set.
-v Invert the sense of tests, only failing
files pass.
-w Test that files are writable.
-x Test that files are executable.
EXIT STATUS
0 At least one file passed all tests.
1 No files passed all tests.
2 An error occurred.
SEE ALSO
dmenu(1), test(1)
dmenu-4.6 STEST(1)
答案 9 :(得分:0)
因此,如果您实际上想查找可执行文件类型(例如脚本,ELF二进制文件等。等等),而不仅是具有执行权限 permission 的文件,那么您可能想做更多类似的事情(当前目录。可以替换为所需的任何目录):
gfind . -type f -exec bash -c '[[ $(file -b "'{}'") == *" executable "* ]] ' \; -print
或者对于那些不使用macports(Linux用户)或以其他方式安装gnu find的用户:
find . -type f -exec bash -c '[[ $(file -b "'{}'") == *" executable "* ]] ' \; -print
尽管如果您使用的是OS X,则它隐藏了一个名为is_exec的小工具,该工具基本上为您捆绑了该小测试,因此,如果找到它,则可以缩短命令行。但是这种方式更加灵活,因为您可以轻松地将==测试替换为=〜测试,并使用它来检查更复杂的属性,例如可执行的纯文本文件或file命令返回的任何其他信息。
这里引用的确切规则非常模糊,因此我最终还是通过反复试验得出结论,但是我很想听听正确的解释。