diff --git a/hesh.cabal b/hesh.cabal
--- a/hesh.cabal
+++ b/hesh.cabal
@@ -1,5 +1,5 @@
 name:                hesh
-version:             1.1.0
+version:             1.2.0
 synopsis:            the Haskell Extensible Shell: Haskell for Bash-style scripts
 description:         Hesh makes writing scripts in Haskell easier by providing Bash-style syntax for running commands, implicit module imports, and automatic dependency inference and Cabal file generation. It allows shebang execution of scripts.
 homepage:            https://github.com/jekor/hesh
@@ -32,7 +32,7 @@
                        filepath,
                        hackage-db >= 1.8,
                        haskell-src-exts,
-                       hesh == 1.1.0,
+                       hesh == 1.2.0,
                        parsec >= 3,
                        process,
                        text,
diff --git a/hesh/Main.hs b/hesh/Main.hs
--- a/hesh/Main.hs
+++ b/hesh/Main.hs
@@ -120,12 +120,8 @@
 importDeclUnqualified :: String -> ImportDecl
 importDeclUnqualified m = ImportDecl (SrcLoc "" 0 0) (ModuleName m) False False False Nothing Nothing Nothing
 
--- packageFromModules modules m
---   | m == "Hesh" || isPrefixOf "Hesh." m = [PackageConstraint "hesh" [1, 1, 0] [1, 1, 0]]
---   | otherwise = Map.findWithDefault (error ("Module \"" ++ m ++ "\" not found in Hackage list.")) (Text.pack m) modules
-
 packageFromModules modules (m, _, Just pkg)
-  | pkg == "hesh" = Cartel.package "hesh" Cartel.anyVersion -- [1, 1, 0] [1, 1, 0]
+  | pkg == "hesh" = Cartel.package "hesh" Cartel.anyVersion -- [1, 2, 0] [1, 2, 0]
   | otherwise = Cartel.package pkg Cartel.anyVersion
 packageFromModules modules (m, _, Nothing)
   | m == "Hesh" || isPrefixOf "Hesh." m = Cartel.package "hesh" Cartel.anyVersion
@@ -135,7 +131,7 @@
 
 term = hesh <$> flagStdin <*> flagNoSugar <*> optionFile <*> arguments
 
-termInfo = defTI { termName = "hesh", version = "1.1.0" }
+termInfo = defTI { termName = "hesh", version = "1.2.0" }
 
 flagStdin :: Term Bool
 flagStdin = value . flag $ (optInfo [ "stdin", "s" ]) { optName = "STDIN", optDoc = "If this option is present, or if no arguments remain after option processing, then the script is read from standard input." }
diff --git a/lib/Hesh.hs b/lib/Hesh.hs
--- a/lib/Hesh.hs
+++ b/lib/Hesh.hs
@@ -1,4 +1,4 @@
-module Hesh ( sh, cmd, (|>), (/>), (!>), (&>), (</), (.=)
+module Hesh ( sh, cmd, (|>), (/>), (!>), (&>), (</), (/>>), (!>>), (&>>), (.=)
             , passThrough
             ) where
 
diff --git a/lib/Hesh/Process.hs b/lib/Hesh/Process.hs
--- a/lib/Hesh/Process.hs
+++ b/lib/Hesh/Process.hs
@@ -1,6 +1,6 @@
 {-# LANGUAGE FlexibleInstances #-}
 
-module Hesh.Process ( (|>), (/>), (!>), (&>), (</), pipeOps
+module Hesh.Process ( (|>), (/>), (!>), (&>), (</), (/>>), (!>>), (&>>), pipeOps
                     , cmd, passThrough, (.=)
                     ) where
 
@@ -14,7 +14,7 @@
 import System.IO (openFile, IOMode(..), hGetContents, hClose, hPutStrLn, stderr)
 import System.Process (proc, createProcess, CreateProcess(..), ProcessHandle, waitForProcess, StdStream(..), CmdSpec(..), readProcess)
 
-pipeOps = ["|>", "/>", "!>", "&>", "</"]
+pipeOps = ["|>", "/>", "!>", "&>", "</", "/>>", "!>>", "&>>"]
 
 class PipeResult a where
   (|>) :: (MonadIO m) => m CreateProcess -> m CreateProcess -> m a
@@ -22,13 +22,19 @@
   (!>) :: (MonadIO m) => m CreateProcess -> FilePath -> m a
   (&>) :: (MonadIO m) => m CreateProcess -> FilePath -> m a
   (</) :: (MonadIO m) => m CreateProcess -> FilePath -> m a
+  (/>>) :: (MonadIO m) => m CreateProcess -> FilePath -> m a
+  (!>>) :: (MonadIO m) => m CreateProcess -> FilePath -> m a
+  (&>>) :: (MonadIO m) => m CreateProcess -> FilePath -> m a
 
 instance PipeResult CreateProcess where
   (|>) = pipe
-  (</) = redirect [Stdin]
-  (/>) = redirect [Stdout]
-  (!>) = redirect [Stderr]
-  (&>) = redirect [Stdout, Stderr]
+  (</) = redirect [Stdin] ReadMode
+  (/>) = redirect [Stdout] WriteMode
+  (!>) = redirect [Stderr] WriteMode
+  (&>) = redirect [Stdout, Stderr] WriteMode
+  (/>>) = redirect [Stdout] AppendMode
+  (!>>) = redirect [Stderr] AppendMode
+  (&>>) = redirect [Stdout, Stderr] AppendMode
 
 instance PipeResult () where
   p1 |> p2 = passThrough (p1 |> p2)
@@ -36,7 +42,20 @@
   p !> path = passThrough (p !> path)
   p &> path = passThrough (p &> path)
   p </ path = passThrough (p </ path)
+  p />> path = passThrough (p />> path)
+  p !>> path = passThrough (p !>> path)
+  p &>> path = passThrough (p &>> path)
 
+instance PipeResult String where
+  p1 |> p2 = stdoutToString (p1 |> p2)
+  p /> path = stdoutToString (p /> path)
+  p !> path = stdoutToString (p !> path)
+  p &> path = stdoutToString (p &> path)
+  p </ path = stdoutToString (p </ path)
+  p />> path = stdoutToString (p />> path)  
+  p !>> path = stdoutToString (p !>> path)  
+  p &>> path = stdoutToString (p &>> path)  
+
 -- cmd is like proc but operates on the resulting process depending on
 -- its calling context.
 class ProcResult a where
@@ -88,10 +107,10 @@
 
 data StdHandle = Stdin | Stdout | Stderr deriving (Eq)
 
-redirect :: (MonadIO m) => [StdHandle] -> m CreateProcess -> FilePath -> m CreateProcess
-redirect handles p' path = do
+redirect :: (MonadIO m) => [StdHandle] -> IOMode -> m CreateProcess -> FilePath -> m CreateProcess
+redirect handles mode p' path = do
   p <- p'
-  f <- liftIO (openFile path (if handles == [Stdin] then ReadMode else WriteMode))
+  f <- liftIO (openFile path mode)
   return (case handles of
              [Stdin] -> p { std_in = UseHandle f }
              [Stdout] -> p { std_out = UseHandle f }
