Ich schreibe ein Shell-Skript, das etwas sicher sein sollte, dh keine sicheren Daten über Parameter von Befehlen weiterleitet und vorzugsweise keine temporären Dateien verwendet. Wie kann ich eine Variable an den Standard eines Befehls übergeben? Oder, wenn es nicht möglich ist, wie man temporäre Dateien für eine solche Aufgabe richtig verwendet?
105
$PATH
? So dasscat
ersetzt werden kann/bin/cat "$@" | tee /attacker/can/read/this/file
Antworten:
Etwas so Einfaches wie:
quelle
echo "$blah"
ist besser.blah=-n
,blah=-e
...printf
stattdessen verwenden. unix.stackexchange.com/questions/65803/…printf '%s\n' "$blah"
? Mit diesem einen Wandel (in vielen Fallen zu vermeidenecho
‚s - Spezifikation, die Stephane ausgezeichnete Antwort in auf im Detail geht Warum istprintf
besser alsecho
? Auf Unix & Linux , oder die die Nutzung von Anwendungen Abschnitt derecho
Spezifikation berührt kürzer) ist es ein perfekt vernünftige Antwort.Das Übergeben eines Werts an
stdin
in bash ist so einfach wie:Stellen Sie immer sicher, dass Sie Anführungszeichen um variable Ausdrücke setzen!
quelle
<<<
sind garantiert nicht verfügbar, sie befinden sich meines Wissens nicht in POSIX-Basis. Sie funktionieren wie erwartet, solange Sie sie nur ausführenbash
. Ich erwähne es nur, weil sie OP sagten "Shell" nicht speziell "Bash". Obwohl er die Frage mitbash
... markiert hat, ist dies offensichtlich immer noch eine akzeptable Antwort.echo
Methode aufgrund der Erstellung eines Rohrs leichter verloren gehen . Der Herestring-Befehl wird vollständig von verarbeitetbash
, obwohl Sie in dieser Situation (wie angegeben) besser wissen sollten, dass er bei Ihrer Bash funktioniert. Andernfalls würde jede Fehlermeldung, die aufgrund der Nichtunterstützung von Herestrings erzeugt wird, diese Informationen ebenfalls verlieren.echo
ist ein eingebauter. Keine Pfeife da, oder? Es ist Unix, aber es kann nicht so viel Unix sein .printf '%s\n' "$var"
liefert die gleichen Ergebnisse wieecho "$var"
, bricht jedoch nicht, wenn z. B.var=-en
, und erfordert nicht einmal Bash.Beachten Sie, dass die '
echo "$var" | command
Operationen bedeuten, dass die Standardeingabe auf die wiedergegebenen Zeilen beschränkt ist. Wenn Sie auch möchten, dass das Terminal angeschlossen wird, müssen Sie schicker sein:Dies bedeutet, dass die erste (n) Zeile (n) der Inhalt ist
$var
, der Rest jedoch aus demcat
Lesen der Standardeingabe stammt. Wenn der Befehl nichts Besonderes tut (versuchen Sie, die Befehlszeilenbearbeitung zu aktivieren oder wie ausgeführt auszuführenvim
), ist dies in Ordnung. Andernfalls müssen Sie wirklich ausgefallen sein - ich denke,expect
oder eines seiner Derivate ist wahrscheinlich angemessen.Die Befehlszeilennotationen sind praktisch identisch - aber das zweite Semikolon ist bei geschweiften Klammern erforderlich, während es nicht bei Klammern steht.
quelle
( echo "$LIST"; cat - ) | sed 1q
Das funktioniert bei mir, aber ich muss Strg drücken, wenn ich dieses Skript ausführe.cat -
liest weiter von der Tastatur bis EOF oder Interrupt, daher müssen Sie es EOF mitteilen, indem Sie Control-D eingeben.cat
wenn Sie keine Terminaleingabe möchten, wie in der ersten Zeile. Oder Sie könnencat
eine Datei auflisten. Oder ... Wenn der Befehl die Terminal-Eingabe lesen soll, müssen Sie ihm mitteilen, wann er das Ende der Eingabe erreicht hat. Oder Sie könnten verwenden( echo "$var"; sed /quit/q - ) | command
; Dies wird fortgesetzt, bis Sie eine Zeile mit 'quit' eingeben. Sie können unendlich erfinderisch sein, wie Sie damit umgehen. Hüten Sie sich vor der alten urbanen Legende eines Programms, das nicht mehr funktioniert, als die Benutzer mit Ecuador zu arbeiten begannen. Sie tippten den Namen der Hauptstadt Quito ein und das Programm wurde beendet.echo "$LIST" | sed 1q | ...
? Es hängt alles davon ab, worum es Ihnen geht. Die<<EOF
Notation sollte einen EOF am Anfang einer eigenen Zeile irgendwo in der Datei erfordern. Ich würde es nicht benutzen, denke ich - aber ich bin mir immer noch nicht sicher, was Sie erreichen wollen. Ein einfachesecho "$LIST" | command
oderecho $LIST | command
wird wahrscheinlich in der Praxis ausreichen (und es ist wichtig, dass Sie die Bedeutung des Unterschieds zwischen den beiden kennen).Ich mochte Martins Antwort, aber es gibt einige Probleme, je nachdem, was in der Variablen enthalten ist. Dies
ist besser, wenn Ihre Variable "oder" enthält!
quelle
foo1=-; foo2='"'; foo3=\!; cat<<<"$foo1"; cat<<<"$foo2"; cat<<<"$foo3"
funktioniert gut für mich. Was genau machen die drei"
? AFAIK Sie stellen nur eine leere Zeichenfolge voran und fügen sie hinzu.Das
cat
wird nicht wirklich benötigt, aber es hilft, den Code besser zu strukturieren und ermöglicht es Ihnen, mehr Befehle in Klammern als Eingabe für Ihren Befehl zu verwenden.quelle
$passwd
Gemäß Martins Antwort gibt es eine Bash-Funktion namens Here Strings (die selbst eine Variante der weiter verbreiteten Here Documents- Funktion ist).
http://www.gnu.org/software/bash/manual/bashref.html#Here-Strings
Beachten Sie, dass Here Strings nur für Bashs gedacht sind. Um die Portabilität zu verbessern, sollten Sie mit der ursprünglichen Here Documents-Funktion gemäß der Antwort von PoltoS wahrscheinlich besser dran sein:
Oder eine einfachere Variante des oben genannten:
Sie können
(
und weglassen)
, es sei denn, Sie möchten dies weiter in andere Befehle umleiten lassen.quelle
Diese robuste und tragbare Methode wurde bereits in Kommentaren erwähnt. Es sollte eine eigenständige Antwort sein.
oder
Anmerkungen:
echo
, Gründe sind hier: Warum istprintf
besser alsecho
?printf "$var"
ist falsch. Das erste Argument ist Format , bei den verschiedenen Sequenzen mögen%s
oder\n
werden interpretiert . Um die Variable richtig zu übergeben, darf sie nicht als Format interpretiert werden.Normalerweise enthalten Variablen keine nachgestellten Zeilenumbrüche. Der vorherige Befehl (mit
%s
) übergibt die Variable so wie sie ist. Tools, die mit Text arbeiten, können jedoch eine unvollständige Zeile ignorieren oder sich darüber beschweren (siehe Warum sollten Textdateien mit einer neuen Zeile enden? ). Vielleicht möchten Sie den letzteren Befehl (mit%s\n
), der dem Inhalt der Variablen ein Zeilenumbruchzeichen hinzufügt. Nicht offensichtliche Tatsachen:<<<"$var" my_cmd
hängt der String in Bash ( ) eine neue Zeile an.my_cmd
, selbst wenn die Variable leer oder undefiniert ist.quelle
Versuche dies:
quelle
ps -u
angezeigt, wenn das Echo ausgeführt wird?echo
ist ein eingebautes, so gibt es keinen Prozess, um in ps zu zeigenecho "$variable"
ist besser.Mach einfach:
Wenn die Variable keine Leerzeichen enthält, können die Anführungszeichen weggelassen werden.
Wenn Sie bash verwenden, können Sie auch Folgendes tun:
Vermeiden Sie die Verwendung von Echo ohne -n, da dies die Vraiable mit einem zusätzlichen Zeilenumbruch am Ende weiterleitet.
quelle
%s
, printf druckt nichts.my_var="%s"; printf "$my_var";
- Vielleicht versuchenprintf "%s" "$my_var" | my_cmd
?