【发布时间】:2014-09-21 10:01:41
【问题描述】:
我正在尝试调用一个脚本 deepScript 并在另一个脚本 shallowScript 中处理其输出;它看起来像下面的代码片段:
shallowScript.sh
#!/bin/zsh
exec 1> >( tr "[a-z]" "[A-Z]" )
print "Hello - this is shallowScript"
. ./deepScript.sh
deepScript.sh
#!/bin/zsh
print "Hello - this is deepScript"
现在,当我运行 ./shallowScript.sh 时,结果是不稳定的:要么按预期工作(很少),要么打印一个空行,后跟两个预期的行(有时),或者它打印两行然后挂起,直到我按回车并给它一个换行符(大部分时间)。 到目前为止,我发现了以下内容:
- 这可能是一种竞争条件,因为两个“打印”试图同时输出到标准输出;在调用“../deepScript.sh”之前插入“sleep 1”可以始终如一地纠正问题
- 问题来自进程替换“exec 1> >(tr ...)”;将其注释掉也可以始终如一地纠正问题
我浏览了很多关于进程替换和重定向的论坛和帖子,但无法找到如何保证我的脚本同步调用命令。想法?
zsh --version
zsh 5.0.5 (x86_64-apple-darwin14.0)
[编辑]
由于这个策略似乎注定会失败或导致可怕的变通语法,这里是另一种似乎适用于可忍受语法的策略:我从 shallowScript.sh 中删除了所有重定向和创建了第三个脚本,其中输出处理发生在函数中:
shallowScript.sh
#!/bin/zsh
print "Hello - this is shallowScript"
. ./deepScript.sh
thirdScript.sh
#!/bin/zsh
function _process {
while read input; do
echo $input | tr "[a-z]" "[A-Z]"
done
}
. ./shallowScript.sh | _process
【问题讨论】:
-
_process中的while循环是不必要的;_process () { tr "[a-z]" "[A-Z]"; }。tr将处理其标准输入的每一行,因此无需为函数的标准输入的每一行调用一次。 -
真;我使用
tr制作了一个易于理解和可测试的代码sn-p,但我的真实脚本试图做的不仅仅是tr
标签: shell stdout zsh race-condition io-redirection