调用“sudo lsof | grep username | wc -l”的 perl 脚本的输出在 cron 与手动中有所不同

调用“sudo lsof | grep username | wc -l”的 perl 脚本的输出在 cron 与手动中有所不同

我们运行用于文件计数的 perl 脚本时遇到问题:

#!/usr/bin/perl
    $stat=`sudo lsof | grep username | wc -l`;
    $date=`date '+ %Y/%m/%d-%H:%M:%S'`;
    $exit=`echo $?`;
    if ( $exit == 0 ) {
            print "$date\n Statistic: $stat\n";
            exit 0;
            }

我们可以手动运行此脚本并获得良好的输出:

# perl test.pl
 2020/07/30-19:17:10
 Statistic: 580

作为 cronjob 运行*/5 * * * * perl /filepath/test.pl >> /filepath/test.txt,它输出 0:

 2020/07/30-19:20:01
 Statistic: 0

它在 RHEL4 机器上运行,我们希望将其作为 cronjob 运行以附加文件来获取统计数据。

答案1

改进脚本可能会起作用:

#!/usr/bin/perl
use POSIX qw(strftime);
$user = shift; $outputfile = shift;
$lsof=`lsof 2> /dev/null`;
exit $? unless($? == 0);
$count=0;
foreach(split /\n/, $lsof) {
        $count++ if(/$user/);
}
open($fh, ">>$outputfile") or die "Can't append to $outputfile";
print $fh strftime(" %Y/%m/%d-%H:%M:%S\n Statistic: $count\n", localtime);
close $fh;

在 cron 中会变成这样

*/5 * * * * root perl /filepath/test.pl username /filepath/test.txt

您的案例中存在错误的地方:

  • cron 中缺少用户名字段(我使用root这样我们就不必使用 提升权限sudo
  • 即使有用户名,sudo也会因为缺少密码而失败
  • echo $?将是 echo 命令的返回码,所有其他命令将被忽略
  • 不完全错误,但建议不要这样做:perlscript 中的 shell 代码太多
  • 可能没有错,但我认为你不想要它: lsof 的所有警告都没有被过滤掉

如果仍然不起作用,请尝试lsof按完整路径切换(最有可能/usr/bin/lsof

编辑:另一个问题:你grep和我的正则表达式还会找到包含username该字符串不作为用户名的行。
这段代码更好:

#!/usr/bin/perl
use POSIX qw(strftime);
$user = shift; $outputfile = shift;
$count=split(/n/,`lsof -u $user 2> /dev/null`);
exit $? unless($?==0);
open($fh, ">>$outputfile") or die "Can't append to $outputfile";
print $fh strftime(" %Y/%m/%d-%H:%M:%S\n Statistic: $count\n", localtime);
close $fh;

相关内容