Почему
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. Это поместит вывод ошибок в файл со стандартным выводом.