
Ich schreibe ein ziemlich Ad-hoc-Installationsskript für etwas. Keine großen Kontrollkonstrukte, im Grunde nur eine Liste von Befehlen. Ich möchte, dass der Benutzer jeden Befehl bestätigt, bevor er ausgeführt wird. Gibt es eine Möglichkeit, Bash dies tun zu lassen, ohne jedem Befehl einen Shell-Funktionsnamen voranzustellen?
Antwort1
Du könntest benutzen 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
...
Als Referenz zsh
wäre das Äquivalent:
TRAPDEBUG() {
read -q "?run \"$ZSH_DEBUG_CMD\"? " || setopt errexit
echo > /dev/tty
}
cmd1
cmd2
...
Tragbarer:
run() {
printf '%s ' "run $@?" > /dev/tty
IFS= read -r answer < /dev/tty
case $answer in
[yY]*) "$@";;
esac
}
run cmd1
run cmd2
run cmd3 > file
Beachten Sie, dass in abgeschnitten run cmd3 > file
wird, file
auch wenn Sie sagen n
. Sie können es also so schreiben:
run eval 'cmd3 > file'
Oder verschieben Sie es eval
in die run
Funktion wie in:
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'
Eine weitere portable Version, allerdings mit noch mehr Einschränkungen:
xargs -pL1 env << 'EOF'
cmd1 "some arg"
cmd2 'other arg' arg\ 2
ENV_VAR=value cmd3
EOF
Es funktioniert nur für Befehle (die in gefunden werden $PATH
), und Argumente können nur wörtliche Zeichenfolgen sein (keine Variablen oder Shell-Strukturen, obwohl xargs einige eigene Formen der Anführungszeichen versteht), und Sie können keine Umleitungen oder Pipes verwenden ...