为何通过test4.sh调用1.sh时readline误判输入了d键?
问题:通过脚本调用时
read命令意外获取到'd'的原因解析 我有两个脚本test4.sh和1.sh,其中test4.sh会调用1.sh。直接运行1.sh时一切正常,但通过test4.sh调用时,1.sh中的read命令获取到的输入为'd',请解释这个现象。
1.sh代码
set -x echo "Please enter some input: " echo "enter $(echo $RANDOM)" sleep 2 read input_variable echo "You entered: $input_variable"
test4.sh代码
set -x set +e mkfifo p_in bash 1.sh p_in<0 | sed -e 's/^/1\.sh:: /' & cat - 1> p_in
执行输出
pi@raspberrypi:~/tmp/lolttt $ bash test4.sh + set +e + mkfifo p_in mkfifo: cannot create fifo 'p_in': File exists + bash 1.sh p_in + cat - + sed -e 's/^/1\.sh:: /' + echo 'Please enter some input: ' 1.sh:: Please enter some input: ++ echo 23876 + echo 'enter 23876' 1.sh:: enter 23876 + sleep 2 + read input_variable + echo 'You entered: d' 1.sh:: You entered: d
原因分析
重定向语法完全错误
你在test4.sh中写的bash 1.sh p_in<0不符合shell重定向规则:- 这里的
<0会被解析为「把1.sh的标准输入绑定到名为0的文件」,而非你预期的「将FIFOp_in作为1.sh的输入源」。 - 因为设置了
set +e,即使文件0不存在,脚本也会继续执行,此时1.sh的标准输入直接继承自test4.sh的终端输入。
- 这里的
多进程抢占终端输入
脚本启动后,同时有两个进程在监听终端输入:1.sh中的read命令等待用户输入cat -也在等待终端输入(cat -默认从标准输入读取内容)
操作系统会随机将终端输入分配给其中一个进程,你看到的'd'就是某次运行时,你不小心输入的字符被1.sh的read抢先捕获了。
FIFO未被正确利用
你创建p_in的目的应该是让1.sh通过FIFO获取输入,但当前写法完全没有建立这个关联。正确的写法应该是将1.sh的标准输入重定向到FIFO:bash 1.sh < p_in | sed -e 's/^/1\.sh:: /' &另外,建议添加清理逻辑避免FIFO残留导致下次运行报错:
trap 'rm -f p_in' EXIT
内容的提问来源于stack exchange,提问作者dewijones92
相关产品推荐
相关产品推荐

