1. sudo su
2. sudo nano /etc/rc.local
3. 在 exit0 上一行加入 sudo python /xx/xx/xx.py
實測 :
就算我依 一起學 Python 102 修正預設的 python 版本後,
使用 sudo /etc/rc.local
還是會出現沒有 import module 的問題。但如果直接輸入 python /xx/xx/xx.py 是可以的,原因不明
20181018 更新
我找到一個簡單的方法。在參考連結中有人提出一樣的問題,其下的回答大致上的意思是說"因為在安裝外部 module 的時候我們只有將其安裝到 "pi" 使用者上,而使用 /etc/rc.local 此方法開機自啟動時,使用的是 "root" 使用者(而我們平常在終端機操作 Rpi 時執行文件等等的都是使用 "pi" 使用者",所以才會發生找不到 module 的情況。
遇到這情形可使用
sudo -u pi python /xx/xx/xx.py
改以 "pi" 使用者執行 python 檔
P.S. : 此方法有個需要注意的點,如果你的 python 檔具有 blocking 的特性。例如說你總共要開啟五個檔案,但你的第一個檔案(python)程式內容會有迴圈讓程式卡在裡面的,則你必須使用 "&" 後綴在指令後面解決這個問題,也就是說告知系統以一個子進程的方式開啟檔案,如
sudo -u pi python /xx/xx/xx.py &
(方法2) /home/pi/.config 中新增 *.desktop 腳本 (可參考)
/home/pi/.config 下找到名為 autostart 的文件夾,如果沒有就新創建一個。
在該文件夾下創建一個 xxx.desktop 文件,文件名自擬,後綴必須是 desktop
xxx.desktop 的內文為
[Desktop Entry]
Type=Application
Name=test
Comment=Python Program
Exec=sudo -H -u pi python /home/pi/test.py
實測 : 成功
(方法3) /etc/init.d 中新增腳本 (可參考)
1. sudo su
2. sudo nano /etc/init.d/TEST
... (後續請參考參考連結)
實測 : 失敗(原因我懶得查了,這方法有點麻煩)
(方法4) 在 /home/pi/.config/lxsession/LXDE-pi/autostart 加入路徑 (可參考)
此方法最簡易,且可以打開終端機,從電腦上顯示出 print 的那些字
步驟如下
1. sudo su
2. sudo nano /home/pi/.config/lxsession/LXDE-pi/autostart
3. 在最後面加入 @lxterminal -e python /full/path/to/your/script
我使用此法後,有一天莫名發現我桌面的 "工具欄" 消失了
解決辦法請看 一起學 Python 108 : Raspberry pi 桌面的工具列消失 解決辦法
實測 : 成功又簡單
(方法5) 使用 service 的方法開機自啟動
假設要開機自啟動的 python 文件以及名稱為以下
/home/pi/python_program/PiTurnON_v1.0.0.py
執行步驟
1. 進入 /lib/systemd/system/ 目錄底下
cd /lib/systemd/system/
2. 開起一個 service 編譯檔
sudo nano PiTurnON.service
3. 於該 service 編譯檔中鍵入以下內容
[Unit]
Description=EqNotifyMQTT
After=multi-user.target
[Service]
Type=simple
User = pi
ExecStart=/usr/bin/python -u /home/pi/python_program/EqNotifyMQTT_v2.3.6.py
Restart=on-abort
[Install]
WantedBy=multi-user.target
4. 對該 service 編譯檔設定權限( 777 代表所有使用者皆可以 讀/寫/執行 該檔案)
相關可參考此連結、
sudo chmod 777 /lib/systemd/system/PiTurnON.service
5. 對 python 檔設定權限( a=rwx 亦代表所有使用者皆可以 讀/寫/執行 該檔案)
相關可參考此連結
chmod a=rwx /home/pi/python_program/PiTurnON_v1.0.0.py
6. Reload systemd manager configuration, scanning for new or changed units
sudo systemctl daemon-reload
7. Enable a service to be started on bootup and Start immediately
sudo systemctl enable PiTurnON.service
8. Start service
sudo systemctl start PiTurnON.service
更多與 systemctl 相關的指令如下(用來查看或重啟 service 的狀態)
# Check status
sudo systemctl status EqLineNotify.service
# Stop service
sudo systemctl stop PiTurnON.service
# Restart service
sudo systemctl restart EqLineNotify.service
# Check service's log
sudo journalctl -f -u EqLineNotify.service
補充(20181108) :
我在某個 python 應用中有使用 apscheduler 的 BackgroundScheduler
企圖讓這個 python 程式碼在某個時間點執行某一段程式碼
原本的程式碼中我將這段程式碼 add_job 以及 start 後就沒有後續的程式碼了
但我發現如果這樣子的話,當排定到開機啟動的 service 後
沒多久這個 service 就會死掉 (status : dead)
我在 Restart 中是設定 on-abort 的
這個設定會讓程式碼遇到"錯誤"的時候自動重啟
但或許沒有包含這種 "長時間待命不幹事" 而被 service 關閉的情形
他並沒有幫我自動重啟
故我在程式碼的最後隨意寫了一個 while 迴圈,搭配 time.sleep 以及 print 讓他幹點事
這問題就解決了
HOW TO RUN A SCRIPT AS A SERVICE IN RASPBERRY PI - RASPBIAN JESSIE