bug-bash
[Top][All Lists]
Advanced

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

Re: anonymous pipes in recursive function calls


From: Zachary Santer
Subject: Re: anonymous pipes in recursive function calls
Date: Sat, 29 Jun 2024 10:23:23 -0400

On Sat, Jun 29, 2024 at 4:40 AM konsolebox <konsolebox@gmail.com> wrote:
>
> You can avoid pipe recursions by storing the output first in an array.

So is this a known issue?

> There's also no need to use an error flag variable.  Just make sure
> return calls are chained.

The intention here is to report as many error conditions as possible
before exiting.

> -------------------------
> local temp
> command this-file | readarray -d '' temp # -d is a Bash 5.0 feature.
>
> if (( PIPESTATUS[0] != 0 )); then
>   printf '%s\n' "command failed" >&2
>   return 1
> fi
>
> for path in "${temp[@]}"; do
>   cd -- "${starting_PWD}/${path}" || return
>   if [[ -r this-file ]]; then
>     recursive_function "${entry_path}/${path}" || return
>   fi
>   ...
> done
>
> cd -- "${starting_PWD}"
> -------------------------

Filling an array of paths and then looping over it in a subsequent for
loop wouldn't actually be unreasonable here, considering how many
paths there are. It just feels like bad practice. There's always the
possibility of busting out the named pipes again. Bash 4.2 couldn't
wait for process substitutions.


set -o nounset -o noglob +o braceexpand
shopt -s lastpipe

main () {
  tempdlir="$( mktemp --tmpdir --directory -- script-XXXXXXXX )" || exit 1
  local -i pipeindex=0
  # initialize arrays
  recursive_function .
  # loop through arrays
}

recursive_function () {
  local entry_path="${1}"
  local named_pipe="${tempdir}/${pipeindex}.pipe"
  (( ++pipeindex ))
  mkfifo -- "${named_pipe}"
  local starting_PWD="${PWD}"
  command this-file > "${pipe}" &
  local command_pid="${?}"
  while IFS='' read -r -d '' path; do
    cd -- "${starting_PWD}/${path}" || exit 1
    if [[ -r this-file ]]; then
      recursive_function "${entry_path}/${path}"
    fi
    # fill arrays
    # there is another anonymous pipe here, as well
  done < "${named_pipe}"
  if ! wait -- "${command_pid}"; then
    printf '%s\n' "command failed" >&2
    error='true'
  fi
  cd -- "${starting_PWD}" || exit 1
}

main "${@}"


Yeah, honestly, filling an array of paths and then looping over it in
a subsequent for loop wouldn't be the end of the world. Either way,
it'll show if the issue is actually the anonymous pipe in a recursive
function call.

Thanks, konsolebox.



reply via email to

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