在Windows上使用exec-maven-plugin执行shell脚本

问题描述 投票:0回答:4

我有一个 pom,它使用 exec-maven-plugin 来执行带有三个参数的 shell 脚本。 运行

mvn clean install -X -e
时,它在该步骤失败并出现错误,

[DEBUG] Toolchains are ignored, 'executable' parameter is set to C:\dev\intellij\projects\project-in-question\driver/src/main/scripts/dependencies.sh
[DEBUG] Executing command line: [C:\dev\intellij\projects\project-in-question\driver\src\main\scripts\dependencies.sh, C:\dev\intellij\projects\project-in-question\driver\target/project-in-question.dependencies, C:\dev\intellij\projects\project-in-question\driver\target, third-parameter]  

[ERROR] Failed to execute goal org.codehaus.mojo:exec-maven-plugin:1.3.2:exec (dependencies) on project project-in-question: Command execution failed.: Cannot run program "C:\dev\intellij\projects\project-in-question\driver\src\main\scripts\dependencies.sh" (in directory "C:\dev\intellij\projects\project-in-question\driver"): CreateProcess error=193, %1 is not a valid Win32 application -> [Help 1]
org.apache.maven.lifecycle.LifecycleExecutionException: Failed to execute goal org.codehaus.mojo:exec-maven-plugin:1.3.2:exec (dependencies) on project project-in-question: Command execution failed.

pom.xml 的相关部分:

        ...
        <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>exec-maven-plugin</artifactId>
            <version>1.3.2</version>
            <executions>
                <execution>
                   ...
                </execution>
                <execution>
                    <id>dependencies</id>
                    <phase>compile</phase>
                    <goals>
                        <goal>exec</goal>
                    </goals>
                    <configuration>
                        <workingDirectory>${project.basedir}</workingDirectory>
                        <executable>${project.basedir}/src/main/scripts/dependencies.sh</executable>
                        <arguments>
                            <argument>${project.build.directory}/${project.artifactId}.dependencies</argument>
                            <argument>${project.build.directory}</argument>
                            <argument>project-in-question</argument>
                        </arguments>
                    </configuration>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

我觉得这可能与操作系统有关,我(唯一的)在 Windows 10 x64 上运行,其他人在 Mac 上运行。 如果我在 Cygwin 中运行此命令,它会成功完成,并使用正确的参数执行 shell 脚本。 即使使用cmd.exe,我也可以执行这个脚本。

但是使用Maven构建项目,每次都会失败。 我什至清空了 shell 脚本,因此它实际上由以下内容组成:

#!/bin/sh
echo "hello world"

虽然真实的原始 shell 脚本确实采用三个参数,但我收到了完全相同的错误消息,即 %1 不是有效的 Win32 应用程序,并且该脚本不采用任何参数,也不尝试引用任何参数;它只是回响“你好世界。”

我确实注意到各个参数中的斜线是混合的,我不确定这是罪魁祸首;它似乎更多地与尝试从 Maven 在 Windows 上执行 shell 脚本有关。

任何人都可以帮我解决这个问题并解释发生了什么事吗? 如果需要任何其他详细信息,请告诉我,我将提供更多背景信息。

java windows shell maven exec-maven-plugin
4个回答
9
投票

您的命令行是*:

[dependencies.sh, project-in-question.dependencies, target, third-parameter]

但在 Windows 上,

dependencies.sh
不是可执行文件。 要使用 cygwin 运行它,您必须像这样运行它*:

[c:\cygwin\bin\run.exe, dependencies.sh, project-in-question.dependencies, target, third-parameter]

现在我猜,其他人不会乐意将 pom.xml 更改为那样。


一种可能的解决方案应该是安装“Windows Subsystem For Linux”。


另一个解决方案是创建一个dependency.sh.bat,其中包含以下内容:

c:\cygwin\bin\run.exe dependencies.sh %*

但是使用此解决方案,您可能必须重命名计算机上的dependency.sh,以便Windows首先选择.bat文件。


另一个折衷方案可能是将执行更改为

<executable>sh</executable>
  <arguments>
    <argument>-c</argument>
    <argument>${project.basedir}/src/main/scripts/dependencies.sh ${project.build.directory}/${project.artifactId}.dependencies ${project.build.directory} project-in-question</argument>

在您的系统上,

PATH
中有一个 sh.bat,其中包含:

c:\cygwin\bin\run.exe sh %*

*为了更好的可读性,我省略了文件夹


4
投票

尝试使用

cmd
作为可执行文件,然后使用
/C
作为第一个参数,使用 shell 脚本的路径名作为下一个参数,然后使用其余参数:

            <executable>cmd</executable>
            <arguments>
                <argument>/C</argument>
                <argument>${project.basedir}/src/main/scripts/dependencies.sh</argument>

2
投票

我会将

cygwin\bin
路径添加到 Windows
%PATH%
环境变量,因为 Cygwin 提供了
bash.exe
可执行文件。然后修改 .pom 使其与平台无关:

           ...
                    <execution>
                        <id>dependencies</id>
                        <phase>compile</phase>
                        <goals>
                            <goal>exec</goal>
                        </goals>
                        <configuration>
                            <workingDirectory>${project.basedir}</workingDirectory>
                            <executable>bash</executable>
                            <arguments>
                                <argument>${project.basedir}/src/main/scripts/dependencies.sh</argument>
                                <argument>${project.build.directory}/${project.artifactId}.dependencies</argument>
                                <argument>${project.build.directory}</argument>
                                <argument>project-in-question</argument>
                            </arguments>
                        </configuration>
                    </execution>
           ...

正如 @Samuel Kirschner 上面指出的,您还可以使用 Windows Subsystem for Linux (WSL) 而不是 Cygwin,它会自动在 Windows %PATH% 上提供

bash
可执行文件,并与给定的 .pom 配置一起使用


0
投票

对于 2024 年以上使用 git-bash 执行脚本时遇到问题的人。
这可能是由于运行

wsl2
命令时执行的是
bash
而不是 git bash。

Wsl2也不会继承父级的环境变量,这可能会导致shell脚本在执行时中断。

这是一个简单的解决方案。

<profile>
    <id>os-windows</id>
    <activation>
        <os>
            <family>windows</family>
        </os>
    </activation>
    <properties>
        <!-- Workaround bash command executing wsl2 instead of git-bash -->
        <bash.path>C:\Program Files\Git\bin\bash.exe</bash.path>
    </properties>
</profile>
<profile>
    <id>os-unix</id>
    <activation>
        <os>
            <family>unix</family>
        </os>
    </activation>
    <properties>
        <!-- Running maven from wsl2 fall in unix family, which is fine -->
        <bash.path>bash</bash.path>
    </properties>
</profile>

然后执行插件时只需指定路径即可

<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>exec-maven-plugin</artifactId>
    <executions>
        <execution>
            <id>example</id>
            <phase>install</phase>
            <goals>
                <goal>exec</goal>
            </goals>
            <configuration>
                <arguments>
                    <argument>--verbose</argument>
                </arguments>
                <environmentVariables>
                    <EXAMPLE_VAR>value</EXAMPLE_VAR>
                </environmentVariables>
            </configuration>
        </execution>
    </executions>
    <configuration>
        <executable>${bash.path}</executable>
        <commandlineArgs>-c ../example.sh</commandlineArgs>
        <environmentVariables>
            <VAR_ONE>Hello world</VAR_ONE>
            <VAR_TWO>example</VAR_TWO>
        </environmentVariables>
    </configuration>
</plugin>

© www.soinside.com 2019 - 2024. All rights reserved.