Pracowałem przez samouczek i zobaczyłem użycie obu cat myfile.txti cat < myfile.txt. Czy istnieje różnica między tymi dwiema sekwencjami poleceń? Wydaje się, że oba drukują zawartość pliku do powłoki.
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.
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.
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.
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).
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.
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.
Odpowiedzi:
W pierwszym przypadku
cat
otwiera plik, aw drugim przypadku powłoka otwiera plik, przekazując go jakocat
standardowe 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ż
cat
program. 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
cat
nie są tym samym programem.źródło
sudo cat myfile.txt
. Alesudo cat < myfile.txt
nie będzie działać, jeśli nie masz uprawnień do odczytu pliku.ksh93
macat
wbudowane (domyślnie wyłączone, chyba że masz na/opt/ast/bin
początku$PATH
).wc
wydrukuje nazwę pliku przed liczeniem, gdy otrzyma argument.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.txt
w bieżącym katalogu nie ma pliku o nazwie lub jeśli nie można go odczytać.W pierwszym przypadku
cat
będzie narzekać, a w drugim przypadku twoja powłoka wyraźnie pokaże, który proces próbuje otworzyć plik,cat
w pierwszym i powłokę w drugim.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,cat
chyba że użyjeszzsh
i jegomultios
"zshism".W standardowym systemie powłoka
cat
nie ma żadnej różnicy w prawach dostępu do plików, więc oba zakończy się niepowodzeniem jednakowo. Użyciesudo
podniesieniacat
uprawnień znacznie zmieni zachowanie, jak sugerował Thomas Dickey i dołączone komentarze.źródło
ksh
własnej woli, a jeśli tak ... dlaczego ?bash
,ksh93
jest zdecydowanie lepsze powłoki. to shell, prawie.cat < file1 > file2
ma zupełnie inny efekt niżcat file1 > file2
w przypadku, gdyfile1
jest nieczytelny lub nie istnieje. (Ta ostatnia forma zostaje obciętafile2
; pierwsza nie.)cat myfile.txt
czyta plik,myfile.txt
a następnie drukuje go na standardowe wyjście.cat < myfile.txt
tutajcat
nie podano żadnych plików do otwarcia, tak jak wiele poleceń Uniksa odczytuje dane ze standardowego wejścia, które jest tam kierowanefile.txt
przez powłokę, i wypisuje na standardowe wyjście.źródło
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 <file3
odczyta 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 file3
odczyta 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.źródło
cat
będą jednak otwartefile1
ifile2
, samofile4
ifile5
w trzecim przykładzie. Pokaże tylkofile3
, odpowiednio.file6
zawartość, jeśli poprzednie otwarte instrukcje się powiodą.możemy użyć innego polecenia, aby zauważyć różnicę między:
Możliwe wyjście:
polecenie podaje nazwę pliku, ponieważ go zna (przekazany jako argument).
Możliwe wyjście:
standardowe wejście jest przekierowywane do pliku food2.txt bez polecenia o tym polecenia.
źródło