Как автозапустить скрипт Python в RaspBerry Pi 3 (Raspbian (Debian))?

Проблема в том, что я не могу найти способ автоматического запуска файла Application.py при запуске системы. Я пробовал несколько способов; crontab, init.d, rc.local. А скрипт sh выполняется, проблема в том, что строка, где он: sudo /usr/lib/python3 /home/pi/file.py, ничего не происходит. Я знаю, что sh выполняется, потому что я создаю файл test1.log, и он всегда создается при запуске.

С другой стороны, если я вручную выполняю sudo /etc/init.d/startApp start, все проходит нормально, а когда вы ставите sudo /etc/init.d/inicioApp stop, процесс останавливается. Затем я оставляю файл /etc/init.d/startApp, чтобы узнать, может ли кто-нибудь мне помочь, помните, что Raspbian работает на Raspberry Pi 3 Model B V1.2.

Файл /etc/init.d/startApp:

#! /bin/sh
# /etc/init.d/startApp

### BEGIN INIT INFO
# Provides: startApp
# Required-Start: $remote_fs $syslog
# Required-Stop: $remote_fs $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Start Application
# Description: Start Application.py automatically.
### END INIT INFO


case "$1" in
 start)
  echo "Start Application.py"
  echo "startApp is running" >> /home/pi/test1.log
  sudo /usr/bin/python3 /home/pi/Application.py
  ;;

 stop)
  echo "Stop Application.py"
  /usr/bin/python3 -kill :1
  ;;

 *)
  echo "Usage: /etc/init.d/startApp {start|stop}"
  exit 1
  ;;
esac

exit 0

Файл /home/pi/Application.py:

from PIL import Image, ImageTk
import sys

try:
    import tkinter as tk  # Python 3
except ImportError:
    import Tkinter as tk  # Python 2

import RPi.GPIO as GPIO

GPIO_present = True
GPIO_PULSE = 4
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
GPIO.setup(GPIO_PULSE, GPIO.IN, GPIO.PUD_UP)


class Application(tk.Frame):
    DELAY = 100  # ms
    IMG_DELAY = 200
    POST_DELAY = 2000

    def __init__(self, master=None):
        super().__init__(master)
        print("executed")
        self.pack()
        self.w, self.h = self.winfo_screenwidth(), self.winfo_screenheight()
        self.img_name = "/home/pi/pattern.png"
        self.control = 0
        self.create_widgets()
        self.flag = False
        self.after(self.DELAY, self.check_signal)
        root.bind('<Escape>', self.quitApp)

    def load_image(self, filename):

        try:
            pil_img = Image.open(filename)
            img_width, img_height = pil_img.size

            if img_width > self.w or img_height > self.h:  # Too big?
                size = (int(self.w), int(self.h))
                pil_img = pil_img.resize(size)
                ratio = min(self.w / img_width, self.h / img_height)
                img_width, img_height = int(img_width * ratio), int(img_height * ratio)
                pil_img = pil_img.resize((img_width, img_height), Image.ANTIALIAS)  # Resize.
            self.control = 0
            img = ImageTk.PhotoImage(pil_img)  # Convert to tkinter PhotoImage.
            return img

        except FileNotFoundError:
            self.control = 1

    def quitApp(self, a):
        root.destroy()

    def create_widgets(self):
        file = open("testfile.txt", "w")

        file.write("Se ejecuto.py")

        file.close()
        self.canvas = tk.Canvas(root, width=self.w, height=self.h, background='black')
        self.canvas.pack()

        self.pattern_img = self.load_image(self.img_name)
        if self.control == 1:
            sys.exit()
            root.destroy()

        self.image_id = self.canvas.create_image(self.w / 2, self.h / 2, image=None)

    def show_image(self):
        self.cur_img = self.pattern_img
        self.after(self.IMG_DELAY)
        self.canvas.itemconfigure(self.image_id, image=self.cur_img)
        self.update()
        self.after(self.POST_DELAY)
        self.canvas.delete(self.image_id)
        self.image_id = self.canvas.create_image(self.w / 2, self.h / 2, image=None)

    def check_signal(self):

        if GPIO_present:
            self.flag = not GPIO.input(GPIO_PULSE)

        if self.flag:
            self.show_image()
            self.flag = False  # Reset

        root.after(self.DELAY, self.check_signal)  # Check again after delay.


if __name__ == '__main__':
    root = tk.Tk()
    w, h = root.winfo_screenwidth(), root.winfo_screenheight()
    root.wm_attributes('-fullscreen', 'true')
    root.focus_set()

app = Application(root)

app.mainloop()

Спасибо заранее!!!


person Jano CL    schedule 22.02.2019    source источник
comment
что значит ничего не происходит?   -  person SuperStew    schedule 22.02.2019
comment
Что файл Application.py, указанный в строке с надписью sudo /usr/bin/python3 /home/pi/Application.py, не запускается, что происходит, когда я вручную запускаю команду sudo /etc/init.d/startApp start. Я хорошо объясняюсь? Спасибо   -  person Jano CL    schedule 22.02.2019
comment
test.txt создан Application.py? Если это так, это означает, что ваше приложение работает... пробовали ли вы более простой скрипт Python, например print("It works!")?   -  person r.ook    schedule 22.02.2019
comment
Извините, у меня была ошибка в названии файла, так как я его модифицировал, это был не test.txt, файл, о котором я говорю, это test1.log. Снова простите!   -  person Jano CL    schedule 22.02.2019
comment
Все нет, захожу на него и комментирую, если у кого работает, спасибо!   -  person Jano CL    schedule 22.02.2019
comment
Если скрипт точно выполняется из-за лога, значит что-то пошло не так с выполнением Application.py. Либо проблема с разрешением, либо python3 не запускается, либо проблема в самом .py. Я бы посоветовал попробовать какой-нибудь действительно простой скрипт, чтобы увидеть, запускается ли сначала sudo /usr/bin/python3, например, простой with open('testfile.txt', 'w') as file: file.write("hey"), и искать testfile.txt.   -  person r.ook    schedule 22.02.2019
comment
Нет, я уже смог протестировать эти 5 методов и ни один из них не запускает скрипт Application.py, методы работают, но в момент создания флейма sudo /usr/bin/python3 /home/pi/Application.py ни один не приходит на выполнение. Да, если выполнение принудительно после запуска системы, если оно работает в случаях, которые возможны, поэтому единственное, что мне приходит в голову, это то, что Python не загружается, но другие также работают в Raspbian и Raspberry, я делаю не знаю что это может быть :/   -  person Jano CL    schedule 22.02.2019
comment
@Idlehands Я пробовал то, что вы говорите, и python3 отлично работает и создает текстовый файл с тем, что я пишу, и файл Application.py работает нормально, если я делаю это вручную с помощью python3, я этого не понимаю, я даю разрешения, как указано в учебниках / руководствах, но у меня это не работает.   -  person Jano CL    schedule 22.02.2019
comment
Тогда, возможно, будет полезнее показать содержимое того, что ваш Application.py. Это может привести к сбою из-за использования относительного пути вместо абсолютного пути или других факторов. Ваш cwd при запуске вручную по сравнению с автозапуском может отличаться.   -  person r.ook    schedule 22.02.2019
comment
@Idlehands Посмотрите на пост, я обновил его, и теперь у вас есть содержимое файла Application.py, большое спасибо за помощь!   -  person Jano CL    schedule 22.02.2019


Ответы (1)


Я предполагаю, что вы используете raspbian, не так ли?

Поскольку в Debian 7 (raspbian основан на Debian) системой инициализации по умолчанию является systemd, тем не менее существует совместимость со старой известной systemv, поэтому вы все равно можете использовать /etc/ init.d/youscript, но убедитесь, что:

  • Предоставьте разрешения на выполнение для вашего сценария init.d startApp
  • Выберите, какие уровни запуска вы хотите, чтобы startApp выполнялся, т.е. 5, 3 и т. д., вы можете найти свой уровень запуска по умолчанию с помощью:
sudo runlevel
  • Используйте update-rc.d, чтобы поместить ваш скрипт в автозагрузку для уровня запуска по умолчанию (таким образом вам не нужно беспокоиться о том, является ли значение по умолчанию /etc/rc5.d или /etc/rc2.d, оно делает это для тебя )
update-rc.d script-name default
  • (Необязательно, если не используется update-rc.d) Создайте программную ссылку и укажите ее на правильный каталог уровня выполнения /etc/rcX.d, но обратите внимание на имя! ' для запуска и число, подобное "99", так как вы хотите, чтобы оно выполнялось в самом конце последовательности запуска уровня выполнения, то есть:
ln -s /etc/init.d/startApp /etc/rc5.d/S99startApp
person theraulpareja    schedule 22.02.2019