Reputation: 97
Is there a way in a batch script to add multiple spaces at the beginning of each line without breaking the syntax and keeping the spaces on each line as they are as per example below?
gacutil /u ^
Microsoft.IdentityModel.Clients.ActiveDirectory,^
Version=2.28.0.725,^
Culture=neutral,^
PublicKeyToken=31bf3856ad364e35
The goal is to allow better readability not only when utilizing gacutil.exe
but whenever writing a batch command
Upvotes: 1
Views: 694
Reputation: 49216
Every executable has its own rule set for splitting up the string after the executable file name into argument values being processed further by the executable.
The windows command processor cmd.exe
interprets a horizontal tab, a normal space, a comma, a semicolon, an equal sign and an OEM encoded no-break space (byte with hexadecimal value FF) outside a double quoted string as argument separators as it can be seen on running a batch file with name test.cmd
with just the command line @echo %0 $1 $2 $3 $4
from within a command prompt window with
test argument1,,,"argument 2";;;"argument 3 contains a comma ',' a semicolon ';' an equal sign '=' and multiple spaces"===argument4
resulting in the output
test argument1 "argument 2" "argument 3 contains a comma ',' a semicolon ';' an equal sign '=' and multiple spaces" argument4
,,,
and ;;;
and ===
are interpreted as argument string separators.
The global assembly cache tool gacutil.exe
splits up the string passed to it to argument strings different in comparison to cmd.exe
. Commas and equal signs are not interpreted as argument separators. Only the normal space character is interpreted as argument separator, except a normal space is inside a double quoted argument string.
It is common for Windows executables that the number of argument separators between argument strings does not matter. So if there is used just one space or multiple spaces between two argument strings does not matter.
What does happen on using in a batch file following lines?
gacutil /u ^
Microsoft.IdentityModel.Clients.ActiveDirectory,^
Version=2.28.0.725,^
Culture=neutral,^
PublicKeyToken=31bf3856ad364e35
Please read first: How does the Windows Command Interpreter (CMD.EXE) parse scripts?
The Windows command processor cmd.exe
reads a batch file line by line with replacing carriage return + line-feed by just a line-feed on reading a line.
The caret character ^
at end of a line is interpreted by cmd.exe
as an escape character for the newline character line-feed resulting in concatenating the next line with the current line which is repeated until either reaching end of the batch file or finding a line-feed not escaped with ^
. There are no characters removed during the concatenation of lines in a batch file.
The result for the lines above in the batch file with three leading normal spaces on each line is:
gacutil /u Microsoft.IdentityModel.Clients.ActiveDirectory, Version=2.28.0.725, Culture=neutral, PublicKeyToken=31bf3856ad364e35
The three leading spaces left to gacutil
at beginning of the command line are removed by cmd.exe
, but all other spaces are kept because of cmd.exe
cannot know if they are important for the program/script to run next or not. So there are four spaces after /u
and three spaces between the other strings specified on separate lines in the batch file.
gacutil.exe
interprets the command line now as list of following arguments:
/u
Microsoft.IdentityModel.Clients.ActiveDirectory,
Version=2.28.0.725,
Culture=neutral,
PublicKeyToken=31bf3856ad364e35
The result is an error message because of gacutil.exe
must be run in this case with just two arguments:
/u
to instruct the global assembly cache tool to uninstall an assembly from the global assembly cacheMicrosoft.IdentityModel.Clients.ActiveDirectory,Version=2.28.0.725,Culture=neutral,PublicKeyToken=31bf3856ad364e35
.So the indenting spaces used in the batch file between the individual parts of the assembly name argument string not removed by cmd.exe
makes the command line invalid for gacutil.exe
.
For that reason it is not possible in this case to define the assembly name argument string on multiple lines with indenting spaces because of how cmd.exe
concatenates the lines with keeping the spaces and how gacutil.exe
splits up the string passed to it from cmd.exe
into arguments.
A different executable could do the string splitting to a list of argument values different and for that reason writing the arguments of the executable on multiple lines in a batch file with indent spaces could work for this executable.
But the following syntax can be used in a batch file for this use case:
gacutil /u ^
^"Microsoft.IdentityModel.Clients.ActiveDirectory,^
Version=2.28.0.725,^
Culture=neutral,^
PublicKeyToken=31bf3856ad364e35^"
The global assembly cache tool has no problems with one or more spaces after a comma in assembly name as long as the entire assembly name argument string is enclosed in double quotes. For that reason there is a "
at beginning and one more "
at the end of the assembly name string. But the two double quotes must be escaped with ^
for the Windows command processor as otherwise cmd.exe
would interpret the caret character ^
at end of each line as literal character and not as an escape character.
The command line spread over multiple lines must be interpreted by cmd.exe
as a line with no argument string in double quotes to get each ^
interpreted as escape character while the assembly name is in real enclosed in double quotes on running finally gacutil.exe
with the command line:
gacutil /u "Microsoft.IdentityModel.Clients.ActiveDirectory, Version=2.28.0.725, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
Yes, that is strange.
Upvotes: 1