В чем разница между здесь строкой и эхом + трубой

Интересно, как правильно использовать здесь-строку (здесь-документ) и канал.

Например,

a='a,b,c,d'
echo $a | IFS=',' read -ra x
IFS=',' read -ra x <<< $a

Оба метода работают. Тогда в чем будет разница между двумя функциями?

Другая проблема, связанная с «чтением», заключается в том, что:

IFS=',' read x1 x2 x3 x4 <<< $a

не работает, x1 оценивается как "a b c d", а x2, x3, x4 не имеет значения

но если:

IFS=',' read x1 x2 x3 x4 <<< "$a"

Я могу получить x1=a, x2=b, x3=c, x4=d Все в порядке!

Кто-нибудь может это объяснить?

заранее спасибо


person dragonxlwang    schedule 08.08.2013    source источник
comment
Ваш второй вопрос интересен, но его следует задать отдельно. Размещение двух несвязанных вопросов в одном и том же сообщении значительно затрудняет поиск вопроса позже кем-то еще с той же проблемой.   -  person rici    schedule 08.08.2013
comment
Мне интересно, может быть, стоит пометить это как обман stackoverflow.com/questions/41899075/ -- вопрос здесь задается с меньшим отступлением и, таким образом, потенциально более полезен для людей, которые строго заинтересован в вопросе о конвейере против строки, указанном в заголовке.   -  person Charles Duffy    schedule 27.01.2017


Ответы (1)


В конвейере создаются два новых процесса: один для оболочки для выполнения команды echo, а другой для оболочки для выполнения команды read. Поскольку обе подоболочки завершают работу после завершения, переменная x недоступна после завершения конвейера. (В bash 4 была введена опция lastpipe, позволяющая последней команде в конвейере выполняться в текущей оболочке, а не в подоболочке, что устраняет проблему с такими конвейерами).

Во втором примере не требуется никакого дополнительного процесса для строки здесь (особый тип документа здесь, состоящий из одной строки), поэтому значение x фактически устанавливается в текущей оболочке, что делает его доступным для использования позже в сценарий/сеанс.

person chepner    schedule 08.08.2013
comment
спасибо, но я не совсем понимаю, что конвейер привел к недоступности переменных: я экспериментировал с GNU bash версии 3.2.48(1) и все еще могу вывести $x после окончания конвейера. И в чем различие целей этих двух методов? (функция, использование) - person dragonxlwang; 08.08.2013
comment
x должно было иметь предыдущее значение, потому что конвейер не установит значение x в текущей оболочке. Здесь документы были созданы отчасти для того, чтобы избежать проблемы с подоболочкой, возникающей при использовании конвейеров. - person chepner; 08.08.2013
comment
Ясно спасибо!! И, пожалуйста, помогите мне с добавленной частью вопроса. Спасибо! - person dragonxlwang; 08.08.2013