我一直工作在这一段时间,似乎是没有办法做到这一点与过程替代,除了诉诸内嵌信号,并能真的只能用于输入管道,所以我不打算扩展它。
但是,bash-4.0提供了coprocesses,它可以用来取代在这种情况下的进程替换,并提供清晰的收获。
你提供下面的代码片段:
git status --short | tee >(xargs -Istr test -z str)
可以通过东西都被替换为:
coproc GIT_XARGS { xargs -Istr test -z str; }
{ git status --short | tee; } >&${GIT_XARGS[1]}
exec {GIT_XARGS[1]}>&-
wait ${GIT_XARGS_PID}
现在,对于一些解释:
的coproc
调用创建一个新的协进程,命名它GIT_XARGS
(你可以使用任何你喜欢的名字),并运行大括号中的命令。为协处理创建了一对管道,重定向其标准输入和标准输出。
的coproc
调用设置两个变量:
${GIT_XARGS[@]}
含有管道处理stdin和stdout,适当地([0]
从标准输出读,[1]
写入标准输入),
${GIT_XARGS_PID}
含有协进程PID。
然后,运行命令并将其输出定向到第二个管道(即coprocess的stdin)。看似隐秘的>&${GIT_XARGS[1]}
部分扩展到>&60
这是常规的输出到fd重定向。
请注意,我需要把你的命令放在大括号中。这是因为管道会导致子进程生成,并且它们不会从父进程继承文件描述符。换句话说,执行以下操作:
git status --short | tee >&${GIT_XARGS[1]}
会失败,无效的文件描述符错误,因为相关的FD的父进程存在,而不是催生tee
过程。将其放在大括号中会导致bash将重定向应用于整个管道。
exec
调用用于关闭到您的协处理的管道。在使用进程替换时,该进程会作为输出重定向的一部分生成,并且在重定向不再生效后立即关闭该进程的管道。由于协处理管道的生命周期超出了单个重定向,我们需要明确地关闭它。
关闭输出管道应该会导致进程在标准输入上获得EOF条件并正常终止。我们使用wait
等待终止并收获。 wait
返回协处理器的退出状态。
作为最后一个注意事项,请注意,在这种情况下,您不能使用kill
来终止协处理,因为这会改变其退出状态。
对不起,你究竟想要达到什么目的?只需检查该目录中是否有git状态? –
是的,它是部署脚本的一部分,如果目录很脏,应该退出非零值。 – jodell