首页 > 解决方案 > 如何在 Python 中清除 ssh 下子进程的标准输出?

问题描述

我想清除 ssh 下子进程的标准输出。请看下面的简化代码,它没有太大意义,但它会重新生成现象。

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.'”是pickle的序列化数据。但是,“stdout”包含额外的二进制文件,“我想清除此消息,但我不能。\n”。

在“打印(字节流)”行之前,我尝试通过

'os.system(\'cls\' if os.name == \'nt\' else \'clear\') \n'

但它失败了。

如何清除 ssh 下子进程的标准输出?

stderr 的消息是什么意思?

请告诉我。

非常感谢。

标签: pythonsubprocess

解决方案


您有两件事要写入标准输出。首先,pre_defined_func()在您的脚本中立即调用 which,然后print()转储 pickle 结果。这两个输出一个接一个地完成,所以,是的,你收到的是两者的串联。您在两者之间尝试的clsorclear只是使终端清除其屏幕的更多字节,但在流中它们只是一些额外的字节。

进程通常有两个主要的输出通道,称为 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))

推荐阅读