为什么没有重定向到fifo块而没有重定向到文件描述符?

时间:2019-07-11 06:14:25

标签: shell pipe posix fifo

我的要求是将子进程(或子shell)的输出和错误捕获到变量中。

我找到了使用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不会同时阻塞?

0 个答案:

没有答案