我需要隐藏所有权限被拒绝的消息:
find . > files_and_folders
我正在尝试这样的消息出现时。我需要收集所有不会出现的文件夹和文件。
是否可以将权限级别定向到files_and_folders
文件?
如何同时隐藏错误?
答案 0 :(得分:527)
使用:
find . 2>/dev/null > files_and_folders
当然,这不仅会隐藏Permission denied
错误,还会隐藏所有错误消息。
如果你真的想要保留其他可能的错误,例如符号链接上的跳数过多,而不是允许拒绝的错误,那么你可能不得不猜测你没有很多名为'的文件'许可被拒绝'并尝试:
find . 2>&1 | grep -v 'Permission denied' > files_and_folders
如果您只想过滤标准错误,可以使用更精细的构造:
find . 2>&1 > files_and_folders | grep -v 'Permission denied' >&2
find
命令的I / O重定向为:2>&1 > files_and_folders |
。
管道将标准输出重定向到grep
命令并首先应用。 2>&1
将标准错误发送到与标准输出(管道)相同的位置。 > files_and_folders
将标准输出(但不是标准错误)发送到文件。最终结果是写入标准错误的消息沿管道发送,find
的常规输出写入文件。 grep
过滤标准输出(您可以决定您希望它具有多大的选择性,并且可能必须根据区域设置和操作系统更改拼写),最终>&2
表示存活错误消息(写入标准输出)再次转到标准错误。最终的重定向在终端上可以被视为可选的,但在脚本中使用它是一个非常好的主意,以便在标准错误中出现错误消息。
这个主题有无穷无尽的变化,取决于你想做什么。这适用于任何带有任何Bourne shell衍生物(Bash,Korn,...)和任何符合POSIX的find
版本的Unix版本。
如果您希望适应系统中find
的特定版本,可能会有其他选项。 GNU find
特别具有其他版本中无法提供的无数选项 - 请参阅当前接受的一组选项的答案。
答案 1 :(得分:268)
使用:
find . ! -readable -prune -o -print
或更一般地
find <paths> ! -readable -prune -o <other conditions like -name> -print
适用于:find(GNU findutils)4.4.2。 背景:
-readable
测试与可读文件匹配。当test为false时,!
运算符返回true。并且! -readable
匹配不可读的目录(&amp; files)。-prune
操作不会进入目录。! -readable -prune
可以翻译为:如果目录不可读,请不要进入。-readable
测试考虑了-perm
测试忽略的访问控制列表和其他权限假象。有关更多详细信息,另请参阅find
(1) manpage。
答案 2 :(得分:224)
注意:
*这个答案可能比用例保证更深入,find 2>/dev/null
在许多情况下可能已经足够好了。对于跨平台的观点以及为了找到尽可能强大的解决方案而讨论一些先进的shell技术可能仍然有意义,即使防范的案例可能在很大程度上是假设的。
* 如果您的系统配置为显示本地化错误消息,请使用find
(LC_ALL=C
)为LC_ALL=C find ...
以下grep -v 'Permission denied'
来电添加前缀,以确保报告英语消息,以便bash
按预期工作。但是,任何 显示的错误消息都会以英语显示。功能
如果你的 shell是zsh
或find
,那么一个非常强大而且相当简单的解决方案,使用< strong>仅符合POSIX标准bash
功能;虽然find . > files_and_folders 2> >(grep -v 'Permission denied' >&2)
本身不是POSIX的一部分,但大多数现代Unix平台都附带它,使这个解决方案具有广泛的可移植性:
grep
注意:在 find
完成后,某些>(...)
的输出很可能会到达,因为整体命令并非如此; t等待bash
内的命令完成。在| cat
中,您可以通过在命令中附加>(...)
来阻止此操作。
2>
是一个(很少使用)输出 process substitution,它允许重定向输出(在本例中为 stderr 输出({ {1}})>(...)
内命令的标准输入
除了bash
和zsh
之外,ksh
原则上也支持 ,但尝试将它们与来自 stderr 的重定向相结合,就像这里所做的那样(2> >(...)
),似乎被默默忽略(在ksh 93u+
中)。
grep -v 'Permission denied'
过滤 out (-v
)包含短语{{1}的所有行(来自find
命令的stderr流)并将剩余的行输出到stderr(Permission denied
)。这种方法是:
健壮:>&2
仅适用于错误消息(而不是文件路径和错误消息的组合,可能导致错误积极的),以及除了权限被拒绝的错误消息传递给stderr。
免费副作用:grep
的退出代码被保留:无法访问至少一个遇到的文件系统项导致退出代码{ {1}}(虽然这不会告诉您错误其他是否也发生了许可拒绝的错误)。
完全符合POSIX标准的解决方案要么有局限性,要么需要额外的工作。
如果要在文件中 (或完全取消)捕获find
的输出,那么基于管道的解决方案来自Jonathan Leffler's answer简单,强大且符合POSIX标准:
1
请注意,重定向的顺序很重要:find
必须首先。
预先在文件中捕获stdout输出允许find . 2>&1 >files_and_folders | grep -v 'Permission denied' >&2
通过管道发送仅错误消息,然后2>&1
可以明确地操作。
唯一的缺点是整体退出代码将是2>&1
命令,而不是grep
&#39; s,在这种情况下意味着:如果完全存在 no 错误或仅权限被拒绝错误,则退出代码将为grep
(信令失败),否则(除了权限被拒绝的错误)find
- 这与意图相反。
也就是说,1
的退出代码很少被使用,因为它通常会传递除基本失败之外的一些信息,例如传递不存在的信息路径。
但是,即使只有某些输入路径由于缺少权限而无法访问的特定情况也会反映在0
的退出代码中(在GNU和BSD find
)中:如果处理的任何文件发生权限被拒绝,则退出代码设置为find
。
以下变体解决了:
find
现在,退出代码指示是否发生 1
以外的任何错误:find . 2>&1 >files_and_folders | { grep -v 'Permission denied' >&2; [ $? -eq 1 ]; }
如果是,Permission denied
否则。1
。
换句话说:退出代码现在反映了命令的真实意图:如果没有错误或仅发生 权限拒绝错误,则报告成功(0
)。
这可以说比通过0
的退出代码更好,就像在顶部的解决方案中一样。
gniourf_gniourf提出了一个(仍然符合POSIX标准)使用复杂重定向来概括此解决方案,即使使用打印文件路径的默认行为也能正常工作标准输出 强>:
find
简而言之:自定义文件描述符{ find . 3>&2 2>&1 1>&3 | grep -v 'Permission denied' >&3; } 3>&2 2>&1
用于临时交换stdout(3
)和stderr(1
),因此单独的错误消息 可以通过stdout传送到2
。
如果没有这些重定向,数据(文件路径)和错误消息将通过stdout传送到grep
,grep
将无法区分< em>错误消息 grep
和一个(假设的)文件,其名称恰好包含短语Permission denied
。
与第一个解决方案一样,报告的退出代码为Permission denied
,而不是grep
,但可以应用与上述相同的修复
有关Michael Brux's answer,find
的几点注意事项:
它需要 GNU find . ! -readable -prune -o -print
;值得注意的是,它不会在macOS上工作。当然,如果您只需要使用命令来处理GNU find
,那么这对您来说不会有问题。
某些find
错误可能仍表面:Permission denied
报告当前用户的子目录项的此类错误是否拥有find ! -readable -prune
权限,但缺少r
(可执行)权限。原因是因为目录本身是可读的,所以x
没有执行,并且尝试将下降到该目录然后触发错误消息。也就是说,典型的案例是-prune
允许丢失的。
注意:以下几点是哲学和/或特定用例的问题,您可能认为它与您无关,并且该命令可以很好地满足您的需求,特别是如果只是打印< / em>路径就是你所做的一切:
r
命令,这也引入了复杂性和逻辑陷阱。find
过滤器来展示如何扩展命令,如下:find
-name
操作必需(可以在this answer中找到解释)。这种微妙之处可能会引入错误。 Jonathan Leffler's answer中的第一个解决方案,find . ! -readable -prune -o -name '*.txt'
,正如他自己所说,盲目地沉默所有错误消息(以及解决方法)他解释说,这很麻烦而且不够完整。 务实地说,但它是最简单的解决方案,因为您可能会满足于假设任何和所有错误都与权限相关。
mist's answer,-print
,简明实用,但除了打印文件名之外的其他任何内容都是不明智的,安全原因:因为您作为 root 用户运行,&#34;您可能会因查找或恶意版本中的错误或不正确的调用而导致整个系统混乱意外地写了一些东西,如果你用正常的权限运行它就不会发生这种情况。 (来自tripleee对雾的答案的评论)。
viraptor's answer中的第二个解决方案,find . 2>/dev/null > files_and_folders
存在误报的风险(由于通过管道发送混合的stdout和stderr),并且可能不会报告<通过stderr将em> non -permission-denied错误捕获,并将它们与输出文件中的输出路径一起捕获。
答案 3 :(得分:107)
如果你想从根“/”开始搜索,你可能会看到输出的东西,如:
find: /./proc/1731/fdinfo: Permission denied
find: /./proc/2032/task/2032/fd: Permission denied
这是因为许可。要解决这个问题:
您可以使用sudo命令:sudo find /. -name 'toBeSearched.file'
。它询问超级用户的密码,输入密码后你会看到你真正想要的结果。
您可以使用(通常显示/屏幕)的标准错误输出重定向到某个文件,避免在屏幕上看到错误消息!重定向到特殊文件/ dev / null:
find /. -name 'toBeSearched.file' 2>/dev/null
您可以使用标准错误输出从(一般显示/屏幕)重定向到标准输出(一般显示/屏幕),然后使用带有-v“invert”参数的grep命令管道,以便不看输出线其中有“权限被拒绝”字对:
find /. -name 'toBeSearched.file' 2>&1 | grep -v 'Permission denied'
答案 4 :(得分:88)
我不得不使用:
find / -name expect 2>/dev/null
指定我想要查找的名称,然后告诉它将所有错误重定向到/ dev / null
期待成为我正在寻找的期待计划的位置。
答案 5 :(得分:54)
使用 2&gt; / dev / null
将stderr
导管到/dev/null
find . -name '...' 2>/dev/null
答案 6 :(得分:29)
您还可以使用-perm
和-prune
谓词来避免降级到不可读的目录(另请参阅How do I remove "permission denied" printout statements from the find program? - Unix & Linux Stack Exchange):
find . -type d ! -perm -g+r,u+r,o+r -prune -o -print > files_and_folders
答案 7 :(得分:23)
重定向标准错误。例如,如果你在unix机器上使用bash,你可以将标准错误重定向到/ dev / null,如下所示:
find . 2>/dev/null >files_and_folders
答案 8 :(得分:19)
虽然上述方法无法解决Mac OS X的问题,因为Mac OS X不支持a {
color: #c54bb7 !important; (it's a sort of red)
text-decoration: none !important;
}
切换,但您可以避免输出中出现“权限被拒绝”错误。这可能对某人有所帮助。
-readable
。
例如,如果您使用find / -type f -name "your_pattern" 2>/dev/null
的其他命令,要查找目录find
中某些模式的文件大小,仍然可以如下所示。
2>/dev/null
。
这将返回给定模式的文件的总大小。请注意find命令末尾的find . -type f -name "your_pattern" -exec du -ch {} + 2>/dev/null | grep total$
。
答案 9 :(得分:13)
这些错误打印到标准错误输出(fd 2)。要过滤掉它们,只需将所有错误重定向到/ dev / null:
find . 2>/dev/null > some_file
或首先加入stderr和stdout然后grep out那些特定的错误:
find . 2>&1 | grep -v 'Permission denied' > some_file
答案 10 :(得分:10)
find . > files_and_folders 2>&-
2>&-
关闭(-
)标准错误文件描述符(2
),以便所有错误消息都被静音。
1
”错误,退出代码仍为Permission denied
find
的强大答案: find . -type d \! \( -readable -executable \) -prune -print -o -print > files_and_folders
将额外选项传递给find
-prune
(防止降级),但仍然-print
任何目录(-type
d
) (\!
)拥有-readable
和-executable
权限,或(-o
)-print
任何其他文件。
-readable
和-executable
选项是GNU扩展,不属于POSIX standard Permission denied
”(例如,请参阅bug report使用lxcfs
&lt; v2.0.5来影响装有容器的文件系统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
使用pipeline将标准错误流传递给grep
,删除包含'Permission denied'
字符串的所有行。
LC_ALL=C
使用POSIX locale,3>&2 2>&1 1>&3
和3>&2 2>&1
environment variable设置duplicate file descriptors,以便将标准错误流传输到grep
和[ $? = 1 ]
使用[]
来反转grep
返回的错误代码,以接近find
的原始行为。
'Permission denied'
错误(例如,如果files_and_folders
文件本身不可写)答案 11 :(得分:4)
使用
sudo find / -name file.txt
这是愚蠢的(因为你提升了搜索)和非安全,但写得更短。
答案 12 :(得分:4)
要避免只是权限被拒绝的警告,请告诉find通过从搜索中删除它们来忽略不可读的文件。将表达式作为OR添加到您的查找中,例如
find / \! -readable -prune -o -name '*.jbd' -ls
这主要是指(匹配一个不可读的文件并从列表中删除它)或(匹配一个名称,如 * .jbd 并显示它[与LS])。 (请记住,除非你使用-or,否则默认情况下表达式是AND。)你需要在第二个表达式中使用-ls,否则find可以添加一个默认动作来显示匹配,这也会显示所有不可读的文件
但是如果你在你的系统上寻找真实文件,通常没有理由查看/ dev,它有很多文件,所以你应该添加一个排除该目录的表达式,如:
find / -mount \! -readable -prune -o -path /dev -prune -o -name '*.jbd' -ls
所以(匹配不可读的文件和从列表中删除)或(匹配路径/ dev和从列表中删除)或(匹配文件,如 * .jbd 并显示它)。
答案 13 :(得分:2)
上述答案都不适合我。无论我在互联网上发现什么,重点是:隐藏错误。没有正确处理进程返回代码/退出代码。我在bash脚本中使用命令查找一些目录,然后检查它们的内容。我使用退出代码评估命令查找成功:值零工作,否则失败。
answer provided above Michael Brux有时可以正常工作。但我有一个失败的场景!我发现了这个问题并自己解决了。我需要在以下时间修剪文件:
it is a directory AND has no read access AND/OR has no execute access
这里看到的关键问题是:AND / OR。我读到的一个好的建议条件序列是:
-type d ! -readable ! -executable -prune
这始终不起作用。这意味着当匹配为:
时会触发剪枝it is directory AND no read access AND no execute access
当授予读访问权但没有执行访问权时,此表达式序列失败。
经过一些测试后,我意识到这一点并将我的shell脚本解决方案更改为:
nice find / home * / -maxdepth 5 -follow \
\(-type d -a !\(-readable -a -executable \) \)-prune \
-o \
\(-type d -a -readable -a -executable -a -name“$ {m_find_name}”\) - print
这里的关键是将“not true”放在组合表达式中:
has read access AND has execute access
否则它没有完全访问权限,这意味着:修剪它。事实证明,这在以前建议的解决方案失败的情况下对我有用。
我在评论部分提供了以下技术问题的详细信息。如果细节过多,我道歉。
答案 14 :(得分:2)
您可以使用grep -v invert-match
-v, --invert-match select non-matching lines
像这样:
find . > files_and_folders
cat files_and_folders | grep -v "permission denied" > files_and_folders
应该是魔术
答案 15 :(得分:2)
- =对于MacOS = -
使用别名创建一个新命令:只需添加〜/ .bash_profile行:
alias search='find / -name $file 2>/dev/null'
在新的终端窗口中,您可以调用它:
$ file=<filename or mask>; search
例如:
$ file = etc;搜索
答案 16 :(得分:0)
如果您使用CSH或TCSH,这是一个解决方案:
( find . > files_and_folders ) >& /dev/null
如果您想要输出到终端:
( find . > /dev/tty ) >& /dev/null
然而,as the "csh-whynot" FAQ describes, you should not use CSH.
答案 17 :(得分:0)
只需使用它来搜索系统中的文件。
find / -name YOUR_SEARCH_TERM 2>&1 | grep YOUR_SEARCH_TERM
我们不要做不必要的工程,你只是想搜索你的文件对吗?如果文件位于您可以访问的区域,那么该命令将为您列出文件。
答案 18 :(得分:-1)
您也可以轻松地将查找结果放入文件中。
找到。 -name&#39; NameOfSearchedFile&#39; &GT;&GT; RESULTS.TXT答案 19 :(得分:-1)
最小的解决方案就是添加 readable
标志。
find . -name foo -readable