The Windows Command Prompt is rather sensitive to SPACEs, so when you provide such, they may have some effect. For instance: echo foo & echo bar
will output a line foo
+ SPACE and a line bar
(given that there is no "invisible" trailing SPACE, of course).
But the situation at hand is even more complicated: You have got a pipe (|
) involved in your batch script, which will initiate a new cmd.exe
instance for the left side since there is a parenthesised block1; this new instance receives the left code somehow rebuilt, so even more unwanted SPACEs become inserted. Returning to the previous example, (echo foo&echo bar) | more
would return even both lines with a trailing SPACE each2, because the left command would become rebuilt as something like ( echo foo & echo bar )
.
Even the following would still return a trailing SPACE per line:
(
echo foo
echo bar
) | more
since the command block on the left side would again become rebuilt to something like ( echo foo & echo bar )
.
A possible solution is to escape the ampersand, so it becomes passed over to the new cmd.exe
instance literally without modification:
(echo foo^& echo bar) | more
Obviously this only prevents the first line from being appended with a SPACE, but when we append another escaped ampersand plus a command that literally does nothing, like rem/
3, the solution is complete:
(echo foo^& echo bar^& rem/) | more
The same can also be applied to the block approach:
(
echo foo^& rem/
echo bar^& rem/
) | more
which would eventually become translated to something like ( echo foo& rem/ & echo bar& rem/ )
.
Now let us apply this to your code, together with another few changes:
- The
cd
command requires the /D
option in order to change the current drive as well, and quoting paths is generally a good practice. Also consider what to do when the path does not exist or cannot be accessed for some reason (conditional execution &&
or ||
may serve here).
- You should generally prefer the quoted syntax of the
set
command, like set "Pass=12345678"
instead of set Pass=12345678
, in order to protect special characters and to avoid unwanted trailing SPACEs.
- I entirely skipped the code block for removal of SPACEs, because I assume this was just a failed attempt to remove the unwanted SPACEs in the output (if you do want that block, you should use the quoted syntax like
set "Pass=%Pass: =%"
rather than set Pass=%Pass: =%
).
- Although widely used,
echo.
is a bad way of echoing a (potentially) empty line, because a file called echo.
is actually searched before the internal command echo
becomes executed. If, for whatever reason, such a file exists, it is attempted to be executed instead. Therefore, use the syntax echo(
, which looks odd but is safe.
- You do not need conditional execution to chain
echo
commands, an unconditional &
operator is fine.
So here is the probably fixed code:
@echo off
cd /D "C:\Java\jdk-11.0.1\bin" || exit /B
set "Pass=12345678"
set "RepetitionPass=test"
set "FLname=test"
set "OrganUnit=test"
set "Organ=test"
set "City=test"
set "State=test"
set "Country=US"
(
echo(%Pass%^& rem/
echo(%RepetitionPass%^& rem/
echo(%FLname%^& rem/
echo(%OrganUnit%^& rem/
echo(%Organ%^& rem/
echo(%City%^& rem/
echo(%State%^& rem/
echo(%Country%^& rem/
echo y^& rem/
) | keytool -genkey -v -keystore my-release-key.keystore -alias alias_name -keyalg RSA -keysize 2048 -validity 10000
pause
1) For a detailed explanation refer to this post: How does the Windows Command Interpreter (CMD.EXE) parse scripts? (see phase 5.3)
2) Write the output into a file using output redirection (>
) in order to prove it.
3) It has to be rem/
and not rem
, because the latter would comment out the whole remainder of the command line.