Я працював підручником і бачив використання обох cat myfile.txt
та cat < myfile.txt
. Чи є різниця між цими двома послідовностями команд? Здається, обидва надрукують вміст файлу в оболонку.
Я працював підручником і бачив використання обох cat myfile.txt
та cat < myfile.txt
. Чи є різниця між цими двома послідовностями команд? Здається, обидва надрукують вміст файлу в оболонку.
Відповіді:
У першому випадку cat
відкривається файл, а в другому випадку оболонка відкриває файл, передаючи його як cat
стандартний вхід.
Технічно вони можуть мати різний вплив. Наприклад, можлива реалізація оболонки, більш привілейована, ніж cat
програма. Для цього сценарію один може не вдатися відкрити файл, а інший -.
Це не звичайний сценарій, але згадується, щоб вказати, що оболонка і cat
це не та сама програма.
sudo cat myfile.txt
. Але sudo cat < myfile.txt
не вийде, якщо у вас немає привілеїв для читання файлу.
ksh93
має cat
вбудовані (не включена за замовчуванням , якщо ви не маєте /opt/ast/bin
на початку вашого , $PATH
хоча).
wc
буде надруковано ім'я файлу до відліку, коли йому буде надано аргумент.
У вашому тестовому випадку не спостерігається жодної істотної різниці. Найбільш очевидним з них буде повідомлення про помилку, яке ви отримаєте, якщо 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
привілеїв призведе до великої різниці в поведінці, як відповів Томас Дікі і додав коментарі, які вже пропонували.
ksh
власну волю, і якщо так ... чому ?
bash
, ksh93
це набагато краща оболонка. це оболонка, майже.
cat < file1 > file2
має дуже різний ефект від cat file1 > file2
випадку, коли він file1
не читається або його немає. (Останні утворюють усічки file2
; перші не будуть.)
cat myfile.txt
читає файл, myfile.txt
після чого виводить його на стандартний вихід.
cat < myfile.txt
тут cat
не дається жодних файлів, що відкриваються, так -подібно багато команд Unix записує дані зі стандартного вводу, який направляється туди file.txt
оболонкою, і друкує на стандартний вихід.
Відповідь Томаса Дікі - геніальна.
Я просто хочу додати кілька очевидних фактів щодо випадку читання декількох файлів (слабко пов’язаних із вашим запитанням, але все ж):
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), але все ж читатиме інші файли. У разі неможливості відкрити принаймні один із файлів, вказаних як перенаправлення (з <
), оболонка навіть не запустить кота (це відбувається навіть для перенаправлень, фактично не використовуваних котом). В обох випадках повертається помилковий код виходу.
cat
все-таки відкриється file1
і file2
, як file4
і file5
у вашому третьому прикладі. Це лише покаже file3
, респ. file6
вміст, якщо ці попередні відкриті інструкції досягли успіху.
ми можемо використовувати іншу команду, щоб помітити різницю між:
wc –w food2.txt
.
Можливий вихід:
6 food2.txt
.
команда повідомляє ім'я файлу, оскільки він його знає (передається як аргумент).
wc –w < food2.txt
.
Можливий вихід:
6
.
стандартний вхід переспрямовується на файл food2.txt, не знаючи про це команди.