我正在为某些事情编写一个非常临时的安装脚本。没有太多的控制结构,基本上只是一个命令列表。我希望用户在执行每个命令之前确认它。有没有办法让 bash 做到这一点,而不用在每个命令前加上 shell 函数名前缀?
答案1
你可以使用extdebug
:
shopt -s extdebug
trap '
IFS= read -rn1 -d '' -p "run \"$BASH_COMMAND\"? " answer <> /dev/tty 1>&0
echo > /dev/tty
[[ $answer = [yY] ]]' DEBUG
cmd1
cmd2
...
作为参考,zsh
等效项是:
TRAPDEBUG() {
read -q "?run \"$ZSH_DEBUG_CMD\"? " || setopt errexit
echo > /dev/tty
}
cmd1
cmd2
...
更便携:
run() {
printf '%s ' "run $@?" > /dev/tty
IFS= read -r answer < /dev/tty
case $answer in
[yY]*) "$@";;
esac
}
run cmd1
run cmd2
run cmd3 > file
请注意run cmd3 > file
,file
即使您说 , 也会被截断n
。所以你可能想这样写:
run eval 'cmd3 > file'
或者将 移动eval
到run
函数中,如下所示:
run() {
printf '%s ' "run $@?" > /dev/tty
IFS= read -r answer < /dev/tty
case $answer in
[yY]*) eval "$@";;
esac
}
run cmd1
run 'cmd2 "$var"'
run 'cmd3 > file'
另一种便携式的,但有更多的限制:
xargs -pL1 env << 'EOF'
cmd1 "some arg"
cmd2 'other arg' arg\ 2
ENV_VAR=value cmd3
EOF
它仅适用于命令(在 中找到的命令$PATH
),参数只能是文字字符串(没有变量或任何 shell 结构,尽管 xargs 理解其自身的某些形式的引用),并且不能有重定向、管道...