打印grep -c return时输出奇怪

时间:2018-10-24 18:53:02

标签: perl grep

下面是一个shell程序,这是我测试如何使用相同的参数来确定相同的Perl脚本是否已经在运行。

它有效,但令我惊讶的是行数之后的尾随零。我看不到代码在哪里打印零。如果我从命令行运行该grep命令,它将仅返回计数,没有尾随的'0',但在代码中无法正常工作。

有任何线索吗?

谢谢

应用

#!/usr/bin/perl

use CGI;
$|=1;

my $q = CGI->new();
my $userid = $q->param("u");
my $check = "'perly.pl u=" . $userid . "'";

my $return= system("ps aux | grep $check | grep -v 'grep' -c");

print $return;
print "\n";

while(1)
{
        print "$userid...";
        sleep(3);
}

exit 0;

输出

  

2 0   PlasticProgrammer..PlasticProgrammer..PlasticProgrammer..PlasticProgrammer..PlasticProgrammer..PlasticProgrammer..PlasticProgrammer..PlasticProgrammer..PlasticProgrammer..PlasticProgrammer..PlasticProgrammer。

2 个答案:

答案 0 :(得分:1)

您可以使用Capture::Tiny轻松捕获命令的输出和退出值。另外,在使用内置system时,请务必确保检查执行是否成功,如果执行失败,则返回值-1表示。

use strict;
use warnings;
use Capture::Tiny 'capture_stdout';

my $check = "perly.pl u=foo";
my ($stdout, $exit) = capture_stdout { system 'pgrep', '-fc', $check };
die "pgrep failed: $!" if $exit == -1;

请记住,您的输出很可能会以换行符结尾,甚至只是一个计数,因此您可能想要chomp

您还可以使用backticks/qx operator仅返回STDOUT,但这将始终通过外壳传递命令,要求您对包含用户输入的自变量使用String :: ShellQuote,如@ikegami所述。

use strict;
use warnings;
use String::ShellQuote;

my $check = shell_quote "perly.pl u=foo";
my $stdout = `pgrep -fc $check`;
die "pgrep failed: $!" if $? == -1;

另一种选择是IPC::System::Simple,它提供capturex,这是反引号运算符的一种形式,它采用参数列表(例如system),并且从不通过外壳传递。默认情况下,如果命令失败或退出代码非零,它将抛出异常,但是您可以指定允许某些退出代码。由于pgrep如果没有匹配项,则返回非零退出代码,因此您希望允许非零退出代码。

use strict;
use warnings;
use IPC::System::Simple qw(capturex EXIT_ANY $EXITVAL);

my $check = "perly.pl u=foo";
my $stdout = capturex EXIT_ANY, 'pgrep', '-fc', $check;
my $exit = $EXITVAL;

答案 1 :(得分:1)

万一有人在寻找解决方案,那么最好的主意是,但最后我选择创建一个唯一的临时文件并将输出通过管道传递到该文件。

从很多方面来说,我都觉得这很适合我。

#!/usr/bin/perl

use CGI;
use File::Temp;
$|=1;

my $q = CGI->new();
my $userid = $q->param("u");
my $check = "'perly.pl u=" . $userid . "'";

my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time); 
$year += 1900;
$mon++;

my $uFile = $userid . $year . $mon . $mday . $hour . $min . $sec . ".dat";

my $command = "ps aux | grep $check | grep -v 'grep' -c > $uFile";

system($command);

if (open(my $fh, "$uFile"))
{
    while (my $line = <$fh>)
    {
        if($line>1)
        {
            print"\nApp is already running";
         }
    }

    close($fh);
    unlink($uFile);
}
exit 0;