I have a simple script:

caffeinate -di

that I saved as an app. When I click on the app it runs the process and stays in the dock. When I click on the Dock icon, it says "Application Not Responding" and the only way to terminate the process is to Force Quit.

Is there any way to write this script so that the normal "Quit" menu displays and I don't have to force quit it every time I want to stop it?

  • If that is all there is, the shell script is blocking the user interface, so just launch it as a background task and terminate it on quit.
    – red_menace
    Feb 10, 2020 at 21:06
  • How would you "quit it" in that case? If it's run as a background task the icon in the dock has no option to quit. Clicking it just the script again as a new process.
    – Choy
    Feb 10, 2020 at 21:31

1 Answer 1


Any time an application does something like a execute a tight loop or perform a shell script that doesn't return, the user interface gets blocked because the app is not allowing the system time to process events. In this case an NSTask can be used, since it runs in the background, and the application is just used to start and stop it.

The following needs to be saved as a stay-open application - the shell script is launched and terminated with the app:

use AppleScript version "2.4" -- Yosemite (10.10) or later
use framework "Foundation"
use scripting additions

property task : missing value -- keep track of the NSTask

on run -- example
    tell current application's NSTask's alloc()'s init()
        set my task to it
        its setLaunchPath:"/bin/sh"
        its setArguments:{"-c", "/usr/bin/caffeinate -di"}
        tell it to |launch|()
    end tell
end run

on quit
    if task's isRunning then tell task to terminate()
    continue quit
end quit
  • Thank you! I see how NSTask is used in this case to monitor the subprocess and actually close it like I want it to.
    – Choy
    Feb 10, 2020 at 21:54

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .