Last active
September 30, 2016 18:25
-
-
Save dpwright/6588908 to your computer and use it in GitHub Desktop.
Watchdog -- Dumb Haskell process monitor
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Watchdog | |
======== | |
Watchdog is a simple utility to spawn and monitor a process, respawning it if it | |
dies or is killed for whatever reason. This is useful if you have a daemon | |
process that may encounter an unexpected error, or even just as a quick 'n' easy | |
upgrade mechanic -- just pop the new executable over the old one and shut the | |
process down! | |
There are a million of these, but I needed something quick 'n' dirty to | |
distribute with another program I was writing in Haskell, so I knocked this | |
together to go with it. | |
It's built on top of `System.Process`, naturally. We also want | |
`System.Environment` and `Control.Monad`: | |
> import System.Process | |
> import System.Environment | |
> import Control.Monad | |
The program takes the command to run as its argument(s). You can pass this as a | |
single, quoted argument, or just by passing arguments as parameters to the | |
program -- but beware of shell expansion! | |
> getTarget :: IO String | |
> getTarget = liftM unwords getArgs | |
We make use of `System.Process.runInteractiveCommand` in order to spawn the | |
process. This mitigates issues on Windows where the command window appears for | |
spawned processes. We then drop all the standard streams and wait for the | |
process to end. | |
> monitor :: String -> IO () | |
> monitor cmd = forever $ runInteractiveCommand cmd >>= handleOutput | |
> where handleOutput (_, _, _, ps) = waitForProcess ps | |
In case the user doesn't pass any arguments, display a usage banner: | |
> help :: IO () | |
> help = do | |
> progName <- getProgName | |
> putStrLn $ "Usage: " ++ progName ++ " cmd [arguments]" | |
Finally, it's just a case of putting these pieces together! | |
> main :: IO () | |
> main = getTarget >>= handle | |
> where handle cmd = if null cmd then help else monitor cmd | |
The end <3 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment