Safe Haskell | None |
---|---|
Language | Haskell98 |
Shell scripting with Conduit
This module consists only of re-exports, including a few thousand
top-level names based on PATH
. If you don't want that, you can
cherry-pick specific modules to import from the library.
See Data.Conduit.Shell.PATH for all binaries. But you should be
able to use whatever executables are in your PATH
when the library
is compiled.
Examples
The monad instance of Conduit will simply pass along all stdout results:
>>>
run (do echo "Hello"; sed "s/l/a/"; echo "OK!")
Hello OK!
Piping with Conduit's normal pipe will predictably pipe things together, as in Bash:
>>>
run (do shell "echo Hello" $= sed "s/l/a/"; echo "OK!")
Healo OK!
Streaming pipes (aka lazy pipes) is also possible:
>>>
run (do tail' "foo.txt" "-f" $= grep "--line-buffered" "Hello")
Hello, world! Oh, hello!
(Remember that grep
needs --line-buffered
if it is to output
things line-by-line).
How it works
All executable names in the PATH
at compile-time are brought into
scope as runnable process conduits e.g. ls
or grep
.
Stdin/out and stderr are handled as an Either
type: Chunk
Left
is stderr, Right
is stdin
/stdout
.
All processes are bound as variadic process calling functions, like this:
rmdir :: ProcessType r => r ls :: ProcessType r => r
But ultimately the types end up being:
rmdir "foo" :: Conduit Chunk m Chunk ls :: Conduit Chunk m Chunk ls "." :: Conduit Chunk m Chunk
Etc.
Run all shell scripts with run
:
run :: (MonadIO m, MonadBaseControl IO m) => Conduit Chunk (ShellT m) Chunk -> m ()
String types
If using OverloadedStrings
so that you can use Text
for arguments,
then also enable ExtendedDefaultRules
, otherwise you'll get
ambiguous type errors.
{--}
But this isn't necessary if you don't need to use Text
yet. Strings
literals will be interpreted as String
. Though you can pass a value
of type Text
or any instance of CmdArg
without needing conversions.
- run :: (MonadIO m, MonadBaseControl IO m) => Conduit Chunk (ShellT m) Chunk -> m ()
- shell :: MonadResource m => String -> Conduit Chunk m Chunk
- proc :: MonadResource m => String -> [String] -> Conduit Chunk m Chunk
- bytes :: Monad m => Conduit Chunk m ByteString
- unbytes :: Monad m => Conduit ByteString m Chunk
- withRights :: Monad m => Conduit ByteString m ByteString -> Conduit Chunk m Chunk
- redirect :: Monad m => ChunkType -> Conduit Chunk m Chunk
- quiet :: (Monad m, MonadIO m) => Conduit Chunk m Chunk -> Conduit Chunk m Chunk
- writeChunks :: MonadIO m => Consumer Chunk m ()
- discardChunks :: MonadIO m => Consumer Chunk m ()
- module Data.Conduit.Shell.PATH
- module Data.Conduit.Shell.Types
- module Data.Conduit.Shell.Variadic
- module Data.Conduit
Running scripts
run :: (MonadIO m, MonadBaseControl IO m) => Conduit Chunk (ShellT m) Chunk -> m () Source
Run a shell scripting conduit.
Running custom processes
I/O chunks
bytes :: Monad m => Conduit Chunk m ByteString Source
Extract the stdout values from the stream, discarding any errors.
unbytes :: Monad m => Conduit ByteString m Chunk Source
Extract the stdout values from the stream, discarding any errors.
withRights :: Monad m => Conduit ByteString m ByteString -> Conduit Chunk m Chunk Source
Do something with just the rights.
redirect :: Monad m => ChunkType -> Conduit Chunk m Chunk Source
Redirect the given chunk type to the other type.
quiet :: (Monad m, MonadIO m) => Conduit Chunk m Chunk -> Conduit Chunk m Chunk Source
Discard any output from the command: make it quiet.
writeChunks :: MonadIO m => Consumer Chunk m () Source
Write chunks to stdout and stderr.
discardChunks :: MonadIO m => Consumer Chunk m () Source
Discard all chunks.
Re-exports
The following modules are exported for scripting
convenience. Data.Conduit and Data.Conduit.Filesystem are
re-exported from other libraries because they are typical uses. If
you want a stream of the contents of a directory, recursively,
sourceDirectoryDeep
is handy. A program like find
is strict,
whereas a Conduit can stop processing whenever you wish.
You might want to import the regular Conduit modules qualified, too:
import qualified Data.Conduit.List as CL
Which contains handy functions for working on streams in a list-like way. See the rest of the handy modules for Conduit in conduit-extra: http://hackage.haskell.org/package/conduit-extra
Also of interest is csv-conduit: http://hackage.haskell.org/package/csv-conduit And html-conduit: http://hackage.haskell.org/package/html-conduit And http-conduit: http://hackage.haskell.org/package/http-conduit
Finally, see the Conduit category on Hackage for other useful libraries: http://hackage.haskell.org/packages/#cat:Conduit
All of these general purpose Conduits can be used in shell scripting.
module Data.Conduit.Shell.PATH
module Data.Conduit.Shell.Types
module Data.Conduit.Shell.Variadic
module Data.Conduit