5

Почему

echo "hello world" | cat

работает пока

cat < echo "hello world"

не? Моя (неверная) интуиция заключается в том, что канал перенаправляет стандартный stdout в cat как stdin .

2 ответа2

7

У нас есть две похожие, но разные вещи

  • Трубопровод

    echo "hello world" | cat   # This is a pipeline
    

    Операторы управления каналом (| и |&) соединяют выход команды со входом следующей в конвейере. Итак, первый пример работает, вывод команды echo , "Hello word", связан с вводом следующей команды cat , которая предполагает стандартный ввод в качестве входного файла, если не указано иное. На самом деле мы можем прочитать от man cat:

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

    и ниже пример с простым вызовом cat

    cat Copy standard input to standard output

  • Перенаправление или лучше попытка перенаправления ввода <

    cat < echo "hello world"   # This is an attempt of redirection 
    

    В этом случае команда cat берет свой ввод из стандартного ввода, который вы перенаправляете с помощью оператора < из файла с правой стороны < ..., который не является файлом. Это потому, что это не работает .

    Из раздела перенаправления man bash

    Перенаправление ввода
    Перенаправление ввода вызывает открытие файла, имя которого является результатом раскрытия слова, для чтения по дескриптору файла n или стандартного ввода (дескриптор файла 0), если n не указано.

  • В bash это работает по разным причинам

    • cat <(echo "hello world") Замена процесса

      Подстановка процессов поддерживается в системах, которые поддерживают именованные каналы (FIFO) или метод /dev /fd для именования открытых файлов. Он принимает форму <(list) или >(list) . Список процессов запускается с его входом или выходом, подключенным к FIFO или некоторому файлу в /dev/fd . Имя этого файла передается в качестве аргумента текущей команде в результате расширения. Если используется форма >(list) , запись в файл обеспечит ввод для списка. Если используется форма <(list) , файл, переданный в качестве аргумента, должен быть прочитан для получения вывода списка.

    • cat <<< $(echo "hello world") Здесь строки

      Слово подвергается расширению скобок, расширению тильды, расширению параметров и переменных, подстановке команд, расширению арифметики и удалению кавычек. Расширение имени пути и разбиение по словам не выполняются. Результат передается команде в виде одной строки на ее стандартном входе.

Рекомендации

  • man bash и поиск перенаправления, конвейера, здесь строк и подстановок процессов
  • man cat только потому, что мы его используем ...
0

Этот поток читает из файлов. > находится в файле, а < - в файле. Демонстрация:

Сначала echo "HELLO HELLO HELLO" > HELLO.txt а затем cat < HELLO.txt

 HELLO HELLO HELLO

Это бесполезно, поскольку вывод уже идет туда, куда вы хотите, но другой пример с тем же HELLO.txt - это cat < HELLO.txt >&1 явно направляющий вывод cat в STDOUT.

Более полезно, иногда вы обнаруживаете, что вывод файлового дескриптора 2 (STDERR) перенаправляется такими командами, как

grep somepattern /path/to/a_bunch_of_files/* 2>&1 >> alloutput.txt

Поток 2>&1 направляет ошибки на стандартный вывод. Затем весь стандартный вывод передается в alloutput.txt. Это поместит вывод ошибок в файл со стандартным выводом.

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