Crontab 不再在后台运行 Raspberry Pi Python 脚本,但仍手动运行

Crontab No Longer Runs Raspberry Pi Python Script in Background But Still Runs Manually

我能够 运行 我的 Python 脚本在后台通过使用 sudo crontab -e 在启动时自动启动脚本来控制两个伺服系统。我修改了脚本,所以我现在不断地将舵机当前位置写入 horz.txt 和 vert.txt 文件,并使用这些文件将步进器初始化到它们的起始位置,这样我可以在通电后再次找到起始位置失利。当我使用 sudo python mystepper6.py 从命令行在黑屏上手动启动脚本时,该脚本与我添加的 horz.txt 和 vert.txt 代码一起工作正常,但它不会在启动时自动启动,也不会在我在命令行上键入 ps ax 时显示为 运行ning。我添加了一些额外的代码只是为了在主程序启动之前摆动伺服系统并且伺服系统按照 sudo crontab -e 中的编程自动摆动但是然后它只是停止 ps 并且不会继续找到起始位置.它似乎与新代码有关,但我不知道它可能是什么。我的 sudo crontab -e 行是 @reboot (sleep2;python /home/pi/mystepper6.py) &。下面是 mystepper6.py.

的脚本

由于此 post 中可用的 space 有限,因此缩短了以下脚本以显示相关行。 sudo 重启挂起,底部附近没有错误消息,它被注释为 'move to home position'(它不会移动)。我能够在该点之前打印 adjustv 和 adjusth 整数,以便在该点从 .txt 文件中为变量正确分配一个值。当我从命令行手动 运行 mystepper6.py 时,它 运行 非常完美。

我在这个问题上花了太多时间,买了两本电子书都无济于事。请帮忙。

import RPi.GPIO as gpio         # import library RPi.GPIO gpio=use general          purpose input output pin names
import time                             # import time library

PINSh = [27,10,18,23]           # variable 'PINS' holds a list of gpio pin numbers
SEQAh = [(27,),(10,),(18,),(23,)]
PINSv = [4,17,22,24]            # variable 'PINS' holds a list of gpio pin numbers
SEQAv = [(4,),(17,),(22,),(24,)]

DELAY = 0.01                            # time between motor steps (too small of a number then the motor stalls)
alpha = 140                             # horizontal full scale viewing angle in motor counts 128 counts = 360 degrees
beta = 30                               # was 15 vertical full scale viewing angle in motor counts 128 counts = 360 degrees

gpio.setmode(gpio.BCM)          # tells RPi.GPIO we want to use pin names (BCM is the mfg)
for pin in PINSh:           # pin is a variable name assigned a new value each loop; PINS is a list
    gpio.setup(pin, gpio.OUT)       # this says we want to use 'pin' as an output

for pin in PINSv:           # pin is a variable name assigned a new value   each loop; PINS is a list
    gpio.setup(pin, gpio.OUT)

def stepper(sequence, pins):        # def says 'stepper' is the function name (like a variable), then parameters are inside ()
    for step in sequence:
        for pin in pins:
            if pin in step:
                gpio.output(pin, gpio.HIGH)
            else:
                gpio.output(pin, gpio.LOW)

webcam_horz_home = open("horz.txt", "a")  
webcam_horz_home.close()                  
webcam_vert_home = open("vert.txt", "a")
webcam_vert_home.close()

#  load last position prior to power down

webcam_horz_home = open("horz.txt", "r")
rows = webcam_horz_home.readlines();
for row in rows:
    adjusth = int(row)
webcam_horz_home.close()

webcam_vert_home = open("vert.txt", "r")
rows = webcam_vert_home.readlines();
for row in rows:
    adjustv = int(row)
webcam_vert_home.close()                
counter = 0               #   move to home position
while counter < adjustv:                               
    stepper(SEQAv, PINSv)                              
    counter = counter + 1
# CONTINUAL PAN AND TILT OPERATION (box pattern):

我刚刚在我的 Pi 运行ning Raspbian 上测试了这个并且它有效。

首先,我在主用户​​的主目录中创建了一个名为 some_script.py 的 python 脚本。 脚本内容:

import sys
import time

with open("/home/username/some_script.py.out", "w") as f:
    f.write(str(time.time()) + " " + "some_script.py RAN!\n")

然后,在终端中,我在允许它执行的文件上设置了可执行位:

sudo chmod +x some_script.py

然后,同样在终端中,我输入了 sudo crontab -e 并在 root 用户的 crontab 底部添加了以下行:

@reboot sleep 2; /usr/bin/python /home/username/some_script.py

然后我重新启动,cded 到 /home/username/ 并确认 python 在重新启动时有 运行 并写入文件:

cat some_script.py.out 
1458062009.53 some_script.py RAN!

更新/解决方案

在确认 OP 能够成功复制上述步骤后,我相当有信心这不是由于 cron 在不同 *nix 系统或其他一些边缘情况下的不同实现而引起的问题。正如预期的那样,他可以通过 cron 运行 python,他可以使用 @reboot 功能,并且他可以在没有任何权限问题的情况下写入磁盘。

但是,还是不行。 did 解决的问题只是使用绝对路径而不是相对路径。

改变

webcam_horz_home = open("horz.txt", "a")

webcam_horz_home = open("/home/pi/horz.txt", "a")

webcam_vert_home = open("vert.txt", "a")

webcam_vert_home = open("/home/pi/vert.txt", "a")

OP 的踏步机又发出呼噜声了:)

说明/背景

当通过其他用户的 crontab 执行脚本或命令时(在本例中为 root),相对于普通用户主目录的路径(例如 ~/.bashrc)将不再有效或将指向具有相同文件名的不同文件(如果存在)。当人们 运行 服务器调用 PHP 等脚本语言(通常由 www-data 用户执行)时,有时会看到相同的 "issue"。

在 Raspberry Pi 上,这些事情在使用 GPIO 时可能会导致一些问题,因为 GPIO 设备被锁定并且在不更改权限和组的情况下非特权用户无法访问。

如果 OP 运行 他的脚本作为 root 通过 sudo crontab -e 添加 cron 条目,他将可以访问 GPIO 设备(因为 root 可以访问几乎所有的)。但是,他的 python 脚本中隐式引用非特权用户 pi 的主文件夹的相对路径将不再有效(因为 home 现在意味着文件夹 /root 这是 root 用户的主文件夹)。

如果 OP 运行 他的脚本通过非特权 pi 用户的 crontab 通过 crontab -e 添加 cron 条目(没有 sudo),路径将是有效(home~/ 现在意味着 /home/pi/)但是他将无法访问 GPIO 设备,因为 pi 是非常没有特权的。注意:@reboot 功能并非在所有 cron 实现中都可用(一些嵌入式和精简的 *nix 发行版没有它)并且通常它对 root 以外的用户不起作用。

这意味着 OP 有两个选择(可能还有更多;我不是 Linux 大师):

  1. 将文件 vert.txthorz.txt 放在 root 用户的主文件夹中。
  2. 只需更改 python 脚本中指定的路径,并在 root 的 crontab 中保持 运行ing 脚本 @reboot。

没有。 2 可能更好,因为它将 root 的主文件夹保持为空,并将 OP 的文件保存在 pi 的主文件夹中。 root 通常不应该乱用,除非没有其他选择,例如使用 sudo.