Tentando dividir uma string em duas variables

Estou tentando dividir uma string em duas variables ​​(sem ter que usar um loop while):

var="hello:world" IFS=':' read var1 var2 <<< $var echo "var1: $var1" echo "var2: $var2" 

mas não estou conseguindo o resultado desejado:

 var1: 'hello world' var2: '' 

Alguém poderia, por favor, explicar se é possível fazer assim (ou de maneira similar)?

Este é um bug no Bash 4.2. Veja a resposta de chepner para uma explicação adequada.


É sobre citações. Usar:

 IFS=':' read var1 var2 < << "$var" ^ ^ 

ao invés de

 IFS=':' read var1 var2 < << $var 

Veja o resultado:

 $ IFS=':' read var1 var2 < << "$var" $ echo "var1=$var1, var2=$var2" var1=hello, var2=world 

Mas

 $ IFS=':' read var1 var2 < << $var $ echo "var1=$var1, var2=$var2" var1=hello world, var2= 

FYI para futuros leitores:

Depois de discutir isso com os desenvolvedores, parece que este é realmente um bug no bash 4.2, e foi corrigido na próxima versão 4.3. Do log de alteração do ramo de devel

rrrr. Corrigido vários problemas com o IFS quando ele aparece no ambiente temporário e é usado em redirecionamentos.

Embora seja sempre uma boa ideia citar as expansões de parâmetros, o código do OP deve funcionar como planejado sem aspas.


Aqui está uma explicação do bug. Com o código

 var="hello:world" IFS=':' read var1 var2 < << $var 

o $var não citado deve ser uma única palavra, já que não contém nenhum caractere no valor global do IFS (ou seja, nenhum espaço em branco). read deve então ver a string hello:world . Como recebeu dois argumentos, ele deve aplicar a divisão de palavras usando seu valor local de IFS , produzindo hello e world que são atribuídos a var1 e var2 , respectivamente.

O erro é que a string here parece sofrer divisão parcial usando o valor "vazado" do IFS sendo passado para read . Como resultado, a string se torna hello world , mas ainda é vista como uma única palavra. Como essa palavra não contém um:, a read não a divide em duas palavras e a cadeia inteira é atribuída a var1 .

No bash 4.3, conforme documentado, a expansão de $var não passa pela divisão de palavras como argumento para o operador < << ; o código

 var="hello:1:2 world" IFS=: read var1 var2 < << $var 

define var1 para hello e var2 para 1:2 world .