Запрашивать подтверждение для каждой команды

Запрашивать подтверждение для каждой команды

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

Связанный контент