Die Anführungszeichen werden entfernt, bevor die Argumente an Ihr Skript übergeben werden, daher ist es zu spät, sie beizubehalten. Sie können ihre Wirkung beibehalten, wenn Sie die Argumente an den inneren Befehl übergeben, und eine äquivalente Version der Argumente mit Anführungszeichen/Escapezeichen zum Drucken rekonstruieren.
Zur Übergabe der Argumente an den inneren Befehl "[email protected]"
-- mit den doppelten Anführungszeichen behält [email protected] die ursprünglichen Wortumbrüche bei, was bedeutet, dass der innere Befehl genau dieselbe Argumentliste erhält wie Ihr Skript.
Zum Drucken können Sie das %q-Format im printf-Befehl der Bash verwenden, um die Anführungszeichen zu rekonstruieren. Beachten Sie, dass dies nicht immer das ursprüngliche Zitat rekonstruiert, sondern ein Äquivalent erstellt Zeichenfolge in Anführungszeichen/mit Escapezeichen. Zum Beispiel, wenn Sie das Argument 'uptime ; uname -a'
übergeben haben es könnte uptime\ \;\ uname\ -a
ausgeben oder "uptime ; uname -a"
oder ein anderes Äquivalent (siehe Antwort von @William Pursell für ähnliche Beispiele).
Hier ist ein Beispiel für die Verwendung dieser:
printf "Running command:"
printf " %q" innercmd "[email protected]" # note the space before %q -- this inserts spaces between arguments
printf "\n"
innercmd "[email protected]"
Wenn der Benutzer Ihren Befehl aufruft als:
./script 'foo'
Das erste Argument, das dem Skript übergeben wird, ist die Zeichenfolge foo
ohne die Anführungszeichen. Es gibt keine Möglichkeit für Ihr Skript, zwischen dieser und einer der anderen Methoden zu unterscheiden, mit denen es foo
erhalten könnte als Argument (zB ./script $(echo foo)
oder ./script foo
oder ./script "foo"
oder ./script \f\o""''""o
).
Wenn Sie die Argumentliste so nah wie möglich an dem drucken möchten, was der Benutzer wahrscheinlich eingegeben hat:
#!/bin/bash
chars='[ !"#$&()*,;<>?\^`{|}]'
for arg
do
if [[ $arg == *\'* ]]
then
arg=\""$arg"\"
elif [[ $arg == *$chars* ]]
then
arg="'$arg'"
fi
allargs+=("$arg") # ${allargs[@]} is to be used only for printing
done
printf '%s\n' "${allargs[*]}"
Es ist nicht perfekt. Ein Argument wie ''\''"'
schwieriger unterzubringen ist als gerechtfertigt.