Ich habe eine Anwendung, die als Eingabeattribute doppelte Anführungszeichen verwendet, die in einfache Anführungszeichen eingebettet sind. Nehmen Sie zum Beispiel diesen richtigen Befehl:
command -p 'cluster="cl1"'
Um dies zu automatisieren, habe ich eine Bash-Datei $CLUSTER
als Variable erstellt. Wie soll mein Befehl sein? Mit anderen Worten, was soll ich anstelle von cl1 setzen?
Bitte beachten Sie, dass wenn ich den obigen Befehl geändert habe, er nicht akzeptiert wird. Zum Beispiel: command -p "cluster=cl1"
wird nicht akzeptiert
CLUSTER='"cl1"'; command -p "cluster=$CLUSTER"
cli
ohne Anführungszeichen in derCLUSTER
Variablen zu speichern ):CLUSTER='cl1'; command -p 'cluster="'"$CLUSTER"'"'
Antworten:
Es sieht so aus, als würde Ihr Befehl möglicherweise Umgebungsvariablen basierend auf Argumenten festlegen, die in der Befehlszeile angegeben wurden. Möglicherweise können Sie Folgendes tun:
... und legen Sie beim Aufruf die Umgebung dafür fest.
Andernfalls begrenzen Shell-Anführungszeichen normalerweise Argumente oder entziehen andere Shell-Sonderzeichen der Shell-Interpretation. Sie können verschiedene Arten von Shell-Anführungszeichen in anderen Arten enthalten (und daher entkommen), basierend auf verschiedenen Regeln:
"''''"
- Eine Zeichenfolge in weichen Anführungszeichen kann eine beliebige Anzahl von Anführungszeichen enthalten."\""
- Ein\
Backslash kann einem"
weichen Anführungszeichen innerhalb einer"
Zeichenfolge mit weichen Anführungszeichen entgehen .\\
entgeht auch ein Backslash, das\$
Erweiterungstoken und\n
Ewlines, wie unten angegeben, wird aber ansonsten wörtlich behandelt."${expand} and then some"
- Eine Zeichenfolge in weichen Anführungszeichen kann eine interpretierte Shell-$
Erweiterung enthalten.'"\'
- Eine'
Zeichenfolge in harten Anführungszeichen kann ein anderes Zeichen als ein Zeichen in'
harten Anführungszeichen enthalten.\
- Ein nicht\n
zitierter Backslash entgeht jedem folgenden Zeichen für die wörtliche Interpretation - sogar einem weiteren Backslash - mit Ausnahme einer Ewline.\\n
Ewline-Fall werden sowohl der\
Backslash als auch der\n
Ewline vollständig aus dem resultierenden interpretierten Befehl entfernt.${parameter+expand "$parameter"}
- Anführungszeichen, die sich aus einer Shell-Erweiterung ergeben, dienen mit Ausnahme einiger Sonderfälle fast nie als Trennzeichen. Ich werde es nicht wagen, diese hier weiter zu beschreiben.Ich finde es seltsam, dass jede Anwendung Anführungszeichen in ihren Befehlszeilenargumenten interpretiert. Eine solche Praxis macht insofern wenig Sinn, als - zumindest für Muscheln - der Hauptzweck eines Zitats im Allgemeinen darin besteht, ein Argument abzugrenzen. Bei Aufruf werden immer jedoch Argumente bereits begrenzt mit
\0NUL
Zeichen und so ein Angebot kann nicht viel Zweck dienen.Selbst eine Shell wird sich normalerweise nur dann die Mühe machen, Anführungszeichen in einem ihrer Aufrufargumente zu interpretieren, wenn sie mit einem
-c
Schalter aufgerufen wird. Dies bedeutet, dass ihr erster Operand tatsächlich ein Shell-Skript ist, das beim Aufruf ausgeführt werden soll. Dies ist ein Fall von zweimal ausgewerteten Eingaben.Trotzdem können Sie eine Reihe von Maßnahmen ergreifen, um wörtliche Anführungszeichen über Argumente in der Befehlszeile zu übergeben. Beispielsweise:
Wie ich bereits in einem Kommentar erwähnt habe, können Sie die
"
Anführungszeichen in einer Erweiterung enthalten, die selbst in"
Anführungszeichen gesetzt ist.Sie können das
"
mit einem\
Backslash innerhalb der angegebenen"
Zeichenfolge umgehen.Sie können Anführungszeichenstile abwechseln und verketten, um das gewünschte Endergebnis zu erzielen , wie oben unter @jimmij angegeben .
Sie können sowohl die Generierung als auch die
$IFS
Aufteilung von Dateinamen deaktivieren,$expansion
sodass Sie die Anführungszeichen überhaupt nicht zitieren müssen, und daher nur die Anführungszeichen zitieren. Das ist wahrscheinlich übertrieben.Zuletzt gibt es eine andere Art von Shell-Zitat, die verwendet werden könnte. Wie bereits erwähnt, wird die
sh -c "$scriptlet"
Form des Shell-Aufrufs häufig verwendet, um das Skript einer Shell in der Befehlszeile bereitzustellen. Wenn es jedoch$scriptlet
kompliziert wird - beispielsweise wenn Anführungszeichen andere Anführungszeichen enthalten müssen - kann es oft vorteilhaft sein, ein Here-Dokument zu verwenden undsh -s
stattdessen - wo die Shell speziell angewiesen wird , den Positionsparametern alle folgenden Operanden zuzuweisen, wie dies in einem-c
Fall der Fall wäre und doch auch sein Skript zu entnehmenstdin
.Wenn Ihr Befehl Anführungszeichen auf diese Weise interpretieren muss, würde ich es besser in Betracht ziehen, wenn dies in einer Dateieingabe möglich wäre. Beispielsweise:
Wenn Sie das Trennzeichen von a nicht zitieren, werden
<<here-document
alle Inhalte fast genau so behandelt, als wären sie in"
weichen Anführungszeichen gesetzt worden - mit der Ausnahme, dass"
doppelte Anführungszeichen selbst nicht speziell behandelt werden. Und wenn wircat
stattdessen das Obige ausführen mit :... es druckt ...
quelle
Wie mikeserv schrieb:
„Double - Zitat“ jeder wörtlich , die Leerzeichen / Metazeichen und enthält jede Expansion:
"$var"
,"$(command "$var")"
,"${array[@]}"
,"a & b"
. Verwendung'single quotes'
für Code oder Literal$'s: 'Costs $5 US'
,ssh host 'echo "$HOSTNAME"'
. Siehehttp://mywiki.wooledge.org/Quotes
http://mywiki.wooledge.org/Arguments
http://wiki.bash-hackers.org/syntax/words
quelle
"
Zeichen bereinigen müssen - nur die erste und die letzte sollten ausreichen. Das eigentliche Problem hierbei ist, dass Ihre App Zitate in einem Argument interpretiert. Das Interpretieren eines Zitats in einem Argument ist fast nie eine gute Idee, da ein Zitat nur ein Mittel zur Abgrenzung eines Arguments sein sollte - und beim Aufrufen wird die Abgrenzung\0NUL
in jedem Fall von s behandelt . Wahrscheinlich gibt es eine bessere Möglichkeit, die gewünschten Informationen an die App zu übergeben? Wie eincommand --'script=/path/to/some/file'
oder so?