diff --git a/Control/Shell.hs b/Control/Shell.hs
--- a/Control/Shell.hs
+++ b/Control/Shell.hs
@@ -6,7 +6,7 @@
   , shell, shell_, exitString
 
     -- * Error handling and control flow
-  , (|>), capture, stream, lift
+  , (|>), capture, captureStdErr, capture2, stream, lift
   , try, orElse, exit
   , Guard (..), guard, when, unless
 
@@ -43,6 +43,9 @@
   , hPutStr, hPutStrLn, echo, echo_, ask, stdin
   , hGetLine, hGetContents
 
+    -- * Terminal text formatting
+  , module Control.Shell.Color
+
     -- * ByteString I/O
   , hGetBytes, hPutBytes, hGetByteLine, hGetByteContents
 
@@ -59,6 +62,7 @@
 import Control.Shell.Directory
 import Control.Shell.Temp
 import Control.Shell.Control
+import Control.Shell.Color
 import Control.Monad hiding (guard, when, unless)
 import System.FilePath
 
diff --git a/Control/Shell/Base.hs b/Control/Shell/Base.hs
--- a/Control/Shell/Base.hs
+++ b/Control/Shell/Base.hs
@@ -7,7 +7,7 @@
   , MonadIO (..), shellEnv
   , shell_
   , stdin, echo, echo_, ask
-  , capture, stream, lift
+  , capture, captureStdErr, capture2, stream, lift
   , takeEnvLock, releaseEnvLock, setShellEnv, joinResult, absPath
   ) where
 import qualified System.Process as Proc
@@ -92,6 +92,29 @@
   (r, w) <- unsafeLiftIO Proc.createPipe
   inEnv (env {envStdOut = w}) m
   unsafeLiftIO $ IO.hClose w >> IO.hGetContents r
+
+-- | Perform the given computation and return its standard error.
+captureStdErr :: Shell () -> Shell String
+captureStdErr m = do
+  env <- getEnv
+  (r, w) <- unsafeLiftIO Proc.createPipe
+  inEnv (env {envStdErr = w}) m
+  unsafeLiftIO $ IO.hClose w >> IO.hGetContents r
+
+-- | Perform the given computation and return its standard output and error,
+--   in that order.
+capture2 :: Shell () -> Shell (String, String)
+capture2 m = do
+  env <- getEnv
+  (ro, wo) <- unsafeLiftIO Proc.createPipe
+  (re, we) <- unsafeLiftIO Proc.createPipe
+  inEnv (env {envStdOut = wo, envStdErr = we}) m
+  unsafeLiftIO $ do
+    IO.hClose wo
+    IO.hClose we
+    o <- IO.hGetContents ro
+    e <- IO.hGetContents re
+    return (o, e)
 
 -- | Lift a pure function to a computation over standard input/output.
 --   Similar to 'interact'.
diff --git a/Control/Shell/Color.hs b/Control/Shell/Color.hs
new file mode 100644
--- /dev/null
+++ b/Control/Shell/Color.hs
@@ -0,0 +1,62 @@
+-- | Color and formatting for terminal output.
+--   For Windows systems, any and all formatting are no-ops due to
+--   compatibility reasons.
+--
+--   While formattings can be stacked (i.e. @bold (underline "Hello Joe")@),
+--   they do not properly nest: the escape code used to reset formatting at the
+--   end of a formatted string removes *all* formatting. Thus,
+--   @color Red ("Hello" ++ color Blue "Mike")@ will print \"Hello\" in red and
+--   \"Mike\" in blue, but @color Red (color Blue "Hello" ++ "Robert")@ will
+--   print \"Robert\" in the terminal's default color, and not in red as one
+--   might expect.
+module Control.Shell.Color
+  ( Color (..)
+  , color, background
+  , highlight, bold, underline
+  ) where
+import System.Info (os)
+
+data Color
+  = Black
+  | Red
+  | Green
+  | Yellow
+  | Blue
+  | Purple
+  | Magenta
+  | White
+    deriving (Show, Read, Eq, Ord, Enum)
+
+colorNum :: Color -> Int
+colorNum = fromEnum
+
+-- | Apply the given color to the given string.
+color :: Color -> String -> String
+color c s = concat [esc ("0" ++ show (30+colorNum c)), s, normal]
+
+-- | Apply the given background color to the given string.
+background :: Color -> String -> String
+background c s = concat [esc ("0" ++ show (40+colorNum c)), s, normal]
+
+-- | Apply the terminal's default highlighting to the given string.
+highlight :: String -> String
+highlight s = esc "7" ++ s ++ normal
+
+-- | Output the given string in bold font.
+bold :: String -> String
+bold s = esc "1" ++ s ++ normal
+
+-- | Underline the given string.
+underline :: String -> String
+underline s = esc "4" ++ s ++ normal
+
+-- | Escape sequence to reset formatting back to normal.
+normal :: String
+normal = esc "0"
+
+-- | An escape character.
+{-# INLINE esc #-}
+esc :: String -> String
+esc s
+  | os == "mingw32" = ""
+  | otherwise       = "\ESC[" ++ s ++ "m"
diff --git a/shellmate.cabal b/shellmate.cabal
--- a/shellmate.cabal
+++ b/shellmate.cabal
@@ -1,5 +1,5 @@
 name:                shellmate
-version:             0.3.1
+version:             0.3.2
 synopsis:            Simple interface for shell scripting in Haskell.
 description:         Aims to simplify development of cross-platform shell scripts and similar things.
 homepage:            https://github.com/valderman/shellmate
@@ -28,6 +28,7 @@
     Control.Shell.Control
     Control.Shell.File
     Control.Shell.Directory
+    Control.Shell.Color
   build-depends:
     base         >=4.8  && <5,
     transformers >=0.3  && <0.5,
