我的要求是将子进程(或子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
不会同时阻塞?