【问题标题】:TypeError: coercing to Unicode: need string or buffer, file foundTypeError:强制转换为 Unicode:需要字符串或缓冲区,找到文件
【发布时间】:2014-01-15 00:29:24
【问题描述】:

我收到缓冲区错误,但我在第 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()

【问题讨论】:

  • 哪一行?请显示完整的回溯和相关功能。
  • Traceback(最近一次调用最后):文件“asaos-snmpv3-tool.py”,第 145 行,在 main() 文件“asaos-snmpv3-tool.py”,第 124 行, 在 main with open(hosts, mode='r', buffering=-1): TypeError: coercing to Unicode: need string or buffer, file found
  • 另外,在你的所有问题中,你一直说所有其他部分都工作正常,但这绝不是真的。例如,如果我用--host=a.b.c 运行它,我会得到一个TypeError 来连接strNone(因为你将--user 设为可选,默认值为None,但随后盲目地将它连接成一个字符串)。请不要再假装每个新错误都是您的代码唯一的错误。
  • 或者,最好不要发布整个程序;发布Minimal, Complete, Valid Example,说明您遇到的问题,并且没有任何不相关的内容。
  • 最后一件事:不要在 hostshost_file 案例之间以及 connectconnects 函数之间复制和粘贴所有代码,而是重构事物,因此您只需要写一次。例如,如所写,connectconnects 之间的唯一区别是第二个参数的名称和使用该参数的一行代码。所以他们做同样的事情。这是故意的吗?如果是这样,为什么有两个不同的功能?如果没有,您将如何记住它们是如何应该与那一堆乱七八糟的copypasta不同的?

标签: python unicode


【解决方案1】:

这里有一系列问题:

if hosts:
    with open(hosts, mode='r', buffering=1):

这里,hosts 显然是一个文件名。你打开那​​个文件……然后不要将它存储在任何地方的变量中,然后继续使用文件名,就像它是一个文件一样。

但是,在你到达那里之前,hosts 实际上不是一个文件名。 argparse 的一个漂亮功能是它可以自动为您打开文件,而您要求它通过在参数规范中使用 type=file 来做到这一点。这意味着 hosts 实际上是一个文件对象,而您正在尝试将该文件对象本身用作文件名!这实际上是导致 TypeError: coercing to Unicode: need string or buffer, file found: open 尝试将文件名转换为 Unicode 字符串的原因,它不知道如何使用文件对象来做到这一点。如果你想open 主机,不要告诉 argparse 为你做;只需将其类型保留为str

        for line in hosts:

由于hosts 应该是一个文件名,作为一个字符串,这会给你文件名中的每个字符,作为一个字符串。哪个没用。

            hosts = line.rstrip

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

            child = connects(user, hosts, passwd, en_passwd)

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

不要一遍又一遍地使用相同的变量名来表示不同的东西。为每件事使用不同的名称。理想情况下,它的名字在某种程度上与它所持有的东西有关。例如,名为 hosts 的文件中的 ech(已剥离)行可能是 host,或 hosts_entry……它不是的一件事是你的全部 hosts

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

if hosts:
    for line in hosts:
        host = line.rstrip()
        child = connects(user, host, passwd, en_passwd)

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

parser.add_argument('--host_file', dest='hosts', type=str, help='specify a target host file')

# …

if hosts:
    with open(hosts, buffering=1) as hosts_file:
        for line in hosts_file:
            host = line.rstrip()
            child = connects(user, host, passwd, en_passwd)

【讨论】:

  • 感谢您的帮助。由于其他示例,我只使用“缓冲”。如您所见,我不是开发人员,但我正在尝试。当我使用你的第一个例子时,(没有 open(hosts...))我现在得到这个 errot.TypeError: cannot concatenate 'str' and 'builtin_function_or_method' objects
  • @insecure-IT:我和至少另外两个人已经多次向你解释过发布一个没有回溯的异常,尤其是没有任何迹象表明它来自哪一行代码,完全没用。请停止这样做。
  • @insecure-IT:但我的第一个猜测是您没有复制我的代码,而是更改了代码以匹配您碰巧注意到的任何差异,并且没有注意到括号line.rstrip()。如果是这样,您最终将尝试使用绑定方法line.rstrip 而不是剥离的字符串。如果是这样的话,我已经在答案中解释过了。我怀疑您实际上并没有阅读答案,因为例如,我在您的上一个问题中解释了 with open(…) as f: 的事情,但这次您离开了 as f
  • Sorry.Traceback(最近一次调用最后):文件“asaos-snmpv3-tool.py”,第 121 行,在 main() 文件“asaos-snmpv3-tool.py”中,第 103 行,在 main child = connect(user, host, passwd, en_passwd) 文件“asaos-snmpv3-tool.py”,第 47 行,在 connect constr = 'ssh' + user + '@' + host TypeError: cannot concatenate 'str' 和 'builtin_function_or_method' 对象
  • @insecure-IT:好的,该代码甚至不是来自--host_file 案例,它来自--host 案例。因此,它与您在此问题中询问的代码完全无关;相反,它是您所说的“有效”的代码。我不会一一调试你所有的问题。如果您需要开发代码,并且不愿意学习开发代码,则需要聘请开发人员。
【解决方案2】:

看起来就像你在这里迭代错误的东西:

with open(hosts, mode='r', buffering=1):
    for line in hosts:
        hosts = line.rstrip

你可能想要这个:

with open(hosts, mode='r', buffering=1) as lines:
    for line in lines:
        host = line.rstrip

【讨论】:

    猜你喜欢
    • 2016-05-02
    • 1970-01-01
    • 2021-03-28
    • 2015-02-01
    • 2014-12-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多