Warum funktioniert das Minuszeichen nicht als Ersatz für cat in bash?

17

Ich habe von "unnützem Gebrauch von Katze" gehört und einige Vorschläge gefunden, aber die folgenden Ausgaben enthalten nichts in meiner Bash-Shell.

< filename

Die Verwendung von cat funktioniert jedoch wie erwartet.

cat filename

Ich verwende Fedora Core 18 und GNU Bash, Version 4.2.45 (1).

BEARBEITEN: Die Verwendung vor einer Pipe funktioniert auch nicht.

< filename | grep pattern

Während mit Katze funktioniert wie erwartet.

cat filename | grep pattern

EDIT2: Zur Verdeutlichung weiß ich, dass ich das nutzen kann

grep pattern < filename

aber ich lese hier /programming/11710552/useless-use-of-cat, dass ich es auch vor dem befehl benutzen kann. Es funktioniert jedoch nicht vor dem Befehl.

Fehler
quelle
2
Es klappt. Was Sie versucht haben, ist nicht dasselbe, wie Jonathan Lefflers Kommentar nahe legt.
Handarbeit
"Der Zweck von cat ist das Verketten (oder" Verketten ") von Dateien. Wenn es sich nur um eine Datei handelt, ist das Verketten mit nichts Zeitverschwendung und kostet Sie einen Prozess." partmaps.org/era/unix/award.html
Bonsi Scott

Antworten:

22

Das Symbol kleiner als und ( <) öffnet die Datei und hängt sie an das Standard-Eingabegerät-Handle einer Anwendung / eines Programms an. Sie haben der Shell jedoch keine Anwendung zum Anhängen der Eingabe gegeben.

Beispiel

Diese beiden Beispiele tun im Wesentlichen das Gleiche, aber sie werden auf zwei leicht unterschiedliche Arten eingegeben.

öffnet die Datei

$ cat blah.txt 
hi

öffnet STDIN

$ cat < blah.txt 
hi

Hinter den Vorhang spähen

Sie können verwenden, um stracezu sehen, was los ist.

Wenn wir aus einer Datei lesen

open("blah.txt", O_RDONLY)              = 3
fstat(3, {st_mode=S_IFREG|0664, st_size=3, ...}) = 0
fadvise64(3, 0, 0, POSIX_FADV_SEQUENTIAL) = 0
read(3, "hi\n", 65536)                  = 3
write(1, "hi\n", 3hi
)                     = 3
read(3, "", 65536)                      = 0
close(3)                                = 0
close(1)                                = 0

Wenn wir aus STDIN lesen (identifiziert als 0)

read(0, "hi\n", 65536)                  = 3
write(1, "hi\n", 3hi
)                     = 3
read(0, "", 65536)                      = 0
close(0)                                = 0
close(1)                                = 0

Im ersten Beispiel können wir sehen, dass catdie Datei geöffnet und daraus gelesen wurde blah.txt. In der Sekunde können wir sehen, dass catder Inhalt der Datei blah.txtüber den STDIN-Dateideskriptor gelesen wird, der als Deskriptornummer 0 identifiziert wird.

read(0, "hi\n", 65536)                  = 3
slm
quelle
1
Also ist dieses Gerede über nutzlosen Katzenkonsum Schwindel?
Fehler
@ Bug - Nein, es gibt Verwendungen. Wird cataber allgemein missverstanden und verwendet, wenn es nicht notwendig ist.
slm
Aber ist es notwendig, wenn ich die Reihenfolge der Operationen von links nach rechts beibehalten möchte? Ich habe gelesen, dass es auch möglich ist, das less-than-Konstrukt vor dem Befehl zu verwenden.
Fehler
@bug ja die Weiterleitung kann vor oder nach dem Befehl erfolgen, siehe Stephanes Antwort, er zeigt auch dieses Beispiel.
slm
Ah, jetzt verstehe ich es. Ich würde schreiben müssen < filename command.
Fehler
14

Die klassische nutzlose Verwendung von catist die Eingabe in Programme, die perfekt in der Lage sind, Dateien direkt zu öffnen. Beispielsweise:

Schlecht

cat file | grep foo
cat file | while read line; do echo "$line"; done
cat file | sed 's/a/b/'
cat file | awk '{print $1}'

Gut

grep foo file
while read line; do echo "$line"; done < file 
sed 's/a/b/' file
awk '{print $1}' file

Auch gut (die <filekann auf beiden Seiten des Befehls sein)

<file grep foo
 sed 's/a/b/' < file
<file awk '{print $1}' 
terdon
quelle
6
"Schlecht" ist hier subjektiv. Ich finde , diejenigen insgesamt besser zu sein, denn es ist Weg konsequentes und leichter zu lesen. Und der Datenfluss ist vollständig von links nach rechts, wie es sein sollte, wenn mehr Pipes beteiligt sind
Izkata
2
@ Izkata sie sind "schlecht" in dem Sinne, dass sie nutzlos verwendet werden cat.
terdon
"Nieder! Geh runter vom Tisch! Du bist eine böse Katze! ”;-) Aber im Ernst…
G-Man sagt 'Reinstate Monica'
1
Bemerkenswert gut (oder zumindest nützlich) Verwendungen catumfassen (1) cat file(mit Ausgabe auf den Bildschirm / Terminal, obwohl, wenn die Datei länger ist als der Bildschirm hoch ist, Sie könnten es vorziehen , zu verwenden , moreoder lessoder so ähnlich), (2) cat file1 file2 file3 > all_data( genau das , wofür cates gedacht ist), (3) cat f1 f2 f3 | tr …(oder leiten Sie es an ein anderes Programm weiter, an das Sie die Dateien nicht direkt übergeben möchten, z. B. wc(z. B. wenn Sie nur die Gesamtsumme anzeigen möchten) oder grep(zB, wenn Sie eine alte Version haben, die das nicht unterstützt -h, --no-filenamezB)),… (Fortsetzung)
G-Man sagt, 'Monica wieder
(Fortsetzung)… (4) cat -n file | sort … -k1 | sed 's/^ *[0-9]*\t//', (5) sudo cat file600 | untrusted_program(dh Sie (Ihre UID) können die Datei nicht lesen, und Sie möchten das Programm nicht als root oder als halbprivilegierte UID ausführen). Auch ( e ) (dh eine Zahl zwischen 2 und 3) program_that_generates_html | cat static_html_header - static_html_footer(die Sie wahrscheinlich zu einer Datei oder einer Pipe umleiten möchten).
G-Man sagt, dass Monica
13

Das UUOC ist in:

cat somefile | some-cmd

oder

cat < somefile | some-cmd

Dort some-cmdwird der Inhalt somefilevon einer Pipe catgelesen, von der aus er selbst gelesen wird somefile.

some-cmdkann direkt von lesen somefile(nachdem die Shell es für stdin geöffnet hat), gibt es keine Notwendigkeit für cat:

some-cmd < somefile

oder

< somefile some-cmd

(Umleitungen können überall in einer einfachen Befehlszeile erscheinen).

Stéphane Chazelas
quelle