coreutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Does head util cause SIGPIPE?


From: Stephane Chazelas
Subject: Re: Does head util cause SIGPIPE?
Date: Sat, 26 Oct 2019 20:51:53 +0100
User-agent: NeoMutt/20171215

2019-10-25 03:56:49 -0400, Ray Satiro:
[...]
> Since we only need the first line I can just use find options -print -quit
> and skip piping to head. But say we needed the first n results, how would I
> do that with head and get find to terminate rather than continue searching?
[...]

With zsh/bash, you could do:

max=10
{
  IFS= read -r pid
  files=() n=0
  while ((n < max)); do
    if IFS= read -rd '' file; then
      ((n++)); files+=("$file")
    else
      pid=0
      break
    fi
  done
  ((pid)) && kill -s PIPE "$pid"
} < <(
  sh -c 'echo "$$"; exec "$0" "$@"' \
    stdbuf -o0 find . -type f -print0
)
echo "First $n regular files:"
printf ' - %s\n' "${files[@]}"

That is obtain the pid of find by spawning a sh that prints its
pid before executing find in the same process (though GNU stdbuf
-o0 to avoid buffering), and at the other end, read that pid,
and the first 10 lines in a loop.

We actually use the SIGPIPE signal because bash treats that
signal specially and doesn't report the death of processes
killed by that signal.

Note that the list is not sorted, so the first files you get
will be more or less random.

The { ... } < <(cmd) is needed in bash where cmd | { ... }
wouldn't work as { ... } would be run in a subshell.

With zsh, you can do the same with:

files=(./**/*(ND.Y10))

-- 
Stephane




reply via email to

[Prev in Thread] Current Thread [Next in Thread]