我正在Python中执行一个程序,该程序似乎明确检查了是否正在使用stdin
,如果这样做,则会导致某些不良行为,从而输出我不需要的垃圾二进制文件。为此,我特别希望not希望程序“查看”任何已连接的stdin。但是,默认情况下,subprocess.run()
连接到父级的stdin,因此,如果父级进程(例如pytest)具有stdin文件,则测试将失败。
例如,说我的测试是这个(samtools
可以使用conda install -c bioconda samtools
安装:]
import subprocess
def test_execute():
print(subprocess.run(
['samtools', 'sort'],
stdout=subprocess.PIPE,
encoding='utf-8'
))
如果我运行pytest test.py -s
,则代码有效,因为-s
会断开标准输入。但是,如果我pytest test.py
,该命令将输出一些垃圾二进制文件,这将导致测试失败:
> (result, consumed) = self._buffer_decode(data, self.errors, final)
E UnicodeDecodeError: 'utf-8' codec can't decode byte 0x8b in position 1: invalid start byte
/media/michael/Storage2/miniconda/lib/python3.7/codecs.py:322: UnicodeDecodeError
是否存在某种强制标准输入断开连接的方法,所以无论我的pytest
标志如何,我的子进程都将永远不会检测到已连接的标准输入?
编辑:通过查看source code of my target program(samtools),似乎它正在使用isatty()
检查它是否应该产生输出。因此,在这种情况下,我需要傻瓜isatty()
。
事实证明,此特定问题涉及欺骗函数isatty()
,因为这是我的子进程用来确定是否应输出二进制文件的原因。因此,要解决此问题,我只需要将stdin
连接到tty:
import subprocess
import pty # <--------------------------- Added
def test_execute():
master, slave = pty.openpty() # <---- Added
print(subprocess.run(
['samtools', 'sort'],
stdout=subprocess.PIPE,
stdin=slave, # <----------------- Added
encoding='utf-8'
))
现在pytest test.py
总是成功,万岁!