4

I need to run a command that contains '<' in it.

I can run it from the command line, but it throws error when I put it into mvn exec.

The command:

c:\apps\putty\plink.exe myuser@myhost -T -ssh -2 $SHELL /dev/stdin 'a b c d' < test.sh

test.sh:

#!/bin/bash
echo "execution parameters: $@"

Command line output:

execution parameters: a b c d

pom.xml:

<plugin> 
                <groupId>org.codehaus.mojo</groupId> 
                <artifactId>exec-maven-plugin</artifactId> 
                <version>1.4.0</version> 
                <executions> 
                    <execution>
                        <id>test</id>
                        <phase>pre-integration-test</phase>
                        <goals>
                            <goal>exec</goal>
                        </goals>
                        <configuration><executable>c:\apps\putty\plink.exe</executable>
                            <commandlineArgs>"myuser@myhost -T -ssh -2 $SHELL /dev/stdin 'a b c d' < test.sh"</commandlineArgs>
                        </configuration>
                    </execution>
            </executions> 
        </plugin> 

I tried to change '<' to '&lt;', putting commandlineArgs into CDATA, put doubleqoutes (") everywhere but could not get this to work.

[DEBUG] Executing command line: [c:\apps\putty\plink.exe, > myuser@myhost -T -ssh -2 -pw tomcat  $SHELL /dev/stdin 'a b c d' &lt; test.sh] 
Unable to open connection: Host does not exist[INFO]
------------------------------------------------------------------------ 
[INFO] BUILD FAILURE

or:

[DEBUG] Executing command line: [c:\apps\putty\plink.exe, myuser@myhost, -T, -ssh, -2, -pw, tomcat, $SHELL /dev /stdin 'a b c d' &lt; test.sh] 
bash: test.sh: No such file or directory [INFO]
------------------------------------------------------------------------ 
[INFO] BUILD FAILURE

I'm suspecting the '<' parameter, but I'm not sure what is the real problem.

Any tips?

UPDATE: when I say "I tried to change '<' to '&lt;', putting commandlineArgs into CDATA, put doubleqoutes (") everywhere but could not get this to work." - I mean it!

BTakacs
  • 2,397
  • 3
  • 24
  • 26
  • Tried: <![CDATA[myuser@myhost -T -ssh -2 "$SHELL /dev/stdin 'a b c d' < test.sh"]]> – BTakacs Feb 16 '16 at 11:19
  • Also tried: – BTakacs Feb 16 '16 at 11:20
  • Also tried: <![CDATA["myuser@myhost -T -ssh -2 $SHELL /dev/stdin 'a b c d' < test.sh"]]> – BTakacs Feb 16 '16 at 11:20
  • Just to be on the same page as you: you are trying to execute a command on a remote machine, then use the result of that as command like args for Maven? From this: `"myuser@myhost -T -ssh -2 $SHELL /dev/stdin 'a b c d' < test.sh"` Maven somehow concludes that `myhost -T -ssh -2 $SHELL /dev/stdin 'a b c d' < test.sh` is the host. – Haris Osmanagić Feb 16 '16 at 11:21
  • The issue is not with plink nor with bash since the command line above is working. The question is how should I pass it to mvn exec:exec to make it run the same :-) – BTakacs Feb 16 '16 at 11:37

3 Answers3

1

It's working if I wrap it inside a .bat file:

@echo off
set plinkExec=%1
set env=%2
set user=%3
set pass=%4
set shellPath=%5
...

%plinkExec% %user%@%env% -T -ssh -2 -pw %pass% $SHELL /dev/stdin '...' < %shellPath%

Not nice, but does the magic :-)

BTakacs
  • 2,397
  • 3
  • 24
  • 26
1

There is a difference between a system command and a shell command. Pipes and stream redirections are shell syntax.

A system command typically only launches a program with given parameters, such as

  • notepad.exe myfile.txt
  • java -jar my-program.jar

System commands can be passed to a simple call of an some exec function of various APIs (Java's java.lang.Runtime.getRuntime().exec(), PHP's backticks, etc).

Shell commands then are specific syntax of the shell processing it and Maven has no idea what shell you use.

Typically, shells provide a way to execute their command as a parameter to their executable. So if you want to use a shell command, you need to pass it e.g. like this:

            <configuration>
                <executable>bash</executable>
                <arguments>
                    <argument>-c</argument>
                    <argument>java -jar myprogram.jar < input.txt > output.txt</argument>
                </arguments>
            </configuration>

For Windows that would be

            <configuration>
                <executable>path/to/cmd.exe</executable>
                <arguments>
                    <argument>/C</argument>
                    <argument>java -jar myprogram.jar < input.txt > output.txt</argument>
                </arguments>
            </configuration>

You could use some cross-platform shell, e.g. Groovy.

Hope that helps.

Community
  • 1
  • 1
Ondra Žižka
  • 43,948
  • 41
  • 217
  • 277
  • You missed the plugin's artifact section. Is that a working example using `exec-maven-plugin`? About groovy tip: I've already found that out: if you need to do something complex with maven then: a) you are using the wrong tool b) you can do it with groovy-maven-plugin ;-) – BTakacs Apr 09 '17 at 22:01
  • Yes, that's for the standard exec plugin. I haven't tried this exact code but I recall I used this for both linux and windows. Effectively it turns into: `bash "-c" "java ..."` – Ondra Žižka Apr 10 '17 at 00:46
0

You specifically asked for mvn exec:exec. But assuming you rather need to run a command with redirection, another way is to use a plugin that can handle streams itself, e.g. Maven Ant Plugin. Notice the input="...":

        <plugin>
            <artifactId>maven-antrun-plugin</artifactId>
            <version>1.8</version>
            <executions>
                <execution>
                    <phase>verify</phase>
                    <goals> <goal>run</goal> </goals>
                    <configuration>
                        <target name="run">
                            <exec dir="${work.dir}" executable="java" input="input.txt">
                                <arg value="-jar"/>
                                <arg file="${project.build.directory}/${project.build.finalName}.jar"/>
                            </exec>
                        </target>
                    </configuration>
                </execution>
            </executions>
        </plugin>            
Ondra Žižka
  • 43,948
  • 41
  • 217
  • 277
  • Ok :) Updated - added the phase which is necessary, and an example of how to point to the jar produced by the build. Greetings to Budapest from Brno. – Ondra Žižka Apr 10 '17 at 00:50