Різниця між "котом" і "котом <"


70

Я працював підручником і бачив використання обох cat myfile.txtта cat < myfile.txt. Чи є різниця між цими двома послідовностями команд? Здається, обидва надрукують вміст файлу в оболонку.


Відповіді:


106

У першому випадку catвідкривається файл, а в другому випадку оболонка відкриває файл, передаючи його як catстандартний вхід.

Технічно вони можуть мати різний вплив. Наприклад, можлива реалізація оболонки, більш привілейована, ніж catпрограма. Для цього сценарію один може не вдатися відкрити файл, а інший -.

Це не звичайний сценарій, але згадується, щоб вказати, що оболонка і catце не та сама програма.


83
Так, і, наприклад, ви можете це зробити sudo cat myfile.txt. Але sudo cat < myfile.txtне вийде, якщо у вас немає привілеїв для читання файлу.
zuazo

2
Зверніть увагу , що ksh93має catвбудовані (не включена за замовчуванням , якщо ви не маєте /opt/ast/binна початку вашого , $PATHхоча).
Стефан Шазелас

2
Деякі програми поводяться по-різному залежно від того, отримують вони аргумент імені файлу чи stdin. Наприклад, wcбуде надруковано ім'я файлу до відліку, коли йому буде надано аргумент.
Barmar

21

У вашому тестовому випадку не спостерігається жодної істотної різниці. Найбільш очевидним з них буде повідомлення про помилку, яке ви отримаєте, якщо myfile.txtу поточному каталозі немає імені , або якщо ви не можете його читати.

У першому випадку catбуде скаржитися, а в другому - ваша оболонка, чітко показуючи, який процес намагається відкрити файл, catв першому та оболонку в другому.

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

У більш загальному випадку основна різниця полягає у використанні перенаправлень, які не можуть використовуватися для друку вмісту більш ніж одного файлу, що, зрештою, є початковою метою команди cat(тобто cat enate). Зауважте, що оболонка все одно намагатиметься відкрити всі файли, передані як перенаправлений вхід, але лише фактично передасть останній, catякщо ви не використовуєте zshта його multios"зшизм".

$ 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]

У стандартній системі оболонка і catне мають різниці у правах доступу до файлів, тому обидва будуть успішно виходити з ладу однаково. Використання sudoдля підвищення catпривілеїв призведе до великої різниці в поведінці, як відповів Томас Дікі і додав коментарі, які вже пропонували.


5
Чи з цікавості ви справді використовуєте kshвласну волю, і якщо так ... чому ?
кіт

1
@cat - це питання, очевидно, засноване на незнанні. побудуй це сам і побачи.
mikeserv

2
@mikeserv, який мав бути легковажним, не серйозно грубим, але досить справедливим, я вважаю
кіт

2
@cat - я не припускаю, що інакше. невігластво - це річ, якої не соромно - це лише брак знань. якщо ви не розумієте, чому хтось може вибрати ksh93, то я можу лише припустити, що це тому, що ви його ніколи не використовували. тому я рекомендую вам зробити. варто спробувати, щоб бути впевненим. і повірте мені, коли я вам скажу, що в порівнянні з bash, ksh93це набагато краща оболонка. це оболонка, майже.
mikeserv

5
Як вказував @mikeserv в інших місцях , він cat < file1 > file2має дуже різний ефект від cat file1 > file2випадку, коли він file1не читається або його немає. (Останні утворюють усічки file2; перші не будуть.)
Wildcard

7

cat myfile.txtчитає файл, myfile.txtпісля чого виводить його на стандартний вихід.

cat < myfile.txtтут catне дається жодних файлів, що відкриваються, так -подібно багато команд Unix записує дані зі стандартного вводу, який направляється туди file.txtоболонкою, і друкує на стандартний вихід.


6

Відповідь Томаса Дікі - геніальна.

Я просто хочу додати кілька очевидних фактів щодо випадку читання декількох файлів (слабко пов’язаних із вашим запитанням, але все ж):

  • cat <file1 <file2 <file3буде читати тільки файл3, принаймні в bash. (Насправді це залежить від оболонки, але більшість оболонок копіюватиме кожен вказаний файл у stdin, що спричиняє дію останнього.)
  • cat file1 file2 file3буде читати всі вказані файли послідовно (насправді кішка - це скорочена форма слова concatenate ).
  • cat file1 file2 file3 <file4 <file5 <file6 буде читати тільки file1, file2, file3 (оскільки кіт ігнорує stdin при передачі аргументів імені файлу).
    • cat file1 file2 - file3 <file4 <file5 <file6 прочитає file1, file2, file6, file3 (як дефіс змушує кішку не ігнорувати stdin).

А про помилки. У разі неможливості відкрити деякі файли, вказані як аргументи (без <), кішка буде пропускати файли, що не відбулися (з виведенням відповідного повідомлення на stderr), але все ж читатиме інші файли. У разі неможливості відкрити принаймні один із файлів, вказаних як перенаправлення (з <), оболонка навіть не запустить кота (це відбувається навіть для перенаправлень, фактично не використовуваних котом). В обох випадках повертається помилковий код виходу.


1
Зауважте, що в першому прикладі catвсе-таки відкриється file1і file2, як file4і file5у вашому третьому прикладі. Це лише покаже file3, респ. file6вміст, якщо ці попередні відкриті інструкції досягли успіху.
jlliagre

@jlliagre, дякую, я цього не знав. Страйс явно довів свою правоту. Я виправив текст у дужках для випадків 1 та 3a.
саша

0

ми можемо використовувати іншу команду, щоб помітити різницю між:

wc –w food2.txt .

Можливий вихід:

6 food2.txt .

команда повідомляє ім'я файлу, оскільки він його знає (передається як аргумент).

wc –w < food2.txt .

Можливий вихід:

6 .

стандартний вхід переспрямовується на файл food2.txt, не знаючи про це команди.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.