如何最好地将 find + exec 命令的输出发送到管道?

如何最好地将 find + exec 命令的输出发送到管道?

我想了解如何正确地将 find + exec 命令的输出发送到管道以进行进一步处理。

即我们如何
(1) 选择一个组文件
(2) 通过 exec 对组执行某些操作以及
(3) 使用该操作的输出作为管道中 1 个或多个过滤器的输入

例如,当我尝试像这样过滤 find + exec 命令时,我在过滤掉的行中看到许多“由信号 13 终止”错误。

$ find c* -name "*.jpg" -exec ls {} \; | head
c0/1467058201899.jpg
c0/1465854461118.jpg
c0/1465855196637.jpg
c0/1467050962421.jpg
c0/1465856476225.jpg
c0/1467050385287.jpg
c0/1465853696999.jpg
c0/1467144293032.jpg
c0/1467051637981.jpg
c0/1465841226352.jpg
find: `ls' terminated by signal 13
find: `ls' terminated by signal 13
find: `ls' terminated by signal 13
...

我可以像这样让这个特定的错误消失,但这感觉不太优雅。

$ find c* -name "*.jpg" -exec ls {} \; -print 2>/dev/null | head
c0/1467058201899.jpg
c0/1467058201899.jpg
c0/1465854461118.jpg
c0/1465854461118.jpg
c0/1465855196637.jpg
c0/1465855196637.jpg
c0/1467050962421.jpg
c0/1467050962421.jpg
c0/1465856476225.jpg
c0/1465856476225.jpg

对于 find + exec 的一般情况,执行的命令可能会有所不同,是否有更优雅的方法来执行此操作?

更新
使用 xargs 似乎仍然生成输出到 stderr ...

$ find c* -name "*.jpg" -print0 | xargs -0 ls | head
c0/1465425913832.jpg
c0/1465425968779.jpg
c0/1465426112741.jpg
c0/1465426116540.jpg
c0/1465426121623.jpg
c0/1465426127656.jpg
c0/1465426133584.jpg
c0/1465426140097.jpg
c0/1465426143185.jpg
c0/1465426156715.jpg
xargs: ls: terminated by signal 13

使用 find + exec 以 + 而不是 ; 终止还生成输出到 stderr ...

$ find c* -name "*.jpg" -exec ls {} \+ | head
c0/1465425913832.jpg
c0/1465425968779.jpg
c0/1465426112741.jpg
c0/1465426116540.jpg
c0/1465426121623.jpg
c0/1465426127656.jpg
c0/1465426133584.jpg
c0/1465426140097.jpg
c0/1465426143185.jpg
c0/1465426156715.jpg
find: `ls' terminated by signal 13
find: `ls' terminated by signal 13

虽然添加“-print 2>/dev/null”到这个命令会导致命令执行得非常快......

$ find c* -name "*.jpg" -exec ls {} \+ -print 2>/dev/null | head
c0/1467058201899.jpg
c0/1465854461118.jpg
c0/1465855196637.jpg
c0/1467050962421.jpg
c0/1465856476225.jpg
c0/1467050385287.jpg
c0/1465853696999.jpg
c0/1467144293032.jpg
c0/1467051637981.jpg
c0/1465841226352.jpg

答案1

发生错误是因为find不知道何时停止。如果你运行find | head,当 head 得到十行并退出时,下次find尝试写入文件名时,它将得到一个信号管道(让它知道管道的另一端已损坏或关闭),find 将正常退出。

但在这里,find 并没有写任何东西,ls而是。find它可以看到它的孩子正在死亡,并且知道原因,但它不知道管道的另一端是关闭的,也不知道停止生成它们。

相关内容