在命令替代中用外部调用诱捕会破坏父Bash shell

问题描述 投票:1回答:1

我有一个基于文本的用户界面脚本,该脚本可让我浏览目录并选择文件。图形输出到stderr,所选文件的路径发送到stdout。这样可以通过以下方式获取所选文件:

file="$(./script)"

这非常方便,因为命令替换仅获取stdout

但是我需要我的脚本来处理信号,以便当脚本被中断时,它可以重置显示。我设置了一个处理INT信号的陷阱。为了模拟它的作用,请考虑以下脚本:

catch() { 
    echo "caught"
    ps # Calling an external command
    exit
}

trap catch INT

while read -sN1; do # Reading from the keyboard
    echo $REPLY >&2
done

然后用var="$(./script)"调用脚本。现在,如果您通过按INT发送^C信号,则父shell会中断:您键入的任何内容(包括控制字符)都将被打印出来,直到您按回车键,则不会显示任何输入。

catch函数中删除外部命令调用似乎可以解决此问题(尽管echo似乎不起作用),但是我不明白为什么,在没有它的情况下我无法做我的最终脚本。

我缺少什么吗?为什么这会破坏父外壳?

bash shell command bash-trap command-substitution
1个回答
0
投票

我缺少什么吗?为什么这会破坏父外壳?

不是外壳,而是端子损坏。 read -sN1更改终端设置;它会关闭icanonechoechok模式,并且用catch中断exit中的脚本时,它不会恢复旧的设置。我可能不知道可能是个错误。

一种解决方法是手动还原旧的设置,如下所示。

catch() {
    echo "caught"
    ps # Calling an external command
    stty icanon echo echok # restore terminal settings
    exit
}

有关更多信息,请参见stty联机帮助页。

© www.soinside.com 2019 - 2024. All rights reserved.