【问题标题】:Using groovy, how do you pipe multiple shell commands?使用 groovy,如何通过管道传输多个 shell 命令?
【发布时间】:2016-05-13 05:54:38
【问题描述】:

使用 Groovy 并且支持 java.lang.Process,我如何将多个 shell 命令连接在一起?

考虑这个 bash 命令(并假设您的用户名是 foo):

ps aux | grep ' foo' | awk '{print $1}'

这将打印出用户名 - 与您的用户帐户相关的某些进程的一行。

使用 Groovy,ProcessGroovyMethods 文档和代码说我应该能够这样做以获得相同的结果:

def p = "ps aux".execute() | "grep ' foo'".execute() | "awk '{print $1}'".execute()
p.waitFor()
println p.text

但是,除此之外,我无法获得任何文本输出:

def p = "ps aux".execute()
p.waitFor()
println p.text

只要我开始管道,println 就不会打印出任何东西。

想法?

【问题讨论】:

    标签: bash shell groovy process


    【解决方案1】:

    这对我有用:

    def p = 'ps aux'.execute() | 'grep foo'.execute() | ['awk', '{ print $1 }'].execute()
    p.waitFor()
    println p.text
    

    由于未知原因,不能仅使用一个字符串发送 awk 的参数(我不知道为什么!也许 bash 引用了不同的内容)。如果您使用命令转储错误流,您将看到与编译 awk 脚本相关的错误。

    编辑:其实,

    1. "-string-".execute() 委托给Runtime.getRuntime().exec(-string-)
    2. 使用 ' 或 " 处理包含空格的参数是 bash 工作。Runtime.exec 或操作系统不知道引号
    3. 执行"grep ' foo'".execute()执行命令grep,'作为第一个参数,foo'作为第二个参数:无效。 awk 也一样

    【讨论】:

    • 虽然@tim_yates 的回答以不同的方式解决了我的特定问题(对此我非常感激),但这个回答解决了 Groovy 的 or 运算符和 Process 对象的 OP 问题,所以我会奖励它。谢谢!
    【解决方案2】:

    您可以这样做,让外壳对其进行排序:

    // slash string at the end so we don't need to escape ' or $
    def p = ['/bin/bash', '-c', /ps aux | grep ' foo' | awk '{print $1}'/].execute()
    p.waitFor()
    println p.text
    

    【讨论】:

    • 是的,我可以,这可能是我需要走的路,但你知道为什么“或”方法不能像文档中定义的那样工作吗?
    • 这和awk有关。不知道是什么,但它不喜欢以这种方式运行
    • 有趣 - 粗暴的方法奏效了。使用双引号没有。去图吧!
    • 这个答案不是假的.. 但它没有回答原始问题:如何使用 | groovy 中 Process 对象之间的运算符。你只通过 bash 执行一个命令,它是 bash 管道进程,而不是 groovy
    • @tim_yates 是的,我认为这与 awk 或嵌套单引号有关。使用斜线字符串为我解决了这个问题,所以我想我会继续使用它。不幸的是,关于 Groovy 管道的问题仍然存在:/
    【解决方案3】:

    这对我有用

    def command = '''
        ps aux | grep bash | awk '{print $1}'
    '''
    def proc = ['bash', '-c', command].execute()
    proc.waitFor()
    println proc.text
    

    如果要运行多个命令,可以在命令中添加。

    def command = '''
        ls -ltr
        cat secret
    '''
    def proc = ['bash', '-c', command].execute()
    proc.waitFor()
    println proc.text
    

    【讨论】:

    • 这与上面@tim_yates 的回答相同——他只是使用斜杠字符串而不是heredoc :)
    • @LesHazlewood 对我来说不同的是,这个有效而斜线字符串无效。
    【解决方案4】:

    如果你想要异步,我推荐

     proc.consumeProcessOutputStream(new LineOrientedOutputStream() {
            @Override
            protected void processLine(String line) throws IOException {
               println line
            }
        }
        );
    

    【讨论】:

      猜你喜欢
      • 2012-08-08
      • 1970-01-01
      • 2012-06-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多