diff --git a/shelly.cabal b/shelly.cabal
--- a/shelly.cabal
+++ b/shelly.cabal
@@ -1,6 +1,6 @@
 Name:       shelly
 
-Version:     1.6.2.5
+Version:     1.6.3
 Synopsis:    shell-like (systems) programming in Haskell
 
 Description: Shelly provides convenient systems programming in Haskell,
diff --git a/src/Shelly.hs b/src/Shelly.hs
--- a/src/Shelly.hs
+++ b/src/Shelly.hs
@@ -30,7 +30,7 @@
          , log_stdout_with, log_stderr_with
 
          -- * Running external commands.
-         , run, run_, runFoldLines, cmd, FoldCallback
+         , run, run_, bash, bash_, runFoldLines, cmd, FoldCallback
          , (-|-), lastStderr, setStdin, lastExitCode
          , command, command_, command1, command1_
          , sshPairs, sshPairs_
@@ -1049,6 +1049,18 @@
 --
 run :: FilePath -> [Text] -> Sh Text
 run fp args = return . lineSeqToText =<< runFoldLines mempty (|>) fp args
+
+-- | Like `run`, but it invokes the user-requested program with _bash_,
+-- setting _pipefail_ appropriately.
+bash :: FilePath -> [Text] -> Sh Text
+bash fp args = escaping False $ do
+  let sanitise = T.replace "'" "\'" . T.intercalate " "
+  run "bash" ["-c", "'set -o pipefail && " <> sanitise (toTextIgnore fp : args) <> "'"]
+
+bash_ :: FilePath -> [Text] -> Sh ()
+bash_ fp args = escaping False $ do
+  let sanitise = T.replace "'" "\'" . T.intercalate " "
+  run_ "bash" ["-c", "'set -o pipefail && " <> sanitise (toTextIgnore fp : args) <> "'"]
 
 -- | bind some arguments to run for re-use. Example:
 --
diff --git a/test/src/RunSpec.hs b/test/src/RunSpec.hs
--- a/test/src/RunSpec.hs
+++ b/test/src/RunSpec.hs
@@ -24,3 +24,32 @@
       res <- shelly $ onCommandHandles (initOutputHandles (flip hSetBinaryMode True))
                     $ run "cat" [ "test/data/nonascii.txt" ]
       res @?= "Selbstverst\228ndlich \252berraschend\n"
+
+  -- Bash-related commands
+  describe "bash" $ do
+    it "simple command" $ do
+      res <- shelly $ bash "echo" [ "wibble" ]
+      res @?= "wibble\n"
+
+    it "without escaping" $ do
+      res <- shelly $ escaping False $ bash "echo" [ "*" ]
+      assert $ "README.md" `elem` T.words res
+
+    it "with binary handle mode" $ do
+      res <- shelly $ onCommandHandles (initOutputHandles (flip hSetBinaryMode True))
+                    $ bash "cat" [ "test/data/nonascii.txt" ]
+      res @?= "Selbstverst\228ndlich \252berraschend\n"
+
+    it "can detect failing commands in pipes" $ do
+      eCode <- shelly $ escaping False $ errExit False $ do
+        bash_ "echo" [ "'foo'", "|", "ls", "\"eoueouoe\"", "|", "echo", "'bar'" ]
+        lastExitCode
+      eCode @?= 1
+
+    it "preserve pipe behaviour" $ do
+      (eCode, res) <- shelly $ escaping False $ errExit False $ do
+        res <- bash "echo" [ "'foo'", "|", "echo", "'bar'" ]
+        eCode <- lastExitCode
+        return (eCode, res)
+      res @?= "bar\n"
+      eCode @?= 0
diff --git a/test/src/TestMain.hs b/test/src/TestMain.hs
--- a/test/src/TestMain.hs
+++ b/test/src/TestMain.hs
@@ -28,4 +28,3 @@
     copySpec
     liftedSpec
     runSpec
-
