Когда я запускаю следующий Bash script, я ожидаю, что он напечатает Hello. Вместо этого он печатает пустую строку и выходит.
echo 'Hello' | echo
Почему не работает piping с echo до echo?
Когда я запускаю следующий Bash script, я ожидаю, что он напечатает Hello. Вместо этого он печатает пустую строку и выходит.
echo 'Hello' | echo
Почему не работает piping с echo до echo?
 echo печатает все свои аргументы. Он не читается из stdin. Таким образом, второй echo печатает все свои аргументы (none) и выходит, игнорируя Hello on stdin.
Для программы, которая читает ее stdin и печатает ее на stdout, используйте cat:
$ echo Hello | cat
Hello
Кажется, вы не понимаете трубы. В этом случае они более точно известны как анонимные трубы, потому что у них нет имени (есть и именованные каналы). Анонимные трубы работают только между связанными процессами, например с процессами с одним и тем же родителем.
Трубы являются частью системы ввода-вывода, полученной из библиотеки времени выполнения 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. Я опустил много других деталей, включая другие формы перенаправления, такие как замещение процессов и здесь документы.
Трубопровод может выполняться только для команд, принимающих входы от stdin. Но эхо не берется из stdin. Он будет принимать входные данные из аргумента и печатать его. Так что это не сработает. Inorder to echo вы можете сделать что-то вроде echo $(echo 'hello')
Это потому, что echo (как встроенный, так и /bin/echo) ничего не читает из stdin.
Вместо этого используйте cat:
echo 'Hello' | cat
Hello
Или без труб:
cat <<< 'Hello'