From d9330ef698c34bae3a3587433363ac17aa9f132b Mon Sep 17 00:00:00 2001 From: deix Date: Mon, 28 Aug 2017 17:20:38 +0200 Subject: [PATCH 1/7] Use the "with" keyword when dealing with file objects It is good practice to use the "with" keyword when dealing with file objects. This has the advantage that the file is properly closed after its suite finishes, even if an exception is raised on the way. It is also much shorter than writing equivalent try-finally blocks --- Wifite.py | 5 ++--- py/Aircrack.py | 6 ++---- py/Aireplay.py | 13 +++++-------- py/AttackWPA.py | 5 ++--- py/CrackResult.py | 10 ++++------ py/Reaver.py | 11 ++++------- 6 files changed, 19 insertions(+), 31 deletions(-) diff --git a/Wifite.py b/Wifite.py index c9cf2e9..49f6a83 100755 --- a/Wifite.py +++ b/Wifite.py @@ -45,9 +45,8 @@ class Wifite(object): if not os.path.exists(name): Color.pl('{!} {O}file {C}%s{O} not found{W}' % name) return - f = open(name, 'r') - json = loads(f.read()) - f.close() + with open(name, 'r') as fid: + json = loads(fid.read()) for (index, item) in enumerate(json): Color.pl('\n{+} Cracked target #%d:' % (index + 1)) cr = CrackResult.load(item) diff --git a/py/Aircrack.py b/py/Aircrack.py index aedcca9..f4b78c8 100644 --- a/py/Aircrack.py +++ b/py/Aircrack.py @@ -39,10 +39,8 @@ class Aircrack(object): def get_key_hex_ascii(self): if not self.is_cracked(): raise Exception('Cracked file not found') - f = open(self.cracked_file, 'r') - hex_raw = f.read() - f.close() - + with open(self.cracked_file, 'r') as fid: + hex_raw = fid.read() hex_key = '' ascii_key = '' while len(hex_raw) > 0: diff --git a/py/Aireplay.py b/py/Aireplay.py index 5249254..7ad8d2f 100644 --- a/py/Aireplay.py +++ b/py/Aireplay.py @@ -96,14 +96,11 @@ class Aireplay(Thread): while self.pid.poll() is None: time.sleep(0.1) if not os.path.exists(self.output_file): continue - # Read output file - f = open(self.output_file, "r") - lines = f.read() - f.close() - # Clear output file - f = open(self.output_file, "w") - f.write("") - f.close() + # Read output file & clear output file + with open(self.output_file, "r+") as fid: + lines = fid.read() + fid.seek(0) + fid.truncate() for line in lines.split("\n"): line = line.replace("\r", "").strip() if line == "": continue diff --git a/py/AttackWPA.py b/py/AttackWPA.py index fbbae6f..114b64d 100644 --- a/py/AttackWPA.py +++ b/py/AttackWPA.py @@ -189,9 +189,8 @@ class AttackWPA(Attack): Color.pl("") # Check crack result if os.path.exists(key_file): - f = open(key_file, "r") - key = f.read().strip() - f.close() + with open(key_file, "r") as fid: + key = fid.read().strip() os.remove(key_file) Color.pl("{+} {G}Cracked WPA Handshake{W} PSK: {G}%s{W}\n" % key) diff --git a/py/CrackResult.py b/py/CrackResult.py index 5a80d6d..0e8768c 100644 --- a/py/CrackResult.py +++ b/py/CrackResult.py @@ -27,17 +27,15 @@ class CrackResult(object): name = CrackResult.cracked_file json = [] if os.path.exists(name): - f = open(name, 'r') - text = f.read() - f.close() + with open(name, 'r') as fid: + text = fid.read() try: json = loads(text) except Exception, e: Color.pl('{!} error while loading %s: %s' % (name, str(e))) json.append(self.to_dict()) - f = open(name, 'w') - f.write(dumps(json, indent=2)) - f.close() + with open(name, 'w') as fid: + fid.write(dumps(json, indent=2)) Color.pl('{+} saved crack result to {C}%s{W} ({G}%d total{W})' % (name, len(json))) diff --git a/py/Reaver.py b/py/Reaver.py index 0b40c76..8cbb982 100644 --- a/py/Reaver.py +++ b/py/Reaver.py @@ -240,10 +240,8 @@ class Reaver(Attack): out = self.get_stdout() # Clear output file - f = open(self.stdout_file, 'w') - f.write('') - f.close() - + with open(self.stdout_file, 'w'): + pass # CHECK FOR CRACK (pin, psk, ssid) = Reaver.get_pin_psk_ssid(out) @@ -394,9 +392,8 @@ class Reaver(Attack): ''' Gets output from stdout_file ''' if not self.stdout_file: return '' - f = open(self.stdout_file, 'r') - stdout = f.read() - f.close() + with open(self.stdout_file, 'r') as fid: + stdout = fid.read() return stdout.strip() From 00e5246f96b95ff7a79e0d34e15aef001a06c963 Mon Sep 17 00:00:00 2001 From: deix Date: Mon, 28 Aug 2017 17:51:27 +0200 Subject: [PATCH 2/7] Comparisons to singletons like None should always be done with is or is not, never the equality operators. --- py/Aircrack.py | 6 +++--- py/Aireplay.py | 10 +++++----- py/Airmon.py | 2 +- py/Airodump.py | 8 ++++---- py/Attack.py | 2 +- py/Bully.py | 2 +- py/Configuration.py | 8 ++++---- py/Handshake.py | 4 ++-- py/Interface.py | 4 ++-- py/Process.py | 8 ++++---- py/Reaver.py | 4 ++-- py/Scanner.py | 4 ++-- 12 files changed, 31 insertions(+), 31 deletions(-) diff --git a/py/Aircrack.py b/py/Aircrack.py index f4b78c8..751b128 100644 --- a/py/Aircrack.py +++ b/py/Aircrack.py @@ -26,14 +26,14 @@ class Aircrack(object): def is_running(self): - return self.pid.poll() == None + return self.pid.poll() is None def is_cracked(self): return os.path.exists(self.cracked_file) def stop(self): ''' Stops aircrack process ''' - if self.pid.poll() == None: + if self.pid.poll() is None: self.pid.interrupt() def get_key_hex_ascii(self): @@ -56,7 +56,7 @@ class Aircrack(object): # Hex key is non-printable in ascii ascii_key = None continue - elif ascii_key == None: + elif ascii_key is None: # We can't generate an Ascii key continue # Convert decimal to char diff --git a/py/Aireplay.py b/py/Aireplay.py index 7ad8d2f..3d58fc8 100644 --- a/py/Aireplay.py +++ b/py/Aireplay.py @@ -81,11 +81,11 @@ class Aireplay(Thread): self.start() def is_running(self): - return self.pid.poll() == None + return self.pid.poll() is None def stop(self): ''' Stops aireplay process ''' - if hasattr(self, "pid") and self.pid and self.pid.poll() == None: + if hasattr(self, "pid") and self.pid and self.pid.poll() is None: self.pid.interrupt() def get_output(self): @@ -182,7 +182,7 @@ class Aireplay(Thread): # Interface is required at this point Configuration.initialize() - if Configuration.interface == None: + if Configuration.interface is None: raise Exception("Wireless interface must be defined (-i)") cmd = ["aireplay-ng"] @@ -259,7 +259,7 @@ class Aireplay(Thread): cmd.extend(["-h", client_mac]) elif attack_type == WEPAttackType.hirte: - if client_mac == None: + if client_mac is None: # Unable to carry out hirte attack raise Exception("Client is required for hirte attack") cmd.extend([ @@ -267,7 +267,7 @@ class Aireplay(Thread): "-h", client_mac ]) elif attack_type == WEPAttackType.forgedreplay: - if client_mac == None or replay_file == None: + if client_mac is None or replay_file is None: raise Exception("Client_mac and Replay_File are required for arp replay") cmd.extend([ "--arpreplay", diff --git a/py/Airmon.py b/py/Airmon.py index e9f211e..0e209f7 100644 --- a/py/Airmon.py +++ b/py/Airmon.py @@ -89,7 +89,7 @@ class Airmon(object): mon_iface = mon_iface.split(')')[0] break - if mon_iface == None: + if mon_iface is None: # Airmon did not enable monitor mode on an interface Color.pl("{R}failed{W}") diff --git a/py/Airodump.py b/py/Airodump.py index 3860c25..c42eef4 100644 --- a/py/Airodump.py +++ b/py/Airodump.py @@ -21,15 +21,15 @@ class Airodump(object): Configuration.initialize() - if interface == None: + if interface is None: interface = Configuration.interface - if interface == None: + if interface is None: raise Exception("Wireless interface must be defined (-i)") self.interface = interface self.targets = [] - if channel == None: + if channel is None: channel = Configuration.target_channel self.channel = channel self.five_ghz = Configuration.five_ghz @@ -133,7 +133,7 @@ class Airodump(object): # Found the file csv_filename = fil break - if csv_filename == None or not os.path.exists(csv_filename): + if csv_filename is None or not os.path.exists(csv_filename): # No file found return self.targets diff --git a/py/Attack.py b/py/Attack.py index c18aa16..9e0cc2e 100644 --- a/py/Attack.py +++ b/py/Attack.py @@ -39,7 +39,7 @@ class Attack(object): airodump_target = t break - if airodump_target == None: + if airodump_target is None: raise Exception( 'Could not find target (%s) in airodump' % self.target.bssid) diff --git a/py/Bully.py b/py/Bully.py index dc343fe..c860b7e 100644 --- a/py/Bully.py +++ b/py/Bully.py @@ -206,7 +206,7 @@ class Bully(Attack): return False def stop(self): - if hasattr(self, "pid") and self.pid and self.pid.poll() == None: + if hasattr(self, "pid") and self.pid and self.pid.poll() is None: self.pid.interrupt() def __del__(self): diff --git a/py/Configuration.py b/py/Configuration.py index 2f47abc..c62abc7 100644 --- a/py/Configuration.py +++ b/py/Configuration.py @@ -100,7 +100,7 @@ class Configuration(object): @staticmethod def get_interface(): - if Configuration.interface == None: + if Configuration.interface is None: # Interface wasn't defined, select it! from Airmon import Airmon Configuration.interface = Airmon.ask() @@ -273,7 +273,7 @@ class Configuration(object): @staticmethod def temp(subfile=''): ''' Creates and/or returns the temporary directory ''' - if Configuration.temp_dir == None: + if Configuration.temp_dir is None: Configuration.temp_dir = Configuration.create_temp() return Configuration.temp_dir + subfile @@ -289,7 +289,7 @@ class Configuration(object): @staticmethod def delete_temp(): ''' Remove temp files and folder ''' - if Configuration.temp_dir == None: return + if Configuration.temp_dir is None: return if os.path.exists(Configuration.temp_dir): for f in os.listdir(Configuration.temp_dir): os.remove(Configuration.temp_dir + f) @@ -323,7 +323,7 @@ class Configuration(object): for (key,val) in sorted(Configuration.__dict__.iteritems()): if key.startswith('__'): continue if type(val) == staticmethod: continue - if val == None: continue + if val is None: continue result += Color.s("{G}%s {W} {C}%s{W}\n" % (key.ljust(max_len),val)) return result diff --git a/py/Handshake.py b/py/Handshake.py index 0e27d83..78ce6a6 100644 --- a/py/Handshake.py +++ b/py/Handshake.py @@ -100,7 +100,7 @@ class Handshake(object): mac_regex = ('[a-zA-Z0-9]{2}:' * 6)[:-1] match = re.search('(%s) [^ ]* (%s).*.*SSID=(.*)$' % (mac_regex, mac_regex), line) - if match == None: + if match is None: # Line doesn't contain src, dst, ssid continue (src, dst, essid) = match.groups() @@ -139,7 +139,7 @@ class Handshake(object): mac_regex = ('[a-zA-Z0-9]{2}:' * 6)[:-1] match = re.search('(%s) (?:->|→) (%s).*Message.*(\d).*(\d)' % (mac_regex, mac_regex), line) - if match == None: + if match is None: # Line doesn't contain src, dst, Message numbers continue (src, dst, index, ttl) = match.groups() diff --git a/py/Interface.py b/py/Interface.py index 61c2725..b08b89a 100644 --- a/py/Interface.py +++ b/py/Interface.py @@ -82,10 +82,10 @@ class Interface(object): from Process import Process import re - if iface == None: + if iface is None: Configuration.initialize() iface = Configuration.interface - if iface == None: + if iface is None: raise Exception('Interface must be defined (-i)') output = Process(['ifconfig', iface]).stdout() diff --git a/py/Process.py b/py/Process.py index 503e0bd..d220826 100644 --- a/py/Process.py +++ b/py/Process.py @@ -85,7 +85,7 @@ class Process(object): Ran when object is GC'd. If process is still running at this point, it should die. ''' - if self.pid and self.pid.poll() == None: + if self.pid and self.pid.poll() is None: self.interrupt() def stdout(self): @@ -110,9 +110,9 @@ class Process(object): def get_output(self): ''' Waits for process to finish, sets stdout & stderr ''' - if self.pid.poll() == None: + if self.pid.poll() is None: self.pid.wait() - if self.out == None: + if self.out is None: (self.out, self.err) = self.pid.communicate() def poll(self): @@ -139,7 +139,7 @@ class Process(object): kill(pid, SIGINT) wait_time = 0 # Time since Interrupt was sent - while self.pid.poll() == None: + while self.pid.poll() is None: # Process is still running wait_time += 0.1 sleep(0.1) diff --git a/py/Reaver.py b/py/Reaver.py index 8cbb982..f73f560 100644 --- a/py/Reaver.py +++ b/py/Reaver.py @@ -96,7 +96,7 @@ class Reaver(Attack): (pin, psk, ssid) = self.get_pin_psk_ssid(stdout) # Check if we cracked it, or if process stopped. - if (pin and psk and ssid) or reaver.poll() != None: + if (pin and psk and ssid) or reaver.poll() is not None: reaver.interrupt() # Check one-last-time for PIN/PSK/SSID, in case of race condition. @@ -321,7 +321,7 @@ class Reaver(Attack): pin_current = 11000 - pins_left # Check if process is still running - if reaver.pid.poll() != None: + if reaver.pid.poll() is not None: Color.pl('{R}failed{W}') Color.pl('{!} {R}reaver{O} quit unexpectedly{W}') self.success = False diff --git a/py/Scanner.py b/py/Scanner.py index f24492a..288c9a6 100644 --- a/py/Scanner.py +++ b/py/Scanner.py @@ -30,7 +30,7 @@ class Scanner(object): # Loop until interrupted (Ctrl+C) while True: - if airodump.pid.poll() != None: + if airodump.pid.poll() is not None: # Airodump process died! raise Exception( "Airodump exited unexpectedly! " + @@ -76,7 +76,7 @@ class Scanner(object): bssid = Configuration.target_bssid essid = Configuration.target_essid - if bssid == None and essid == None: + if bssid is None and essid is None: return False for target in self.targets: From dbc0d995e316eec9a9834a5287d7254b32fdd670 Mon Sep 17 00:00:00 2001 From: deix Date: Mon, 28 Aug 2017 18:14:09 +0200 Subject: [PATCH 3/7] The start parameter for enumerate() Since python version 2.6 the start parameter was added and can be used --- Wifite.py | 8 ++++---- py/Airmon.py | 4 ++-- py/Airodump.py | 5 ++--- py/CrackHandshake.py | 4 ++-- py/Scanner.py | 5 ++--- 5 files changed, 12 insertions(+), 14 deletions(-) diff --git a/Wifite.py b/Wifite.py index 49f6a83..ec14a83 100755 --- a/Wifite.py +++ b/Wifite.py @@ -47,8 +47,8 @@ class Wifite(object): return with open(name, 'r') as fid: json = loads(fid.read()) - for (index, item) in enumerate(json): - Color.pl('\n{+} Cracked target #%d:' % (index + 1)) + for idx, item in enumerate(json, start=1): + Color.pl('\n{+} Cracked target #%d:' % (idx)) cr = CrackResult.load(item) cr.dump() @@ -88,11 +88,11 @@ class Wifite(object): attacked_targets = 0 targets_remaining = len(targets) - for index, t in enumerate(targets): + for idx, t in enumerate(targets, start=1): attacked_targets += 1 targets_remaining -= 1 - Color.pl('\n{+} ({G}%d{W}/{G}%d{W})' % (index + 1, len(targets)) + + Color.pl('\n{+} ({G}%d{W}/{G}%d{W})' % (idx, len(targets)) + ' starting attacks against {C}%s{W} ({C}%s{W})' % (t.bssid, t.essid if t.essid_known else "{O}ESSID unknown")) if 'WEP' in t.encryption: diff --git a/py/Airmon.py b/py/Airmon.py index 0e209f7..52595d2 100644 --- a/py/Airmon.py +++ b/py/Airmon.py @@ -24,8 +24,8 @@ class Airmon(object): def print_menu(self): ''' Prints menu ''' print Interface.menu_header() - for (index, iface) in enumerate(self.interfaces): - Color.pl(" {G}%d{W}. %s" % (index + 1, iface)) + for idx, iface in enumerate(self.interfaces, start=1): + Color.pl(" {G}%d{W}. %s" % (idx, iface)) def get(self, index): ''' Gets interface at index (starts at 1) ''' diff --git a/py/Airodump.py b/py/Airodump.py index c42eef4..0957774 100644 --- a/py/Airodump.py +++ b/py/Airodump.py @@ -298,9 +298,8 @@ if __name__ == '__main__': targets = airodump.get_targets() Target.print_header() - for (index, target) in enumerate(targets): - index += 1 - Color.pl(' {G}%s %s' % (str(index).rjust(3), target)) + for idx, target in enumerate(targets, start=1): + Color.pl(' {G}%s %s' % (str(idx).rjust(3), target)) Configuration.delete_temp() diff --git a/py/CrackHandshake.py b/py/CrackHandshake.py index 17a27d3..19dcae7 100644 --- a/py/CrackHandshake.py +++ b/py/CrackHandshake.py @@ -74,11 +74,11 @@ class CrackHandshake(object): Color.p(" " + ("-" * 17)) Color.p(" " + ("-" * 19) + "\n") # Print all handshakes - for index, hs in enumerate(handshakes): + for idx, hs in enumerate(handshakes, start=1): bssid = hs["bssid"] essid = hs["essid"] date = datetime.strftime(datetime.fromtimestamp(hs["date"]), "%Y-%m-%dT%H:%M:%S") - Color.p(" {G}%s{W}" % str(index + 1).rjust(3)) + Color.p(" {G}%s{W}" % str(idx).rjust(3)) Color.p(" {C}%s{W}" % essid.ljust(max_essid_len)) Color.p(" {C}%s{W}" % bssid) Color.p(" {C}%s{W}\n" % date) diff --git a/py/Scanner.py b/py/Scanner.py index 288c9a6..8ecd423 100644 --- a/py/Scanner.py +++ b/py/Scanner.py @@ -125,10 +125,9 @@ class Scanner(object): Color.p('\r') Target.print_header() - for (index, target) in enumerate(self.targets): - index += 1 + for idx, target in enumerate(self.targets, start=1): Color.clear_entire_line() - Color.pl(' {G}%s %s' % (str(index).rjust(3), target)) + Color.pl(' {G}%s %s' % (str(idx).rjust(3), target)) @staticmethod def get_terminal_height(): From 101332316a4370e55ec8b1310451bbf47e13a0a6 Mon Sep 17 00:00:00 2001 From: deix Date: Mon, 28 Aug 2017 18:37:12 +0200 Subject: [PATCH 4/7] Another comparisons to singletons... --- py/Aireplay.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/py/Aireplay.py b/py/Aireplay.py index 3d58fc8..74c97d0 100644 --- a/py/Aireplay.py +++ b/py/Aireplay.py @@ -28,9 +28,9 @@ class WEPAttackType(object): ''' self.value = None self.name = None - if type(var) == int: + if type(var) is int: for (name,value) in WEPAttackType.__dict__.iteritems(): - if type(value) == int: + if type(value) is int: if value == var: self.name = name self.value = value @@ -38,7 +38,7 @@ class WEPAttackType(object): raise Exception("Attack number %d not found" % var) elif type(var) == str: for (name,value) in WEPAttackType.__dict__.iteritems(): - if type(value) == int: + if type(value) is int: if name == var: self.name = name self.value = value From 383d09ff29556f2d039a396e2606c95b8757497d Mon Sep 17 00:00:00 2001 From: deix Date: Mon, 28 Aug 2017 19:13:04 +0200 Subject: [PATCH 5/7] Try to combine some if statements --- py/Airmon.py | 9 ++++----- py/Airodump.py | 4 +--- py/Configuration.py | 5 ++--- 3 files changed, 7 insertions(+), 11 deletions(-) diff --git a/py/Airmon.py b/py/Airmon.py index 52595d2..e22b753 100644 --- a/py/Airmon.py +++ b/py/Airmon.py @@ -44,9 +44,8 @@ class Airmon(object): p = Process('airmon-ng') for line in p.stdout().split('\n'): # Ignore blank/header lines - if len(line) == 0: continue - if line.startswith('Interface'): continue - if line.startswith('PHY'): continue + if len(line) == 0 or line.startswith('Interface') or line.startswith('PHY'): + continue # Strip out interface information fields = line.split("\t") @@ -242,8 +241,8 @@ class Airmon(object): if re.search('^ *PID', line): hit_pids = True continue - if not hit_pids: continue - if line.strip() == '': continue + if not hit_pids or line.strip() == '': + continue match = re.search('^[ \t]*(\d+)[ \t]*([a-zA-Z0-9_\-]+)[ \t]*$', line) if match: # Found process to kill diff --git a/py/Airodump.py b/py/Airodump.py index 0957774..c8814e7 100644 --- a/py/Airodump.py +++ b/py/Airodump.py @@ -120,9 +120,7 @@ class Airodump(object): # Remove .cap and .xor files from pwd for fil in os.listdir('.'): - if fil.startswith('replay_') and fil.endswith('.cap'): - os.remove(fil) - if fil.endswith('.xor'): + if fil.startswith('replay_') and fil.endswith('.cap') or fil.endswith('.xor'): os.remove(fil) def get_targets(self, apply_filter=True): diff --git a/py/Configuration.py b/py/Configuration.py index c62abc7..fc34585 100644 --- a/py/Configuration.py +++ b/py/Configuration.py @@ -321,9 +321,8 @@ class Configuration(object): result += Color.s('{W}%s------------------{W}\n' % ('-' * max_len)) for (key,val) in sorted(Configuration.__dict__.iteritems()): - if key.startswith('__'): continue - if type(val) == staticmethod: continue - if val is None: continue + if key.startswith('__') or type(val) == staticmethod or val is None: + continue result += Color.s("{G}%s {W} {C}%s{W}\n" % (key.ljust(max_len),val)) return result From 3fe4e1fd2513211b89062249e886c4005e7f7342 Mon Sep 17 00:00:00 2001 From: deix Date: Mon, 28 Aug 2017 19:13:25 +0200 Subject: [PATCH 6/7] And another comparisons to singletons.. --- py/Process.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/py/Process.py b/py/Process.py index d220826..622fb50 100644 --- a/py/Process.py +++ b/py/Process.py @@ -58,7 +58,7 @@ class Process(object): def __init__(self, command, devnull=False, stdout=PIPE, stderr=PIPE, cwd=None, bufsize=0): ''' Starts executing command ''' - if type(command) == str: + if type(command) is str: # Commands have to be a list command = command.split(' ') From 48f74171772f9ed51f8a3c843eea73d22967ec20 Mon Sep 17 00:00:00 2001 From: deix Date: Tue, 29 Aug 2017 18:19:50 +0200 Subject: [PATCH 7/7] Test for object identity --- py/Aireplay.py | 2 +- py/Airmon.py | 2 +- py/Process.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/py/Aireplay.py b/py/Aireplay.py index 74c97d0..30b9959 100644 --- a/py/Aireplay.py +++ b/py/Aireplay.py @@ -36,7 +36,7 @@ class WEPAttackType(object): self.value = value return raise Exception("Attack number %d not found" % var) - elif type(var) == str: + elif type(var) is str: for (name,value) in WEPAttackType.__dict__.iteritems(): if type(value) is int: if name == var: diff --git a/py/Airmon.py b/py/Airmon.py index e22b753..794cdae 100644 --- a/py/Airmon.py +++ b/py/Airmon.py @@ -29,7 +29,7 @@ class Airmon(object): def get(self, index): ''' Gets interface at index (starts at 1) ''' - if type(index) == str: + if type(index) is str: index = int(index) return self.interfaces[index - 1] diff --git a/py/Process.py b/py/Process.py index 622fb50..51a2c67 100644 --- a/py/Process.py +++ b/py/Process.py @@ -23,7 +23,7 @@ class Process(object): Returns tuple: (stdout, stderr) ''' - if type(command) != str or ' ' in command or shell: + if type(command) is not str or ' ' in command or shell: shell = True if Configuration.verbose > 1: Color.pe("\n {C}[?] {W} Executing (Shell): {B}%s{W}" % command)