Unixfind:search可执行文件

什么types的参数/标志可以使用Unix find命令,以便我search可执行文件?

在GNU版本的find上你可以使用-executable

 find . -type f -executable -print 

对于BSD版本的查找,您可以使用带有+和八进制掩码的-perm

 find . -type f -perm +111 -print 

在这个上下文中,“+”表示“任何这些位被设置”,而111是执行位。

请注意,这与GNU find中的-executable谓词不同。 特别是, -executabletesting文件可以由当前用户执行,而-perm +111只是testing是否设置了任何执行权限。

老版本的GNU查找也支持-perm +111语法,但从4.5.12开始,不再支持这种语法。 相反,你可以使用-perm /111来得到这个行为。

为了澄清一个根本性的误解,给@ gniourf_gniourf的提示。

这个答案试图提供现有答案概述,并讨论它们的细微之处相对优点 ,并提供背景信息 ,特别是在可移植性方面

查找可执行文件可以引用两个不同的用例

  • 以用户为中心 :查找当前用户可以执行的文件
  • 以文件为中心 :查找具有(一个或多个) 可执行权限位的文件

请注意,在任一情况下, 使用find -L ...而不是仅仅find ... 可以find符号链接到可执行文件

请注意,最简单的以文件为中心的情况 – 为所有三个安全主体(user,group,other)寻找可执行权限为可执行权限位的可执行文件 – 通常会不一定产生与以用户为中心的情况相同的结果 -重要的是要了解差异。

以用户为中心( -executable

  • 接受的答案值得称道的build议 – -executable ,IF GNU find是可用的。

    • GNU find与大多数Linux发行版一起提供
      • 相比之下,基于BSD的平台,包括OSX,都带有BSD查找function。
    • 根据场景的需要, -executable只匹配当前用户可以执行的文件(有边缘情况[1] )。
  • 被接受的答案( -perm +111 )提供BSD find替代方法 回答了一个不同的 ,以文件为中心的问题 (如答案本身所述)。

    • 仅仅使用-perm来回答用户中心问题是不可能的 ,因为需要将文件的用户和组身份与当前用户相关联 ,而-perm只能testing文件的权限。
      仅使用POSIX findfunction ,如果不涉及外部实用程序,则无法回答该问题。
    • 因此, 最好的-perm可以(本身)是 -executable 近似也许比-perm +111 近似于-perm -111 ,以便find为所有安全主体(user,group,other)设置可执行位的文件 – 这使我觉得这是典型的真实世界场景。 作为奖励,它也恰好符合POSIX标准(使用find -L来包含符号链接,请参阅下面的解释):

       find . -type f -perm -111 # or: find . -type f -perm -a=x 
  • gniourf_gniourf的答案提供了一个真正的,可移植的等同的-executable ,使用-exec test -x {} \; 尽pipe以牺牲性能为代价

    • 结合 -exec test -x {} \; 使用-perm +111 (即至less有一个可执行位集的文件)可能有助于提高性能,因为不需要为每个文件调用exec (以下使用符合POSIX标准的BSD find -perm +111 / GNU find -perm /111 ;请参阅下面的说明):

       find . -type f \( -perm -u=x -o -perm -g=x -o -perm -o=x \) -exec test -x {} \; -print 

以文件为中心( -perm

  • 回答以文件为中心的问题使用POSIX兼容的-perm (在GNU查找术语中称为testing 足够了
    • -perm允许您testing任何文件权限,而不仅仅是可执行性。
    • 权限被指定为八进制符号模式 。 八进制模式是八进制数(例如111 ),而符号模式是string(例如, a=x )。
    • 符号模式将安全主体标识为u (用户), g (组)和o (其他)或a来引用所有三个。 例如,权限表示为可执行文件的x ,并使用运算符=+-分配给主体。 有关八进制模式全面讨论,请参阅chmod实用程序的POSIX规范
    • find的上下文中:
      • 使用- (例如, -ug=x前缀模式意味着:匹配具有指定的 所有权限的文件 (但是匹配的文件可能具有额外的权限)。
      • 没有前缀 (例如755 )意味着:匹配具有完整的一准确权限的文件。
      • 警告GNU find和BSD都会find一个额外的非标准前缀它们是任意指定的权限位集合逻辑 ,但是这样做却是不兼容的语法
        • BSDfind: +
        • GNU find: / [2]
      • 因此, 如果您的代码必须是可移植的 ,请避免这些扩展
  • 以下示例演示了各种以文件为中心的问题的便携式答案。

以文件为中心的命令示例

注意:

  • 下面的例子符合POSIX标准 ,这意味着它们可以在任何POSIX兼容的实现中工作,包括GNU find和BSD find; 具体来说,这需要:
    • 不使用非标准模式前缀+/
    • 使用POSIXforms的逻辑运算符初选
      • ! 对于不(GNU查找和BSD查找也允许-not ); 注意\! 在例子中使用,以保护! 从shell历史扩展
      • -a用于(GNU查找和BSD查找还允许-and
      • -o for OR(GNU find和BSD find也允许-or
  • 这些示例使用符号模式,因为它们更易于阅读和记忆。
    • 对于模式前缀, =+运算符可以互换使用(例如, -u=x相当于-u+x – 除非稍后再应用-x ,但这样做没有意义)。
    • 使用,join部分模式; 暗示AND逻辑; 例如, -u=x,g=x意味着用户组可执行位必须被设置。
    • 模式本身不能expression否定匹配的意义,即“只有在未设置该位时才匹配”。 你必须使用一个单独的-permexpression式与NOT主, !
  • 请注意find的初选 (如-print ,或者-perm ;在GNU find中也被称为动作testing )与-a (逻辑AND)和-o以及可能的括号(作为\(\)转义\)为了实现OR逻辑。
  • find -L ...而不是仅仅find ...用于也符合链接到可执行文件
    • -L指示查找来评估符号链接的目标而不是符号链接本身; 因此,如果没有-L-type f就会完全忽略符号链接。
 # 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 # (eg, /bin) and user-installed executables in _shared_ locations # (eg, /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 

[1]从GNU find 4.4.2开始-executable描述:

匹配可执行的文件和可search的目录(在文件名称parsing意义上)。 这考虑到了-permtesting忽略的访问控制列表和其他许可权文物。 这个testing利用了访问(2)系统调用,所以可以被执行UID映射(或根挤压)的NFS服务器愚弄,因为许多系统在客户的内核中实现访问(2),所以不能利用保存在服务器上的UID映射信息。 因为这个testing只是基于访问(2)系统调用的结果,所以不能保证这个testing成功的文件能够被真正执行。

[2] 早于4.5.12的 GNU查找版本也允许使用前缀+ ,但是这是第一次被弃用并最终被删除,因为将+符号模式结合可能会产生意想不到的结果,因为被解释为精确的权限掩码。 如果你(a) 4.5.12 之前运行一个版本 并且 (b)仅限于八进制模式,那么你可以用GNU find和BSD查找来使用+ ,但这不是一个好主意。

您可以使用-executabletesting标志:

 -executable Matches files which are executable and directories which are searchable (in a file name resolution sense). 

为了有另一个可能性1find当前用户可以执行的文件:

 find . -type f -exec test -x {} \; -print 

(这里的testing命令是在PATH中find的,很可能是/usr/bin/test ,而不是内置的)。


1只有在-executable标志不可用的情况下才能使用! 这与-perm +111解决scheme略有不同。

这对我工作和思想共享…

 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 
 find . -executable -type f 

并不能保证文件是可执行文件,它会find设置了执行位的文件。 如果你这样做

 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 . -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 

在上面的示例中,文件的完整path名在最后一个字段中,并且必须反映在awk的“NAME = $(awk'{print $ NF}'<<< $ LINE)”中查找的位置“查找输出string,您需要用正确的数字位置replace“NF”。 如果你的分隔符不是空格,你还需要告诉awk你的分隔符是什么。

太可笑了 ,这不是超级简单的…更不用说了。 举起手来,我顺从苹果/ Spotlight …

mdfind 'kMDItemContentType=public.unix-executable'

至less它工作!

那么简单的答案就是:“你的可执行文件在你的PATHvariables中包含的目录中”,但是它不会真的find你的可执行文件,并且可能会错过很多可执行文件。

我不太了解mac,但我认为“mdfind'kMDItemContentType = public.unix-executable'”可能会错过解释脚本之类的东西

如果可以find设置了可执行位的文件(无论它们是否是可执行的),那么可以这么做

 find . -type f -perm +111 -print 

在支持“-executable”选项的情况下,将进一步查看acl和其他许可工件,但在技术上与“-pemr + 111”没有多大区别。

也许在将来会发现支持“-magic”,让你明确地看看具有特定魔术ID的文件…但是,那么你将不得不指定罚款所有的可执行格式魔术ID。

我不知道unix上一个技术上正确的简单方法。

我有同样的问题,答案是在dmenu源代码 :为此目的而制作的最简单的工具。 你可以编译'stest.c'和'arg.h'文件,它应该可以工作。 有一个使用的手册页,我为了方便而放在那里:

 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)