Beefy Boxes and Bandwidth Generously Provided by pair Networks
go ahead... be a heretic
 
PerlMonks  

\" on the WinXP Command Line

by Ardemus (Beadle)
on Feb 25, 2004 at 20:18 UTC ( [id://331797]=perlquestion: print w/replies, xml ) Need Help??

Ardemus has asked for the wisdom of the Perl Monks concerning the following question:

This is just a curiosity. I understand Perl's behavior when parsing \" off of the win32 command line. Is there a way to handle the behavior in Perl, rather than expecting the user to adapt to my program?

For those who aren't familiar with this behavior:

foreach (@ARGV){print "'$_'\n";} EXAMPLE A parameters - "A A\" B output - 'A A" B' EXAMPLE B parameters - "A A" B output - 'A A' output - 'B' #example B is how batch files (and all apps I've used) behave in windows. Also, \ is the path delimiter in windows, so it's natural to have one at the end of an argument.

I've asked on the chatterbox, and one wise monk suggested that user education was the best solution. This is a fine for my purposes. However, I'm still curious if anyone has another idea?

Replies are listed 'Best First'.
Re: \" on the WinXP Command Line
by John M. Dlugosz (Monsignor) on Feb 25, 2004 at 21:11 UTC
    The perl.exe program contains common code supplied by the compiler that parses the command tail into words which it then passes to main() as argv. If you recompile perl.exe, you can change that with some effort, or ignore it with less effort: at the top of main call GetCommandLine, parse it the way you please, re-point argv to your own array. The rest of the program will be none the wiser.

    But if you don't mind perl itself getting flags in its usual way, you can affect parsing of the arguments to your script from within Perl. Ignore ARGV and parse the string from GetCommandLine within the program. If it's not available already in some module, just use Win32::API to import it.

    —John

      Thanks folks. Between your comments and a quick search (Is it possible to include GetOpt flags in $0), here is a stab at reading the command line directly:
      if ($^O=~/win/){ use Win32::API; my $GetCommandLine = Win32::API->new('kernel32', 'GetCommandLine', + [ ] , 'P' ); $cmdline = $GetCommandLine->Call(); #Parse Command Line, into @ARGV if desired }
      I haven't gotten it to work on my machine yet (the error follows), but I think that it's a configuration issue on my end. Thanks again.
      Can't locate Win32/API.pm in @INC (@INC contains: D:/Exoddus/Util/Tool +s/Scripts C:\Perl\lib C:/Perl/lib C:/Perl/site/lib .) at C:\Documents + and Settings\nburger \Desktop\PerlTemp\dirComptest.pl line 4. BEGIN failed--compilation aborted at C:\Documents and Settings\nburger +\Desktop\PerlTemp\dirComptest.pl line 4.
Re: \" on the WinXP Command Line
by BrowserUk (Patriarch) on Feb 26, 2004 at 01:04 UTC

    This will let you get at the command line without it being messed with.

    #! perl -slw use strict; use Win32::API::Prototype; ApiLink( 'kernel32', 'PVOID GetCommandLine(void)' ); my $cmdline = GetCommandLine( 0 ); my( $exe, $switches, $script, $params ) = $cmdline =~ m[(\S+)\s+(-\S+)?\s+"([^"]+)"\s*(.*$)]; print "Script params: '$params'"; __END__ P:\test>331797 "A A" B Script params: '"A A" B' P:\test>331797 "A A\" B Script params: '"A A\" B'

    Examine what is said, not who speaks.
    "Efficiency is intelligent laziness." -David Dunham
    "Think for yourself!" - Abigail
    Timing (and a little luck) are everything!
Re: \" on the WinXP Command Line
by NetWallah (Canon) on Feb 25, 2004 at 20:32 UTC
    • Its not clear what behaviour you are expecting.
    • This is OT, since your question relates to Win32 command line argument passing, rather than perl.
    That said, - if you want 2 parameters passed in, with a trailing '\', try passing the params as '"A A\\" B"':
    >perl -e "foreach (@ARGV){print qq('$_'\n);}" "A A\\" B" 'A A\' 'B'
    perl never gets a chance to parse the escaped "\" - that is done by the cmd interpreter.

    Update: Aah - learned something today - there is a backdoor way to get the args after all! .. see nodes below.

    "Experience is a wonderful thing. It enables you to recognize a mistake when you make it again."
      I'm sorry, I'm expecting all arguments (even those ending with a backslash) to be parsed as they are in example B.

      As John comments a little later: this is an issue with how Perl handles standard Windows command line arguments (the goal was to avoid deviating from that standard syntax).

      I am looking for Perl based solutions (like the one that John provided). Is this the incorrect forum for that type of question? I'm new to the Perl Monks, so I applogize if I chose the wrong forum.

      Thanks

Re: \" on the WinXP Command Line
by hardburn (Abbot) on Feb 25, 2004 at 20:34 UTC

    Is there a way to handle the behavior in Perl

    Afraid not. The shell parses the arguments before Perl ever sees them.

    ----
    : () { :|:& };:

    Note: All code is untested, unless otherwise stated

      Not in Windows. The shell passes the entire command-line "tail" to the .exe file, and that parses before calling main().
Re: \" on the WinXP Command Line
by Roger (Parson) on Feb 26, 2004 at 10:13 UTC
      Roger: Getopt::Long won't work because perl (and program modules) only see what the command shell passes them, after the command shell is done interpreting (in this case, mis-interpreting) the args.

      BrowserUK and others have provided a method to reach around the command shell and get what the user originally typed in.

      Update: On second thought - it probably IS a good idea to use Getopt::Long after getting the args from the Windows Kernel.

      "Experience is a wonderful thing. It enables you to recognize a mistake when you make it again."
Re: \" on the WinXP Command Line
by flyingmoose (Priest) on Feb 25, 2004 at 21:05 UTC
    I would suggest you test for Windows ($^O=~/win/) and then reassemble the command line before letting your program muck with it.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://331797]
Approved by Old_Gray_Bear
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others avoiding work at the Monastery: (4)
As of 2024-04-25 15:57 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found