面對這個狀況有幾個解決方案,例如使用專面負責離線工作的程式,像是screen;但因為幾台工作站的作業系統太過老舊,上面甚至連screen都沒有;另一個解決方案是用atd,也就是linux內建的服務,在某個時間進行某個指令,這個解決方式很好,只是at 的語法比較麻煩,強迫每個使用者去記也沒什麼道理,身為網管要提供使用者方便,決定把at包成一個shell,使用者只要使用這個指令即可。
--
其實這個只要用shell script寫幾行即可,不過考量到一些特別的功能,還是用python來寫。 核心功能其實就一個,透過python 的subprocess把em 的指令透過atd送進去(ref 3):
cmd = "echo 'em -v {0}'".format(filename) cmd2 = "at now +0 minutes" p1 = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE) p2 = subprocess.Popen(cmd2, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=p1.stdout)
監控程序:
啟動atd之後,必須要監控該執行程序,看看它是不是結束了,這裡我使用強者我同學AZ的python 解決方案: pnotify(ref 2)當然,這個監控的程式也要用atd的方式來執行。
第一步是先找出atd呼叫出來的em -v的process,再來的function就是抄襲AZ的,簡單來說是先檢查/proc,看看該pid是否開啟,然後每隔一段時間就用kill 0的方式檢查該程序存在與否。
找出pid的部分,用的方法就笨一點,直接叫外部的ps,抓出有em的部分、濾出該使用者的資訊、排除grep自身,再用pid排個序,抓最大(最新)的pid即可,這個方法在pid用完一圈後會出錯,不過將就用一下,之後再看看有沒有更好的解,有的話麻煩強者們提示一下m(_ _)m:
pid_list = [] cmd = "sleep 1; ps -elf" p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE) stdout = p.stdout.read().decode("utf-8").split('\n') for line in stdout: if ("em -v" in line) and (username in line) and ("grep" not in line): pid_list.append(line.split()[3])就可以抓出pid了。 再來再用atd開啟一個pnotify的監控工作即可。
email:
為了方便使用者,使用的是python + SMTP module,這部分的程式碼只能用明碼寫出帳號密碼,不過這在權限上設定為只有我能看即可;主要code如下:# open smtp session session = smtplib.SMTP('smtp.gmail.com', 587) session.ehlo session.starttls() session.ehlo session.login(account, password) # prepare the send message msg = MIMEText("Your EM simulation: {0} is over".format(filename)) msg['Subject'] = "the test title" msg['From'] = sender msg['To'] = receiver # send the message session.sendmail(sender, [receiver], msg.as_string()) session.quit()透過google的smtp進行文件的轉送,其實這沒什麼,大部分都是抄的lol(ref 1)
成果:
現在工作站可以透過 runem file1.son 的方式執行一個超大em模擬,em模擬結束時候,可以透過電子郵件,通知進行模擬的使用者。本程式透過python譔寫,相當快速,總開發時間約3-4天。
原始碼已上傳到github上:
https://github.com/lc85301/runem
附章:
趁著這次佈署runem的時候,順便佈署了另一個小script: clearcdslck其實沒什麼,只是一個shell包含一行指令:
find . -name *.cdslck -exec rm -fv {} \;方便使用者清除因不當結束產生的.cdslck檔。
參考資料:
1. about python mail using google SMTPhttp://segfault.in/2010/12/sending-gmail-from-python/
2. about pnotify.py
http://blog.azhuang.me/2011/07/script-for-notifying-process.html#more
3. about python subprocess
http://docs.python.org/2/library/subprocess.html
沒有留言:
張貼留言