Anexar dados ao arquivo com uma única abertura / fechamento de um script de shell

2

Eu preciso ajustar meu script de shell e gravar em $log várias vezes. Abrir e fechar o arquivo repetidamente causará um aumento no tempo de execução.

Como posso escrever tudo de uma vez no arquivo, incluindo todas as instruções echo definidas no meu script?

#!/bin/sh
log="loadlog.log"

for i in {1..10}
do
   n=$((100*$i))
   echo "## Users=$i  requests=$n ##" >> $log     
   ab -n $n -c $i  http://mainserver.com/index.html  >>  $log
   ssh root@mainserver cat /proc/loadavg >> $log
   echo "======" >> $log
done
    
por Jecki 10.02.2013 / 08:28

2 respostas

4

Não tenho certeza, mas acho que você deseja abrir o arquivo de registro para escrever apenas uma vez, não é?

Nesse caso, você precisa usar um sub-shell, enviar para o STDOUT e, fora dele, enviá-lo para o arquivo de log.

#! /bin/bash
log="loadlog.log"

(
for i in {1..10}; do
    n=$((100*$i))

    echo "## Users=$i  requests=$n ##"

    ab -n $n -c $i  http://mainserver.com/index.html

    ssh root@mainserver cat /proc/loadavg

    echo "======"
done
) >> $log

Além disso, recomendo que você faça algo com seu estilo de código, pois é ilegível. E você precisa usar #!/bin/bash porque usa construções específicas do bash no loop.

    
por 10.02.2013 / 08:48
2

Usar o comando exec com um redirecionamento aplica esse redirecionamento ao script inteiro. Assim, você poderia redirecionar todos os stdout para anexar ao arquivo de log:

#!/bin/sh
log="loadlog.log"

exec 1>>$log

for i in {1..10}
do
   n=$((100*$i))
   echo "## Users=$i  requests=$n ##"
   ab -n $n -c $i  http://mainserver.com/index.html
   ssh root@mainserver cat /proc/loadavg
   echo "======"
done

Se você ainda quiser emitir material para o usuário, faça uma cópia do stdout primeiro:

#!/bin/sh
log="loadlog.log"

exec 3>&1     # file descriptor 3 is now stdout
exec 1>>$log

for i in {1..10}
do
    # ...
   echo "======"                  # this line will be appended to the log file
   echo "completed loop $i" >&3   # this line will be displayed to user
done

exec 1>&3     # fd 1 restored to stdout
exec 3>&-     # fd 3 is closed

echo "stdout now restored"
    
por 10.02.2013 / 13:10

Tags