Hướng dẫn run python file from crontab - chạy tệp python từ crontab

Tôi đang cố gắng thực thi tập lệnh Python bằng Linux Crontab. Tôi muốn chạy tập lệnh này cứ sau 10 phút.

Tôi tìm thấy rất nhiều giải pháp và không ai trong số họ làm việc. Ví dụ: Chỉnh sửa Anacron tại /etc/cron.d hoặc sử dụng crontab -e. Tôi đặt dòng này ở cuối tệp, nhưng nó không thay đổi gì cả. Tôi có phải khởi động lại (các) dịch vụ nào không?

*/2 * * * * /usr/bin/python /home/souza/Documets/Listener/listener.py

Tôi phải chỉnh sửa tệp nào để định cấu hình cái này?


Đây là kịch bản.

#!/usr/bin/python
# -*- coding: iso-8859-15 -*-

import json
import os
import pycurl
import sys
import cStringIO

if __name__ == "__main__":

    name_server_standart = "Server created by script %d"
    json_file_standart = "{ \"server\" : {  \"name\" : \"%s\", \"imageRef\" : \"%s\", \"flavorRef\" : \"%s\" } }"

    curl_auth_token = pycurl.Curl()

    gettoken = cStringIO.StringIO()

    curl_auth_token.setopt(pycurl.URL, "http://192.168.100.241:8774/v1.1")
    curl_auth_token.setopt(pycurl.POST, 1)
    curl_auth_token.setopt(pycurl.HTTPHEADER, ["X-Auth-User: cpca",
                          "X-Auth-Key: 438ac2d9-689f-4c50-9d00-c2883cfd38d0"])

    curl_auth_token.setopt(pycurl.HEADERFUNCTION, gettoken.write)
    curl_auth_token.perform()
    chg = gettoken.getvalue()

    auth_token = chg[chg.find("X-Auth-Token: ")+len("X-Auth-Token: ") : chg.find("X-Server-Management-Url:")-1]

    token = "X-Auth-Token: {0}".format(auth_token)
    curl_auth_token.close()

    #----------------------------

    getter = cStringIO.StringIO()
    curl_hab_image = pycurl.Curl()
    curl_hab_image.setopt(pycurl.URL, "http://192.168.100.241:8774/v1.1/nuvemcpca/images/7")
    curl_hab_image.setopt(pycurl.HTTPGET, 1) #tirei essa linha e funcionou, nao sei porque
    curl_hab_image.setopt(pycurl.HTTPHEADER, [token])

    curl_hab_image.setopt(pycurl.WRITEFUNCTION, getter.write)
    #curl_list.setopt(pycurl.VERBOSE, 1)
    curl_hab_image.perform()
    curl_hab_image.close()

    getter = cStringIO.StringIO()

    curl_list = pycurl.Curl()
    curl_list.setopt(pycurl.URL, "http://192.168.100.241:8774/v1.1/nuvemcpca/servers/detail")
    curl_list.setopt(pycurl.HTTPGET, 1) #tirei essa linha e funcionou, nao sei porque
    curl_list.setopt(pycurl.HTTPHEADER, [token])

    curl_list.setopt(pycurl.WRITEFUNCTION, getter.write)
    #curl_list.setopt(pycurl.VERBOSE, 1)
    curl_list.perform()
    curl_list.close()

    #----------------------------

    resp = getter.getvalue()

    con = int(resp.count("status"))

    s = json.loads(resp)

    lst = []

    for i in range(con):
        lst.append(s['servers'][i]['status'])

    for j in range(len(lst)):
        actual = lst.pop()
        print actual

        if actual != "ACTIVE" and actual != "BUILD" and actual != "REBOOT" and actual != "RESIZE":

            print "Entra no If"

            f = file('counter', 'r+w')

            num = 0
            for line in f:
                num = line

            content = int(num)+1

            ins = str(content)

            f.seek(0)
            f.write(ins)
            f.truncate()
            f.close()

            print "Contador"

            json_file = file('json_file_create_server.json','r+w')

            name_server_final = name_server_standart % content
            path_to_image = "http://192.168.100.241:8774/v1.1/nuvemcpca/images/7"
            path_to_flavor = "http://192.168.100.241:8774/v1.1/nuvemcpca/flavors/1"

            new_json_file_content = json_file_standart % (name_server_final, path_to_image, path_to_flavor)

            json_file.seek(0)
            json_file.write(new_json_file_content)
            json_file.truncate()
            json_file.close()

            print "Json File"

            fil = file("json_file_create_server.json")
            siz = os.path.getsize("json_file_create_server.json")

            cont_size = "Content-Length: %d" % siz
            cont_type = "Content-Type: application/json"
            accept = "Accept: application/json"

            c_create_servers = pycurl.Curl()

            logger = cStringIO.StringIO()

            c_create_servers.setopt(pycurl.URL, "http://192.168.100.241:8774/v1.1/nuvemcpca/servers")

            c_create_servers.setopt(pycurl.HTTPHEADER, [token, cont_type, accept, cont_size])

            c_create_servers.setopt(pycurl.POST, 1)

            c_create_servers.setopt(pycurl.INFILE, fil)

            c_create_servers.setopt(pycurl.INFILESIZE, siz)

            c_create_servers.setopt(pycurl.WRITEFUNCTION, logger.write)

            print "Teste perform"

            c_create_servers.perform()

            print logger.getvalue()

            c_create_servers.close()

Tự động hóa việc thực thi tập lệnh Python của bạn - hoạt động trên Linux và MacOS

Ảnh của Joel & Jasmin Førestbird trên unplash

Khi nói đến các nhiệm vụ lặp đi lặp lại, bạn tốt hơn là tự động hóa chúng. Bài viết này sẽ dạy cho bạn cách.

Sau khi đọc, bạn sẽ biết cách tự động hóa việc thực thi hai tập lệnh Python để tìm nạp, phân tích cú pháp và lưu dữ liệu khỏi web. Bắt đầu nào!

Bài viết được cấu trúc như sau:

  • Cron là gì?
  • Viết các kịch bản
  • Chỉnh sửa tập tin crontab
  • Kiểm tra
  • MacOS Gotchas
  • Sự kết luận

Cron là gì?

Viết các kịch bản

Chỉnh sửa tập tin crontab

Kiểm tra

MacOS Gotchas

Sự kết luận

Viết các kịch bản

Chỉnh sửa tập tin crontab

  • https://jsonplaceholder.typicode.com/users
  • https://jsonplaceholder.typicode.com/posts

Kiểm tra

MacOS Gotchas

Sự kết luận

Hãy nghĩ về Cron là một trong những cách dễ nhất để lên lịch các nhiệm vụ trong môi trường Linux và MacOS. Từ ngữ Cron Cron xuất phát từ từ Hy Lạp, Chronos, (thời gian), và từ ngữ crontab crontab là viết tắt của bảng cron cron hoặc bảng thời gian. Bạn sẽ học được một chút những gì mà bảng này đề cập đến.

Bạn nên sử dụng Cron bất cứ khi nào bạn muốn tự động hóa một cái gì đó, như một công việc HĐH hoặc kịch bản Python. Không cần phải nói, nhưng một kịch bản Python tự động có thể làm bất cứ điều gì.

Trên Linux và MacOS, Crontab bao gồm sáu lĩnh vực. Năm đầu tiên được dành riêng cho ngày và thời gian thực hiện theo lịch trình (phút, ngày của tháng, tháng trong năm, ngày trong tuần) và lĩnh vực cuối cùng được dành riêng cho một lệnh được thực hiện.

Bạn có thể tự do sử dụng dấu hoa thị, giá trị và phạm vi cho các trường thời gian ngày, nhưng nhiều hơn về điều đó một chút.

Bây giờ bạn biết Cron và Crontab là gì, nhưng chúng tôi vẫn cần một số tập lệnh Python trước khi làm việc để lên lịch. Hãy để chúng bao gồm chúng tiếp theo.

Hôm nay chúng tôi sẽ lên lịch hai kịch bản đơn giản. Công việc của họ là tìm nạp dữ liệu từ các trang web giả sau:

Các trang web này chứa dữ liệu giả về các chủ đề khác nhau, nhưng chúng tôi chỉ tập trung vào người dùng và bài đăng. Lý do duy nhất chúng tôi xử lý hai trang web là để chỉ ra cách lên lịch cho các công việc trong các khoảng thời gian khác nhau.

Cả hai tập lệnh sẽ tìm nạp dữ liệu thông qua cuộc gọi API requests.get(), phân tích dữ liệu JSON, xử lý nó (chỉ giữ một số thuộc tính nhất định), chuyển đổi nó thành một dữ liệu gấu trúc và lưu nó vào tệp CSV. Nghe có vẻ rất nhiều, nhưng nó chỉ có một vài dòng mã.

Hãy bắt đầu với tệp get_users.py:

Tệp get_posts.py sẽ giống nhau nhiều hoặc ít hơn - ngoại trừ phần xử lý:

Cuối cùng, hãy đảm bảo tạo ra output chỉ có các tập lệnh của bạn. Đó là tất cả những gì chúng ta cần. Nếu bạn chạy các tập lệnh, CSV sẽ lưu trong thư mục output với cấu trúc tên _.csv. Dấu thời gian ở đây để đảm bảo các tập tin không được ghi đè.

Hãy cùng xem cách sắp xếp các nhiệm vụ tiếp theo.

Chỉnh sửa tệp crontab

Nó không quan trọng nếu bạn trên Linux hoặc MacOS - phần này sẽ giống hệt nhau. Có một số gotchas cho phép macOS, nhưng chúng tôi sẽ nhận được điều đó sau.

Như đã thảo luận trước đây, bạn phải tuân theo một cú pháp cụ thể để lên lịch cho các công việc cron. Tin tốt là, bạn có thể sử dụng trang web crontab.guru để làm việc trong lịch trình của bạn.

Chúng tôi muốn get_users.py chạy vào mỗi phút thậm chí (ví dụ: 0, 2, 4) và get_posts.py để chạy trên mỗi phút lẻ (ví dụ: 1, 3, 5). Ở đây, mô hình chính xác để chạy một công việc vào mỗi phút chẵn:

Hình ảnh 1 - Mẫu công việc Cron cho mỗi lần thực hiện chẵn (hình ảnh của tác giả)

Và ở đây, trong những phút kỳ lạ:

Hình ảnh 2 - Mẫu công việc Cron cho mỗi lần thực hiện phút lẻ (hình ảnh của tác giả)

Neat - Hãy để sử dụng các mẫu này để lên lịch thực hiện. Mở cửa sổ đầu cuối và thực thi các lệnh
#!/usr/bin/python
# -*- coding: iso-8859-15 -*-

import json
import os
import pycurl
import sys
import cStringIO

if __name__ == "__main__":

    name_server_standart = "Server created by script %d"
    json_file_standart = "{ \"server\" : {  \"name\" : \"%s\", \"imageRef\" : \"%s\", \"flavorRef\" : \"%s\" } }"

    curl_auth_token = pycurl.Curl()

    gettoken = cStringIO.StringIO()

    curl_auth_token.setopt(pycurl.URL, "http://192.168.100.241:8774/v1.1")
    curl_auth_token.setopt(pycurl.POST, 1)
    curl_auth_token.setopt(pycurl.HTTPHEADER, ["X-Auth-User: cpca",
                          "X-Auth-Key: 438ac2d9-689f-4c50-9d00-c2883cfd38d0"])

    curl_auth_token.setopt(pycurl.HEADERFUNCTION, gettoken.write)
    curl_auth_token.perform()
    chg = gettoken.getvalue()

    auth_token = chg[chg.find("X-Auth-Token: ")+len("X-Auth-Token: ") : chg.find("X-Server-Management-Url:")-1]

    token = "X-Auth-Token: {0}".format(auth_token)
    curl_auth_token.close()

    #----------------------------

    getter = cStringIO.StringIO()
    curl_hab_image = pycurl.Curl()
    curl_hab_image.setopt(pycurl.URL, "http://192.168.100.241:8774/v1.1/nuvemcpca/images/7")
    curl_hab_image.setopt(pycurl.HTTPGET, 1) #tirei essa linha e funcionou, nao sei porque
    curl_hab_image.setopt(pycurl.HTTPHEADER, [token])

    curl_hab_image.setopt(pycurl.WRITEFUNCTION, getter.write)
    #curl_list.setopt(pycurl.VERBOSE, 1)
    curl_hab_image.perform()
    curl_hab_image.close()

    getter = cStringIO.StringIO()

    curl_list = pycurl.Curl()
    curl_list.setopt(pycurl.URL, "http://192.168.100.241:8774/v1.1/nuvemcpca/servers/detail")
    curl_list.setopt(pycurl.HTTPGET, 1) #tirei essa linha e funcionou, nao sei porque
    curl_list.setopt(pycurl.HTTPHEADER, [token])

    curl_list.setopt(pycurl.WRITEFUNCTION, getter.write)
    #curl_list.setopt(pycurl.VERBOSE, 1)
    curl_list.perform()
    curl_list.close()

    #----------------------------

    resp = getter.getvalue()

    con = int(resp.count("status"))

    s = json.loads(resp)

    lst = []

    for i in range(con):
        lst.append(s['servers'][i]['status'])

    for j in range(len(lst)):
        actual = lst.pop()
        print actual

        if actual != "ACTIVE" and actual != "BUILD" and actual != "REBOOT" and actual != "RESIZE":

            print "Entra no If"

            f = file('counter', 'r+w')

            num = 0
            for line in f:
                num = line

            content = int(num)+1

            ins = str(content)

            f.seek(0)
            f.write(ins)
            f.truncate()
            f.close()

            print "Contador"

            json_file = file('json_file_create_server.json','r+w')

            name_server_final = name_server_standart % content
            path_to_image = "http://192.168.100.241:8774/v1.1/nuvemcpca/images/7"
            path_to_flavor = "http://192.168.100.241:8774/v1.1/nuvemcpca/flavors/1"

            new_json_file_content = json_file_standart % (name_server_final, path_to_image, path_to_flavor)

            json_file.seek(0)
            json_file.write(new_json_file_content)
            json_file.truncate()
            json_file.close()

            print "Json File"

            fil = file("json_file_create_server.json")
            siz = os.path.getsize("json_file_create_server.json")

            cont_size = "Content-Length: %d" % siz
            cont_type = "Content-Type: application/json"
            accept = "Accept: application/json"

            c_create_servers = pycurl.Curl()

            logger = cStringIO.StringIO()

            c_create_servers.setopt(pycurl.URL, "http://192.168.100.241:8774/v1.1/nuvemcpca/servers")

            c_create_servers.setopt(pycurl.HTTPHEADER, [token, cont_type, accept, cont_size])

            c_create_servers.setopt(pycurl.POST, 1)

            c_create_servers.setopt(pycurl.INFILE, fil)

            c_create_servers.setopt(pycurl.INFILESIZE, siz)

            c_create_servers.setopt(pycurl.WRITEFUNCTION, logger.write)

            print "Teste perform"

            c_create_servers.perform()

            print logger.getvalue()

            c_create_servers.close()
1 và
#!/usr/bin/python
# -*- coding: iso-8859-15 -*-

import json
import os
import pycurl
import sys
import cStringIO

if __name__ == "__main__":

    name_server_standart = "Server created by script %d"
    json_file_standart = "{ \"server\" : {  \"name\" : \"%s\", \"imageRef\" : \"%s\", \"flavorRef\" : \"%s\" } }"

    curl_auth_token = pycurl.Curl()

    gettoken = cStringIO.StringIO()

    curl_auth_token.setopt(pycurl.URL, "http://192.168.100.241:8774/v1.1")
    curl_auth_token.setopt(pycurl.POST, 1)
    curl_auth_token.setopt(pycurl.HTTPHEADER, ["X-Auth-User: cpca",
                          "X-Auth-Key: 438ac2d9-689f-4c50-9d00-c2883cfd38d0"])

    curl_auth_token.setopt(pycurl.HEADERFUNCTION, gettoken.write)
    curl_auth_token.perform()
    chg = gettoken.getvalue()

    auth_token = chg[chg.find("X-Auth-Token: ")+len("X-Auth-Token: ") : chg.find("X-Server-Management-Url:")-1]

    token = "X-Auth-Token: {0}".format(auth_token)
    curl_auth_token.close()

    #----------------------------

    getter = cStringIO.StringIO()
    curl_hab_image = pycurl.Curl()
    curl_hab_image.setopt(pycurl.URL, "http://192.168.100.241:8774/v1.1/nuvemcpca/images/7")
    curl_hab_image.setopt(pycurl.HTTPGET, 1) #tirei essa linha e funcionou, nao sei porque
    curl_hab_image.setopt(pycurl.HTTPHEADER, [token])

    curl_hab_image.setopt(pycurl.WRITEFUNCTION, getter.write)
    #curl_list.setopt(pycurl.VERBOSE, 1)
    curl_hab_image.perform()
    curl_hab_image.close()

    getter = cStringIO.StringIO()

    curl_list = pycurl.Curl()
    curl_list.setopt(pycurl.URL, "http://192.168.100.241:8774/v1.1/nuvemcpca/servers/detail")
    curl_list.setopt(pycurl.HTTPGET, 1) #tirei essa linha e funcionou, nao sei porque
    curl_list.setopt(pycurl.HTTPHEADER, [token])

    curl_list.setopt(pycurl.WRITEFUNCTION, getter.write)
    #curl_list.setopt(pycurl.VERBOSE, 1)
    curl_list.perform()
    curl_list.close()

    #----------------------------

    resp = getter.getvalue()

    con = int(resp.count("status"))

    s = json.loads(resp)

    lst = []

    for i in range(con):
        lst.append(s['servers'][i]['status'])

    for j in range(len(lst)):
        actual = lst.pop()
        print actual

        if actual != "ACTIVE" and actual != "BUILD" and actual != "REBOOT" and actual != "RESIZE":

            print "Entra no If"

            f = file('counter', 'r+w')

            num = 0
            for line in f:
                num = line

            content = int(num)+1

            ins = str(content)

            f.seek(0)
            f.write(ins)
            f.truncate()
            f.close()

            print "Contador"

            json_file = file('json_file_create_server.json','r+w')

            name_server_final = name_server_standart % content
            path_to_image = "http://192.168.100.241:8774/v1.1/nuvemcpca/images/7"
            path_to_flavor = "http://192.168.100.241:8774/v1.1/nuvemcpca/flavors/1"

            new_json_file_content = json_file_standart % (name_server_final, path_to_image, path_to_flavor)

            json_file.seek(0)
            json_file.write(new_json_file_content)
            json_file.truncate()
            json_file.close()

            print "Json File"

            fil = file("json_file_create_server.json")
            siz = os.path.getsize("json_file_create_server.json")

            cont_size = "Content-Length: %d" % siz
            cont_type = "Content-Type: application/json"
            accept = "Accept: application/json"

            c_create_servers = pycurl.Curl()

            logger = cStringIO.StringIO()

            c_create_servers.setopt(pycurl.URL, "http://192.168.100.241:8774/v1.1/nuvemcpca/servers")

            c_create_servers.setopt(pycurl.HTTPHEADER, [token, cont_type, accept, cont_size])

            c_create_servers.setopt(pycurl.POST, 1)

            c_create_servers.setopt(pycurl.INFILE, fil)

            c_create_servers.setopt(pycurl.INFILESIZE, siz)

            c_create_servers.setopt(pycurl.WRITEFUNCTION, logger.write)

            print "Teste perform"

            c_create_servers.perform()

            print logger.getvalue()

            c_create_servers.close()
2 để có được các đường dẫn tuyệt đối đến thư mục tập lệnh của bạn và Python:

Hình ảnh 3 - Có được đường dẫn tuyệt đối (hình ảnh của tác giả)

Kiểm tra

MacOS Gotchas

Hình ảnh 8 - Thư mục đầu ra (hình ảnh của tác giả)

Như bạn có thể thấy, mọi thứ hoạt động như mong đợi. Don Tiết quên xóa hai công việc này, hoặc bạn sẽ kết thúc với 1440 tệp CSV mới mỗi ngày.

MacOS Gotchas

Người dùng Linux không nên có bất kỳ vấn đề nào, nhưng câu chuyện khác trên các macOS. Theo mặc định, MacOS không cung cấp quyền truy cập đĩa đầy đủ vào thiết bị đầu cuối và cron, vì vậy bạn sẽ phải làm điều đó bằng tay.

Chỉ cần rõ ràng - bạn đã giành được bất kỳ lỗi nào, nhưng thư mục output sẽ vẫn trống.

Nếu trường hợp đó, vui lòng theo dõi bài viết này - nó sẽ chỉ cho bạn cách cấp toàn bộ quyền truy cập đĩa cho cả thiết bị đầu cuối và cron.

Sự kết luận

Và ở đó bạn có nó - làm thế nào để dễ dàng lên lịch cho các kịch bản Python với Cron trên Linux và MacOS.

Các khả năng là vô tận - từ việc quét web theo lịch trình đến thực hiện tự động các đường ống ETL. Mã có thể thay đổi, nhưng nguyên tắc vẫn giống hệt nhau.

Chúc vui vẻ!

Yêu thích bài báo? Trở thành một thành viên trung bình để tiếp tục học tập mà không giới hạn. Tôi sẽ nhận được một phần phí thành viên của bạn nếu bạn sử dụng liên kết sau, không có thêm chi phí cho bạn.

Tìm hiểu thêm

  • 3 Sách lập trình Mỗi nhà khoa học dữ liệu phải đọc
  • Cách làm Python được gõ tĩnh - hướng dẫn cần thiết
  • Lập trình hướng đối tượng với Python - Mọi thứ bạn cần biết
  • Từ điển Python: Mọi thứ bạn cần biết
  • Giới thiệu chuỗi F-Các tùy chọn tốt nhất để định dạng chuỗi trong Python