Ich versuche derzeit, ein Skript zu erstellen, das Bytes erstellt, die als Eingabe an netcat weitergeleitet werden.
Hier ist die Idee des Skripts:
(perl -e "print \"$BYTES\x00\";
cat file;
perl -e "print \"More bytes\"x16 . \"\r\n\"";) | netcat ip port
Ich habe versucht, sowohl eine Subshell als auch eine Befehlssubstitution (z. B. mit $ ()) zu verwenden, um die Befehle auszuführen. Ich verstehe jedoch nicht, warum die Ausgabe des Skripts bei Verwendung der Befehlssubstitution falsch ist. Ich vermute, dass die Befehlssubstitution ihre Ausgabe bei der Ausführung mehrerer Befehle falsch weiterleitet. Kann mir jemand erklären, warum das so ist?
BEARBEITEN
Hier ist die Variante, die die Befehlssubstitution verwendet hat:
$(perl -e "print \"$BYTES\x00\";
cat file;
perl -e "print \"More bytes\"x16 . \"\r\n\"";) | netcat ip port
shell
shell-script
pipe
command-substitution
MykelXIII
quelle
quelle
netcat
da es sich nur um bloßen Text handelt. Wenn Sie beispielsweiseecho
vor Beginn der Befehlsersetzung hinzugefügt haben, stellen Sie möglicherweise fest, dass dies funktioniert.netcat
weil nichts ausgeführt wird.Antworten:
Okay, lass uns das zusammenfassen. Eine Subshell führt ihren Inhalt in einer Kette aus (dh sie gruppiert sie). Dies ist tatsächlich intuitiv sinnvoll, da eine Unterschale einfach durch Umgeben der Befehlskette mit erstellt wird
()
. Abgesehen davon, dass der Inhalt der Subshell bei der Ausführung zusammengefasst wird, können Sie eine Subshell weiterhin so verwenden, als wäre es ein einzelner Befehl. Das heißt, eine Unterschale hat immer noch einestdin
,stdout
undstderr
so können Sie Dinge zu und von einer Unterschale leiten.Andererseits ist das Ersetzen von Befehlen nicht dasselbe wie das einfache Verketten von Befehlen. Die Befehlssubstitution soll sich eher wie ein variabler Zugriff verhalten, jedoch mit einem Funktionsaufruf. Im Gegensatz zu Befehlen verfügen Variablen nicht über die Standard-Dateideskriptoren, sodass Sie (im Allgemeinen) nichts zu oder von einer Variablen weiterleiten können. Dies gilt auch für Befehlsersetzungen.
Um dies klarer zu machen, folgen eine Reihe von möglicherweise unklaren (aber genauen) Beispielen und eine Reihe von, wie ich denke, besser verständlichen Beispielen.
Angenommen, der
date -u
Befehl gibt Folgendes aus:Wir möchten jedoch die Ausgabe dieses Befehls bearbeiten. Also, lasst es uns in etwas wie
sed
:Wow, das hat Spaß gemacht! Das Folgende entspricht vollständig dem oben Gesagten (abgesehen von einigen Umgebungsunterschieden, über die Sie in den Manpages zu Ihrer Shell lesen können):
Das sollte keine Überraschung sein, da wir nur eine Gruppe gemacht haben
date -u
. Wenn wir jedoch Folgendes tun, werden wir etwas bekommen, das auf den ersten Blick etwas seltsam erscheint:Dies liegt daran
$(date -u)
, dass Sie genau eingeben müssen, welchedate -u
Ausgaben ausgegeben werden sollen. Das oben Gesagte entspricht also dem Folgenden:Was natürlich fehlerhaft sein wird, weil
Thu
es kein Befehl ist (zumindest keiner, den ich kenne); und es leitet sicher nichts weiterstdout
(sed
wird also niemals eine Eingabe bekommen).Da wir jedoch wissen, dass Befehlssubstitutionen wie Variablen wirken, können wir dieses Problem leicht beheben, da wir wissen, wie der Wert einer Variablen in einen anderen Befehl übertragen wird:
Aber wie bei jeder Variablen in bash sollten Sie wahrscheinlich Befehlsersetzungen mit zitieren
""
.Nun zum vielleicht einfacheren Beispiel; Folgendes berücksichtigen:
Ich bin mir nicht sicher, wie ich es einfacher beschreiben soll. Die Befehlssubstitution funktioniert genau wie ein variabler Zugriff, bei dem die Subshell weiterhin wie ein Befehl funktioniert.
quelle
Unterschale
(command)
führt den Befehl in der Unterschale aus. Dies ist nützlich, wenn Sie mehr als einen Befehl haben.(ls) | wc
wird Rohrls
zuwc
, offensichtlich können Sie schreibenls | wc
(ls ; date) | wc
wird das Ergebnis von beidenls
unddate
zu leitenwc
. Die Verwendungls ; date | wc
führt dazu, dass nurdate
an weitergeleitet wirdwc
.Auswechslung
$(command)
führt den Befehl aus und ersetzt ihn durch die Ausgabe. z.Bersetzt
$(date)
durchThu Jul 2 15:20:43 CEST 2015
, dannzusammenfügen
Sie können die beiden kombinieren.
$file
oder verwenden${file}
quelle
stdout
und sich stattdessen durch das Ergebnis des Ausdrucks ersetzen.