streamly-process-0.2.0.1: Use OS processes as stream transformation functions
Copyright(c) 2020 Composewell Technologies
LicenseApache-2.0
Maintainerstreamly@composewell.com
Stabilityexperimental
PortabilityGHC
Safe HaskellNone
LanguageHaskell2010

Streamly.Internal.System.Process

Description

 
Synopsis

Process Configuration

data Config Source #

Process configuration used for creating a new process.

By default the process config is setup to inherit the following attributes from the parent process:

  • Current working directory
  • Environment
  • Open file descriptors
  • Process group
  • Process uid and gid
  • Signal handlers
  • Terminal (Session)

Exceptions

newtype ProcessFailure Source #

An exception that is raised when a process fails.

Since: 0.1.0

Constructors

ProcessFailure Int

The exit code of the process.

Generation

toBytes Source #

Arguments

:: (IsStream t, MonadAsync m, MonadCatch m) 
=> FilePath

Executable name or path

-> [String]

Arguments

-> t m Word8

Output Stream

See processBytes. toBytes is defined as:

>>> toBytes path args = processBytes path args Stream.nil

The following code is equivalent to the shell command echo "hello world":

>>> :{
   Process.toBytes "echo" ["hello world"]
 & Stream.fold Stdio.write
 :}
hello world

Since: 0.1.0

toBytes' Source #

Arguments

:: (IsStream t, MonadAsync m, MonadCatch m) 
=> FilePath

Executable name or path

-> [String]

Arguments

-> t m (Either Word8 Word8)

Output Stream

toBytes' path args runs the executable at path using args as arguments and returns a stream of Either bytes. The Left values are from stderr and the Right values are from stdout of the executable.

Raises ProcessFailure exception in case of failure.

The following example uses echo to write hello to stdout and world to stderr, then uses folds from Streamly.Console.Stdio to write them back to stdout and stderr respectively:

>>> :{
  Process.toBytes' "/bin/bash" ["-c", "echo 'hello'; echo 'world' 1>&2"]
& Stream.fold (Fold.partition Stdio.writeErr Stdio.write)
:}
world
hello
((),())
>>> toBytes' path args = Process.processBytes' path args Stream.nil

Since: 0.1.0

toChunks Source #

Arguments

:: (IsStream t, MonadAsync m, MonadCatch m) 
=> FilePath

Executable name or path

-> [String]

Arguments

-> t m (Array Word8)

Output Stream

See processChunks. toChunks is defined as:

>>> toChunks path args = processChunks path args Stream.nil

The following code is equivalent to the shell command echo "hello world":

>>> :{
   Process.toChunks "echo" ["hello world"]
 & Stream.fold Stdio.writeChunks
 :}
hello world

Since: 0.1.0

toChunks' Source #

Arguments

:: (IsStream t, MonadAsync m, MonadCatch m) 
=> FilePath

Executable name or path

-> [String]

Arguments

-> t m (Either (Array Word8) (Array Word8))

Output Stream

Like toBytes but generates a stream of Array Word8 instead of a stream of Word8.

>>> :{
  toChunks' "bash" ["-c", "echo 'hello'; echo 'world' 1>&2"]
& Stream.fold (Fold.partition Stdio.writeErrChunks Stdio.writeChunks)
:}
world
hello
((),())
>>> toChunks' path args = processChunks' path args Stream.nil

Prefer toChunks over toBytes when performance matters.

Since: 0.1.0

Transformation

processBytes Source #

Arguments

:: (IsStream t, MonadCatch m, MonadAsync m) 
=> FilePath

Executable name or path

-> [String]

Arguments

-> t m Word8

Input Stream

-> t m Word8

Output Stream

Like processChunks except that it works on a stream of bytes instead of a stream of chunks.

We can write the example in processChunks as follows. Notice how seamlessly we can replace the tr process with the Haskell toUpper function:

>>> :{
   Process.toBytes "echo" ["hello world"]
 & Unicode.decodeLatin1 & Stream.map toUpper & Unicode.encodeLatin1
 & Stream.fold Stdio.write
 :}
HELLO WORLD

Since: 0.1.0

processBytes' Source #

Arguments

:: (IsStream t, MonadCatch m, MonadAsync m) 
=> FilePath

Executable name or path

-> [String]

Arguments

-> t m Word8

Input Stream

-> t m (Either Word8 Word8)

Output Stream

processBytes' path args input runs the executable at path using args as arguments and input stream as its standard input. The error stream of the executable is presented as Left values in the resulting stream and output stream as Right values.

Raises ProcessFailure exception in case of failure.

For example, the following is equivalent to the shell command echo "hello world" | tr [:lower:] [:upper:]:

>>> :{
   processBytes' "echo" ["hello world"] Stream.nil
 & Stream.rights
 & processBytes' "tr" ["[:lower:]", "[:upper:]"]
 & Stream.rights
 & Stream.fold Stdio.write
 :}
HELLO WORLD

Since: 0.1.0

processChunksWith Source #

Arguments

:: (IsStream t, MonadCatch m, MonadAsync m) 
=> (Config -> Config)

Config modifier

-> FilePath

Executable name or path

-> [String]

Arguments

-> t m (Array Word8)

Input stream

-> t m (Array Word8)

Output stream

processChunks Source #

Arguments

:: (IsStream t, MonadCatch m, MonadAsync m) 
=> FilePath

Executable name or path

-> [String]

Arguments

-> t m (Array Word8)

Input stream

-> t m (Array Word8)

Output stream

processChunks file args input runs the executable file specified by its name or path using args as arguments and input stream as its standard input. Returns the standard output of the executable as a stream.

If only the name of an executable file is specified instead of its path then the file name is searched in the directories specified by the PATH environment variable.

If the input stream throws an exception or if the output stream is garbage collected before it could finish then the process is terminated with SIGTERM.

If the process terminates with a non-zero exit code then a ProcessFailure exception is raised.

The following code is equivalent to the shell command echo "hello world" | tr [a-z] [A-Z]:

>>> :{
   Process.toChunks "echo" ["hello world"]
 & Process.processChunks "tr" ["[a-z]", "[A-Z]"]
 & Stream.fold Stdio.writeChunks
 :}
HELLO WORLD

Since: 0.1.0

processChunks'With Source #

Arguments

:: (IsStream t, MonadCatch m, MonadAsync m) 
=> (Config -> Config)

Config modifier

-> FilePath

Executable name or path

-> [String]

Arguments

-> t m (Array Word8)

Input stream

-> t m (Either (Array Word8) (Array Word8))

Output stream

processChunks' Source #

Arguments

:: (IsStream t, MonadCatch m, MonadAsync m) 
=> FilePath

Executable name or path

-> [String]

Arguments

-> t m (Array Word8)

Input stream

-> t m (Either (Array Word8) (Array Word8))

Output stream