使用断开连接的标准输入启动 Python 子进程
Starting a Python subprocess with a disconnected stdin
我正在 Python 中执行一个程序,它似乎明确检查是否正在使用 stdin
,如果使用了,它会导致一些不良行为,从而输出一些垃圾二进制文件我不想。由于这个原因,我特别 不 希望程序 "see" 任何连接的标准输入。但是,默认情况下,subprocess.run()
连接到父进程的标准输入,因此如果父进程(例如 pytest)有标准输入文件,测试将失败。
例如说我的测试是这样的(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
总是成功,万岁!
我正在 Python 中执行一个程序,它似乎明确检查是否正在使用 stdin
,如果使用了,它会导致一些不良行为,从而输出一些垃圾二进制文件我不想。由于这个原因,我特别 不 希望程序 "see" 任何连接的标准输入。但是,默认情况下,subprocess.run()
连接到父进程的标准输入,因此如果父进程(例如 pytest)有标准输入文件,测试将失败。
例如说我的测试是这样的(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
总是成功,万岁!