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

tmcd@panix.com tmcd at panix.com
Thu Aug 25 14:29:28 PDT 2005

On Thu, 25 Aug 2005, Tim Peoples <tim at toolman.org> wrote:
> The reason you're not getting the quotes in Perl is because they
> aren't there; the shell has already removed them in order to parse
> the command line into an array of strings.  The quotes are merely a
> shell device to tell it not to separate the tokens on whitespace and
> to treat the whole quoted string as one token.

Quoting also tells the shell not to expand certain metacharacters:
" still allows $ interpretation, \ interpretation, and others, while
' allows much less.

Bill wrote:
> I will concede it may be a 'C' thing.  However, there are other
> executables in *nix that manage to get the unfiltered command line.

That's not possible.

> How about:
>    $cmdline = join(' ', map { (/\s/) ? "\"$_\"" : $_ } @ARGV);

Whitespace isn't the only problematic character.  Also, you use double
quotes, and that allows for far more interpretation inside, which you
generally don't want.

    mycmd arg1 arg2 '*' arg4
    mycmd arg1 "arg2'rest"
    mycmd arg1 'arg2"rest'
    mycmd one_backslash\\after_parsing
    mycmd arg1 "arg2\"'rest"
    mycmd 'arg1$rest'

It's a very difficult problem to re-add proper quoting in general.
In the past, I've tended to just single-quote each argument.
This still fails if any argument contains at least one single quote (').

Doing a cursory search at CPAN, though, via <http://search.cpan.org/>
with "quoting shell arguments" as the search, indicates that
String::ShellQuote may do what you want.  That's just the hit I saw on
the first page; there may be other packages.

> I think this begs the quetion of, "Why are you wanting to recombine
> your command line into a single string?"  The tokens are already
> parsed for you.

To be precise, it doesn't "beg the question", it "leaves unanswered
the underlying question".
    beg the question: Take for granted or assume the truth of the very
    thing being questioned. For example, "Shopping now for a dress to
    wear to the ceremony is really begging the question---she hasn't
    been invited yet". This phrase, whose roots are in Aristotle's
    writings on logic, came into English in the late 1500s. In the
    1990s, however, people sometimes used the phrase as a synonym of
    "ask the question" (as in 'The article begs the question: "What
    are we afraid of?"').

It can convenient to pass off a command line to the shell, as in

    system("mycommand '$arg1' '$arg2' >out.txt 2>&1 || rm '$lockfile'");

Yes, all of that can be done in Perl, but I'd have to implement the
saving of file descriptors, opening of the output file, unlinking,
...  In such cases, I've known that the arguments can't have "'".

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

More information about the Austin mailing list