146 Stimmen

Wie kann der Wert einer Variablen an die Standardeingabe eines Befehls übergeben werden?

Ich schreibe ein Shell-Skript, das einigermaßen sicher sein soll, d.h. keine sicheren Daten über Parameter von Befehlen übergibt und möglichst keine temporären Dateien verwendet. Wie kann ich eine Variable an die Standardeingabe eines Befehls übergeben?

Oder, falls dies nicht möglich ist, wie kann ich temporäre Dateien korrekt für eine solche Aufgabe verwenden?

257voto

Martin Punkte 35108

Die Übergabe eines Wertes an die Standardeingabe in der Bash ist so einfach wie:

your-command <<< "$your_variable"

Stellen Sie sicher, dass Sie variable Ausdrücke immer in Anführungszeichen setzen!

Bitte beachten Sie, dass dies wahrscheinlich nur in bash und wird nicht funktionieren in sh .

94voto

Oliver Charlesworth Punkte 259497

Einfach, aber fehleranfällig: mit echo

Etwas so Einfaches wie dies wird den Zweck erfüllen:

echo "$blah" | my_cmd

Bitte beachten Sie, dass dies möglicherweise nicht korrekt funktioniert, wenn $blah enthält -n , -e , -E usw.; oder wenn sie Backslashes enthält (die Bash-Kopie von echo bewahrt buchstäbliche Backslashes in Abwesenheit von -e standardmäßig, behandelt sie aber als Escape-Sequenzen und ersetzt sie durch entsprechende Zeichen, auch ohne -e wenn optionale XSI-Erweiterungen aktiviert sind).

Anspruchsvollerer Ansatz: Verwendung von printf

printf '%s\n' "$blah" | my_cmd

Dies hat nicht die oben genannten Nachteile: alle möglichen C-Strings (Strings, die keine NULs enthalten) werden unverändert ausgegeben.

20voto

PoltoS Punkte 1161
(cat <<END
$passwd
END
) | command

En cat ist eigentlich nicht nötig, 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.

20voto

Jonathan Leffler Punkte 694013

Beachten Sie, dass die ' echo "$var" | command Operationen bedeuten, dass die Standardeingabe auf die Zeile(n) beschränkt ist, die geechot werden. Wenn Sie wollen, dass auch das Terminal verbunden wird, müssen Sie sich etwas einfallen lassen:

{ echo "$var"; cat - ; } | command

( echo "$var"; cat -   ) | command

Das bedeutet, dass die erste(n) Zeile(n) der Inhalt von $var aber der Rest kommt von cat seine Standardeingabe lesen. Wenn der Befehl nichts allzu Ausgefallenes tut (versuchen Sie, die Befehlszeilenbearbeitung zu aktivieren, oder führen Sie ihn aus wie vim tut), dann wird es gut sein. Andernfalls müssen Sie sich wirklich etwas einfallen lassen - ich denke expect oder eines seiner Derivate ist wahrscheinlich geeignet.

Die Schreibweisen in der Befehlszeile sind praktisch identisch - nur das zweite Semikolon ist bei den geschweiften Klammern notwendig, während es bei den geklammerten Klammern nicht notwendig ist.

16voto

Kamil Maciorowski Punkte 320

Diese robuste und tragbare Methode wurde bereits in Kommentaren erwähnt. Es sollte eine eigenständige Antwort sein.

printf '%s' "$var" | my_cmd

o

printf '%s\n' "$var" | my_cmd

Notas:

  • Es ist besser als echo Die Gründe sind hier: Warum ist printf besser als echo ?
  • printf "$var" ist falsch. Das erste Argument ist das Format, in dem verschiedene Sequenzen wie %s o \n sont gedolmetscht . Um die Variable richtig zu übergeben, darf sie nicht als Format interpretiert werden.
  • Normalerweise enthalten Variablen keine nachgestellten Zeilenumbrüche. Der erste Befehl (mit %s ) übergibt die Variable so, wie sie ist. Werkzeuge, die mit Text arbeiten, können jedoch eine unvollständige Zeile ignorieren oder sich darüber beschweren (siehe Warum sollten Textdateien mit einem Zeilenumbruch enden? ). Sie können also den letzteren Befehl (mit %s\n ), die ein Zeilenumbruchzeichen an den Inhalt der Variablen anhängt. Nicht offensichtliche Fakten:

    • Hier String in Bash ( <<<"$var" my_cmd ) wird ein Zeilenumbruch angehängt.
    • Jede Methode, die einen Zeilenumbruch anhängt, führt zu einer nicht leeren stdin von my_cmd , auch wenn die Variable leer oder undefiniert ist.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X