Maven命令mvn可以从终端运行但不会从python错误运行

时间:2020-03-21 14:29:15

标签: java python-3.x shell maven subprocess

我正在尝试从python脚本运行Maven项目。我已经安装了Apache Maven。 从pom.xml所在的项目文件夹中的终端运行命令:mvn exec:java -D"exec.mainClass"="org.matsim.project.RunMatsim",不会产生任何错误,并且项目可以正常运行。

但是从我的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脚本)发生的警告都是相同的。

4 个答案:

答案 0 :(得分:4)

通常,当我从java / python / etc运行程序时遇到args问题时。我将要使用的命令包装在[Pdo_mysql] pdo_mysql.default_socket=/var/run/mysqld/mysqld.sock [MySQLi] mysqli.default_socket = /var/run/mysqld/mysqld.sock 中,如下所示:

sh -c

以上内容似乎对我来说正常。请注意,这样做可能会带来安全隐患,请确保作为sp.Popen(['/bin/sh', '-c', "mvn exec:java -D\"exec.mainClass\"=\"org.matsim.project.MatsimRun\""]) 的第三个参数输入的命令永远不会挂接到仇恨互联网上。

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

python docssh等效于:

shell=True

因此,一个很好的假设是Popen(['/bin/sh', '-c', args[0], args[1], ...]) 忽略了sh和其他参数。 您可以通过以下方法进行测试:

arg[1]

观察<censored>@debian:~$ sh -c echo "sfaklg" <censored>@debian:~$ 如何无法获得期望的参数。这在许多不同的引用方法/ shell中是一致的:

echo

bash的手册页上说:

如果存在-c选项,那么将从第一个非选项参数command_string中读取命令。如果在command_string之后有参数,则第一个参数分配给$ 0,其余所有参数分配给位置参数。分配给$ 0设置外壳的名称,该名称用于警告和错误消息。

换句话说,<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:~$ 适用于运行shell脚本,这些脚本期望args与sh -c$1,...一起传递。

那你该怎么办?

怀疑您要在Shell中运行Maven,因为它需要设置$2或类似的环境变量。尽管您可能仍需要JAVA_HOME,但此question提供了有关如何设置/修改环境变量的示例。此answer还建议使用env命令覆盖环境变量。

最后,您可能会发现此question有用。

答案 1 :(得分:0)

尝试删除exec.mainClass周围的双引号,即:

mvn exec:java -Dexec.mainClass="org.matsim.project.MatsimRun"

代替:

mvn exec:java -D"exec.mainClass"="org.matsim.project.MatsimRun"

答案 2 :(得分:0)

只需更改下面的行

["mvn", "exec:java" ,'-D"exec.mainClass"="org.matsim.project.MatsimRun"']

使用

["mvn", "exec:java" ,"-D\"exec.mainClass\"=\"org.matsim.project.MatsimRun\""]

答案 3 :(得分:0)

我个人认为,在不同编程环境中进行编程的程序员面临的最大问题之一是使用双引号("")和单引号(''),这会引起像您这样的烦人的问题。

要进行处理,可以使用插件,而不使用maven的内置命令。将以下插件添加到您的pom.xml文件中,然后轻松执行您的应用程序。

<plugin>
  <groupId>org.codehaus.mojo</groupId>
  <artifactId>exec-maven-plugin</artifactId>
  <version>1.4.0</version>
  <configuration>
    <mainClass>org.matsim.project.MatsimRun</mainClass>
  </configuration>
</plugin>

在上述插件中,假定您的Main类为org.matsim.project.MatsimRun。要从命令行触发插件,只需运行:

mvn exec:java

我希望这会有所帮助!