
Я пишу довольно специальный скрипт установки для чего-то. Никаких особых управляющих конструкций, в основном просто список команд. Я бы хотел, чтобы пользователь подтверждал каждую команду перед ее выполнением. Есть ли способ позволить bash делать это, не предваряя каждую команду именем функции оболочки?
решение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
), а аргументы могут быть только литеральными строками (никаких переменных или структур оболочки, хотя xargs понимает некоторые собственные формы кавычек), и вы не можете использовать перенаправления, конвейеры...