Изменить: оригинальное название было "чтение не удается в Bash"
С помощью ksh я использую read как удобный способ разделения значений:
$ echo 1 2 3 4 5 | read a b dump
$ echo $b $a
2 1
$
Но это не сработает в bash:
$ echo 1 2 3 4 5 | read a b dump
$ echo $b $a
$
Я не нашел причину в справочной странице, почему это не помогает, любая идея?
Ответы:
bash
запускает правую часть конвейера в контексте подоболочки , поэтому изменения в переменных (что иread
происходит) не сохраняются - они умирают, когда это делает подоболочка, в конце команды.Вместо этого вы можете использовать процесс подстановки :
В этом случае
read
он работает в нашей основной оболочке, а наша производящая команда запускается в подоболочке.<(...)
Синтаксис создает подоболочку и подключает свой выход к трубе, которую мы перенаправлять на входread
с обычной<
операцией . Посколькуread
запускается в нашей основной оболочке, переменные установлены правильно.Как указано в комментарии, если ваша цель буквально как-то разделить строку на переменные, вы можете использовать строку здесь :
Я предполагаю, что есть нечто большее, чем это, но это лучший вариант, если нет.
источник
read a b dump <<< '1 2 3 4 5'
.cat /etc/passwd | (read -r line ; echo $line)
. Но следующийecho
из$line
которых не находится в конвейере, ничего не выводит на экран, потому что значение существовало только в скобках (подоболочка). Надеюсь, это кому-то поможет.Это не
bash
ошибка, посколькуPOSIX
допускаетbash
иksh
поведение, и поведение, приводящее к печальному расхождению, которое вы наблюдаете.http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_12
Кроме того, каждая команда многокомпонентного конвейера находится в среде подоболочек; однако в качестве расширения любая или все команды в конвейере могут выполняться в текущей среде. Все остальные команды должны выполняться в текущей среде оболочки.
Однако, с
bash 4.2
и новее, вы можете установитьlastpipe
опцию в неинтерактивных сценариях, чтобы получить ожидаемый результат, например:Выход:
источник
lastpipe
том, что он не работает в других оболочках (например, в тире). в принципе нет никакого способа сделать этот переносной,