Różnica między „kotem” a „kotem”

Odpowiedzi:

106

W pierwszym przypadku catotwiera plik, aw drugim przypadku powłoka otwiera plik, przekazując go jako catstandardowe wejście.

Technicznie mogą mieć różne efekty. Na przykład możliwe byłoby posiadanie implementacji powłoki, która była bardziej (lub mniej) uprzywilejowana niż catprogram. W tym scenariuszu jeden może nie otworzyć pliku, a drugi może.

To nie jest zwykły scenariusz, ale wspomniano, aby wskazać, że powłoka i catnie są tym samym programem.

Thomas Dickey
źródło
83
Tak i na przykład możesz to zrobić sudo cat myfile.txt. Ale sudo cat < myfile.txtnie będzie działać, jeśli nie masz uprawnień do odczytu pliku.
zuazo
2
Zauważ, że ksh93ma catwbudowane (domyślnie wyłączone, chyba że masz na /opt/ast/binpoczątku $PATH).
Stéphane Chazelas
2
Niektóre programy zachowują się inaczej w zależności od tego, czy otrzymują argument nazwy pliku lub standardowe wejście. Na przykład wcwydrukuje nazwę pliku przed liczeniem, gdy otrzyma argument.
Barmar
21

Nie ma widocznej różnicy w twoim przypadku testowym. Najbardziej oczywistym z nich byłby komunikat o błędzie, który pojawia się, jeśli myfile.txtw bieżącym katalogu nie ma pliku o nazwie lub jeśli nie można go odczytać.

W pierwszym przypadku catbędzie narzekać, a w drugim przypadku twoja powłoka wyraźnie pokaże, który proces próbuje otworzyć plik, catw pierwszym i powłokę w drugim.

$ cat myfile.txt
cat: myfile.txt: No such file or directory
$ cat < myfile.txt
ksh93: myfile.txt: cannot open [No such file or directory]

W bardziej ogólnym przypadku zasadnicza różnica polega na tym, że przy użyciu przekierowań nie można drukować zawartości więcej niż jednego pliku, co jest przecież pierwotnym celem polecenia cat(tj. Cat enate). Zauważ, że powłoka i tak spróbuje otworzyć wszystkie pliki przekazane jako przekierowane dane wejściowe, ale faktycznie przekaże ostatni plik, catchyba że użyjesz zshi jego multios"zshism".

$ echo one > one
$ echo two > two
$ cat one two # cat opens one, shows one, opens two, shows two
one
two
$ cat < one < two # sh opens one then opens two, cat shows stdin (two)
two
$ rm one two
$ echo one > one
$ cat one two # cat opens and shows one, fails to open two
one
cat: two: No such file or directory
$ cat < one < two # the shell opens one then opens two, fails and 
                  # displays an error message, cat gets nothing on stdin
                  # so shows nothing
ksh93: two: cannot open [No such file or directory]

W standardowym systemie powłoka catnie ma żadnej różnicy w prawach dostępu do plików, więc oba zakończy się niepowodzeniem jednakowo. Użycie sudopodniesienia catuprawnień znacznie zmieni zachowanie, jak sugerował Thomas Dickey i dołączone komentarze.

jlliagre
źródło
5
Z ciekawości, czy naprawdę używasz kshwłasnej woli, a jeśli tak ... dlaczego ?
kot
1
@cat - to pytanie oczywiście opiera się na ignorancji. zbuduj sam i przekonaj się.
mikeserv
2
@mikeserv, który miał być nieprzyzwoity, nie na tyle niegrzeczny, ale dość sprawiedliwy, jak sądzę
cat
2
@cat - nie przypuszczałem, że jest inaczej. ignorancja nie jest czymś, czego należy się wstydzić - to tylko brak wiedzy. jeśli nie rozumiesz, dlaczego ktoś może użyć ksh93, to mogę tylko założyć, że nigdy go nie używałeś. więc polecam. warto spróbować. i uwierz mi, kiedy mówię ci, że w porównaniu do bash, ksh93jest zdecydowanie lepsze powłoki. to shell, prawie.
mikeserv
5
Jak zauważył @mikeserv w innym miejscu , cat < file1 > file2ma zupełnie inny efekt niż cat file1 > file2w przypadku, gdy file1jest nieczytelny lub nie istnieje. (Ta ostatnia forma zostaje obcięta file2; pierwsza nie.)
Wildcard
7

cat myfile.txtczyta plik, myfile.txta następnie drukuje go na standardowe wyjście.

cat < myfile.txttutaj catnie podano żadnych plików do otwarcia, tak jak wiele poleceń Uniksa odczytuje dane ze standardowego wejścia, które jest tam kierowane file.txtprzez powłokę, i wypisuje na standardowe wyjście.

Hamza Abbad
źródło
6

Odpowiedź Thomasa Dickeya jest genialna.

Chcę tylko dodać kilka oczywistych faktów na temat czytania kilku plików (luźno związanych z twoim pytaniem, ale nadal):

  • cat <file1 <file2 <file3odczyta tylko plik3, przynajmniej w bash. (Faktycznie, to zależy od powłoki, ale większość powłok będzie dup każdy podany plik do standardowego wejścia, co powoduje ostatni do skutku).
  • cat file1 file2 file3odczyta kolejno wszystkie określone pliki (w rzeczywistości cat jest skróconą formą słowa concatenate ).
  • cat file1 file2 file3 <file4 <file5 <file6 odczyta tylko plik 1, plik 2, plik 3 (ponieważ cat ignoruje stdin po przekazaniu argumentów nazwy pliku).
    • cat file1 file2 - file3 <file4 <file5 <file6 odczyta plik 1, plik 2, plik 6, plik 3 (ponieważ łącznik zmusza kota, aby nie ignorował standardowego wejścia).

I o błędach. W przypadku niemożności otwarcia niektórych plików określonych jako argumenty (bez <), cat pominie pliki nieudane (z wysłaniem odpowiedniego komunikatu do stderr), ale nadal będzie czytał inne pliki. W przypadku niemożności otwarcia co najmniej jednego z plików określonych jako przekierowania (with <), shell nawet nie uruchomi cat (dzieje się tak nawet w przypadku przekierowań faktycznie nieużywanych przez cat). W obu przypadkach zostanie zwrócony błędny kod wyjścia.

Sasha
źródło
1
Należy zauważyć, że w pierwszym przykładzie catbędą jednak otwarte file1i file2, samo file4i file5w trzecim przykładzie. Pokaże tylko file3, odpowiednio. file6zawartość, jeśli poprzednie otwarte instrukcje się powiodą.
jlliagre
@jlliagre, dzięki, nie wiedziałem tego. Strace oczywiście udowodnił twoją poprawność. Poprawiłem tekst w nawiasach dla przypadków 1 i 3a.
sasha
0

możemy użyć innego polecenia, aby zauważyć różnicę między:

wc –w food2.txt .

Możliwe wyjście:

6 food2.txt .

polecenie podaje nazwę pliku, ponieważ go zna (przekazany jako argument).

wc –w < food2.txt .

Możliwe wyjście:

6 .

standardowe wejście jest przekierowywane do pliku food2.txt bez polecenia o tym polecenia.

użytkownik307770
źródło