
Estoy escribiendo un script de instalación bastante ad hoc para algo. No hay muchas construcciones de control, básicamente solo una lista de comandos. Me gustaría que el usuario confirme cada comando antes de ejecutarlo. ¿Hay alguna manera de permitir que bash haga eso, sin anteponer a cada comando un nombre de función de Shell?
Respuesta1
Podrías 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
...
Como referencia, el zsh
equivalente sería:
TRAPDEBUG() {
read -q "?run \"$ZSH_DEBUG_CMD\"? " || setopt errexit
echo > /dev/tty
}
cmd1
cmd2
...
Más portátil:
run() {
printf '%s ' "run $@?" > /dev/tty
IFS= read -r answer < /dev/tty
case $answer in
[yY]*) "$@";;
esac
}
run cmd1
run cmd2
run cmd3 > file
Tenga en cuenta que en run cmd3 > file
, file
se truncará incluso si dice n
. Entonces quizás quieras escribirlo:
run eval 'cmd3 > file'
O mueva el eval
a la run
función como en:
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'
Otro portátil, pero con aún más limitaciones:
xargs -pL1 env << 'EOF'
cmd1 "some arg"
cmd2 'other arg' arg\ 2
ENV_VAR=value cmd3
EOF
Solo funciona para comandos (los que se encuentran en $PATH
), y los argumentos solo pueden ser cadenas literales (sin variables ni estructura de shell, aunque los xargs entienden algunas formas de comillas propias), y no puede tener redirecciones, canalizaciones...