Editar: o título original foi "falha na leitura no bash"
Com o ksh, estou usando o read como uma maneira conveniente de separar valores:
$ echo 1 2 3 4 5 | read a b dump
$ echo $b $a
2 1
$
Mas falha no bash:
$ echo 1 2 3 4 5 | read a b dump
$ echo $b $a
$
Não encontrei um motivo na página de manual por que falha, alguma ideia?
Respostas:
bash
executa o lado direito de um pipeline em um contexto de subshell , para que as alterações nas variáveis (que é o queread
faz) não sejam preservadas - elas morrem quando o subshell faz, no final do comando.Em vez disso, você pode usar a substituição de processo :
Nesse caso,
read
está sendo executado em nosso shell primário e nosso comando de produção de saída é executado no subshell. A<(...)
sintaxe cria um subshell e conecta sua saída a um canal, para o qual redirecionamos para a entradaread
com a<
operação comum . Por serread
executado em nosso shell principal, as variáveis estão definidas corretamente.Conforme indicado em um comentário, se seu objetivo é literalmente dividir uma sequência em variáveis de alguma forma, você pode usar uma sequência aqui :
Presumo que há mais do que isso, mas essa é uma opção melhor, se não houver.
fonte
read a b dump <<< '1 2 3 4 5'
.cat /etc/passwd | (read -r line ; echo $line)
. Mas o próximoecho
item$line
que não está no pipeline não coloca nada na tela, porque o valor existia apenas entre parênteses (subshell). Espero que ajude alguém.Isso não é um
bash
bug, poisPOSIX
permite comportamentosbash
e ambosksh
, levando à discrepância infeliz que você está observando.http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_12
Além disso, cada comando de um pipeline de comandos múltiplos está em um ambiente de subcasca; como uma extensão, no entanto, qualquer um ou todos os comandos em um pipeline podem ser executados no ambiente atual. Todos os outros comandos devem ser executados no ambiente atual do shell.
No entanto, com
bash 4.2
e mais recentes, você pode definir alastpipe
opção em scripts não interativos para obter o resultado esperado, por exemplo:Saída:
fonte
lastpipe
é que ele não funciona em outras conchas (por exemplo, traço). há basicamente nenhuma maneira de fazer este pequeno portátil de executar tudo em que subshell, consulte stackoverflow.com/questions/36268479/...