Как работает перенаправление ввода?

5

Да, я уже пробовал искать его в другом месте, но примеры, которые должны иллюстрировать перенаправление ввода, например здесь , например, всегда есть одна путающая оговорка. На примере только что опубликованного сайта они говорят:

  # echo 'hello world' >output
  # cat <output
  

Первая строка записывает «hello world» в файл «output», второй   считывает его и записывает на стандартный вывод (обычно   терминал).

Однако cat output будет делать то же самое, no noeed для < здесь. Так в чем разница?

    
задан AlphaOmega 15.02.2017 в 22:56
источник

2 ответа

4

Перенаправление ввода (как в cat < file ) означает, что shell открывает входной файл и записывает его содержимое в стандартный ввод другого процесса. Передача файла в качестве аргумента (как и при запуске cat file ) означает, что программа, которую вы используете (например, cat ), должна открыть сам файл и прочитать содержимое.

В основном, command file передает файл в command , а command < file передает содержимое файла в command . Да, в таких случаях, как cat file vs cat < file , нет легко воспринимаемой разницы в результатах, но они работают по-разному.

Чтобы понять разницу, подумайте о маленьком ребенке и взрослом. Оба они могут пить воду. Тем не менее, взрослый может открыть кран и заполнить стакан (открыть файл и прочитать его содержимое), в то время как ребенку нужна вода, которую нужно передать ему напрямую (он не может открыть файл и может обрабатывать только его содержимое).

Некоторые программы, такие как cat , могут принимать имя_файла в качестве входных данных, а затем открывать файл и делать на нем свою вещь. Вот почему cat file работает. Другие программы, однако, не знают, какие файлы и как их использовать. Все, что они знают, это потоки ввода (например, содержимое файла). Например, tr :

$ cat file
foo
$ cat file | tr 'o' 'b'  ## tr can read a stream
fbb
$ tr 'o' 'b' file  ## tr can't deal with files
tr: extra operand ‘file’
Try 'tr --help' for more information.
$ tr 'o' 'b' < file ## input redirection!
fbb

Другим примером является ls , который может обрабатывать файлы только штрафом, но игнорирует входные потоки:

$ ls
file1  file2
$ ls file1   ## lists only file1: ls takes file names as arguments
file1
$ ls < file1 ## ls ignores its standard input, this is the same as ls alone
file1 file2

Другие программы не могут обрабатывать потоки и вместо этого требуют файлы:

$ rm < file ## fails, rm needs a file 
rm: missing operand
Try 'rm --help' for more information.
$ rm file ## works, file is deleted

Некоторые программы могут работать как с открытыми файлами, так и с чтением входных потоков, но с каждым из них ведут себя по-разному. Например, wc , который при открытии файла печатает имя файла, а также количество строк, слов и символов:

$ wc file
1 1 4 file

Но, если мы просто передаем ему поток, он не знает, что это происходит из определенного файла, поэтому имя файла не печатается:

$ wc < file
1 1 4

Команда md5sum ведет себя аналогично:

$ md5sum file
17fd54512c91e3cd0f70fbaaa9a94d0d  file
$ md5sum < file
17fd54512c91e3cd0f70fbaaa9a94d0d  - 

Обратите внимание, что в первом случае отображается имя файла file , а во втором - «имя файла» - это - : стандартный ввод.

Теперь, если вы хотите получить более подробные сведения, вы можете использовать strace , чтобы узнать, что именно происходит:

strace -e trace=open,close,read,write wc file 2>strace1.txt

и

strace -e trace=open,close,read,write wc < file 2>strace2.txt

У всех будет информация о всех действиях open() , close() и read() , выполняемых процессом. Вы хотите видеть, что strace1.txt (когда файл передан как аргумент, а не с перенаправлением ввода) содержит следующие строки:

open("file", O_RDONLY)                  = 3
read(3, "foo\n", 16384)                 = 4

Это означает, что файл file был открыт и привязан к файловому дескриптору 3 . Затем строка foo\n была прочитана из 3 . Эквивалентная часть выхода strace при использовании перенаправления ввода:

read(0, "foo\n", 16384)                 = 4

Нет соответствующего вызова open() , вместо этого строка foo\n считывается из 0 , стандартный вход 1 .

1 По умолчанию, 0 - стандартный ввод, 1 - стандартный вывод, а 2 - стандартная ошибка. Это, кстати, почему file было открыто как 3 , это был следующий доступный.

    
ответ дан terdon 16.02.2017 в 00:53
источник
1

В основном различия заключаются в следующем:

  1. cat output.txt : напрямую считывает содержимое файла output.txt на стандартный вывод

  2. cat < output.txt : вывод (или содержимое) output.txt через стандартный символ ввода переадресации ( < ) считывается с помощью cat . Следовательно, output.txt используется вход для команды < .

Вывод для обоих методов будет таким же, но второй путь берется во втором методе в результате стандартного входного символа переадресации < .

    
ответ дан George Udosen 15.02.2017 в 23:32