1

ちょっとした背景として、いくつかのリモート サーバーに SSH で接続し、公開鍵をそれらのサーバーにコピーするスクリプトを作成しています。外部の python モジュールをインストールできないため、custon ssh クライアントの作成に着手しました。簡単に言えば、私が働いている会社は、それが標準の 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: pidandfはこの関数スコープで定義されていません -> これはあなたの問題です。

106:portnumこのスコープでは不明です

コード検証で適切なIDEを使用できますか? それに切り替えます。それ以外の場合は、必要最小限の vi 静的ソースチェッカーを使用してください。

Paul Mikesell のコード スニペットを見ると、sshconnect91 行目の関数は必要ないと思いsshclient.pushますsshpush

于 2013-02-08T21:12:59.943 に答える