Powershell: CLI: escaped command line quotes "" difference with powershell 5.1

Created on 13 Jan 2020  路  7Comments  路  Source: PowerShell/PowerShell

PowerShell

Steps to reproduce

C:\> pwsh -Command "echo 1 \"2 3\""

Expected behavior

1
2 3

Actual behavior

1
2
3

Environment data

Major  Minor  Patch  PreReleaseLabel BuildLabel
-----  -----  -----  --------------- ----------
7      0      0      rc.1
Issue-Question Resolution-Answered

All 7 comments

No version of PowerShell or cmd has ever used the backslash \ as the escape character.

It's the caret ^ for cmd, and the backtick ` for PowerShell (all versions).

Either way, the behavior of this mostly depends on how the calling shell interprets the quotes ".
I cannot replicate this.

When calling from cmd.exe:

jantari@AMDESKTOP:C:\Users\jantari
鈹斺攢 cmd> pwsh-preview -Command "echo 1 \"2 3\""
1
2 3

jantari@AMDESKTOP:C:\Users\jantari
鈹斺攢 cmd> powershell -Command "echo 1 \"2 3\""
1
2 3

When calling from PowerShell 7:

jantari@AMDESKTOP:~ > powershell -Command "echo 1 \"2 3\""
1
\
2
3\
jantari@AMDESKTOP:~ > pwsh-preview -Command "echo 1 \"2 3\""
1
\
2
3\

When calling from Windows PowerShell:

jantari@AMDESKTOP:~
鈹斺攢 PS> powershell -Command "echo 1 \"2 3\""
The string is missing the terminator: ".
    + CategoryInfo          : ParserError: (:) [], ParentContainsErrorRecordException
    + FullyQualifiedErrorId : TerminatorExpectedAtEndOfString

jantari@AMDESKTOP:~
鈹斺攢 PS> pwsh-preview -Command "echo 1 \"2 3\""
jantari@AMDESKTOP:~
鈹斺攢 PS>

Windows PowerShell: 5.1.19041.1
PowerShell Core: 7.0.0-rc.1

You are right about \"". However, I can still repro this with "".
I have a another, clean, Windows Insider VM where I can also reproduced it:
This may be related to how you install pwsh, in my case using dotnet tool install powershell --global --version 7.0.0-rc.1

C:\Users\Gerardo>ver

Microsoft Windows [Version 10.0.19541.1000]

C:\Users\Gerardo>dotnet
'dotnet' is not recognized as an internal or external command,
operable program or batch file.

C:\Users\Gerardo>pwsh
'pwsh' is not recognized as an internal or external command,
operable program or batch file.

C:\Users\Gerardo>curl https://download.visualstudio.microsoft.com/download/pr/639f7cfa-84f8-48e8-b6c9-82634314e28f/8eb04e1b5f34df0c840c1bffa363c101/dotnet-sdk-3.1.100-win-x64.exe
(...)

C:\Users\Gerardo>dotnet-sdk-3.1.100-win-x64.exe 
(...)

C:\Users\Gerardo>dotnet tool install powershell --global --version 7.0.0-rc.1
Since you just installed the .NET Core SDK, you will need to reopen the Command Prompt window before running the tool you installed.
You can invoke the tool using the following command: pwsh
Tool 'powershell' (version '7.0.0-rc.1') was successfully installed.
(...)

C:\Users\Gerardo>pwsh -Version
PowerShell 7.0.0-rc.1

C:\Users\Gerardo>pwsh -Command "echo 1 ""2 3"""
1
2
3

C:\Users\Gerardo>powershell -Command "echo 1 ""2 3"""
1
2 3

/cc @mklement0 It seems it is dup?

I _think_ the issue is related to installation of PowerShell as a dotnet global tool, because the regularly installed PowerShell does _not_ exhibit these problems.

Some general background information below (applies to the regularly installed version):


No version of PowerShell or cmd has ever used the backslash \ as the escape character.

The PowerShell _CLI_ has always supported \ for escaping ", for consistency with other console applications (even though PowerShell-_internally_ you must escape them as `" or "" (inside "..." only)).

On Windows, the majority of - but not all - console applications support "" for escaping " as an alternative to \".

Windows PowerShell did _not_ support this properly, but PowerShell Core now does.

Therefore, _when executed from cmd.exe_, both the following commands work:

# Also works on Unix-like platforms, from a POSIX-like shell such as Bash.
# (For literal strings you can also use '...' quoting there, without the need to 
#  escape embedded " chars.)
# Situationally, this can break on Windows.
C:>pwsh -noprofile -c "echo 1 \"2 3\""

# Windows only, but works robustly.
C:>pwsh -noprofile -c "echo 1 ""2 3"""

On Windows, the \"-escaped command can break, since cmd.exe itself doesn't recognize \" as an _escaped_ ", so what follows it is considered _unquoted_ and breaks with chars. such as &; e.g.:
C:>pwsh -noprofile -c "echo 1 \"2 & 3\"".
Since cmd.exe _does_ recognize "" as an escaped, ", it is therefore safer to use "" _on Windows_ - but, unfortunately, that doesn't work on Unix.

The upshot:

  • Use "" on Windows, but know that it won't work on Unix.
  • Use \" on Unix and if you need to be cross-platform, but know that it _may_ break on Windows (probably not too frequently)

I can reproduce the problem with PowerShell Core 7.0.0-rc.2 _when installed as a .NET global tool_, @gerardog, and to present it in a more focus manner I've created #11747.
If you agree with the new presentation, please close this issue.

P.S.: It's a reasonable assumption that all pwsh executables with a given version number are created equal, irrespective of the installation method, but that is unfortunately not true for the dotnet tool-installed version, which has exhibited other problems in the past.

Fair enough. Thanks!

Was this page helpful?
0 / 5 - 0 ratings