如何在搜索和替换时在Ant中运行shell脚本?

时间:2016-07-27 18:29:47

标签: ant ant-contrib

我正在尝试使用Ant实现以下功能。 我有一个属性文件,其中包含令牌列表及其值。 这个文件传递给Ant,它运行良好,并且可以完成所有正常的字符串替换。

            <copy todir="${target_direcotry}" overwrite="true">
                    <fileset dir="config">
                            <include name="*.change_me"/>
                    </fileset>
                    <filterset begintoken="&lt;" endtoken="&gt;">
                            <filtersfile file="${property_file}"/>
                    </filterset>
                    <mapper type="glob" from="*.change_me" to="*"/>
            </copy>

现在如果我有一个令牌 - 值对,如下所示: 属性文件中的 TOKEN_VALUE1 =`./ run_me.ksh`

目标文件test.xml.change_me包含以下内容: 您有<TOKEN_VALUE1>个条目!!!

使用build.xml中的上述代码和属性文件中的这个新标记,我在运行ant后得到test.xml的内容是: 你有`./ run_me.ksh`条目!!!

脚本run_me.ksh的输出将决定此标记的值,并按如下方式给出输出:

场景1:

Run_me.ksh输出:10

执行后文件test.xml的必需内容: “你有10个参赛作品!!!”

场景1:

Run_me.ksh输出:20

执行后文件test.xml的必需内容: “你有20个参赛作品!!!”

我可以使用Ant函数/命令在替换期间运行这样的shell脚本吗?

1 个答案:

答案 0 :(得分:0)

在技术上可以使用FilterChain and FilterReader(特别是这一个:ScriptFilter)来实现这一点。然而,这不是那么微不足道,可能会有一些可移植性问题。您可以考虑编写自己的任务(或特定的FilterReader),或者只是定义执行shell脚本的目标并将其结果存储在属性中,并将该属性用作代码替换的值。

此后是如何在令牌替换任务中启动脚本的片段:

<copy todir="${target.dir}" overwrite="true">
    <fileset dir="${config.dir}">
        <include name="*.change_me" />
    </fileset>
    <filterchain>
        <!-- replace token with value in the property file (i.e. `run_me.sh`) -->
        <filterreader classname="org.apache.tools.ant.filters.ReplaceTokens">
            <param type="propertiesfile" value="${token.properties}" />
        </filterreader>
        <tokenfilter>
            <!-- split result along a specific pattern ('`' character for instance). -->
            <stringtokenizer delims="`" delimsaretokens="false" />
            <!-- apply a script filter to execute shell if token is script name -->
            <scriptfilter language="javascript">
                <![CDATA[
                if( self.getToken().indexOf(".sh") != -1 ){
                    <!-- rely on ant Exec task to run script -->
                    exectask = project.createTask("exec");
                    exectask.setExecutable("sh");
                    exectask.createArg().setValue(self.getToken());
                    <!-- store output in an ant property : -->
                    exectask.setOutputproperty("result");
                    exectask.perform();
                    <!-- retrieve the ant property and use it to replace current token -->
                    self.setToken(project.getProperty("result"));
                }
                ]]>
            </scriptfilter>
        </tokenfilter>
    </filterchain>
    <mapper type="glob" from="*.change_me" to="*" />
</copy>