织物2.x:焦油和焦油通过管道

时间:2019-02-08 16:19:09

标签: python ssh tar invoke fabric

我想做与此shell脚本等效的事情:

ssh visarend.solasistim.net tar -c /home/amoe/episodes | tar -vx -

但是使用Fabric2.x。这是我的尝试,但是我不确定是什么问题。

remote_path = "/home/amoe/episodes"

c = fabric.Connection('visarend.solasistim.net')

with subprocess.Popen(['tar', '-vx'], stdin=subprocess.PIPE) as reader_proc:
    c.run(
        "tar -c %s" % (remote_path,),
        out_stream=reader_proc.stdin
    )

这给了我错误:

  File "/usr/local/lib/python3.5/dist-packages/invoke/runners.py", line 525, in write_our_output
    stream.write(encode_output(string, self.encoding))

TypeError: a bytes-like object is required, not 'str'

还有一些other errors。我了解这可能是因为我从reader_proc.stdin获得的流是字节流,而不是unicode流。但是我不明白为什么run会需要一个unicode流,或者要使其正常工作将进行什么正确的更改。

1 个答案:

答案 0 :(得分:2)

我无法评论为什么假设通过fabric.Connection.run()执行的任务会产生文本流,但是,由于存在latin-1编码,实际的二进制流已打包为文本流对象可以重新解释为二进制流而没有任何失真:

import fabric
import subprocess
from io import TextIOWrapper

remote_path = "/home/amoe/episodes"

c = fabric.Connection('visarend.solasistim.net')

with subprocess.Popen(['tar', '-vx'], stdin=subprocess.PIPE) as reader_proc:
    c.run(
        "tar -c %s" % (remote_path,),
        out_stream=TextIOWrapper(reader_proc.stdin, encoding='latin-1'),
        encoding='latin-1'
    )