Я устанавливаю задачу crontab, которая выполняется каждые 5 минут на моем сервере Ubuntu 18.04. Эта задача (написанная с python3) должна запросить некоторую цену на криптовалюту на cryptomarketcap.com и отправить мне письмо. Однако задача не выполняется так, как я хочу.
Я проверил журнал crontab и добавил команду logging в мой код на python. Но результат очень странный. Похоже, что в cron.log задача просто выполняется в идеальное время
Apr 14 04:30:01 lemp-s-1vcpu-1gb-sgp1-01 CRON[14979]: (root) CMD (/bin/sh /root/request_price/mail_price.sh)
Apr 14 04:35:01 lemp-s-1vcpu-1gb-sgp1-01 CRON[15004]: (root) CMD (/bin/sh /root/request_price/mail_price.sh)
Apr 14 04:39:01 lemp-s-1vcpu-1gb-sgp1-01 CRON[15088]: (root) CMD ( [ -x /usr/lib/php/sessionclean ] && if [ ! -d /run/systemd/system ]; then /usr/lib/php/sessionclean; fi)
Apr 14 04:40:01 lemp-s-1vcpu-1gb-sgp1-01 CRON[15090]: (root) CMD (/bin/sh /root/request_price/mail_price.sh)
Apr 14 04:45:01 lemp-s-1vcpu-1gb-sgp1-01 CRON[15102]: (root) CMD (/bin/sh /root/request_price/mail_price.sh)
Apr 14 04:50:01 lemp-s-1vcpu-1gb-sgp1-01 CRON[15112]: (root) CMD (/bin/sh /root/request_price/mail_price.sh)
Apr 14 04:55:01 lemp-s-1vcpu-1gb-sgp1-01 CRON[15150]: (root) CMD (/bin/sh /root/request_price/mail_price.sh)
Apr 14 05:00:01 lemp-s-1vcpu-1gb-sgp1-01 CRON[15174]: (root) CMD (/bin/sh /root/request_price/mail_price.sh)
Однако в журнале, записанном Python, все обстоит иначе
start program 2019-04-14 04:30:01.932384
start request 2019-04-14 04:30:01.932869
end request 2019-04-14 04:30:02.690205
start mailing 2019-04-14 04:30:02.694734
end mailing 2019-04-14 04:30:06.602899
start program 2019-04-14 04:43:31.499914
start request 2019-04-14 04:43:31.500368
start program 2019-04-14 04:43:31.512064
start request 2019-04-14 04:43:31.514192
end request 2019-04-14 04:43:31.853871
start mailing 2019-04-14 04:43:31.859186
end request 2019-04-14 04:43:31.877854
start mailing 2019-04-14 04:43:31.881670
end mailing 2019-04-14 04:43:33.438788
end mailing 2019-04-14 04:43:33.477752
start program 2019-04-14 04:45:02.085442
start request 2019-04-14 04:45:02.085969
end request 2019-04-14 04:45:02.434488
start mailing 2019-04-14 04:45:02.439000
end mailing 2019-04-14 04:45:03.724816
start program 2019-04-14 04:50:02.236511
start request 2019-04-14 04:50:02.237008
end request 2019-04-14 04:50:02.938542
start mailing 2019-04-14 04:50:02.943317
end mailing 2019-04-14 04:50:04.690106
start program 2019-04-14 04:57:59.706844
start request 2019-04-14 04:57:59.707152
end request 2019-04-14 04:58:00.065410
start mailing 2019-04-14 04:58:00.069808
end mailing 2019-04-14 04:58:02.075729
start program 2019-04-14 05:00:01.557796
start request 2019-04-14 05:00:01.558173
end request 2019-04-14 05:00:02.180507
start mailing 2019-04-14 05:00:02.185072
end mailing 2019-04-14 05:00:03.440213
Видно, что в 04:35 и 04:40 программа не запускалась, но в 04:43 она запускалась дважды. Аналогичные вещи в 04:57.
КОД:
Командный файл crontab
*/5 * * * * /bin/sh /root/request_price/mail_price.sh
mail_price.sh
/root/anaconda3/bin/python3 /root/request_price/main.py
main.py
import get_price as gp
from send_mail import send_mail
import json
from pytz import timezone
from datetime import datetime,timedelta
with open('log.txt','a') as log:
log.write('start program '+str(datetime.now())+'\n')
raw_response = gp.request_api()
with open('log.txt', 'a') as log:
log.write('end request ' + str(datetime.now()) + '\n')
status = raw_response['status']
time_utc = datetime.strptime(status['timestamp'][0:-5], '%Y-%m-%dT%H:%M:%S')
time_beijing = time_utc+timedelta(hours=8)
data = raw_response['data']
btc_price = gp.get_currency_price(data, 'BTC')
bch_price = gp.get_currency_price(data, 'BCH')
print(datetime.strftime(time_beijing, '%Y-%m-%d %H:%M:%S'))
subject = 'Price'
content = 'BTC:'+"{0:.2f}".format(btc_price)+'\n BCH:'+"{0:.2f}".format(bch_price)+'\nTime:'\
+ datetime.strftime(time_beijing, '%Y-%m-%d %H:%M:%S')
receiver = "HIDE"
with open('log.txt', 'a') as log:
log.write('start mailing ' + str(datetime.now()) + '\n')
send_mail(receiver, subject, content)
with open('log.txt', 'a') as log:
log.write('end mailing ' + str(datetime.now()) + '\n')
get_price.py
from requests import Request, Session
from requests.exceptions import ConnectionError, Timeout, TooManyRedirects
import json
from datetime import datetime
def request_api():
url = 'https://pro-api.coinmarketcap.com/v1/cryptocurrency/listings/latest'
parameters = {
'start': '1',
'limit': '100',
'convert': 'USD',
}
headers = {
'Accepts': 'application/json',
'X-CMC_PRO_API_KEY': 'HIDE',
}
session = Session()
session.headers.update(headers)
with open('log.txt', 'a') as log:
log.write('start request ' + str(datetime.now()) + '\n')
try:
response = session.get(url, params=parameters)
data = json.loads(response.text)
return data
except (ConnectionError, Timeout, TooManyRedirects) as e:
print(e)
def get_currency_price(data, symbol):
for currency in data:
if currency['symbol'] == symbol:
return currency['quote']['USD']['price']
return -1
send_mail.py
import smtplib
from email.mime.text import MIMEText
from email.header import Header
from email.utils import formataddr
def send_mail(receiver, subject, content):
mail_host = "HIDE"
mail_user = "HIDE"
mail_pass = "HIDE"
sender = 'HIDE'
message = MIMEText(content, 'plain', 'utf-8')
message['From'] = formataddr(["RapidSub Notification", sender])
message['To'] = formataddr([receiver.split('@')[0], receiver])
message['Subject'] = Header(subject, 'utf-8')
try:
smtpObj = smtplib.SMTP_SSL(host=mail_host)
smtpObj.connect(mail_host, 465)
smtpObj.login(mail_user, mail_pass)
smtpObj.sendmail(sender, receiver, message.as_string())
print("Success")
smtpObj.quit()
except smtplib.SMTPException:
print("Error: Fail")
smtpObj.quit()