Solicitar confirmação para cada comando

Solicitar confirmação para cada comando

Estou escrevendo um script de instalação bastante ad-hoc para alguma coisa. Não há muitas construções de controle, basicamente apenas uma lista de comandos. Gostaria que o usuário confirmasse cada comando antes de ser executado. Existe uma maneira de permitir que o bash faça isso, sem prefixar cada comando com um nome de função shell?

Responder1

Você poderia usar 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
...

Para referência, o zshequivalente seria:

TRAPDEBUG() {
  read -q "?run \"$ZSH_DEBUG_CMD\"? " || setopt errexit
  echo > /dev/tty
}
cmd1
cmd2
...

Mais portável:

run() {
  printf '%s ' "run $@?" > /dev/tty
  IFS= read -r answer < /dev/tty
  case $answer in
    [yY]*) "$@";;
  esac
}
run cmd1
run cmd2
run cmd3 > file

Cuidado, pois em run cmd3 > file, o fileserá truncado mesmo se você disser n. Então você pode querer escrever:

run eval 'cmd3 > file'

Ou mova evalpara a runfunção como em:

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'

Outro portátil, mas com ainda mais limitações:

xargs -pL1 env << 'EOF'
cmd1 "some arg"
cmd2 'other arg' arg\ 2
ENV_VAR=value cmd3
EOF

Ele só funciona para comandos (encontrados em $PATH), e os argumentos só podem ser strings literais (nenhuma variável ou qualquer estrutura de shell, embora xargs entenda algumas formas de citação próprias), e você não pode ter redirecionamentos, pipes...

informação relacionada