
Ich kämpfe schon seit einiger Zeit mit diesem Problem und wäre sehr dankbar, wenn mir jemand Klarheit verschaffen könnte. Angenommen, ich versuche, die beiden Befehle über eine Pipe zusammenzuführen. readlink
undcat
readlink Command output
$ readlink -f SUService.log
/cygdrive/c/SUService.log
Wenn ich jetzt so etwas versuche (es schlägt fehl)
$ readlink -f SUService.log | cat
Während so etwas funktionieren wird
$ readlink -f SUService.log | xargs cat
Ich wollte wissen, warum das so ist. Ich habe gelesenDasBeitrag hier, in dem der OP eine ähnliche Frage hatte undDasBeitrag, der versucht, den Unterschied zwischen einem Argument und einer Eingabe zu erklären, aber ich konnte die akzeptierten Antworten immer noch nicht verstehen. So wie ich es verstehe, wird readlink
das Ergebnis an stdout zurückgegeben, also den Terminalbildschirm, während cat
eine Eingabe als Argument gewünscht wird. Dies wiederum veranlasst mich zu der Frage, woher ich weiß, ob die Ausgabe eines Befehls (wie „locate“ oder „readlink“) als Argument für den nächsten Befehl verwendet werden kann oder nicht. Ich habe mehr gelesen und es stellt sich heraus, dass ich gerne wissen würde, wann ich den Befehl „xarg“ verwenden sollte.
Antwort1
Ihr Beispiel ist ziemlich verwirrend.
Normalerweise schickt man nicht einfach irgendwelche Charaktere an cat.
Normalerweise senden Sie eine Datei an cat.
Wenn Sie dennoch einige Zeichen an cat senden, werden diese ausgedruckt.
$ echo abc12123 | cat
abc12123
Normalerweise schickt man einen Dateinamen an cat
$ cat abc12123
cat: abc12123: No such file or directory
Beachten Sie also, dass die Katze selbst anders mit lustigen Zeichen umgeht, die ihr übermittelt werden, als wenn sie ihr als Parameter übergeben werden.
$ cat b.b
textofb.b
$ echo b.b | cat
b.b
$ cat b.b
textofb.b
ich werde ein einfacheres Beispiel als Ihres verwenden
$ echo b.b | xargs cat
textofb.b
Sehen Sie, es druckt den Inhalt von bb asdfasdfs | xargs cat
, weil die Ausgabe von asdfasdfs als Parameter an cat gesendet wird.
Also
echo b.b | xargs cat
=
cat b.b
Wobei echo b.b | cat
ist nicht dasselbe wiecat b.b
Antwort2
Der folgende Befehlnichtfehlschlagen. Es passiert einfach etwas, was Sie nicht erwartet haben:
readlink -f SUService.log | cat
Wenn cat
stdin angegeben wird, wird es nach stdout kopiert. Es wird dort nicht nach Dateinamen gesucht.
Alternativ wird dies aus der benannten Datei gelesen:
cat "$(readlink -f SUService.log)"
xargs
gibt den Namen auch in die cat
Befehlszeile ein und führt zum selben Ergebnis:
readlink -f SUService.log | xargs cat
Antwort3
Sehen Sie sich die Manpages für cat und xargs an, um zu erfahren, was sie tun.
man cat
cat - concatenate files and print on the standard output
Und:
man xargs
xargs - build and execute command lines from standard input
Hier ist eine kleine Demo
Lassen Sie uns eine Testdatei erstellen:
echo "a" > test
echo "b" >> test
echo "c" >> test
Katze
cat test
Liest die Datei und gibt aus:
a
b
c
Echo | Katze
echo test | cat
Laut man cat
hat dies die gleiche Wirkung wie:
echo test | cat -
Dadurch wird eine Weiterleitung test
an die Standardeingabe von cat durchgeführt und cat angewiesen, von der Standardeingabe zu lesen.
Echo | Xargs Katze
echo test | xargs cat
Generiert und führt den folgenden Befehl aus:
cat test
Die Ausgabe hiervon haben wir bereits gezeigt.
Wenn wir rennen
<test xargs -n1 cat
Xargs sieht dies bei der Eingabe:
a
b
c
Und es generiert die folgenden Befehle:
cat a
cat b
cat c
Dies sollte zu drei Fehlern führen, da diese Dateien nicht vorhanden sind.
Warum zum -n1
?
Laut weist xargs an man xargs
, -n1
in jedem generierten Befehl ein Argument (gelesen von stdin) zu verwenden.
Wenn wir -n2
stattdessen verwenden, generieren wir Folgendes, das bis zu zwei Parameter pro Befehl verwendet:
cat a b
cat c
Und wenn wir -n3
oder höher verwenden oder einfach das weglassen -n
:
< test xargs cat
Wir bekommen:
cat a b c