TypeError: coercing to Unicode: need string or buffer, file found
python, unicode
Solution
There are a whole series of problems here:
if hosts:
with open(hosts, mode='r', buffering=1):
Here, `hosts` is clearly meant to be a filename. You open that file… and then don't store it in a variable anywhere, and go on to use the filename as if it were a file.
But, before you even get there, `hosts` is not actually a filename. One of the nifty features of `argparse` is that it can automatically open files for you, and you're asking it to do that by using `type=file` in the argument spec. Which means that `hosts` is actually a file object, and you're trying to use that file object itself as a filename! Which is what' actually causing the `TypeError: coercing to Unicode: need string or buffer, file found`: `open` tries to convert filenames to Unicode strings, and it has no idea how to do that with a file object. If you want to `open` hosts, don't tell argparse to do it for you; just leave its type as a `str`.
for line in hosts:
Since `hosts` is supposed to be a filename, as a string, this will give you each character in the filename, as a string. Which is not useful.
hosts = line.rstrip
This overwrites the `hosts` variable, which you need. And, even worse, it overwrites it with the bound method `line.rstrip`, rather than the result of calling `line.rstrip`.
child = connects(user, hosts, passwd, en_passwd)
And here, you're passing that bound method to a function that wants a string, which isn't going to work.
Don't keep using the same variable name over and over to mean different things. Use a different name for each thing. Ideally one whose name relates in some way to the thing it's holding. For example, a ech (stripped) line in a file named `hosts` is probably a `host`, or a `hosts_entry`… one thing it's not is all of your `hosts`.
Anyway, to fix all of these problems:
if hosts:
for line in hosts:
host = line.rstrip()
child = connects(user, host, passwd, en_passwd)
Or, if you want to control how `hosts` is being opened (I'm not sure why you think it's important to specify `buffering=1`, but presumably you have some reason?):
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)
Problem
I'm getting a buffer error, but I have a line buffer in the 'with open()' block at line 123. Is this the correct location for the buffer? Should I have something in the connects class too/instead, or the parser argument maybe. I'm trying to use a file with addresses or hostnames using a '--host_file' argument to run the SNMP commands on multiple ASA's. It works using the '--host' argument just fine. Any help provided would be greatly appreceated. ``` 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() ```