Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Listening on CTRL+C in Groovy Script

Tags:

java

groovy

Is it possible to listen to CTRL+C when a groovy script is run from the command line ?

I have a script that creates some files. If interrupted I want to delete them from disk and then terminate.

Possible?

UPDATE 1: Derived from @tim_yates answer:

def withInteruptionListener = { Closure cloj, Closure onInterrupt ->

    def thread = { onInterrupt?.call() } as Thread

    Runtime.runtime.addShutdownHook (thread)
    cloj();
    Runtime.runtime.removeShutdownHook (thread)

}

withInteruptionListener ({

    println "Do this"
    sleep(3000)

    throw new java.lang.RuntimeException("Just to see that this is also taken care of")
}, {
    println "Interupted! Clean up!"
})
like image 224
mjs Avatar asked Jan 13 '12 13:01

mjs


People also ask

What does Ctrl C do in Java?

ctrl c is used to kill a process. It terminates your program. ctrl z is used to pause the process. It will not terminate your program, it will keep your program in background.

How do you comment on a Groovy script?

Single-line comments start with // and can be found at any position in the line. The characters following // , until the end of the line, are considered part of the comment.

What are keywords in Groovy?

Reserved keywords are words that have special meanings in Groovy language and therefore cannot be used as variable or function names in Groovy scripts.

How do I add a print statement in Groovy?

You can use the print function to print a string to the screen. You can include \n to embed a newline character. There is no need for semi-colon ; at the end of the statement. Alternatively you can use the println function that will automatically append a newline to the end of the output.


1 Answers

The following should work:

CLEANUP_REQUIRED = true
Runtime.runtime.addShutdownHook {
  println "Shutting down..."
  if( CLEANUP_REQUIRED ) {
    println "Cleaning up..."
  }
}
(1..10).each {
  sleep( 1000 )
}
CLEANUP_REQUIRED = false

As you can see, (as @DaveNewton points out), "Shutting down..." will be printed when the user presses CTRL-C, or the process finishes normally, so you'd need some method of detecting whether cleanup is required

Update

For the sake of curiosity, here is how you would do it using the unsupported sun.misc classes:

import sun.misc.Signal
import sun.misc.SignalHandler

def oldHandler
oldHandler = Signal.handle( new Signal("INT"), [ handle:{ sig ->
  println "Caught SIGINT"
  if( oldHandler ) oldHandler.handle( sig )
} ] as SignalHandler );

(1..10).each {
  sleep( 1000 )
}

But obviously, those classes can't be recommended as they might disappear/change/move

like image 105
tim_yates Avatar answered Sep 18 '22 12:09

tim_yates