You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何通过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

原因分析

  1. 重定向语法完全错误
    你在test4.sh中写的bash 1.sh p_in<0不符合shell重定向规则:

    • 这里的<0会被解析为「把1.sh的标准输入绑定到名为0的文件」,而非你预期的「将FIFOp_in作为1.sh的输入源」。
    • 因为设置了set +e,即使文件0不存在,脚本也会继续执行,此时1.sh的标准输入直接继承自test4.sh的终端输入。
  2. 多进程抢占终端输入
    脚本启动后,同时有两个进程在监听终端输入:

    • 1.sh中的read命令等待用户输入
    • cat -也在等待终端输入(cat -默认从标准输入读取内容)
      操作系统会随机将终端输入分配给其中一个进程,你看到的'd'就是某次运行时,你不小心输入的字符被1.sh的read抢先捕获了。
  3. 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 20:30:43