简体   繁体   English

Python sys.stdout.write()无法正常工作

[英]Python sys.stdout.write() not working

I am trying to "scp" a child python script called "whichserver.py" using parent python script called "server.py". 我正在尝试使用名为“ server.py”的父级python脚本来“ scp”一个名为“ whichserver.py”的子级python脚本。 I am using "subprocess" in the parent script. 我在父脚本中使用“子进程”。 The parent script will first "SCP" the child script into the remote server. 父脚本将首先将子脚本“ SCP”到远程服务器中。 Both parent and child script are in the same directory. 父脚本和子脚本都在同一目录中。 Then run the child script on remote server and show the output back in local terminal. 然后在远程服务器上运行子脚本,并在本地终端中显示输出。 However I am not seeing any output. 但是我没有看到任何输出。 Here are my script: 这是我的脚本:

Parent script "server.py": 父脚本“ 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 script called "whichserver.py" is: 我的孩子脚本称为“ whichserver.py”是:

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

Output: 输出:

['\n']

Expected Output: 预期产量:

ZT Systems

Can you please suggest why I am only getting newline character ? 你能建议我为什么只换行符吗? Is there a way to store the value "ZT Systems" in a variable in localhost after getting output from remote server ? 从远程服务器获取输出后,是否可以将值“ ZT Systems”存储在localhost中的变量中?

There are a few things going on here. 这里发生了一些事情。

  1. You should use ssh.communicate() instead of ssh.stdout or ssh.stderr unless you have no choice. 除非ssh.stderr否则应使用ssh.communicate()代替ssh.stdoutssh.stderr This avoids blocking (potentially blocking forever because you're waiting on the wrong pipe). 这样可以避免阻塞(有可能永远阻塞,因为您正在等待错误的管道)。

  2. You should check the output status of your subprocess. 您应该检查子流程的输出状态。 Instead, you just check if it produces output. 相反,您只需检查它是否产生输出。 But it should produce output, even if it fails, because of the echo statement. 但是由于echo语句,即使失败,它也应该产生输出。 So the test for success and failure doesn't work. 因此,对成功和失败的测试不起作用。

  3. That shell script is a bit of a mess. 该shell脚本有点混乱。 It won't handle errors, it puts newlines in funny places. 它不会处理错误,它会将换行符放在有趣的地方。 There's a $server variable that serves no purpose (well, other than stripping whitespace). 有一个$server变量没有任何作用(好吧,除了去除空格)。

Here is a fixed shell script for you: 这是给您的固定外壳脚本:

#!/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/[^:]*: *//'

However, this isn't really necessary. 但是,这并不是必须的。 Instead of uploading a script with scp and executing it with ssh , we can just execute the script directly with ssh . 无需使用scp上传脚本并使用ssh执行脚本,我们只需使用ssh直接执行脚本即可。 This saves us some steps. 这为我们节省了一些步骤。

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())

Also note that sudo may require a tty. 另请注意, sudo可能需要tty。 You can configure it to not require a tty, or you can use ssh -t , which makes ssh provide a tty. 您可以将其配置为不需要tty,也可以使用ssh -t ,这使ssh提供了tty。 Both choices have drawbacks. 两种选择都有缺点。

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

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