Трубопровод не работает с командой echo
Когда я запускаю следующий Bash
script, я ожидаю, что он напечатает Hello
. Вместо этого он печатает пустую строку и выходит.
echo 'Hello' | echo
Почему не работает piping
с echo
до echo
?
Ответы
Ответ 1
echo
печатает все свои аргументы. Он не читается из stdin
. Таким образом, второй echo
печатает все свои аргументы (none) и выходит, игнорируя Hello
on stdin
.
Для программы, которая читает ее stdin
и печатает ее на stdout
, используйте cat
:
$ echo Hello | cat
Hello
Ответ 2
Кажется, вы не понимаете трубы. В этом случае они более точно известны как анонимные трубы, потому что у них нет имени (есть и именованные каналы). Анонимные трубы работают только между связанными процессами, например с процессами с одним и тем же родителем.
Трубы являются частью системы ввода-вывода, полученной из библиотеки времени выполнения C. По умолчанию эти потоки буферизуются (есть исключение). В основном труба просто подключает выходной буфер от одного процесса к входному буфере другого.
Первые три потока, используемые (называемые файловыми дескрипторами), пронумерованы 0, 1 и 2. Первый, 0, известен как стандартный ввод или stdin
(имя, используемое в C). По умолчанию это связано с клавиатурой, но ее можно перенаправить либо с помощью символа <
, либо с именем программы, находящимся на правой стороне канала.
Второй, 1, известен как стандартный вывод или stdout
. По умолчанию это связано с экраном терминала, но может быть перенаправлено с помощью символа >
или имени программы, расположенного на левой стороне канала.
Итак:
echo 'Hello' | echo
принимает стандартный вывод из echo
и передает его на стандартный ввод echo
. Но echo
не читает stdin! Так что ничего не происходит.
Фильтровать программы обрабатывают имена файлов, указанные в командной строке. Если имена файлов не указаны, они читают stdin. Примеры включают cat
, grep
и sed
, но не echo
. Например:
echo 'Hello' | cat
отобразит "Hello", а cat
бесполезен (это часто бывает).
echo 'Hello' | cat file1
будет игнорировать вывод из echo
и просто отобразить содержимое файла1. Помните, что stdin читается только в том случае, если имя файла не указано.
Как вы думаете, что это отображается?
echo 'Hello' | cat < file1 file2
и почему?
Наконец, третий поток, 2, называется стандартной ошибкой или stderr
, и этот небуферизован. Он игнорируется трубами, потому что они работают только между stdin и stdout. Однако вы можете перенаправить stderr на использование stdout (см. man dup2
):
myprog 2>&1 | anotherprog
2>&1
означает "перенаправить файловый дескриптор 2 на то же место, что и дескриптор 1".
Это нормальное поведение, однако программа может переопределить все, что захочет. Например, он мог читать из дескриптора файла 2. Я опустил много других деталей, включая другие формы перенаправления, такие как замещение процессов и здесь документы.
Ответ 3
Трубопровод может выполняться только для команд, принимающих входы от stdin. Но эхо не берется из stdin. Он будет принимать входные данные из аргумента и печатать его. Так что это не сработает. Inorder to echo вы можете сделать что-то вроде echo $(echo 'hello')
Ответ 4
Это потому, что echo
(как встроенный, так и /bin/echo
) ничего не читает из stdin
.
Вместо этого используйте cat
:
echo 'Hello' | cat
Hello
Или без труб:
cat <<< 'Hello'