我有这个脚本的逐字记录:
#!/usr/bin/env bash
handle_json(){
while read line; do
cat <<EOF
{"@json-stdio":true,"value":{"mark":"$1","v":"$line"}}
EOF
done;
}
( echo; echo; echo 'du results:'; exit 0 ) > >(handle_json foo);
echo "zoom"
当我执行它时,我得到这个:
我必须用 ctrl-C 手动杀死它,因为它不会自行退出。
我想做的就是将子 shell 的标准输出发送到 bash 函数,以便它对输出进行 JSON 字符串化(现在不用担心转义特殊字符)。
有人知道为什么这个脚本不会自行退出吗?
更新:
这实际上做了我想要它做的事情:
( echo; echo; echo 'du results'; ) | handle_json 'foo';
echo "zoom"
上面使用管道运算符而不是重定向/进程替换。我没想到管道操作员会在这里工作。有人可以解释为什么/它是如何工作的吗?
答案1
据我所知,你的脚本做过出口;只是在外壳打印出提示符后,进程替换在后台完成了运行和打印。
避免这种情况的一种方法是简单地通过管道输入您的函数而不是使用> >(...)
:
( echo; echo; echo 'du results:'; exit 0 ) | handle_json foo
这是有效的,因为在写入 时cmd1 | cmd2
,两个命令并行启动,标准输出cmd1
连接到 的标准输入cmd2
,和bash 等待两者都完成才能认为管道已完成。
相比之下,cmd1 > >(cmd2)
几乎相同,除了 bash 在继续执行进一步命令之前不会等待cmd2
完成(在本例中,打印“zoom”然后退出,让交互式 bash 打印其提示符):如果碰巧,cmd2
完成所需的时间明显多于cmd1
,然后您观察到的那种令人惊讶的竞争条件就会发生。