Python 当从终端发出命令时,使脚本自动停止

Python 当从终端发出命令时,使脚本自动停止,python,linux,Python,Linux,我有一个脚本runReports.py,每天晚上都会执行。假设由于某种原因,脚本执行时间过长,我希望能够通过发出类似于/runReports.py stop的命令从终端停止脚本 我试图通过让脚本在发出stop命令时创建一个临时文件来实现这一点 脚本在运行每个报告之前检查此文件是否存在 如果文件在那里,脚本将停止执行,否则将继续执行 但我无法找到一种方法使stop命令的发出者知道脚本已成功停止。大致如下: $ ./runReports.py stop Stopping runReports..

我有一个脚本
runReports.py
,每天晚上都会执行。假设由于某种原因,脚本执行时间过长,我希望能够通过发出类似于
/runReports.py stop
的命令从终端停止脚本

我试图通过让脚本在发出stop命令时创建一个临时文件来实现这一点

脚本在运行每个报告之前检查此文件是否存在

如果文件在那里,脚本将停止执行,否则将继续执行

但我无法找到一种方法使stop命令的发出者知道脚本已成功停止。大致如下:

$ ./runReports.py stop
  Stopping runReports...
  runReports.py stopped successfully.

如何实现这一点?

您希望实现进程间通信。您应该首先探索实现这一点的不同方法:system V IPC(内存,非常通用,可能令人费解的API)、套接字(包括unix域套接字)(内存,更有限,更干净的API)、文件系统(磁盘上的持久性,几乎与体系结构无关),然后选择您自己的

当您询问文件时,仍然有两种使用文件进行通信的方法:要么使用文件内容(功能丰富,更难实现),要么简单地使用文件存在。但是使用文件的问题是,如果程序由于错误而终止,它可能无法在磁盘上写入其结束状态

IMHO,在选择基于文件系统的通信之前,您应该明确定义您的需求(测试程序的结尾并不是它最擅长的),除非您还需要架构独立性


要直接回答您的问题,如果您使用文件系统通信,了解程序是否已结束的唯一可靠方法是浏览当前活动进程的列表,最简单的方法是如何在子进程中使用
ps-e

例如,如果您的脚本在循环中运行,您可以捕获信号并终止进程:

import signal

class SimpleReport(BaseReport):
    def __init__(self):
        ...
        is_running = True

    def _signal_handler(self, signum, frame):
        is_running = False

    def run(self):
        signal.signal(signal.SIGUSR1, self._signal_handler) # set signal handler
        ...
        while is_running:
            print("Preparing report")
        print("Exiting ...")

要终止进程,只需调用kill-SIGUSR1 procId,而不是临时文件,您可以拥有一个永久文件(config.txt),其中包含一些标记,并检查标记“running=True”

要实现这一点非常简单,如果代码中有一个循环(我想是的),只需创建一个函数/方法,在这个文件上分支一个检查条件

def continue_running():
    with open("config.txt") as f:
        for line in f:
            tag, condition = line.split(" = ")
            if tag == "running" and condition == "True":
                return True
    return False
在脚本中,您将执行以下操作:

while True: # or your terminal condition
    if continue_running():
        # your regular code goes here
    else:
        break

因此,要停止脚本中的循环,只需将“running”更改为“True”以外的任何内容即可。

脚本在哪里运行?它必须向调用用户的终端或GUI写入哪些功能?可能最简单的方法是让closer打开一个管道进行读取,然后等待主脚本将其状态写入管道。