เรียกใช้สคริปต์ Python ผ่าน crontab


91

ฉันพยายามที่จะดำเนินการสคริปต์ Python ใช้ลินุกซ์crontab ฉันต้องการเรียกใช้สคริปต์นี้ทุกๆ 10 นาที

ฉันพบวิธีแก้ปัญหามากมายและไม่มีวิธีใดได้ผล ตัวอย่างเช่น: แก้ไข anacron ที่/etc/cron.dcrontab -eหรือการใช้งาน ฉันวางบรรทัดนี้ไว้ที่ส่วนท้ายของไฟล์ แต่มันไม่ได้เปลี่ยนแปลงอะไรเลย ฉันต้องเริ่มบริการใหม่หรือไม่?

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

ไฟล์ใดที่ฉันต้องแก้ไขเพื่อกำหนดค่านี้


นี่คือสคริปต์

#!/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()

เมื่อคุณพูดว่า "มันไม่เปลี่ยนแปลงอะไรเลย" มันแสดงข้อผิดพลาดมันไม่ทำงาน? มีพฤติกรรมอย่างไร?
Raul Marengo

"Documets" แทนที่จะเป็น "Documents" โดยเจตนาหรือไม่?
Raul Marengo

เพียงแค่ไม่เกิดอะไรขึ้น :(
guisantogui

ประเภทนี้เกินขอบเขตของคำถาม แต่คุณคาดหวังให้สคริปต์ "listener.py" ทำอะไร มันทำอะไรที่บ่งบอกว่ามันทำงานอยู่หรือเปล่า? ทำ ps -ef | grep 'crond' ในบรรทัดคำสั่งของคุณเพื่อตรวจสอบว่า cron กำลังทำงานอยู่หรือไม่
Raul Marengo

ไม่สคริปต์นี้ส่งคำสั่งของ cURL ไปยังคอมพิวเตอร์เครื่องอื่น เมื่อฉันรัน "ps -f | grep 'crond'" มันจะส่งกลับสิ่งนี้: "souza 4736 3947 0 14:01 pts / 1 00:00:00 grep --color = auto crond"
guisantogui

คำตอบ:


131

เพียงใช้crontab -eและทำตามบทแนะนำที่นี่

ดูข้อ 3 สำหรับคำแนะนำเกี่ยวกับวิธีระบุความถี่

ตามความต้องการของคุณควรมีประสิทธิภาพ:

*/10 * * * * /usr/bin/python script.py

1
ฉันทำตามบทช่วยสอนนี้ แต่เมื่อฉันบันทึกไฟล์ปรากฏข้อความ: "/tmp/crontab.JTQ0My/crontab":22: ข้อผิดพลาดที่ไม่ดีในไฟล์ crontab ไม่สามารถติดตั้งได้ คุณต้องการลองแก้ไขแบบเดิมอีกครั้งหรือไม่ (y / n) "ถ้าฉันพิมพ์" y "ฉันจะกลับไปแก้ไขไฟล์และถ้าฉันพิมพ์" n "ไฟล์จะไม่ถูกบันทึกฉันเพิ่มบรรทัดนี้ที่บรรทัดสุดท้ายของไฟล์:" / 1 * * * * / usr / bin / python script.py "
guisantogui

@guisantogui มีประเด็นหนึ่งในบทช่วยสอนที่อธิบายว่าระบบปฏิบัติการบางระบบอาจไม่รองรับการใช้ "/ 1" คุณใช้ระบบปฏิบัติการใดอยู่
Raul Marengo

3
@guisantogui เพิ่งสังเกตเห็นว่าคุณไม่มี "*" ก่อนวันที่ "/"
Raul Marengo

อีกวิธีหนึ่งคือเพิ่มการประกาศ env ใน script.py ของคุณ ดูความคิดเห็นของฉันเกี่ยวกับโซลูชันที่ยอมรับได้ที่: stackoverflow.com/questions/25633737/python-crontab-and-paths
Quetzalcoatl

จะเกิดอะไรขึ้นถ้าคุณต้องการดำเนินการscript.pyเฉพาะในไดเร็กทอรีที่กำหนด?
Shubham A.

68

ใส่สคริปต์ของคุณในไฟล์ที่foo.pyขึ้นต้นด้วย

#!/usr/bin/python

จากนั้นให้สิทธิ์ดำเนินการกับสคริปต์นั้นโดยใช้

chmod a+x foo.py

และใช้เส้นทางแบบเต็มของfoo.pyไฟล์ในไฟล์crontab.

ดูเอกสารของexecve (2)ซึ่งมีการจัดการshebang


1
@Tomer ถ้าเป็น POSIX shเชลล์สคริปต์ใช่ ถ้าพวกเขาใช้คุณสมบัติที่ไม่เป็นมาตรฐานที่เฉพาะเจาะจงเพื่อksh, zshหรือbashแล้วพวกเขาก็จะต้องมีการทำงานโดยใช้เปลือกเฉพาะที่
tripleee

28

ตามที่คุณได้กล่าวไว้มันไม่ได้เปลี่ยนแปลงอะไรเลย

ขั้นแรกคุณควรเปลี่ยนเส้นทางทั้งอินพุตมาตรฐานและข้อผิดพลาดมาตรฐานจากการดำเนินการ crontab ดังต่อไปนี้:

*/2 * * * * /usr/bin/python /home/souza/Documets/Listener/listener.py > /tmp/listener.log 2>&1

จากนั้นคุณสามารถดูไฟล์/tmp/listener.logเพื่อดูว่าสคริปต์ทำงานตามที่คุณคาดไว้หรือไม่

ประการที่สองฉันเดาว่าคุณหมายถึงอะไรจากการเปลี่ยนแปลงทุกอย่างโดยดูไฟล์ที่สร้างโดยโปรแกรมของคุณ:

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

งาน crontab ด้านบนจะไม่สร้างไฟล์เหล่านี้ในไดเร็กทอรี/home/souza/Documets/Listenerเนื่องจากงาน cron ไม่ได้ทำงานในไดเร็กทอรีนี้และคุณใช้พา ธ สัมพัทธ์ในโปรแกรม ดังนั้นในการสร้างไฟล์นี้ในไดเร็กทอรี/home/souza/Documets/Listenerงาน cron ต่อไปนี้จะทำเคล็ดลับ:

*/2 * * * * cd /home/souza/Documets/Listener && /usr/bin/python listener.py > /tmp/listener.log 2>&1

เปลี่ยนเป็นไดเร็กทอรีการทำงานและเรียกใช้สคริปต์จากที่นั่นจากนั้นคุณสามารถดูไฟล์ที่สร้างขึ้นในตำแหน่ง


2> & 1 mean คืออะไร?
Mohideen bin Mohammed

1
@MohideenibnMohammed เปลี่ยนเส้นทางข้อความแสดงข้อผิดพลาด ( stderr) ไปยังบรรทัดคำสั่งที่มองเห็นได้ ( stdout)
Juha Untinen

คำตอบนี้เป็นคำตอบที่คุณควรใช้หากคุณใช้เส้นทางสัมพัทธ์
DaReal

คำตอบนี้สามารถใช้ได้กับสิ่งนี้: stackoverflow.com/questions/65586171/… ?
Devilhorn
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.