Почему перенаправление на блок fifo, а перенаправление на дескриптор файла - нет? - PullRequest
0 голосов
/ 11 июля 2019

Мое требование - записывать выходные данные и ошибки дочернего процесса (или подоболочки) в переменные.

Я нашел рабочее решение с использованием fifos и файловых дескрипторов.

Код:

#!/bin/sh

print() {
 echo foo
 echo bar >&2
}

run1() {
  out="$1"; shift
  err="$1"; shift
  command=$*

  fifo_out=$(mktemp -u) && mkfifo "$fifo_out"
  fifo_err=$(mktemp -u) && mkfifo "$fifo_err"

  $command >"$fifo_out" 2>"$fifo_err" &

  exec 3<"$fifo_out" 4<"$fifo_err"
  read -r "$out" <&3 # does not block here - why?
  read -r "$err" <&4
  exec 3<&- 4<&-
  rm "$fifo_out" "$fifo_err"
}

run1 message error print
echo "Message: $message"
echo "Error:   $error"

Вывод:

Message: foo
Error:   bar

Затем я попытался упростить сценарий, избегая файловых дескрипторов.

Код:

#!/bin/sh

print() {
 echo foo
 echo bar >&2
}

run2() {
  out="$1"; shift
  err="$1"; shift
  command=$*

  fifo_out=$(mktemp -u) && mkfifo "$fifo_out"
  fifo_err=$(mktemp -u) && mkfifo "$fifo_err"

  $command >"$fifo_out" 2>"$fifo_err" &

  read -r "$out" <"$fifo_out" # blocks here - why?
  read -r "$err" <"$fifo_err"
  rm "$fifo_out" "$fifo_err"
}

run2 message error print
echo "Message: $message"
echo "Error:   $error"

Нет вывода, потому что run2 блокируется при считывании $fifo_out.Почему это происходит, и почему run1 не блокируется в одной точке?

...