【问题标题】:Gradle Exec task and process outputGradle Exec 任务和流程输出
【发布时间】:2014-09-22 18:42:54
【问题描述】:

我有一个 python 脚本,它打印一些字符串并在控制台中更新它的执行进度:

if __name__ == '__main__':
    ...

    print 'Hello, world!'

    while page <= pages:
        ...

        done = float(page) / pages
        sys.stdout.write('\r[{0:50s}] {1:.2f}%'.format('#' * int(done * 50), done * 100))

        page += 1

    print ''

当我从 python script.py 这样的控制台运行它时,一切正常,我可以看到输出和进度条。我需要将此脚本作为 Gradle 构建的一部分运行,因此我创建了一个任务:

task process(type: Exec) {
    workingDir file('src/main/python')
    commandLine 'python', 'process.py', ...
}

现在,当我使用gradle process 执行脚本时,我在控制台中看不到任何输出,打印的最后一行是&gt; Building 0% &gt; :process

我也尝试过使用 Java 7 的 ProcessBuilder,但也没有成功:

task process << {
    def processBuilder = new ProcessBuilder([
            'python',
            'process.py',
            ...
    ]).directory(file('src/main/python'))
            .redirectInput(ProcessBuilder.Redirect.INHERIT)
            .redirectOutput(ProcessBuilder.Redirect.INHERIT)
            .redirectError(ProcessBuilder.Redirect.INHERIT).start().waitFor()
}

我被困住了。我真的很想在同一个控制台中看到 python 的输出。我怎样才能实现它?

UPD:有时它会以某种方式打印乱码:

【问题讨论】:

    标签: python process gradle stdout build.gradle


    【解决方案1】:

    我通过在 python 脚本中刷新系统输出解决了这个问题。这不是理想的解决方案,但它可以完成工作。

    所以我的 python 脚本中有以下内容

    import sys
    import time
    
    def flush_out(string):
        print(string)
        sys.stdout.flush()
    
    #script does something
    flush_out("Waiting for 10 seconds...")
    time.sleep(10)
    flush_out("Exiting")
    sys.exit(0)
    

    【讨论】:

      【解决方案2】:

      对我来说唯一的解决方案是将输出重定向到文件:

        .redirectErrorStream(true)
        .redirectOutput(ProcessBuilder.Redirect.to(new File(project.buildDir, "my-task.log")))
      

      【讨论】:

        【解决方案3】:

        即使问题很老,也可能与其他问题有关。我的解决方案是用“-c”参数显式启动一个shell,让shell处理参数。这甚至允许重定向 STDERR 和 STDOUT。

        这是一个例子:

        task(createVersionFile, type: Exec) {
            commandLine 'sh', '-c', "echo ${version} > ${htmlDir}/version.txt"
        }
        

        【讨论】:

          【解决方案4】:

          我看到了这篇 7 年前发布的帖子。解决方案是像这样连接System.out

          def sqlplus = "sqlplus ${db.un}/${db.pw}@${db.tns} @upgrade.sql".execute(null, new File('file/path/'))
          
          sqlplus.withWriter { writer ->
              writer.write("exit")
          }
          
          sqlplus.consumeProcessOutput(System.out, System.err) // This is the trick
          
          sqlplus.waitFor()
          if (sqlplus.exitValue() != 0) {
              throw new RuntimeException("Error updating database")
          }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2015-11-13
            • 2015-02-08
            • 1970-01-01
            • 2013-08-24
            相关资源
            最近更新 更多