使用find命令时,'ls'被信号13终止

时间:2018-06-01 19:21:24

标签: linux bash shell server-administration

所以我试图运行一个脚本,在df -h的内容中搜索超过阈值的目录,并且基本上在该目录上运行find命令以获取前十个最大的文件,然后停止运行find。但是,当它按预期提供前十个文件时,它会多次吐出:

find: ‘ls’ terminated by signal 13

我的问题很简单,如何阻止这些?我想我明白这些是由于我的find命令和head -n 10命令同时运行,因为head在发现之后被管道输送,但如果有人可以详细说明,那就太好了。我的目标是将这个提交给工作中的权力(沃尔玛),以便在我们的测试服务器上运行。

下面还要注意,find命令中的大小只有5M,因为我的测试服务器上没有10个文件,这个文件在该目录中很大。

这是脚本:

#!/bin/bash

#defines what exceeds threshold

threshold="90%|91%|92%|93%|94%|95%|96%|97%|98%|99%|100%|6%"

#puts the output of df -h  into output_df

df -h > output_df

cat output_df | awk -v VAR=$threshold '{if($5~VAR)print $6}' > exceeds_thresh

LINES=()
while IFS= read -r exceeds_thresh
do
find $exceeds_thresh -xdev -size +5M -exec ls -lah {} \; | head -n 10
done < "exceeds_thresh"

#cleaning up the files the script created

rm output_df exceeds_thresh

这是一个示例输出:

-rw-r-----+ 1 root systemd-journal 16M Jun  1 19:18 /var/log/journal/a237b5bc574941af85c796e15b0ce420/system.journal
-rw-r-----+ 1 root systemd-journal 8.0M May 29 05:38 /var/log/journal/a237b5bc574941af85c796e15b0ce420/system@00056d51a41389f0-0c1bef27b9d68ad6.journal~
-rw-r-----+ 1 root systemd-journal 104M Jun  1 05:55 /var/log/journal/a237b5bc574941af85c796e15b0ce420/system@45697f9ed4b84f07b92c5fcbc8a945bd-0000000000000001-00056d51a40f2f0c.journal
find: ‘ls’ terminated by signal 13
find: ‘ls’ terminated by signal 13
find: ‘ls’ terminated by signal 13
find: ‘ls’ terminated by signal 13
find: ‘ls’ terminated by signal 13
find: ‘ls’ terminated by signal 13
find: ‘ls’ terminated by signal 13
find: ‘ls’ terminated by signal 13

2 个答案:

答案 0 :(得分:1)

没什么好担心的。这是一个破损的管道,因为在将所有行写入stdout之前,head将完成读取前10行。

您可以使用>/dev/null 2>&12>/dev/null将其静音,以便让错误无声。我还看到了另一个将tail -n +1添加到管道中的技巧:

find $exceeds_thresh -xdev -size +5M -exec ls -lah {} \; | tail -n +1 | head -n 10

这会花费你一些时间,但它会在不改变结果的情况下发挥作用。

答案 1 :(得分:1)

这条消息无害,但很烦人。这是因为head在填充输入行时退出,但find继续运行并执行更多ls次调用。那些ls命令试图打印并最终被SIGPIPE杀死,因为没有人再听它们了。

您可以使用2>/dev/null隐藏错误,但这也会隐藏其他合法错误。更外科的方法是:

find ... \; 2> >(grep -v 'terminated by signal 13' >&2) | head -n 10

这使用process substitution仅过滤掉一条消息。 2>将stderr重定向到grep>&2将任何幸存的消息重定向回stderr。

这并不完美,因为find不知道它应该退出。它会在ls退出后很长时间内继续运行head