Search code examples
pythonpopennameerror

NameError: global name 'interfaceName' is not defined even though it is


def putCardMon():
    interfaceName = input(('Type an interface name to put in monitor mode: '))
    print(colored('[+] ', 'green') + 'Trying to put the interface ' + colored(interfaceName, 'yellow') + ' in monitor mode\n')
    call(["sudo ifconfig " + interfaceName + " down; sudo iwconfig " + interfaceName + " mode monitor; sudo ifconfig " + interfaceName + " up"], shell=True)
    interfaceMonCheck = Popen(["iwconfig " + interfaceName + " | grep Mode | cut -d ':' -f2 | cut -d ' ' -f1"], shell=True, stdout=PIPE, universal_newlines=True).communicate()[0].rstrip()
    sleep (1)

---//lots of code before the putCardMon is called//---

interfacesList = Popen("ifconfig -a | grep Link | cut -d ' ' -f1", shell=True, stdout=PIPE, universal_newlines=True).communicate()[0].rstrip()
print('The available interfaces are:\n' + interfacesList + '\n')
putCardMon()
print('Checking if ' + interfaceName + ' is really in monitor mode.')
if interfaceMonCheck == 'Managed':
    print('The interface ' + colored(interfaceName, "green") + ' is not in monitor mode! Check if you typed the interface name correctly or contact support.\n')
    putCardMon()
elif interfaceMonCheck == 'Monitor':
    print(colored('The interface ' + colored(interfaceName, "green") + ' is in monitor mode!'))
    pass
else:
    print(colored('There was an unexpected error. Contact support!\n', "red"))
    exit()

The script works fine, the function does its job, but then when it gets to the checking part everything goes downhill.

Traceback (most recent call last):
  File "script.py", line 76, in <module>
    print('Checking if ' + interfaceName + ' is really in monitor mode.')
NameError: name 'interfaceName' is not defined

How come interfaceName is not defined if the function that assigns a string to it has already been called and successfully assigned a value to it?

I searched stack overflow for the same error, but all the threads were answered and it was either an indentation error or the function was defined after being invoked, which neither is the case here. I'm really out of options. I tried everything.


Solution

  • From https://python-textbok.readthedocs.io/en/1.0/Variables_and_Scope.html#variable-scope-and-lifetime

    A variable which is defined inside a function is local to that function. It is accessible from the point at which it is defined until the end of the function

    Your variable interfaceName is only defined inside the scope of your function putCardMon(). It ceases to exist outside the scope of the function. Hence you are getting the error.

    If you want to use the variable outside the function body, consider returning it and saving its value.

    def putCardMon():
        interfaceName = input(('Type an interface name to put in monitor mode: '))
        print(colored('[+] ', 'green') + 'Trying to put the interface ' + colored(interfaceName, 'yellow') + ' in monitor mode\n')
        call(["sudo ifconfig " + interfaceName + " down; sudo iwconfig " + interfaceName + " mode monitor; sudo ifconfig " + interfaceName + " up"], shell=True)
        interfaceMonCheck = Popen(["iwconfig " + interfaceName + " | grep Mode | cut -d ':' -f2 | cut -d ' ' -f1"], shell=True, stdout=PIPE, universal_newlines=True).communicate()[0].rstrip()
        sleep (1)
        return interfaceName
    
    # Later you can do this
    interfaceName = putCardMon()