我正在尝试使用Python的Popen来更改我的工作目录并执行命令。
pg = subprocess.Popen("cd c:/mydirectory ; ./runExecutable.exe --help", stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=True)
buff,buffErr = pg.communicate()
然而,powershell返回"系统无法找到指定的路径。"路径确实存在。
如果我跑
pg = subprocess.Popen("cd c:/mydirectory ;", stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=True)
它返回相同的东西。
但是,如果我运行这个:(没有分号)
pg = subprocess.Popen("cd c:/mydirectory",stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=True)
该命令返回时没有错误。这让我相信分号是个问题。造成这种行为的原因是什么?如何解决这个问题?
我知道我可以做c:/mydirectory/runExecutable.exe --help,但我想知道为什么会这样。
更新:
我已经测试过将powershell的路径作为Popen executable
参数的参数传递。仅powershell.exe
可能还不够。要查找powershell
的真实绝对路径,请执行where.exe powershell
。然后你可以将它传递给Popen。请注意shell
仍然是正确的。它将使用默认shell但将命令传递给powershell.exe
powershell = C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
pg = subprocess.Popen("cd c:/mydirectory ; ./runExecutable.exe", stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=True, executable=powershell)
buff,buffErr = pg.communicate()
//It works!
答案 0 :(得分:4)
在subprocess.Popen()
来电中,shell=True
表示应该使用平台的默认 shell。
虽然Windows世界 - 值得称赞 - 从CMD(cmd.exe
)迁移到PowerShell,但 Python根据COMSPEC
环境变量确定要调用的shell,< strong>仍然指向cmd.exe
,即使在最新的W10更新中,就 GUI 提供的默认shell而言,已经转向PowerShell。
为了向后兼容,这不会很快改变,并且可能永远不会改变。
因此,选项是:
根据Maurice Meyer's回答中的建议使用cmd
语法。
不使用shell = True
并明确调用powershell.exe
- 请参阅下文。
仅限Windows :在使用COMSPEC
之前重新定义环境变量shell = True
- 请参阅下文。
一个简单的Python示例,说明如何直接调用powershell
二进制文件,命令行开关后跟一个包含要执行的PowerShell源代码的字符串:
import subprocess
args = 'powershell', '-noprofile', '-command', 'set-location /; $pwd'
subprocess.Popen(args)
请注意,我故意使用powershell
而不是powershell.exe
,因为这样就可以让命令在 Unix 平台上运行,{{3} }被释放。
仅限Windows :在将环境变量shell = True
重新定义为首先指向PowerShell后,使用COMSPEC
的示例:
import os, subprocess
os.environ["COMSPEC"] = 'powershell'
subprocess.Popen('Set-Location /; $pwd', shell=True)
注意:
COMSPEC
仅在 Windows 上查阅;在Unix平台上,shell可执行文件总是 /bin/sh
从Windows PowerShell v5.1 / PowerShell Core v6-beta.3开始,仅使用powershell
(解释为-c
)调用-Command
仍会加载配置文件< em>默认情况下,可能会产生意外的副作用(上面使用powershell
的显式调用,-noprofile
会抑制)。
答案 1 :(得分:0)
您可以使用'&amp;'连接多个命令字符而不是分号。试试这个:
{{1}}