
我正在為某些事情編寫一個非常臨時的安裝腳本。沒有太多的控制結構,基本上只是一個指令清單。我希望用戶在執行每個命令之前確認它。有沒有辦法讓 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 理解其自身的某些形式的引用),並且不能有重定向、管道.. .