Ошибка при планировании скрипта Python: fcron [12036]: не удалось выполнить «/usr/bin/sendmail»: нет такого файла или каталога

У меня есть скрипт Python, который я хотел бы запланировать с помощью fcrontab. Этот скрипт отправляет электронные письма на основе поля статуса, установленного в одном из столбцов. Сценарий выполняется ожидаемым образом, когда я вызываю следующее:

python2 mail.py

Это приводит к следующему и ожидаемому результату:

Successfully sent email... 
Update sent status on EdPost...  xxxxxx
Update sent status on EdPost...  xxxxxx
Update sent status on EdPost...  xxxxxx
Update sent status on EdPost...  xxxxxx
Update sent status on EdPost...  xxxxxx
Update sent status on EdPost...  xxxxxx
Update sent status on EdPost...  xxxxxx
Update sent status on EdPost...  xxxxxx

Однако, когда я пытаюсь запустить этот скрипт как задание cron, я получаю указанную ошибку.

Крон:

0 15 * * * /home/x/JobParse/mail.py >> /home/x/JobParse/mailer.log

Ошибка:

fcron[23191]: Couldn't exec '/usr/bin/sendmail': No such file or directory

У меня есть еще один скрипт Python, запланированный аналогичным образом, который отлично работает с #!/usr/bin/env python2 shebang. Однако этот скрипт не использует библиотеку smtplib.

Сценарий, который я пытаюсь запланировать, приведен ниже:

mail.py

#!/usr/bin/python2
import smtplib
from db import get_records,update_sent_status
import traceback
import datetime
configs = [line.rstrip('\n') for line in open('configs')]
usr = configs[0]
pwd = configs[1]
rcvr = configs[2]
receivers = [rcvr]
date = datetime.datetime.now().date()
posts = []
edpost_tbl_rows= ""
appli_tbl_rows= ""

ed_posts = get_records(0) # * non-appli and  unsent
ed_posts_ids = [row[0] for row in ed_posts]
ed_posts_sent = get_records(1) # post_id

uniq_appli = get_records(2) # unique unsent appli
uniq_appli_ids = [row[0] for row in uniq_appli]

all_appli_sent = [row[0] for row in get_records(4)] # all app_id sent
all_appli_unsent = [row[0] for row in get_records(5)] # all app_id unsent


# No jobs to send so exit
if len(all_appli_unsent) == 0 and len(ed_posts) == 0:
    print "Exit: No new unique posts.."
    exit()

# Transform db data into html table row format
for row in ed_posts:
    edpost_tbl_rows += \
            "<tr style=\"border:1px solid black\"><td style=\"border:1px solid black\">"\
            +str(row[0])\
            +"</td><td style=\"border:1px solid black\"><a href = "\
            +'"'\
            +row[1]\
            +'"'\
            +">"\
            +row[4]\
            +"</a></td><td style=\"border:1px solid black\">"\
            +row[5]\
            +"</td><td style=\"border:1px solid black\">"\
            +row[6]\
            +"</td></tr>"

# Transform applitrack posts into html table
for row in uniq_appli:
    # check if sent before - app_id not unique on edpost
    if row[3] not in all_appli_sent:
        print "New unique & unsent applitrack post... ",row[3]
        appli_tbl_rows += \
            "<tr style=\"border:1px solid black\"><td style=\"border:1px solid black\">"\
            +str(row[0])\
            +"</td><td style=\"border:1px solid black\"><a href = "\
            +'"'\
            +row[2]\
            +'"'\
            +">"\
            +str(row[3])\
            +"</a></td><td style=\"border:1px solid black\"><a href = "\
            +'"'\
            +row[1]\
            +'"'\
            +">"\
            +row[4]\
            +"</a></td><td style=\"border:1px solid black\">"\
            +row[5]\
            +"</td><td style=\"border:1px solid black\">"\
            +row[6]\
            +"</td></tr>"
    else:
        print "Skipping applitrack post... ",row[3]


message = """From: JobUpdates <{usr}>
To: xxxx <{rcvr}>
MIME-Version: 1.0
Content-type: text/html; charset=utf-8
Subject: New Job Postings: {date}

<p>Check out these postings you may have not have seen yet :)</p>
<p>Searched: words

<h2>Jobs With Applitrack</h2>
<table style = "width:100%;border:1px solid black">
    <tr style = "border:1px solid black">
        <th style = "border:1px solid black">EdPost ID</th>
        <th style = "border:1px solid black">AppliTrack ID</th>
        <th style = "border:1px solid black">Description</th>
        <th style = "border:1px solid black">Post DT</th>
        <th style = "border:1px solid black">Exp DT</th>
    </tr>
    {appli_tbl_rows}
</table>
</br>
</br>
<h2>Jobs Without Applitrack</h2>
<table style = "width:100%;border:1px solid black">
    <tr style = "border:1px solid black">
        <th style = "border:1px solid black">EdPost ID</th>
        <th style = "border:1px solid black">Description</th>
        <th style = "border:1px solid black">Post DT</th>
        <th style = "border:1px solid black">Exp DT</th>
    </tr>
    {edpost_tbl_rows}
</table>
""".format(usr=usr,rcvr=rcvr,date=date,edpost_tbl_rows=edpost_tbl_rows,appli_tbl_rows=appli_tbl_rows)

try:
    smtpObj = smtplib.SMTP('localhost',1025)
    smtpObj.login(usr,pwd)
    smtpObj.sendmail(usr, rcvr, message)
    print "Successfully sent email... "
    for post_id in ed_posts_ids:
        print "Update sent status on EdPost... ",post_id
        update_sent_status(post_id)

    for app_id in all_appli_unsent:
        print "Update sent status on Appli... ",app_id
        update_sent_status(app_id,1)

except smtplib.SMTPException:
    print "ERROR: unable to send email... "
    print traceback.format_exc()

Я пробовал это с #!/usr/bin/env python2 shebang, но безрезультатно.

это похоже на проблему с cron, а не на проблему с кодом Python. Обычно cron отправляет письмо пользователю, когда возникает проблема с запуском скрипта. Кажется, он пытается отправить почту, но не может найти для нее sendmail. Сначала вы должны проверить, можете ли вы запустить /usr/bin/sendmail в терминале.

furas 29.05.2019 03:01

У меня не установлен sendmail. Я не понимал, что cron может понадобиться. Я буду работать над его установкой и настройкой, и, надеюсь, это даст мне больше информации. Спасибо!

wermy 29.05.2019 03:15
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
2
114
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я смог решить проблему без установки sendmail. Это было сделано путем перемещения пути Python в скрипт в его начале следующим образом:

import os
abspath = os.path.abspath(__file__)
dname = os.path.dirname(abspath)
os.chdir(dname)

См. ответ Питто здесь.

Я предполагаю, что обновление переменной пути для среды cron из самого crontab также будет жизнеспособным решением.

Другие вопросы по теме