Was ist das 'Arbeitsverzeichnis', wenn cron einen Job ausführt?

170

Ich habe ein Skript, das funktioniert, wenn ich es über die Befehlszeile ausführe, aber wenn ich es mit cronplane, erhalte ich die Fehlermeldung, dass es keine Dateien oder Befehle finden kann. Meine Frage ist zweifach:

  1. Wenn ich einen Cron-Job mit terminiere crontab -e, verwendet er meine Benutzer-ID als Grundlage für seine Berechtigungen? Oder verwendet es eine Cron-Benutzer-ID und die damit verbundenen Berechtigungen?

  2. Was ist das Arbeitsverzeichnis, wenn ein Cron-Job gestartet wird? Ist es das Verzeichnis, in dem ich das auszuführende Skript spezifiziere, oder ein anderes Verzeichnis?

Hier ist mein Cron Job:

15 7 * * * /home/xxxx/Documents/Scripts/email_ip_script.sh

Hier ist das aktuelle Skript:

vIP_ADDR="`curl automation.whatismyip.com/n09230945.asp`"
echo "$vIP_ADDR"
sed "s/IPADDR/$vIP_ADDR/g" template.txt > emailmsg.txt
ssmtp [email protected] < emailmsg.txt

Folgende Fehler werden beim Anzeigen der mailNachricht angezeigt, die von cron:

sed: can't read template.txt: No such file or directory
/home/xxxx/Documents/Scripts/email_ip_script.sh: line 15: ssmtp: command not found

Es kann das nicht finden, template.txtaber es befindet sich im selben Verzeichnis wie das Skript. Es kann auch nicht laufen ssmtp, aber ich kann als mein Benutzer. Was fehlt mir, damit das richtig funktioniert?

ProfessionalAmateur
quelle

Antworten:

158

Fügen cd /home/xxxx/Documents/Scripts/Sie hinzu, wenn Ihr Job in diesem Verzeichnis ausgeführt werden soll. Es gibt keinen Grund, warum cron in dieses bestimmte Verzeichnis wechseln würde. Cron führt Ihre Befehle in Ihrem Home-Verzeichnis aus.

Was ssmtpkönnte es nicht in Ihrem Standard sein PATH. Der Standardpfad von Cron ist implementierungsabhängig. Überprüfen Sie also Ihre Manpage, aber aller Wahrscheinlichkeit nach ssmtpist /usr/sbindies nicht der Standardpfad von Cron, sondern PATHnur der von root.

PATH=/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin
15 7 * * * cd /home/xxxx/Documents/Scripts && ./email_ip_script.sh
Gilles
quelle
@Giles - Danke, hätte crones ein eigenes PATHoder kann ich das meines Benutzers überprüfen PATH? Ich habe ssmtp bis haben seine eigene userund die wheelErlaubnis dachte , es würde jemand erlauben , es zu benutzen (einschließlich cron). Wenn es hilft Im auf CENTOS 6.2
ProfessionalAmateur
3
@ProfessionalAmateur Ihr Problem ist nicht, dass Sie nicht verwenden dürfen ssmtp, sondern dass Ihr Cron-Job keine aufgerufene ausführbare Datei findet, ssmtpweil sie nicht in Ihrer ist PATH. Es gibt keinen "Benutzer PATH"; Dies ist eine Einstellung pro Prozess, keine Einstellung pro Benutzer. Sie können den Pfad für alle Ihre Cron-Jobs festlegen, indem Sie eine PATH=…Linie in Ihre Crontab einfügen.
Gilles
Ich musste auch MAILTO='[email protected] 'hinzufügen, damit es mit dem PATH-Setup funktioniert. Wierd aber es hat bei mir geklappt.
Mac
Für ssmtp kann man verwenden; ´which ssmtp´ ...
Fredrick Gauß
@FredrickGauss Machen Sie dastype ssmtp
Gilles
20

Wenn es sich bei Ihrem Cronjob um ein Bash-Skript handelt, wird Folgendes an den Speicherort Ihres Skripts kopiert (vorausgesetzt, Sie verwenden in Ihrer Cron-Definition den absoluten Pfad):

cd "$(dirname "$0")";
Hugo
quelle
14

Zur Beantwortung von Frage 1: Wenn Sie crontab -eals eigener Benutzer ausgeführt werden, werden die Jobs in der crontab dieses Benutzers eingeplant und daher mit den Berechtigungen dieses Benutzers ausgeführt.

Sie müssen jedoch berücksichtigen, dass die Jobs in einer nicht interaktiven Shell ausgeführt werden. Dies bedeutet, dass sich $ PATH möglicherweise von dem unterscheidet, den Sie beim Ausführen des Skripts über die Befehlszeile haben.

Es ist am besten, in Skripten immer vollständige Pfade zu verwenden, insbesondere wenn Sie planen, diese über at / cron usw. zu planen.

Ich würde auch empfehlen, vollständige Pfade zu allen Dateien zu verwenden, um genau die Probleme zu vermeiden, die Sie sehen.

Um Rennbedingungen und andere Sicherheitsprobleme zu vermeiden, sollten Sie auch mktempsicherstellen, dass die gelesene Datei durch nichts außerhalb Ihres Skripts geändert wird.

Also würde ich das Skript in etwas ändern wie:

vIP_ADDR="`curl automation.whatismyip.com/n09230945.asp`"
echo "$vIP_ADDR"
mail_msg=`/bin/mktemp`
/bin/sed "s/IPADDR/$vIP_ADDR/g" /home/xxxx/Documents/Scripts/template.txt > $mailmsg
/path/to/ssmtp [email protected] < $mailmsg
/bin/rm $mailmsg
Bram
quelle
7

cronführt die geplanten Jobs jedes Benutzers als dieser Benutzer aus. Dies sollte ausreichen, damit wir feststellen können, dass Ihre Skripte im Verhältnis zu Ihrem Home-Verzeichnis ausgeführt werden.

Wenn Sie es von einem anderen Ort ausführen müssen, verwenden Sie einfach cdin Ihrem Skript, um zu diesem Ort zu gelangen.

ssmtpist wahrscheinlich nicht in cronder Standardeinstellung von PATH enthalten (auf den meisten Plattformen ist der Wert von vornherein sehr eng eingestellt). Sie können entweder den vollständigen Pfad zu ssmtpin Ihrem Skript angeben oder Sie können PATH explizit in a) Ihrer crontab-Datei festlegen, die für alle Ihre Skripte verfügbar sein wird, oder b) in jedem Skript.

D_Bye
quelle
3

Überprüfen Sie in diesem Thread, wie Sie die Umgebung von cron auf einfache Weise herausfinden können. Es ist viel weniger als in einer interaktiven Shell üblich. Nehmen Sie am besten an, dass nichts festgelegt wurde, und legen Sie es explizit selbst fest.

jippie
quelle
1

Das Standardarbeitsverzeichnis für die cronAusführung des Jobs ist normalerweise das Basisverzeichnis /home/your-user-name.

Annahme @ Kusalananda ausgezeichneten Kommentar.

Intelligente Menschen helfen anderen
quelle
1
Nein, es hängt davon ab, wo das System die Home-Verzeichnisse aufbewahrt. /homeist alles andere als universell.
Kusalananda
1
@ Kusalananda Der LSB-Standard sagt /home.
Peterh
1
@peterh Nun, macOS verwendet /Usersund historische Unices verwenden /usr, und selbst unter Linux kann sich das Home-Verzeichnis eines Systembenutzers irgendwo darunter /varoder anderswo befinden.
Kusalananda
1
@ Kusalananda Es ist richtig.
Peterh
Danke, du bist die einzige Person, die diese Frage tatsächlich beantwortet hat :)
OwN
0

Einige Leute haben es angedeutet oder verlinkt, aber der beste Weg, es herauszufinden, da ich es in den Man Docs für meine Distribution nicht finden kann, ist, es einfach einem Cron hinzuzufügen

* * * * * echo $PATH > /tmp/lolcronjobs

In meinem Fall verwendet Ubuntu standardmäßig nur das, /usr/bin:/binwas einige Probleme verursacht hat.

mschuett
quelle