简体   繁体   English

如何从cron运行的Perl脚本中运行shell脚本?

[英]How can I run a shell script from inside a Perl script run by cron?

Is it possible to run Perl script (vas.pl) with shell sript inside (date.sh & backlog.sh) in cron or vice versa? 是否有可能在cron中使用shell sript(date.sh和backlog.sh)运行Perl脚本(vas.pl),反之亦然? Thanks. 谢谢。

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

Error encountered: 遇到错误:

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

Perl 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;

cron runs your perl script in a different working directory than your current working directory. cron在与当前工作目录不同的工作目录中运行perl脚本。 Use the full path of your script file: 使用脚本文件的完整路径:

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

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

Or if your're allergic to hardcoding paths like I am you can use the FindBin package from CPAN: 或者如果你对我这样的硬编码路径过敏,你可以使用CPAN的FindBin包:

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

If your shell script also needs to start in the correct path then it's probably better to first change your working directory: 如果您的shell脚本还需要以正确的路径启动,那么首先更改您的工作目录可能更好:

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

You can do what you want as long as you are careful. 只要你小心,你就可以做你想做的事。

The first thing to remember with cron jobs is that you get almost no environment set. 使用cron作业要记住的第一件事是你几乎没有环境设置。

The chances are, the current directory is / or perhaps $HOME . 可能性是,当前目录是/或可能是$HOME And the value of $PATH is minimal - your profile has not been run, for example. 并且$ PATH的值很小 - 例如,您的个人资料尚未运行。

So, your script didn't find 'date.sh' because it wasn't in the correct directory. 因此,您的脚本找不到'date.sh',因为它不在正确的目录中。

To get the data from the shell script into your program, you need to pipe it there - or arrange for the 'date.sh' to dump the data into the file successfully. 要将shell脚本中的数据导入到程序中,需要将其移植到那里 - 或者安排'date.sh'将数据成功转储到文件中。 Of course, Perl has built-in date and time handling, so you don't need to use the shell for it. 当然,Perl具有内置的日期和时间处理功能,因此您无需使用shell。

You also did not run with use warnings; 您也没有use warnings; or use strict; use strict; which would also help you. 这对你也有帮助。 For example, $cat1 is not a defined variable. 例如, $cat1不是已定义的变量。

Personally, I run a simple shell script from cron and let it deal with all the complexities; 就个人而言,我从cron运行一个简单的shell脚本,让它处理所有的复杂性; I don't use I/O redirection in the crontab file. 我不在crontab文件中使用I / O重定向。 That's partly a legacy of working on ancient systems - but it also leads to portable and reliable running of cron jobs. 这部分是在古代系统上工作的遗产 - 但它也导致了cron工作的便携和可靠运行。

It's possible. 这是可能的。 Just keep in mind that your working directory when running under cron may not be what you think it is - it's the value in your HOME environment variable, or that specified in the /etc/passwd file. 请记住,在cron下运行时,您的工作目录可能不是您认为的 - 它是HOME环境变量中的值,或者在/ etc / passwd文件中指定的值。 Consider fully qualifying the path to your .shes. 考虑完全限定您的.shes的路径。

There are a lot of things that need care in your script, and I talk about most of them in the "Secure Programming Techniques" chapter of Mastering Perl . 你的脚本中有很多东西需要注意,我在Mastering Perl的“安全编程技术”一章中讨论了大部分内容。 You can also find some of it in perlsec / 你也可以在perlsec中找到一些/

Since you are taking external data and passing them to other external programs, you should use taint checking to ensure that the data are what you expect. 由于您正在获取外部数据并将其传递给其他外部程序,因此您应该使用污点检查来确保数据符合您的预期。 What if someone were able to sneak something extra into those files? 如果有人能够将某些东西偷偷带进这些文件怎么办?

When you want to pass data to external programs, use system in the list form so the shell doesn't get a chance to interpret possible meta-characters. 如果要将数据传递给外部程序,请使用列表表单中的system ,以便shell无法解释可能的元字符。

Instead of relying on the PATH to find the programs that you expect to run, specify their full paths explicitly to ensure you are at least running the file you think you are (and not something someone snuck into a directory that is earlier in PATH ). 而不是依赖PATH来查找您希望运行的程序,而是明确指定它们的完整路径,以确保您至少运行您认为自己的文件(而不是某人偷偷进入PATH较早的目录)。 If you were really paranoid (like taint checking is), you might also check that those files and directories had suitable permissions (eg, not world-writeable). 如果你真的是偏执狂(比如污点检查),你也可以检查那些文件和目录是否具有合适的权限(例如,不是世界可写的)。

Just as a bonus note, if you only want one line from a filehandle, you can use the line-input operator in scalar context: 作为奖励说明,如果您只需要文件句柄中的一行,则可以在标量上下文中使用行输入运算符:

 my $date = <$fh>;

You probably want to chomp the data too to get rid of possible ending newlines. 你可能想终日啃食的数据量太大,以摆脱可能的结局换行。 Even if you don't think a terminating newline should be there because another program created the file, someone looking at the file with a text editor might add it. 即使您不认为终止换行符应该存在,因为另一个程序创建了该文件,但是使用文本编辑器查看该文件的人可能会添加它。

Good luck, :) 祝好运, :)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM