2010-01-05 257 views
2

是否有可能在cron中使用shell sript(date.sh & backlog.sh)运行Perl脚本(vas.pl),反之亦然? 谢谢。如何从cron运行的Perl脚本中运行shell脚本?

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

遇到的错误:

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

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; 

回答

2

这是可能的。请记住,在cron下运行时,您的工作目录可能不是您认为的那样 - 它是您的环境变量HOME或/ etc/passwd文件中指定的值。考虑完全限定你的.shes的路径。

+0

或用户与PATH – Schwern 2010-01-05 03:09:35

+0

感谢:-)我忘了,包括路径。它的工作原理!:-) – Cez 2010-01-05 03:44:06

8

cron在与当前工作目录不同的工作目录中运行perl脚本。使用完整路径脚本文件:

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

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

或者,如果your're过敏的硬编码路径像我,你可以使用CPAN FindBin包:

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

如果你的shell脚本也需要以正确的路径开始,那么它可能更好地首先改变你的工作目录:

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

它已经可以工作了。谢谢:-) – Cez 2010-01-05 03:42:29

+0

@slebetman:正在运行的shell脚本的“home/start”目录是什么?我想我有点偏执,但我会确保在那里有'cd/reports/daily/scripts'或脚本写入绝对路径。 (从我的+1解决方案和替代品) – lexu 2010-01-05 06:51:18

+0

@lexu:你说得对。在启动shell脚本之前应该改变当前的工作目录以保证安全。但是由于OP提到简单地加入完整路径解决了他的问题,那么在他的情况下他不需要它。 – slebetman 2010-01-05 07:50:20

3

只要你小心,你可以做你想做的。

cron工作要记住的第一件事是你几乎没有环境设置。

可能是,当前目录是/或者$HOME。并且$ PATH的值很小 - 例如,您的配置文件尚未运行。

所以,你的脚本没有找到'date.sh',因为它没有在正确的目录中。

为了从shell脚本中获取数据到你的程序中,你需要在那里管它 - 或者安排'date.sh'将数据成功转储到文件中。当然,Perl有内置的日期和时间处理,所以你不需要为它使用shell。

你也没有运行use warnings;use strict;这也可以帮助你。例如,$cat1不是定义的变量。

就我个人而言,我从cron运行一个简单的shell脚本,让它处理所有的复杂性;我不使用crontab文件中的I/O重定向。这部分是在古代系统上工作的遗留问题 - 但它也导致便携式和可靠的cron工作。

+0

感谢您的建议!它有很多帮助:-) – Cez 2010-01-05 03:45:41

0

脚本中有很多事情需要注意,我在Mastering Perl的“安全编程技术”一章中讨论了其中的大部分内容。你也可以在perlsec/

中找到它的一部分,因为你正在接受外部数据并将它们传递给其他外部程序,所以应该使用污点检查来确保数据是你所期望的。如果有人能够将这些文件额外偷偷地添加到这些文件中,该怎么办?

当您想要将数据传递给外部程序时,请使用列表形式中的system,以便shell无法解释可能的元字符。

而不是依靠PATH来查找您希望运行的程序,请明确指定它们的完整路径,以确保至少运行您认为自己的文件(而不是某人偷偷进入较早的目录在PATH)。如果你确实是偏执的(就像检查异常),你也可以检查这些文件和目录是否具有合适的权限(例如,不是世界可写的)。

正如奖金的注意,如果你只是想从一个文件句柄一条线,你可以使用线路输入者在标量上下文:

my $date = <$fh>; 

你可能想chomp数据也摆脱可能结束换行。即使你不认为终止换行符应该在那里,因为另一个程序创建了该文件,有人用文本编辑器查看该文件可能会添加它。

祝你好运:)