I wrote a bat file to generate a keystore via keytool. My code is:
cd C:\Java\jdk-11.0.1\bin
set Pass=12345678
set RepetitionPass=test
set FLname=test
set OrganUnit=test
set Organ=test
set City=test
set State=test
set Country=US
set Pass=%Pass: =%
set RepetitionPass=%RepetitionPass: =%
set FLname=%FLname: =%
set OrganUnit=%OrganUnit: =%
set Organ=%Organ: =%
set City=%City: =%
set State=%State: =%
set Pass=%Pass: =%
set Country=%Country: =%
(echo.%Pass% && echo.%RepetitionPass% && echo.%FLname% && echo.%OrganUnit% && echo.%Organ% && echo.%City% && echo.%State% && echo.%Country% && echo y)| keytool -genkey -v -keystore my-release-key.keystore -alias alias_name -keyalg RSA -keysize 2048 -validity 10000
pause
I put this code inside Notepad and then changed its extension to .bat. Everything works fine My only problem is that the end of a space password is automatically added. For example, if my password is "12345678", when the key is generated, its password will be "12345678 ". For some reason, I do not want to use Android Studio to generate the key, and I must produce my Key Store this way. where is the problem from? How do I solve this problem?
CodePudding user response:
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, likeset "Pass=12345678"
instead ofset 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 thanset Pass=%Pass: =%
). - Although widely used,
echo.
is a bad way of echoing a (potentially) empty line, because a file calledecho.
is actually searched before the internal commandecho
becomes executed. If, for whatever reason, such a file exists, it is attempted to be executed instead. Therefore, use the syntaxecho(
, 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.