Shell 为什么在使用zsh小部件执行交互命令时会中断
Zsh版本: zsh 5.4.2(x86_64-ubuntu-linux-gnu) 代码(两个文件:.zshrc和interactive,都位于我的主目录中): .zshrc:Shell 为什么在使用zsh小部件执行交互命令时会中断,shell,zsh,Shell,Zsh,Zsh版本: zsh 5.4.2(x86_64-ubuntu-linux-gnu) 代码(两个文件:.zshrc和interactive,都位于我的主目录中): .zshrc: source ./interactive custom_execute(){ echo exc0 $BUFFER BUFFER="" zle accept-line } zle -N custom_execute bind_enter(){ bindkey '^M' custom_execute }
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密码,该部分正在工作。但当涉及到确认时,第二个命令中断。问题:为什么?如果直接从TTY读取(如
sudo
password entry)有效,但从stdin读取(如常规提示)无效,那么您可以通过将TTY重定向到stdin来解决这一问题,以获得应该从TTY读取的特定命令
因此:
exc0(){
本地网
回声exc0_开始
“$@”这不是您当前问题的原因,但是cmd=“$@”;eval“$cmd”
通常有错误--“$@”
是一个数组,不能毫无损失地转换为字符串。为了向您自己证明这一点,请尝试运行以下命令:设置--printf“%s\n”第一行“第二行”;cmd=“$@”;eval“$cmd”
…将其与正常运行的代码集--printf“%s\n”第一行“第二行”;“$@”
,或同样正常运行的集--printf“%s\n”第一行“第二行”;cmd=(“$@”);“${cmd[@}”
,或与同样正常运行的集--printf“%s\n”第一行“第二行”进行比较;printf-v cmd“%q'”$@;eval“$cmd”
。无论如何,就sudo
密码和其他输入之间的差异而言,请使用@CharlesDuffy I将eval“$@”替换为eval“$@” $@谢谢你的回答。我试着用“$@”。啊!在这种情况下,您的代码将作为单个参数传递,而不是每个单词一个参数,因此您可以eval“$1”至于查看您键入的内容,配置本地echo是stty
的一项工作。请确保您在/dev/tty
上给它一个要操作的文件句柄。我最后保存了.zshrc中开始的tty配置,并将eval行更改为eval“stty$stty\u CONFIG;$cmd”exc0() {
local ret
echo exc0_begin
"$@" </dev/tty; ret=$?
echo exc0_end
return "$ret"
}