Shell Script - Saída redirecionada para um arquivo e resultados não são esperados na primeira execução

2

Eu redirecionei a saída do comando que retorna algumas vezes 2 linhas, 5 linhas .. 100 linhas etc no arquivo .. e usarei este arquivo em if condition later para verificar algumas outras condições ..

Estranho é - eu preciso executar o script várias vezes para obter os dados como esperado .. se eu executar o script pela primeira vez simplesmente não retornar nada .. Por favor, você pode ajudar porque isso não está dando o resultado esperado no primeira execução

O código é para o AIX e é o seguinte:

df -gt | grep /home/prods/db2/ > /tmp/DISKREQ.TMP
if [[ $? -eq 0 ]]; then
        chmod 777 /tmp/DISKREQ.TMP
        cat /tmp/DISKREQ.TMP | awk '{print$6}' | awk 'length($0) == 22' > /tmp/DISKREQ.TMP
        cat /tmp/DISKREQ.TMP | while read line
        do
                        FSIZE_DISKREQ='df -g | awk '$7 == "'$line'" {print $3;}''
                        if [[ $FSIZE_DISKREQ -lt 2 ]]; then
                        echo
                         echo " Instance Home Directory $line = $FSIZE_DISKREQ "
                        else
                        echo
                                echo " Instance Home Directory $line "
                        fi
        done
else
echo
        echo "No Instance Home directory Mounted"
fi
    
por RenukaKC 08.10.2015 / 18:46

1 resposta

2
cat /tmp/DISKREQ.TMP | awk '{print$6}' | awk 'length($0) == 22' > /tmp/DISKREQ.TMP

Os componentes de um pipeline são executados em paralelo. Esta linha, portanto, executa três comandos em paralelo:

  • cat /tmp/DISKREQ.TMP
  • awk '{print$6}'
  • awk 'length($0) == 22' > /tmp/DISKREQ.TMP

O primeiro comando está abrindo /tmp/DISKREQ.TMP para leitura. O terceiro comando está truncando /tmp/DISKREQ.TMP antes de fazer qualquer outra coisa. Dependendo do tempo, cat pode ou não ter tempo para ler pelo menos o início do arquivo.

Solução: não escreva no mesmo arquivo da entrada. (Existem soluções mais complexas e mais frágeis que permitem reutilizar o nome; não vou dar uma porque não faz sentido fazer algo complicado aqui.)

df -gt | grep /home/prods/db2/ > /tmp/DISKREQ.TMP
if [[ $? -eq 0 ]]; then
    cat /tmp/DISKREQ.TMP | awk '{print$6}' | awk 'length($0) == 22' > /tmp/DISKREQ2.TMP
    cat /tmp/DISKREQ2.TMP | while read line
    …

(Não use chmod 777 . Isso nunca resolve nada, mas pode criar problemas.)

Você não precisa de todos esses arquivos temporários, então você pode evitar completamente o problema se livrando deles. Apenas canalize a cadeia do awk diretamente para o loop while para se livrar do segundo arquivo temporário. Eu também me livrei dos usos inúteis de cat e combinei os dois scripts awk em um.

df -gt | grep /home/prods/db2/ > /tmp/DISKREQ.TMP
if [[ $? -eq 0 ]]; then
    </tmp/DISKREQ.TMP awk 'length($6) == 22 {print $6}' | while read line
    do
    …

Você pode até mesmo se livrar de awk e fazer a filtragem no while read loop; Vou deixar isso como um exercício para o leitor.

Para se livrar do primeiro arquivo temporário, é necessário alterar um pouco a lógica. O corpo do loop while não será executado de qualquer maneira se grep não encontrar nada, já que ele terá zero linhas para trabalhar, mas você precisa de alguma lógica para exibir a mensagem nesse caso. Você pode usar uma diretiva END no awk.

df -gt | grep /home/prods/db2/ |
awk 'length($6) == 22 {print $6}
     END {if (NR==0) print "No Instance Home directory Mounted"}' |
while read line; do …

Você pode combinar a chamada grep com awk . (Exercício para o leitor.) Ou você pode fazer toda a filtragem no shell. Eu assumo que /home/prods/db2/ será sempre o começo da sexta coluna.

found=0
df -gt |
while read device total used available percent mountpoint; do
    [[ $mountpoint == /home/prods/db2/* ]] || continue
    ((++found))
    [[ ${#mountpoint} -eq 22 ]] || continue
    …
done
if ((found == 0)); then echo "No Instance Home directory Mounted"; fi
    
por 09.10.2015 / 03:00