6

I'm working on a script that executes a command line application which requires user input at runtime (sadly command line arguments are not provided).

So my first attempt looked like this:

@echo off
(echo N
echo %~dp0%SomeOther\Directory\
echo Y)|call "%~dp0%SomeDirectory\SadSoftware.exe"

At first glance it looked like it worked pretty well, but as it turned out it didn't. After investigation I found out that the directory I was passing to the software contained extra space at the end, which resulted in some problems.

I looked around for a while and found out following question: echo is adding space when used with a pipe .

This explained what is going on, but didn't really help me solve my problem (I'm not too familiar with batch programming).

At the moment I "kind of solved" my problem with an ugly workaround:

echo N> omg.txt
echo %~dp0%SomeOther\Directory\>> omg.txt
echo Y>> omg.txt

"%~dp0%SomeDirectory\SadSoftware.exe"<omg.txt

del omg.txt

This solution works, but I'm less than happy with it. Is there some prettier way? Or even uglier way, but without temporary file?

1 Answer 1

10

Solution1: Linefeeds

You can use a linefeed to avoid the spaces.
The rem. is required to avoid problems with the injected & by cmd.exe

SET LF=^


REM ** The two empts lines are required for the new line **

(
echo line1%%LF%%rem.
echo line2%%LF%%rem.
echo line3%%LF%%rem.
) | sort

When a block is piped the cmd.exe will rebuild the block by building a single line combined with ampersands between each command.

(
echo line1
echo line2
) | sort

Will be converted to

C:\Windows\system32\cmd.exe  /S /D /c" (<space>echo line1<space>&<space>echo line2<space>)"

So the linefeed trick results in a line like

C:\Windows\system32\cmd.exe  /S /D /c" ( echo line1%LF%rem. & echo line2%LF%rem. )"

And this expands to

( echo line1
rem. & echo line2
rem. )

Solution2: Escaped ampersands
You can also use directly ampersands, but they need to be escaped, else the spaces are injected anyway.
The last rem. is to avoid a space after the last echo

( 
    echo Line1^&echo Line2^&echo Line3^&rem. 
) | more

Solution3: Create a single command
@MCND Mentioned the trick to use directly the form:

cmd /q /c"(echo line1&echo line2&echo line3)" | sort

This works, as the parser only sees the cmd command, the rest is handled as parameters for this single command.
Therefore there aren't any problems with spaces. Or with the linefeeds it looks like

cmd /q /c"(echo line1%%LF%%echo line2%%LF%%echo line3)"| (sort > out.txt)

And then you can modify it also to

cmd /q /c^"(echo line1%%LF%%^
echo line2%%LF%%^
echo line3)^"| (sort > out.txt)
3
  • 3
    Just for completion, maybe you could include cmd /q /c"(echo line1)&(echo line2)&(echo line3)"|more
    – MC ND
    Commented Apr 20, 2015 at 13:28
  • Thanks! I've used the second solution and it works like a charm. ^_^
    – Dino
    Commented Apr 21, 2015 at 7:46
  • Thanks for the great answer. I've used Solution2 in this way (new lines are not allowed in comments therefore "<crlf>" is a new line here): (<crlf> echo b^& ^<crlf> echo a^& ^<crlf> rem.<crlf> ) | sort so you don't have to put everything in one line.
    – anilech
    Commented Oct 17, 2016 at 10:29

Not the answer you're looking for? Browse other questions tagged or ask your own question.