Почему некоторые команды не принимают перенаправление ввода?

297
angelcool.net

Например, echo :

[aesteban@localhost ~]$ cat tmp.txt  Angel [aesteban@localhost ~]$ echo < tmp.txt  [aesteban@localhost ~]$ 

Как видите, вывод - просто пустая строка. Согласно моим прочтениям, некоторые команды могут перенаправлять ввод, например, mail :

[aesteban@localhost ~]$ mail barney@example.com < tmp.txt 

Таким образом, перенаправление ввода применяется только для интерактивных команд (которые могут ждать ввода)? Как определить, является ли команда интерактивной (кроме попыток)?

4

3 ответа на вопрос

3
Edward

Почему некоторые команды не принимают перенаправление ввода?

Короткий ответ: потому что они не были запрограммированы на.

Для программы для чтения stdin(которая является потоком, который оболочка подключается к файлу, указанному после <) не является автоматическим. Это должно быть закодировано программистом. В этом отношении чтение из файлов, указанных в командной строке, также не является автоматическим. То есть содержимое этих файлов, независимо от того, передается ли оно перенаправлением или указывается по имени, волшебным образом не отображается внутри переменных программы без дополнительного кодирования.

Если программа никогда не кодировалась для чтения из потока, не имеет значения, вставили ли вы перенаправление - она ​​просто не будет читать из нее. В соответствии со спецификацией POSIX ( http://pubs.opengroup.org/onlinepubs/009604599/utilities/echo.html ) echoне требуется читать stdin, а только проверяет аргументы командной строки (и некоторые переменные среды). Чтобы узнать о других программах, вы можете прочитать исходный код, документацию или просто попробовать, как вы сказали :-)

Чтобы ответить на ваш последний вопрос: вы не можете сказать, что команда является интерактивной. Вы можете определить, подключен ли входной поток, из которого он читает, к терминалу (в отличие, например, от простого файла). Есть примеры на многих языках на http://rosettacode.org/wiki/Check_input_device_is_a_terminal . Вы можете представить почтовую программу, которая использует эту функцию, чтобы определить, используется ли она в интерактивном режиме (принимает команды клавиатуры для чтения почты) или неинтерактивно (скажем, для чтения почтового сообщения из файла). Я не уверен, как mailэто получается. (Обратите внимание, что mailведет себя по-разному при вызове с или без аргументов командной строки!)

1
Scott

Большинство команд, которые читают содержимое файла (или файлов), чьи имена указаны в командной строке, будут считываться из стандартного ввода, если в командной строке не указаны файлы. Некоторые также будут читать из стандартного ввода, если - в командной строке указано имя файла ; например,

кошка файл 1  -  файл 2

будет читать, затем стандартный ввод, а затем . Но если команда обычно не читает содержимое файла (ов), чьи имена указаны в командной строке, то она, вероятно, также ничего не сделает со стандартным вводом. никогда не читает из файлов.file1file2echo

Конечно, есть различные исключения:

  • Команда trвсегда читает со стандартного ввода и не принимает имя файла (ов) в командной строке.
  • Если bcвызывается с аргументом (ами) имени файла, он читает их, а затем также читает стандартный ввод, если только один из файлов не имеет команды haltили quit.
  • Компиляторы (например, компилятор C, который может быть вызван ccили gcc), как правило, требуют (или, по крайней мере, сильно предпочитают) имя файла (ов) в командной строке.  ccпотерпит неудачу, если вызывается без имен файлов в командной строке. cc -будет читать стандартный ввод, только если указаны определенные опции.
  • Не имеет смысла вызывать cmpили использовать diff менее двух источников ввода. Они потерпят неудачу, если вызваны без имен файлов в командной строке. Оба они соблюдают соглашение о том, что аргумент -обозначает стандартный ввод.  эквивалентно ; т.е. он будет сравниваться со стандартным вводом.  терпит неудачу, если вызывается с одним аргументом имени файла; вам нужно будет сказать .cmp file1cmp file1 -file1diffdiff file1 -
  • И, в то время как ddбудет принимать я Nput ф ИОС, указанный в командной строке, если она представлена в виде, например,if=filename

    dd if=my_iso_file of=/dev/sda1 

    ( ofЭто о utput ф Ile), и он будет читать со стандартного ввода, если не указано какое - либо if; например,

    dd of=/dev/sda1 < my_iso_file 

    он не принимает аргументы командной строки, которые неукрашенные имена файлов (так, например, dd my_iso_file > /dev/sda1и dd my_iso_file of=/dev/sda1 ничего не работает). (Кроме того, в отличие от большинства команд, которые читают из файлов, ddне будет обрабатываться более одного входного файла из командной строки.)

(Есть, вероятно, другие.)

Технически, вы можете перенаправить файл в `dd`:` dd status = none </ proc / uptime` Steven 8 лет назад 0
0
Steven

Прочитайте документацию.

Команда echo не читает из стандартного ввода. Поэтому перенаправление ввода ничего не делает. Руководство Bash гласит:

echo: выводит аргументы, разделенные пробелами, за которыми следует новая строка.

Справочная страница для cat:

cat - объединяет файлы и печатает на стандартный вывод.