Falha no loop do Bash quando o subprocesso altera arquivos no disco

1

Este código está falhando há dias e estou no fim da minha cabeça. Talvez alguém possa ajudar.

Eu codifiquei um script bash que deveria passar por sistemas Linux gerenciados. Ele chama outro script bash para obter registros com 8 campos:

local cmd="/usr/local/sbin/zlsexpirations -s -l $nodeList"
local expList                            # list of nodes and expiration days
expList='$cmd'                           # run the command

...

Portanto, a variável 'expList' tem os registros. Em seguida, ele deve percorrer todos os registros passando-os para a função zSetOneSystem () para processar um sistema por vez. Aqui está o loop principal (as aspas duplas em torno de expList são necessárias para passar um registro, não apenas um token):

local nextLine
while read nextLine; do
  zVerbose "calling zSetOneSystem $nextLine"
  zSetOneSystem $nextLine
done < <(echo "$expList")

Esta foi minha primeira tentativa no loop:

echo "$expList" |
while read nextLine; do
  zVerbose "calling zSetOneSystem $nextLine"
  zSetOneSystem $nextLine
done

Os dois sabores do loop acima têm esse comportamento:

  1. Se o sinalizador -n (sem operação) for passado, o loop será executado corretamente conclusão.
  2. Se esse sinalizador não for passado, o loop é executado, processa um sistema (o que resulta em arquivos sendo alterados no disco), mas o loop simplesmente pára.

Quando eu o rastreio, a 'próxima linha de leitura' falha. Eu imprimo 'expList' após o loop e todos os registros ainda estão no lugar. Como um subprocesso pode afetar o pai dessa maneira? Reduzi para duas chamadas de script bash resultantes aninhadas mais profundamente em zSetOneSystem (). Se eu comentar os dois, o loop é bem-sucedido. Se eu não comentar qualquer um dos dois scripts bash, o loop falhará conforme descrito. Estranho.

Qualquer ajuda será apreciada.

Obrigado.

    
por Michael MacIsaac 04.05.2017 / 13:54

1 resposta

0

Você está passando a entrada para o loop while na entrada padrão (descritor de arquivo 0). Qualquer comando dentro do loop que lê a entrada padrão consumirá o fluxo , tornando o conteúdo não disponível para read na segunda vez. Este é um problema comum ao passar a entrada padrão para o que é efetivamente vários comandos. A maneira mais fácil de consertar isso é usar um descritor de arquivo que os comandos dentro do loop provavelmente não usarão, por exemplo:

while read -u "$fd" line
do
    commands…
done {fd}< <(input command(s))
    
por 04.05.2017 / 14:36

Tags