Bash запускает команды конвейера в среде подоболочек, поэтому любые переменные и т.д., Которые происходят внутри него, не видны остальной части оболочки.
Dash (Debian's /bin/sh
), а также busybox sh
похожи, в то время как zsh и ksh запускают последнюю часть в основной оболочке. В Bash вы можете использовать shopt -s lastpipe
чтобы сделать то же самое, но это работает только тогда, когда управление заданиями отключено, поэтому по умолчанию не используется в интерактивных оболочках.
Так:
$ bash -c 'x=a; echo b | read x; echo $x'
a
$ bash -c 'shopt -s lastpipe; x=a; echo b | read x; echo $x'
b
(read
и mapfile
имеют одинаковую проблему.)
В качестве альтернативы (и как уже упоминалось в Attie), используйте процесс подстановки, который работает как обобщенный канал и поддерживается в Bash, ksh и zsh.
$ bash -c 'x=a; read x < <(echo b); echo $x'
b
POSIX оставляет это неопределенным, если части конвейера работают в подоболочках или нет, так что нельзя сказать, что какая-либо из оболочек будет "неправильной" в этом.