如何在路径和参数中使用 space 从 python 执行 powershell 脚本
How to execute powershell script from python with space in the path and parameters
路径示例:C:\Users\user\Some Space\dev\sensor\
def readSensorList():
with open('sensor.json') as json_data:
data = json.load(json_data)
json_data.close()
return data
def executeSensor():
sensorList = list()
sensorListRaw = readSensorList()
for sensor in sensorListRaw['sensors']:
x = [subprocess.Popen(['powershell.exe','-ExecutionPolicy', 'Unrestricted', sensorListRaw["path"] + sensor["filename"], "-name", sensor["name"]], stdout=subprocess.PIPE, stderr=subprocess.PIPE), sensor["name"]]
sensorList.append(x)
return sensorList
Json 包含路径:
{
"path": "C:\Users\\sensor\",
"sensors":
[{
"name": "partition",
"filename": "partition.ps1"
}]
}
在我的测试环境中,路径中没有space,但是现在,在生产中,我的路径中有一些space,我对如何执行powershell一无所知来自 python 的脚本,带有 space 和参数
我尝试引用路径,但没有成功。
编辑:我确定问题出在 powershell.exe 命令而不是 python,因为:
powershell.exe -ExecutionPolicy 'Unrestricted C:\Users\some space\Desktop\PythonSensor\sensor\sensor.ps1'
不要在 CMD 中工作。
问题不仅在于 Python,而且在于 Windows。在内部类 Unix 系统使用 execve
系统调用,该系统调用将可执行文件(路径)和将传递给命令的参数作为参数。
在Windows中,系统API有一个函数CreateProcess
,它将可执行文件的路径和整个命令行作为一个字符串作为参数。然后由子进程解析命令行以找到其参数
Python 尽力遵循 Windows 内部用法来构建将按预期解析的命令行,但一旦一个参数包含双引号 ("
).
例如,如果 foo.bat
是一个带 3 个参数的批处理脚本,这将是正确的:
proc = subprocess.Popen(('foo.bat', 'a', 'b c', 'd'),
stdout= subprocess.PIPE, stderr=subprocess.PIPE)
foo 将接收 3 个参数,a
、b c
和 d
。
但是如果你使用:
proc = subprocess.Popen(('foo.bat', '"a"', '"b c"', '"d"'),
stdout= subprocess.PIPE, stderr=subprocess.PIPE)
foo 将收到 4 个参数:"a"
、"b
、c"
和 "d"
.
TL/DR:必须确保包含参数的字符串包含space是而不是包含在"
[=中24=]
我终于发现,你必须像这样把'放在space之间:
powershell -command "C:\Users\me\Desktop\test\ps' 'test.ps1"
在python中:
subprocess.Popen(['powershell','-ExecutionPolicy', 'Unrestricted', '-command', path]
路径为:
C:\Users\me\Desktop\some' 'space\sensor\
没有 " 正如 Serge Ballesta 解释的那样。
虽然进程parameters/arguments在Windows上的处理确实有些不一致,但在本例中这不是问题所在。 Pythons submodule.Popen
正确处理了这个问题(基于 these rules). (Serge Ballestas example of calling .bat
files does not really fit, because .bat
files are executed by cmd.exe
and cmd.exe
is almost the only application these days that doesn't follow these rules。)
这种情况下的问题是 -Command
:
的用法
当使用 -Command
参数调用 PowerShell 时,所有后续参数都将连接到单个命令(如 $args -join " "
)。然后执行此命令。
-Command
是默认参数:如果参数不是以 -
或 /
开头,powershell 的行为就好像 -Command
之前存在一样。
这个:
subprocess.Popen(['powershell.exe', r'C:\Users\user\Some Space\dev\sensor\partition.ps1', "-name", "partition"])
因此等同于交互式 powershell 会话中的此命令:
C:\Users\user\Some Space\dev\sensor\partition.ps1 -name partition
如果您用引号将每个 space 括起来(如您自己的回答中所述),则生成的 powershell 命令为:
C:\Users\user\Some' 'Space\dev\sensor\partition.ps1 -name partition
这是允许的并且有效 - 但如果您的路径包含其他特殊字符,如 $
或 `
,它将再次中断。如果
脚本参数包含 space 或其他特殊字符。
tl;博士:
要从 powershell 外部正确调用 powershell 脚本,请使用 -File
参数:
subprocess.Popen(['powershell.exe','-ExecutionPolicy', 'Unrestricted', '-File', sensorListRaw["path"] + sensor["filename"], "-name:", sensor["name"]])
-File
后面的参数是脚本名(没有任何额外奇怪的转义),后面的参数都是脚本的参数。
请注意附加到参数名称的 :
(-name:
而不是 -name
)- 在大多数情况下它也可以在没有 :
的情况下工作,但是如果相应的值以破折号开头,没有 :
.
将失败
路径示例:C:\Users\user\Some Space\dev\sensor\
def readSensorList():
with open('sensor.json') as json_data:
data = json.load(json_data)
json_data.close()
return data
def executeSensor():
sensorList = list()
sensorListRaw = readSensorList()
for sensor in sensorListRaw['sensors']:
x = [subprocess.Popen(['powershell.exe','-ExecutionPolicy', 'Unrestricted', sensorListRaw["path"] + sensor["filename"], "-name", sensor["name"]], stdout=subprocess.PIPE, stderr=subprocess.PIPE), sensor["name"]]
sensorList.append(x)
return sensorList
Json 包含路径:
{
"path": "C:\Users\\sensor\",
"sensors":
[{
"name": "partition",
"filename": "partition.ps1"
}]
}
在我的测试环境中,路径中没有space,但是现在,在生产中,我的路径中有一些space,我对如何执行powershell一无所知来自 python 的脚本,带有 space 和参数
我尝试引用路径,但没有成功。
编辑:我确定问题出在 powershell.exe 命令而不是 python,因为:
powershell.exe -ExecutionPolicy 'Unrestricted C:\Users\some space\Desktop\PythonSensor\sensor\sensor.ps1'
不要在 CMD 中工作。
问题不仅在于 Python,而且在于 Windows。在内部类 Unix 系统使用 execve
系统调用,该系统调用将可执行文件(路径)和将传递给命令的参数作为参数。
在Windows中,系统API有一个函数CreateProcess
,它将可执行文件的路径和整个命令行作为一个字符串作为参数。然后由子进程解析命令行以找到其参数
Python 尽力遵循 Windows 内部用法来构建将按预期解析的命令行,但一旦一个参数包含双引号 ("
).
例如,如果 foo.bat
是一个带 3 个参数的批处理脚本,这将是正确的:
proc = subprocess.Popen(('foo.bat', 'a', 'b c', 'd'),
stdout= subprocess.PIPE, stderr=subprocess.PIPE)
foo 将接收 3 个参数,a
、b c
和 d
。
但是如果你使用:
proc = subprocess.Popen(('foo.bat', '"a"', '"b c"', '"d"'),
stdout= subprocess.PIPE, stderr=subprocess.PIPE)
foo 将收到 4 个参数:"a"
、"b
、c"
和 "d"
.
TL/DR:必须确保包含参数的字符串包含space是而不是包含在"
[=中24=]
我终于发现,你必须像这样把'放在space之间:
powershell -command "C:\Users\me\Desktop\test\ps' 'test.ps1"
在python中:
subprocess.Popen(['powershell','-ExecutionPolicy', 'Unrestricted', '-command', path]
路径为:
C:\Users\me\Desktop\some' 'space\sensor\
没有 " 正如 Serge Ballesta 解释的那样。
虽然进程parameters/arguments在Windows上的处理确实有些不一致,但在本例中这不是问题所在。 Pythons submodule.Popen
正确处理了这个问题(基于 these rules). (Serge Ballestas example of calling .bat
files does not really fit, because .bat
files are executed by cmd.exe
and cmd.exe
is almost the only application these days that doesn't follow these rules。)
这种情况下的问题是 -Command
:
当使用 -Command
参数调用 PowerShell 时,所有后续参数都将连接到单个命令(如 $args -join " "
)。然后执行此命令。
-Command
是默认参数:如果参数不是以 -
或 /
开头,powershell 的行为就好像 -Command
之前存在一样。
这个:
subprocess.Popen(['powershell.exe', r'C:\Users\user\Some Space\dev\sensor\partition.ps1', "-name", "partition"])
因此等同于交互式 powershell 会话中的此命令:
C:\Users\user\Some Space\dev\sensor\partition.ps1 -name partition
如果您用引号将每个 space 括起来(如您自己的回答中所述),则生成的 powershell 命令为:
C:\Users\user\Some' 'Space\dev\sensor\partition.ps1 -name partition
这是允许的并且有效 - 但如果您的路径包含其他特殊字符,如 $
或 `
,它将再次中断。如果
脚本参数包含 space 或其他特殊字符。
tl;博士:
要从 powershell 外部正确调用 powershell 脚本,请使用 -File
参数:
subprocess.Popen(['powershell.exe','-ExecutionPolicy', 'Unrestricted', '-File', sensorListRaw["path"] + sensor["filename"], "-name:", sensor["name"]])
-File
后面的参数是脚本名(没有任何额外奇怪的转义),后面的参数都是脚本的参数。
请注意附加到参数名称的 :
(-name:
而不是 -name
)- 在大多数情况下它也可以在没有 :
的情况下工作,但是如果相应的值以破折号开头,没有 :
.