【问题标题】:How do I use the Ant exec task to run piped commands?如何使用 Ant exec 任务运行管道命令?
【发布时间】:2011-04-25 07:13:29
【问题描述】:

我正在尝试使用 Ant 中的 'exec' 任务运行以下命令:

ls -l /foo/bar | wc -l

目前,我的高管看起来像这样:

<exec executable="ls" outputproperty="noOfFiles">
    <arg value="-l" />
    <arg value="/foo/bar" />
    <arg value="|" />
    <arg value="wc" />
    <arg value="-l" />
</exec>

“ls”命令看起来正在工作,但很难将输出通过管道传输到“wc”。有什么建议吗?

【问题讨论】:

  • 看起来值得编写一个简单的 ant 任务来完成此任务,而不是使用 exec。
  • 已经有这样一个任务,叫resourcecount

标签: shell ant pipe


【解决方案1】:

您需要有人来识别和建造管道。试试sh

<exec executable="sh" outputproperty="noOfFiles">
    <arg value="-c" />
    <arg value="ls" />
    <arg value="-l" />
    <arg value="/foo/bar" />
    <arg value="|" />
    <arg value="wc" />
    <arg value="-l" />
</exec>

【讨论】:

  • 嗨亚伦 - 它几乎工作了!它似乎忽略了 /foo/bar 目录,只计算你在 bash 上的当前目录中的文件数量。
  • 试试/bin/ls -1(一个,不是 i 或 L)并始终使用绝对路径。
  • ls -l /foo/bar | wc -l 都应该是 /bin/sh 的单个参数。
  • @JesperE:在命令行上,我同意,但在 Java 中不同意。如果你拆分参数,那么路径可以包含特殊字符(如空格),它仍然可以工作。
  • 你没有理解我的意思。如果您希望sh 执行一个shell 脚本,您需要将该脚本作为one 参数传递。将“ls”“-l”等传递给sh 没有意义。如果你想传递一个包含空格的sh的路径,你需要引用它。
【解决方案2】:

如果您按照 Aaron 的建议使用 sh -c,则可以将整个管道作为单个 arg 传递,有效地执行以下操作:

sh -c "ls -l foo/bar | wc -l"

如果您使用单独的 args,它们会被 sh 使用,而不是传递给 ls(因此您只能看到当前目录)。

请注意,在我的系统上,ls -l 包括找到的文件总数和列表,这意味着显示的计数比文件数多一。所以建议:

<exec executable="sh" outputproperty="noOfFiles">
    <arg value="-c" />
    <arg value="ls foo/bar | wc -l" />
</exec>

【讨论】:

  • 谢谢马丁,这解决了我面临的问题。也感谢亚伦。
【解决方案3】:

如果您只想计算目录中的文件,则根本不要使用外部 shell。使用resourcecount 任务。快速、紧凑、便携且易于阅读:

<resourcecount property="numfiles">
  <fileset dir="."/>
</resourcecount>

您当然可以自定义 fileset 以仅包含您需要的特定文件。

(实际上很少有需要生成外部 shell 的情况。Ant 内置的 I/O 重定向器和输入/输出过滤器链通常可以以可移植的方式完成同样的事情,即使有时有点详细。)

【讨论】:

  • 感谢 JesperE 的评论。我将研究资源计数并用它替换我当前的解决方案。干杯
  • 另一个答案是我正在寻找的答案,但 +1 是为了提供对原始问题的最佳答案。
猜你喜欢
  • 1970-01-01
  • 2017-01-22
  • 1970-01-01
  • 2012-09-19
  • 1970-01-01
  • 2012-12-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多