8

I have a shell script that I want to execute this line:

qtvars.bat vsstart "qt.sln" /BUILD "Debug|Win32"

This works fine (though I had to modify qtvars.bat, but that's beside the point). The problem is that I want the command to execute to be in a variable: EDIT: This doesn't work either, if I type it into bash. Previously I was typing it into cmd.exe, which hardly made for a fair comparison.

command="qtvars.bat"
args="vsstart"

$command $args "qt.sln" /BUILD "Debug|Win32"

Now it chokes on the pipe! I get this message:

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

I've tried a bunch of forms of escaping the quotes and/or pipe, all to no avail. Interestingly, it works when it's an executable rather than a batch file, e.g.:

command="devenv.exe"
args=""

$command $args "qt.sln" /BUILD "Debug|Win32"

Thanks for any ideas.

Owen
  • 6,853
  • 8
  • 36
  • 50

6 Answers6

9

I know you "escape" the pipe character in a batch file with the ^ character, so...

echo ^| Some text here ^|

Would display...

| Some text here |

I don't know whether that would help you in this instance? Maybe try prepending each pipe character with a ^ and see what happens? :-)

Valiante
  • 182
  • 2
  • 1
3

This is a classic case of double-escaping, where both bash and CMD.EXE need to be instructed to ignore the special | (pipe) character.

Try the following:

$command $args "qt.sln" /BUILD '"Debug|Win32"'

This will be the equivalent of you typing, at a CMD.EXE prompt:

qtvars.bat vsstart qt.sln /BUILD "Debug|Win32"

Using the above, you are essentially forcing the passing of the double-quotes on to CMD.EXE (instead of bash eating them away.) The outermost single quotes instruct bash not to interpret or touch in any way what's inside them; the inner double-quotes instruct CMD.EXE to ignore any special characters (the pipe in this case) within.

Alternatively, you can also try:

$command $args "qt.sln" /BUILD 'Debug\|Win32'

This should be the equivalent of you typing, at a CMD.EXE prompt:

qtvars.bat vsstart qt.sln /BUILD Debug\|Win32

Note the use of single quotes (!), which ensure that bash will not interpret the \ (and, instead, will pass it as-is to CMD.EXE.)

Tim Cooper
  • 144,163
  • 35
  • 302
  • 261
vladr
  • 61,376
  • 17
  • 123
  • 127
  • Tried those. Did it again just now to be sure. They result in the same error, though sometimes 'Win32' becomes 'Win32\""' in the error message. – Owen Feb 20 '09 at 19:28
1

Escaping a piping character in the Windows scripting language is done with a caret (^). I just had to do this the other day. I know this is old, but I thought I would post what I found in case others ran across this, like I did.

  • Thanks! I appreciate it. I somehow didn't notice the previous answer saying that, and the notification of your answer brought me back here. – Owen Aug 12 '12 at 23:31
1

Here's another solution (workaround?) I've found:

first, ensure an environment variable defines the pipe character, for example:
set PIPE="|"

later, run the command specifying the above defined environment variable name:
"c:\(...)\devenv.com" foo.sln /build Debug%PIPE%Win32

That does the job even if there are multiple wrappers between the caller and the callee. I'm now using it with a very long chain of wrappers: Python/Linux -> VirtualBox guest's executeProcess -> Cmd/Windows -> devenv.com

(cross posted to: How to pass a quoted pipe character to cmd.exe?)

Community
  • 1
  • 1
rdesgroppes
  • 616
  • 7
  • 9
0

I'd consider going the easy route, and passing a placeholder-token instead - "$P", and then replace it within the CMD/Batch file; e.g. using the 'UnxUtils' SEd command to do the replacement:

For /F "usebackq delims=" %%r in (`Echo %Cmd% ^| sed -e "s/$P/|/g"`) do @Set Cmd2=%%r

REM  Now run the command, with the proper pipe symbol in place

%Cmd2%

So having passed the command arg/CMD script args - "git status $P wc -l".

DennisVM-D2i
  • 54
  • 1
  • 5
0

Interesting! What does escaping the | do?

Do these work?

  • echo "Debug|Win32"
  • echo "qt.sln" /BUILD 'Debug|Win32'
dirkgently
  • 101,474
  • 16
  • 123
  • 183
  • Do you mean: What is the intent? To have bash or cmd.exe pass the | through as part of the argument, rather than trying to process it as pipe syntax. or What is the result in my situation? Nothing. – Owen Feb 20 '09 at 19:31
  • I wanted to know what was the result of using escape? – dirkgently Feb 20 '09 at 19:39