use*_*468 29 bash shell file-descriptor
(在BASH中)我希望子shell使用非STDOUT非STDERR文件描述符将一些数据传递回父shell.我怎样才能做到这一点?最终我希望将数据保存到父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
Run Code Online (Sandbox Code Playgroud)
编辑:子shell运行一个写入STDOUT和&3的黑盒程序.
Jan*_*dec 28
注意,BASHISM AHEAD(有比posash快得多的 posix shell,例如ash或dash,没有进程替换).
你可以做一个手柄舞,将原始标准输出移动到一个新的描述符,使标准输出可用于管道(从我的头顶):
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"
}
Run Code Online (Sandbox Code Playgroud)
现在你应该可以写:
while read line; do
process $line
done < <(run_in_subshell)
Run Code Online (Sandbox Code Playgroud)
但<()构造是一种基础.您可以用管道替换它
run_in_subshell | while read line; do
process $line
done
Run Code Online (Sandbox Code Playgroud)
除了第二个命令也在子shell中运行,因为管道中的所有命令都可以.
当然,最简单的方法是直接在父级中捕获输出
data_from_subshell=$(echo "This is the data I want to pass to the parent shell")
Run Code Online (Sandbox Code Playgroud)
您可以使用命名管道作为从子项读取数据的替代方法
mkfifo /tmp/fifo
Run Code Online (Sandbox Code Playgroud)
现在你可以将孩子重定向到 /tmp/fifo
(
echo "This should go to STDOUT"
echo "This is the data I want to pass to the parent shell" >/tmp/fifo
) &
Run Code Online (Sandbox Code Playgroud)
父母可以从那里读
read data_from_subshell </tmp/fifo
Run Code Online (Sandbox Code Playgroud)
另一种方法是使用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"
Run Code Online (Sandbox Code Playgroud)
在Bash 4.0中引入了Coprocesses.