it-swarm.com.de

Wie man CRON dazu bringt, die richtigen PFADs aufzurufen

Ich versuche, cron dazu zu bringen, die richtigen PFADs aufzurufen. Wenn ich ein Python-Skript von Shell aus ausführe, wird das Skript einwandfrei ausgeführt, da es die in bashrc festgelegten PATHs verwendet, aber wenn ich cron verwende, werden alle PATHs nicht von bashrc verwendet. Gibt es eine Datei, in die ich die PATHs für cron wie bashrc eingeben kann, oder eine Möglichkeit, die PATHs von bashrc aufzurufen?

Es tut mir leid, ich glaube nicht, dass ich das richtig formuliert habe. Ich kann das korrekte Skript ausführen (dh der Pfad zum Skript in crontab ist hier nicht das Problem). Es ist nur, wenn das Skript ausgeführt wird PATHs in .bashrc eingestellt. Wenn ich das Skript ausführte, wenn ich angemeldet bin, werden die .bashrc-PFADs eingezogen. Da cron nicht in einer Shell ausgeführt wird, wird .bashrc nicht aufgerufen. Gibt es eine Möglichkeit, dies herauszufinden, ohne einen bash-Script-Wrapper schreiben zu müssen?

104
chrissygormley

Ich habe /etc/crontab verwendet. Ich verwendete vi und gab die benötigten Pfade in diese Datei ein und führte sie als root aus. Die normale Crontab überschreibt von Ihnen eingerichtete PFADs. Ein gutes Tutorial, wie man das macht .

Die systemweite Cron-Datei sieht folgendermaßen aus:

This has the username field, as used by /etc/crontab.
# /etc/crontab: system-wide crontab
# Unlike any other crontab you don't have to run the `crontab'
# command to install the new version when you edit this file.
# This file also has a username field, that none of the other crontabs do.

Shell=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

# m h dom mon dow user   command
42 6 * * *   root    run-parts --report /etc/cron.daily
47 6 * * 7   root    run-parts --report /etc/cron.weekly
52 6 1 * *   root    run-parts --report /etc/cron.monthly
01 01 * * 1-5 root python /path/to/file.py
146
chrissygormley

Wahrscheinlich läuft Cron in einer sehr spärlichen Umgebung. Überprüfen Sie die Umgebungsvariablen, die cron verwendet, indem Sie einen Dummy-Job anhängen, der env in eine Datei wie diese abbildet:

* * * * * env > env_dump.txt

Vergleichen Sie das mit der Ausgabe von env in einer normalen Shell-Sitzung.

Sie können der lokalen Crontab Ihre eigenen Umgebungsvariablen voranstellen, indem Sie sie oben in Ihrer Crontab definieren.

Hier ist eine schnelle Lösung, um $PATH der aktuellen crontab voranzustellen:

# echo PATH=$PATH > tmp.cron
# echo >> tmp.cron
# crontab -l >> tmp.cron
# crontab tmp.cron

Die resultierende Crontab sieht der Antwort von chrissygormley ähnlich aus, wobei PATH vor den Crontab-Regeln definiert wird. 

45
joemaller

Sie sollten vollständige Pfade in Ihre crontab eingeben. Das ist die sicherste Option.
Wenn Sie dies nicht möchten, können Sie ein Wrapper-Skript um Ihre Programme legen und dort den PFAD setzen.

z.B.

01 01 * * * command

wird:

01 01 * * * /full/path/to/command

Auch alles, was von cron aufgerufen wird, sollte sehr vorsichtig mit den von ihm ausgeführten Programmen sein und wahrscheinlich eine eigene Wahl für die Variable PATH treffen.

BEARBEITEN:

Wenn Sie nicht wissen, wo der Befehl ist, den Sie ausführen möchten, führen Sie which <command> von Ihrer Shell aus aus, und der Pfad wird angezeigt. 

EDIT2:

Sobald Ihr Programm ausgeführt wird, sollten Sie zunächst PATH und jede andere erforderliche Variable (z. B. LD_LIBRARY_PATH) auf die Werte setzen, die für die Ausführung des Skripts erforderlich sind.
Statt zu überlegen, wie Sie die cron-Umgebung modifizieren können, damit sie für Ihr Programm/Skript besser geeignet ist, sollten Sie Ihr Skript mit der angegebenen Umgebung umgehen, indem Sie beim Start eine entsprechende festlegen.

19
Douglas Leeder

Sorgen Sie dafür, dass Ihre Variablen für Sie funktionieren. Dies ermöglicht den Zugriff auf t

Definiere deinen PFAD in /etc/profile.d/*.sh

Systemweite Umgebungsvariablen

Dateien mit der Erweiterung .sh im Verzeichnis /etc/profile.d werden bei jeder Eingabe einer bash-Login-Shell (z. B. beim Anmelden von der Konsole oder über ssh) sowie vom DisplayManager beim Laden der Desktopsitzung ausgeführt.

Sie können zum Beispiel die Datei /etc/profile.d/myenvvars.sh erstellen und Variablen wie folgt setzen:

export Java_HOME=/usr/lib/jvm/jdk1.7.0
export PATH=$PATH:$Java_HOME/bin

Crontab mit Login-Option ausführen!

CRONTAB Skript oder Befehl mit Umgebungsvariablen ausführen

0 9 * * * cd /var/www/vhosts/foo/crons/; bash -l -c 'php -f ./download.php'
0 9 * * * cd /var/www/vhosts/foo/crons/; bash -l -c download.sh
14
Artistan

Das Einstellen von PATH direkt vor der Befehlszeile in meinem Crontab funktionierte für mich:

* * * * * PATH=$PATH:/usr/local/bin:/path/to/some/thing
13
myrho

Problem

Ihr Skript funktioniert, wenn Sie es von der Konsole aus ausführen, aber in cron fehlschlägt.

Ursache

Ihre Crontab hat nicht die richtigen Pfadvariablen (und möglicherweise auch Shell)

Lösung

Fügen Sie Ihre aktuelle Shell hinzu und pflegen Sie die Crontab

Skript, um es für Sie zu tun

#!/bin/bash
#
# Date: August 22, 2013
# Author: Steve Stonebraker
# File: add_current_Shell_and_path_to_crontab.sh
# Description: Add current user's Shell and path to crontab
# Source: http://brakertech.com/add-current-path-to-crontab
# Github: hhttps://github.com/ssstonebraker/braker-scripts/blob/master/working-scripts/add_current_Shell_and_path_to_crontab.sh

# function that is called when the script exits (cleans up our tmp.cron file)
function finish { [ -e "tmp.cron" ] && rm tmp.cron; }

#whenver the script exits call the function "finish"
trap finish EXIT

########################################
# pretty printing functions
function print_status { echo -e "\x1B[01;34m[*]\x1B[0m $1"; }
function print_good { echo -e "\x1B[01;32m[*]\x1B[0m $1"; }
function print_error { echo -e "\x1B[01;31m[*]\x1B[0m $1"; }
function print_notification { echo -e "\x1B[01;33m[*]\x1B[0m $1"; }
function printline { 
  hr=-------------------------------------------------------------------------------------------------------------------------------
  printf '%s\n' "${hr:0:${COLUMNS:-$(tput cols)}}"
}
####################################
# print message and exit program
function die { print_error "$1"; exit 1; }

####################################
# user must have at least one job in their crontab
function require_gt1_user_crontab_job {
        crontab -l &> /dev/null
        [ $? -ne 0 ] && die "Script requires you have at least one user crontab job!"
}


####################################
# Add current Shell and path to user's crontab
function add_Shell_path_to_crontab {
    #print info about what's being added
    print_notification "Current Shell: ${Shell}"
    print_notification "Current PATH: ${PATH}"

    #Add current Shell and path to crontab
    print_status "Adding current Shell and PATH to crontab \nold crontab:"

    printline; crontab -l; printline

    #keep old comments but start new crontab file
    crontab -l | grep "^#" > tmp.cron

    #Add our current Shell and path to the new crontab file
    echo -e "Shell=${Shell}\nPATH=${PATH}\n" >> tmp.cron 

    #Add old crontab entries but ignore comments or any Shell or path statements
    crontab -l | grep -v "^#" | grep -v "Shell" | grep -v "PATH" >> tmp.cron

    #load up the new crontab we just created
    crontab tmp.cron

    #Display new crontab
    print_good "New crontab:"
    printline; crontab -l; printline
}

require_gt1_user_crontab_job
add_Shell_path_to_crontab

Quelle

https://github.com/ssstonebraker/braker-scripts/blob/master/working-scripts/add_current_Shell_and_path_to_crontab.sh

Beispielausgabe

add_curent_Shell_and_path_to_crontab.sh example output

9
brakertech

Wenn Sie eine PATH-Definition mit korrekten Werten in die Benutzer-Crontab hinzufügen, wird dies hilfreich sein.

PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

Und es ist genug, um alle meine Skripte zum Laufen zu bringen ... Fügen Sie bei Bedarf jeden benutzerdefinierten Pfad hinzu.

9
Treviño

Auf meinem AIX greift cron seine Umgebungsvariablen aus/etc/environment auf und ignoriert, was in der .profile gesetzt ist. 

Edit: Ich habe auch ein paar Linux-Boxen verschiedener Altersstufen ausgecheckt, und diese scheinen auch diese Datei zu haben, daher ist dies wahrscheinlich nicht AIX-spezifisch. 

Ich habe dies anhand des Cron-Vorschlags von joemaller überprüft und die Ausgabe vor und nach der Bearbeitung der PATH-Variablen in/etc/environment überprüft.

2
Van Amburg

Die Standardumgebung für Cron-Jobs ist sehr spärlich und unterscheidet sich möglicherweise sehr von der Umgebung, in der Sie Ihre Python-Skripts entwickeln. Für ein Skript, das möglicherweise in Cron ausgeführt wird, sollte jede Umgebung, von der Sie abhängig sind, explizit festgelegt werden. Fügen Sie in der Cron-Datei selbst vollständige Pfade zu ausführbaren Python-Dateien und zu Ihren Python-Skripts ein.

2
mob

Ich weiß, dass dies bereits beantwortet wurde, aber ich dachte, dass dies für einige nützlich sein würde. Ich hatte ein ähnliches Problem, das ich kürzlich gelöst habe ( hier gefunden ), und hier sind die Highlights der Schritte, die ich zur Beantwortung dieser Frage unternommen habe:

  1. stellen Sie sicher, dass Sie die benötigten Variablen in PYTHONPATH (hier und hier und für weitere Informationen hier) im .profile oder .bash_profile für jede Shell haben, in der Sie Ihr Skript testen möchten, um sicherzustellen, dass es funktioniert.

  2. bearbeiten Sie Ihre Crontab, um die Verzeichnisse aufzunehmen, die zum Ausführen des Skripts in einem Cron-Job erforderlich sind (hier und hier).

    a) Stellen Sie sicher, dass Sie das Root-Verzeichnis in die PATH-Variable (.) einschließen, wie hier erklärt (im Wesentlichen, wenn Sie eine ausführbare Datei mit Ihrem Befehl ausführen, muss es in der Lage sein, root oder das Verzeichnis zu finden, in dem die ausführbare Datei gespeichert ist) und möglicherweise auch diese (/ sbin:/bin:/usr/sbin:/usr/bin)

  3. erstellen Sie in Ihrer Crontab-Datei einen Cronjob, der das Verzeichnis in das Verzeichnis ändert, in dem Sie das Skript zuvor erfolgreich ausgeführt haben (d. h. Benutzer/Benutzer/Dokumente/Foo).

    a) Das sieht wie folgt aus:

    * * * * cd /Users/user/Documents/foo; bar -l doSomething -v 
    
2
derigible

@Trevino: Deine Antwort hat mir geholfen, mein Problem zu lösen. Versuchen Sie jedoch für Anfänger, Schritt für Schritt vorzugehen. 

  1. Erhalten Sie Ihre aktuelle Java-Installation über $ echo $Java_HOME.
  2. $ crontab -e
  3. * * * * * echo $PATH - Damit wissen Sie, was der von Crontab derzeit verwendete PATH-Wert ist. Führen Sie crontab aus und holen Sie sich den von crontab verwendeten $ PATH-Wert.
  4. Bearbeiten Sie nun crontab erneut, um den gewünschten Java-Bin-Pfad festzulegen: a) crontab -e; b) PATH=<value of $Java_HOME>/bin:/usr/bin:/bin (es handelt sich um einen Beispielpfad); c) jetzt Ihren geplanten Job/Skript wie */10 * * * * sh runMyJob.sh &; d) Entfernen Sie echo $PATH von crontab, da es jetzt nicht mehr benötigt wird.
1
Ram Dwivedi

Die einfachste Problemumgehung, die ich gefunden habe, sieht so aus:

* * * * * root su -l -c command

In diesem Beispiel wird su als Rootbenutzer aufgerufen und die Shell wird mit der vollständigen Umgebung des Benutzers, einschließlich $ PATH, gestartet, als wären sie angemeldet. Sie funktioniert auf verschiedenen Distros gleich und ist zuverlässiger als das Erstellen von .bashrc (das nicht funktioniert hat) für mich) und vermeidet das Festcodieren spezifischer Pfade, die ein Problem darstellen können, wenn Sie ein Beispiel- oder Setup-Tool angeben und nicht wissen, welches Distro- oder File-Layout auf dem System des Benutzers vorhanden ist.

Sie können den Benutzernamen auch nach su angeben, wenn Sie einen anderen Benutzer als root verwenden möchten. Der root-Parameter sollte jedoch wahrscheinlich vor dem Befehl su stehen, da su über ausreichende Berechtigungen verfügt, um zu einem von Ihnen angegebenen Benutzer zu wechseln.

1
tasket

Wenn Sie nicht an verschiedenen Stellen die gleichen Änderungen vornehmen möchten, tun Sie dies ungefähr:

* * * * * . /home/username/.bashrc && yourcommand all of your args

Das . Leerzeichen und dann der Pfad zu .bashrc und der Befehl && sind der Zauber, um Änderungen an Ihrer Umgebung in die laufende Bash-Shell zu bringen. Wenn Sie wirklich wollen, dass die Shell bash ist, ist es eine gute Idee, eine Zeile in Ihrer Crontab zu haben:

Shell=/bin/bash

Hoffe es hilft jemandem!

1
Wade Chandler

Stellen Sie den gewünschten PFAD in Ihrem cron ein 

crontab -e

Bearbeiten: Drücken Sie i

PATH=/usr/local/bin:/usr/local/:or_whatever

10 * * * * your_command

Speichern und beenden Sie :wq

0
shiva