Re: Making Python Script Exit Completely with One Ctrl+C
Hongyi Zhao via curl-users <[email protected]>
| Newsgroups | gmane.comp.web.curl.general |
|---|---|
| Message-ID | <CAGP6PO+c_XJVtByVV90fh-S8fR6H7ZgcdjOjjsCgzTt6=9Qiwg@mail.gmail.com> |
On Sat, Dec 9, 2023 at 9:37 AM Hongyi Zhao <[email protected]> wrote: > > On Fri, Dec 8, 2023 at 10:44 AM Dan Fandrich via curl-users > <[email protected]> wrote: > > > > On Fri, Dec 08, 2023 at 09:56:44AM +0800, Hongyi Zhao via curl-users wrote: > > > I tried the following method but in vain: > > [...] > > > try: > > > pass > > > except KeyboardInterrupt: > > > kb_interrupt = True > > > > This won't accomplish anything because "pass" will never raise an exception. > > I have a feeling that even putting the entire contents of the progress callback > > into a try/except block won't even help; I suspect the exception is raised the > > moment the Python interpreter is returned to by pycurl while calling that > > callback, which is before even that point. > > > > You'll probably have to block SIGINT before calling calling into pycurl, then > > unblocking in the progress callback to check it, e.g. > > > > ... > > signal.pthread_sigmask(signal.SIG_BLOCK, [signal.SIGINT]) > > c.perform() > > signal.pthread_sigmask(signal.SIG_UNBLOCK, [signal.SIGINT]) > > ... > > > > def progress(...): > > try: > > signal.pthread_sigmask(signal.SIG_UNBLOCK, [signal.SIGINT]) > > except KeyboardInterrupt: > > print('interrupted!') > > return 1 > > finally: > > signal.pthread_sigmask(signal.SIG_BLOCK, [signal.SIGINT]) > > > > or just set your own SIGINT handler that sets a flag (kb_interrupt), then check > > that flag in the progress callback and return an error if it's set. > > I tried using the first method of your tips. It works, but the > calculated *Average Speed* is too high, as shown below: > > (datasci) werner@X10DAi:~/Desktop$ python callback-SIGINT.py > Proxy: SG_ssr_futeapbquf5m.nodelist.club_1453_018d83c677e05e71f172014fc3f45e39 > Current Speed: 1371.74 kB/s > Current Speed: 6565.90 kB/s > Average Speed: 7552.72 kB/s > Proxy: HK_ssr_wo8o8npg4fny.nodelist.club_1303_b5bf85111d0f51c517ec7302d3f33ce1 > Current Speed: 1252.55 kB/s > Current Speed: 7461.93 kB/s > Average Speed: 8807.27 kB/s > Proxy: SG_ssr_futeapbquf5m.nodelist.club_1354_ddfba110eddfdb7037f389e9b5917477 > Current Speed: 3081.76 kB/s > Current Speed: 9351.58 kB/s > Average Speed: 10745.23 kB/s > Proxy: HK_ssr_fwqvvo60u1mj.nodelist.club_1423_dba3b0996744e7b82eae7634626a5ba9 > ^Cinterrupted! > Average Speed: 156.74 kB/s > Proxy: SG_ssr_futeapbquf5m.nodelist.club_1356_8ce27b1301fcbcb77cc5abb28cb127a6 > Script terminated by user. Exiting. > > I'm not sure how to fix this problem. Attached please find the test script. I tried another method which also had the same problem: (datasci) werner@X10DAi:~/Desktop$ python rev-2.py Proxy: SG_ssr_futeapbquf5m.nodelist.club_1453_018d83c677e05e71f172014fc3f45e39 Current Speed: 664.56 kB/s Current Speed: 7691.08 kB/s Average Speed: 9403.12 kB/s Proxy: HK_ssr_wo8o8npg4fny.nodelist.club_1303_b5bf85111d0f51c517ec7302d3f33ce1 Current Speed: 950.39 kB/s Current Speed: 6146.08 kB/s Average Speed: 7297.46 kB/s Proxy: SG_ssr_futeapbquf5m.nodelist.club_1354_ddfba110eddfdb7037f389e9b5917477 ^CTraceback (most recent call last): File "/home/werner/Desktop/rev-2.py", line 60, in progress def progress(download_t, download_d, upload_t, upload_d): KeyboardInterrupt > Regards, > Zhao > > > -- > > Unsubscribe: https://lists.haxx.se/mailman/listinfo/curl-users > > Etiquette: https://curl.se/mail/etiquette.html -- Unsubscribe: https://lists.haxx.se/mailman/listinfo/curl-users Etiquette: https://curl.se/mail/etiquette.html
rev-2.py
(text/x-python, 2.5 KB)
import subprocess
import time
import pycurl
from io import BytesIO
import sys
def fetch_proxies():
command = 'echo "show stat" | sudo socat stdio /var/run/haproxy.sock 2>/dev/null | awk -F, \'$1=="socks5" && !($2~/^(FRONTEND|BACKEND)$/) {print $2,$74}\''
process = subprocess.Popen(command, stdout=subprocess.PIPE, shell=True)
output, error = process.communicate()
result_dict = {} # Initialize default empty dictionary
if error is not None:
return result_dict # Return the empty dictionary in case of error
lines = output.decode('utf-8').split('\n')
for line in lines:
if line != "":
key_value = line.split(' ')
result_dict[key_value[0]] = key_value[1]
return result_dict
def test_proxy(proxy, url):
global last_calc_time, download_start_time
buffer = BytesIO()
c = pycurl.Curl()
c.setopt(pycurl.URL, url)
c.setopt(pycurl.WRITEDATA, buffer)
c.setopt(pycurl.PROXY, proxy)
c.setopt(pycurl.PROXYTYPE, pycurl.PROXYTYPE_SOCKS5_HOSTNAME)
c.setopt(pycurl.NOPROGRESS, False)
c.setopt(pycurl.XFERINFOFUNCTION, progress)
c.setopt(pycurl.TIMEOUT, 5)
download_start_time = time.time()
last_calc_time = download_start_time
try:
c.perform()
except pycurl.error as e:
#print(f'An error occurred: {e}')
# 输出异常的错误代码和描述
#print(f'Error code: {e.args[0]}')
#print(f'Error message: {e.args[1]}')
if e.args[0]==42:
#print("Script interrupted by user. Exiting During perform pycurl.")
sys.exit(0) # 立即退出程序
else:
pass
average_speed = c.getinfo(pycurl.SPEED_DOWNLOAD) / 1024
return average_speed
def progress(download_t, download_d, upload_t, upload_d):
global last_calc_time, download_start_time
current_time = time.time()
if current_time - last_calc_time >= 2:
elapsed_time = current_time - download_start_time
current_speed = download_d / elapsed_time / 1024
print(f"Current Speed: {current_speed:.2f} kB/s")
last_calc_time = current_time
proxy_data = fetch_proxies()
url = "http://ipv4.download.thinkbroadband.com/1GB.zip"
for key, value in proxy_data.items():
print(f"Proxy: {key}")
try:
average_speed = test_proxy(value, url)
print(f"Average Speed: {average_speed:.2f} kB/s")
except KeyboardInterrupt:
print("Script interrupted by user. Exiting.")
break # 退出for循环