Мне нужно настроить сценарий оболочки и написать в $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"