![/etc/rc.local에 무한 루프가 나타나도 정상적으로 시작할 수 있습니다.](https://linux55.com/image/132861/%2Fetc%2Frc.local%EC%97%90%20%EB%AC%B4%ED%95%9C%20%EB%A3%A8%ED%94%84%EA%B0%80%20%EB%82%98%ED%83%80%EB%82%98%EB%8F%84%20%EC%A0%95%EC%83%81%EC%A0%81%EC%9C%BC%EB%A1%9C%20%EC%8B%9C%EC%9E%91%ED%95%A0%20%EC%88%98%20%EC%9E%88%EC%8A%B5%EB%8B%88%EB%8B%A4..png)
무한히 반복되는 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
signal.py 시작
#!/usr/bin/python
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BCM)
GPIO.setup(18, GPIO.OUT)
GPIO.output(18, 1)
fan.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 Stretch
답변1
Raspbian Stretch가 systemd
일반 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
systemd 는 기본적으로 시작하고 종료해도 상관하지 않는다는 것을 이해합니다 TimeoutSec=0
. RemainAfterExit=yes
이는 시스템이 /etc/rc.local
아직 실행 중임에도 불구하고 부팅이 성공적으로 완료되는 이유를 설명합니다.
스크립트 rc.local
는 startsignal.py
먼저 백그라운드에서 실행됩니다(= 사용 &
). 즉, 이 시점에서는 스크립트 시작에 실패할 경우에만 rc.local
스크립트에 오류가 발생한다는 의미입니다. startsignal.py
성공적으로 시작되었지만 오류가 반환되면 프로세스 에서 들어오는 오류를 읽어야 rc.local
합니다 . 그러나 귀하의 프로세스는 분명히 이것을 확인하는 데 관심이 없습니다.wait <process or job ID>
startsignal.py
그러면 당신의 일이 rc.local
시작됩니다 fan.py
. 없이 시작되기 때문에 &
쉘은 실행하기 위해 다른 프로세스를 시작 fan.py
하고 그것이 종료될 때까지 기다린다... 하지만 fan.py
무한 루프가 있기 때문에 시스템이 종료되거나 fan.py
오류가 발생하거나 프로세스가 실행 중일 때까지 종료되지 않습니다. fan.py
살해당했습니다. 종료한 후에만 실행됩니다 touch /home/pi/thisisrun
.fan.py
시작하는 것이 더 합리적이라고 생각합니다startsignal.py
아니요의 &
및fan.py
그리고오히려 그 반대입니다.