=comment Windows quoting by rovf (Monk)on Jul 21, 2008 at 13:18 UTC (#699036=perlquestion) My application generates at run time a Windows BAT file (oh you wonderful Windows Batch language - if I only knew which insane person had invented it!), which then in turn calls other programs (some compiled C application, some Perl programs). I need to pass strings from my Perl application via the Batch file to these programs (using the environment is no option here). For example: my $some_argument='abc'; # ... $batchfile=IO::File->new(">x.bat"); print $batchfile "\@echo off\nMyProg $some_argument\n"; $batchfile->close; # ... later, in a different process ... : system("x.bat"); # executes MyProg abc That's the basic idea. Of course it is not so easy, because I don't know the content of $some_argument until at run-time, and this means I have to generate the argument in a way which is properly quoted according to Batch Language Syntax Rules. I researched a bit how to do proper quoting in Windows batch files, and though a found a bit of information here and a bit of information there, I could not find a concise document which really describes it properly. So my first question is: Does someone happen to know a CPAN module which implements Windows Batch Language quoting? Otherwise, does someone know the rules, so that I can implement it myself? So far, I found the following set of rules: - The special characters <>|^ must be escaped by ^ (for example, we have to convert 'a^b|c' into 'a^^b^|c') - A double quote at the beginning or at the end of the argument must be escaped by \ (for example, we have to convert '"ab"' to '\\"ab"\\') - If the argument contains spaces, it must be enclosed by double quotes, and in practice, it does not hurt to enclose the argument in double quotes always (for example, we have to convert 'a b' to '"a b"') - A double quote, which is followed by a space, must get a backslash in front (for example, we have to convert 'a" b' to 'a\" b') - If the argument starts with \", we are out of luck (at least I have not found yet a way how to encode the string '\\"foo' properly for my batchfile [but see response below] Is this list complete or do I miss something? -- Ronald Fischer =cut =comment Re: Windows quoting by InfiniteSilence (Chaplain) on Jul 21, 2008 at 13:42 UTC Are these batch files going to be reused in the future? If not, perhaps it would be best to do away with this mode of operation altogether and switch to using Win32::Process or something. Celebrate Intellectual Diversity Re^2: Windows quoting by rovf (Monk) on Jul 21, 2008 at 13:56 UTC perhaps it would be best to do away with this mode of operation altogether and switch to using Win32::Process The batch files are sent to a remote machine and executed there independently, at some unspecified later time. The remote execution mechanism *expects* Windows batch files. Basically, the only assumption we have on the remote machine is that it is a standard Windows system which can execute batch files. -- Ronald Fischer Re: Windows quoting by pc88mxer (Vicar) on Jul 21, 2008 at 14:19 UTC Instead of trying to quote $some_argument, can you pass it as an argument? system("x.bat", $some_argument); and then reference it in your batch script as %1 (or however batch scripts do this.) Re^2: Windows quoting by rovf (Monk) on Jul 22, 2008 at 08:19 UTC Instead of trying to quote $some_argument, can you pass it as an argument? No, because I do not call the batch file. A different process on a different machine calls the batch file, and it expects only a batch file, which will be invoked without parameters. -- Ronald Fischer Re: Windows quoting by BrowserUk (Sage) on Jul 21, 2008 at 14:46 UTC If the argument starts with \", we are out of luck (at least I have not found yet a way how to encode the string '\\"foo' properly for my batchfile Using the following cmd file as the mechanism of demonstration (called echoem.cmd): @echo off perl -wle"print qq['$_'] for @ARGV" %* Does this achieve what you are after? C:\test>echoem "\"foo" "bar \"qux" \\\"foo '"foo' ### $1 'bar "qux' ### $2 '\"foo' ### $3 ----------------------------------------------------------------- Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error. "Science is about questioning the status quo. Questioning authority". In the absence of evidence, opinion is indistinguishable from prejudice. "Too many [] have been sedated by an oppressive environment of political correctness and risk aversion." [reply] Re^2: Windows quoting by rovf (Monk) on Jul 22, 2008 at 08:31 UTC \\\"foo Indeed it does! Thanks a lot! -- Ronald Fischer =cut =comment from playing around with various combinations, rules for escaping "-quoted c.l. parameters seem to be: all embedded "-quotes escaped with '\' all embedded '\' that precede non-" must be escaped with a '\' and <|> escaped with a '^' if odd number of \" precede it in line any '^' that is not inserted as an escape is escaped with a '^' 08aug08waw =cut use warnings; use strict; my $backslash_escapable = do { # unescaped " my $raw_qq = qr{ (? ^ ^ ); ### # null esc. seq. for existing \" so they are just counted ### $escape{\"} = ''; my ($hat_escapable) = do { ### # any " not after a \ ### my $not_after_bsl = qr{ (?] }xms; use re 'eval'; my $escapable_special = # qr{ (?(?{ $preceding_embedded_qqs % 2 }) (?= $special)) . }xms; qr{ $special (?{ ++$preceding_embedded_qqs }) }xms; no re 'eval'; # any hat character my $hat = qr{ ^ }xms; # return regex for escapable characters or char sequences qr{ $embedded_bsl | $embedded_qq | $escapable_special | $hat }xms; }; my $param = 'print "a \" b < > \" < >"' # shift or die "no c.l. param" ; $param =~ s{ ($unescaped_embedded_qq) }{\\$1}xmsg; $param =~ s{ ($escapable) } { print qq(-$1- \n); $preceding_embedded_qqs++ if $1 eq q{"}; $escape{$1} }xmsge; # { $preceding_embedded_qqs++ if $1 eq q{"}; $escape{$1} }xmsge; print "~$param~";