Выполнение и чтение выходных данных двоичного файла в скрипте python / bash / perl

1

У меня есть исполняемый файл, который выполняет следующие действия: 1. выводит строку BEGIN 2. Подождите некоторое время 3. выводит строку END

Я хочу сделать следующее с помощью python/ bash/perl script в MacOS:

  • выполнить упомянутую выше программу из командной строки
  • записывать время между сообщением BEGIN и сообщением END, выводимым программой

как я могу сделать это чисто?

  • 0
    У вас есть доступ к исходному коду этого двоичного файла? Было бы проще (и точнее) отобразить отметку времени с сообщениями BEGIN / END непосредственно внутри программы.
  • 3
    То, что @Antonin Portelli говорит, правильно. Наблюдение за выводом одного процесса из другого с использованием канала даст неточные результаты синхронизации из-за системных издержек и буферизации - поэтому, если внешняя программа не пометит временные метки своим собственным выходом, потребуется некоторая другая форма межпроцессного взаимодействия с низким объемом служебных данных.
Теги:
scripting

4 ответа

1
Лучший ответ

Самый простой (лучший?) способ сделать это в bash - просто вызвать date и вывести его время в секундах. timer.sh script будет вызывать ваш исполняемый файл (randbegend.sh для моих целей тестирования), а затем искать линии BEGIN и END, чтобы вызвать вызов на дату. После завершения вашего исполняемого файла timer.sh будет вычислять и отображать временную дельта в секундах.

timer.sh

#!/bin/bash

while read line; do
  if [[ "$line" == "BEGIN" ]]; then
    t1=$(date "+%s")
    echo t1=$t1
  elif [[ "$line" == "END" ]]; then
    t2=$(date "+%s")
    echo t2=$t2
  fi
done < <(./randbegend.sh) # Change this to call your executable

echo "delta = $((t2 - t1)) seconds"

randbegend.sh

#!/bin/bash

sleep $((RANDOM % 5))
echo BEGIN
sleep $((RANDOM % 10))
echo END

Выход

$ ./timer.sh
t1=1292451820
t2=1292451825
delta = 5 seconds

$ ./timer.sh
t1=1292451886
t2=1292451889
delta = 3 seconds

$ ./timer.sh
t1=1292451896
t2=1292451903
delta = 7 seconds
1

Если вы хотите только детализацию всего-второго, вы можете сделать следующий "однострочный" в perl:

( echo BEGIN ; sleep 3s ; echo END ) | \
    perl -ne 'print $_; if (/BEGIN/) { $begin_time = time(); } if (/END/) { $t = time()-$begin_time; print "time was : $t seconds" }'

Выдает:

BEGIN
[ 3 second delay ]
END
time was : 3 seconds

Вы будете придерживаться своей командной строки вашей программы, где у меня есть ( echo BEGIN ; sleep 3s ; echo END ).

0

Вы можете сделать это просто с помощью GAWK:

exec | gawk '{if ($1 == "BEGIN") {t1 = systime()} else if ($1 == "END") {t2 = systime()}} END{print t2-t1" sec"}'

где exec - ваш исполняемый файл. Это хорошо, только если вам не нужна точность, более точная, чем одна секунда.

0

В Python:

Вы можете использовать модуль datetime, чтобы отметить текущую временную метку до и после выполнения внешней программы, а затем вычесть их для получения времени выполнения.

Вы можете выполнять внешние программы с помощью модуля subprocess.

Итак, код будет выглядеть примерно так:

import datetime, subprocess

ts1 = datetime.datetime.now()
subprocess.Popen('/path/to/external/program')
ts2 = datetime.datetime.now()
print ts2-ts1
  • 0
    Это не учитывает возможность того, что его исполняемый файл делает несколько вещей перед выводом BEGIN и несколько вещей после вывода END.
  • 0
    Ну, это правда, но он не упомянул, что это возможно.
Показать ещё 2 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню