9

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.

1
  • I think the Batch language is a bit particular, in that the invoked programs must remove quotes from the arguments; it is not done automatically by Batch. Therefore I would try to pass the quotes verbatim to Batch, as counter-intuitive as this may sound, i.e. do a cmd /c qtvars.bat vsstart qt.sln /BUILD '"Debug|Win32"' Commented Jul 25, 2022 at 7:26

6 Answers 6

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? :-)

Sign up to request clarification or add additional context in comments.

Comments

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.)

1 Comment

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.
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?)

Comments

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.

1 Comment

Thanks! I appreciate it. I somehow didn't notice the previous answer saying that, and the notification of your answer brought me back here.
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".

Comments

0

Interesting! What does escaping the | do?

Do these work?

echo "Debug|Win32"
echo "qt.sln" /BUILD 'Debug|Win32'

2 Comments

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.
I wanted to know what was the result of using escape?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.