docker run -v "$(pwd)":/assignments -it reeselevine/cse113:latest not working [duplicate]

First, the obligatory warning: Unless you have a command line stored as a single string somewhere and you either fully control or trust the content of the string, Invoke-Expression should generally be avoided.


You're seeing an inconsistency in how PowerShell relays arguments to external programs, such as docker, as of PowerShell 7.1.

Specifically, argument "C:\Test Folder With Blanks":/zzz is unexpectedly broken in two (i.e, passed as two separate arguments).

The workaround is to quote the entire argument, i.e.
"C:\Test Folder With Blanks:/zzz"

Note: I'm assuming that docker doesn't actually require partial quoting in its arguments, which it shouldn't; however, there are high-profile CLIs on Windows that do, notably msiexec.

General caveats:

  • Compared to cmd.exe and also POSIX-compatible shells such as bash, PowerShell has several additional metacharacters, notably @ (at the start of a token), { / }, and ;. Therefore, you cannot always expect command lines written for these shells to work as-is in PowerShell.

  • As of PowerShell 7.1, passing arguments to external programs is fundamentally broken with respect to arguments that have embedded " characters and arguments that are the empty string - see this answer.


The general pattern of the inconsistency, as of PowerShell 7.1, is as follows:

If an argument:

  • starts with a quoted token - whether single- ('...') or double-quoted ("...") -
  • and has additional characters directly following the closing quote,

the first such character starts a separate argument.

E.g. "foo":bar / "foo"=bar are passed as separate arguments foo and :bar / foo and =bar, respectively.

In other words:

  • You cannot compose a single string argument from a mix of quoted and unquoted tokens if the first token is quoted.

  • Conversely, it does work if the first token is unquoted.

# OK: First token is unquoted.
PS> cmd /c echo foo"bar"'baz'last
foobarbazlast

# !! BROKEN: First token is quoted.
# !!         Because each successive token is quoted too, 
# !!         each becomes its own argument.
PS> cmd /c echo 'foo'"bar"'baz'last
foo bar baz last

GitHub issue #6467 discusses this inconsistency; however, it has been closed, because the behavior is - surprisingly - considered by design.


This does not happen if the first token is unquoted; however, there are related bugs that start with unquoted tokens that similarly break arguments in two, related to their looking like named arguments to PowerShell (which is a PowerShell concept that doesn't apply when calling external programs):

  • GitHub issue #11646: an argument such as -foo=1,2 breaks parsing.

  • GitHub issue #6291: an argument such as -foo=bar.baz is broken in two at the (first) .