2014-02-06 68 views
2

我有一個啓動時在後臺運行的python腳本。啓動方法是使用/etc/rc.local調用的run.sh文件中的一個條目。確切的條目是「sudo python /home/pi/run/main.py &」。該系統是一個有喘息的樹莓派。在關閉信號的Python腳本中運行代碼

腳本正在運行,至今沒有問題。如果關閉命令發送到系統(通過控制檯「sudo shutdown -h now」),我需要進一步腳本不立即中止,而是先執行一些代碼。這就是我到目前爲止:

#!/usr/bin/env python 

import atexit 

@atexit.register 
def byebye(): 
    c = "End" 
    datei = open("/home/pi/logfile",'a+b') 
    datei.write(c + "\n") 
    datei.close() 

def main(): 

    while True: 
    ...do anything... 

main() 

現在,它似乎只是關閉關閉主循環。我是否需要使用不同的方式來關閉系統,以便將信號傳輸到我的腳本,或者我是否可能無法使用「@atexit」方法?有任何想法嗎?

由於

+0

也許如果你看看molly-guard的含義 - http://packages.debian.org/sid/all/molly-guard/filelist - 這樣做,你會有更好的方法嗎? – nrathaus

+0

感謝您的評論,但它似乎代碼是高於我的專業知識......甚至不知道如何開始......( – user3281341

回答

4

shutdown發送SIGTERM信號,其atexit不處理。也不會對上下文管理,finally塊等

import signal 

signal.getsignal(signal.SIGTERM) 
Out[64]: 0 #i.e. nothing 

對比這跟,說CTRL-C:

signal.getsignal(signal.SIGINT) 
Out[65]: <function signal.default_int_handler> #i.e. something 

您可以signal註冊byebye功能來運行,而不是什麼都不做(這會導致給翻譯最終被外殼殺死)

signal.signal(signal.SIGTERM,byebye) 

如果你這樣做,你需要做兩件事:

  • 變化byebye簽名接受兩個參數是signal將傳遞給它。
  • 您應該在byebye函數的結尾處撥打電話號碼sys.exit(),讓python優雅地關閉商店。

你可以做交替的signalatexit一些組合:

import sys 
signal.signal(signal.SIGTERM, lambda num, frame: sys.exit(0)) 

這將降權到您當前密碼。這確保了清理操作的原子性(即byebye保證是最後的I/O操作),但代價有點笨拙。

+0

+1爲lambda。我不認爲它是笨重的,只要它的評論 – zigg

+0

是的,這是我唯一關心的問題 - 你的代碼沒有聲明你的退出處理程序在哪裏/什麼,它可能是modules,不然,* packages * away!(所以是的,請使用註釋:-)) – roippi

+0

非常感謝爲您的答案...這是我需要的推動! :-) – user3281341