简体   繁体   English

如何只为一个进程选择性地将stdout保存在文件中?

[英]How can I selectively save stdout in a file only for one process?

To capture the output of a SSH command execution session in a txt file I did this: 要在txt文件中捕获SSH命令执行会话的输出,我执行了以下操作:

sys.stdout = open('Output_Log.txt','w')

Now, once the SSH session is closed, I want to stop writing to the file and let the other print statements come to the console. 现在,一旦SSH会话关闭,我想停止写入文件,而让其他打印语句进入控制台。

But that is not happening. 但那并没有发生。 The subsequent prints are overwriting my above log file and I am loosing my SSH command execution data. 后续打印将覆盖我上面的日志文件,并且我正在丢失SSH命令执行数据。

Here is the complete code: 这是完整的代码:

  session.exec_command('cd /project/neptune/neptune_psv/fw; ./Do_Regr.sh -i Testlist_Regression.in -m 135.24.237.198 -g')

  stdout_data = []
  stderr_data = []
  sys.stdout = open('Output_Log.txt','w')
  sys.stderr = open('Error_Log.txt','w')

  while True:

   try:
     if session.recv_ready():
      stdout_data.append(session.recv(16384))

     if session.recv_stderr_ready():
      stderr_data.append(session.recv_stderr(16384))

     if session.exit_status_ready():
      break

   except socket.timeout:
    print("SSH channel timeout exceeded.")
    break
   except Exception:
    traceback.print_exc()
   break

  print 'exit status: ', session.recv_exit_status()
  print ''.join(stdout_data)
  print ''.join(stderr_data)

  session.close()
  trans.close()
  print "############Regression Complete############"

When I open Output_Log.txt I only find the last print. 当我打开Output_Log.txt时,我只找到最后一个打印件。 Whereas, if I comment the last print statement (Regression Complete) then the Output_Log nicely captures the stdout_data of the session. 而如果我评论最后一个打印语句(Regression Complete),则Output_Log会很好地捕获会话的stdout_data。

Instead of redirecting sys.stdout and sys.stderr , write to the files directly. 而不是重定向sys.stdoutsys.stderr ,直接写入文件。 You are already capturing the output in lists -- use that to your advantage: 您已经在列表中捕获了输出-利用它可以发挥自己的优势:

try:
    # capture output streams
finally:
    with open('Output_Log.txt', 'w') as output:
        output.write(''.join(stdout_data))
        output.write('\nexit status: %s' % session.recv_exit_status())
    with open('Error_Log.txt', 'w') as output:
        output.write(''.join(stderr_data))

To save output of a ssh command in a file, don't redirect Python's stdout/stderr, use subprocess module instead: 要将ssh命令的输出保存在文件中,请勿重定向Python的stdout / stderr,而应使用subprocess模块:

from subprocess import call

cmd = ['ssh', 'host', 'cd /project/neptune/neptune_psv/fw; '
       './Do_Regr.sh -i Testlist_Regression.in -m 135.24.237.198 -g']
with open('Output_Log.txt', 'w') as out, open('Error_Log.txt','w') as err:
    rc = call(cmd, stdout=out, stderr=err)

Or if you want to continue using paramiko ; 或者如果你想继续使用paramiko ; a minimal change to your code is to use out.write instead of stdout_data.append and err.write instead of stderr_data.append where out , err are corresponding file objects. 对代码的最小更改是使用out.write而不是stdout_data.appenderr.write而不是stderr_data.append ,其中outerr是相应的文件对象。 Do not redirect sys.stdout , sys.stderr -- it is unnecessary here. 不要重定向sys.stdoutsys.stderr - 这里没有必要。

To avoid loosing data you should read possibly buffered data even if the subprocess is finished ie, read until EOF (until an empty result) after if session.exit_status_ready() . 为了避免丢失数据,即使子进程已完成,也应该读取可能缓冲的数据,即在if session.exit_status_ready()之后读取直到EOF(直到空结果if session.exit_status_ready()

Well, with the existing code I found one solution: 好吧,使用现有代码我找到了一个解决方案:

  stdout_data = []
  stderr_data = []
  temp = sys.stdout      --------- Added this
  sys.stdout = open('Output_Log.txt','w')
  sys.stderr = open('Error_Log.txt','w')

  ---------------Main Code---------------------

  print 'exit status: ', session.recv_exit_status()
  print ''.join(stdout_data)
  print ''.join(stderr_data)

  session.close()
  trans.close()
  sys.stdout.close()
  sys.stdout = temp      ------ Added this

  print "############Regression Complete############"

This works good for me. 这对我有用。 But I will try both the solutions suggested above and reply later. 但我会尝试上面提出的解决方案并稍后回复。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM