Почему
echo "hello world" | cat
работает пока
cat < echo "hello world"
не? Моя (неверная) интуиция заключается в том, что канал перенаправляет стандартный stdout в cat как stdin .
У нас есть две похожие, но разные вещи
Трубопровод
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 только потому, что мы его используем ...Этот поток читает из файлов. > находится в файле, а < - в файле. Демонстрация:
Сначала 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. Это поместит вывод ошибок в файл со стандартным выводом.