In dieser Frage geht es nicht darum, wie ein ordnungsgemäß maskiertes Zeichenfolgenliteral geschrieben wird. Ich konnte keine verwandte Frage finden, bei der es nicht darum geht, Variablen für den direkten Verbrauch innerhalb eines Skripts oder durch andere Programme zu entziehen.
Mein Ziel ist es, ein Skript zu ermöglichen, andere Skripte zu generieren. Dies liegt daran, dass die Tasks in den generierten Skripten auf einem anderen Computer zwischen 0 und n Mal ausgeführt werden und sich die Daten, aus denen sie generiert werden, möglicherweise ändern, bevor sie (erneut) ausgeführt werden, sodass die Vorgänge direkt über ein Netzwerk ausgeführt werden nicht arbeiten.
Bei einer bekannten Variablen, die Sonderzeichen wie einfache Anführungszeichen enthalten kann, muss diese als vollständig maskiertes Zeichenfolgenliteral ausgegeben werden. Eine Variable, die beispielsweise Folgendes foo
enthält, bar'baz
sollte im generierten Skript folgendermaßen aussehen:
qux='bar'\''baz'
Das würde durch Anhängen "qux=$foo_esc"
an die anderen Zeilen der Schrift geschrieben werden. Ich habe es mit Perl so gemacht:
foo_esc="'`perl -pe 's/('\'')/\\1\\\\\\1\\1/g' <<<"$foo"`'"
aber das scheint übertrieben.
Ich habe keinen Erfolg damit gehabt, es mit Bash alleine zu tun. Ich habe viele Variationen davon ausprobiert:
foo_esc="'${file//\'/\'\\\'\'}'"
foo_esc="'${file//\'/'\\''}'"
Aber entweder erscheinen zusätzliche Schrägstriche in der Ausgabe (wenn ich das tue echo "$foo"
) oder sie verursachen einen Syntaxfehler (weitere Eingaben werden von der Shell erwartet).
alias
und / oderset
ziemlich universellalias "varname=$varname" varname
odervar=value set
Antworten:
Bash bietet für genau diesen Fall eine Option zur Parametererweiterung :
Also in diesem Fall:
Dies wird in Bash 4.4 und höher unterstützt. Es gibt verschiedene Optionen für andere Formen der Erweiterung und zum gezielten Generieren vollständiger Zuweisungsanweisungen (
@A
).quelle
bad substitution
."${foo:q}"
."${foo@Q}"
funktioniert!Bash bietet einen
printf
eingebauten%q
Formatbezeichner, der Shell- Escape-Vorgänge auch in älteren Versionen (<4.0) von Bash ausführt:Dieser Trick kann auch verwendet werden, um Datenfelder von einer Funktion zurückzugeben:
Beachten Sie, dass sich das integrierte Bash von
printf
demprintf
Dienstprogramm unterscheidet, das mit den meisten Unix-ähnlichen Betriebssystemen geliefert wird. Wenn derprintf
Befehl aus irgendeinem Grund das Dienstprogramm anstelle des eingebauten aufruft, können Sie ihnbuiltin printf
stattdessen immer ausführen .quelle
'Ne'\''er do well'
, usw., dh Zitate in der Ausgabe enthalten.[[ 'Ne'\''er do well' == Ne\'er\ do\ well ]] && echo 'equivalent!'
will Echoequivalent!
'hello'
zum falschen Wert führt''\''hello''
, der eine unnötig führende leere Zeichenfolge (die ersten beiden einfachen Anführungszeichen) und ein unangemessenes nachgestelltes einfaches Anführungszeichen enthält.$'escape-these-chars'
die ANSI-C- Anführungszeichenfunktion von Bash, mit der alle Zeichen in der angegebenen Zeichenfolge maskiert werden. Somit kann leicht eine Stringliteral erstellen , die eine neue Zeile im Dateinamen enthält (zB die$'first-line\nsecond-line')
Verwendung\n
innerhalb dieses Konstrukts.Ich glaube, ich habe nicht RTFM. Das kann so gemacht werden:
Dann
echo "$foo_esc"
gibts das erwartete'bar'\''baz'
Wie ich es tatsächlich benutze, ist mit einer Funktion:
Ändern Sie dies, um die
printf
integrierte Lösung von Dejay zu verwenden:quelle
Es gibt verschiedene Lösungen, um einen var-Wert anzugeben:
Alias
In den meisten Shells (wo Alias verfügbar ist) (außer csh, tcsh und wahrscheinlich anderen csh-ähnlichen):
Ja, das funktioniert in vielen
sh
ähnlichen Schalen wie Bindestrich oder Asche.set
Auch in den meisten Shells (wieder nicht csh):
gesetzte
In einigen Shells (mindestens ksh, bash und zsh):
Exportieren
Zuerst machen Sie:
Dann benutze:
ksh
export -p | grep 'qux='
bashexport -p | grep 'qux='
zsh
export -p qux
Zitat
bash
echo "${qux@Q}"
zsh
echo "${(qq)qux}"
# von ein bis vier qs kann verwendet werden.quelle
grep
mitexport
oderset
brechen können auf Variablen eingebettete Zeilenumbrüche enthalten.