Reputation: 94820
Suppose the call was
/usr/local/bin/perl verify.pl 1 3 de# > result.log
Inside verify.pl
I want to capture the whole call above and append it to a log file for tracking purposes.
How can I capture the whole call as it is?
Upvotes: 10
Views: 14142
Reputation: 1
Example which handles more special cases (and without adding own name) and with processing the line with GetOpt:
#!perl
use strict;
use warnings;
use Getopt::Long qw(GetOptionsFromString);
use feature qw ( say );
# Note: $0 is own name
my $sScriptCommandLine;
my @asArgs = ();
my $iRet;
my $sFile = '';
my $iN = -1;
my $iVerbose = 0;
# ============================================================================
my %OptionsHash = (
"f=s" => \$sFile,
"n=i" => \$iN,
"v:+" => \$iVerbose);
$sScriptCommandLine = join( ' ', @ARGV ); # useless for argument with spaces
say 'A: ' . $sScriptCommandLine;
$sScriptCommandLine = '"' . join( '" "', @ARGV ) . '"'; # all arguments in "", but not suitable for arguments with '"' (given as '\"')
say 'B: ' . $sScriptCommandLine;
$sScriptCommandLine = '';
foreach (@ARGV) {
$sScriptCommandLine .= ' ' if ($sScriptCommandLine);
$_ =~ s/\\/\\\\/g; # needed for GetOptionsFromString
$_ =~ s/\"/\\\"/g;
if (/\s/) {
$sScriptCommandLine .= '"'.$_.'"';
}
else {
$sScriptCommandLine .= $_;
}
}
say 'C: ' . $sScriptCommandLine;
my ($iRet,$paArgs);
($iRet,$paArgs) = GetOptionsFromString($sScriptCommandLine,%OptionsHash);
# remaining parameters in $$paArgs[0] etc.
if (!$iRet) {
# error message already printed from GetOptionsFromString
print "Invalid parameter(s) in: \"$sScriptCommandLine\"\n";
}
say 'D: ' . '<<' . join( '>> <<', @{$paArgs} ) . '>>';
say 'f=s: "'.$sFile.'"';
say 'n=i: '.$iN;
say 'v:+: '.$iVerbose;
# eof
Upvotes: -1
Reputation: 11
Here virtually same Linux-only variants (of course, after shell intervention):
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";
};
using 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";
};
Upvotes: 1
Reputation: 21
$commandline = join " ", $0, @ARGV;
does not handle the case that command line has quotes such as ./xxx.pl --love "dad and mom"
A Quick Solution:
my $script_command = $0;
foreach (@ARGV) {
$script_command .= /\s/ ? " \'" . $_ . "\'"
: " " . $_;
}
Try to save the following code as xxx.pl
and run ./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;
Upvotes: 2
Reputation: 8376
There is way (at least on unix-systems) to get whole command line:
my $cmdline = `ps -o args -C perl | grep verify.pl`;
print $cmdline, "\n";
e: Cleaner way using PID (courtesy of Nathan Fellman):
print qx/ps -o args $$/;
Upvotes: 10
Reputation: 127428
$0
has the script name and @ARGV
has the arguments, so the whole commandline is:
$commandline = $0 . " ". (join " ", @ARGV);
or, more elegantly (thanks FMc):
$commandline = join " ", $0, @ARGV;
I don't however, know how to capture the redirection (> result.log
)
Upvotes: 10
Reputation: 45652
See In Perl, how do I get the directory or path of the current executing code?
Upvotes: 0