Corrected double side effect on the Windows command line

I ran into a very strange problem with the Windows command interpreter. This happens on both XP and Windows 7. My description below relates to a Perl script, but this problem is used to run any program on the command line that accepts command line parameters.

For the test, I use a Perl script check-params.pl , which simply displays what it saw as parameters -

 use strict; use warnings; while (my $param = shift @ARGV) { print "Param: [$param]\n"; } 

So, if I run -

 perl check-params.pl "ab|<>" c^|^<^>cc 

Then the conclusion

 [Param: ab|<>] [Param: c|<>cc] 

as was expected. Special characters | <> we work normally inside double quotes, but when external quotes you escape them with ^.

However, when a double quote is added to the specified parameter, for example, in

 perl check-params.pl "a\" b|<>" 

Then I get the error -

 > was unexpected at this time. 

But if a double checkout occurs after a special char | <or>, then it works fine.

You can easily fix this by speeding up a special | <> char c ^ inside the specified parameter. eg,

 perl check-params.pl "a\" b^|" 

However, it’s not just the hidden double quote that affects special characters | <> in the current parameter, but it affects these special characters inside any subsequent parameters.

For example, if I do this -

 perl check-params.pl "aa \"bb" ccc | perl check-pipe.pl 

(where check-pipe.pl just prints what the pipe got -

 use strict; use warnings; while (<STDIN>) { print "PIPE RECEIVED ---> $_"; } 

)

then the conclusion will be -

 Param: [aa "bb] Param: [ccc] Param: [|] Param: [perl] Param: [check-pipe.pl] 

those. he processes the pipe | as a letter symbol, and there are no pipelines.

Does anyone have any experience with this problem and are aware of a workaround?

I have written several Perl scripts to process web log files, and one uses regular expressions that I pass inside the quoted parameter on the command line. A regular expression may contain characters such as | <>, and it may also have a double quote that I enter as \ ". Thus, the above problem arises.

Any help is greatly appreciated, thanks.


Thanks for the answer, but when you try this on XP SP3, the Perl script sees two command line options.

This problem is not related to Perl, for example

 echo "a \"b|c" 

causes an error -

 'c"' is not recognized as an internal or external command, operable program or batch file. 

but

 echo "ab|\"c" 

works because \ "comes after a special char |.

This must be an error in the command interpreter. I would be interested to know more about this and find a workaround if possible. This issue confuses some useful scripts. This is a pretty glaring issue for the shell. I also tried on Windows 7, and the same problem occurs there with the above echo test.


Additional Information:

I updated the check-params.pl and check-pipe.pl scripts to provide more useful information: -

check-params.pl: -

 use strict; use warnings; while (my $param = shift @ARGV) { print "COMMAND LINE RECEIVED: [$param]\n"; } 

check-pipe.pl: -

 use strict; use warnings; while (<STDIN>) { print "PIPE RECEIVED: $_"; } while (my $param = shift @ARGV) { print "COMMAND LINE RECEIVED: [$param]\n"; } 

For example: running: -

 perl pl/utils/check-params.pl l1 l1-b l1-c | perl pl/utils/check-pipe.pl l2 l2-b | perl pl/utils/check-pipe.pl l3 l3-b | perl pl/utils/check-pipe.pl united arsenal rangers raith 

displays the result: -

 PIPE RECEIVED: PIPE RECEIVED: PIPE RECEIVED: COMMAND LINE RECEIVED: [l1] PIPE RECEIVED: PIPE RECEIVED: PIPE RECEIVED: COMMAND LINE RECEIVED: [l1-b] PIPE RECEIVED: PIPE RECEIVED: PIPE RECEIVED: COMMAND LINE RECEIVED: [l1-c] PIPE RECEIVED: PIPE RECEIVED: COMMAND LINE RECEIVED: [l2] PIPE RECEIVED: PIPE RECEIVED: COMMAND LINE RECEIVED: [l2-b] PIPE RECEIVED: COMMAND LINE RECEIVED: [l3] PIPE RECEIVED: COMMAND LINE RECEIVED: [l3-b] COMMAND LINE RECEIVED: [united] COMMAND LINE RECEIVED: [arsenal] COMMAND LINE RECEIVED: [rangers] COMMAND LINE RECEIVED: [raith] 

thereby confirming that this command line will work as expected. Scripts will work with any number of channels on the command line.


Additional Information:

I find that I can get this to work using numerous workarounds - for example, Harry - one example. Sometimes you can rewrite the regex to avoid using it. "When there are two sequences before the special char | <>, then the problem does not arise. Before running any command, I run check-params.pl and check-pipe.pl to check how Perl scripts will see command line options, for example, the above edit to my OP describes these scripts that I have changed since my OP.

+7
source share
1 answer

The double quotation mark in \ "is considered to coincide with the initial double quote, ending with the specified parameter. To include the double quote in the specified parameter, use two double quotes:

 perl check-params.pl "a"" b|<>" 

should generate the expected result, depending on how perl.exe analyzes the command line parameters (I tested command scripts, since I do not have Perl installed). You will need to modify your script so that "instead of \" is treated as a double quote.

Optional : this command line

 echo "a \"b|c" 

I get an error message starting with c" is not recognized . This is not an error.

The backslash is not an escape character, so the command line contains one line with quotation marks ( "a \" ), followed by a pipe ( | ), which makes the rest ( c" ) an additional command, the echo command is transmitted over the channels.

If you say

 echo "a ""b|c" 

that is, there is only one line with quotes ( "a ""b|c" ), and it will work as expected.

Unfortunately, I can now confirm that parsing on the ActivePerl command line invokes

 perl check-params.pl "a"" b|" 

divided into two parameters. You may need to extract the entire command line (if there is a way to do this in Perl) and analyze it yourself.

Additional

 perl check-params.pl ^"a\^" b^|c^" 

gives the desired result. This works by avoiding all special characters, including quotation marks.

+2
source

All Articles