3

I have a very similar situation as in the the outofdate example (see gengrammer, http://ant-contrib.sourceforge.net/tasks/tasks/outofdate.html): I have a folder with *.class and *.seq files that should be converted to *.pdf with the help of plantuml (a java program).

This is my current task:

<property name="diagram.path" value="../graphics/plantuml/src"/>

...

<target name="diagram-files" depends="update-classpath">
    <outofdate property="manual.outofdate" outputsources="diagram.sources">
        <sourcefiles>
            <fileset dir="${diagram.path}" includes="*.class"/>
            <fileset dir="${diagram.path}" includes="*.seq"/>
        </sourcefiles>
        <mapper type="glob" dir="${diagram.path}" from="*.class" to="graphics/*.pdf"/>
        <mapper type="glob" dir="${diagram.path}" from="*.seq" to="graphics/*.pdf"/>
        <sequential>
            <shellscript shell="bash">
                cd ${diagram.path}
                echo ${diagram.sources}
                #for diagram in ${diagram.sources}
                #do
                # java -jar plantuml ... $diagram
                #done
            </shellscript>
        </sequential>
    </outofdate>
</target>

I can't get this to run because inside ${diagram.sources} all (back)slashes were stripped off. So echoing this variable gives me something like this:

C:UsersMYUSERpath-to-folderANDsoONmyfile.class
C:UsersMYUSERpath-to-folderANDsoONmyfile2.class

Don't know if I made something wrong or this is a feature. Any help would be great!

btw. I'm on Windows 10, but ant is running inside a cygwin shell. I never had problems with this combination.

4

1 回答 1

1

尚不清楚反斜杠是否outofdate在执行到达您的 bash 脚本之前被 Ant 任务剥离,或者是否反斜杠进入脚本并且您看到了 shell 转义的影响。

如果是后者,那么您可以通过${diagram.sources}用引号括起来来解决问题,以便 shell 将其解释为字符串文字而不会转义。例如:

构建.xml

<project>
    <taskdef resource="net/sf/antcontrib/antcontrib.properties">
        <classpath>
            <pathelement location="/Users/naurc001/ant-contrib-0.6-bin/lib/ant-contrib-0.6.jar"/>
        </classpath>
    </taskdef>
    <property name="diagram.path" value="../graphics/plantuml/src"/>
    <property name="diagram.sources.property" value="C:\private\tmp\anttest\graphics\plantuml\src\myfile.class C:\private\tmp\anttest\graphics\plantuml\src\myfile2.class" />
    <target name="diagram-files">
        <outofdate property="manual.outofdate" outputsources="diagram.sources">
            <sourcefiles>
                <fileset dir="${diagram.path}" includes="*.class"/>
                <fileset dir="${diagram.path}" includes="*.seq"/>
            </sourcefiles>
            <mapper type="glob" dir="${diagram.path}" from="*.class" to="graphics/*.pdf"/>
            <mapper type="glob" dir="${diagram.path}" from="*.seq" to="graphics/*.pdf"/>
            <sequential>
                <shellscript shell="bash">
                    echo Unquoted: ${diagram.sources.property}
                    echo Quoted: '${diagram.sources.property}'
                    for diagram in $(echo '${diagram.sources.property}')
                    do
                        # I don't have plantuml, so just stubbing it to print the command.
                        echo java -jar plantuml ... $diagram
                    done
                </shellscript>
            </sequential>
        </outofdate>
    </target>
</project>

输出

> ant diagram-files
Buildfile: /private/tmp/anttest/proj/build.xml

diagram-files:
[shellscript] Unquoted: 
C:privatetmpanttestgraphicsplantumlsrcmyfile.class 
C:privatetmpanttestgraphicsplantumlsrcmyfile2.class
[shellscript] Quoted: 
C:\private\tmp\anttest\graphics\plantuml\src\myfile.class 
C:\private\tmp\anttest\graphics\plantuml\src\myfile2.class
[shellscript] java -jar plantuml ... 
/private/tmp/anttest/graphics/plantuml/src/myfile.class
[shellscript] java -jar plantuml ... 
/private/tmp/anttest/graphics/plantuml/src/myfile2.class

BUILD SUCCESSFUL
Total time: 0 seconds

解释

我无法访问 Windows 机器以在该平台上进行直接测试,因此我通过硬编码diagram.sources.property来模拟问题,以便在路径中使用 Windows 样式的反斜杠。两次回显相同的<shellscript>属性:一次不带单引号,一次带单引号。对于未引用的表单,由于 shell 转义,输出看起来像您所描述的。引用它之后,我们得到了预期的结果。

但是,如果我们只是传递'{diagram.sources.property}'给其他命令,例如jar ...,那么我们会产生意想不到的副作用。Bash 会将整个列表作为单个参数传递。为了解决这个问题,我们可以把整个东西包装起来$(echo ...),把它变成多个参数。测试输出证明我们jar为每个文件调用了一次命令。

根据您需要运行的工具,有时需要将 Windows 样式的反斜杠路径分隔符转换为 Unix 样式的正斜杠。如果需要,我建议使用cygpathbash 脚本中的实用程序将反斜杠转换为斜杠。特别是,-u-w选项在这里很有帮助。

-u 和 -w 选项指示您是希望转换为 UNIX (POSIX) 格式 (-u) 还是 Windows 格式 (-w)。使用 -d 获取 DOS 样式 (8.3) 文件和路径名。-m 选项将输出 Windows 样式的格式,但使用正斜杠而不是反斜杠。此选项在使用反斜杠作为转义字符的 shell 脚本中特别有用。

您提到您正在使用 Cygwin,但也许您也有在 Mac 或直接 Linux 上运行的队友,您需要与他们进行互操作。如果是这样,那么您可以保护对cygpath内部的调用以检查uname -a. 在 Cygwin shell 中, 的输出uname -a将包含某种形式的“Cygwin”。

关于 bash 转义的其他参考:

于 2017-07-21T18:19:32.320 回答