完美的包装器(Python)

问题描述 投票:0回答:2

我运行一个配置管理工具,它调用 /usr/bin/dpkg,但不显示 stdout/stderr。

出了问题,我想调试问题的根源。

我想查看对

dpkg
和 stdout/stderr 的所有调用。

我将原来的

/usr/bin/dpkg
移动到
/usr/bin/dpkg-orig
并写了一个包装:

#!/usr/bin/env python
import os
import sys
import datetime
import subx
import psutil
cmd=list(sys.argv)
cmd[0]='dpkg-orig'

def parents(pid=None):
    if pid==1:
        return '\n'
    if pid is None:
        pid = os.getpid()
    process = psutil.Process(pid)
    lines = [parents(process.ppid())]
    lines.append('Parent: %s' % ' '.join(process.cmdline()))
    return '\n'.join(lines)

result = subx.call(cmd, assert_zero_exit_status=False)
with open('/var/tmp/dpkg-calls.log', 'ab') as fd:
    fd.write('----------- %s\n' % (datetime.datetime.now()))
    fd.write('%s\n' % parents())
    fd.write('stdout:\n%s\n\n' % result.stdout)
    sys.stdout.write(result.stdout)
    fd.write('stderr:\n%s\n' % result.stderr)
    fd.write('ret: %s\n' % result.ret)
    sys.stderr.write(result.stderr)
sys.exit(result.ret)

现在我再次运行配置管理工具并搜索非零的“ret:”行。

输出:

Parent: /usr/bin/apt-get -q -y -o DPkg::Options::=--force-confold -o DPkg::Options::=--force-confdef install openssl-foo-bar-aptguettler.cert
Parent: python /usr/bin/dpkg --force-confold --force-confdef --status-fd 67 --no-triggers --unpack --auto-deconfigure /var/cache/apt/archives/openssl-foo-bar-aptguettler.cert_1-2_all.deb

stdout:


stderr:
dpkg: error: unable to read filedescriptor flags for <package status and progress file descriptor>: Bad file descriptor

ret: 2

发生这种情况是因为我的包装还不完美。

调用

dpkg
的工具想要读取文件描述符,但这不适用于我的包装器。

我的目标:

  • 捕获对
    dpkg
    的所有调用并将其写入日志文件(有效)
  • 写出父进程(作品)
  • dpkg
    的父进程不应该注意到差异并且不会像上面那样失败(尚未工作)。

知道如何实现这一目标吗?

python wrapper
2个回答
1
投票

我写了一个简单的Python脚本来解决这个问题:

https://github.com/guettli/wrap_and_log_calls

用于记录对 Linux 命令的所有调用的包装器

特定用例:我的配置管理工具调用 /usr/bin/dpkg.发生错误,但不幸的是我的配置 管理工具没有向我显示整个标准输出/标准错误。我没有 知道出了什么问题。

一般用例:包装 Linux 命令,如 /usr/bin/dpkg 并写入 出所有对此的调用。


0
投票

包裹

dpkg
时,出现此错误:

dpkg: error: unable to read filedescriptor flags for <package status and progress file descriptor>: Bad file descriptor

如果包装器使用

subprocess.Popen

close_fds=True
 来打开 
dpkg
,则可能会发生 
。在这种情况下,这发生在
subx.call

上下文:

apt-get
使用
dpkg
参数运行
--status-fd 43
。这是
apt-get
用于从
dpkg
接收某些详细信息的“包状态和进度文件描述符”。因此,当使用 Python 的
dpkg
包装
subprocess.Popen
时,有助于通过
close_fds=False

© www.soinside.com 2019 - 2024. All rights reserved.