4

Например, echo:

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

[aesteban@localhost ~]$

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

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

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

3 ответа3

3

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

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

Для программы для чтения из 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

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

cat file1 - file2

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

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

  • Команда tr всегда читает со стандартного ввода и не принимает имя файла (ов) в командной строке.
  • Если bc вызывается с аргументом (ами) имени файла, он читает их, а затем также читает стандартный ввод, если только один из файлов не имеет команды halt или quit .
  • Компиляторы (например, компилятор C, который может называться cc или gcc), как правило, требуют (или, по крайней мере, сильно предпочитают) имя файла (ов) в командной строке.  cc потерпит неудачу, если вызывается без имен файлов в командной строке.  cc - будет читать стандартный ввод, только если указаны определенные опции.
  • Не имеет смысла вызывать cmp или diff с менее чем двумя источниками ввода.  Они потерпят неудачу, если вызваны без имен файлов в командной строке.  Оба они соблюдают соглашение, которое аргумент - обозначает стандартный ввод.  cmp file1 эквивалентен cmp file1 - ; т.е. он будет сравнивать file1 со стандартным вводом.  diff завершается неудачно, если вызывается с одним аргументом имени файла; вам нужно было бы сказать diff 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 не будет обрабатывать более одного входного файла из командной строки.)

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

0

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

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

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

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

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

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .