madhead
madhead

Reputation: 33422

Gradle Exec task and process output

I have a python script which prints some strings and updates it's execution progress in console:

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 ''

When I run it from console like python script.py everything is ok and I can see output and progressbar. I need to run this script as a part of Gradle build, so, I've created a task:

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

Now, when I use gradle process to execute the script I see no output in console, the last line that is printed is > Building 0% > :process

I've tried to use Java 7's ProcessBuilder with no luck too:

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()
}

I'm stuck. I really want to see python's output in the same console. How can I achieve it?

UPD: sometimes it somehow prints gibberish: enter image description here

Upvotes: 6

Views: 5246

Answers (4)

Minh Kieu
Minh Kieu

Reputation: 475

I sees this post, posted 7 years ago. The solution is to hook up the System.out like this:

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")
}

Upvotes: 1

Thomas Sch&#252;tt
Thomas Sch&#252;tt

Reputation: 939

Even though the question is old, this may be relevant to others. My solution is to explicitely start a shell with "-c" parameter to let the shell process the parameters. This even allows to redirect STDERR and STDOUT.

Here is an example:

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

Upvotes: 2

bkhouri
bkhouri

Reputation: 243

I worked around this issue by flushing the system output in the python script. it's not the ideal solution, but it gets the job done.

So I have the following in my python script

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)

Upvotes: 7

Oleksandr
Oleksandr

Reputation: 3801

The only solution for me was to redirect output to the file:

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

Upvotes: 2

Related Questions