Нужно ли вызывать Python в скрипте задания cron?

Я пытаюсь запустить задание cron с домашнего сервера, на котором работает Ubuntu 24/7, используя скрипт Python очистить удаленный почтовый ящик.

В папке «scripts» в моей домашней папке я поместил скрипт Python, garbage.py.

Я сделал его исполняемым:

chmod +x garbage.py 

Сценарий ( с именем пользователя и паролем, обновленными до реального имени пользователя и пароля):

#!/bin/env python3

import imaplib
import ssl
from datetime import datetime
# your IMAP server credentials
IMAP_HOST = 'mail.us.opalstack.com'
IMAP_USER = 'mail_username'
IMAP_PASS = 'mail_password'
def clear_old_messages():

today = datetime.today().strftime('%d-%b-%Y')

ctx = ssl.create_default_context()
server = imaplib.IMAP4_SSL(host=IMAP_HOST, ssl_context=ctx)
server.login(IMAP_USER, IMAP_PASS)
server.select()

resp, items = server.search(None, f"SENTBEFORE {today}")
items = items[0].split()
for i in items:
    server.store(i, '+FLAGS', '\\Deleted')

server.expunge()
    server.logout()
if __name__ == '__main__':
    clear_old_messages()

Я открыл crontab в Ubuntu с помощью

crontab -e

и добавил

0 1 * * * /home/[user]/scripts/garbage.py

Я немного запутался в том, что не работает. Нужно ли вызывать Python в задаче cron, даже если она вызывается в верхней части скрипта? Или я что-то Пример файла {"Имя": "% Хана-29-миссис-Смит", "работа": "инженер"} {"Name": "% ...

У меня есть большой файл, содержащий объекты json, каждый объект в новой строке.

Пример файла

{"Name" :"%Hana-29-Mrs-Smith","job":"engineer"}
{"Name" :"%Mike-31-Mr-Larry","job":"marketing"}
{"Name" :"%Jhon-40-Mr-Doe","job":"engineer"}

Желаемый вывод:

{"Name" :"%Hana-29-Mr-Smith", "f_nams":"Hana", "age":29, "title":"Mrs", "l_name":"Smith","job":"engineer"}
{"Name" :"%Mike-29-Mr-Larry", "f_nams":"Mike", "age":31, "title":"Mr", "l_name":"Larry","job":"marketing"}
{"Name" :"%Jhon-29-Mr-Smith", "f_nams":"Jhon", "age":40, "title":"Mr", "l_name":"Doe","job":"engineer"}
1
задан 25 July 2020 в 03:23

2 ответа

For non-nested objects such as this, you could consider using Miller

$ mlr --json put -S '
    @x = splitnv(substr($Name,1,-1),"-"); $f_nams = @x[1]; $age = @x[2]; $title = @x[3]; $l_name = @x[4]
  ' then reorder -e -f job file.json
{ "Name": "%Hana-29-Mrs-Smith", "f_nams": "Hana", "age": 29, "title": "Mrs", "l_name": "Smith", "job": "engineer" }
{ "Name": "%Mike-31-Mr-Larry", "f_nams": "Mike", "age": 31, "title": "Mr", "l_name": "Larry", "job": "marketing" }
{ "Name": "%Jhon-40-Mr-Doe", "f_nams": "Jhon", "age": 40, "title": "Mr", "l_name": "Doe", "job": "engineer" }
3
ответ дан 30 July 2020 в 22:03

One of the possible ways that is expressive, procedural and clear (although the script itself can seem a bit lengthy), is to use Python3 with json module.

#!/usr/bin/env python3
import json
import sys

with open(sys.argv[1]) as json_file:
    for line in json_file:
        json_obj = dict(json.loads(line))
        tokens = json_obj["Name"].split('-')
        extra_data = { 
            "f_nams": tokens[0].replace('%','') ,
            "age"   : tokens[1],
            "title" : tokens[2],
            "l_name": tokens[3]
        }
        joined_data = {**json_obj, **extra_data}
        print(json.dumps(joined_data))

The way it works is that we use a context manager open() to open the file and to be closed automatically upon completion. From the sample data in the question we may assume that each json object is on separate lines (NOTE: if the actual data you use has multi-line json objects, you may have to adapt the script to use try-except block to read file until full json data is read into a variable).

From there it's just text manipulations and Python magic: split value of key "Name" into tokens on - character into a list, put list of tokens into new dictionary and join the two dictionaries with Python 3.5 ** operator, which I believe is called "keyword unpacking" ( if you use other version of Python, check the link for alternatives ). All that is converted back into json object and printed on standard output. If you do need to save it to new file, use shell redirection as in ./parse_data.py ./data.json > ./new_data.json or if you want to see it simultaneously on screen ./parse_data.py ./data.json | tee ./new_data.json

How it works in action:

$ ./parse_data.py ./data.json 
{"Name": "%Hana-29-Mrs-Smith", "job": "engineer", "f_nams": "Hana", "age": "29", "title": "Mrs", "l_name": "Smith"}
{"Name": "%Mike-31-Mr-Larry", "job": "marketing", "f_nams": "Mike", "age": "31", "title": "Mr", "l_name": "Larry"}
{"Name": "%Jhon-40-Mr-Doe", "job": "engineer", "f_nams": "Jhon", "age": "40", "title": "Mr", "l_name": "Doe"}

$ cat ./data.json 
{"Name" :"%Hana-29-Mrs-Smith","job":"engineer"}
{"Name" :"%Mike-31-Mr-Larry","job":"marketing"}
{"Name" :"%Jhon-40-Mr-Doe","job":"engineer"}
2
ответ дан 30 July 2020 в 22:03

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

Похожие вопросы: