APM: Question: How to access command line before its parsed into @ARGV

tmcd@panix.com tmcd at panix.com
Thu Aug 25 18:56:39 PDT 2005


On Thu, 25 Aug 2005, Bill Raty <bill_raty at yahoo.com> wrote:
> In Linux one can access the pre-parsed command line given to
> exec, using CPAN module Proc::ProcessTable .  It seems to
> reflect the assertions that quotes are removed by the shell
> before being given to exec.

It cannot access "the pre-parsed command line".  Linux sees only
execve, in which the arguments to the command are already separated
into separate strings.  What Proc::ProcessTable reports is just a
space-separated concatenation of the arguments that the kernel saw.
For example, just now on my system (014.pl is the Proc::ProcessTable
test program you posted):

    tmcd 1045 $ man Proc::ProcessTable::Process
    Reformatting Proc::ProcessTable::Process(3pm), please wait...
    tmcd 1046 $ foo='\'
    tmcd 1049 $ local/test/014.pl  arg1 arg2 arg3 "abc$foo more \$$$ !1045 '"
    Command line for pid=18064: (/usr/bin/perl -w local/test/014.pl arg1 arg2 arg3 abc\ more $2178 man Proc::ProcessTable::Process ' )

Note that the output only vaguely resembles the command line, because
the shell expanded all sorts of things (variables, \, $, !) and split
the arguments itself.  And the output is not usable, not just due to
quotes and whitespace, but due to other items.

> The underlying problem is I need to gather forensics on an
> executable running on AIX that hangs intermittently.  The idea was
> to put a command proxy in its place (perl) that captures invocation
> arguments, STDIN, invokes the miscreant, and logs its STDOUT, STDERR
> and other vitals for later analysis.  Hopefully I'll be able to
> gather information for logging a support ticket with the producer of
> the executable.

It's always helpful to give the underlying problem you're trying to
solve, so thank you.  Do you know what kinds of arguments the program
will take?  If there are no shell metacharacters, then things become
simpler.

Off the top of my head and untested, a simple test is:

    #! /bin/sh
    realProgram='/usr/local/bin/underlying_command'
    (
        echo 'Beginning run of miscreant'
        date
        env
        for f
        do
            echo "argument: '$f'"
        done
    ) > /tmp/log-miscreant
    tee -a /tmp/log-miscreant | $realProgram "$@" 2>&1 |
        tee -a /tmp/log-miscreant

I'm uncertain about the "tee -a" business: two programs running at the
same time outputting to the same file.  I'm hoping that it opens the
file in APPEND mode, so no output will be lost.  -- If you don't care
about correlating the standard input with the standard ouput, then use
two different output files.

That also puts standard error into standard output.  That also loses
the return code from $realProgram.  Whether that's a problem in your
site's usage only you can say.

> Presumably the quotes I supply to this program don't reach it, and I
> can apply the cmndline from above to an 'exec', 'open', or 'open3'.

Why do you want to supply a command line to exec(), when you already
have the arguments you need in @ARGV?!

    exec $realProgram @ARGV;
    die "exec failed: $realProgram: $? $!, ";

@ARGV in Perl corresponds to "$@" in the modern shell.

-- 
Tim McDaniel; Reply-To: tmcd at panix.com


More information about the Austin mailing list