我已经设置了一个记录器,但我不知道如何仅在命令失败或生成 stderr 时进行记录。
def RunAndLog(self, command, logf) p = subprocess.Popen(command, shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE) (stdout, stderr) = p.communicate() logger = logging.getLogger('check rel') logger.setLevel(logging.ERROR) filehand = logging.handlers.RotatingFileHandler(logFile, mode='a',maxBytes=0, backupCount=0, encoding=None, delay=0) filehand.setLevel(logging.ERROR) lformat = logging.Formatter('%(message)s') filehand.setFormatter(lformat) logger.addHandler(filehand) logger.info(stdout) logger.error(stderr) logger.removeHandler(filehand)
我调用这个来列出目录。例如,
self.RunAndLog(["dir","%s",pathtodir], "test.log")
test.log包含两种情况的消息,即当目录不存在时以及当目录存在时…这是一个例子:
test.log
#case where dir doesn't exist dir: /path/to/dir/dir1: No such file or directory # case where it does bin lib include src test python doc
我如何才能test.log仅在目录不存在或dir命令失败且退出状态非零的情况下记录消息?
dir
要实现只记录命令失败或有 stderr 输出的日志,可以对命令的退出状态码和 stderr 进行检查。在你的代码中,可以根据 subprocess.Popen 的返回值 p.returncode 和 stderr 是否非空,来决定是否记录日志。
stderr
subprocess.Popen
p.returncode
以下是改进后的代码:
import subprocess import logging from logging.handlers import RotatingFileHandler def RunAndLog(command, log_file): # Run the command and capture stdout and stderr p = subprocess.Popen(command, shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout, stderr = p.communicate() # Check the return code and stderr if p.returncode != 0 or stderr: # Set up the logger logger = logging.getLogger('check_rel') logger.setLevel(logging.ERROR) file_handler = RotatingFileHandler(log_file, mode='a', maxBytes=0, backupCount=0, encoding=None, delay=0) file_handler.setLevel(logging.ERROR) formatter = logging.Formatter('%(message)s') file_handler.setFormatter(formatter) logger.addHandler(file_handler) # Log the stderr or a custom error message logger.error(f"Command failed with return code {p.returncode}") if stderr: logger.error(stderr.decode().strip()) # Clean up the logger to avoid duplicate handlers logger.removeHandler(file_handler) return stdout, stderr, p.returncode
假设要运行一个命令并记录失败的情况:
# Example: Running the directory listing command command = ["ls", "/nonexistent/path"] # Replace with your command log_file = "test.log" stdout, stderr, returncode = RunAndLog(command, log_file) if returncode == 0: print("Command succeeded!") else: print("Command failed. See test.log for details.")
如果 stderr 非空,表示有错误输出,也需要记录日志。
日志记录改进:
在日志消息中记录命令的返回码和错误输出。
避免日志处理器重复添加:
logger.removeHandler
test.log 会记录:
Command failed with return code 2 ls: cannot access '/nonexistent/path': No such file or directory
不会写入 test.log。