java之Maven 命令 mvn 从终端运行没有错误,但从 python 没有错误

落叶无声 阅读:16 2024-11-24 20:56:43 评论:0

我正在尝试从 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="") 

我收到以下错误:

[错误] 没有为此构建指定目标。您必须以 : 或 :[:]: 格式指定有效的生命周期阶段或目标。可用的生命周期阶段有:验证、初始化、生成源、处理源、生成资源、处理资源、编译、处理类、生成测试源、处理测试源、生成测试资源、处理-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\""]) 

以上似乎对我来说正常工作。请注意,这样做可能会带来安全隐患,请确保输入的命令是 sh 的第三个参数。永远不会连接到仇恨的互联网。

好的,现在为什么您的代码不起作用?

python docsshell=True相当于:
Popen(['/bin/sh', '-c', args[0], args[1], ...]) 

所以一个好的假设是 sh无视 arg[1]和进一步的论据。
您可以通过执行以下操作来测试:
<censored>@debian:~$ sh -c echo "sfaklg" 
 
<censored>@debian:~$  

观察如何 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:~$  
 

bash 的手册页说:

If the -c option is present, then commands are read from the first non-option argument command_string. If there are arguments after the command_string, the first argument is assigned to $0 and any remaining arguments are assigned to the positional parameters. The assignment to $0 sets the name of the shell, which is used in warning and error messages.



换句话说 sh -c用于运行希望通过 $1 传递参数的 shell 脚本, $2 , ... .

那你该怎么办?

怀疑您想在 shell 中运行 maven,因为它需要 JAVA_HOME或要设置的类似环境变量。此 question给出了如何设置/修改环境变量的示例,尽管您可能仍然需要 shell=True .此 answer还建议使用 env 命令覆盖环境变量。

最后你会发现这个 question有帮助。


标签:Maven
声明

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

关注我们

一个IT知识分享的公众号