/etc/rc.local에 무한 루프가 나타나도 정상적으로 시작할 수 있습니다.

/etc/rc.local에 무한 루프가 나타나도 정상적으로 시작할 수 있습니다.

무한히 반복되는 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()

모든 관련 코드는 위에 있습니다. 구글링 끝에 이런 생각이 들었습니다.

  1. #!/bin/sh -e오류가 발생하면 스크립트가 종료됨을 나타냅니다 .
  2. 파일 /home/pi/thisisrun이 생성되지 않았으므로 이 줄에 오류가 있을 것입니다.
  3. 시스템으로 부팅한 후 시스템이 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=forkingsystemd 는 기본적으로 시작하고 종료해도 상관하지 않는다는 것을 이해합니다 TimeoutSec=0. RemainAfterExit=yes이는 시스템이 /etc/rc.local아직 실행 중임에도 불구하고 부팅이 성공적으로 완료되는 이유를 설명합니다.

스크립트 rc.localstartsignal.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 그리고오히려 그 반대입니다.

관련 정보