inicializa normalmente mesmo com um loop infinito em /etc/rc.local

0

Eu coloquei um script python com um loop infinito em /etc/rc.local , mas a máquina inicializa com sucesso, o que me confunde.

O /etc/rc.local content:

#!/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

startsignal.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()

Todo o código relevante está acima. Eu pensei sobre isso depois de pesquisar.

  1. o #!/bin/sh -e indica que o script será encerrado assim que ocorrer um erro.
  2. o arquivo /home/pi/thisisrun não é criado, portanto, deve haver um erro acima dessa linha
  3. depois de inicializar no sistema, vejo que fan.py está em execução. Então eu acho que o erro ocorre durante a execução de fan.py . Mas o fan.py tem um loop infinito!

Como um script python pode gerar um erro, mas ainda é executado normalmente?

Como o /bin/sh detecta o erro quando o fan.py nunca retorna?

SO: trecho raspbian

    
por Charles 07.05.2018 / 03:24

1 resposta

1

Assumindo que o Stretch Raspbian usa systemd como o Debian Stretch regular faz por padrão, /etc/rc.local é iniciado por /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

Como ele especifica Type=forking , TimeoutSec=0 e RemainAfterExit=yes , eu entendo que o systemd basicamente inicia e não importa se sai ou não. Isso explica por que o sistema pode concluir a inicialização com êxito, mesmo se /etc/rc.local ainda estiver em execução.

Seu script rc.local primeiro executa startsignal.py em segundo plano (= com & ): isso significa que apenas uma falha ao iniciar o script causaria um erro no script rc.local nesse ponto. Se startsignal.py for iniciado com êxito, mas retornar um erro, rc.local teria que usar wait <process or job ID> para ler o erro recebido do processo startsignal.py . Mas o seu processo aparentemente não se importa em verificar isso.

Então, seu rc.local começa com fan.py . Como ele é iniciado sem & , o shell iniciará outro processo para executar fan.py e aguardar a saída ... mas como fan.py tem um loop infinito, ele não será encerrado até que o sistema esteja sendo encerrado , fan.py tem um erro ou o processo executando fan.py é eliminado. O touch /home/pi/thisisrun será executado somente após a saída de fan.py .

Acho que faria mais sentido começar startsignal.py sem o & e fan.py com , em vez de vice-versa.

    
por 07.05.2018 / 08:52

Tags