Python-Skript schreibt keine Daten, wenn es von cron ausgeführt wird

7

Wenn ich ein Python-Skript in einem Terminal ausführe, wird es wie erwartet ausgeführt. lädt die Datei herunter und speichert sie an der gewünschten Stelle.

sudo python script.py    

Ich habe das Python-Skript zur Root-Crontab hinzugefügt, aber dann wird es so ausgeführt, wie es soll, außer dass die Datei nicht geschrieben wird.

$ sudo crontab -l
> * * * * * python /home/test/script.py >> /var/log/test.log 2>&1

Unten finden Sie ein vereinfachtes Skript, bei dem das Problem weiterhin besteht:

#!/usr/bin/python

scheduleUrl = 'http://test.com/schedule.xml'
schedule = '/var/test/schedule.xml'

# Download url and save as filename
def wget(url, filename):
    import urllib2
    try:
        response = urllib2.urlopen(url)
    except Exception:
        import traceback
        logging.exception('generic exception: ' + traceback.format_exc())
    else:
        print('writing:'+filename+';')
        output = open(filename,'wb')
        output.write(response.read())
        output.close()

# Download the schedule
wget(scheduleUrl, schedule)

Ich erhalte die Meldung "Schreiben: Name der Datei;" innerhalb des Protokolls, an das der Cron-Eintrag ausgegeben wird. Aber die eigentliche Datei ist nirgends zu finden ...

Das Verzeichnis / var / test ist auf 777 geändert und mit jedem Benutzer kann ich Dateien nach Belieben hinzufügen und ändern.

Ruud
quelle
Es ist eine Rechtefrage. Ich habe herausgefunden, dass alles gut funktioniert, wenn ich die Dateien habe, die ich schreiben möchte, und diese auf so etwas wie 666 modifiziere. Wie kann man Python dazu bringen, auch schreiben zu können? Ich dachte, wenn ich das Skript zur sudo crontab hinzufüge, würde es mit einigen Privilegien laufen, die ich normalerweise hätte, wenn ich mich selbst sudoing ...
Ruud
1
Sie können nicht sudo, wenn Sie nicht da sind. Mit diesem Befehl erhalten Sie vorübergehend erhöhte Rechte, die auf der Eingabe des erforderlichen Kennworts beruhen.
David6
david6 dachte ich, dass durch das Hinzufügen mit sudo crontab filename.cron die Skripte so ausgeführt würden, als ob sie mit sudo ausgeführt würden. Also mit erhöhten Rechten. Das ist nicht richtig?
Ruud
Der Befehl sudo crontab -l meldet Ihre aktuellen crontab-Einstellungen. Das "Sudo" würde nichts bewirken. Sie müssten etwas wie die Verwendung von 'cron' (für Root-Benutzer) [Nicht empfohlen] ausprobieren - Sie sollten sich stattdessen Folgendes ansehen : chroot .
David6
david6; Sie liegen falsch. sudo crontab -l und crontab -l zeigen unterschiedliche Einträge an. Und bis jetzt erhalte ich keine verweigerten Berechtigungen für Aufgaben in der sudo crontab für Aufgaben, die diese Meldung in der aktuellen Benutzer-crontab anzeigen.
Ruud

Antworten:

4
  • Überprüfen Sie die Protokolldateien grep -i cron /var/log/syslog
  • Fügen Sie am Ende der Crontab eine leere Zeile hinzu. Dies ist seit Ewigkeiten ein bekannter Fehler, nicht sicher, ob er behoben ist.
  • Entfernen Sie das 2>&1von der Befehlszeile, bis es wie vorgesehen funktioniert. Alle nützlichen Fehler werden in eine Datei umgeleitet, die nicht erstellt wurde. effektiv verloren.
  • Überprüfen Sie, ob root E-Mails empfangen hat (z. B. mit muttoder in /var/spool/mail). Fehlermeldungen von cron werden standardmäßig an System-E-Mails gesendet.

Ebenfalls:

  • Überdenken Sie die 777-Berechtigungen so schnell wie möglich. Bei der Ausführung von root sollte 755 root: root ausreichen, um die Protokolle von nicht privilegierten Benutzern überprüfen zu können.
  • Überdenken Sie das Ausführen des Skripts von root, es ist eine schlechte Praxis.
Jippie
quelle
1

Was funktioniert bei mir?

Crontab

#Borrowed from anacron
SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
#End borrowed from anacron

* * * * *   python /home/username/somedir/test.py

Python-Skript

scheduleUrl = 'http://example.com/index.html'
schedule = '/tmp/test.html'

# Download url and save as filename
def wget(url, filename):
    import urllib2
    try:
        response = urllib2.urlopen(url)
    except Exception:
        import logging
        logging.exception('error')
    else:
        print('writing:'+filename+';')
        output = open(filename,'wb')
        output.write(response.read())
        output.close()

# Download the schedule
wget(scheduleUrl, schedule)

Umgebungsvariablen hinzugefügt. Verwendet tmp anstelle von var, um zu überprüfen, ob keine Berechtigungsprobleme vorliegen.

RobotHumans
quelle
0

Für mich war die Lösung so einfach wie das Ändern des Dateizugriffsmodus. Anstatt:

output = open(filename,'wb')

Versuchen:

output = open(filename,'rb+')

Ich habe dies verwendet, um Craigslist für Stellenausschreibungen (für mich selbst) zu kratzen und in eine Datenbank zu modellieren. Alles auf einem Himbeer-Pi gemacht.

Ich habe das gefunden und es ist dem Problem, das ich hatte, sehr ähnlich, obwohl ich meine Antwort von hier nicht ganz bekommen habe. Der Cron-Job wurde ausgeführt, aber das Python-Skript schrieb keine Dateien, wenn es über einen Cron-Job ausgeführt wurde. Das Skript würde Web-Scraped-Textdateien schreiben, wenn es über die Befehlszeile ausgeführt wird.

Lösung für mich war einfach das wbzu rb+ rb+ Öffnet eine Datei zum Lesen und Schreiben im Binärformat. Der Dateizeiger am Anfang der Datei.

Andrew Sychra
quelle
Eigentlich mein Fehler. Ich habe zu wb + gewechselt, aber der wichtigste Gedanke ist, beim Speichern der Datei den absoluten Dateipfad zu verwenden. file = open ('absolute / path / to / file.txt', 'wb +') Jetzt funktionieren die Dinge
Andrew Sychra
0

Ich hatte ein ähnliches Problem:

f = open('./my_file.txt', 'w')
f.close()

Öffnete und schrieb die Datei nicht, wenn sie von cron ausgeführt wurde. Dies löste es

f = open('<full_path_of_file>/my_file.txt', 'w')
f.close()
Luis Miguel
quelle