Script Python ne s'exécute pas dans crontab appelant pysaunter

j'ai lu plusieurs billets et de nombreux articles détaillant que scipts dans un travail cron besoin de garder les variables d'environnement nécessaires pour exécuter à l'intérieur du script lui-même en raison de l'ouverture des coquilles dans cron. Ma situation est unique en ce que mes variables de chemin sont toutes définies comme discuté, qui à son tour appellera avec succès l'oeuf Python pysaunter en utilisant le sous-processus .call() , mais il semble se casser de là. Cela provoque l'ensemble du processus de rupture dans un cron.

pour plus de clarté, voici les étapes auxquelles je me réfère:

1) cronjob calls run_test.py -n foo
2) run_test.py sets the environment variables correctly 
(cur_shell_path=sys.path (converted to proper path string, not shown here)
 my_env= os.environ.copy()
 my_env["PATH"] = my_env["PATH"] + cur_shell_path)
3) run_test.py calls subprocess.call("pysaunter -m foo -v", env=my_env, shell=True)

la sortie de l'étape 3 montre qu'il trouve l'oeuf et commence avec succès à charger les modules nécessaires à partir de pysaunter, mais ensuite il casse en essayant de trouver un répertoire utilisé pour modifier pysaunter. L'erreur se lit comme suit :

ImportError: no module named helpers

j'ai essayé d'ajouter ce chemin à l'environnement, à plusieurs reprises, mais il ne semble jamais trouver le répertoire qui contient helpers.py. La commande pysaunter -m foo -v fonctionne normalement lorsqu'elle est appelée à partir d'un shell interactif.

Je n'ai pas pu trouver beaucoup d'aide sur pysaunter, donc je suppose que trop de détails sur pysaunter seraient inutiles ici. Si toutefois vous en savez plus sur pysaunter, s'il vous plaît laissez-moi savoir si vous avez besoin de plus d'informations. Je ne suis pas sûr de ce partage.

j'ai aussi lu de nombreux billets discutant de la possibilité de changer le comportement par défaut d'un shell par l'édition de l' .profil./bash_profile. J'ai essayé de trouver un endroit qui rendrait mes variables path globalement accessibles, mais je n'ai rien trouvé. Je ne sais pas comment cela se fait, et cela pourrait résoudre mon problème, donc si vous savez quelque chose à ce sujet s'il vous plaît laissez-moi savoir.

note finale, ça tourne sur Mac 10.7.5.

6
demandé sur derigible 2013-07-11 04:06:16

2 réponses

après beaucoup d'essais et d'erreurs, et beaucoup, beaucoup stackoverflow.com articles et autres tutoriels en ligne, et avec L'aide d'un script Perl que j'ai trouvé qui a fait quelque chose de similaire, j'ai été en mesure de comprendre ce qui devait être fait pour obtenir ce travail.

Voici les étapes pour s'assurer que tout est mis en place correctement:

  1. assurez-vous que vous avez les variables dont vous avez besoin en PYTHONPATH (trouvé ici et ici , et pour plus d'informations. aller ici ) à l'intérieur de la .de profil ou de .bash_profile pour n'importe quel environnement vous souhaitez tester votre script pour vérifier qu'il fonctionne.

  2. éditez votre crontab pour inclure les répertoires nécessaires pour exécuter votre script dans un travail cron (trouvé ici et ici ).

    a) assurez-vous d'inclure le répertoire racine dans le chemin variable.( ) comme expliqué ici . Fondamentalement, si vous exécutez un exécutable avec votre commande, il doit être capable de trouver root ou le répertoire où l'exécutable est stocké et aussi probablement ceux-ci: (/sbin:/bin:/usr/sbin:/usr/bin).

  3. dans votre fichier crontab, créez une cronjob qui modifiera le répertoire courant vers le répertoire où vous avez déjà exécuté le script (par exemple, /Users/user/Documents/foo).

    a) cela ressemblera à ce qui suit:

    * * * * cd /Users/user/Documents/foo; bar -l doSomething -v 
    
  4. étant donné que mon problème portait spécifiquement sur l'appel d'un exécutable, il est nécessaire de noter qu'il existe plusieurs façons d'écrire le script Python à exécuter (bien que dans le processus de découverte j'ai appris que cela fonctionne pour tout appel fait en utilisant un sous-processus dans cron).

    La première méthode ressemble à ceci:

    ... #some script calls
    my_env = os.environ.copy()
    my_env["PYTHONPATH"] = "{}:{}".format(os.environ["PATH"] ,"<path you want to include>")
    os.chdir("<path/to/desired/directory>")
    subprocess.Popen(<call_as_string>, env=my_env, shell=True)
    

    Et le second ressemble à ceci:

    ... #some script calls
    os.environ["PYTHONPATH"] = "{}:{}".format(os.environ["PATH"] ,"<path you want to include>")
    os.chdir("<path/to/desired/directory>")
    subprocess.Popen(<call_as_list_of_arguments)
    

    étant donné que l'exécutable avait besoin du chemin d'accès au répertoire des helpers inclus dans le shell d'où il était appelé, il était nécessaire de passer la variable d'environnement à l'exécutable comme expliqué ici . Ce que j'ai trouvé, cependant, c'est que modifier la variable PATH dans l'environnement ne fonctionnait pas pour un travail cron, mais configurer le PYTHONPATH le faisait. J'ai lu ici que la variable PATH est utilisé par le shell pour ne Rechercher que les exécutables, donc pour un nouveau shell dans un cronjob vous devez passer le shell un PYTHONPATH pour rechercher de nouveaux modules Python. (C'est aussi expliqué dans les docs Python .)

    les différences entre les deux méthodes sont expliquées dans la documentation du sous-processus citée dans la question, mais un bon tutoriel sur ce module peut être trouvé ici .

3
répondu derigible 2017-05-23 10:29:21

Ce que vous avez dit n'a aucun sens.

vous dites shell_env = sys.path . sys.path est une liste de dossiers pour python pour rechercher des modules, pas une variable d'environnement de mappage!

vous l'utilisez ensuite dans subprocess.call . Vous vouliez peut-être écrire env=my_env .

C'est le problème suivant. Tout d'abord, PATH doit être une liste de dossiers séparés par ':' . Vous mettez juste shell_path dans le dernier dossier.

enfin, python utilise PYTHONPATH comme liste pour localiser les modules python (ce qui semble être le problème que vous avez.)

1
répondu korylprince 2013-07-15 21:41:22