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