
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 zsh
equivalente 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 file
será truncado mesmo se você disser n
. Então você pode querer escrever:
run eval 'cmd3 > file'
Ou mova eval
para a run
funçã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...