Angenommen, ich möchte alle Dateien in einem Verzeichnis mit Ausnahme der Datei "notes.txt" entfernen. Ich würde das mit der Pipeline machen ls | grep -v "notes.txt" | xargs rm
. Warum brauche ich xargs, wenn der Ausgang der zweiten Pipe der Eingang ist, den rm verwenden soll?
Zu Vergleichszwecken echo "#include <knowledge.h>" | cat > foo.c
fügt die Pipeline den wiedergegebenen Text ohne die Verwendung von xargs in die Datei ein. Was ist der Unterschied zwischen diesen beiden Pipelines?
ls | grep -v "notes.txt" | xargs rm
, um alles zu entfernen, es sei dennnotes.txt
, Sie analysieren niemals diels
Ausgabe . Ihr Befehl würde abbrechen, wenn eine einzelne Datei beispielsweise ein Leerzeichen enthält. Der sicherere Weg wärerm !(notes.txt)
in Bash (mitshopt -s extglob
Satz) oderrm ^notes.txt
in Zsh (mitEXTENDED_GLOB
) usw.find . -maxdepth 1 -mindepth 1 -print0 | xargs -0
stattdessenls | xargs
Antworten:
Sie verwechseln zwei sehr unterschiedliche Arten von Eingaben: STDIN und Argumente. Argumente sind eine Liste von Zeichenfolgen, die dem Befehl beim Start bereitgestellt werden, in der Regel durch Angabe nach dem Befehlsnamen (z . B.
echo these are some arguments
oderrm file1 file2
). STDIN hingegen ist ein Strom von Bytes (manchmal Text, manchmal nicht), den der Befehl (optional) nach dem Start lesen kann. Hier sind einige Beispiele (Anmerkung,cat
die entweder Argumente oder STDIN annehmen kann, aber verschiedene Dinge damit macht):xargs
Man kann sich vorstellen, wie man eine Eingabe im STDIN-Stil in Argumente umwandelt:echo
Tatsächlich macht es mehr oder weniger das Gegenteil: Es konvertiert seine Argumente in STDOUT (das an die STDIN eines anderen Befehls weitergeleitet werden kann):quelle
cat
nimmt Eingaben vonSTDIN
undrm
nicht. Für solche Befehle müssen Sie zeilenweisexargs
iterierenSTDIN
und die Befehle mit Befehlszeilenparametern ausführen.quelle