Ответ 1
Вы также можете использовать seq
в итерации:
for i in 'seq 1 100'; do ... done
Как запустить 100 итераций, используя скрипт оболочки bash? Я хочу знать, сколько времени займет выполнение одной команды (время начала и окончания). Я хочу отслеживать, какая итерация выполняется в данный момент. Я хочу регистрировать каждую итерацию. У меня есть один автоматизированный скрипт, который мне нужно запустить и зарегистрировать.
for i in 1 2 3
do
command1
done
Но я хочу знать, сколько времени потребуется, чтобы завершить одну итерацию - и записать информацию тоже в файл журнала!
Вы также можете использовать seq
в итерации:
for i in 'seq 1 100'; do ... done
for ((i = 1; i <= 100; i++)); do
echo "--- Iteration #$i: $(date) ---"
time command1
done 2>&1 | tee timing.log
Здесь многое происходит. Что происходит?
for
выполняет итерацию от 1 до 100 с использованием синтаксиса C-стиля.$i
в эхо-печати печатает текущий номер итерации.$(date)
вставляет временную метку в каждую распечатку.time
запускает команду и печатает, сколько времени потребовалось выполнить.tee
, что сохраняет копию до timing.log
.2>&1
перенаправляет stderr в stdout, чтобы файл журнала содержал как регулярные сообщения, так и сообщения об ошибках.Следующий script показывает один из способов сделать это.
#!/usr/bin/bash
for i in {1..100} ; do
echo =============================
echo "Number $i: $(date +%Y-%m-%d-%H:%M:%S)"
( time ( echo $i ; sleep 1 ) ) 2>&1 | sed 's/^/ /'
done | tee timing.log
Он использует функцию диапазона bash
для запуска 100 итераций цикла, вывода счетчика циклов и даты.
Затем в это время ваша команда (echo $i ; sleep 1
) и объединяет стандартный вывод и ошибку, прежде чем красиво ее форматировать, и отправив их как на терминал, так и на файл журнала для последующего анализа.
Операция с пятью итерациями:
pax> testprog.sh
=============================
Number 1: 2010-09-16-13:44:19
1
real 0m1.063s
user 0m0.077s
sys 0m0.015s
=============================
Number 2: 2010-09-16-13:44:20
2
real 0m1.056s
user 0m0.030s
sys 0m0.046s
=============================
Number 3: 2010-09-16-13:44:21
3
real 0m1.057s
user 0m0.046s
sys 0m0.030s
=============================
Number 4: 2010-09-16-13:44:22
4
real 0m1.057s
user 0m0.061s
sys 0m0.031s
=============================
Number 5: 2010-09-16-13:44:23
5
real 0m1.057s
user 0m0.046s
sys 0m0.015s
Вы можете попробовать:
for i in {1..100}; do time some_script.sh; done 2>&1 | grep ^real | sed -e s/.*m// | awk '{sum += $1} END {print sum / NR}'
time
time
, чтобы мы могли grep егоgrep ^real
- это получить только строки, начинающиеся с "real" в выводе time
sed
- удалить начало строки до части минут (на выходе time
)awk
добавляется к сумме, так что в конце она может вывести среднее значение, которое является общей суммой, деленное на количество входных записей (= NR
)Фрагмент предполагает, что время выполнения some_script.sh меньше 1 минуты, иначе оно не будет работать вообще. В зависимости от вашей системы встроенный time
может работать по-разному. Другой альтернативой является использование команды time/usr/bin/time вместо встроенного bash.
Примечание. Этот script был извлечен из здесь.