python-3.x - 当python3链两个subprocess.run(如bash管道)得到错误“AttributeError:'bytes'对象没有属性'fileno'”
问题描述
bash 代码是:
mx=8;my=8;head -c "$((3*mx*my))" /dev/urandom | convert -depth 8 -size "${mx}x${my}" RGB:- /tmp/random.png
而python3中的代码:
#!/usr/bin/python3
import subprocess
result = subprocess.run(['head', '-c {}'.format(3 * size * size), '/dev/urandom'], stdout=subprocess.PIPE)
print('{}'.format(result))
result = subprocess.run(['convert', '-depth 8', '-size{}x{}'.format(size, size), 'RGB:-', '/tmp/random.png'], stdin=result.stdout, stdout=subprocess.PIPE)
但输出是:
$ python3 create_mosaic_images.py
CompletedProcess(args=['head', '-c 192', '/dev/urandom'], returncode=0, stdout=b"j\xd1U0\x7f\xc0\x11\x9e\xcdJ\x88P\xdc\xe5\xd26\xee\xf3m\xe0\xf9S\xd5%0q\xfb\x01\xd4^\xbd^R\xe4\x9c\x9e\xb5\xaf\x99:B[\xdc4\x80\x1a\x8a>\xeb\x9e\xab\xae/\xa4\xf4\xc3u\xaca\x8efJ\x9fNK\xa2\xb0\x18\x98\x95\xb08\xeb\x07\xf6\x9d2Ko\x11\xa0\x98\xf7\x8b\x04'\xd4;\xe8\xa5SD\xc7\xf8\xe6;\x8b\x880\xb8\x1e~\xee>r\xf0\xc0g\xfb\xce\xd6\xfcq\x1a\x91\xa0t0\x96\xf47\x9cj\xd4\x9ac\x15z\x81\xf35\x8f\x1ay\xa2\x8av\xb5\xe4\x15ox\x00\x00O\xfa\x98\x17\xe1\x04\xd5\x8dx\xdf\x9a.\xce<b\xb2\x16\x15\x94\xbd\x17Z\x14\xba\xc5-?\xbcH\t\x9a~1y\xc5\xe6\xf5\xd2[\xfb\xc0k\x90\xdfB\xafje")
Traceback (most recent call last):
File "create_mosaic_images.py", line 26, in <module>
generate_random_pixels_square()
File "create_mosaic_images.py", line 19, in generate_random_pixels_square
result = subprocess.run(['convert', '-depth 8', '-size{}x{}'.format(size, size), 'RGB:-', '/tmp/random.png'], stdin=result.stdout, stdout=subprocess.PIPE)
File "/usr/lib/python3.5/subprocess.py", line 693, in run
with Popen(*popenargs, **kwargs) as process:
File "/usr/lib/python3.5/subprocess.py", line 911, in __init__
errread, errwrite) = self._get_handles(stdin, stdout, stderr)
File "/usr/lib/python3.5/subprocess.py", line 1392, in _get_handles
p2cread = stdin.fileno()
AttributeError: 'bytes' object has no attribute 'fileno'
好吧,我不知道什么是坏的。
解决方案
你不能run
像这样链接 2 个调用。
您需要第一次调用 use Popen
,result.stdout
真正的文件在哪里(result.stdout
返回的run
是一个bytes
对象,而不是真正的文件,因为run
返回时,该过程已经结束,所有输出都产生了,而不是Popen
启动该过程并写入管道)
process1 = subprocess.Popen(['head', '-c','{}'.format(3 * size * size), '/dev/urandom'], stdout=subprocess.PIPE)
result = subprocess.Popen(['convert', '-depth','8', '-size{}x{}'.format(size, size), 'RGB:-', '/tmp/random.png'], stdin=process1.stdout, stdout=subprocess.PIPE)
另外,您的论点分裂是错误的。您不能包含空格,您必须执行完整拆分。
在这种情况下,更好的方法是关闭第一个进程,因为您已经可以在 python 中执行此操作:
with open('/dev/urandom','rb') as f:
random_block = b"".join(f.readline() for _ in range(3 * size * size))
result = subprocess.Popen(['convert', '-depth','8', '-size{}x{}'.format(size, size), 'RGB:-', '/tmp/random.png'], stdin=subprocess.PIPE, stdout=subprocess.PIPE)
output,error = result.communicate(random_block);
推荐阅读
- angular - Angular 通用加载器组件
- c# - Xamarin.Forms SQLite 异常 - 不知道
- c# - InstallShield - 如何编写自定义操作函数
- javascript - 获取图片 src 如果有更多图片 src 只获取一张图片 src
- c++ - 在决定游戏中对象的生命时,何时使用指针、引用、原始指针和智能指针?
- angular - 使用 HttpInterceptor 设置标头的问题
- javascript - 数据总是空的 AJAX 调用 Rails 5
- android - Android - 焦点导航返回按钮
- jenkins - 由于缺少 Slack baseUrl,Jenkins JobDSL 种子作业突然失败
- mysql - mysql存储过程多参数