(在bash),我希望有一个子shell使用非STDOUT非STDERR的文件描述符传递一些数据传回父shell。 我怎样才能做到这一点? 最后,我很愿意将数据保存到父壳的一些变量。
(
# The following two lines show the behavior of the subshell.
# We cannot change them.
echo "This should go to STDOUT"
echo "This is the data I want to pass to the parent shell" >&3
)
#...
data_from_subshell=... # Somehow assign the value of &3 of the
# subshell to this variable
编辑:子shell运行黑箱程序写入到标准输出和&3。
BEWARE, BASHISM AHEAD (there are posix shells that are significantly faster than bash, e.g. ash or dash, that don't have process substitution).
You can do a handle dance to move original standard output to a new descriptor to make standard output available for piping (from the top of my head):
exec 3>&1 # creates 3 as alias for 1
run_in_subshell() { # just shortcut for the two cases below
echo "This goes to STDOUT" >&3
echo "And this goes to THE OTHER FUNCTION"
}
Now you should be able to write:
while read line; do
process $line
done < <(run_in_subshell)
but the <()
construct is a bashism. You can replace it with pipeline
run_in_subshell | while read line; do
process $line
done
except than the second command also runs in subshell, because all commands in pipeline do.
当然,最简单的方法,就是直接捕获输出父
data_from_subshell=$(echo "This is the data I want to pass to the parent shell")
您可以使用命名管道作为一种替代方法,从一个孩子读数据
mkfifo /tmp/fifo
现在你可以重定向孩子/tmp/fifo
(
echo "This should go to STDOUT"
echo "This is the data I want to pass to the parent shell" >/tmp/fifo
) &
和家长可以从那里读
read data_from_subshell </tmp/fifo
另一种方法是使用coproc
启动一个子进程。 这将创建一个双向管一个孩子,孩子的stdin和stdout重定向到管道描述符。 要在孩子同时使用管道和stdout,您必须在父先复制标准输出
exec 4>&1 # duplicate stdout for usage in client
coproc SUBSHELL (
exec 3>&1 1>&4- # redirect fd 3 to pipe, redirect fd 1 to stdout
(
echo "This should go to STDOUT"
echo "This is the data I want to pass to the parent shell" >&3
)
)
exec 4>&- # close fd 4 in parent
read data <&${SUBSHELL[0]}
echo "Parent: $data"
协进程中的Bash 4.0中引入。
文章来源: How to redirect an output file descriptor of a subshell to an input file descriptor in the parent shell?