如何将属性转换为<exec> task </exec>的多个参数

时间:2012-02-01 17:43:39

标签: ant

我有一个包含多个值的属性,我想为属性中的每个值执行一个带有单独“-j”参数的命令。

E.g。 <property name="arguments" value="foo bar hello world"/>

应该执行:mycommand -j foo -j bar -j hello -j world

我正在使用Ant 1.7.1,因此我无法在<arg>任务的<exec>元素上使用“prefix”属性(Ant 1.8)。

一种解决方法是手动将“-j”直接插入属性,然后使用<arg>的“line”属性:

<property name="args" value="-j foo -j bar -j hello -j world"/>
<exec executable="mycommand">
    <arg line="${args}"/>
</exec>

...但我更喜欢将属性设置为没有嵌入参数的简单列表。

编辑:实际上,我的参数是XML文件中的路径,因此更准确的参数列表将是:

<property name="arguments" value="/foo/bar /hello/world /a/very/long/path"/>

我希望命令然后用参数执行:“ - j / foo / bar -j / hello / world -j / a / very / long / path”。请注意,即使在Windows下,斜杠仍然是正斜杠(这些是命令的参数,而不是文件名)。

3 个答案:

答案 0 :(得分:3)

您可以使用Ant资源工具。

<property name="arg_list" value="foo bar hello world"/>    
<resources id="arguments">
  <mappedresources>
    <string value="${arg_list}" />
    <filtermapper>
      <replacestring from=" " to=" -j "/>
    </filtermapper>
  </mappedresources>
</resources>
<property name="arguments" value="-j ${toString:arguments}" />

上述操作会导致属性arguments的值为-j foo -j bar -j hello -j world,然后可以在exec arg行中使用。

或者,pathconvert task可以在这方面提供帮助:

<property name="arg_list" value="foo bar hello world"/>    
<pathconvert property="arguments" pathsep=" ">
  <chainedmapper>
    <flattenmapper />
    <regexpmapper from="(.*)" to="-j \1" />
  </chainedmapper>
  <filelist files="${arg_list}" />
</pathconvert>

如果你有绝对路径,而不只是列表中的字符串,那么删除flattenmapper

如果您有相对路径,请将flattenmapper行替换为:

<globmapper from="${basedir}/*" to="*" />

以防止路径转换为绝对路径。

如果Windows系统上的arg_list中有类UNIX路径,则pathconvert的默认设置将不起作用 - 路径将转换为Windows样式。相反,要处理列表使用:

<pathconvert property="arguments" pathsep=" " targetos="unix">
  <chainedmapper>
    <regexpmapper from="C:(.*)" to="-j \1" />
  </chainedmapper>
  <filelist files="${arg_list}" />
</pathconvert>

请注意targetos设置和参数中修订的regexmapper。

答案 1 :(得分:0)

使用一些for循环,这是基于Ant Addon Flaka的解决方案:

<project name="demo" xmlns:fl="antlib:it.haefelinger.flaka">

 <!-- make standard ant tasks like i.e. exec understand EL expressions -->
 <fl:install-property-handler/>

 <property name="arguments" value="foo bar hello world"/>

 <fl:for var="arg" in="split('${arguments}',' ')">
  <exec executable="mycommand">
   <arg line="#{arg} -j"/>
  </exec>
 </fl:for>

</project>

答案 2 :(得分:0)

不确定您对脚本语言的熟悉程度,但您也可以嵌入脚本来进行解析/重组:

http://ant.apache.org/manual/Tasks/script.html

我会说,我认为它有点脆弱,因为你明确提到了ANT项目的名称,但由你决定:

<?xml version="1.0" encoding="utf-8"?>
<project name="ScriptProj" basedir=".">

    <property name="arguments" value="foo bar hello world"/>

    <target name="test">

        <script language="javascript">
            <![CDATA[

                argsParm = ScriptProj.getProperty("arguments");
                argsParmAmend = "";
                args = argsParm.split(" ");

                for (i = 0; i < args.length; i++)
                    argsParmAmend = argsParmAmend + "-j " + args[i] + " ";

                // remove trailing string
                ScriptProj.setProperty("arguments.amended", argsParmAmend.substr(0, argsParmAmend.length-1));
            ]]>
        </script>

        <echo>${arguments}</echo>
        <echo>${arguments.amended}</echo>

    </target>

</project>