类型错误:强制转换为 Unicode:需要字符串或缓冲区,已找到文件

ins*_*-IT 4 python unicode

我收到缓冲区错误,但我在第 123 行的“with open()”块中有一个行缓冲区。这是缓冲区的正确位置吗?我是否应该在连接类中也有一些东西/相反,或者可能是解析器参数。

我尝试使用带有“--host_file”参数的地址或主机名文件在多个 ASA 上运行 SNMP 命令。使用“--host”参数就可以了。

提供的任何帮助将不胜感激。

Traceback (most recent call last):
  File "asaos-snmpv3-tool.py", line 145, in <module>
    main()
  File "asaos-snmpv3-tool.py", line 124, in main
    with open(hosts, mode='r', buffering=-1):
TypeError: coercing to Unicode: need string or buffer, file found

import pexpect
import argparse

PROMPT = ['# ', '>>> ', '>', '\$ ']
SNMPGROUPCMD = ' snmp-server group '
V3PRIVCMD = ' v3 priv '
SNMPSRVUSRCMD = ' snmp-server user '
V3AUTHCMD = ' v3 auth '
PRIVCMD = ' priv '
SNMPSRVHOSTCMD = ' snmp-server host '
VERSION3CMD = ' version 3 '
SHAHMACCMD = ' sha '
SNMPSRVENTRAP = ' snmp-server enable traps all '
WRME = ' write memory '

def send_command(child, cmd):
    child.sendline(cmd)
    child.expect(PROMPT)
    print child.before

def connect(user, host, passwd, en_passwd):
    ssh_newkey = 'Are you sure you want to continue connecting?'
    constr = 'ssh ' + user + '@' + host
    child = pexpect.spawn(constr)
    ret = child.expect([pexpect.TIMEOUT, ssh_newkey, '[P|p]assword:'])

    if ret == 0:
        print '[-] Error Connecting'
        return
    if ret == 1:
        child.sendline('yes')
        ret = child.expect([pexpect.TIMEOUT, '[P|p]assword:'])
        if ret == 0:
            print '[-] Error Connecting'
            return
    child.sendline(passwd)
    child.expect(PROMPT)
    child.sendline('enable')
    child.sendline(en_passwd)
    child.expect(PROMPT)
    child.sendline('config t')
    child.expect(PROMPT)
    return child

def connects(user, hosts, passwd, en_passwd):
    ssh_newkey = 'Are you sure you want to continue connecting?'
    constr = 'ssh ' + user + '@' + hosts
    child = pexpect.spawn(constr)
    ret = child.expect([pexpect.TIMEOUT, ssh_newkey, '[P|p]assword:'])

    if ret == 0:
        print '[-] Error Connecting'
        return
    if ret == 1:
        child.sendline('yes')
        ret = child.expect([pexpect.TIMEOUT, '[P|p]assword:'])
        if ret == 0:
            print '[-] Error Connecting'
            return
    child.sendline(passwd)
    child.expect(PROMPT)
    child.sendline('enable')
    child.sendline(en_passwd)
    child.expect(PROMPT)
    child.sendline('config t')
    child.expect(PROMPT)
    return child

def main():
    parser = argparse.ArgumentParser('usage %prog ' + '--host --host_file --username --password--enable --group --snmp_user --snmp_host --int_name --snmp_v3_auth --snmp_v3_hmac --snmp_v3_priv --snmp_v3_encr')
    parser.add_argument('--host', dest='host', type=str, help='specify a target host')
    parser.add_argument('--host_file', dest='hosts', type=file, help='specify a target host file')
    parser.add_argument('--username', dest='user', type=str, help='specify a user name')
    parser.add_argument('--password', dest='passwd', type=str, help='specify a passwd')
    parser.add_argument('--enable', dest='en_passwd', type=str, help='specify an enable passwd')
    parser.add_argument('--group', dest='group', type=str, help='specify an snmp group')
    parser.add_argument('--snmp_user', dest='snmpuser', type=str, help='specify an snmp user')
    parser.add_argument('--snmp_host', dest='snmphost', type=str, help='specify an snmp server host')
    parser.add_argument('--int_name', dest='intname', type=str, help='specify interface name')
    parser.add_argument('--snmp_v3_auth', dest='snmpauth', type=str, help='specify the snmp user authentication')
    parser.add_argument('--snmp_v3_hmac', dest='snmphmac', type=str, help='set snmp HMAC, md5 or sha')
    parser.add_argument('--snmp_v3_priv', dest='snmppriv', type=str, help='specify the snmp priv password')
    parser.add_argument('--snmp_v3_encr', dest='snmpencrypt', type=str, help='specify encryption, des, 3des, or aes(128/192/256)')

    args = parser.parse_args()
    host = args.host
    hosts = args.hosts
    user = args.user
    passwd = args.passwd
    en_passwd = args.en_passwd
    group = args.group
    snmpuser = args.snmpuser
    snmphost = args.snmphost
    intname = args.intname
    snmpauth = args.snmpauth
    snmppriv = args.snmppriv
    snmpencrypt = args.snmpencrypt

    if hosts:
        with open(hosts, mode='r', buffering=1):
            for line in hosts:
                hosts = line.rstrip
                child = connects(user, hosts, passwd, en_passwd)
                send_command(child, SNMPGROUPCMD + group + V3PRIVCMD)
                send_command(child, SNMPSRVUSRCMD + snmpuser + ' ' + group + V3AUTHCMD + SHAHMACCMD + snmpauth + PRIVCMD + snmpencrypt + ' ' + snmppriv)
                send_command(child, SNMPSRVHOSTCMD + intname + ' ' + snmphost + VERSION3CMD + snmpuser)
                send_command(child, SNMPSRVENTRAP)
                send_command(child, WRME)

    elif host:
        child = connect(user, host, passwd, en_passwd)
        send_command(child, SNMPGROUPCMD + group + V3PRIVCMD)
        send_command(child, SNMPSRVUSRCMD + snmpuser + ' ' + group + V3AUTHCMD + SHAHMACCMD + snmpauth + PRIVCMD + snmpencrypt + ' ' + snmppriv)
        send_command(child, SNMPSRVHOSTCMD + intname + ' ' + snmphost + VERSION3CMD + snmpuser)
        send_command(child, SNMPSRVENTRAP)
        send_command(child, WRME)
    else:
        print ('Specify either --host or --host_file or I have nothing to do')

if __name__ == '__main__':
    main()
Run Code Online (Sandbox Code Playgroud)

aba*_*ert 6

这里有一系列的问题:

\n\n
if hosts:\n    with open(hosts, mode='r', buffering=1):\n
Run Code Online (Sandbox Code Playgroud)\n\n

在这里,hosts显然是一个文件名。您打开该文件\xe2\x80\xa6\xc2\xa0,然后不要将其存储在任何地方的变量中,并继续使用该文件名,就好像它是一个文件一样。

\n\n

但是,在您到达那里之前,它实际上hosts并不是一个文件名。它的一个很棒的功能是它可以自动为您打开文件,并且您可以通过在参数规范中使用来要求它这样做。这意味着这实际上是一个文件对象,并且您正在尝试使用该文件对象本身作为文件名!这就是实际导致:尝试将文件名转换为 Unicode 字符串的原因,但它不知道如何使用文件对象来执行此操作。如果你想托管,不要告诉 argparse 为你做;只需将其类型保留为 a 。argparsetype=filehostsTypeError: coercing to Unicode: need string or buffer, file foundopenopenstr

\n\n
        for line in hosts:\n
Run Code Online (Sandbox Code Playgroud)\n\n

由于hosts应该是一个文件名,作为一个字符串,这将为您提供文件名中的每个字符,作为一个字符串。这是没有用的。

\n\n
            hosts = line.rstrip\n
Run Code Online (Sandbox Code Playgroud)\n\n

这会覆盖hosts您需要的变量。而且,更糟糕的是,它用绑定的方法覆盖它line.rstrip,而不是调用的结果line.rstrip

\n\n
            child = connects(user, hosts, passwd, en_passwd)\n
Run Code Online (Sandbox Code Playgroud)\n\n

在这里,您将该绑定方法传递给需要字符串的函数,这是行不通的。

\n\n

不要一遍又一遍地使用相同的变量名来表示不同的含义。为每件事使用不同的名称。理想情况下,其名称在某种程度上与其所持有的物品相关。例如,名为 的文件中的 ech(剥离)行hosts可能是host, 或hosts_entry\xe2\x80\xa6 ,但它不是的全部hosts.

\n\n

无论如何,要解决所有这些问题:

\n\n
if hosts:\n    for line in hosts:\n        host = line.rstrip()\n        child = connects(user, host, passwd, en_passwd)\n
Run Code Online (Sandbox Code Playgroud)\n\n

或者,如果您想控制hosts打开方式(我不确定您为什么认为指定 很重要buffering=1,但大概您有某种原因?):

\n\n
parser.add_argument('--host_file', dest='hosts', type=str, help='specify a target host file')\n\n# \xe2\x80\xa6\n\nif hosts:\n    with open(hosts, buffering=1) as hosts_file:\n        for line in hosts_file:\n            host = line.rstrip()\n            child = connects(user, host, passwd, en_passwd)\n
Run Code Online (Sandbox Code Playgroud)\n