when my python script uses a file for an argparse "args" my "if" statment is passed by

StackOverflow https://stackoverflow.com/questions/21103571

  •  27-09-2022
  •  | 
  •  

Question

When I use --host=192.168.1.1 as an argument, this script works like a charm. When I use --host_file=asa.hosts, it fails because it seems to not be matching the "if hfile is True:". So this is obviously wrong. What would be a better term to match my --host_file=NAME.TXT

This is my error

Traceback (most recent call last):
 File "asaos-snmpv3-tool-hostfile.py", line 147, in <module>
  main()
   File "asaos-snmpv3-tool-hostfile.py", line 138, in main
   child = connect(user, host, passwd, en_passwd)
   File "asaos-snmpv3-tool-hostfile.py", line 47, in connect
   constr = 'ssh ' + user + '@' + host
  TypeError: cannot concatenate 'str' and 'NoneType' objects

If it was failing, I would have expected it to error using "child = connects(user, hosts, passwd, en_passwd)" If you look close, youll see that under my "if" I use connects, and hosts (plural), but it looks like its trying to parse the file under the main connect, and host.

def connect(user, host, passwd, en_passwd):
  ...output cut short

def connects(user, hosts, passwd, en_passwd):
  ...output cut short

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='hfile', type=str, help='specify a target host file')

host = args.host
hfile = args.hfile
hosts = open(hfile, 'r')

for line in hosts.readlines():

    if hfile is True:
        hosts = line.strip('r').strip('\n')
        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)
        exit()
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)
exit()

Thanks much for any help!

Was it helpful?

Solution

First, your hfile is either going to be a string, or None. Neither of those is True. Neither of those is even == True.

A non-empty string is truthy. None is not. Neither is a non-empty string. So, if you want to treat an empty string (e.g., --host-file='') the same as no argument, just test hfile for truthiness:

if hfile:

If, on the other hand, you want to treat an empty string as a valid argument, test for None-ness:

if hfile is not None:

The reason you don't have this problem for --host is simple: You don't test host anywhere, so there's nowhere to get the test wrong.


However, maybe you should be testing host for None. I'm not sure what you actually want to do in that case, but you definitely don't want to call connect(user, host, passwd, en_passwd) with None for the host. That's why you're getting the exception, because the library is trying to concatenate all those strings together, and one of them isn't a string.


If it was failing, I would have expected it to error using "child = connects(user, hosts, passwd, en_passwd)" If you look close, youll see that under my "if" I use connects, and hosts (plural), but it looks like its trying to parse the file under the main connect, and host.

But your if never triggers, so it doesn't matter what you do in that block. On the other hand the connect always runs, so that's what fails.


Finally, your logic makes no sense in the first place.

You go through the hosts file. For each line, you check hfile. If it's truthy, you will do a single connect and then exit. If it's not truthy, it will never become truthy, so you'll skip over all of the other lines as well. So, there is no way you could ever process any line beyond the first.

Also, inside that loop, you replace hosts with each line.

Also, you're stripping r instead of \r, and you're stripping it before \n, which means there would never be anything to strip even if you got it right.

And finally, you've got all that top-level code that comes after the main definition, and tries to use main's local variables, and never even calls main. I suspect you may be mixing tabs and spaces, so what ends up pasted here doesn't match what you have in your original script; if so, it's almost guaranteed to cause problems that are hard to debug if you're lucky (and get an IndentationError) and nearly impossible if you're not (and just have the wrong flow control). Find a text editor that automatically turns tabs into spaces and/or shows tabs visually (almost anything but Notepad and TextEdit will do…), and test your scripts with the -tt flag just in case it slips past the editor.

Anyway, maybe you wanted something like this, but I'm really just guessing here.

OTHER TIPS

The error is caused either user or host arguments to connect being None.

I do not see where you set user.

It looks like the host argument to connect comes from args.host. If you have not given it a --host argument, the value of this will be the default None.

When debugging code using argparse I often print args just to make sure it is parsing the input as I expected.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top