1

I have to use:

x=input()
subprocess.Popen(f'PowerShell -Executionpolicy byPass {x}\n')

To open an executable, but it does not allow me to use a path from the input of an variable that contains backslash or spaces that are not written in the following way:

  • '\\' for backslashes.
  • '\u0020' for spaces.

For C:\Users\Administrator\Desktop\Folder Name\executable.exe it should look like this:

'PowerShell -Executionpolicy byPass C:\\Users\\Administrator\\Desktop\\Folder\u0020Name\\executable.exe'

How could I replace all those spaces and backslashes on the variable for those unicode equivalents? I need the user to be able just to copy and paste the executable's path.

I tried this, but didn't work:

x=input()
x=x.replace('\','\\')
x=x.replace(' ','\u0020')

I'm using Python 3.

martineau
  • 119,623
  • 25
  • 170
  • 301
  • 1
    For a path with a space character in it I would think you would need to enclose it in double quotes. i.e. `'PowerShell -Executionpolicy byPass "C:\\Users\\Administrator\\Desktop\\Folder\u0020Name\\executable.exe"` – martineau Jun 23 '22 at 00:49
  • @martineau, enclosing a script file path containing spaces in double quotes when calling the Windows PowerShell CLI is _necessary_, but not _sufficient_, because - due to the CLI defaulting to `-Command` - those double quotes would be _stripped_ before being interpreted as PowerShell code; hence, preceding the script path with `-File` is required. – mklement0 Jun 23 '22 at 02:30

2 Answers2

2
  • Do not try to use escaping on the Python side: \, when provided as part of a variable value needs no escaping, and neither do spaces.

  • For PowerShell's sake, however, file paths that contain spaces require quoting; when using PowerShell's CLI, double-quoting ("...") is needed.

  • Additionally, you use the -File CLI parameter explicitly in order to execute a script file, because, by default, the -Command parameter is implied in Windows PowerShell, which interprets the following argument(s) as PowerShell source code, after stripping unescaped " from them, which causes script file paths with spaces to break.

    • Note: This applies to Windows PowerShell, but is no longer strictly necessary in PowerShell (Core) 7+, which now defaults to -File rather than -Command.

Therefore:

import subprocess

print('Enter the path of the .ps1 script to execute:')
x=input()
subprocess.Popen(f'PowerShell -Executionpolicy ByPass -File "{x}"').wait()

Note: To avoid unnecessary processing and to ensure a more predictable runtime environment, consider preceding -File with the -NoProfile switch, which suppresses loading of PowerShell's profile files

See also:


As roeland's answer demonstrates, you may alternatively pass the arguments that make up the PowerShell CLI command line individually to subprocess.Popen(), as elements of an array.

While Python then conveniently takes care of double-quoting the elements if necessary on the command line it synthesizes behind the scenes (on Windows), the same rules discussed above apply here too: the script-file path argument must be qualified with -File in order for script paths with spaces to be invoked correctly:

subprocess.Popen(['PowerShell', '-Executionpolicy', 'ByPass', '-File', x]).wait()
mklement0
  • 382,024
  • 64
  • 607
  • 775
0

The easiest way to pass arguments to a subprocess is to pass in the program with arguments as a list:

    subprocess.Popen(['PowerShell', '-Executionpolicy', 'byPass', x])

This assumes x will only contain one single extra argument. If it potentially contains multiple arguments you’ll need to make a decision on how to split it, and how to handle paths with spaces.

roeland
  • 5,349
  • 2
  • 14
  • 28