Executing and reading the output of a binary in python/bash/perl script
I have an executable that does the following: 1. outputs the string BEGIN 2. wait for some random time 3. outputs the string END
I want to do the following with a python/bash/perl script开发者_StackOverflow on MacOS:
- execute the program mentioned before from command line
- record the time between the BEGIN message and the END message outputted by the program
how do I do this cleanly?
The easiest (best?) way to do this in bash is to just call date
and have it output it's time in seconds. The timer.sh
script will call your executable (randbegend.sh
for my testing purposes) and then look for the BEGIN and END lines to trigger the call to date. Once your executable quits, timer.sh
will then calculate and display the time delta in seconds.
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
Output
$ ./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
If you want only whole-second granularity, you can do the following "one-liner" in 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" }'
Produces:
BEGIN
[ 3 second delay ]
END
time was : 3 seconds
You'd stick your command line execution of your program where I have ( echo BEGIN ; sleep 3s ; echo END )
.
In Python:
You can use the datetime
module to make a note of the current timestamp, before and after the execution of the external program, and then subtract the two to get the execution time.
You can execute external programs using the subprocess
module.
- More about datetime: http://docs.python.org/library/datetime.html
- More about subprocess: http://docs.python.org/library/subprocess.html
So the code would look something like:
import datetime, subprocess
ts1 = datetime.datetime.now()
subprocess.Popen('/path/to/external/program')
ts2 = datetime.datetime.now()
print ts2-ts1
You can do it simply with GAWK :
exec | gawk '{if ($1 == "BEGIN") {t1 = systime()} else if ($1 == "END") {t2 = systime()}} END{print t2-t1" sec"}'
where exec
is your executable. This is good only if you don't need a precision more accurate than one second.
精彩评论