需求:在任务系统中调度shell命令行命令执行一个脚本,并且执行脚本是阻塞的,同时需要设计超时。
考虑到os.system()
函数可以执行系统命令,同样也是阻塞的,但是本身是不带超时结束的,这时候就需要考虑如何让一个阻塞的函数能够在我们设置的timeout
时间耗完之后告知我们该命令还未跑完。
这里想到在调用os.system()
的时候开启一个线程,通过线程的状态来判断是否完成了命令执行。
代码:
from os import system
from threading import Thread
import time
def exec_shell(cmd_str, timeout=30 * 60):
def run_shell_func(sh):
system(sh)
start_time = time.time()
t = Thread(target=run_shell_func, args=(cmd_str,), daemon=False)
t.start()
while 1:
now = time.time()
if now - start_time >= timeout:
if not t.is_alive():
return 'exec_shell_complete'
else:
return 'exec_shell_timeout'
if not t.is_alive():
return 'exec_shell_complete'
time.sleep(1)
说明:
每次调用exec_shell
函数时新建一个线程,线程内运行的run_shell_func
函数执行阻塞命令system(sh)
,同时通过while
循环每一秒检查一下线程的状态,当线程is_alive()
为False
时说明线程内执行shell命令
已经完成(因为线程中的函数执行完成之后线程会自动退出)。
当进入if now - start_time >= timeout:
分支时说明设置的超时时间已经到了,再判断一次t.is_alive()
是为了防止在最后一秒命令执行完成了,但是返回的是exec_shell_timeout
。