diff --git a/Shelly.hs b/Shelly.hs
--- a/Shelly.hs
+++ b/Shelly.hs
@@ -25,15 +25,15 @@
 module Shelly
        (
          -- * Entering Sh.
-         Sh, ShIO, shelly, sub, silently, verbosely, escaping, print_stdout, print_commands, tracing
+         Sh, ShIO, shelly, sub, silently, verbosely, escaping, print_stdout, print_commands, tracing, errExit
 
          -- * Running external commands.
-         , run, run_, runFoldLines, cmd, (-|-), lastStderr, setStdin
+         , run, run_, runFoldLines, cmd, (-|-), lastStderr, setStdin, lastExitCode
          , command, command_, command1, command1_
          , sshPairs, sshPairs_
 
          -- * Modifying and querying environment.
-         , setenv, get_env, get_env_text, getenv, getenv_def, appendToPath
+         , setenv, set_env, get_env, get_env_text, getenv, getenv_def, appendToPath
 
          -- * Environment directory
          , cd, chdir, pwd
@@ -53,7 +53,7 @@
          , mv, rm, rm_f, rm_rf, cp, cp_r, mkdir, mkdir_p
 
          -- * reading/writing Files
-         , readfile, writefile, appendfile, touchfile, withTmpDir
+         , readfile, readBinary, writefile, appendfile, touchfile, withTmpDir
 
          -- * exiting the program
          , exit, errorExit, quietExit, terror
@@ -95,13 +95,16 @@
 import Data.Time.Clock( getCurrentTime, diffUTCTime  )
 
 import qualified Data.Text.Lazy.IO as TIO
-import qualified Data.Text.IO as STIO
+import qualified Data.Text.Encoding as TE
+import qualified Data.Text.Encoding.Error as TE
 import System.Process( CmdSpec(..), StdStream(CreatePipe), CreateProcess(..), createProcess, waitForProcess, ProcessHandle )
 import System.IO.Error (isPermissionError)
 
 import qualified Data.Text.Lazy as LT
 import qualified Data.Text.Lazy.Builder as B
 import qualified Data.Text as T
+import qualified Data.ByteString as BS
+import Data.ByteString (ByteString)
 import Data.Monoid (mappend)
 
 import Filesystem.Path.CurrentOS hiding (concat, fromText, (</>), (<.>))
@@ -457,10 +460,15 @@
   -- TODO: better error message for removeFile (give filename)
   canonic f >>= liftIO . removeFile
 
+-- | deprecated in favor of 'set_env'
+setenv :: Text -> Text -> Sh ()
+setenv = set_env
+{-# DEPRECATED setenv "use set_env" #-}
+
 -- | Set an environment variable. The environment is maintained in Sh
 -- internally, and is passed to any external commands to be executed.
-setenv :: Text -> Text -> Sh ()
-setenv k v =
+set_env :: Text -> Text -> Sh ()
+set_env k v =
   let (kStr, vStr) = (LT.unpack k, LT.unpack v)
       wibble environment = (kStr, vStr) : filter ((/=kStr).fst) environment
    in modify $ \x -> x { sEnvironment = wibble $ sEnvironment x }
@@ -470,8 +478,8 @@
 appendToPath :: FilePath -> Sh ()
 appendToPath = absPath >=> \filepath -> do
   tp <- toTextWarn filepath
-  pe <- getenv path_env
-  setenv path_env $ pe `mappend` ":" `mappend` tp
+  pe <- get_env_text path_env
+  set_env path_env $ pe `mappend` ":" `mappend` tp
   where
     path_env = "PATH"
 
@@ -484,6 +492,7 @@
     Nothing -> Nothing
     j@(Just val) -> if LT.null val then Nothing else j
 
+-- | deprecated
 getenv :: Text -> Sh Text
 getenv k = getenv_def k ""
 {-# DEPRECATED getenv "use get_env or get_env_text" #-}
@@ -491,7 +500,7 @@
 -- | Fetch the current value of an environment variable. Both empty and
 -- non-existent variables give empty string as a result.
 get_env_text :: Text -> Sh Text
-get_env_text k = getenv_def k ""
+get_env_text = getenv_def ""
 
 -- | Fetch the current value of an environment variable. Both empty and
 -- non-existent variables give the default Text value as a result
@@ -555,6 +564,14 @@
     }
   action
 
+-- | named after bash -e errexit. Defaults to True.
+-- When True, throw an exception on a non-zero exit code.
+-- Not recommended to set to False unless you are specifically checking the error code with 'lastExitCode'.
+errExit :: Bool -> Sh a -> Sh a
+errExit shouldExit action = sub $ do
+  modify $ \st -> st { sErrExit = shouldExit }
+  action
+
 -- | Enter a Sh 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
@@ -572,7 +589,9 @@
                    , sEnvironment = environment
                    , sTracing = True
                    , sTrace = B.fromText ""
-                   , sDirectory = dir }
+                   , sDirectory = dir
+                   , sErrExit = True
+                   }
   stref <- liftIO $ newIORef def
   let caught =
         action `catches_sh` [
@@ -763,14 +782,19 @@
 
     put $ state { sStderr = errs , sCode = code }
 
-    liftIO $ case ex of
-      ExitSuccess   -> takeMVar outV
-      ExitFailure n -> throwIO $ RunFailed exe args n errs
+    liftIO $ case (sErrExit state, ex) of
+      (True,  ExitFailure n) -> throwIO $ RunFailed exe args n errs
+      _                      -> takeMVar outV
 
 -- | The output of last external command. See "run".
 lastStderr :: Sh Text
 lastStderr = gets sStderr
 
+-- | The exit code from the last command.
+-- Unless you set 'errExit' to False you won't get a chance to use this: a non-zero exit code will throw an exception.
+lastExitCode :: Sh Int
+lastExitCode = gets sCode
+
 -- | set the stdin to be used and cleared by the next "run".
 setStdin :: Text -> Sh ()
 setStdin input = modify $ \st -> st { sStdin = Just input }
@@ -852,11 +876,16 @@
 
 -- | (Strictly) read file into a Text.
 -- All other functions use Lazy Text.
--- So Internally this reads a file as strict text and then converts it to lazy text, which is inefficient
+-- Internally this reads a file as strict text and then converts it to lazy text, which is inefficient
 readfile :: FilePath -> Sh Text
 readfile = absPath >=> \fp -> do
   trace $ "readfile " `mappend` toTextIgnore fp
-  (fmap LT.fromStrict . liftIO . STIO.readFile . unpack) fp
+  readBinary fp >>=
+    return . LT.fromStrict . TE.decodeUtf8With TE.lenientDecode
+
+-- | wraps ByteSting readFile
+readBinary :: FilePath -> Sh ByteString
+readBinary = absPath >=> liftIO . BS.readFile . unpack
 
 -- | flipped hasExtension for Text
 hasExt :: Text -> FilePath -> Bool
diff --git a/Shelly/Base.hs b/Shelly/Base.hs
--- a/Shelly/Base.hs
+++ b/Shelly/Base.hs
@@ -64,6 +64,7 @@
                      , sEnvironment :: [(String, String)]
                      , sTracing :: Bool
                      , sTrace :: B.Builder
+                     , sErrExit :: Bool
                      }
 
 -- | A monadic-conditional version of the "when" guard.
diff --git a/Shelly/Find.hs b/Shelly/Find.hs
--- a/Shelly/Find.hs
+++ b/Shelly/Find.hs
@@ -63,10 +63,11 @@
       (rPaths, aPaths) <- lsRelAbs dir 
       foldM traverse startValue (zip rPaths aPaths)
   where
-    traverse acc (relPath, absPath) = do
+    traverse acc (relativePath, absolutePath) = do
       -- optimization: don't use Shelly API since our path is already good
-      isDir <- liftIO $ isDirectory absPath
-      sym   <- liftIO $ fmap isSymbolicLink $ getSymbolicLinkStatus (unpack absPath)
+      isDir <- liftIO $ isDirectory absolutePath
+      sym   <- liftIO $ fmap isSymbolicLink $ getSymbolicLinkStatus (unpack absolutePath)
+      newAcc <- folder acc relativePath
       if isDir && not sym
-        then findFold folder acc relPath
-        else folder acc relPath
+        then findFold folder newAcc relativePath
+        else return newAcc
diff --git a/shelly.cabal b/shelly.cabal
--- a/shelly.cabal
+++ b/shelly.cabal
@@ -1,6 +1,6 @@
 Name:       shelly
 
-Version:     0.13.3
+Version:     0.13.4
 Synopsis:    shell-like (systems) programming in Haskell
 
 Description: Shelly provides convenient systems programming in Haskell,
@@ -41,6 +41,7 @@
                , unix-compat < 0.4
                , system-filepath < 0.5
                , system-fileio < 0.4
+               , bytestring
 
   ghc-options: -Wall
 
@@ -54,6 +55,7 @@
                  , unix-compat < 0.4
                  , system-filepath < 0.5
                  , system-fileio < 0.4
+                 , bytestring
                  , hspec-discover
                  , hspec >= 1.1
                  , HUnit
