@ jw013 Guter Punkt und tolle Artikel. Ich mag das Zitat "Variablen enthalten Daten, Funktionen enthalten Code." Vom ersten Link an, aber für meine Verwendung sind die Daten, die einer Funktion (in diesem Fall at) gegeben werden, Code. Gibt es Tipps, wie Sie Code sicherer organisieren / sammeln können at?
Cory Klein
atVerwendet die shSyntax als Eingabe. Das Erzeugen von Eingaben für atbedeutet, dass gültige, korrekt zitierte shSyntax aus beliebigen Eingaben generiert wird , was nicht trivial ist. Daher würde ich versuchen, dies zu vermeiden, wenn dies überhaupt möglich ist. Es wäre wirklich hilfreich, wenn Sie ein wenig detaillierter beschreiben könnten, was Sie erreichen möchten.
jw013
Entschuldigung, ich wollte nicht mit zu vielen Details ablenken, aber was ich tue, ist nicht wirklich kompliziert, IMO. Ich erstelle ein Skript, das eine "Zeit" und eine "Nachricht" benötigt. Es wird dann atfür die angegebene "Zeit" ausgeführt und weist atan, den Befehl auszuführen dzen2. dzen2Nimmt die "Nachricht" von stdin und verwendet auch einige andere statische Parameter. Die Schwierigkeit besteht darin , dass ich die „message“ Parameter vom Benutzer in dem zu Rohr benötigen dzen2Befehl, aber ich bin nicht wirklich laufe dzen2mich, ich sage ates zu tun.
Es ist auch wichtig zu beachten, dass Anführungszeichen unterschiedlich bewertet werden. doppelte Anführungszeichen ( ") erlauben Auswertung der eingeschlossenen Zeichenfolge, einfache Anführungszeichen ( ') die Zeichenfolge als eine wörtliche drucken . Beispiel: "$(ls)"und '$(ls)'Dies ist der Grund , warum Zitate in Originalfragen Beispiele erscheinen..
Joseph Kern
Ein Array ist auch eine Quelle von Problemen. Code gehört zu Funktionen, Daten zu Variablen. Das von Ihnen dargestellte Beispiel funktioniert nur, weil die Anführungszeichen in der Aufteilung des Arrays entfernt werden. A printf '<%s> ' "${VAR[@]}"zeigt an, dass Anführungszeichen bereits entfernt wurden. Wenn Sie VAR eingestellt , wie VAR=(echo \"hi\")tatsächlich Anführungszeichen haben, das gleiche Problem erneut angezeigt wird, $ ${VAR[@]}druckt"hi"
9
Das Entfernen von Anführungszeichen erfolgt nur für die ursprünglichen Eingabewörter, nicht für das Ergebnis von Erweiterungen. Anführungszeichen, die Teil erweiterter Variablen sind, bleiben unberührt.
Wenn Sie etwas zurücktreten, können Sie sehen, warum die Variablensubstitution Anführungszeichen unbedingt beibehalten sollte.
Der Sinn der Anführungszeichen in einer Unix / Linux / BSD-Shell besteht darin, Teile eines Strings zusammenzuhalten, die andernfalls als mehrere Strings analysiert würden. Da eine Shell standardmäßig Leerzeichen als Token-Trennzeichen verwendet, wird eine Zeichenfolge mit Leerzeichen (wie "eins zwei drei"), wenn sie nicht in Anführungszeichen gesetzt oder in irgendeiner Weise maskiert wird, als drei Zeichenfolgen analysiert: "eins", "zwei" und "drei".
Wenn ein Programmierer einen String mit dem Wert einer Variablen interpolieren möchte:
VAR=two
STRING="one $VAR three"
Die Shell sollte die Anführungszeichen auf keinen Fall entfernen: Die Zeichenfolge, die Leerzeichen enthält, wird als 3 kleinere Zeichenfolgen analysiert.
eval
ein Minenfeld von potenziellen Sicherheitslücken, die Sie sehr vorsichtigat
) gegeben werden, Code. Gibt es Tipps, wie Sie Code sicherer organisieren / sammeln könnenat
?at
Verwendet diesh
Syntax als Eingabe. Das Erzeugen von Eingaben fürat
bedeutet, dass gültige, korrekt zitiertesh
Syntax aus beliebigen Eingaben generiert wird , was nicht trivial ist. Daher würde ich versuchen, dies zu vermeiden, wenn dies überhaupt möglich ist. Es wäre wirklich hilfreich, wenn Sie ein wenig detaillierter beschreiben könnten, was Sie erreichen möchten.at
für die angegebene "Zeit" ausgeführt und weistat
an, den Befehl auszuführendzen2
.dzen2
Nimmt die "Nachricht" von stdin und verwendet auch einige andere statische Parameter. Die Schwierigkeit besteht darin , dass ich die „message“ Parameter vom Benutzer in dem zu Rohr benötigendzen2
Befehl, aber ich bin nicht wirklich laufedzen2
mich, ich sageat
es zu tun.Antworten:
Das zusätzliche Paar von Anführungszeichen würde nur durch einen zusätzlichen Bewertungsschritt verbraucht. Zum Beispiel gezwungen durch
eval
:Generell ist es jedoch eine schlechte Idee, Befehle mit Parametern in eine Zeichenfolge zu setzen. Verwenden Sie stattdessen ein Array:
quelle
"$(ls)"
und'$(ls)'
Dies ist der Grund , warum Zitate in Originalfragen Beispiele erscheinen..printf '<%s> ' "${VAR[@]}"
zeigt an, dass Anführungszeichen bereits entfernt wurden. Wenn Sie VAR eingestellt , wieVAR=(echo \"hi\")
tatsächlich Anführungszeichen haben, das gleiche Problem erneut angezeigt wird,$ ${VAR[@]}
druckt"hi"
Das Entfernen von Anführungszeichen erfolgt nur für die ursprünglichen Eingabewörter, nicht für das Ergebnis von Erweiterungen. Anführungszeichen, die Teil erweiterter Variablen sind, bleiben unberührt.
quelle
Wenn Sie etwas zurücktreten, können Sie sehen, warum die Variablensubstitution Anführungszeichen unbedingt beibehalten sollte.
Der Sinn der Anführungszeichen in einer Unix / Linux / BSD-Shell besteht darin, Teile eines Strings zusammenzuhalten, die andernfalls als mehrere Strings analysiert würden. Da eine Shell standardmäßig Leerzeichen als Token-Trennzeichen verwendet, wird eine Zeichenfolge mit Leerzeichen (wie "eins zwei drei"), wenn sie nicht in Anführungszeichen gesetzt oder in irgendeiner Weise maskiert wird, als drei Zeichenfolgen analysiert: "eins", "zwei" und "drei".
Wenn ein Programmierer einen String mit dem Wert einer Variablen interpolieren möchte:
Die Shell sollte die Anführungszeichen auf keinen Fall entfernen: Die Zeichenfolge, die Leerzeichen enthält, wird als 3 kleinere Zeichenfolgen analysiert.
quelle