Python subprocess.check_output() 似乎忽略了参数

Python subprocess.check_output() seems to ignore arguments

首先,我尽可能多地阅读了 subprocess.check_output() 的相关问题,但仍然难以找出问题所在。

如果我在shell中执行kill -l 1,我得到1对应的信号名称,即HUP。我的 python 脚本需要相同的行为,所以我使用:

>>> subprocess.check_output(['kill', '-l', '1'])
b'HUP INT QUIT ILL TRAP ABRT BUS FPE KILL USR1 SEGV USR2 PIPE ALRM TERM STKFLT\nCHLD CONT STOP TSTP TTIN TTOU URG XCPU XFSZ VTALRM PROF WINCH POLL PWR SYS\n'

子进程似乎忽略了参数列表中的“1”,而是执行了 kill -l

我尝试了不同的版本,参数为列表或字符串,shell 选项为 True 和 False,但 none 似乎有效。

任何想法可能是什么原因?在 Ubuntu14.04 上使用 python3.4。

谢谢!

可能的原因:shell 中的 kill 命令正在执行一个 shell 内置命令(大多数 shell 都有一个,因为你需要能够当你有失控的 fork 炸弹等时,在没有进程启动的情况下杀死),而 check_output(默认情况下不在 shell 中执行)是 运行 找到的 kill 可执行文件在您的 PATH 中(通常 /bin/kill,但并非总是如此,bash 中的 运行 type -P kill 会告诉您该可执行文件的位置。

奇怪的是,内置支持您正在寻找的开关,可执行文件不支持。在 bash 中,尝试 运行 type -P kill,然后显式 运行 /full/path/to/kill -l 1 以查看 kill check_output 是否确实支持那个调用。 kill.

的不同实现之间通常存在细微差别

最好的解决方案可能是避免昂贵且毫无意义的 subprocess 启动并检查信号的 Python 定义。例如,在 Python 3.5 中,构建从 Python 已知的信号到它们的 Python 名称的映射是微不足道的:

import signal

sigdict = {sig.value: sig.name for sig in signal.Signals}

print(sigdict[1])
CTRL_BREAK_EVENT  # <-- The output on my Windows box. On your machine, it would probably be SIGHUP

在名称不是 enum 的旧 Python 中,您可以使用模块的 dir 使用类似的代码,过滤 __module__ 是的名称signal 并且其值为整数来构造映射。