Bek*_*aro 5 java shell subprocess maven python-3.x
我正在尝试从 python 脚本运行 Maven 项目。我已经安装了 apache maven。运行命令:mvn exec:java -D"exec.mainClass"="org.matsim.project.RunMatsim"从终端在 pom.xml 所在的项目文件夹中,不会产生错误并且项目运行正常。
但是当从我的 python 脚本运行以下代码时
import subprocess as sp
def execute(cmd):
popen = sp.Popen(cmd, stdout=sp.PIPE, universal_newlines=True,shell=True)
for stdout_line in iter(popen.stdout.readline, ""):
yield stdout_line
popen.stdout.close()
return_code = popen.wait()
if return_code:
raise sp.CalledProcessError(return_code, cmd)
for path in execute(["mvn", "exec:java" ,'-D"exec.mainClass"="org.matsim.project.MatsimRun"']):
print(path, end="")
Run Code Online (Sandbox Code Playgroud)
我收到以下错误:
[错误] 没有为此构建指定目标。您必须以 : 或 :[:]: 格式指定有效的生命周期阶段或目标。可用的生命周期阶段有:验证、初始化、生成源、处理源、生成资源、处理资源、编译、处理类、生成测试源、处理测试源、生成测试资源、处理-test-resources, test-compile, process-test-classes, test, prepare-package, package, pre-integration-test, integration-test, post-integration-test, verify`
为什么会这样?可能有什么问题?
两种情况(终端、python 脚本)发生的警告相同。
通常,当我在从 java/python/etc 运行程序时遇到 args 问题时。我将要使用的命令包装在 中sh -c,如下所示:
sp.Popen(['/bin/sh', '-c', "mvn exec:java -D\"exec.mainClass\"=\"org.matsim.project.MatsimRun\""])
Run Code Online (Sandbox Code Playgroud)
以上似乎对我来说正常工作。请注意这样做可能会带来安全隐患,请确保作为第三个参数输入的命令sh永远不会连接到仇恨互联网。
好的,现在为什么您的代码不起作用?
python文档说这shell=True相当于:
Popen(['/bin/sh', '-c', args[0], args[1], ...])
Run Code Online (Sandbox Code Playgroud)
所以一个好的假设是sh忽略arg[1]和进一步论证。您可以通过执行以下操作来测试:
<censored>@debian:~$ sh -c echo "sfaklg"
<censored>@debian:~$
Run Code Online (Sandbox Code Playgroud)
观察如何echo没有得到它期望的参数。这在许多不同的引用方法/shell 中是一致的:
<censored>@debian:~$ dash -c echo "sfaklg"
<censored>@debian:~$ bash -c echo "sfaklg"
<censored>@debian:~$ zsh -c echo "sfaklg"
<censored>@debian:~$ zsh -c echo sfaklg
<censored>@debian:~$ bash -c echo sfaklg
<censored>@debian:~$
Run Code Online (Sandbox Code Playgroud)
bash 的手册页说:
如果存在 -c 选项,则从第一个非选项参数 command_string 中读取命令。如果 command_string 之后有参数,则第一个参数将分配给 $0,其余参数分配给位置参数。对 $0 的赋值设置了 shell 的名称,该名称用于警告和错误消息。
换句话说sh -c,用于运行期望 args 与$1, $2, ...一起传递的 shell 脚本。
那你该怎么办?
怀疑您想在 shell 中运行 maven,因为它需要设置JAVA_HOME或类似的环境变量。这个问题给出了如何设置/修改环境变量的例子,尽管你可能仍然需要shell=True. 这个答案还建议使用 env 命令来覆盖环境变量。
最后,您可能会发现这个问题很有帮助。
| 归档时间: |
|
| 查看次数: |
536 次 |
| 最近记录: |