On 10/25/2019 6:37 PM, Assaf Gordon wrote:
On 2019-10-25 1:56 a.m., Ray Satiro wrote:
Recently I tracked down a delay in some scripts to this line:
find / -name filename* 2>/dev/null | head -n 1
[...]
owner@ubuntu1604-x64-vm:~$ ( trap '' pipe; find / -name initrd*
2>/dev/null | strace -e 'trace=!all' head -n 1)
/initrd.img
+++ exited with 0 +++
(few seconds wait)
In your case,
I can guess that there is only a single file matching your predicate
'initrd*'.
The 'head' indeed terminates, and the pipe is closed.
But if 'find' doesn't find any more matching files, it doesn't
try to print anything more, and SIGPIPE is never raised.
Note the manual page of pipe(7) says:
?????? "If all file descriptors referring to?? the?? read
???????? end?? of a pipe have been closed, then a write(2)
???????? will cause a SIGPIPE signal to be generated for the
???????? calling process."
So if no further files were found, 'find' continues (slowly scanning
the disk) until it finishes.
Thanks for all the help guys. The explanation quoted above is indeed
what is happening: find is only killed by SIGPIPE after it writes again,
which in this case it does after it finds the second result.
I probably caused some confusion with my example because I made a
mistake. For the purposes of the example I was trying to demonstrate I
had reset the sigpipe trap, but actually I ignored it (oops). I wrote
trap '' pipe which *ignores* sigpipe (in other words find will keep
running after SIGPIPE), but I meant trap - pipe to reset it. Sorry.
I can confirm:
First window:
( trap - pipe; find / -name initrd* 2>/dev/null | head -n 1)
And in second window:
sudo strace -ff -e trace=write?? -e write=1 -p `pgrep find`
Then:
write(1, "/usr/src/linux-headers-4.4.0-34/"..., 127) = -1 EPIPE (Broken
pipe)
--- SIGPIPE {si_signo=SIGPIPE, si_code=SI_USER, si_pid=7252,
si_uid=1000} ---
+++ killed by SIGPIPE +++
So that's what's happened, killed by SIGPIPE but only after the next
write. To remedy I am using the find ... -print -quit instead of head -n
1 to get just the first result , and I will use Stephane's script if I
need to get the first n results.
* Note I am not subscribed to the list, I can't get mail from the list
for some reason (probably yahoo), so if a reply is necessary I will need
a CC to see it.