Zsh版本:
zsh 5.4.2(x86_64-ubuntu-linux-gnu)
代码(两个文件:.zshrc和交互式文件,都位于我的主目录中):
.zshrc:
source ./interactive
custom_execute(){
echo
exc0 $BUFFER
BUFFER=""
zle accept-line
}
zle -N custom_execute
bind_enter(){
bindkey '^M' custom_execute
}
互动:
exc0(){
echo exc0_begin
cmd="$@"
eval "$cmd"
ret=$?
echo exc0_end
return $ret
}
场景:
打开一个新的shell,执行以下命令:
exc0 sudo apt remove gparted
在exc0之后执行什么命令并不重要,重要的是它需要用户从stdin中输入才能完成。就我而言,已经安装了gparted,它将询问我是否要删除它。
我使用ctrl + c终止命令,因为我确实不想删除gparted。 最后一行显示为:
Do you want to continue? [Y/n] ^C%
现在我输入以下命令:
bind_enter
之后:
sudo apt remove gparted
最后两行显示:
Do you want to continue? [Y/n] Abort.
exc0_end
在两种情况下,shell都要求输入我的sudo密码,该部分正在运行。但是当涉及到确认时,第二条命令中断了。问题:为什么?
答案 0 :(得分:2)
如果直接从TTY读取(如sudo
密码)有效,但从stdin读取(如常规提示)无效,则可以通过将TTY重定向到特定命令的stdin来解决此问题。应该从TTY读取。
因此:
exc0() {
local ret
echo exc0_begin
"$@" </dev/tty; ret=$?
echo exc0_end
return "$ret"
}
注意:
</dev/tty
意味着在有问题的命令期间,stdin从TTY重定向。ret
标记为局部变量,以避免污染全局名称空间。ret
并与生成要捕获的退出状态的命令所在的行相同(以减少将来在命令之间放置更改并因此修改{{1} })。$?
不必要的使用(并且引起了错误)。