Python sys.stdout.write()无效

时间:2016-01-28 23:23:11

标签: python subprocess

我正在尝试使用名为“server.py”的父python脚本“scp”一个名为“whichserver.py”的子python脚本。我在父脚本中使用“subprocess”。父脚本首先将“SCP”子脚本“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')

My Child脚本名为“whichserver.py”:

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

输出:

['\n']

预期产出:

ZT Systems

你能否说明我为什么只能获得换行符?有没有办法在从远程服务器获取输出后将值“ZT Systems”存储在localhost中的变量中?

1 个答案:

答案 0 :(得分:0)

这里有一些事情发生。

  1. 除非您别无选择,否则应使用ssh.communicate()代替ssh.stdoutssh.stderr。这可以避免阻塞(可能会阻止永远,因为您正在等待错误的管道)。

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

  3. 那个shell脚本有点乱。它不会处理错误,它会把新行放在有趣的地方。有一个$server变量没有用处(除了剥离空格外)。

  4. 这是一个固定的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。两种选择都有缺点。