shqq-0.1: Embed shell commands with interpolated Haskell variables, and capture output

System.ShQQ

Contents

Description

Embed shell commands with interpolated Haskell variables, and capture output.

Synopsis

Quasiquoters

sh :: QuasiQuoterSource

Execute a shell command, capturing output.

This requires the QuasiQuotes extension.

The expression [sh| ... |] has type IO String. Executing this IO action will invoke the quoted shell command and produce its standard output as a String.

>>> [sh| sha1sum /proc/uptime |]
"ebe14a88cf9be69d2192dcd7bec395e3f00ca7a4  /proc/uptime\n"

You can interpolate Haskell String variables using the syntax $x. Special characters are escaped, so that the program invoked by the shell will see each interpolated variable as a single argument.

>>> let x = "foo bar" in [sh| cat $x |]
cat: foo bar: No such file or directory
*** Exception: ExitFailure 1

You can also write ${x} to separate the variable name from adjacent characters.

>>> let x = "b" in [sh| echo a${x}c |]
"abc\n"

Be careful: the automatic escaping means that [sh| cat '$x' |] is less safe than [sh| cat $x |], though it will work "by accident" in common cases.

To interpolate without escaping special characters, use the syntax $+x .

>>> let x = "foo bar" in [sh| cat $+x |]
cat: foo: No such file or directory
cat: bar: No such file or directory
*** Exception: ExitFailure 1

You can pass a literal $ to the shell as \$, or a literal \ as \\.

As demonstrated above, a non-zero exit code from the subprocess will raise an exception in your Haskell program.

Variables of type other than String are interpolated via show.

>>> let x = Just (2 + 2) in [sh| touch $x; ls -l J* |]
"-rw-r--r-- 1 keegan keegan 0 Oct  7 23:28 Just 4\n"

The interpolated variable's type must be an instance of Show and of Typeable.

shc :: QuasiQuoterSource

Execute a shell command, capturing output and exit code.

The expression [shc| ... |] has type IO (ExitCode, String). A non-zero exit code does not raise an exception your the Haskell program.

Otherwise, shc acts like sh.

Helper functions

These functions are used in the implementation of sh, and may be useful on their own.

readShell :: String -> IO StringSource

Execute a shell command, capturing output.

Used in the implementation of sh.

readShellWithCode :: String -> IO (ExitCode, String)Source

Execute a shell command, capturing output and exit code.

Used in the implementation of shc.

showNonString :: (Typeable a, Show a) => a -> StringSource

Acts like the identity function on String, and like show on other types.