views:

498

answers:

2

Hi,

On many occasions I have dealt with passing batch files arguments with spaces, quotes, percents, and slashes and all sorts of combinations of them. Usually I managed to figure out how to accomplish what I want, but this time I am stuck. I have tried a couple of hundred combinations now and my head is starting to hurt.

I’ve reduced the problem to a—fairly—simple requirement: pass from one batch file to another, an argument that contains some space-delimited text, one of which is a quoted space. That is, one batch file should pass some string X to another so that the the second one echos "A "B C" D". I just can’t figure out what X should be.

Here is a minimal batch file that demonstrates some attempts that do not work. (This BAT file takes the place of both by calling itself.)

::Goal is to print:
::"A "B C" D"
::ie., pass from one BAT file to another a quote containing spaces and a quote containing a space
@echo off
if not (%1)==() goto print
:passarg
  call %0 "A "B C" D"
  call %0 "A \"B C\" D"
       %0 "A ""B C"" D"
:print
  echo %1
  pause

None of those attempts work. I’ve tried using "\" \"", """ """, """" """", "\"" "\"", ""\" \""", "^" ^"", ^"" "^", and so on. Either they print double double-quotes, lose everything after the space, or something else (that is wrong).

Any ideas? Thanks.

+1  A: 

This works

@echo off
if not (%1)==() goto print
:passarg
  call %0 "A "B C" D"
:print
  echo %*
Charles Gargent
Hmm, I seem to have reduced it a little too much. I’ll update it in a second… done.
Synetech inc.
Im unsure what your goal is now, in the updated code ^" ^" still works. What phrase are you trying to pass, and what actually comes out?
Charles Gargent
I’m trying to print `"A "B C" D"`. The `" "` has other stuff (including spaces) around it. Using `^" ^"` (eg `"A ^"B C^" D"`) does not work.
Synetech inc.
sorry i caught your edit half, way through. I have been looking at the last change and I think the problem lies in how you call the batch file , in my test calling the batch file with the parameters on the command line gives a different result if they are in the file ...
Charles Gargent
Indeed. That is a nasty little trick that I doubt is documented anywhere. I have had many times when I managed to get something working from one place only to find it not working from the other. :(
Synetech inc.
Try this now please.
Charles Gargent
For the purposes of this simplified example, that does indeed work. For the purposes of using it in a real BAT file with other arguments besides just this one, it will still work, but would require quite a bit more work to parse the arguments correctly. Since %* would concatenate the other args to this one, instead of %* it would have to have a loop to test each argument, shift, store other args in env.vars., and finally use something like `%3%4%5` as the target string.This method is however good to keep in mind for cases where it would simplify things.
Synetech inc.
+2  A: 

How about this workaround:

caller.bat:

@echo off
echo "A "B C" D">dummy.txt
call callee.bat

callee.bat:

@echo off
set /p argument=<dummy.txt
echo %argument%
pause
JRL
Well that works and I’ll consider using it instead of what I’m currently doing (directly setting a registry entry instead of using a specific BAT file to do it), but I really prefer avoiding the use of temporary files.
Synetech inc.
Doh! I just remembered why I had already dismissed this method before you posted it: it would require modifying the other batch file to accept environment variables for its input in addition to command line arguments. That’s no good for cases where you can’t modify the callee, and for cases where you can, it requires a fair bit of more work to support two input methods (BAT files are CISC—uh, CISL languages like ASM: limited commands, and thus unwieldy).
Synetech inc.
Oh, and who cleans up the environment variable? The caller or the callee? It’s not like a class that can be destroyed when it goes out of scope; the variable will linger there until the console is closed. :(
Synetech inc.
Double-oh, the file is unnecessary, you can just set the variable directly.
Synetech inc.