Léo*_* 준영 778 error-handling bash file-permissions find
我需要隐藏所有被拒绝的权限消息:
find . > files_and_folders
Run Code Online (Sandbox Code Playgroud)
我正在尝试这样的消息出现.我需要收集所有不会出现的文件夹和文件.
是否可以将权限级别定向到files_and_folders文件?
如何同时隐藏错误?
Jon*_*ler 537
使用:
find . 2>/dev/null > files_and_folders
Run Code Online (Sandbox Code Playgroud)
Permission denied当然,这不仅隐藏错误,还隐藏所有错误消息.
如果你真的想要保留其他可能的错误,例如符号链接上的跳数太多,而不是允许拒绝的错误,那么你可能不得不猜测你没有很多名为"权限被拒绝"的文件并尝试:
find . 2>&1 | grep -v 'Permission denied' > files_and_folders
Run Code Online (Sandbox Code Playgroud)
如果您只想过滤标准错误,可以使用更精细的构造:
find . 2>&1 > files_and_folders | grep -v 'Permission denied' >&2
Run Code Online (Sandbox Code Playgroud)
find命令的I/O重定向是:2>&1 > files_and_folders |.管道将标准输出重定向到grep命令并首先应用.的2>&1发送标准误差相同的地方标准输出(管).的> files_and_folders发送标准输出(但不是标准误差)到一个文件.最终结果是写入标准错误的消息沿管道发送,并将常规输出find写入文件.该grep过滤器的标准输出(你可以决定你要如何选择它是,并且可能根据地区不同和O/S改变拼写)和最终>&2意味着幸存的错误消息(写到标准输出)到标准错误再一次.最终的重定向在终端上可以被视为可选的,但在脚本中使用它是一个非常好的主意,以便在标准错误中出现错误消息.
这个主题有无穷无尽的变化,取决于你想做什么.这将适用于任何带有任何Bourne shell衍生产品(Bash,Korn,...)和任何符合POSIX标准版本的Unix版本find.
如果您希望适应系统上的特定版本find,可能还有其他选择.GNU find尤其具有其他版本中无法提供的无数选项 - 请参阅当前接受的一个选项集的答案.
Mic*_*rux 278
使用:
find . ! -readable -prune -o -print
Run Code Online (Sandbox Code Playgroud)
或更一般地说
find <paths> ! -readable -prune -o <other conditions like -name> -print
Run Code Online (Sandbox Code Playgroud)
适用于:find(GNU findutils)4.4.2.背景:
-readable测试与可读文件匹配.!当测试为假时,运算符返回true.并且! -readable匹配不可读的目录(和文件).-prune操作不会进入目录.! -readable -prune 可以翻译为:如果目录不可读,请不要进入.-readable测试考虑了访问控制列表和-perm测试忽略的其他权限假象.有关更多详细信息,另请参见find(1)联机帮助页.
mkl*_*nt0 250
注意:
*这个答案可能比用例保证更深入,并且find 2>/dev/null在许多情况下可能已经足够好了.对于跨平台的观点以及为了找到尽可能强大的解决方案而讨论一些先进的shell技术可能仍然有意义,即使防范的案例可能在很大程度上是假设的.
*如果您的系统配置为显示本地化的错误消息,请在find下面的调用前加上LC_ALL=C(LC_ALL=C find ...)以确保报告英语消息,以便grep -v 'Permission denied'按预期工作.但是,任何显示的错误消息都将以英语显示.
如果您的shell是bash或者zsh,那么只需使用符合POSIX标准的功能,即使是相当简单的解决方案也是健壮的.虽然它本身不是POSIX的一部分,但大多数现代Unix平台都附带它,使这个解决方案具有广泛的可移植性:findbash
find . > files_and_folders 2> >(grep -v 'Permission denied' >&2)
Run Code Online (Sandbox Code Playgroud)
注意:完成之后某些grep输出可能会到达的可能性很小,因为整个命令不会等待内部命令完成.在,您可以通过附加到命令来防止这种情况. find>(...)bash| cat
>(...)是一个(很少使用)输出 进程替换,允许将输出重定向(在本例中,stderr output(2>)到命令的stdin内>(...).
除了bash和zsh,原则上ksh支持它们,但试图将它们与重定向结合起来stderr,就像在这里完成的那样(),似乎被默默地忽略(in ).2> >(...)ksh 93u+
grep -v 'Permission denied'过滤out(-v)find包含短语的所有行(来自命令的stderr流)Permission denied并将剩余的行输出到stderr(>&2).这种方法是:
robust:grep仅应用于错误消息(而不是文件路径和错误消息的组合,可能导致误报),并且除了权限拒绝之外的错误消息将传递给stderr.
无副作用:find的退出代码被保留:无法访问文件系统项目中的至少一个遇到的退出码结果1(虽然这不会告诉你的错误是否其他比许可被拒绝的人发生了(太)).
完全符合POSIX标准的解决方案有限制或需要额外的工作.
如果find的输出是在被捕获文件反正(或完全抑制),然后从基于管线的解决方案乔纳森·莱弗勒的回答很简单,健壮,符合POSIX标准:
find . 2>&1 >files_and_folders | grep -v 'Permission denied' >&2
Run Code Online (Sandbox Code Playgroud)
请注意,重定向的顺序很重要:2>&1必须先行.
在前面的文件中捕获stdout输出允许仅通过管道2>&1发送错误消息,然后可以明确地操作.grep
该唯一的缺点是,整体退出代码将是grep命令的,不是find的,在这种情况下意味着:如果有没有在所有或错误,只允许被拒绝的错误,退出代码将是1(信号故障),否则(除了权限被拒绝的错误之外的错误)0- 这与意图相反.
也就是说,find无论如何都很少使用退出代码,因为它通常会传递除基本故障之外的少量信息,例如传递不存在的路径.
然而,即使只有特定的情况下的一些输入路径由于缺乏权限的不可访问的是反映在find的退出代码(在GNU和BSD find):如果出现权限被拒绝的错误任何处理的文件的,在退出代码设置为1.
以下变体解决了以下问题:
find . 2>&1 >files_and_folders | { grep -v 'Permission denied' >&2; [ $? -eq 1 ]; }
Run Code Online (Sandbox Code Playgroud)
现在,退出代码指示任何错误,是否比其他 Permission denied发生:1如果是这样,0否则.
换句话说:退出代码现在反映了命令的真实意图:0如果没有错误或仅发生权限拒绝错误,则报告success().
这可以说比传递find退出代码更好,就像在顶部的解决方案一样.
评论中的gniourf_gniourf提出了一种(仍然符合POSIX标准)使用复杂重定向来推广此解决方案,即使将文件路径打印到stdout的默认行为也是如此:
{ find . 3>&2 2>&1 1>&3 | grep -v 'Permission denied' >&3; } 3>&2 2>&1
Run Code Online (Sandbox Code Playgroud)
简而言之:自定义文件描述符3用于临时交换stdout(1)和stderr(2),因此单独的错误消息可以grep通过stdout 传送到.
如果没有这些重定向,数据(文件路径)和错误消息都将grep通过stdout 传送到管道,grep然后无法区分错误消息 Permission denied和名称恰好包含该短语的(假设的)文件Permission denied.
但是,与第一个解决方案一样,报告的退出代码将是grep's,而不是find,但可以应用与上述相同的修复.
有几点需要注意迈克尔Brux的回答,find . ! -readable -prune -o -print:
它需要GNU find ; 值得注意的是,它不适用于macOS.当然,如果您只需要使用命令来使用GNU find,这对您来说不是问题.
某些Permission denied错误可能仍然存在:find ! -readable -prune报告当前用户具有权限但缺少(可执行)权限的目录的子项目的此类错误.原因是因为目录本身是可读的,不会被执行,并且尝试下降到该目录然后会触发错误消息.也就是说,典型的情况是许可被遗漏.rx-pruner
注意:以下几点是哲学和/或特定用例的问题,您可能认为它与您无关,并且该命令可以很好地满足您的需求,特别是如果您只需要打印路径:
findfind-name,如下所示:find . ! -readable -prune -o -name '*.txt'-print操作(可在此答案中找到解释).这种微妙之处可能会引入漏洞.在第一个解决方案乔纳森·莱弗勒的回答,find . 2>/dev/null > files_and_folders如他自己陈述, 一味沉默所有的错误信息(和解决方法很麻烦并没有完全健壮,他也解释了).从务实角度来说,但是,这是最简单的解决方案,因为你可能会内容承担任何和所有的错误都会被允许相关.
雾的回答,sudo find . > files_and_folders,简洁,务实的,但不明智的不仅仅是任何其他打印的文件名,出于安全方面的原因:是因为你作为运行根用户,"你可能有你的整个系统在发现bug被搞砸了或者是一个恶意版本,或者是一个意外写入错误的错误调用,如果你以正常的权限运行它,就不会发生这种情况"(来自对三人的薄雾回答的评论).
在第二个解决方案viraptor的答案,find . 2>&1 | grep -v 'Permission denied' > some_file运行误报的风险(由于通过管道传送输出和错误的混合),以及潜在的,而不是报告不通过stderr -permission被拒绝的错误,捕捉他们旁边的输出路径在输出文件中.
Fat*_*ksu 108
如果你想从root"/"开始搜索,你可能会看到输出的东西,比如:
find: /./proc/1731/fdinfo: Permission denied
find: /./proc/2032/task/2032/fd: Permission denied
Run Code Online (Sandbox Code Playgroud)
这是因为许可.要解决这个问题:
你可以使用sudo命令:sudo find /. -name 'toBeSearched.file'.它询问超级用户的密码,输入密码后你会看到你真正想要的结果.
您可以使用将标准错误输出(通常显示/屏幕)重定向到某个文件,避免在屏幕上看到错误消息!重定向到特殊文件/ dev/null:
find /. -name 'toBeSearched.file' 2>/dev/null
Run Code Online (Sandbox Code Playgroud)您可以使用标准错误输出从(通常显示/屏幕)重定向到标准输出(通常显示/屏幕),然后使用带有-v"invert"参数的grep命令管道,以便不查看具有"权限被拒绝"的输出行单词对:
find /. -name 'toBeSearched.file' 2>&1 | grep -v 'Permission denied'
Run Code Online (Sandbox Code Playgroud)小智 91
我不得不使用:
find / -name expect 2>/dev/null
Run Code Online (Sandbox Code Playgroud)
指定我想要查找的名称,然后告诉它将所有错误重定向到/ dev/null
期待成为我正在寻找的期待计划的位置.
Mat*_*att 58
管stderr以/dev/null通过使用2>的/ dev/null的
find . -name '...' 2>/dev/null
sda*_*aau 30
您还可以使用-perm和-prune谓词来避免降级到不可读的目录(另请参阅如何从查找程序中删除"权限被拒绝"的打印输出语句? - Unix和Linux Stack Exchange):
find . -type d ! -perm -g+r,u+r,o+r -prune -o -print > files_and_folders
Run Code Online (Sandbox Code Playgroud)
Jas*_*oco 23
重定向标准错误.例如,如果您在unix机器上使用bash,则可以将标准错误重定向到/ dev/null,如下所示:
find . 2>/dev/null >files_and_folders
Run Code Online (Sandbox Code Playgroud)
Bun*_*nti 19
虽然上述方法没有解决Mac OS X的情况,因为Mac OS X不支持-readable切换,但这是如何避免输出中的"Permission denied"错误.这可能对某人有帮助.
find / -type f -name "your_pattern" 2>/dev/null.
find例如,如果您正在使用其他命令,则查找目录中某些模式的文件大小2>/dev/null仍然可以正常工作,如下所示.
find . -type f -name "your_pattern" -exec du -ch {} + 2>/dev/null | grep total$.
这将返回给定模式的文件的总大小.请注意2>/dev/nullfind命令的末尾.
vir*_*tor 13
这些错误打印到标准错误输出(fd 2).要过滤掉它们,只需将所有错误重定向到/ dev/null:
find . 2>/dev/null > some_file
Run Code Online (Sandbox Code Playgroud)
或者首先加入stderr和stdout然后grep out那些特定的错误:
find . 2>&1 | grep -v 'Permission denied' > some_file
Run Code Online (Sandbox Code Playgroud)
wjo*_*dan 10
find . > files_and_folders 2>&-
2>&-closing(-)标准错误文件描述符(2),以便所有错误消息都被静音.
1如果Permission denied否则会打印任何错误,退出代码仍然是find:find . -type d \! \( -readable -executable \) -prune -print -o -print > files_and_folders
通过额外的选项find是-prune(防止下降到),但仍-print任何目录(),其不()同时拥有和权限,或()的任何其他文件.-typed\!-readable-executable-o-print
-readable和-executable选项是GNU扩展,不是POSIX标准的一部分Permission denied在异常/损坏的文件上返回' '(例如,请参阅使用<v2.0.5 影响容器挂载文件系统的错误报告lxcfs)find(GNU,OSX/BSD等){ LC_ALL=C find . 3>&2 2>&1 1>&3 > files_and_folders | grep -v 'Permission denied'; [ $? = 1 ]; } 3>&2 2>&1
使用管道将标准错误流传递给grep,删除包含该'Permission denied'字符串的所有行.
LC_ALL=C使用环境变量设置POSIX语言环境,3>&2 2>&1 1>&3并使用3>&2 2>&1 重复的文件描述符将标准错误流传递给grep,并[ $? = 1 ]使用它[]来反转返回的错误代码grep以近似原始行为find.
'Permission denied'由于输出重定向导致的任何错误(例如,如果files_and_folders文件本身不可写)