so I'm attempting to run a script which searches the contents of df -h for a directory that exceeds threshold, and basically run a find command on that directory to get the top ten largest files, then stop running find. However, when it gives the top ten files, as intended, it then spits out several times:
find: ‘ls’ terminated by signal 13
My question is simply, how do I stop these? I think I understand that these are due to my find command and head -n 10 command running at the same time, as head is piped after find, but if someone could elaborate, that would be great. My goal is to submit this to the powers that be at work (Walmart) to have this start being ran on our test servers.
Also note below, that the size in the find command is only 5M, as my test server does not have 10 files on it that are that big in that directory.
Here is the script:
#!/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
and here is a sample output:
-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/[email protected]~
-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
It is nothing to worry about. It is a broken pipe because head will finish reading the first 10 lines before all of the lines are written to stdout.
You can silence it with >/dev/null 2>&1
on the end or 2>/dev/null
to just silence the errors. I've also seen another trick where you add tail -n +1
into the pipeline:
find $exceeds_thresh -xdev -size +5M -exec ls -lah {} \; | tail -n +1 | head -n 10
This is going to cost you some time, but it will work without changing the outcome.
The message is harmless, but annoying. It happens because head
exits when it's gotten its fill of input lines, yet find
keeps running and executing more ls
calls. Those ls
commands try to print and end up being killed with a SIGPIPE because there's nobody listening to them any longer.
You could use 2>/dev/null
to hide the errors, but that'd also hide other legitimate errors. A more surgical approach would be:
find ... \; 2> >(grep -v 'terminated by signal 13' >&2) | head -n 10
This uses process substitution to filter out only the one message. 2>
redirects stderr into the grep
and >&2
redirects any surviving messages back to stderr.
This isn't perfect as find
doesn't know that it should quit. It keeps running doomed ls
es long after head
has exited.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With