Run a background job from Gradle

自闭症网瘾萝莉.ら 提交于 2019-12-10 14:55:38

问题


I've created a task starting a remote job like

task mytask(type: Exec) {
    commandLine 'ssh'
    args '-f -l me myserver ./start'.split(' ')
}

and it works, however, it seems to wait for the job to terminate. But it never terminates and it shouldn't.

Doing the same from the command line works: Because of the -f switch the ssh command gets executed in the background.

I've tried to add '>&' /dev/null (csh stdout and stderr redirect) to the command line, but without any success. Also the obvious & did nothing. I also extracted the command line into a script, and it's always the same: Gradle waits for termination.

Solution

I've solved it by using a script and redirecting both stdout and stderr in the script. My problem came from confusing redirections... by passing '>&' /dev/null I redirected the streams on the remote computer, but what was needed was a redirection on the local one (i.e., without putting the redirection operator in quotes).


回答1:


The Exec task always waits for termination. To run a background job, you need to write your own task, which could, for example, use the Java ProcessBuilder API.




回答2:


The Exec task always waits for termination. To run a background job, use the Ant task 'Exec'

ant.exec(
  executable: 'ssh',
  spawn: true
) {
   arg '-f'
   arg '-l'
   arg 'me'
   arg 'myserver'
   arg './start'
}



回答3:


As @peter-niederwieser suggests, ProcessBuilder might be the sollution. Something along the lines of Tomas Lins ExecWait might work to your winnings.

In short, it listens for a chosen word, and marks task as done when it hits.

From the page:

class ExecWait extends DefaultTask {
String command
String ready
String directory

@TaskAction
def spawnProcess() {

    ProcessBuilder builder = new ProcessBuilder(command.split(' '))
    builder.redirectErrorStream(true)
    builder.directory(new File(directory))
    Process process = builder.start()

    InputStream stdout = process.getInputStream()
    BufferedReader reader = new BufferedReader(new InputStreamReader(stdout))

    def line
    while ((line = reader.readLine()) != null) {
        println line
        if (line.contains(ready)) {
            println "$command is ready"
            break;
        }
    }
}



回答4:


The Gradle spawn plugin can launch a background process in a Gradle build and subsequently tear it down again. NB this does not work under Windows, but seems fine on Linux or MacOS X. If you find that it starts up the background process, but doesn't appear to detect when the background process has finished initialising so that integration testing can begin, you have to configure the task with the parameter "ready", which is a string that it looks for in the output of the started background process to determine when it is safe to proceed.



来源:https://stackoverflow.com/questions/25295945/run-a-background-job-from-gradle

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!