Python sys.stdout.write() 不起作用



我正在尝试使用名为"server.py"的父python脚本"scp"一个名为"whichserver.py"的子python脚本。我在父脚本中使用"子进程"。父脚本将首先将子脚本"SCP"到远程服务器中。父脚本和子脚本位于同一目录中。然后在远程服务器上运行子脚本,并在本地终端中显示输出。但是我没有看到任何输出。这是我的脚本:

父脚本"server.py":

import pexpect
import subprocess
import sys
def server_type(host):
  filepath = "whichserver"
  remotepath = "/tmp/"
  hostname = 'adam@' + host
  HOST = host
  COMMAND="cd /tmp && chmod 755 ./whichserver && ./whichserver"
  subprocess.call(['scp', filepath, ':'.join([hostname,remotepath])])
  ssh = subprocess.Popen(["ssh", "%s" % HOST, COMMAND],shell=False,stdout=subprocess.PIPE,stderr=subprocess.PIPE)  
  result = ssh.stdout.readlines()
  if result == []:
      error = ssh.stderr.readlines()
      print >>sys.stderr, "ERROR: %s" % error
  else:
      print result
      for line in iter(result):
         sys.stdout.write(line)
print('Enter the server name: ')
hostname1 = raw_input()
response = os.system("ping -c 1 " + hostname1)
if response == 0:
  print(hostname1 + ' is up')
  server_type(hostname1)
else:
  print(hostname1 + ' is down')

名为"whichserver.py"的"我的孩子"脚本是:

#!/bin/bash
server="$(sudo dmidecode | grep -m1 'Manufacturer:' | sed 's/.*Manufacturer://')"
echo
printf $server

输出:

['n']

预期输出:

ZT Systems

你能建议为什么我只得到换行符吗?从远程服务器获取输出后,有没有办法将值"ZT Systems"存储在本地主机的变量中?

这里有一些事情发生。

  1. 除非您别无选择,否则您应该使用 ssh.communicate() 而不是 ssh.stdoutssh.stderr。 这样可以避免阻塞(可能永远阻塞,因为您在错误的管道上等待)。

  2. 您应该检查子流程的输出状态。 相反,您只需检查它是否产生输出。 但是它应该产生输出,即使它失败了,因为echo语句。 因此,成功和失败的测试不起作用。

  3. 那个 shell 脚本有点乱。 它不会处理错误,它会在有趣的地方放置换行符。 有一个$server变量没有任何用途(好吧,除了去除空格)。

下面是一个固定的 shell 脚本:

#!/bin/sh
# Note: sh, because we don't need any bash-isms
# Exit on error
set -e
# No need to save to a variable, just print it out
# Also: printf would get rid of the newline at end, but why bother?
sudo dmidecode | grep -m1 'Manufacturer:' | sed 's/[^:]*: *//'

但是,这并不是真正必要的。 而不是上传带有scp的脚本并使用ssh执行它,我们可以直接使用 ssh 执行脚本。 这为我们节省了一些步骤。

from __future__ import print_function
def server_type(host):
    cmd = "sudo dmidecode | grep -m1 'Manufacturer:' | sed 's/[^:]*: *//'"
    proc = subprocess.Popen(
        ['ssh', str(host), cmd],
        stdout=subprocess.PIPE,
        stderr=subprocess.PIPE)
    stdout, stderr = proc.communicate()
    if proc.returncode != 0:
        print('Error:', stderr.rstrip(), file=sys.stderr)
    else:
        print('Server type:', stdout.rstrip())

另请注意,sudo可能需要 tty。 您可以将其配置为不需要 tty,也可以使用 ssh -t ,这使得ssh提供 tty。 这两种选择都有缺点。

最新更新