J'essaye de faire en sorte que cron appelle les PATH corrects. Lorsque j'exécute un script Python à partir de Shell, le script fonctionne correctement car il utilise les PATH définis dans bashrc, mais lorsque j'utilise cron, tous les PATH ne sont pas utilisés depuis bashrc. Existe-t-il un fichier dans lequel je peux entrer les PATH pour cron comme bashrc ou un moyen d'appeler les PATH depuis bashrc?
Désolé, je ne pense pas avoir correctement formulé cela, je peux obtenir le bon script à exécuter (ce qui signifie que le PATH du script dans crontab n'est pas le problème ici), CHEMINS définis dans .bashrc
. Lorsque j'exécute le script lorsque je suis connecté, les chemins .bashrc
sont extraits. Puisque cron ne s'exécute pas dans un shell, il ne récupère pas non plus le .bashrc
. Existe-t-il un moyen d’insérer cela sans avoir à écrire un wrapper de script bash?
J'ai utilisé /etc/crontab
. J'ai utilisé vi
et entré dans les chemins d'accès dont j'avais besoin dans ce fichier et je l'ai exécuté en tant que root. La crontab normale écrase les chemins PATH que vous avez configurés. Un bon tutoriel sur la façon de faire cela .
Le fichier cron à l'échelle du système ressemble à ceci:
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
Très probablement, cron fonctionne dans un environnement très clairsemé. Vérifiez les variables d'environnement utilisées par cron en ajoutant un travail fictif qui copie env
dans un fichier comme celui-ci:
* * * * * env > env_dump.txt
Comparez cela avec le résultat de env
dans une session Shell normale.
Vous pouvez ajouter vos propres variables d’environnement à la crontab locale en les définissant en haut de votre crontab.
Voici une solution rapide pour ajouter $PATH
à la crontab actuelle:
# echo PATH=$PATH > tmp.cron
# echo >> tmp.cron
# crontab -l >> tmp.cron
# crontab tmp.cron
La crontab résultante ressemblera à la réponse de chrissygormley, avec PATH défini avant les règles de la crontab.
Vous devriez mettre des chemins complets dans votre crontab
. C'est l'option la plus sûre.
Si vous ne voulez pas faire cela, vous pouvez mettre un script wrapper autour de vos programmes et y placer le PATH.
par exemple.
01 01 * * * command
devient:
01 01 * * * /full/path/to/command
De même, tout ce qui est appelé depuis cron
doit faire très attention aux programmes qu’il exécute et définir probablement son propre choix pour la variable PATH
.
MODIFIER:
Si vous ne savez pas où la commande consiste à exécuter which <command>
à partir de votre shell, il vous indiquera le chemin.
EDIT2:
Ainsi, une fois que votre programme est en cours d'exécution, la première chose à faire est de définir PATH
et toute autre variable requise (par exemple, LD_LIBRARY_PATH
) sur les valeurs requises pour l'exécution du script.
Au lieu de penser à la modification de l’environnement cron pour l’adapter davantage à votre programme/script, faites en sorte que votre script gère l’environnement qui lui est attribué en définissant un environnement approprié au démarrage.
Faites que vos variables fonctionnent pour vous, cela permettra l'accès
Définissez votre PATH dans /etc/profile.d/*.sh
Variables d'environnement à l'échelle du système
Les fichiers portant l'extension .sh dans le répertoire /etc/profile.d sont exécutés chaque fois qu'un shell de connexion bash est entré (par exemple, lors de la connexion à partir de la console ou via ssh), ainsi que par DisplayManager lors du chargement de la session de bureau.
Vous pouvez par exemple créer le fichier /etc/profile.d/myenvvars.sh et définir des variables comme ceci:
export Java_HOME=/usr/lib/jvm/jdk1.7.0
export PATH=$PATH:$Java_HOME/bin
Exécute la crontab avec l'option de connexion!
Script ou commande d'exécution CRONTAB avec des variables d'environnement
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
Définir PATH juste avant la ligne de commande dans ma crontab a fonctionné pour moi:
* * * * * PATH=$PATH:/usr/local/bin:/path/to/some/thing
Votre script fonctionne lorsque vous l'exécutez à partir de la console mais échoue dans cron.
Votre crontab n'a pas les bonnes variables de chemin (et éventuellement Shell)
Ajoutez votre shell actuel et cheminez la crontab
#!/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
Ajouter une définition de PATH dans la crontab de l'utilisateur avec les valeurs correctes aidera ....... J'ai rempli la mienne avec juste:
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
Et cela suffit pour que tous mes scripts fonctionnent ... Incluez un chemin personnalisé là-bas si vous en avez besoin.
Sur mon AIX, cron sélectionne ses variables d'environnement dans/etc/environment en ignorant ce qui est défini dans le fichier .profile.
Edit: J'ai également extrait deux boîtes Linux de différents âges. Celles-ci semblent également contenir ce fichier. Ce n'est donc probablement pas spécifique à AIX.
J'ai vérifié cela en utilisant la suggestion cron de joemaller et en vérifiant la sortie avant et après l'édition de la variable PATH dans/etc/environment.
L'environnement par défaut des tâches cron est très clairsemé et peut être très différent de l'environnement dans lequel vous développez vos scripts python. Pour un script pouvant être exécuté dans cron, tout environnement sur lequel vous dépendez doit être défini explicitement. Dans le fichier cron lui-même, incluez des chemins complets vers les exécutables python et vos scripts python.
Je sais que cela a déjà été répondu, mais je pensais que le sien serait utile à certains. J'ai eu un problème similaire que j'ai récemment résolu ( trouvé ici ) et voici les points saillants des étapes que j'ai entreprises pour répondre à cette question:
assurez-vous que vous avez les variables dont vous avez besoin dans PYTHONPATH (trouvées ici et ici et pour plus d'informations ici) à l'intérieur du fichier .profile ou .bash_profile de tout shell dans lequel vous souhaitez tester votre script pour vous assurer qu'il fonctionne.
éditez votre crontab pour inclure les répertoires nécessaires à l'exécution de votre script dans un travail cron (trouvé ici et ici)
a) assurez-vous d’inclure le répertoire racine dans la variable PATH (.) comme expliqué ici (essentiellement si vous exécutez un fichier exécutable avec votre commande, vous devez être en mesure de trouver la racine ou le répertoire dans lequel est stocké le fichier exécutable) et probablement ces derniers. (/ sbin:/bin:/usr/sbin:/usr/bin)
dans votre fichier crontab, créez un travail cron qui changera de répertoire en répertoire où vous avez déjà exécuté le script avec succès (à savoir Utilisateurs/utilisateur/Documents/foo)
a) Cela ressemblera à ceci:
* * * * cd /Users/user/Documents/foo; bar -l doSomething -v
@Trevino: votre réponse m'a aidé à résoudre mon problème. Cependant, pour un débutant, essayez de donner une approche étape par étape.
$ echo $Java_HOME
$ crontab -e
* * * * * echo $PATH
- ceci vous permet de comprendre quelle est la valeur de PATH utilisée actuellement par crontab. Exécutez crontab et récupérez la valeur $ PATH utilisée par crontab.crontab -e
; b) PATH=<value of $Java_HOME>/bin:/usr/bin:/bin
(c'est un exemple de chemin); c) maintenant votre travail/script planifié tel que */10 * * * * sh runMyJob.sh &
; d) retirez echo $PATH
de crontab car ce n’est pas nécessaire maintenant.La solution de contournement la plus simple que j'ai trouvée ressemble à ceci:
* * * * * root su -l -c command
Cet exemple appelle su
en tant qu'utilisateur root et démarre le shell avec l'environnement complet de l'utilisateur, y compris $ PATH, défini comme s'il était connecté. Il fonctionne de la même manière sur différentes distributions, il est plus fiable que le sourcing .bashrc (qui n'a pas fonctionné pour moi) et évite de coder en dur des chemins spécifiques qui peuvent poser problème si vous fournissez un exemple ou un outil de configuration et que vous ne savez pas quelle distribution ou quelle disposition de fichier sur le système de l'utilisateur.
Vous pouvez également spécifier le nom d'utilisateur après su
si vous souhaitez utiliser un autre utilisateur que root, mais vous devez probablement laisser le paramètre root
avant la commande su
, car cela garantit que su
dispose des privilèges suffisants pour basculer vers l'utilisateur de votre choix.
Si vous ne voulez pas avoir à faire les mêmes modifications à différents endroits, alors procédez comme suit:
* * * * * . /home/username/.bashrc && yourcommand all of your args
Le . space, puis le chemin d'accès à .bashrc et la commande && sont la magie pour transférer les modifications de votre environnement dans le shell bash en cours d'exécution. Aussi, si vous voulez vraiment que le shell soit bash, c'est une bonne idée d'avoir une ligne dans votre crontab:
Shell=/bin/bash
J'espère que ça aide quelqu'un!
Définissez le chemin requis dans votre cron
crontab -e
Edit: Press i
PATH=/usr/local/bin:/usr/local/:or_whatever
10 * * * * your_command
Sauvegarder et quitter :wq