Eu tenho o seguinte script de shell. O objetivo é percorrer cada linha do arquivo de destino (cujo caminho é o parâmetro de entrada para o script) e trabalhar em cada linha. Agora, parece funcionar apenas com a primeira linha no arquivo de destino e para depois que essa linha foi processada. Há algo de errado com meu script?
#!/bin/bash
# SCRIPT: do.sh
# PURPOSE: loop thru the targets
FILENAME=$1
count=0
echo "proceed with $FILENAME"
while read LINE; do
let count++
echo "$count $LINE"
sh ./do_work.sh $LINE
done < $FILENAME
echo "\ntotal $count targets"
Em do_work.sh
, executo alguns ssh
comandos.
bash
shell
ssh
while-loop
bispo
fonte
fonte
source
e simplesmente sair ouexec
. Mas este código não parece genuíno, o OP notaria que o echo requer-e
para exibir o feed de linha corretamente ...do_work.sh
executadossh
por acaso?do_work.sh
código fonte e também rodardo.sh
comset -x
para depurar.Respostas:
O problema é que
do_work.sh
executassh
comandos e, por padrão,ssh
lê stdin, que é o seu arquivo de entrada. Como resultado, você só vê a primeira linha processada, porquessh
consome o resto do arquivo e seu loop while termina.Para evitar isso, passe a
-n
opção para o seussh
comando de torná-lo lido em/dev/null
vez de stdin.fonte
cat
. Você pensaria que um roedor em particular desconfiaria disso.while read host ; do $host do_something ; done < /etc/hosts
iria evitá-lo. Isso é um salva-vidas e tanto, obrigado!httpie
é outro comando que lê STDIN por padrão e terá o mesmo comportamento quando chamado dentro de um bash ou fish loop. Usehttp --ignore-stdin
ou defina a entrada padrão/dev/null
como acima.De forma mais geral, uma solução alternativa que não é específica para
ssh
é redirecionar a entrada padrão para qualquer comando que, de outra forma, poderia consumir awhile
entrada do loop.A adição de
</dev/null
é o ponto crucial aqui (embora as aspas corrigidas também sejam um pouco importantes; consulte também Quando envolver aspas em uma variável de shell? ). Você vai querer usar, aread -r
menos que exija especificamente o comportamento legado ligeiramente estranho que você consegue sem-r
.Outra solução alternativa que é um tanto específica
ssh
é garantir que qualquerssh
comando tenha sua entrada padrão ligada, por exemplo, alterandoem vez disso, leia os comandos de um documento here, que convenientemente (para este cenário específico) vincula a entrada padrão de
ssh
para os comandos:fonte
A opção ssh -n evita a verificação do status de saída do ssh ao usar HEREdoc enquanto canaliza a saída para outro programa. Portanto, é preferível usar / dev / null como stdin.
fonte
<<EOF
substitui o</dev/null
redirecionamento. O<<
redirecionamento após odone
está errado.Isso estava acontecendo comigo porque eu tinha
set -e
e umgrep
em um loop estava retornando sem saída (o que dá um código de erro diferente de zero).fonte