我放入了一个无限循环的 python 脚本,/etc/rc.local
但机器成功启动,这让我很困惑。
内容/etc/rc.local
:
#!/bin/sh -e
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.
# Print the IP address
_IP=$(hostname -I) || true
if [ "$_IP" ]; then
printf "My IP address is %s\n" "$_IP"
fi
/home/pi/py/startsignal.py &
/home/pi/py/fan.py
touch /home/pi/thisisrun
exit 0
启动信号.py
#!/usr/bin/python
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BCM)
GPIO.setup(18, GPIO.OUT)
GPIO.output(18, 1)
粉丝.py
#!/usr/bin/python
# coding: utf8
import RPi.GPIO as gpio
gpio.setmode(gpio.BCM)
upper_temp = 55
lower_temp = 45
# minutes
check_interval = 2
def get_temp():
with open('/sys/class/thermal/thermal_zone0/temp', 'r') as f:
temp = float(f.read()) / 1000
return temp
def check_temp():
if get_temp() > upper_temp:
gpio.setup(23, gpio.OUT)
elif get_temp() < lower_temp:
gpio.setup(23, gpio.IN)
if __name__ == '__main__':
# check every 2 minutes
try:
while True:
check_temp()
sleep(check_interval * 60)
finally:
gpio.cleanup()
所有相关代码都在上面。我在谷歌搜索后想到了这一点。
- 表示
#!/bin/sh -e
一旦发生错误,脚本就会退出。 - 该
/home/pi/thisisrun
文件没有创建,所以这一行上面一定有错误 - 启动进入系统后我可以看到它
fan.py
正在运行。所以我猜这个错误是在执行过程中发生的fan.py
。但其中fan.py
有一个无限循环!
python脚本如何产生错误但仍然正常运行?
当永远不会返回时如何/bin/sh
检测错误fan.py
?
操作系统:raspbian 拉伸
答案1
假设 Raspbian Stretchsystemd
默认情况下像常规 Debian Stretch 一样使用,/etc/rc.local
启动方式为/lib/systemd/system/rc-local.service
:
# This file is part of systemd.
#
# systemd is free software; you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.
# This unit gets pulled automatically into multi-user.target by
# systemd-rc-local-generator if /etc/rc.local is executable.
[Unit]
Description=/etc/rc.local Compatibility
ConditionFileIsExecutable=/etc/rc.local
After=network.target
[Service]
Type=forking
ExecStart=/etc/rc.local start
TimeoutSec=0
RemainAfterExit=yes
GuessMainPID=no
正如它所指定的Type=forking
,TimeoutSec=0
和RemainAfterExit=yes
,我理解 systemd 基本上启动它并且不关心它是否退出。这就解释了为什么系统即使/etc/rc.local
仍在运行也能成功完成启动。
您的rc.local
脚本首先startsignal.py
在后台运行(= 带有&
):这意味着只有启动脚本失败才会导致rc.local
此时脚本出现错误。如果startsignal.py
成功启动但随后返回错误,rc.local
则必须使用wait <process or job ID>
从进程中读取传入的错误startsignal.py
。但你的过程显然不关心检查这一点。
然后你的rc.local
开始fan.py
。由于它是在没有 的情况下启动的&
,因此 shell 会启动另一个进程来运行fan.py
并等待它退出...但由于fan.py
有一个无限循环,因此它不会退出,直到系统关闭、fan.py
出现错误或进程正在运行fan.py
被杀了。只有退出touch /home/pi/thisisrun
后才会执行。fan.py
我认为开始更有意义startsignal.py
没有的&
和fan.py
和它,而不是相反。