How to make python loop interruptible by ^C on unix? - python

I've written a python script that looks up the recommended server at nordvpn.com and starts the according vpn. There is a part in this script where I assure there is internet access. When I run the script from a terminal, I cannot interrupt this loop by pressing ^C if there is no connection. How can I adapt the code so that the loop is interruptible?
Here is relevant part of the code:
#!/usr/bin/env python3
import re
import os
from selenium import webdriver
if __name__ == '__main__':
# ...
# wait for internet connection and load geckodriver
while True:
try:
browser = webdriver.Firefox(
executable_path=r'/home/maddin/bin/.vpn/geckodriver',
log_path='/dev/null')
break
except:
print("not connected yet, trying again....")
# ...

Using except: will catch all errors, including KeyboardInterrupt. You can instead use except Exception: which will not catch SystemExit, KeyboardInterrupt and GeneratorExit. This will allow you to break a loop with Ctrl + C. You can find more information here and here.

this is because of your default except block which takes all Interrupts including KeyboardInterrupt which is your ^C
while True:
try:
browser = webdriver.Firefox(
executable_path=r'/home/maddin/bin/.vpn/geckodriver',
log_path='/dev/null')
break
except KeyboardInterrupt:
# do whatever you want to do on ^C
except:
print("not connected yet, trying again...."

Related

How to import a Python module that contains an exit() call [duplicate]

I need to call 1 script(test.py) every 5 minutes, so i have used another script timer.py with following code:
import time
while(1==1):
execfile("test.py")
time.sleep(300)
This works correctly.
But it stopped working after few iterations. After debugging i found that there is a flow in test.py which uses following code:
sys.exit()
So, this is causing both test.py and timer.py to stop.
what changes should be done, so as to continue timer.py since i want sys.exit() to only exit test.py and not timer.py
sys.exit() doesn't do more then raising SystemExit (a BaseException subclass), which can be caught like any exception e.g:
import time
while True:
try:
execfile("test.py")
except SystemExit:
print("ignoring SystemExit")
finally:
time.sleep(300)
Use subprocess
import subprocess
import time
while(1==1):
subprocess.call(['python', './test.py'])
time.sleep(300)
You could even remove the python word if the test.py file has a shebang comment on the first line:
#!/usr/bin/env python
This is not exactly the same, as it will start a new interpreter, but the results will be similar.
You should be able to use:
try:
# Your call here
except BaseException as ex:
print("This should be a possible sys.exit()")
Check out the documentation for more information.
Try this:
import time
import os
while True:
os.system("python test.py") # if you are not running script from same directory then mention complete path to the file
time.sleep(300)

Retry urllib request on exception

I have a very small and simple python script on my raspberry, it works well for as long as there is an active Wi-Fi connection. The raspberry is connected to a mobile hotspot and it's possible it will lose it's connection as it could get out of range. As soon as this happens it throws an exception and ends the request "while" loop.
I was hoping to get more information to how i can make this script pause or "ignore" the exception so it goes back into the loop as soon as the connection is restored.
import urllib
import serial
from time import sleep
link = "http://myurl/"
while True:
f = urllib.urlopen(link)
myfile = f.read()
print myfile
ser = serial.Serial('/dev/ttyUSB0', 9600)
ser.write(myfile)
sleep(3)
You can try something called, (obviously) a try statement!
Within your while loop, you can use a try: except block to make sure that even if your code does't execute (your pi loses connection or something else weird happens) you won't end the program!
This type of code would look like this:
import urllib
import serial
from time import sleep
link = "http://myurl/"
while True:
try:
f = urllib.urlopen(link)
myfile = f.read()
print myfile
ser = serial.Serial('/dev/ttyUSB0', 9600)
ser.write(myfile)
sleep(3)
except:
sleep(3) #If the code executed in the try part fails, then your program will simply sleep off 3 seconds before trying again!

Can not get keyboardInterrupt to catch ctrl c in python program running in linux

I want my program to stop executing when a ctrl-c is entered in the terminal window (that has focus) where the program is executing. Every google hit tells me this should work but it doesn't.
First I tried putting the try block in a class method my main invoked:
try:
for row in csvInput:
<process the current row...>
except KeyboardInterrupt:
print '\nTerminating program!\n'
exit()
and then I tried putting the try block in my main program and that didn't work:
if __name__ == '__main__':
try:
programArg = ProgramArgs(argparse.ArgumentParser)
args = programArg.processArgs()
currentDir = os.getcwd()
product = Product(currentDir, args.directory[0], programArg.outputDir)
product.verify()
except KeyboardInterrupt:
print '\nTerminating program!\n'
exit()
I recently (May 2, 2020) hit this same issue in Windows-10 using Anaconda2-Spyder(Python2.7). I am new to using Spyder. I tried multiple ways to get [break] or [ctrl-c] to work as expected by trying several suggestions listed in stackoverflow. Nothing seemed to work. However, what I eventually noticed is that the program stops on the line found after the "KeyboardInterrupt" catch.
[Solution]: select [Run current line] or [continue execution] from the debugger tools (either menu item or icon functions) and the rest of the program executes and the program properly exits. I built the following to experiment with keyboard input.
def Test(a=0,b=0):
#Simple program to test Try/Catch or in Python try/except.
#[break] using [Ctrl-C] seemed to hang the machine.
#Yes, upon [Ctrl-C] the program stopped accepting User #
Inputs but execution was still "hung".
def Add(x,y):
result = x+y
return result
def getValue(x,label="first"):
while not x:
try:
x=input("Enter {} value:".format(label))
x = float(x)
continue
except KeyboardInterrupt:
print("\n\nUser initiated [Break] detected." +
"Stopping Program now....")
#use the following without <import sys>
raise SystemExit
#otherwise, the following requires <import sys>
#sys.exit("User Initiated [Break]!")
except Exception:
x=""
print("Invalid entry, please retry using a " +
"numeric entry value (real or integer #)")
continue
return x
print ("I am an adding machine program.\n" +
"Just feed me two numbers using "Test(x,y) format\n" +
"to add x and y. Invalid entries will cause a \n" +
"prompt for User entries from the keyboard.")
if not a:
a = getValue(a,"first")
if not b:
b = getValue(b,"second")
return Add(a,b)

How come my python batch file closes once its done?

Im trying to prevent the cmd to close when script is done and print out the message and wait for the users input and THEN close but it just closes as soon as its done.. what am I doing wrong?
except tweepy.TweepError as e:
print(e.reason)
sleep(10)
continue
except StopIteration:
break
print('Automation Done! ' + number + ' times! Press Any Key To Continue...')
input()
If it is a batch file, (with a .bat and not a .py) you can use
pause
or
pause >nul
EDIT:
pause
This will prompt the user for input, upon pressing any key, it will proceed.
pause >nul
This will not prompt the user for input, however, it will still behave the same as the regular pause
If you use os.system("pause"), the application send to operational sistem to pause the execution. This code can solve your problem:
import os
# Code...
except tweepy.TweepError as e:
print(e.reason)
sleep(10)
continue
except StopIteration:
print('Automation Done! ' + number + ' times!')
os.system("pause")

Python - how to run the application and leave until it end?

How can i run the application and leave instead of waiting when it will be ended? for example : /var/tmp/runme.sh &
Following code is working but it waits forever when Google Chrome will exit. how can i run Google Chrome but let my script exit?
import subprocess
import sys
import time
line = sys.argv[1]
print line
def kill_chrome():
subprocess.call(['Taskkill', '/IM', 'chrome.exe', '/F'])
def run_chrome():
subprocess.call(['C:/Program Files (x86)/Google/Chrome/Application/chrome.exe', '--kiosk'])
def run_java():
subprocess.call(['java', '-cp', 'C:/Python27/pdfbox-app-2.0.0-RC3.jar;C:/Python27/jprint.jar', 'JPrint'])
try:
if line.startswith("myjava:website"):
print "Google Chrome - IDLE"
run_chrome()
elif line.startswith("myjava:a4"):
print "Printing - JAVA"
run_java()
elif line.startswith("myjava:kill"):
print "Killer"
kill_chrome()
except Exception, err:
print (err)
pass
#time.sleep(2)
What about subprocess.Popen? Looks like it does exactly what you want - runs app end does not waiting. You also pass arguments to the runned application.
from subprocess import Popen
Popen( [ "C:/Program Files (x86)/Google/Chrome/Application/chrome.exe", "myarg"])
Without "myarg" it works too.

Categories

Resources