diff --git a/src/System/Console/StructuredCLI.hs b/src/System/Console/StructuredCLI.hs
--- a/src/System/Console/StructuredCLI.hs
+++ b/src/System/Console/StructuredCLI.hs
@@ -75,6 +75,7 @@
                                      top) where
 
 import Control.Applicative        (liftA2)
+import Control.Exception          (Exception, throw)
 import Control.Monad              (foldM, replicateM, void, when)
 import Control.Monad.IO.Class     (MonadIO, liftIO)
 import Control.Monad.Trans        (MonadTrans, lift)
@@ -88,6 +89,7 @@
 import Data.Default               (Default, def)
 import Data.List                  (filter, isPrefixOf, intercalate, span, sort)
 import Data.Monoid                ((<>))
+import Data.Typeable              (Typeable)
 import System.Console.Haskeline   (Completion,
                                    InputT,
                                    MonadException,
@@ -115,8 +117,13 @@
 
 data Settings = Settings { history :: Maybe FilePath,
                            banner  :: String,
-                           prompt  :: String }
+                           prompt  :: String,
+                           batch   :: Bool }
 
+data CLIException = Exit deriving (Show, Typeable)
+
+instance Exception CLIException
+
 newtype CommandsT m a = CommandsT { runCommandsT :: m (a, [Node m]) }
 type Commands         = CommandsT IO
 
@@ -155,7 +162,7 @@
     def = Parser labelParser
 
 instance Default Settings where
-    def = Settings Nothing "" " > "
+    def = Settings Nothing "" " > " False
 
 nextWord :: String -> (String, String)
 nextWord = span (not.isSpace) . dropWhile isSpace
@@ -224,7 +231,7 @@
   root     <- execCommandsT rootCmds
   settings <- runMaybeT $ do
                s@Settings{..} <- MaybeT . pure $ userSettings
-               liftIO $ putStrLn banner
+               when (not batch) $ liftIO . putStrLn $ banner
                return s
   let ?settings = maybe def id settings
   evalStateT loop $ stateFor root
@@ -237,7 +244,7 @@
 
 runLevel :: (?settings::Settings, MonadException m) => InputT (CState m) ()
 runLevel = do
-  prompt  <- lift getPrompt
+  prompt  <- if batch ?settings then return "" else lift getPrompt
   nodes0  <- lift $ gets nodes
   labels0 <- lift $ gets labels
   result  <- runMaybeT $ do
@@ -245,8 +252,11 @@
               parse line
   case result of
     Nothing -> do
-        lift $ modify $ \state -> state { nodes = nodes0,    -- parse failed or no action
-                                         labels = labels0 } -- restore nodes to previous state
+        if batch ?settings then
+            throw Exit
+        else
+            lift $ modify $ \state -> state { nodes = nodes0,    -- parse failed or no action
+                                             labels = labels0 } -- restore nodes to previous state
     Just [] -> do
         Node{..} <- lift getCurrentCommand
         case action of
diff --git a/structured-cli.cabal b/structured-cli.cabal
--- a/structured-cli.cabal
+++ b/structured-cli.cabal
@@ -1,5 +1,5 @@
 name:                structured-cli
-version:             0.9.0.3
+version:             0.9.1.0
 synopsis:            Application library for building interactive console CLIs
 description:         This module provides the tools to build a complete "structured" CLI application, similar to those found in systems like Cisco IOS or console configuration utilities etc. It aims to be easy for implementors to use.
 homepage:            https://github.com/erickg/structured-cli#readme
