如何在batch指令碼中嵌入python程式碼

lzprgmr發表於2013-07-06

老闆叫我幫他測一個命令在windows下消耗的時間,因為沒有裝windows那個啥工具包,沒有timeit那個命令,於是想自己寫一個,原理很簡單:

REM timeit.bat

echo %TIME%
call %*
echo %TIME%

然後兩個時間減一下就可以了,但是總是自己去減始終不方便,最好能直接算好列印出來。

因為涉及到時間格式的解析,時間的運算,在batch下比較困難,自然就想到了python或者perl指令碼,這裡首先想到的是python的-c引數:

REM timeit.bat

set t1 = %TIME%
call %*
set t2 = %TIME%
python -c "some python code to compute the time elapsed"

但是,由於計算的程式碼會比較複雜,直接放在一行上非常難寫,也非常難讀,最好能分多行寫python程式碼,我們知道bash中有個heredoc,結合python的 “-” 引數:

# test.sh

echo this is a bash script
python - <<EOF
import math
print "this is python code"
print math.pi
EOF

無奈,batch並不支援heredoc,所以在要在batch中實現這個,用到一個非常magic的方法:原理就是我的指令碼既是合法的batch,也是合法的python,然後在batch執行的最後用python呼叫自身:

1># : ^
'''
set t1 = %TIME%
call %*
set t2 = %TIME%
python %~f0"
exit /b
rem ^
'''
import os
import datetime
# python code to compute the time elapsed
print "Time Elapsed: xxx"

具體解釋可以看這個問題:http://stackoverflow.com/questions/17467441/how-to-embed-python-code-in-batch-script

注意第一行奇怪的語法只是為了把第二行合法的移到第一行,從而避免三個單引號這個非法命令呼叫出現在batch中。

完整的timeit的實現在這裡:https://github.com/lzprgmr/privaterepo/blob/master/tools/Batch/timeit.bat

 

最後,當然有人會說為什麼不直接寫一個py然後在batch中呼叫 - 這當然可以,但我想盡量保持一個功能在一個指令碼中,這樣看起來整潔,給別人用拷來拷去也不容易出錯。

相關文章