本文主要講述如何使用Python在指定的秒數後關閉Windows上運行的程序(此程序以網易雲音樂爲例)。本文的背景是昨晚發現網易雲音樂的PC客戶端沒有定時關閉的功能,能夠使用Python編寫一個簡單的腳本,用於定時關閉這樣的計劃任務。通過改良後,能夠對此作一些有用的擴展,用於平常運維中。html
爲何使用Python來作這件事?python
用cmd、計劃任務或者批處理作這件事不能夠嗎?若是說忽略過程,只看結果的話,這些方式確實可能更簡單也能達到目的,可是經過Python來作能夠從過程和結果兩個方面得到不少好處:git
能夠拿來練手,熟能生巧,並且不少東西不用就忘記github
控制程序的行爲上更加靈活,想輸出什麼就輸出什麼,想擴展功能能夠擴展功能,如寫入日誌等多線程
移植性和複用性比較好,還能夠用到Linux和Mac OSXapp
腳本運行原理:運維
1.使用python內置模塊sched實現計劃任務ide
2.使用psutil模塊實現枚舉和kill進程編碼
3.使用thread模塊並行執行兩個阻塞任務spa
此腳本涉及的知識:
獲取系統語言默認編碼
枚舉和kill 進程
獲取當前用戶的用戶名
實現倒計時功能
實現計劃任務功能
Python多線程執行
運行環境與使用方法:
Python 2.7
psutil
使用python直接運行此腳本便可
其中,在腳本的__main__中能夠修改時間(多少秒後執行)和進程的名字
運行結果截圖:
這是設置的10s後關閉網易雲音樂的運行截圖
說明:
第一行顯示當前運行時的時間;
第二行會實時顯示當前時間和剩餘的小時、分鐘和秒數;
第三、四、五、6行表示查到到進程並殺死進程;
最後兩行打印結束時的時間和退出信息;
腳本內容:
腳本能夠從GitHub上的LinuxBashShellScriptForOps項目中獲取,並得到更新和錯誤修正版本。
https://github.com/DingGuodong/LinuxBashShellScriptForOps/blob/master/projects/WindowsSystemOps/System/pyScheduleTask.py
腳本內容以下:
#!/usr/bin/python # encoding: utf-8 # -*- coding: utf8 -*- """ Created by PyCharm. File: LinuxBashShellScriptForOps:pyScheduleTask.py User: Guodong Create Date: 2017/4/6 Create Time: 22:33 """ # https://docs.python.org/2/library/sched.html import threading import sched import time import sys import locale import codecs def get_system_encoding(): """ The encoding of the default system locale but falls back to the given fallback encoding if the encoding is unsupported by python or could not be determined. See tickets #10335 and #5846 """ try: encoding = locale.getdefaultlocale()[1] or 'ascii' codecs.lookup(encoding) except LookupError: encoding = 'ascii' return encoding DEFAULT_LOCALE_ENCODING = get_system_encoding() def shutdown_NetEaseCloudMusic(name): # define NetEaseCloudMusic process name ProcessNameToKill = name print import psutil import sys # learn from getpass.getuser() def getuser(): """Get the username from the environment or password database. First try various environment variables, then the password database. This works on Windows as long as USERNAME is set. """ import os for username in ('LOGNAME', 'USER', 'LNAME', 'USERNAME'): user = os.environ.get(username) if user: return user currentUserName = getuser() if ProcessNameToKill in [x.name() for x in psutil.process_iter()]: print "[I] Process \"%s\" is found!" % ProcessNameToKill else: print "[E] Process \"%s\" is NOT running!" % ProcessNameToKill sys.exit(1) for process in psutil.process_iter(): if process.name() == ProcessNameToKill: try: # root user can only kill its process, but can NOT kill other users process if process.username().endswith(currentUserName): process.kill() print "[I] Process \"%s(pid=%s)\" is killed successfully!" % (process.name(), process.pid) except Exception as e: print e def display_countdown(sec): def countdown(secs): """ blocking process 1 :param secs: seconds, int :return: """ current_time = time.strftime("%Y-%m-%d %H:%M:%S %Z").decode(DEFAULT_LOCALE_ENCODING).encode("utf-8") print "Time current: %s" % current_time while secs: now = time.strftime("%Y-%m-%d %H:%M:%S %Z").decode(DEFAULT_LOCALE_ENCODING).encode("utf-8") hours, seconds = divmod(secs, 3600) minutes, seconds = divmod(seconds, 60) clock_format = '{:02d}:{:02d}:{:02d}'.format(hours, minutes, seconds) sys.stdout.write('\rTime now: %s Time left: %s' % (now, clock_format)) sys.stdout.flush() time.sleep(1) secs -= 1 # set a human readable timer here, such as display how much time left to shutdown countdown(int(sec)) def display_scheduler(name): """ blocking process 2 :return: """ s = sched.scheduler(time.time, time.sleep) s.enter(10, 1, shutdown_NetEaseCloudMusic, (name,)) s.run() now = time.strftime("%Y-%m-%d %H:%M:%S %Z").decode(DEFAULT_LOCALE_ENCODING).encode("utf-8") print "Time finished: %s\nGood bye!" % now if __name__ == '__main__': seconds_to_shutdown = 10 process_name_to_shutdown = "cloudmusic.exe" threadingPool = list() threading_1 = threading.Thread(target=display_countdown, args=(seconds_to_shutdown,)) threading_2 = threading.Thread(target=display_scheduler, args=(process_name_to_shutdown,)) threadingPool.append(threading_1) threadingPool.append(threading_2) for thread in threadingPool: thread.setDaemon(False) thread.start() thread.join()
tag: python計劃任務,python定時任務,python sched
--end--