Ich frage mich, wann wir Pipeline verwenden sollten und wann nicht.
Sagen wir zum Beispiel, um einen bestimmten Prozess abzubrechen, der mit PDF-Dateien umgeht, funktioniert Folgendes nicht mit Pipeline:
ps aux | grep pdf | awk '{print $2}'|kill
Stattdessen können wir es nur auf folgende Arten tun:
kill $(ps aux| grep pdf| awk '{print $2}')
oder
ps aux | grep pdf | awk '{print $2}'| xargs kill
Laut man bash
(version 4.1.2
):
The standard output of command is connected via a pipe to the standard input of command2.
Für obiges Szenario:
- der stdin von
grep
ist der stdout vonps
. Das funktioniert. - der stdin von
awk
ist der stdout vongrep
. Das funktioniert. - der stdin von
kill
ist der stdout vonawk
. Das geht nicht
Das stdin des folgenden Befehls wird immer vom stdout des vorherigen Befehls eingegeben.
- Warum funktioniert es nicht mit
kill
oderrm
? - Was ist der Unterschied zwischen
kill
,rm
Eingabe mitgrep
,awk
Eingabe? - Gibt es irgendwelche Regeln?
pgrep
,pkill
undkillall
Befehle.pgrep
und der Rest kann dies perfekt erreichen :)Antworten:
Es gibt zwei übliche Möglichkeiten, um Eingaben für Programme bereitzustellen:
kill
Verwendet nur Befehlszeilenargumente. Es wird nicht aus STDIN gelesen. Programme mögengrep
undawk
lesen von STDIN (wenn keine Dateinamen als Befehlszeilenargumente angegeben sind) und verarbeiten die Daten gemäß ihren Befehlszeilenargumenten (Muster, Anweisungen, Flags, ...).Sie können nur zu STDIN anderer Prozesse leiten, nicht zu Befehlszeilenargumenten.
Die allgemeine Regel ist, dass Programme STDIN verwenden, um eine beliebige Datenmenge zu verarbeiten. Alle zusätzlichen Eingabeparameter oder, wenn es normalerweise nur wenige gibt, werden von Befehlszeilenargumenten übergeben. Wenn die Kommandozeile sehr lang werden kann, zB bei langen
awk
Programmtexten, besteht häufig die Möglichkeit, diese aus zusätzlichen Programmdateien zu lesen (-f
Option vonawk
).Verwenden Sie
$(...)
oder bei vielen Daten, um das STDOUT von Programmen als Befehlszeilenargumente zu verwendenxargs
.find
kann auch das direkt mit-exec ... {} +
.Der Vollständigkeit halber: Um Befehlszeilenargumente in STDOUT zu schreiben, verwenden Sie
echo
.quelle
gzip
in der ÜBERSICHT nicht angegeben, dass ein DATEINAME als Eingabe verwendet werden muss. Ich schaue, gibt es einen systematischeren Weg, um das festzustellen.xargs
genau, "Argumente an Befehlszeile weiterzuleiten"?xargs
. Es ruft den Befehl bei Bedarf mehrmals auf (die Befehlszeilengröße ist begrenzt) und hat viele andere Optionen.Dies ist eine interessante Frage, die sich mit einem Teil der Unix / Linux-Philosophie befasst.
Also, was ist der Unterschied zwischen Programmen wie
grep
,sed
,sort
auf der einen Seite undkill
,rm
,ls
auf der anderen Seite? Ich sehe zwei Aspekte.Der Filter Aspekt
Die erste Art von Programmen nennt man auch Filter . Sie nehmen eine Eingabe, entweder aus einer Datei oder aus STDIN, ändern diese und generieren eine Ausgabe, meist nach STDOUT. Sie sollen in einer Pipe mit anderen Programmen als Quellen und Ziele verwendet werden.
Die zweite Art von Programmen wirkt auf eine Eingabe, aber die Ausgabe, die sie geben, hängt oft nicht mit der Eingabe zusammen.
kill
hat keine Ausgabe, wenn es regelmäßig funktioniert, auch nichtls
. Sie haben nur einen Rückgabewert, um Erfolg zu zeigen. Sie nehmen normalerweise keine Eingabe von STDIN entgegen, geben aber meistens eine Ausgabe an STDOUT aus.Bei Programmen wie diesem
ls
funktioniert der Filteraspekt nicht so gut. Es kann durchaus einen Eingang haben (benötigt aber keinen), und der Ausgang ist eng mit diesem verbunden, funktioniert aber nicht als Filter. Für diese Art von Programmen funktioniert jedoch noch der andere Aspekt:Der semantische Aspekt
Für Filter hat ihre Eingabe keine semantische Bedeutung . Sie lesen nur Daten, ändern Daten, geben Daten aus. Es spielt keine Rolle, ob es sich um eine Liste mit numerischen Werten, Dateinamen oder HTML-Quellcode handelt. Die Bedeutung dieser Daten ergibt sich nur aus dem Code, den Sie dem Filter geben: der Regex für
grep
, die Regeln fürawk
oder das Perl-Programm.Für andere Programme wie
kill
oderls
hat ihre Eingabe eine Bedeutung , eine Bezeichnung .kill
erwartet Prozessnummern,ls
erwartet Datei- oder Pfadnamen. Sie können nicht mit beliebigen Daten umgehen und sind auch nicht dazu gedacht. Viele von ihnen benötigen nicht einmal Eingaben oder Parameter wieps
. Sie lesen normalerweise nicht aus STDIN.Man könnte diese beiden Aspekte wahrscheinlich kombinieren: Ein Filter ist ein Programm, dessen Eingabe keine semantische Bedeutung für das Programm hat.
Ich bin mir sicher, dass ich irgendwo etwas über diese Philosophie gelesen habe, aber ich kann mich im Moment an keine Quellen erinnern, sorry. Wenn jemand Quellen hat, können Sie diese gerne bearbeiten.
quelle
Es gibt keine "Regeln" als solche. Einige Programme nehmen Eingaben von STDIN entgegen, andere nicht. Wenn ein Programm Eingaben von STDIN entgegennehmen kann, kann es weitergeleitet werden, wenn nicht, kann es nicht.
Normalerweise können Sie feststellen, ob ein Programm Eingaben akzeptiert oder nicht, indem Sie darüber nachdenken, was es tut. Wenn die Aufgabe des Programms ist es , irgendwie die zu manipulieren Inhalt einer Datei (zB
grep
,sed
,awk
etc.), dauert es normalerweise eine Eingabe von STDIN. Wenn seine Aufgabe ist es, die Datei selbst (zB zu manipulierenmv
,rm
,cp
) oder ein Verfahren (zBkill
,lsof
) oder Rückkehr Informationen über etwas (zBtop
,find
,ps
) , dann tut es nicht.Eine andere Art, darüber nachzudenken, ist der Unterschied zwischen Argumenten und Eingaben. Beispielsweise:
Hat im obigen Befehl
mv
keine Eingabe als solche. Was gegeben wurde, sind zwei Argumente. Es weiß oder kümmert sich nicht darum, was sich in einer der Dateien befindet, es weiß nur, dass dies die Argumente sind, und es sollte sie manipulieren.Auf der anderen Seite
Hier wurde
sed
Input sowie ein Argument gegeben. Da es Eingaben akzeptiert, kann es diese von STDIN lesen und weitergeleitet werden.Es wird noch komplizierter , wenn ein Argument sein , der Eingang. Beispielsweise
Hier
file
ist das Argument, das gegeben wurdecat
. Um genau zu sein, der Dateinamefile
ist das Argument. Da es sich jedochcat
um ein Programm handelt, das den Inhalt von Dateien manipuliert, erfolgt die Eingabe nach dem Inhaltfile
.Dies kann mit
strace
einem Programm veranschaulicht werden , das die von Prozessen ausgeführten Systemaufrufe nachverfolgt. Wenn wircat foo
via ausführenstrace
, können wir sehen, dass die Dateifoo
geöffnet ist:Die erste Zeile oben zeigt, dass das Programm
/bin/cat
aufgerufen wurde und seine Argumentecat
und warenfoo
(das erste Argument ist immer das Programm selbst). Später wurde das Argumentfoo
im schreibgeschützten Modus geöffnet. Vergleichen Sie dies nun mitAuch hier
ls
nahm sich undfoo
als Argumente. Es gibt jedoch keinenopen
Aufruf, das Argument wird nicht als Eingabe behandelt. Ruft stattdessenls
die Systembibliothek aufstat
(die nicht mit demstat
Befehl identisch ist ), um Informationen über die Datei abzurufenfoo
.Zusammenfassend kann gesagt werden, dass Sie, wenn der von Ihnen ausgeführte Befehl seine Eingabe liest, eine Pipe zu ihm ausführen können. Wenn dies nicht der Fall ist, können Sie dies nicht.
quelle
kill
undrm
brauche kein STDIN.Für
kill
und gebenrm
Benutzer ihre benutzerdefinierten Informationen als Argument an und$(cmd)
helfen dabei, das STDOUT descmd
info-Arguments zu nehmen und es zu konvertieren.Für
grep
und gebenawk
Benutzer Argumente und zusätzlich auchSTDIN
eine reguläre Datei an, die vom Befehl verarbeitet wird.STDIN
Kann mit Pipeline|
oder durch manuelle Eingabe übergeben werden.Lesen Sie das Handbuch oder die Quellcodes. Und wenn Sie nichts finden, was Sie brauchen, können Sie einen einfachen, aber möglicherweise gefährlichen Test durchführen:
Geben Sie einfach den Befehl ein, auf den Sie neugierig sind, mit Argumenten, die Sie bereits verstanden haben, und prüfen Sie, ob der Befehl pausiert (es passiert nichts). Wenn es anhält, wartet es tatsächlich für STDIN (können Sie versuchen ,
cat
undecho
die verschiedenen zu sehen). Sie geben manuell einCtrl-D
und der Befehl wird ausgeführt (Ergebnisse oder Fehler anzeigen) und kehrt zurück. Ein solcher Befehl benötigt in dieser Situation STDIN (mit Argumenten, die Sie angeben).Der gleiche Befehl benötigt in verschiedenen Situationen möglicherweise nicht STDIN (z. B.
cat
wartet auf STDIN, abercat file.txt
nicht).quelle