A module for shell-like programming in Haskell.
Shelly's focus is entirely on ease of use for those coming from shell scripting.
However, it also tries to use modern libraries and techniques to keep things efficient.

The functionality provided by
this module is (unlike standard Haskell filesystem functionality)
thread-safe: each Sh maintains its own environment and its own working
directory.

Recommended usage includes putting the following at the top of your program,
otherwise you will likely need either type annotations or type conversions

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
running Sh.

Deprecated now, just use shelly, whose default has been changed.
Using this entry point does not create a .shelly directory in the case
of failure. Instead it logs directly into the standard error stream (stderr).

Create a sub-Sh with shell character escaping on or off.
Defaults to True.

Setting to False allows for shell wildcard such as * to be expanded by the shell along with any other special shell characters.
As a side-effect, setting to False causes changes to PATH to be ignored:
see the run documentation.

When running an external command, apply the given initializers to
the specified handles for that command.
This can for example be used to change the encoding of the
handles or set them into binary mode.

named after bash -e errexit. Defaults to True.
When True, throw an exception on a non-zero exit code.
When False, ignore a non-zero exit code.
Not recommended to set to False unless you are specifically checking the error code with lastExitCode.

Create a sub-Sh in which stdout is sent to the user-defined
logger. When running with silently the given log will not be
called for any output. Likewise the log will also not be called for
output from run_ and bash_ commands.

Create a sub-Sh in which stderr is sent to the user-defined
logger. When running with silently the given log will not be
called for any output. However, unlike log_stdout_with the log
will be called for output from run_ and bash_ commands.

All of the stdout output will be loaded into memory.
You can avoid this if you don't need stdout by using run_,
If you want to avoid the memory and need to process the output then use runFoldLines or runHandle or runHandles.

By default shell characters are escaped and
the command name is a name of a program that can be found via PATH.
Shelly will look through the PATH itself to find the command.

When escaping is set to False, shell characters are allowed.
Since there is no longer a guarantee that a single program name is
given, Shelly cannot look in the PATH for it.
a PATH modified by setenv is not taken into account when finding the exe name.
Instead the original Haskell program PATH is used.
On a Posix system the env command can be used to make the setenv PATH used when escaping is set to False. env echo hello instead of echo hello

variadic argument version of run.
Please see the documenation for run.

The syntax is more convenient, but more importantly it also allows the use of a FilePath as a command argument.
So an argument can be a Text or a FilePath without manual conversions.
a FilePath is automatically converted to Text with toTextIgnore.

Pipe operator. set the stdout the first command as the stdin of the second.
This does not create a shell-level pipe, but hopefully it will in the future.
To create a shell level pipe you can set escaping False and use a pipe | character in a command.

Environment directory

Change current working directory of Sh. This does *not* change the
working directory of the process we are running it. Instead, Sh keeps
track of its own working directory and builds absolute paths internally
instead of passing down relative paths.

Run a Sh computation and collect timing information.
The value returned is the amount of _real_ time spent running the computation
in seconds, as measured by the system clock.
The precision is determined by the resolution of getCurrentTime.

internal functions for writing extensions

find functions

List directory recursively (like the POSIX utility "find").
listing is relative if the path given is relative.
If you want to filter out some results or fold over them you can do that with the returned files.
A more efficient approach is to use one of the other find functions.