如何从“查找”中排除所有“拒绝权限”消息?

我需要隐藏以下所有拒绝权限的消息:

find . > files_and_folders

我正在尝试何时出现此类消息。 我需要收集所有不会出现的文件夹和文件。

是否可以将权限级别files_and_foldersfiles_and_folders文件?

如何同时隐藏错误?


#1楼

您还可以使用-perm-prune谓词来避免进入不可读的目录(另请参见如何从查找程序中删除“ permission否认”的打印输出语句?-Unix&Linux Stack Exchange ):

find . -type d ! -perm -g+r,u+r,o+r -prune -o -print > files_and_folders

#2楼

采用:

find . ! -readable -prune -o -print

或更一般地

find <paths> ! -readable -prune -o <other conditions like -name> -print
  • 避免“权限被拒绝”
  • 并且不要抑制(其他)错误消息
  • AND并获得退出状态0(“所有文件已成功处理”)

适用于:find(GNU findutils)4.4.2。 背景:

  • - -readable测试匹配可读文件。 ! 当test为false时,运算符返回true。 还有! -readable ! -readable匹配不可读的目录(&file)。
  • -prune操作不会进入目录。
  • ! -readable -prune ! -readable -prune可以转换为:如果目录不可读,则不要进入该目录。
  • - -readable测试考虑了-perm测试忽略的访问控制列表和其他权限伪像。

另请参见find (1)联机帮助页


#3楼

为了避免获得权限拒绝警告,请通过搜索从修剪中删除不可读文件,以使find忽略它们。 将表达式作为OR添加到您的发现中,例如

find / \! -readable -prune -o -name '*.jbd' -ls

这主要是说(匹配一个不可读的文件并从列表中删除 (匹配一个 * .jbd之类的名称, 并显示它(带有ls)) 。 (请记住,默认情况下,除非使用-or,否则表达式将与在一起。)您需要在第二个表达式中使用-ls,否则find可能会添加默认操作来显示任一匹配项,这还将显示所有不可读的文件。

但是,如果要在系统上查找真实文件,通常没有理由在/ dev中查找文件,因为它有很多文件,因此应添加一个排除该目录的表达式,例如:

find / -mount \! -readable -prune  -o  -path /dev -prune  -o  -name '*.jbd' -ls

因此(匹配列表中的不可读文件和修剪)(匹配 列表 中的路径/ dev和修剪)(匹配 * .jbd 这样的文件 并显示)


#4楼

采用

sudo find / -name file.txt

这很愚蠢(因为您提高了搜索范围)并且不安全,但是编写起来却短得多。


#5楼

尽管上述方法无法解决Mac OS X的问题,因为Mac OS X不支持- -readable开关,这是可以避免输出中出现“权限被拒绝”错误的方法。 这可能会帮助某人。

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$ find . -type f -name "your_pattern" -exec du -ch {} + 2>/dev/null | grep total$

这将返回给定模式的文件总大小。 注意find命令末尾的2>/dev/null


#6楼

注意:
*这个答案可能比用例需要的要深,并且find 2>/dev/null在许多情况下可能已经足够了。对于跨平台的观点及其对某些高级Shell技术的讨论,尽管找到的情况可能是假设的,但仍可能会引起人们的兴趣,以便找到一种尽可能健壮的解决方案。
* 如果您的系统配置为显示本地化的错误消息 ,请在下面的find调用前添加LC_ALL=CLC_ALL=C find ... ),以确保报告了英语消息,以便grep -v 'Permission denied'按预期工作。但是,无论如何,任何确实显示的错误消息将以英语显示。

如果您的shell是bashzsh ,那么有一种解决方案既健壮又相当简单使用符合POSIX的find功能 ; 尽管bash本身不是POSIX的一部分,但大多数现代Unix平台都随附了它,这使得该解决方案具有广泛的可移植性:

find . > files_and_folders 2> >(grep -v 'Permission denied' >&2)

注意: grep的某些输出 find完成后很可能会到达,因为整体命令不会等待>(...)的命令完成。 在bash ,可以通过附加| cat来防止这种情况| cat | cat命令。

  • >(...)是(很少使用的) 输出 过程替代 ,它允许将输出(在这种情况下,将stderr output( 2> )重定向到>(...)内部命令的stdin。
    除了bashzshksh 原则上也支持它们,但是尝试将它们与stderr的重定向结合起来(如此处( 2> >(...) )所示)似乎被默默忽略(在ksh 93u+ ) 。

    • grep -v 'Permission denied'过滤-v )(从find命令的stderr流中)包含短语Permission denied的所有行,并将其余行输出到stderr( >&2 )。

这种方法是:

  • 健壮grep仅应用于错误消息 (不适用于文件路径和错误消息的组合,有可能导致误报),并且除权限被拒绝的错误消息之外的其他错误消息也将传递到stderr。

  • 无副作用find的退出代码被保留:无法访问至少遇到的文件系统项目之一导致退出代码1 (尽管这不会告诉你比许可被拒绝那些其他错误是否发生了(太) )。


符合POSIX的解决方案:

完全符合POSIX的解决方案有局限性或需要其他工作。

如果无论如何都要将find的输出捕获到一个文件中 (或完全删除),那么Jonathan Leffler的回答基于管道的解决方案将是简单,健壮且符合POSIX的:

find . 2>&1 >files_and_folders | grep -v 'Permission denied' >&2

请注意,重定向的顺序很重要: 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 ]; }

现在,退出代码指示是否发生了除“ Permission denied 以外的任何错误:如果是,则为1 ,否则为0
换句话说:退出代码现在反映了命令的真实意图:如果根本没有错误或者发生了权限被拒绝的错误,则报告成功( 0 )。
可以说,这比仅仅传递find的退出代码更好,例如在顶部的解决方案中。


注释中的gniourf_gniourf建议使用复杂的重定向对该解决方案进行通用化 (仍符合POSIX要求) ,该重定向 甚至可以使用将文件路径打印到stdout的默认行为进行工作

{ find . 3>&2 2>&1 1>&3 | grep -v 'Permission denied' >&3; } 3>&2 2>&1

简而言之:自定义文件描述符3用于临时交换stdout( 1 )和stderr( 2 ),以便可以通过stdout将错误消息单独传递给grep

如果没有这些重定向,则数据(文件路径) 错误消息都将通过stdout通过管道传递到grep ,然后grep将无法区分错误消息 Permission denied其名称恰好包含短语Permission denied的(假设) 文件

但是,与第一个解决方案一样,报告的退出代码将是grep而不是find ,但是可以应用与上述相同的修复程序。


现有答案的注释:

  • 关于Michael Brux的答案 ,有几点要注意find . ! -readable -prune -o -print find . ! -readable -prune -o -print find . ! -readable -prune -o -print

    • 它需要GNU find ; 值得注意的是,它不适用于macOS。 当然,如果您只需要使用该命令来使用GNU find ,这对您就不会有问题。

    • 某些Permission denied错误可能仍会浮出水面: find ! -readable -prune find ! -readable -prune报告当前用户确实具有r权限但缺乏x (可执行)权限的目录项的此类错误。 原因是因为目录本身可读的,所以不会执行-prune ,并且尝试进入该目录会触发错误消息。 也就是说, 典型的情况是缺少r许可。

    • 注意:以下几点是有关原理和/或特定用例的问题,您可能会决定它与您无关,并且该命令非常适合您的需求,尤其是仅打印路径就是您所做的一切时:

      • 如果将允许拒绝的错误消息的过滤概念化,这是一个您希望能够应用于任何 find命令的单独任务,那么主动预防允许被拒绝的错误的相反方法是在find命令中引入“噪声”,即还介绍了复杂性和逻辑陷阱
      • 例如,对Michael的回答(在撰写本文时),投票最多的评论试图显示如何通过包含-name过滤器来扩展命令,如下所示:
        find . ! -readable -prune -o -name '*.txt'
        然而,这并不因为后工作打算, -print 需要采取行动(的解释中可以找到这个答案 )。 这样的微妙之处可能会引入错误。
  • 乔纳森·莱夫勒(Jonathan Leffler)的答案的第一个解决方案是find . 2>/dev/null > files_and_folders find . 2>/dev/null > files_and_folders ,正如他本人所言, 盲目地使所有错误消息 find . 2>/dev/null > files_and_folders (而且解决方法很麻烦,而且也不完全健壮,正如他还解释的那样)。 实用地说 ,这是最简单的解决方案 ,因为您可能会满意地假设所有错误都与权限相关。

  • 薄雾的答案sudo find . > files_and_folders sudo find . > files_and_folders 简洁,务实,但出于安全考虑, 除了仅打印文件名外不建议使用其他任何方法 :由于您以root用户身份运行,“您可能会因find或bug的混乱而使整个系统陷入混乱恶意版本,或不正确的调用会意外地写入内容,如果您以正常权限运行此文件,则不会发生”(摘自Tripleee关于Mist的回答的评论 )。

  • Viraptor的答案中的第二个解决方案, find . 2>&1 | grep -v 'Permission denied' > some_file find . 2>&1 | grep -v 'Permission denied' > some_file find . 2>&1 | grep -v 'Permission denied' > some_file存在误报的风险(由于通过管道发送stdout和stderr的混合),并且有可能代替通过stderr报告权限拒绝的错误,而是将它们捕获到输出文件中的输出路径。


#7楼

上面的答案对我都不起作用。 我在Internet上找到的一切都集中在:隐藏错误。 没有正确处理流程的返回码/退出码。 我在bash脚本中使用命令find查找一些目录,然后检查其内容。 我使用退出代码评估命令是否成功:零值有效,否则失败。

迈克尔·布鲁克斯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脚本解决方案更改为:

很高兴找到/ home * / -maxdepth 5-关注\\
\\( -type d -a !\\(-可读-a-可执行\\) \\) -修剪 \\
-o \\
\\(-type d -a-可读-a-可执行-a -name“ $ {m_find_name}” \\)-print

此处的关键是为组合表达式放置“ not true”:

has read access AND has execute access

否则,它没有完全访问权限,这意味着:修剪它。 在以前建议的解决方案失败的一种情况下,这证明对我有用。

我在评论部分提供了以下技术详细信息。 如果细节过多,我深表歉意。

  • ¿为什么使用命令nice? 我在这里有了主意。 最初,我认为在查看整个文件系统时降低进程优先级会很好。 我意识到这对我来说毫无意义,因为我的脚本仅限于几个目录。 我将-maxdepth减少到3。
  • ¿为什么在/ home * /中搜索? 这与此线程无关。 我通过与非特权用户(不是root)一起编译的源代码手动安装所有应用程序。 它们安装在“ / home”中。 我可以同时存在多个二进制文件和版本。 我需要找到所有目录,以主从方式检查和备份。 我可以有多个“ / home”(专用服务器中运行着几个磁盘)。
  • ¿为什么使用-follow? 用户可以创建指向目录的符号链接。 它的有用性取决于,我需要记录找到的绝对路径。

#8楼

简单答案:

find . > files_and_folders 2>&-

2>&-关闭( - )标准错误文件描述符( 2 ),因此所有错误消息均被静音。

  • 如果以其他方式显示“ Permission denied ”错误,则退出代码仍为1

对于GNU强大的答案find

find . -type d \\! \\( -readable -executable \\) -prune -print -o -print > files_and_folders

传递额外的选项以find -prune (防止降序进入),但仍-print任何不具有( \\! )同时具有- -readable和- -executable权限的目录( -type d ),或者( -o )- -print任何其他文件。

  • -readable-executable选项是GNU的扩展,而不是部分POSIX标准
  • 仍可能在异常/损坏的文件上返回“ Permission denied ”(例如,请参见影响使用lxcfs <v2.0.5的容器安装的文件系统的错误报告

适用于任何POSIX兼容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使用环境变量3>&2 2>&1 1>&33>&2 2>&1 复制文件描述符设置POSIX语言 环境 ,以将标准错误流传grep[ $? = 1 ] [ $? = 1 ]使用[]反转grep返回的错误代码,以近似find的原始行为。

  • 还将过滤由于输出重定向而导致的任何'Permission denied'错误(例如,如果files_and_folders文件本身不可写)

#9楼

您可以使用grep -v反向匹配

-v, --invert-match        select non-matching lines

像这样:

find . > files_and_folders
cat files_and_folders | grep -v "permission denied" > files_and_folders

应该去魔术


#10楼

您也是将查找结果保存在文件中的简单解决方案。

找 。 -名称'NameOfSearchedFile'>> results.txt


#11楼

-=对于MacOS =-

使用别名创建新命令:只需添加〜/ .bash_profile行:

alias search='find / -name $file 2>/dev/null'

在新的“终端”窗口中,您可以调用它:

$ file=<filename or mask>; search

例如:

$ file = etc; 搜索


#12楼

如果您使用的是CSH或TCSH,请使用以下解决方案:

( find . > files_and_folders ) >& /dev/null

如果要输出到终端:

( find . > /dev/tty ) >& /dev/null

但是, 如“ csh-whynot”常见问题解答所述,您不应使用CSH。


#13楼

采用:

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过滤标准输出(您可以决定想要的输出有多高,可能取决于语言环境和O / S来更改拼写),最后的>&2表示尚存错误消息(写入标准输出)再次进入标准错误。 最终重定向在终端上可以看作是可选的,但是在脚本中使用它是一个很好的主意,以便错误消息出现在标准错误上。

根据您要执行的操作,此主题有很多变体。 它可以在带有Bourne Shell派生类(Bash,Korn等)和POSIX兼容版本的find任何Unix变体上运行。

如果您希望适应系统上使用的find的特定版本,则可能有其他选择。 特别是GNU find有许多其他版本中没有的选项-请参阅当前接受的答案中的一组这样的选项。


#14楼

重定向标准错误。 例如,如果您在UNIX机器上使用bash,则可以将标准错误重定向到/ dev / null,如下所示:

find . 2>/dev/null >files_and_folders

#15楼

stderr/dev/null通过使用2>的/ dev / null的

find . -name '...' 2>/dev/null


#16楼

这些错误将打印到标准错误输出(fd 2)。 要过滤掉它们,只需将所有错误重定向到/ dev / null即可:

find . 2>/dev/null > some_file

或先加入stderr和stdout,然后grep删除那些特定的错误:

find . 2>&1 | grep -v 'Permission denied' > some_file

#17楼

我不得不使用:

find / -name expect 2>/dev/null

指定我要查找的名称,然后告诉它将所有错误重定向到/ dev / null

期望是我正在搜索的期望程序的位置。


#18楼

如果要从根“ /”开始搜索,则可能会看到类似以下的输出:

find: /./proc/1731/fdinfo: Permission denied
find: /./proc/2032/task/2032/fd: Permission denied

是因为允许。 要解决这个问题:

  1. 您可以使用sudo命令: sudo find /. -name 'toBeSearched.file' sudo find /. -name 'toBeSearched.file' 。 它询问超级用户的密码,当输入密码时,您将看到您真正想要的结果。

  2. 您可以使用将“标准错误输出”从(通常是显示/屏幕)重定向到某些文件,并避免在屏幕上看到错误消息! 重定向到特殊文件/ dev / null:

     find /. -name 'toBeSearched.file' 2>/dev/null 
  3. 您可以使用将标准错误输出从(通常显示/屏幕)重定向到标准输出(通常显示/屏幕),然后使用带有-v“ invert”参数的grep命令进行管道处理,以不显示具有“权限被拒绝”的输出行单词对:

     find /. -name 'toBeSearched.file' 2>&1 | grep -v 'Permission denied' 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值