1

只是一点背景知识,我正在编写一个脚本来 ssh 到几个远程服务器并将我的公钥复制到它们。我开始编写一个 custon ssh 客户端,因为我无法安装任何外部 python 模块。长话短说,我工作的公司说,如果它不是标准 python 库的一部分,你就不能使用它。

经过数周的搜索,我找到了一个我认为是我所有祈祷的答案的脚本。我已经对其进行了修改以满足我的需要,但我遇到了一个未找到变量的错误,我需要一些指导来解决这个问题。

这是脚本:

#!/usr/bin/python

import pty, re, os, sys, stat, socket
from getpass import getpass

class ssherror(Exception):
    def __init__(self, value):
        self.value = value
    def __str__(self):
        return repr(self.value)

class sshclient:
    def __init__(self, ip, passwd, user, port):
        self.ip = ip
        self.passwd = passwd
        self.user = user
        self.port = port

    def runcmd(self, c):
        (pid, f) = pyt.fork()
        if pid == 0:
            os.execlp("ssh", "ssh", '-p %d' % self.port, self.user + '@' + self.ip, c)
        else:
        return (pid, f)

    def pushfile(self, src, dst):
        (pid, f) = pty.fork()
        if pid == 0:
            os.execlp("scp", "scp", '-P %d' % self.port, src, self.user + '@' + self.ip + ':' + dst)
        else:
            return (pid, f)

    def pushdir(self, src, dst):
        (pid, f) = pty.fork()
        if pid == 0:
            os.execlp("scp", "scp", '-P %d' % self.port, "-r", src, self.user + '@' + self.ip + ':' + dst)
        else:
            return (pid, f)

    def _read(self, f):
        x = ''
        try:
            x = os.read(f, 1024)
        except Exception, e:
            pass
        return x

    def connect(self, pid, f):
        output = ''
        got = self._read(f)
        m = re.search('authenticity of host', got)
        if m:
            os.write(f, 'yes\n')
            while True:
                got = self._read(f)
                m = re.search('Permanently added', got)
                if m:
                    break

            got = self._read(f)
        m = re.search('assword:', got)
        if m:
            os.write(f, self.passwd + '\n')
            tmp = self._read(f)
            tmp += self._read(f)
            m = re.search('Permission denied', tmp)
            if m:
                raise Exception('Invalid passwd')
            got = tmp
        while got and len(got) > 0:
            output += got
            got = self._read(f)
        os.waitpid(pid, 0)
        os.close(f)
        return output

    def cmd(self, c):
        (pid, f) = self.runcmd(c)
        return self.connect(pid, f)

    def push(self, src, dst):
        s = os.stat(src)
        if stat.S_ISDIR(s[stat.ST_MODE]):
            (pid, f) = self.pushdir(src, dst)
        else:
            (pid, f) = self.pushfile(src, dst)
        return self.connect(pid, f)



def sshconnect(ip, passwd, user, port=22):
    s = sshclient(ip, passwd, user, port)
    return s.connect(pid, f)


def sshpush(ip, passwd, src, dst, user, port=22):
    s = sshclient(ip, passwd, user, port)
    return s.push(src, dst)



passwd = getpass()
src = '/path/to/dir/being/copied'
dst = '/path/to/destination/directory'
user = os.getlogin()
port = portnum
hosts = ['host1', 'host2', 'host3']
for host in hosts:
    try:
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    except socket.error, msg:
        print 'Failed to create socket. Error code: ' + str(msg[0]) + ' , Error message : ' + msg[1]
        sys.exit()

    print 'Socket Created'
    try:
        ip = socket.gethostbyname(host)
    except socket.gaierror:
        print 'Hostname could not be resolved. Exiting...'
        sys.exit()

    print 'Ip address of ' + host + ' is ' + ip
    sshconnect(ip, passwd, user, port)
    sshpush(ip, passwd, src, dst, user, port=22)
    print 'ssh directory copied to ' + host

我已经对其进行了很多更改,但仍然出现以下错误:

Traceback (most recent call last):
  File "ssh.py", line 129, in <module>
    sshconnect(ip, passwd, user, port)
  File "ssh.py", line 99, in sshconnect
    return s.connect(pid, f)
NameError: global name 'pid' is not defined

我知道我需要定义 pid,但我在最好的方法上画了一个空白。任何帮助、建议、Advil 将不胜感激!!!

4

1 回答 1

1

线上错别字:

20:((pid, f) = pyt.fork()应该是pty)

24:之后没有else:

93:pid并且f没有在这个函数范围内定义 -> 这是你的问题。

106:portnum在这个范围内未知

它们是否允许您使用适当的IDE 进行代码验证?切换到它。否则,如果您喜欢准系统 vi,请使用静态源检查器

查看 Paul Mikesell 的代码片段,我认为您不需要sshconnect第 91 行的函数。只需sshclient.push像在下一个函数 ( sshpush) 中所做的那样调用它,它就会自行连接。

于 2013-02-08T21:12:59.943 回答