Назад | Перейти на главную страницу

Добавление данных в файл с помощью одного открытия / закрытия из сценария оболочки

Мне нужно настроить сценарий оболочки и написать в $log многократно. Повторное открытие и закрытие файла приведет к увеличению времени выполнения.

Как мне записать в файл сразу все, включая все echo операторы, определенные в моем сценарии?

#!/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

Я не уверен, но я думаю, вы хотите открыть файл журнала для записи только один раз, не так ли?

Если это так, вам нужно использовать вспомогательную оболочку, вывести ее в STDOUT и, вне ее, отправить в файл журнала.

#! /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

Также я рекомендую вам что-то сделать со своим стилем кода - он нечитаем. И вам нужно использовать #!/bin/bash потому что вы используете в цикле конструкции, специфичные для bash.

Используя exec команда с перенаправлением применяет это перенаправление ко всему скрипту. Итак, вы можете перенаправить весь стандартный вывод для добавления в файл журнала:

#!/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

Если вы по-прежнему хотите отправлять данные пользователю, вы можете сначала сделать копию stdout:

#!/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"