turtle-1.1.0: Shell programming, Haskell-style

Safe HaskellNone
LanguageHaskell2010

Turtle.Prelude

Contents

Description

This module provides a large suite of utilities that resemble Unix utilities.

Many of these commands are just existing Haskell commands renamed to match their Unix counterparts:

>>> :set -XOverloadedStrings
>>> cd "/tmp"
>>> pwd
FilePath "/tmp"

Some commands are Shells that emit streams of values. view prints all values in a Shell stream:

>>> view (ls "/usr")
FilePath "/usr/lib"
FilePath "/usr/src"
FilePath "/usr/sbin"
FilePath "/usr/include"
FilePath "/usr/share"
FilePath "/usr/games"
FilePath "/usr/local"
FilePath "/usr/bin"
>>> view (find "Browser.py" "/usr/lib")
FilePath "lib/python3.2/idlelib/ObjectBrowser.py"
FilePath "lib/python3.2/idlelib/PathBrowser.py"
FilePath "lib/python3.2/idlelib/RemoteObjectBrowser.py"
FilePath "lib/python3.2/idlelib/ClassBrowser.py"

Use fold to reduce the output of a Shell stream:

>>> import qualified Control.Foldl as Fold
>>> fold (ls "/usr") Fold.length
8
>>> fold (find "Browser.py" "/usr/lib") Fold.head
Just (FilePath "/usr/lib/python3.2/idlelib/ObjectBrowser.py")

Create files using output:

>>> output "foo.txt" ("123" <|> "456" <|> "ABC")
>>> realpath "foo.txt"
FilePath "/tmp/foo.txt"

Read in files using input:

>>> stdout (input "foo.txt")
123
456
ABC

Commands like grep, sed and find accept arbitrary Patterns

>>> stdout (grep ("123" <|> "ABC") (input "foo.txt"))
123
ABC
>>> let exclaim = fmap (<> "!") (plus digit)
>>> stdout (sed exclaim (input "foo.txt"))
123!
456!
ABC

Note that grep and find differ from their Unix counterparts by requiring that the Pattern matches the entire line or file name by default. However, you can optionally match the prefix, suffix, or interior of a line:

>>> stdout (grep (has    "2") (input "foo.txt"))
123
>>> stdout (grep (prefix "1") (input "foo.txt"))
123
>>> stdout (grep (suffix "3") (input "foo.txt"))
123

You can also build up more sophisticated Shell programs using sh in conjunction with do notation:

{-# LANGUAGE OverloadedStrings #-}

import Turtle

main = sh example

example = do
    -- Read in file names from "files1.txt" and "files2.txt"
    file <- fmap fromText (input "files1.txt" <|> input "files2.txt")

    -- Stream each file to standard output only if the file exists
    True <- liftIO (testfile file)
    line <- input file
    liftIO (echo line)

See Turtle.Tutorial for an extended tutorial explaining how to use this library in greater detail.

Synopsis

IO

proc Source

Arguments

:: Text

Command

-> [Text]

Arguments

-> Shell Text

Lines of standard input

-> IO ExitCode

Exit code

Run a command using execvp, retrieving the exit code

The command inherits stdout and stderr for the current process

shell Source

Arguments

:: Text

Command line

-> Shell Text

Lines of standard input

-> IO ExitCode

Exit code

Run a command line using the shell, retrieving the exit code

This command is more powerful than proc, but highly vulnerable to code injection if you template the command line with untrusted input

The command inherits stdout and stderr for the current process

echo :: Text -> IO () Source

Print to stdout

err :: Text -> IO () Source

Print to stderr

readline :: IO (Maybe Text) Source

Read in a line from stdin

Returns Nothing if at end of input

export :: Text -> Text -> IO () Source

Set or modify an environment variable

unset :: Text -> IO () Source

Delete an environment variable

need :: Text -> IO (Maybe Text) Source

Look up an environment variable

env :: IO [(Text, Text)] Source

Retrieve all environment variables

cd :: FilePath -> IO () Source

Change the current directory

pwd :: IO FilePath Source

Get the current directory

home :: IO FilePath Source

Get the home directory

realpath :: FilePath -> IO FilePath Source

Canonicalize a path

mv :: FilePath -> FilePath -> IO () Source

Move a file or directory

mkdir :: FilePath -> IO () Source

Create a directory

Fails if the directory is present

mktree :: FilePath -> IO () Source

Create a directory tree (equivalent to mkdir -p)

Does not fail if the directory is present

cp :: FilePath -> FilePath -> IO () Source

Copy a file

rm :: FilePath -> IO () Source

Remove a file

rmdir :: FilePath -> IO () Source

Remove a directory

rmtree :: FilePath -> IO () Source

Remove a directory tree (equivalent to rm -r)

Use at your own risk

du :: FilePath -> IO Integer Source

Get a file or directory's size

testfile :: FilePath -> IO Bool Source

Check if a file exists

testdir :: FilePath -> IO Bool Source

Check if a directory exists

date :: IO UTCTime Source

Get the current time

datefile :: FilePath -> IO UTCTime Source

Get the time a file was last modified

touch :: FilePath -> IO () Source

Touch a file, updating the access and modification times to the current time

Creates an empty file if it does not exist

time :: IO a -> IO (a, NominalDiffTime) Source

Time how long a command takes in monotonic wall clock time

Returns the duration alongside the return value

sleep :: NominalDiffTime -> IO () Source

Sleep for the given duration

A numeric literal argument is interpreted as seconds. In other words, (sleep 2.0) will sleep for two seconds.

exit :: ExitCode -> IO a Source

Exit with the given exit code

An exit code of 0 indicates success

die :: Text -> IO a Source

Throw an exception using the provided Text message

(.&&.) :: IO ExitCode -> IO ExitCode -> IO ExitCode infixr 2 Source

Analogous to && in Bash

Runs the second command only if the first one returns ExitSuccess

(.||.) :: IO ExitCode -> IO ExitCode -> IO ExitCode infixr 2 Source

Analogous to || in Bash

Run the second command only if the first one returns ExitFailure

Managed

readonly :: FilePath -> Managed Handle Source

Acquire a Managed read-only Handle from a FilePath

writeonly :: FilePath -> Managed Handle Source

Acquire a Managed write-only Handle from a FilePath

appendonly :: FilePath -> Managed Handle Source

Acquire a Managed append-only Handle from a FilePath

mktemp Source

Arguments

:: FilePath

Parent directory

-> Text

File name template

-> Managed (FilePath, Handle) 

Create a temporary file underneath the given directory

Deletes the temporary file when done

mktempdir Source

Arguments

:: FilePath

Parent directory

-> Text

Directory name template

-> Managed FilePath 

Create a temporary directory underneath the given directory

Deletes the temporary directory when done

fork :: IO a -> Managed (Async a) Source

Fork a thread, acquiring an Async value

wait :: Async a -> IO a

Wait for an asynchronous action to complete, and return its value. If the asynchronous action threw an exception, then the exception is re-thrown by wait.

wait = atomically . waitSTM

Shell

inproc Source

Arguments

:: Text

Command

-> [Text]

Arguments

-> Shell Text

Lines of standard input

-> Shell Text

Lines of standard output

Run a command using execvp, streaming stdout as lines of Text

The command inherits stderr for the current process

inshell Source

Arguments

:: Text

Command line

-> Shell Text

Lines of standard input

-> Shell Text

Lines of standard output

Run a command line using the shell, streaming stdout as lines of Text

This command is more powerful than inproc, but highly vulnerable to code injection if you template the command line with untrusted input

The command inherits stderr for the current process

stdin :: Shell Text Source

Read lines of Text from standard input

input :: FilePath -> Shell Text Source

Read lines of Text from a file

inhandle :: Handle -> Shell Text Source

Read lines of Text from a Handle

stdout :: Shell Text -> IO () Source

Stream lines of Text to standard output

stderr :: Shell Text -> IO () Source

Stream lines of Text to standard error

output :: FilePath -> Shell Text -> IO () Source

Stream lines of Text to a file

append :: FilePath -> Shell Text -> IO () Source

Stream lines of Text to append to a file

strict :: Shell Text -> IO Text Source

Read in a stream's contents strictly

ls :: FilePath -> Shell FilePath Source

Stream all immediate children of the given directory, excluding "." and ".."

lstree :: FilePath -> Shell FilePath Source

Stream all recursive descendents of the given directory

cat :: [Shell a] -> Shell a Source

Combine the output of multiple Shells, in order

grep :: Pattern a -> Shell Text -> Shell Text Source

Keep all lines that match the given Pattern

sed :: Pattern Text -> Shell Text -> Shell Text Source

Replace all occurrences of a Pattern with its Text result

Warning: Do not use a Pattern that matches the empty string, since it will match an infinite number of times

find :: Pattern a -> FilePath -> Shell FilePath Source

Search a directory recursively for all files matching the given Pattern

yes :: Shell Text Source

A Stream of "y"s

limit :: Int -> Shell a -> Shell a Source

Limit a Shell to a fixed number of values

limitWhile :: (a -> Bool) -> Shell a -> Shell a Source

Limit a Shell to values that satisfy the predicate

This terminates the stream on the first value that does not satisfy the predicate