Мое требование - записывать выходные данные и ошибки дочернего процесса (или подоболочки) в переменные.
Я нашел рабочее решение с использованием 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
не блокируется в одной точке?