1

I was making user-entered variable configurable via command line parameters & ran into this weird behaviour:

PS D:> python -c "import sys; print(sys.argv)" -imgs ".\Test V4\Rilsa\" -nl 34
['-c', '-imgs', '.\\Test V4\\Rilsa" -nl 34']

PS D:> python -c "import sys; print(sys.argv)" -imgs ".\TestV4\Rilsa\" -nl 34
['-c', '-imgs', '.\\TestV4\\Rilsa\\', '-nl', '34']

If the name of my folder is Test V4 with a space character, then all following parameters end up in the same argument element '.\\Test V4\\Rilsa" -nl 34'. There is also a trailing " quote after the directory name. I tried this again in CMD, thinking it was a Powershell quirk & experienced the same behaviour.

What's going on here? I'm assuming it has something to do with backslashes in Powershell -- though it's the default in Windows for directory paths -- but why do I get diverging behaviour depending on space characters & what's a good way to handle this assuming Windows paths are auto-completed into this form by the shell (i.e. trailing \)?

2
  • 1
    Found an unrelated question which incidentally answered this with respect to PowerShell: stackoverflow.com/questions/71283820/… :: PowerShell parsing preserves the final backslash and drops the single quotes. Then it adds double quotes (because of the spaces in the path) before passing the command line to the C runtime which parses it according to the rules, escaping the double quote added by PowerShell. -- This pretty much answers "why" this is happening; but is the only good way to fix to reparse sys.argv? Commented Feb 28 at 12:52
  • A quick workaround would be to not have spaces in the pathname. Having spaces leads to no end of problems and you waste a lot of time finding that the space is causing the problem and then looking for a solution to fix it. By the time you've done all that, you've probably forgotten what you wanted to do originally. Commented Mar 1 at 16:30

1 Answer 1

2
  • You're seeing a bug in Windows PowerShell (the legacy, ships-with-Windows, Windows-only edition of PowerShell whose latest and last version is 5.1), which has since been fixed in PowerShell (Core) 7, as detailed in this answer.

  • In short, as you've since discovered yourself, the problem occurs when you pass arguments that contain space(s) and end in \ to external programs, because Windows PowerShell - when it constructs the true process command line behind the scenes - blindly encloses such arguments in "...", causing most target programs to interpret the closing \" sequence as an escaped " char.
    (Since arguments without spaces are not subject to this "..." enclosure, they are not affected.)


Workarounds (required in Windows PowerShell only, but should also work in PowerShell 7):

  • Manually add a trailing \ to your argument:

    # Note the '\\'
    python -c "import sys; print(sys.argv)" -imgs ".\Test V4\Rilsa\\" -nl 34
    
  • Alternatively, add a trailing space, relying on the fact that on Windows trailing spaces in paths are usually ignored:

    # Note the trailing space before the closing "
    python -c "import sys; print(sys.argv)" -imgs ".\Test V4\Rilsa " -nl 34
    

In either case, if the path must be passed via a variable rather than a literal and the variable value may or may not end in \, use "...", i.e. an expandable (interpolating) string, such as "$dirPath\" or "$dirPath "

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.