I am trying to run a powershell command with several string arguments via cmd.
The context is that I want to use the Compress-Archive
cmdlet from a Matlab function/script. And Matlab only has access to cmd.
But I can't find a way to preserve consecutive spaces in the string arguments when calling powershell.exe
in cmd.
C:\Users\Artus>powershell.exe echo 'a c'
a c
C:\Users\Artus>powershell.exe echo \"a c\"
a c
C:\Users\Artus>powershell.exe echo `"a c`"
c`
C:\Users\Artus>powershell.exe echo \"`'a c`'\"
'a c'
I tried to adapt the answers for this, this and this questions and none worked.
How does one avoid the removal of consecutive spaces when passing arguments to powershell.exe? Is there a way to ask powershell.exe to accept an argument as string literal?
CodePudding user response:
To add an explanation to Theo's effective solution:
# Use of "..." around the entire argument is the key.
# (The extra space before and after the command is just for visual clarity.)
powershell.exe " echo 'a c' "
# Alternative with embedded double-quoting
powershell.exe " echo \"a c\" "
That is, enclosing the entire command in "..."
is necessary to avoid the whitespace normalization you saw.
When you pass a command (piece of PowerShell code) to the PowerShell CLI, via the -Command
(-c
) parameter (which is positionally implied in your case), PowerShell performs the following command-line parsing first, by splitting the command line into:
- white-space separated tokens
- with double-quoted tokens (
"..."
) getting recognized as single tokens even if they contain spaces, with the interior spaces getting preserved as-is; note that these (unescaped)"
are removed in the process).- Note: By contrast,
'...'
-enclosed tokens are not recognized as single tokens on the command line (even though inside a PowerShell session they are), so that'a b'
is split into verbatim'a
andb'
.
- Note: By contrast,
The resulting tokens are then joined with a single space to form the single string that is then interpreted and executed as PowerShell code.
It is during the splitting by whitespace - which can be any number of spaces between tokens - that the information about how many spaces there were between tokens is lost.
Only inside "..."
-enclosed tokens is the whitespace preserved as-is, hence the use of "..."
around the entire command above.
If you need to use "
quoting as part of the PowerShell command (to use string interpolation), "
characters must be escaped as \"
, as shown in the second command at the top.
However, if you're calling from cmd.exe
/ a batch file, this may break due to how cmd.exe
parses command lines. In such edge cases, use the workarounds discussed in this answer.