Как я могу захватить всю командную строку в Perl? - PullRequest
10 голосов
/ 27 мая 2011

Предположим, что вызов был

/usr/local/bin/perl verify.pl 1 3 de# > result.log

Внутри verify.pl Я хочу перехватить весь вышеуказанный вызов и добавить его в файл журнала для целей отслеживания.

Как я могу перехватитьвесь звонок как есть?

Ответы [ 5 ]

10 голосов
/ 28 мая 2011

Существует способ (по крайней мере, в Unix-системах) получить всю командную строку:

my $cmdline = `ps -o args -C perl | grep verify.pl`;
print $cmdline, "\n";

e: Более чистый способ с использованием PID (любезно предоставлен Натаном Феллманом):

print qx/ps -o args $$/;
8 голосов
/ 27 мая 2011

$0 имеет имя сценария, а @ARGV имеет аргументы, поэтому вся командная строка:

$commandline = $0 . " ". (join " ", @ARGV);

или, более элегантно (спасибо FMc ):

$commandline = join " ", $0, @ARGV;

Однако я не знаю, как захватить перенаправление (> result.log)

2 голосов
/ 28 ноября 2011

$commandline = join " ", $0, @ARGV; не обрабатывает случай, когда в командной строке есть кавычки, такие как ./xxx.pl --love "dad and mom"

A Быстрое решение:

my $script_command = $0;
foreach (@ARGV) {
$script_command .= /\s/ ?   " \'" . $_ . "\'"
                :           " "   . $_;
}

Попробуйте сохранить следующий код как xxx.plи запустить ./xxx.pl --love "dad and mom":

#!/usr/bin/env perl -w
use strict;
use feature qw ( say );
say "A: " . join( " ", $0, @ARGV );
my $script_command = $0;
foreach (@ARGV) {
    $script_command .= /\s/ ?   " \'" . $_ . "\'"
                    :           " "   . $_;
}
say "B: " . $script_command;
1 голос
/ 01 октября 2013

Здесь практически те же варианты только для Linux (конечно, после вмешательства оболочки):

pure perl

BEGIN {
    my @cmd = ( );
    if (open(my $h, "<:raw", "/proc/$$/cmdline")) {
        # precisely, buffer size must be at least `getconf ARG_MAX`
        read($h, my $buf, 1048576); close($h);
        @cmd = split(/\0/s, $buf);
    };
    print join("\n\t", @cmd), "\n";
};

с использованием File :: Slurp:

BEGIN {
    use File::Slurp;
    my @cmd = split(/\0/s, File::Slurp::read_file("/proc/$$/cmdline", {binmode => ":raw"}));
    print join("\n\t", @cmd), "\n";
};
0 голосов
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...