我正试图用Ant实现以下目标。我有一个属性文件,其中有令牌及其值的列表。这个文件被传递给Ant,它工作得很好,可以完成所有正常的字符串替换。
<copy todir="${target_direcotry}" overwrite="true">
<fileset dir="config">
<include name="*.change_me"/>
</fileset>
<filterset begintoken="<" endtoken=">">
<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脚本吗?如何实现?
从技术上讲,使用FilterChain和FilterReader(特别是这个:ScriptFilter)使用Ant可以实现这一点。然而,这并不是微不足道的,而且可能存在一些可移植性问题。您可以考虑编写自己的任务(或特定的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>