如何在Python中的ssh下清除子进程的stdout?

时间:2018-07-25 13:10:00

标签: python subprocess

我想清除ssh下子进程的stdout。 请参阅以下简化的代码,该代码没有多大意义,但会重新产生这种现象。

import shlex
import subprocess
import pickle

# *** I cannot modify the pre_defined_func() ***
print_func_py = 'def pre_defined_func():\n' \
            '    print("I want to clear this message but I could not.")\n' \
            '    return "answer" \n' \
            '\n' \
            'result = pre_defined_func() \n' \
            'import os \n' \
            'import pickle \n' \
            'import io \n' \
            'bytes = io.BytesIO() \n' \
            'byte_stream = pickle.dumps(result) \n' \
            'os.system(\'cls\' if os.name == \'nt\' else \'clear\') \n' \
            'print(byte_stream)'

print_func_py_sh = shlex.quote(print_func_py)

get_value_command = ['ssh', 'localhost', 'python3', '-c', print_func_py_sh]

get_value_process = subprocess.run(get_value_command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)

print("stdout = {0}".format(get_value_process.stdout))
print("stderr = {0}".format(get_value_process.stderr))

输出如下,

stdout = b"I wat to clear this message but I could not.\nb'\\x80\\x03X\\x06\\x00\\x00\\x00answerq\\x00.'\n"
stderr = b'TERM environment variable not set.\n'

我希望“ stdout = b'\ x80 \ x03X \ x06 \ x00 \ x00 \ x00answerq \ x00”。 这是泡菜的序列化数据。但是'stdout'包含额外的二进制文件,'我想清除此消息,但我不能。\ n'。

在“ print(byte_stream)”行之前,我尝试通过

清除标准输出。
'os.system(\'cls\' if os.name == \'nt\' else \'clear\') \n'

但是失败了。

如何清除ssh下子进程的stdout?

stderr消息意味着什么?

请告诉我。

非常感谢您。

1 个答案:

答案 0 :(得分:1)

写入stdout有两件事。首先,pre_defined_func()在脚本中立即被调用,然后是print(),其转储腌制结果。这两个输出是一个接一个地完成的,因此,是的,您收到的是两个的串联。您在两者之间尝试的clsclear只是更多字节,可以使终端清除其屏幕,但是在流中,它们只是另外一些字节。

进程通常有两个主要的输出通道,称为stdout和stderr(输出和错误消息)。默认是打印到标准输出,因此通常所有“结果”都写在这里。任何执行输出的命令都可以决定输出应进入这些通道中的哪一个。顺便说一句,您在stderr上看到的消息仅表示未设置TERM环境变量。通常这应该不成问题,并且不在这里。

我建议将脚本写入两个通道stdout和stderr的内容分开,然后稍后在阅读脚本中将它们分开。只是不要做clear的事情,那没有帮助。 ssh很幸运地分别传输了两个通道,因此这也应该起作用。内联找到我的更改。我还转换了您的代码,以减少引用方式。

import shlex
import subprocess
import pickle

print_func_py = '''\
import sys

def pre_defined_func():
    print("I want to clear this message but I could not.",
          file=sys.stderr)
    return "answer"

result = pre_defined_func()
import os
import pickle
import io
bytes = io.BytesIO()
byte_stream = pickle.dumps(result)
print(byte_stream)
'''

print_func_py_sh = shlex.quote(print_func_py)

get_value_command = ['ssh', 'localhost', 'python3', '-c', print_func_py_sh]

get_value_process = subprocess.run(get_value_command,
                                   stdout=subprocess.PIPE,
                                   stderr=subprocess.PIPE)

print("stdout = {0}".format(get_value_process.stdout))
print("stderr = {0}".format(get_value_process.stderr))