Sorry if this is a simple question and has been answered before, but I couldn't find it anywhere.
I'm trying to listen to UDP packets and if they are certain packets, run different batch scripts. I have this working correctly, but I have found that if the Popen command doesn't find the file it triggers an exception and the script stops running. Ideally, I want this to print a message and then continue listening for other packets and act upon them, just giving us a message for debugging. Here is the code I have used, how could I do this?
if rxdata == "Camera 1":
from subprocess import Popen
try:
p = Popen("Camera 1.bat", cwd=r"C:\xxx")
stdout, stderr = p.communicate()
except FileNotFoundError():
print('Camera 1.bat not found')
elif rxdata == "Camera 2":
from subprocess import Popen
p = Popen("Camera 2.bat", cwd=r"C:\xxx")
stdout, stderr = p.communicate()
In both examples, I receive the following and the script closes.
Traceback (most recent call last):
File "C:\UDP Listener.py", line 42, in <module>
p = Popen("Camera 1.bat", cwd=r"C:\xxx")
File "C:\Python34\lib\subprocess.py", line 858, in __init__
restore_signals, start_new_session)
File "C:\Python34\lib\subprocess.py", line 1111, in _execute_child
startupinfo)
FileNotFoundError: [WinError 2] The system cannot find the file specified
Thanks in advance
Matt
You must not use the brackets behind the FileNotFoundError (don't call it, just "name" it). Test (with Python 2):
try:
b = a
except NameError():
print "NameError caught."
Execution:
Traceback (most recent call last):
File "test.py", line 2, in <module>
b = a
NameError: name 'a' is not defined
For instance, OSError is a type, whereas OSError() creates an instance of this type:
>>> type(OSError)
<type 'type'>
>>> type(OSError())
<type 'exceptions.OSError'>
Strangely, after re-installing python on my PC everything is now working correctly. Not sure what went wrong but when I run the code now and an exception is found then the code prints as expected.
Thanks for your help!
Related
I am completely new to the subprocess module. And I was trying to automate the deauthentication attack commands. When I run airodump-ng wlan0mon as you know it looks for the APs nearby and the connected clients to it.
Now when I try to run this command using lets suppose p = subprocess.run(["airmon-ng","wlan0mon"], capture_output=True) in Python as you know this command runs until the user hits Ctrl+C, so it should save the last output when user hits Ctrl+C in the variable but instead I get error which is this:
Traceback (most recent call last):
File "Deauth.py", line 9, in <module>
p3 = subprocess.run(["airodump-ng","wlan0"], capture_output=True)
File "/usr/lib/python3.8/subprocess.py", line 491, in run
stdout, stderr = process.communicate(input, timeout=timeout)
File "/usr/lib/python3.8/subprocess.py", line 1024, in communicate
stdout, stderr = self._communicate(input, endtime, timeout)
File "/usr/lib/python3.8/subprocess.py", line 1866, in _communicate
ready = selector.select(timeout)
File "/usr/lib/python3.8/selectors.py", line 415, in select
fd_event_list = self._selector.poll(timeout)
KeyboardInterrupt
What can I try to resolve this?
Just use Python's error handling. Catch any KeyboardInnterrupts (within your subprocess function) using try and except statements like so:
def stuff(things):
try:
# do stuff
except KeyboardInterrupt:
return last_value
When opening 4GB+ file on AIX Python 2.6.2 I receive IOError:
>>> fd = open('/mnt/t/MY_BIG_4GB_FILE', 'r')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IOError: [Errno 127] Value too large to be stored in data type: '/mnt/t/MY_BIG_4GB_FILE'
Any solutions? I didn't find information in Google.
EDIT:
To read BIG file I do something line that (I know that it is rubbish but sometimes You simply can't change python version):
from subprocess import Popen, PIPE
p = Popen(["cat", source_file], stdout=PIPE, bufsize=BUFFER_SIZE)
try:
for line in iter(p.stdout.readline, ''):
# process line
pass
finally:
p.communicate() # closing Popen
You're looking for "large file support." There is a decent brief here: http://docs.python.org/2/library/posix.html#large-file-support . You likely need to recompile your Python interpreter with the appropriate options, or find a pre-built one that has those options. Try a build of Python 2.7 if you can, while you're at it.
I want to run terminal commands within a python file. It is working fine and I can also get the terminal messages on a gui window using subprocess.Popen.
import subprocess
import wx
import os
def main():
p = subprocess.Popen(['ls'], stdout = subprocess.PIPE)
text = p.stdout.readlines()
text = "".join(text)
wx.MessageBox("file names:\n%s" % text, "info")
if __name__ == '__main__':
app = wx.PySimpleApp()
main()
But when I run a command for which terminal should ask answers of some questions, I am getting error?
Traceback (most recent call last):
File "to_make_new_project_folder.py", line 19, in <module> main()
File "to_make_new_project_folder.py", line 10, in main p = subprocess.Popen(['gr_modtool add -t general square_ff'], stdout = subprocess.PIPE)
File "/usr/lib/python2.7/subprocess.py", line 711, in init errread, errwrite)
File "/usr/lib/python2.7/subprocess.py", line 1308, in _execute_child raise child_exception
OSError: [Errno 2] No such file or directory
Does someone have idea how to answer the question from terminal using a gui window?
You should try passing in stdin=PIPE as well to popen
Based on your stack trace, the error you're receiving is OSError: No such file or directory, coming up from subprocess. It looks to me like Popen can't find the file that you're trying to execute, and is therefore failing.
I have the following Python code:
import sys
import traceback
fifo_in = sys.argv[1]
while 1:
try:
exec open(fifo_in)
except:
traceback.print_exc()
sys.stdout.flush()
The first argument is a named pipe created by mkfifo. So the following prints '1':
mkfifo input
python script.py input
... in a separate terminal ...
echo "print 1" > input
Great, so far so good. But when I do something like echo "foobar" > input, the script only prints part of the traceback. It then pauses until I send it another command, and the output gets all mixed up:
echo "asdf" > input # pause here and check output
echo "print 1" > input
... in output terminal ...
Traceback (most recent call last):
File "test.py", line 8, in <module>
exec open(fifo_in)
File "in", line 1, in <module>
...PAUSES HERE...
print 1
NameError: name 'asdf' is not defined
What's going on? How can I get stdout to flush fully and why is it out of order? I've tried using traceback.format_exc instead, then printing it by hand, but I get the same result. Calling sys.stderr.flush does not fix anything either. I've also tried putting a sleep in the loop to see if that helps, but nothing.
UPDATE
One interesting piece of behavior I am seeing: If I ctrl+c it, normally the program keeps running - the try/except just catches the KeyboardInterrupt and it keeps looping. However, if I ctr+c it after sending it an error, the program exits and I get the following. It's almost like it pauses inside of print_exc:
^CTraceback (most recent call last):
File "test.py", line 10, in <module>
traceback.print_exc()
File "/usr/lib/python2.7/traceback.py", line 232, in print_exc
print_exception(etype, value, tb, limit, file)
File "/usr/lib/python2.7/traceback.py", line 125, in print_exception
print_tb(tb, limit, file)
File "/usr/lib/python2.7/traceback.py", line 69, in print_tb
line = linecache.getline(filename, lineno, f.f_globals)
File "/usr/lib/python2.7/linecache.py", line 14, in getline
lines = getlines(filename, module_globals)
File "/usr/lib/python2.7/linecache.py", line 40, in getlines
return updatecache(filename, module_globals)
File "/usr/lib/python2.7/linecache.py", line 132, in updatecache
with open(fullname, 'rU') as fp:
KeyboardInterrupt
I think you want to look at the stdlib code module
This behavior is from using exec. Exec is for evaluating python code so "print 1" executes the python code print 1, where as "asdf" will raise a NameError as it does not exist in the context. exec open(fifo_in) is strange as it shouldn't work. The while will also eat up 100% cpu.
UPDATE: fix sleep duration
Here is a modified version of your code to try.
import sys
import time
import traceback
fifo_in = sys.argv[1]
try:
fp = open(fifo_in) # will block until pipe is opened for write
except IOError:
traceback.print_exc()
except OSError:
traceback.print_exc()
data = None
while True:
try:
data = fp.read()
try:
exec data
except:
traceback.print_exc()
finally:
time.sleep(0.1)
except KeyboardInterrupt:
break
Windows version of Python 2.6.4: Is there any way to determine if subprocess.Popen() fails when using shell=True?
Popen() successfully fails when shell=False
>>> import subprocess
>>> p = subprocess.Popen( 'Nonsense.application', shell=False )
Traceback (most recent call last):
File ">>> pyshell#258", line 1, in <module>
p = subprocess.Popen( 'Nonsense.application' )
File "C:\Python26\lib\subprocess.py", line 621, in __init__
errread, errwrite)
File "C:\Python26\lib\subprocess.py", line 830, in
_execute_child
startupinfo)
WindowsError: [Error 2] The system cannot find the file specified
But when shell=True, there appears to be no way to determine if a Popen() call was successful or not.
>>> p = subprocess.Popen( 'Nonsense.application', shell=True )
>>> p
>>> subprocess.Popen object at 0x0275FF90>>>
>>> p.pid
6620
>>> p.returncode
>>>
Ideas appreciated.
Regards,
Malcolm
returncode will work, although it will be None until you've called p.poll(). poll() itself will return the error code, so you can just do
if a.poll() != 0:
print ":("
In the first case it fails to start, in the second - it successfully starts shell which, in turn, fails to execute the application. So your process has been properly spawned, exited and waits for you to inquire about its exit code. So, the thing is, unless your shell or environment (e.g. no memory) is utterly broken there's no way Popen itself may fail.
So, you can safely .poll() and .wait() on it to get all the sad news.