diff --git a/Shelly.hs b/Shelly.hs
--- a/Shelly.hs
+++ b/Shelly.hs
@@ -21,7 +21,7 @@
 module Shelly
        (
          -- * Entering ShIO.
-         ShIO, shelly, sub, silently, verbosely, print_stdout, print_commands
+         ShIO, shelly, sub, silently, verbosely, escaping, print_stdout, print_commands
 
          -- * Running external commands.
          , run, run_, cmd, (-|-), lastStderr, setStdin
@@ -108,7 +108,7 @@
 
 import qualified Data.Text.Lazy.IO as TIO
 import qualified Data.Text.IO as STIO
-import System.Process( runInteractiveProcess, waitForProcess, ProcessHandle )
+import System.Process( CmdSpec(..), StdStream(CreatePipe), CreateProcess(..), createProcess, waitForProcess, ProcessHandle )
 
 import qualified Data.Text.Lazy as LT
 import Data.Text.Lazy (Text)
@@ -297,14 +297,32 @@
 gets f = f <$> get
 
 -- FIXME: find the full path to the exe from PATH
-runInteractiveProcess' :: FilePath -> [Text] -> ShIO (Handle, Handle, Handle, ProcessHandle)
-runInteractiveProcess' exe args = do
+runCommand :: FilePath -> [Text] -> ShIO (Handle, Handle, Handle, ProcessHandle)
+runCommand exe args = do
   st <- get
-  liftIO $ runInteractiveProcess (unpack exe)
-    (map LT.unpack args)
-    (Just $ unpack $ sDirectory st)
-    (Just $ sEnvironment st)
+  shellyProcess st $
+    RawCommand (unpack exe) (map LT.unpack args)
 
+runCommandNoEscape :: FilePath -> [Text] -> ShIO (Handle, Handle, Handle, ProcessHandle)
+runCommandNoEscape exe args = do
+  st <- get
+  shellyProcess st $
+    ShellCommand $ LT.unpack $ LT.intercalate " " (toTextIgnore exe : args)
+    
+
+shellyProcess :: State -> CmdSpec -> ShIO (Handle, Handle, Handle, ProcessHandle)
+shellyProcess st cmdSpec =  do
+  (Just hin, Just hout, Just herr, pHandle) <- liftIO $
+    createProcess $ CreateProcess {
+        cmdspec = cmdSpec
+      , cwd = Just $ unpack $ sDirectory st
+      , env = Just $ sEnvironment st
+      , std_in = CreatePipe, std_out = CreatePipe, std_err = CreatePipe
+      , close_fds = False
+      , create_group = False
+      }
+  return (hin, hout, herr, pHandle)
+
 {-
 -- | use for commands requiring usage of sudo. see 'run_sudo'.
 --  Use this pattern for priveledge separation
@@ -421,7 +439,7 @@
 echo_n_err = traceLiftIO $ (>> hFlush stderr) . TIO.hPutStr stderr
 
 traceLiftIO :: (Text -> IO ()) -> Text -> ShIO ()
-traceLiftIO f msg = trace ("echo " `mappend` msg) >> liftIO (f msg)
+traceLiftIO f msg = trace ("echo " `mappend` "'" `mappend` msg `mappend` "'") >> liftIO (f msg)
 
 exit :: Int -> ShIO ()
 exit 0 = liftIO (exitWith ExitSuccess) `tag` "exit 0"
@@ -524,7 +542,7 @@
 setenv :: Text -> Text -> ShIO ()
 setenv k v =
   let (kStr, vStr) = (LT.unpack k, LT.unpack v)
-      wibble env = (kStr, vStr) : filter ((/=kStr).fst) env
+      wibble environment = (kStr, vStr) : filter ((/=kStr).fst) environment
    in modify $ \x -> x { sEnvironment = wibble $ sEnvironment x }
 
 -- | add the filepath onto the PATH env variable
@@ -633,21 +651,30 @@
       newState <- get
       put oldState { sTrace = sTrace oldState `mappend` sTrace newState  }
 
+escaping :: Bool -> ShIO a -> ShIO a
+escaping shouldEscape action = sub $ do
+  modify $ \st -> st { sRun =
+      if shouldEscape
+        then runCommand
+        else runCommandNoEscape
+    }
+  action
+
 -- | Enter a ShIO from (Monad)IO. The environment and working directories are
 -- inherited from the current process-wide values. Any subsequent changes in
 -- processwide working directory or environment are not reflected in the
 -- running ShIO.
 shelly :: MonadIO m => ShIO a -> m a
 shelly action = do
-  env <- liftIO getEnvironment
+  environment <- liftIO getEnvironment
   dir <- liftIO getWorkingDirectory
   let def  = State { sCode = 0
                    , sStdin = Nothing
                    , sStderr = LT.empty
                    , sPrintStdout = True
                    , sPrintCommands = False
-                   , sRun = runInteractiveProcess'
-                   , sEnvironment = env
+                   , sRun = runCommand
+                   , sEnvironment = environment
                    , sTrace = B.fromText ""
                    , sDirectory = dir }
   stref <- liftIO $ newIORef def
@@ -671,7 +698,8 @@
 show_command exe args =
     LT.intercalate " " $ map quote (toTextIgnore exe : args)
   where
-    quote t = if LT.any isSpace t then surround '\'' t else t
+    quote t = if LT.any (== '\'') t then t
+      else if LT.any isSpace t then surround '\'' t else t
     surround c t = LT.cons c $ LT.snoc t c
 
 
diff --git a/shelly.cabal b/shelly.cabal
--- a/shelly.cabal
+++ b/shelly.cabal
@@ -1,6 +1,6 @@
 Name:       shelly
 
-Version:     0.9.3
+Version:     0.9.4.1
 Synopsis:    shell-like (systems) programming in Haskell
 
 Description: Shelly provides a single module for convenient
