2010-01-05 11 views
2

Est-il possible d'exécuter le script Perl (vas.pl) avec shell sript à l'intérieur (date.sh & backlog.sh) dans cron ou vice versa? Merci.Comment puis-je exécuter un script shell à partir d'un script Perl exécuté par cron?

0 19 * * * /opt/perl/bin/perl /reports/daily/scripts/vas_rpt/vasCIO.pl 2> /reports/daily/scripts/vas_rpt/vasCIO.err 

erreur rencontrée:

date.sh: not found 
backlog.sh: not found 

script Perl:

#!/opt/perl/bin/perl 

system("sh date.sh"); 
open(FH,"/reports/daily/scripts/vas_rpt/date.txt"); 
@date = <FH>; 

close FH; 

open(FH,"/reports/daily/scripts/vas_rpt/$cat1.txt"); 
@array = <FH>; 

system("sh backlog.sh $date[0] $array[0]"); 

close FH; 

Répondre

2

Il est possible. N'oubliez pas que votre répertoire de travail sous cron n'est peut-être pas ce que vous pensez être - c'est la valeur de votre variable d'environnement HOME, ou celle spécifiée dans le fichier/etc/passwd. Envisagez de qualifier complètement le chemin vers votre fichier .shes.

+0

Ou l'utilisateur et PATH – Schwern

+0

Merci :-) J'ai oublié d'inclure le chemin. Cela fonctionne! :-) – Cez

8

cron exécute votre script Perl dans un répertoire de travail différent de celui de votre répertoire de travail actuel. Utilisez le chemin complet de votre fichier script:

# I'm assuming your shell script reside in the same 
# dir as your perl script: 

system("sh /reports/daily/scripts/date.sh"); 

Ou si Vous êtes en train allergique aux hardcoding chemins comme je suis, vous pouvez utiliser le package FindBin de CPAN:

use FindBin qw($Bin); 
system("sh $Bin/date.sh"); 

Si votre script shell doit également pour commencer dans le bon chemin alors il est probablement préférable de commencer par changer votre répertoire de travail:

use FindBin qw($Bin); 
chdir $Bin; 
system("sh date.sh"); 
+0

Cela fonctionne déjà. Merci :-) – Cez

+0

@slebetman: Quel est le répertoire "home/start" du shell-script en cours d'exécution? Je suppose que je suis un peu paranoïde mais je m'assurerais qu'il y a un 'cd/reports/daily/scripts' ou que le script écrit dans un chemin absolu. (et +1 de moi pour la solution et les alternatives) – lexu

+0

@lexu: Vous avez raison. Devrait changer le répertoire de travail en cours avant de démarrer le script shell pour être sûr. Mais puisque le PO a mentionné que simplement ajouter le chemin complet a résolu son problème, alors dans son cas, il n'en a pas besoin. – slebetman

3

vous pouvez faire ce que vous voulez tant que vous êtes prudent. La première chose à retenir avec les travaux cron est que vous n'avez pratiquement aucun environnement défini.

Les chances sont, le répertoire courant est / ou peut-être $HOME. Et la valeur de $ PATH est minime - votre profil n'a pas été exécuté, par exemple. Par conséquent, votre script n'a pas trouvé 'date.sh' car il ne se trouvait pas dans le bon répertoire. Pour obtenir les données à partir du script shell dans votre programme, vous devez l'y attacher - ou organiser le 'date.sh' pour vider les données dans le fichier avec succès. Bien sûr, Perl a intégré la gestion de la date et de l'heure, donc vous n'avez pas besoin d'utiliser le shell pour cela.

Vous n'avez pas non plus exécuté avec use warnings; ou use strict; ce qui peut également vous aider. Par exemple, $cat1 n'est pas une variable définie.

Personnellement, je lance un simple script shell de cron et le laisse gérer toutes les complexités; Je n'utilise pas de redirection d'E/S dans le fichier crontab. C'est en partie un héritage de travailler sur des systèmes anciens - mais cela conduit également à un fonctionnement portable et fiable de cron emplois.

+0

Merci pour le conseil! Ça aide beaucoup :-) – Cez

0

Il y a beaucoup de choses qui ont besoin de soin dans votre script, et j'en parle pour la plupart dans le chapitre "Techniques de programmation sécurisées" de Mastering Perl.Vous pouvez également en trouver dans perlsec/

Puisque vous prenez des données externes et les transmettez à d'autres programmes externes, vous devriez utiliser la vérification des traces pour vous assurer que les données correspondent à vos attentes. Et si quelqu'un était capable de glisser quelque chose de plus dans ces fichiers?

Lorsque vous souhaitez transmettre des données à des programmes externes, utilisez system dans le formulaire de liste afin que l'interpréteur ne puisse pas interpréter les méta-caractères possibles.

Au lieu de compter sur le PATH pour trouver les programmes que vous comptez utiliser, spécifiez leurs chemins complets explicitement pour vous assurer au moins exécutez le fichier que vous pensez que vous êtes (et non une personne quelque chose faufilé dans un répertoire qui est antérieure au PATH). Si vous étiez vraiment paranoïaque (comme la vérification de l'altération), vous pouvez également vérifier que ces fichiers et répertoires possèdent les autorisations appropriées (par exemple, non inscriptibles dans le monde entier).

Tout comme une note de bonus, si vous voulez seulement une ligne à partir d'un descripteur de fichier, vous pouvez utiliser l'opérateur d'entrée de ligne dans un contexte scalaire:

my $date = <$fh>; 

Vous voulez probablement chomp les données trop pour se débarrasser de nouvelles fins de fin possibles. Même si vous ne pensez pas qu'un retour à la ligne final doit être présent parce qu'un autre programme a créé le fichier, quelqu'un qui regarde le fichier avec un éditeur de texte peut l'ajouter.

Bonne chance, :)

Questions connexes