如果 selenium 以无头方式运行,Cron 不会从 python 脚本输出任何内容

如果 selenium 以无头方式运行,Cron 不会从 python 脚本输出任何内容

我遇到了一个奇怪的问题,过去两周我一直在绞尽脑汁解决这个问题,到处搜索,还喝酒来洗去失败的痛苦。

问题是,当我从 cron 运行我的警报脚本时,什么都没有重定向到我的日志文件,并且脚本似乎不起作用。但是,当我注释掉 selenium 中一个看似毫无意义的选项时,日志记录就可以正常工作。在 cron 之外运行时,脚本可以完美运行。顺便说一下,我使用的是非 sudo cron,因为我的 python 环境就是在那里设置的。

该脚本基本上会获取一些信息,并将其输入到一个非常好的 TTS 引擎(自然阅读器)中,然后在早上播放。我不想为 TTS 或自然阅读器付费,这就是我使用 selenium 的原因


代码


这是我的 cron 脚本,我省略了其他 cron 条目,因为它们不重要:

@reboot sh scripts/YakScripts.sh -alarm > scripts/logs/alarm.log 2>&1

这是我的 YakScripts.sh 文件,同样,我省略了它的主要内容:

#!/usr/bin/env bash

TZ=":America/New_York" date

export PYTHONPATH=${PYTHONPATH}:"scripts"


case "$1" in
  -alarm) python3 scripts/Alarm/alarm.py ;;
  *) echo "Thats not a function, dumbass."
    ;;
esac

这是我的闹钟脚本:

import Alarm.Weather.getDailyForecast as weather
import Alarm.SunCycles.suncycles as suncycles
import TTS.speak as voice

from datetime import date

today = date.today()

# dd/mm/YY
naturalDate = today.strftime("%B %d, %Y")
print(naturalDate)

dayOfWeek = today.strftime("%A")
print(dayOfWeek)


alarmText = "Good Morning. \n"
alarmText += "Today is " + dayOfWeek + ". " + naturalDate + ".\n"



alarmText += weather.getMostRecentForecast() + "\n\n"

alarmText += "Today, the sun rises at " + suncycles.getSunrise() + ".\n"
alarmText += "and sets at " + suncycles.getSunset() + ".\n"


print(alarmText)
voice.speak(alarmText)

最后(也是最重要的一点)这是我的演讲脚本,我删除了大部分内容,因为我认为 naturalReader 不会喜欢我发布这些内容。但我测试过,它的功能是一样的:

import time

from selenium import webdriver
from selenium.webdriver.firefox.options import Options

import TTS.locators as locators
import globalData

selectedVoice = globalData.tts["voice"]
max_stale_tries = globalData.tts["max_retries"]


def speak(message):
    options = Options()
    #options.add_argument("--headless")
    driver = webdriver.Firefox(options=options)

    driver.get("https://www.naturalreaders.com/online/")

    print("Loaded the web page")
    time.sleep(3)


问题


因此,问题就在这里,当我不注释掉其中的 headless 行(speak.py 的第 15 行)时,我的 alarm.log 文件如下所示:

Tue Feb  9 21:08:03 EST 2021

当我注释掉该行时,它看起来是这样的:

Tue Feb  9 21:27:43 EST 2021
February 10, 2021
Wednesday
Good Morning. 
Today is Wednesday. February 10, 2021.
Tonight the forecast is Snow showers before 10pm, then snow showers and patchy freezing drizzle. Cloudy, with a low around 8. Wind chill values as low as -6. Northeast wind 8 to 12 mph.
Wednesday the forecast is Snow showers before 7am. Cloudy, with a high near 16. Wind chill values as low as -7. Northeast wind 10 to 14 mph, with gusts as high as 18 mph.

Today, the sun rises at 07:29 AM.
and sets at 06:12 PM.

Traceback (most recent call last):
  File "../../../../../../../../scripts/Alarm/alarm.py", line 35, in <module>
    voice.speak(alarmText)
  File "/scripts/TTS/speak.py", line 16, in speak
    driver = webdriver.Firefox(options=options)
  File "/home/appa/.local/lib/python3.8/site-packages/selenium/webdriver/firefox/webdriver.py", line 170, in __init__
    RemoteWebDriver.__init__(
  File "/home/appa/.local/lib/python3.8/site-packages/selenium/webdriver/remote/webdriver.py", line 157, in __init__
    self.start_session(capabilities, browser_profile)
  File "/home/appa/.local/lib/python3.8/site-packages/selenium/webdriver/remote/webdriver.py", line 252, in start_session
    response = self.execute(Command.NEW_SESSION, parameters)
  File "/home/appa/.local/lib/python3.8/site-packages/selenium/webdriver/remote/webdriver.py", line 321, in execute
    self.error_handler.check_response(response)
  File "/home/appa/.local/lib/python3.8/site-packages/selenium/webdriver/remote/errorhandler.py", line 242, in check_response
    raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.WebDriverException: Message: Process unexpectedly closed with status 1

我知道此错误与 webdriver 无法连接到显示器有关,这就是为什么我需要无头运行它。

还有一件事,我可以在 htop 中看到 geckodriver/python3 进程,但是同样,没有从 alarm.py 脚本中得到任何输出。

我真的只是想知道为什么当该行取消注释时我会得到输出,而在正常运行(无头)时却不会得到输出。

答案1

通过cron、运行的作业crontab不会在桌面上的同一运行时环境中运行。您的任何PATH更改或其他环境变量设置都不会自动传播到您的cron作业。例如,没有$DISPLAY,因此 GUI 程序需要特殊处理(阅读man xhost)。

cron人们可以在crontab文件 Read中为所有作业设置环境变量man 5 crontab

echo "=== set ===";set;echo "=== env ===";env | sort;echo "=== alias ===";alias查看每个环境中的结果 。

由于command该行的一部分crontab默认由 解释/bin/sh,其语法比 更简单/bin/bash,因此我建议command调用一个bash脚本(可执行、已安装、以 开头#!/bin/bash)来设置环境,然后调用所需的程序。

相关内容