我怎样才能排除所有“权限被拒绝”的情况? 来自“查找”的消息?

发布于 2024-07-18 02:50:34 字数 210 浏览 3 评论 0原文

我需要隐藏所有权限被拒绝消息:

find . > files_and_folders

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

是否可以将权限级别定向到 files_and_folders 文件?

如何同时隐藏错误?

I need to hide all permission denied messages from:

find . > files_and_folders

I am experimenting when such message arises. I need to gather all folders and files, to which it does not arise.

Is it possible to direct the permission levels to the files_and_folders file?

How can I hide the errors at the same time?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(21

萌酱 2024-07-25 02:50:34

用途:

find . 2>/dev/null > files_and_folders

当然,这不仅隐藏了权限被拒绝错误,还隐藏了所有错误消息。

如果您确实想保留其他可能的错误,例如符号链接上的跃点太多,但不想保留权限被拒绝的错误,那么您可能必须猜测您没有许多名为“权限被拒绝”的文件并尝试:

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 > 文件和文件夹|
管道将标准输出重定向到 grep 命令并首先应用。 2>&1 将标准错误发送到与标准输出相同的位置(管道)。 <代码>> files_and_folders 将标准输出(但不是标准错误)发送到文件。 最终结果是写入标准错误的消息被沿着管道发送,并且 find 的常规输出被写入文件。 grep 过滤标准输出(您可以决定它的选择性,并且可能必须根据语言环境和操作系统更改拼写)和最终的>& 。 2 意味着幸存的错误消息(写入标准输出)再次进入标准错误。 最终重定向在终端上可以被视为可选,但在脚本中使用它是一个非常好的主意,以便错误消息出现在标准错误上。

这个主题有无穷无尽的变化,具体取决于你想做什么。 这将适用于具有任何 Bourne shell 衍生品(Bash、Korn 等)的任何 Unix 变体以及任何 POSIX 兼容版本的 查找

如果您希望适应系统上的 find 特定版本,可能还有其他可用选项。 GNU find 特别具有其他版本中不可用的无数选项 - 请参阅当前接受的一组此类选项的答案。

Use:

find . 2>/dev/null > files_and_folders

This hides not just the Permission denied errors, of course, but all error messages.

If you really want to keep other possible errors, such as too many hops on a symlink, but not the permission denied ones, then you'd probably have to take a flying guess that you don't have many files called 'permission denied' and try:

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

If you strictly want to filter just standard error, you can use the more elaborate construction:

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

The I/O redirection on the find command is: 2>&1 > files_and_folders |.
The pipe redirects standard output to the grep command and is applied first. The 2>&1 sends standard error to the same place as standard output (the pipe). The > files_and_folders sends standard output (but not standard error) to a file. The net result is that messages written to standard error are sent down the pipe and the regular output of find is written to the file. The grep filters the standard output (you can decide how selective you want it to be, and may have to change the spelling depending on locale and O/S) and the final >&2 means that the surviving error messages (written to standard output) go to standard error once more. The final redirection could be regarded as optional at the terminal, but would be a very good idea to use it in a script so that error messages appear on standard error.

There are endless variations on this theme, depending on what you want to do. This will work on any variant of Unix with any Bourne shell derivative (Bash, Korn, …) and any POSIX-compliant version of find.

If you wish to adapt to the specific version of find you have on your system, there may be alternative options available. GNU find in particular has a myriad options not available in other versions — see the currently accepted answer for one such set of options.

孤城病女 2024-07-25 02:50:34

注意:

  • 这个答案可能比用例的保证更深入,并且 find 2>/dev/null 在许多情况下可能已经足够好了。 尽管所防范的情况在很大程度上可能是假设的,但出于跨平台的角度以及为了找到尽可能强大的解决方案而对一些高级 shell 技术的讨论,它可能仍然令人感兴趣。

如果您的 shell 是 bashzsh,则有一个强大且相当简单的解决方案,使用 >仅符合 POSIX 标准的查找功能; 虽然 bash 本身不是 POSIX 的一部分,但大多数现代 Unix 平台都附带它,使该解决方案具有广泛的可移植性:

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

注意:

  • 如果您的系统配置为显示本地化< /em> 错误消息,请在下面的 find 调用前加上 LC_ALL=C (LC_ALL=C find ...) 来确保报告英语消息,以便grep -v 'Permission returned'按预期工作。 然而,所显示的任何错误消息都将始终以英文显示。


  • >(...) 是(很少使用)输出 进程替换,允许将输出(在本例中,stderr 输出 (2>) 重定向到 > 内命令的标准输入;(...).
    除了 bashzsh 之外,ksh 原则上也支持它们,但尝试将它们与重定向结合起来来自 stderr,正如此处所做的那样 (2> >(...)),似乎被默默地忽略(在 ksh 93u+ 中) .

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


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


这种方法是:

  • 稳健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 ]; }

现在,退出代码指示是否发生除权限被拒绝之外的任何错误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),以便可以通过管道将错误消息单独传送到 grep标准输出。

如果没有这些重定向,数据(文件路径)和错误消息都将通过 stdout 传送到 grep,然后 grep 将无法区分错误消息权限被拒绝和名称恰好包含短语权限被拒绝的(假设的)文件。

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


关于现有答案的说明:

  • 关于 Michael Brux 的答案find ,有几点需要注意。 ! -可读-prune -o -print

    • 它需要GNU find; 值得注意的是,它不适用于 macOS。 当然,如果您只需要该命令与 GNU find 一起使用,那么这对您来说不是问题。

    • 一些权限被拒绝错误可能仍然出现:找到! -read -prune 报告当前用户确实具有 r 权限但缺少 x 的目录项的此类错误>(可执行)权限。 原因是,因为目录本身可读的,所以-prune不会被执行,并且尝试下降进入该目录会触发错误消息。 也就是说,典型情况是缺少 r 权限。

    • 注意:以下几点是哲学和/或特定用例的问题,您可能会认为它与您无关,并且该命令很适合您的需求,特别是如果只是打印< /em> 路径就是你所做的一切:

      • 如果您将权限拒绝错误消息的过滤概念化为一个您希望能够应用于任何单独任务< code>find 命令,那么主动预防权限被拒绝错误的相反方法需要在 find 命令中引入“噪音”,这也会带来复杂性和逻辑性陷阱
      • 例如,对 Michael 的回答(截至撰写本文时)得票最高的评论试图展示如何通过包含 -name 过滤器来扩展命令,如下:
        <代码>查找 . ! -可读-prune -o -name '*.txt'
        然而,这没有按预期工作,因为尾随的-print操作是必需的(可以在这个答案)。 这种微妙之处可能会引入错误。



  • Jonathan Leffler 的答案中的第一个解决方案,find . 2>/dev/null> files_and_folders,正如他自己所说,盲目地沉默所有错误消息(并且解决方法很麻烦并且不完全可靠,正如他也解释的那样)。 然而,务实地说,这是最简单的解决方案,因为您可能会满足于假设任何和所有错误都与权限相关。

  • mist 的答案sudo find . > files_and_folders简洁实用,但出于安全原因,除了打印文件名之外,不建议进行任何其他操作:因为您正在以运行>root 用户,“您的整个系统可能会被 find 中的错误或恶意版本弄乱,或者因不正确的调用而意外写入某些内容,而如果您使用正常权限运行此操作,则不会发生这种情况”(来自tripleee对mist的回答的评论)。

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

Note:

  • This answer probably goes deeper than the use case warrants, and find 2>/dev/null may be good enough in many situations. It may still be of interest for a cross-platform perspective and for its discussion of some advanced shell techniques in the interest of finding a solution that is as robust as possible, even though the cases guarded against may be largely hypothetical.

If your shell is bash or zsh, there's a solution that is robust while being reasonably simple, using only POSIX-compliant find features; while bash itself is not part of POSIX, most modern Unix platforms come with it, making this solution widely portable:

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

Note:

  • If your system is configured to show localized error messages, prefix the find calls below with LC_ALL=C (LC_ALL=C find ...) to ensure that English messages are reported, so that grep -v 'Permission denied' works as intended. Invariably, however, any error messages that do get displayed will then be in English as well.

  • >(...) is a (rarely used) output process substitution that allows redirecting output (in this case, stderr output (2>) to the stdin of the command inside >(...).
    In addition to bash and zsh, ksh supports them as well in principle, but trying to combine them with redirection from stderr, as is done here (2> >(...)), appears to be silently ignored (in ksh 93u+).

    • grep -v 'Permission denied' filters out (-v) all lines (from the find command's stderr stream) that contain the phrase Permission denied and outputs the remaining lines to stderr (>&2).

    • Note: There's a small chance that some of grep's output may arrive after find completes, because the overall command doesn't wait for the command inside >(...) to finish. In bash, you can prevent this by appending | cat to the command.

This approach is:

  • robust: grep is only applied to error messages (and not to a combination of file paths and error messages, potentially leading to false positives), and error messages other than permission-denied ones are passed through, to stderr.

  • side-effect free: find's exit code is preserved: the inability to access at least one of the filesystem items encountered results in exit code 1 (although that won't tell you whether errors other than permission-denied ones occurred (too)).


POSIX-compliant solutions:

Fully POSIX-compliant solutions either have limitations or require additional work.

If find's output is to be captured in a file anyway (or suppressed altogether), then the pipeline-based solution from Jonathan Leffler's answer is simple, robust, and POSIX-compliant:

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

Note that the order of the redirections matters: 2>&1 must come first.

Capturing stdout output in a file up front allows 2>&1 to send only error messages through the pipeline, which grep can then unambiguously operate on.

The only downside is that the overall exit code will be the grep command's, not find's, which in this case means: if there are no errors at all or only permission-denied errors, the exit code will be 1 (signaling failure), otherwise (errors other than permission-denied ones) 0 - which is the opposite of the intent.
That said, find's exit code is rarely used anyway, as it often conveys little information beyond fundamental failure such as passing a non-existent path.
However, the specific case of even only some of the input paths being inaccessible due to lack of permissions is reflected in find's exit code (in both GNU and BSD find): if a permissions-denied error occurs for any of the files processed, the exit code is set to 1.

The following variation addresses that:

find . 2>&1 >files_and_folders | { grep -v 'Permission denied' >&2; [ $? -eq 1 ]; }

Now, the exit code indicates whether any errors other than Permission denied occurred: 1 if so, 0 otherwise.
In other words: the exit code now reflects the true intent of the command: success (0) is reported, if no errors at all or only permission-denied errors occurred.
This is arguably even better than just passing find's exit code through, as in the solution at the top.


gniourf_gniourf in the comments proposes a (still POSIX-compliant) generalization of this solution using sophisticated redirections, which works even with the default behavior of printing the file paths to stdout:

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

In short: Custom file descriptor 3 is used to temporarily swap stdout (1) and stderr (2), so that error messages alone can be piped to grep via stdout.

Without these redirections, both data (file paths) and error messages would be piped to grep via stdout, and grep would then not be able to distinguish between error message Permission denied and a (hypothetical) file whose name happens to contain the phrase Permission denied.

As in the first solution, however, the the exit code reported will be grep's, not find's, but the same fix as above can be applied.


Notes on the existing answers:

  • There are several points to note about Michael Brux's answer, find . ! -readable -prune -o -print:

    • It requires GNU find; notably, it won't work on macOS. Of course, if you only ever need the command to work with GNU find, this won't be a problem for you.

    • Some Permission denied errors may still surface: find ! -readable -prune reports such errors for the child items of directories for which the current user does have r permission, but lacks x (executable) permission. The reason is that because the directory itself is readable, -prune is not executed, and the attempt to descend into that directory then triggers the error messages. That said, the typical case is for the r permission to be missing.

    • Note: The following point is a matter of philosophy and/or specific use case, and you may decide it is not relevant to you and that the command fits your needs well, especially if simply printing the paths is all you do:

      • If you conceptualize the filtering of the permission-denied error messages a separate task that you want to be able to apply to any find command, then the opposite approach of proactively preventing permission-denied errors requires introducing "noise" into the find command, which also introduces complexity and logical pitfalls.
      • For instance, the most up-voted comment on Michael's answer (as of this writing) attempts to show how to extend the command by including a -name filter, as follows:
        find . ! -readable -prune -o -name '*.txt'
        This, however, does not work as intended, because the trailing -print action is required (an explanation can be found in this answer). Such subtleties can introduce bugs.
  • The first solution in Jonathan Leffler's answer, find . 2>/dev/null > files_and_folders, as he himself states, blindly silences all error messages (and the workaround is cumbersome and not fully robust, as he also explains). Pragmatically speaking, however, it is the simplest solution, as you may be content to assume that any and all errors would be permission-related.

  • mist's answer, sudo find . > files_and_folders, is concise and pragmatic, but ill-advised for anything other than merely printing filenames, for security reasons: because you're running as the root user, "you risk having your whole system being messed up by a bug in find or a malicious version, or an incorrect invocation which writes something unexpectedly, which could not happen if you ran this with normal privileges" (from a comment on mist's answer by tripleee).

  • The 2nd solution in viraptor's answer, find . 2>&1 | grep -v 'Permission denied' > some_file runs the risk of false positives (due to sending a mix of stdout and stderr through the pipeline), and, potentially, instead of reporting non-permission-denied errors via stderr, captures them alongside the output paths in the output file.

超可爱的懒熊 2024-07-25 02:50:34

使用:

find . ! -readable -prune -o -print

或更一般地

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

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

  • -read 测试匹配可读文件。 当 test 为 false 时,! 运算符返回 true。 还有<代码>! -read 匹配不可读的目录(&文件)。
  • -prune 操作不会下降到目录中。
  • <代码>! -read -prune 可以翻译为:如果目录不可读,则不要进入该目录。
  • -read 测试考虑了 -perm 测试忽略的访问控制列表和其他权限工件。

另请参阅 find(1) 联机帮助页 了解更多详细信息。

Use:

find . ! -readable -prune -o -print

or more generally

find <paths> ! -readable -prune -o <other conditions like -name> -print
  • to avoid "Permission denied"
  • AND do NOT suppress (other) error messages
  • AND get exit status 0 ("all files are processed successfully")

Works with: find (GNU findutils) 4.4.2.
Background:

  • The -readable test matches readable files. The ! operator returns true, when test is false. And ! -readable matches not readable directories (&files).
  • The -prune action does not descend into directory.
  • ! -readable -prune can be translated to: if directory is not readable, do not descend into it.
  • The -readable test takes into account access control lists and other permissions artefacts which the -perm test ignores.

See also find(1) manpage for many more details.

神妖 2024-07-25 02:50:34

如果您想从根“/”开始搜索,您可能会看到类似这样的输出:

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

It'sbecauseofpermission. 要解决此问题:

  1. 您可以使用 sudo 命令:

    sudo find /.   -name 'toBeSearched.file' 
      

它询问超级用户的密码,当输入密码时您将看到您真正想要的结果。 如果您无权使用 sudo 命令,这意味着您没有超级用户的密码,请首先要求系统管理员将您添加到 sudoers 文件中。

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

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

    查找/。   -name 'toBeSearched.file' 2>&1 |   grep -v '权限被拒绝' 
      

If you want to start search from root "/" , you will probably see output somethings like:

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

It's because of permission. To solve this:

  1. You can use sudo command:

    sudo find /. -name 'toBeSearched.file'
    

It asks super user's password, when enter the password you will see result what you really want. If you don't have permission to use sudo command which means you don't have super user's password, first ask system admin to add you to the sudoers file.

  1. You can use redirect the Standard Error Output from (Generally Display/Screen) to some file and avoid seeing the error messages on the screen! redirect to a special file /dev/null :

    find /. -name 'toBeSearched.file' 2>/dev/null
    
  2. You can use redirect the Standard Error Output from (Generally Display/Screen) to Standard output (Generally Display/Screen), then pipe with grep command with -v "invert" parameter to not to see the output lines which has 'Permission denied' word pairs:

    find /. -name 'toBeSearched.file' 2>&1 | grep -v 'Permission denied'
    
日裸衫吸 2024-07-25 02:50:34

我必须使用:

find / -name expect 2>/dev/null

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

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

I had to use:

find / -name expect 2>/dev/null

specifying the name of what I wanted to find and then telling it to redirect all errors to /dev/null

expect being the location of the expect program I was searching for.

落花随流水 2024-07-25 02:50:34

使用 2>/dev/null

find 将 stderr 传送到 /dev/null 。 -name '...' 2>/dev/null

Pipe stderr to /dev/null by using 2>/dev/null

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

岁吢 2024-07-25 02:50:34

您还可以使用 -perm-prune 谓词来避免下降到不可读的目录(另请参阅如何从 find 程序中删除“权限被拒绝”打印输出语句? - Unix & Linux 堆栈交换):

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

You can also use the -perm and -prune predicates to avoid descending into unreadable directories (see also 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
尽揽少女心 2024-07-25 02:50:34

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

find . 2>/dev/null >files_and_folders

Redirect standard error. For instance, if you're using bash on a unix machine, you can redirect standard error to /dev/null like this:

find . 2>/dev/null >files_and_folders
各自安好 2024-07-25 02:50:34

虽然上述方法不能解决 Mac OS X 的情况,因为 Mac Os X 不支持 -read 开关,但这是您可以避免输出中出现“权限被拒绝”错误的方法。 这可能会对某人有所帮助。

find / -type f -name "your_pattern" 2>/dev/null

例如,如果您将其他命令与 find 一起使用,以查找目录中特定模式的文件的大小,2>/dev/null 仍然可以工作如下所示。

<代码>查找 . -type f -name "your_pattern" -exec du -ch {} + 2>/dev/null | grep 总计$。

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

While above approaches do not address the case for Mac OS X because Mac Os X does not support -readable switch this is how you can avoid 'Permission denied' errors in your output. This might help someone.

find / -type f -name "your_pattern" 2>/dev/null.

If you're using some other command with find, for example, to find the size of files of certain pattern in a directory 2>/dev/null would still work as shown below.

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

This will return the total size of the files of a given pattern. Note the 2>/dev/null at the end of find command.

夜雨飘雪 2024-07-25 02:50:34

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

find . 2>/dev/null > some_file

或首先加入 stderr 和 stdout,然后 grep 出这些特定错误:

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

Those errors are printed out to the standard error output (fd 2). To filter them out, simply redirect all errors to /dev/null:

find . 2>/dev/null > some_file

or first join stderr and stdout and then grep out those specific errors:

find . 2>&1 | grep -v 'Permission denied' > some_file
天暗了我发光 2024-07-25 02:50:34

简单答案:

find 。 > files_and_folders 2>&-

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

  • 退出如果会打印任何“权限被拒绝”错误,则 code 仍将为 1

GNU find 的可靠答案:

find 。 -类型 d \! \(-可读-可执行\)-prune-print-o-print> files_and_folders

传递额外选项来查找-prune(防止下降)但仍然-print 任何目录 (-typed\!) 都有 -可读< /code>-可执行权限,或(-o) -print 任何其他文件。

  • -可读-executable 选项是 GNU 扩展,不是 POSIX 标准
  • 仍可能返回“权限被拒绝”异常/损坏的文件(例如,请参阅错误报告影响使用的容器安装的文件系统lxcfs < v2.0.5)

可靠的答案,适用于任何 POSIX 兼容的 find (GNU、OSX/BSD 等)

{ LC_ALL=C find . 3>&2 2>&1 1>&3> 文件和文件夹 | grep -v '权限被拒绝'; [ $? = 1 ]; } 3>&2 2>&1

使用 管道 将标准错误流传递到 grep,删除所有包含'Permission returned' 字符串的行。

LC_ALL=C 设置POSIX 语言环境 使用 环境变量3>&2 2>&1 1>&33>&2 2>&1 复制文件描述符以将标准错误流传送到grep,以及[ $? = 1 ] 使用 [] 反转 grep 返回的错误代码,以近似 find 的原始行为。

  • 还将过滤任何“权限被拒绝” 由于输出重定向而导致的错误(例如,如果files_and_folders 文件本身不可写)

Simple answer:

find . > files_and_folders 2>&-

2>&- closes (-) the standard error file descriptor (2) so all error messages are silenced.

  • Exit code will still be 1 if any 'Permission denied' errors would otherwise be printed

Robust answer for GNU find:

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

Pass extra options to find that -prune (prevent descending into) but still -print any directory (-typed) that does not (\!) have both -readable and -executable permissions, or (-o) -print any other file.

  • -readable and -executable options are GNU extensions, not part of the POSIX standard
  • May still return 'Permission denied' on abnormal/corrupt files (e.g., see bug report affecting container-mounted filesystems using lxcfs < v2.0.5)

Robust answer that works with any POSIX-compatible find (GNU, OSX/BSD, etc)

{ LC_ALL=C find . 3>&2 2>&1 1>&3 > files_and_folders | grep -v 'Permission denied'; [ $? = 1 ]; } 3>&2 2>&1

Use a pipeline to pass the standard error stream to grep, removing all lines containing the 'Permission denied' string.

LC_ALL=C sets the POSIX locale using an environment variable, 3>&2 2>&1 1>&3 and 3>&2 2>&1 duplicate file descriptors to pipe the standard-error stream to grep, and [ $? = 1 ] uses [] to invert the error code returned by grep to approximate the original behavior of find.

  • Will also filter any 'Permission denied' errors due to output redirection (e.g., if the files_and_folders file itself is not writable)
流年里的时光 2024-07-25 02:50:34

为了避免仅仅权限被拒绝警告,请告诉 find 通过从搜索中删除不可读的文件来忽略它们。 将表达式作为 OR 添加到您的查找中,例如

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

Thismostly said to (匹配不可读的文件并将其从列表中删除) OR (匹配像 *. jbd 并显示它[用 ls])。 (请记住,默认情况下,除非使用 -or,否则表达式是 AND 在一起的。)您需要在第二个表达式中使用 -ls,否则 find 可能会添加默认操作来显示任一匹配项,这也会显示所有不可读的文件。

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

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

So (match unreadable文件并从列表中删除)(匹配路径 /dev 并从列表中删除)(匹配文件如 *.jbd 并显示它)

To avoid just the permission denied warnings, tell find to ignore the unreadable files by pruning them from the search. Add an expression as an OR to your find, such as

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

This mostly says to (match an unreadable file and prune it from the list) OR (match a name like *.jbd and display it [with ls]). (Remember that by default the expressions are AND'd together unless you use -or.) You need the -ls in the second expression or else find may add a default action to show either match, which will also show you all the unreadable files.

But if you're looking for real files on your system, there is usually no reason to look in /dev, which has many many files, so you should add an expression that excludes that directory, like:

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

So (match unreadable file and prune from list) OR (match path /dev and prune from list) OR (match file like *.jbd and display it).

迎风吟唱 2024-07-25 02:50:34

只需使用它来搜索系统中的文件即可。

查找 / -name YOUR_SEARCH_TERM 2>&1 | grep YOUR_SEARCH_TERM

我们不要做不必要的工程,您只想搜索您的文件,对吗? 那么这个命令将为您列出文件(如果它们存在于您可以访问的区域中)。

Simply use this to search for a file in your system.

find / -name YOUR_SEARCH_TERM 2>&1 | grep YOUR_SEARCH_TERM

Let's not do unnecessary over engineering, you just want to search for your file right? then that is the command which will list the files for you if they are present in an area accessible to you.

你げ笑在眉眼 2024-07-25 02:50:34

use

sudo find / -name file.txt

它很愚蠢(因为你提升了搜索)并且不安全,但编写起来要短得多。

use

sudo find / -name file.txt

It's stupid (because you elevate the search) and nonsecure, but far shorter to write.

我们的影子 2024-07-25 02:50:34

上述答案都不适合我。 我在互联网上找到的所有内容都集中在:隐藏错误。 没有一个能够正确处理进程返回代码/退出代码。 我在 bash 脚本中使用 find 命令来定位某些目录,然后检查其内容。 我使用退出代码评估命令 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 -follow \
   \( -type d -a ! \( -可读 -a -可执行 \) \) -prune \
   -o \
   \(-type d -a -可读 -a -可执行 -a -name "${m_find_name}" \) -print

这里的关键是把“not true”放在组合表达式:

has read access AND has execute access

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

我在评论部分提供了以下技术细节以解答问题。 如果细节过多,我深表歉意。

  • ¿为什么使用命令nice? 我得到了这个想法
  • 为什么要在 /home*/ 内搜索? 这与该线程无关。 我通过使用非特权用户(非 root)编译源代码手动安装所有应用程序。 它们安装在“/home”内。 我可以让多个二进制文件和版本共存。 我需要找到所有目录,以主从方式检查和备份。 我可以有多个“/home”(在专用服务器内运行的多个磁盘)。
  • 为什么使用-follow? 用户可以创建目录的符号链接。 它的用处取决于,我需要记录找到的绝对路径。

None of the above answers worked for me. Whatever I find on Internet focuses on: hide errors. None properly handles the process return-code / exit-code. I use command find within bash scripts to locate some directories and then inspect their content. I evaluate command find success using the exit-code: a value zero works, otherwise fails.

The answer provided above by Michael Brux works sometimes. But I have one scenario in which it fails! I discovered the problem and fixed it myself. I need to prune files when:

it is a directory AND has no read access AND/OR has no execute access

See the key issue here is: AND/OR. One good suggested condition sequence I read is:

-type d ! -readable ! -executable -prune

This does not work always. This means a prune is triggered when a match is:

it is directory AND no read access AND no execute access

This sequence of expressions fails when read access is granted but no execute access is.

After some testing I realized about that and changed my shell script solution to:

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

The key here is to place the "not true" for a combined expression:

has read access AND has execute access

Otherwise it has not full access, which means: prune it. This proved to work for me in one scenario which previous suggested solutions failed.

I provide below technical details for questions in the comments section. I apologize if details are excessive.

  • ¿Why using command nice? I got the idea here. Initially I thought it would be nice to reduce process priority when looking an entire filesystem. I realized it makes no sense to me, as my script is limited to few directories. I reduced -maxdepth to 3.
  • ¿Why search within /home*/? This it not relevant for this thread. I install all applications by hand via source code compile with non privileged users (not root). They are installed within "/home". I can have multiple binaries and versions living together. I need to locate all directories, inspect and backup in a master-slave fashion. I can have more than one "/home" (several disks running within a dedicated server).
  • ¿Why using -follow? Users might create symbolic links to directories. It's usefulness depends, I need to keep record of the absolute paths found.
ぃ双果 2024-07-25 02:50:34

针对 GNU find 的优化解决方案

至少对于某些系统+文件系统组合,find 不需要 stat一个文件来获取其类型。 然后,您可以在测试可读性之前检查它是否是一个目录,以加快搜索速度 - 我在所做的测试中得到了大约 30% 的改进。 因此,对于长时间搜索或运行频率足够高的搜索,请使用以下之一:

打印可见的所有内容

$ find . -print -type d ! -readable -prune
$ find . -type d ! -readable -prune , [expression] -print

打印可见的文件

$ find . -type d \( ! -readable -prune -o -true \) -o [expression] -print

打印可见的目录< /strong>

$ find . -type d -print ! -readable -prune
$ find . -type d \( ! -readable -prune , [expression] -print \)

仅打印可读目录

$ find . -type d ! -readable -prune -o [expression] -print

注释

-可读, (逗号)运算符是 GNU 扩展。 此表达式

$ find . [expression] , [expression]

在逻辑上等价

$ find . \( [expression] -o -true \) [expression]

这是因为启用此优化的find实现将避免stating non-所讨论的用例中的所有目录文件。


编辑:shell 函数

这是一个 POSIX shell 函数,我最终将此测试添加到任何表达式中。 它似乎与隐式 -print 和命令行选项配合得很好:

findr () {
    j=$#; done=
    while [ $j -gt 0 ]; do
        j=$(($j - 1))
        arg="$1"; shift
        test "$done" || case "$arg" in
            -[A-Z]*) ;;  # skip options
            -*|\(|!)     # find start of expression
                set -- "$@" \( -type d ! -readable -prune -o -true \)
                done=true
                ;;
        esac
        set -- "$@" "$arg"
    done
    find "$@"
}

答案中列出的其他两个替代方案导致 POSIX shell 中出现语法错误(甚至无法获取包含该函数的文件)定义)或 ZSH 中的错误输出...运行时间似乎是相同的。

Optimized solutions for GNU find

At least for some system+filesystem combinations, find doesn't need to stat a file to get its type. Then you can check if it's a directory before testing readability to speed up the search —I've got some 30% improvement in tests I did. So for long searches or searches that run often enough, use one of these:

Print everything visible

$ find . -print -type d ! -readable -prune
$ find . -type d ! -readable -prune , [expression] -print

Print visible files

$ find . -type d \( ! -readable -prune -o -true \) -o [expression] -print

Print visible directories

$ find . -type d -print ! -readable -prune
$ find . -type d \( ! -readable -prune , [expression] -print \)

Print only readable directories

$ find . -type d ! -readable -prune -o [expression] -print

Notes

The -readable and , (comma) operators are GNU extensions. This expression

$ find . [expression] , [expression]

is logically equivalent to

$ find . \( [expression] -o -true \) [expression]

This is because find implementations with this optimization enabled will avoid stating non-directory files at all in the discussed use case.


Edit: shell function

Here is a POSIX shell function I ended up with to prepend this test to any expression. It seems to work fine with the implicit -print and command-line options:

findr () {
    j=$#; done=
    while [ $j -gt 0 ]; do
        j=$(($j - 1))
        arg="$1"; shift
        test "$done" || case "$arg" in
            -[A-Z]*) ;;  # skip options
            -*|\(|!)     # find start of expression
                set -- "$@" \( -type d ! -readable -prune -o -true \)
                done=true
                ;;
        esac
        set -- "$@" "$arg"
    done
    find "$@"
}

The other two alternatives listed in the answers caused either a syntax error in POSIX shell (couldn't even source a file containing the function definition) or bad output in ZSH... Running time seems to be equivalent.

帝王念 2024-07-25 02:50:34

使用 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

:应该有魔力

You can use the grep -v invert-match

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

like this:

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

Should to the magic

吖咩 2024-07-25 02:50:34

-=对于 MacOS=-

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

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

并在新的终端窗口中调用它:

$ file=<filename or mask>; search

例如:

$ 文件=etc; 搜索

-=For MacOS=-

Make a new command using alias: just add in ~/.bash_profile line:

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

and in new Terminal window you can call it:

$ file=<filename or mask>; search

for example:

$ file=etc; search

风苍溪 2024-07-25 02:50:34

如果您使用 CSH 或 TCSH,这里有一个解决方案:

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

如果您想输出到终端:

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

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

If you are using CSH or TCSH, here is a solution:

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

If you want output to the terminal:

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

However, as the "csh-whynot" FAQ describes, you should not use CSH.

归属感 2024-07-25 02:50:34

要在整个文件系统中搜索某个文件,例如 hosts,除了 /proc 树(这会导致各种错误),我使用以下命令:

# find / -path /proc ! -prune -o -name hosts -type f
/etc/hosts

注意:因为 -prune始终为真,您必须否定它以避免在输出中看到行/proc。 我尝试使用! -readed 方法,发现它返回 /proc 下当前用户可以读取的各种内容。 因此,“OR”条件不会达到您所期望/想要的效果。

我从 查找手册页 给出的示例开始,请参阅 -prune 选项。

To search the entire file system for some file, e.g. hosts, except the /proc tree, which causes all kinds of errors, I use the following:

# find / -path /proc ! -prune -o -name hosts -type f
/etc/hosts

Note: Because -prune is always true, you have to negate it to avoid seeing the line /proc in the output. I tried the using ! -readable approach and found it returns all kinds of things under /proc that the current user can read. So the "OR" condition doesn't do what you expect/want there.

I started with the example given by the find man page, See the -prune option.

时光是把杀猪刀 2024-07-25 02:50:34

最低限度的解决方案只是添加可读标志。

<代码>查找 . -name foo -可读

Minimal solution is just to add the readable flag.

find . -name foo -readable

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文