Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Windows cmd echo / pipe is adding extra space at the end - how to trim it?

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?

like image 209
Dino Avatar asked Apr 20 '15 12:04

Dino


1 Answers

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)
like image 134
jeb Avatar answered Oct 30 '22 00:10

jeb