turtle-1.3.1: Shell programming, Haskell-style

Safe Haskell | None
Language | Haskell2010

Turtle.Prelude

Contents

- IO
- Managed
- Shell
- Folds
- Text
- Subprocess management
- Permissions
- File size
- File status
- Headers
- Exceptions

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 `Shell`s 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 (suffix "Browser.py") "/usr/lib")
    FilePath "/usr/lib/python3.4/idlelib/ClassBrowser.py"
    FilePath "/usr/lib/python3.4/idlelib/RemoteObjectBrowser.py"
    FilePath "/usr/lib/python3.4/idlelib/PathBrowser.py"
    FilePath "/usr/lib/python3.4/idlelib/ObjectBrowser.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 (suffix "Browser.py") "/usr/lib") Fold.head
    Just (FilePath "/usr/lib/python3.4/idlelib/ClassBrowser.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

Format strings in a type safe way using `format`:

    >>> dir <- pwd
    >>> format ("I am in the "%fp%" directory") dir
    "I am in the /tmp directory"

Commands like `grep`, `sed` and `find` accept arbitrary `Pattern`s

    >>> 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

- echo :: MonadIO io => Line -> io ()
- err :: MonadIO io => Line -> io ()
- readline :: MonadIO io => io (Maybe Line)
- readTextFile :: FilePath -> IO Text
- writeTextFile :: FilePath -> Text -> IO ()
- arguments :: MonadIO io => io [Text]
- export :: MonadIO io => Text -> Text -> io ()
- unset :: MonadIO io => Text -> io ()
- need :: MonadIO io => Text -> io (Maybe Text)
- env :: MonadIO io => io [(Text, Text)]
- cd :: MonadIO io => FilePath -> io ()
- pwd :: MonadIO io => io FilePath
- home :: MonadIO io => io FilePath
- realpath :: MonadIO io => FilePath -> io FilePath
- mv :: MonadIO io => FilePath -> FilePath -> io ()
- mkdir :: MonadIO io => FilePath -> io ()
- mktree :: MonadIO io => FilePath -> io ()
- cp :: MonadIO io => FilePath -> FilePath -> io ()
- rm :: MonadIO io => FilePath -> io ()
- rmdir :: MonadIO io => FilePath -> io ()
- rmtree :: MonadIO io => FilePath -> io ()
- testfile :: MonadIO io => FilePath -> io Bool
- testdir :: MonadIO io => FilePath -> io Bool
- testpath :: MonadIO io => FilePath -> io Bool
- date :: MonadIO io => io UTCTime
- datefile :: MonadIO io => FilePath -> io UTCTime
- touch :: MonadIO io => FilePath -> io ()
- time :: MonadIO io => io a -> io (a, NominalDiffTime)
- hostname :: MonadIO io => io Text
- which :: MonadIO io => FilePath -> io (Maybe FilePath)
- whichAll :: FilePath -> Shell FilePath
- sleep :: MonadIO io => NominalDiffTime -> io ()
- exit :: MonadIO io => ExitCode -> io a
- die :: MonadIO io => Text -> io a
- (.&&.) :: Monad m => m ExitCode -> m ExitCode -> m ExitCode
- (.||.) :: Monad m => m ExitCode -> m ExitCode -> m ExitCode
- readonly :: MonadManaged managed => FilePath -> managed Handle
- writeonly :: MonadManaged managed => FilePath -> managed Handle
- appendonly :: MonadManaged managed => FilePath -> managed Handle
- mktemp :: MonadManaged managed => FilePath -> Text -> managed (FilePath, Handle)
- mktempfile :: MonadManaged managed => FilePath -> Text -> managed FilePath
- mktempdir :: MonadManaged managed => FilePath -> Text -> managed FilePath
- fork :: MonadManaged managed => IO a -> managed (Async a)
- wait :: MonadIO io => Async a -> io a
- pushd :: MonadManaged managed => FilePath -> managed ()
- stdin :: Shell Line
- input :: FilePath -> Shell Line
- inhandle :: Handle -> Shell Line
- stdout :: MonadIO io => Shell Line -> io ()
- output :: MonadIO io => FilePath -> Shell Line -> io ()
- outhandle :: MonadIO io => Handle -> Shell Line -> io ()
- append :: MonadIO io => FilePath -> Shell Line -> io ()
- stderr :: MonadIO io => Shell Line -> io ()
- strict :: MonadIO io => Shell Line -> io Text
- ls :: FilePath -> Shell FilePath
- lsif :: (FilePath -> IO Bool) -> FilePath -> Shell FilePath
- lstree :: FilePath -> Shell FilePath
- cat :: [Shell a] -> Shell a
- grep :: Pattern a -> Shell Line -> Shell Line
- sed :: Pattern Text -> Shell Line -> Shell Line
- onFiles :: (Shell Text -> Shell Text) -> Shell FilePath -> Shell FilePath
- inplace :: MonadIO io => Pattern Text -> FilePath -> io ()
- find :: Pattern a -> FilePath -> Shell FilePath
- yes :: Shell Line
- nl :: Num n => Shell a -> Shell (n, a)
- paste :: Shell a -> Shell b -> Shell (a, b)
- endless :: Shell ()
- limit :: Int -> Shell a -> Shell a
- limitWhile :: (a -> Bool) -> Shell a -> Shell a
- cache :: (Read a, Show a) => FilePath -> Shell a -> Shell a
- parallel :: [IO a] -> Shell a
- countChars :: Integral n => Fold Line n
- countWords :: Integral n => Fold Line n
- countLines :: Integral n => Fold Line n
- cut :: Pattern a -> Text -> [Text]
- proc :: MonadIO io => Text -> [Text] -> Shell Line -> io ExitCode
- shell :: MonadIO io => Text -> Shell Line -> io ExitCode
- system :: MonadIO io => CreateProcess -> Shell Line -> io ExitCode
- procs :: MonadIO io => Text -> [Text] -> Shell Line -> io ()
- shells :: MonadIO io => Text -> Shell Line -> io ()
- inproc :: Text -> [Text] -> Shell Line -> Shell Line
- inshell :: Text -> Shell Line -> Shell Line
- inprocWithErr :: Text -> [Text] -> Shell Line -> Shell (Either Line Line)
- inshellWithErr :: Text -> Shell Line -> Shell (Either Line Line)
- procStrict :: MonadIO io => Text -> [Text] -> Shell Line -> io (ExitCode, Text)
- shellStrict :: MonadIO io => Text -> Shell Line -> io (ExitCode, Text)
- procStrictWithErr :: MonadIO io => Text -> [Text] -> Shell Line -> io (ExitCode, Text, Text)
- shellStrictWithErr :: MonadIO io => Text -> Shell Line -> io (ExitCode, Text, Text)
- data Permissions :: *
- chmod :: MonadIO io => (Permissions -> Permissions) -> FilePath -> io Permissions
- getmod :: MonadIO io => FilePath -> io Permissions
- setmod :: MonadIO io => Permissions -> FilePath -> io ()
- copymod :: MonadIO io => FilePath -> FilePath -> io ()
- readable :: Permissions -> Permissions
- nonreadable :: Permissions -> Permissions
- writable :: Permissions -> Permissions
- nonwritable :: Permissions -> Permissions
- executable :: Permissions -> Permissions
- nonexecutable :: Permissions -> Permissions
- searchable :: Permissions -> Permissions
- nonsearchable :: Permissions -> Permissions
- ooo :: Permissions -> Permissions
- roo :: Permissions -> Permissions
- owo :: Permissions -> Permissions
- oox :: Permissions -> Permissions
- oos :: Permissions -> Permissions
- rwo :: Permissions -> Permissions
- rox :: Permissions -> Permissions
- ros :: Permissions -> Permissions
- owx :: Permissions -> Permissions
- rwx :: Permissions -> Permissions
- rws :: Permissions -> Permissions
- du :: MonadIO io => FilePath -> io Size
- data Size
- sz :: Format r (Size -> r)
- bytes :: Integral n => Size -> n
- kilobytes :: Integral n => Size -> n
- megabytes :: Integral n => Size -> n
- gigabytes :: Integral n => Size -> n
- terabytes :: Integral n => Size -> n
- kibibytes :: Integral n => Size -> n
- mebibytes :: Integral n => Size -> n
- gibibytes :: Integral n => Size -> n
- tebibytes :: Integral n => Size -> n
- data FileStatus :: *
- stat :: MonadIO io => FilePath -> io FileStatus
- lstat :: MonadIO io => FilePath -> io FileStatus
- fileSize :: FileStatus -> Size
- accessTime :: FileStatus -> POSIXTime
- modificationTime :: FileStatus -> POSIXTime
- statusChangeTime :: FileStatus -> POSIXTime
- isBlockDevice :: FileStatus -> Bool
- isCharacterDevice :: FileStatus -> Bool
- isNamedPipe :: FileStatus -> Bool
- isRegularFile :: FileStatus -> Bool
- isDirectory :: FileStatus -> Bool
- isSymbolicLink :: FileStatus -> Bool
- isSocket :: FileStatus -> Bool
- data WithHeader a
  - = Header a
  - | Row a a
- header :: Shell a -> Shell (WithHeader a)
- data ProcFailed = ProcFailed {
  - procCommand :: Text
  - procArguments :: [Text]
  - procExitCode :: ExitCode
  }
- data ShellFailed = ShellFailed {
  - shellCommandLine :: Text
  - shellExitCode :: ExitCode
  }

# IO

echo :: MonadIO io => Line -> io () #

Print exactly one line to `stdout`

To print more than one line see `printf`, which also supports formatted output

err :: MonadIO io => Line -> io () #

Print exactly one line to `stderr`

readline :: MonadIO io => io (Maybe Line) #

Read in a line from `stdin`

Returns `Nothing` if at end of input

readTextFile :: FilePath -> IO Text #

Read in the entire content of a text file.

This computation throws `IOError` on failure. See “Classifying I/O errors” in the System.IO.Error documentation for information on why the failure occured.

writeTextFile :: FilePath -> Text -> IO () #

Replace the entire content of a text file with the provided `Text`.

This computation throws `IOError` on failure. See “Classifying I/O errors” in the System.IO.Error documentation for information on why the failure occured.

arguments :: MonadIO io => io [Text] #

Get command line arguments in a list

export :: MonadIO io => Text -> Text -> io () #

Set or modify an environment variable

unset :: MonadIO io => Text -> io () #

Delete an environment variable

need :: MonadIO io => Text -> io (Maybe Text) #

Look up an environment variable

env :: MonadIO io => io [(Text, Text)] #

Retrieve all environment variables

cd :: MonadIO io => FilePath -> io () #

Change the current directory

pwd :: MonadIO io => io FilePath #

Get the current directory

home :: MonadIO io => io FilePath #

Get the home directory

realpath :: MonadIO io => FilePath -> io FilePath #

Canonicalize a path

mv :: MonadIO io => FilePath -> FilePath -> io () #

Move a file or directory

Works if the two paths are on the same filesystem. If not, `mv` will still work when dealing with a regular file, but the operation will not be atomic

mkdir :: MonadIO io => FilePath -> io () #

Create a directory

Fails if the directory is present

mktree :: MonadIO io => FilePath -> io () #

Create a directory tree (equivalent to `mkdir -p`)

Does not fail if the directory is present

cp :: MonadIO io => FilePath -> FilePath -> io () #

Copy a file

rm :: MonadIO io => FilePath -> io () #

Remove a file

rmdir :: MonadIO io => FilePath -> io () #

Remove a directory

rmtree :: MonadIO io => FilePath -> io () #

Remove a directory tree (equivalent to `rm -r`)

Use at your own risk

testfile :: MonadIO io => FilePath -> io Bool #

Check if a file exists

testdir :: MonadIO io => FilePath -> io Bool #

Check if a directory exists

testpath :: MonadIO io => FilePath -> io Bool #

Check if a path exists

date :: MonadIO io => io UTCTime #

Get the current time

datefile :: MonadIO io => FilePath -> io UTCTime #

Get the time a file was last modified

touch :: MonadIO io => FilePath -> io () #

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

Creates an empty file if it does not exist

time :: MonadIO io => io a -> io (a, NominalDiffTime) #

Time how long a command takes in monotonic wall clock time

Returns the duration alongside the return value

hostname :: MonadIO io => io Text #

Get the system's host name

which :: MonadIO io => FilePath -> io (Maybe FilePath) #

Show the full path of an executable file

whichAll :: FilePath -> Shell FilePath #

Show all matching executables in PATH, not just the first

sleep :: MonadIO io => NominalDiffTime -> io () #

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 :: MonadIO io => ExitCode -> io a #

Exit with the given exit code

An exit code of `0` indicates success

die :: MonadIO io => Text -> io a #

Throw an exception using the provided `Text` message

(.&&.) :: Monad m => m ExitCode -> m ExitCode -> m ExitCode infixr 3 #

Analogous to `&&` in Bash

Runs the second command only if the first one returns `ExitSuccess`

(.||.) :: Monad m => m ExitCode -> m ExitCode -> m ExitCode infixr 2 #

Analogous to `||` in Bash

Run the second command only if the first one returns `ExitFailure`

# Managed

readonly :: MonadManaged managed => FilePath -> managed Handle #

Acquire a `Managed` read-only `Handle` from a `FilePath`

writeonly :: MonadManaged managed => FilePath -> managed Handle #

Acquire a `Managed` write-only `Handle` from a `FilePath`

appendonly :: MonadManaged managed => FilePath -> managed Handle #

Acquire a `Managed` append-only `Handle` from a `FilePath`

mktemp #

Arguments

:: MonadManaged managed |
=> FilePath | Parent directory
-> Text | File name template
-> managed (FilePath, Handle) |

Create a temporary file underneath the given directory

Deletes the temporary file when done

Note that this provides the `Handle` of the file in order to avoid a potential race condition from the file being moved or deleted before you have a chance to open the file. The `mktempfile` function provides a simpler API if you don't need to worry about that possibility.

mktempfile #

Arguments

:: MonadManaged managed |
=> FilePath | Parent directory
-> Text | File name template
-> managed FilePath |

Create a temporary file underneath the given directory

Deletes the temporary file when done

mktempdir #

Arguments

:: MonadManaged managed |
=> FilePath | Parent directory
-> Text | Directory name template
-> managed FilePath |

Create a temporary directory underneath the given directory

Deletes the temporary directory when done

fork :: MonadManaged managed => IO a -> managed (Async a) #

Fork a thread, acquiring an `Async` value

wait :: MonadIO io => Async a -> io a #

Wait for an `Async` action to complete

pushd :: MonadManaged managed => FilePath -> managed () #

Change the current directory. Once the current `Shell` is done, it returns back to the original directory.

    >>> :set -XOverloadedStrings
    >>> cd "/"
    >>> view (pushd "/tmp" >> pwd)
    FilePath "/tmp"
    >>> pwd
    FilePath "/"

# Shell

stdin :: Shell Line #

Read lines of `Text` from standard input

input :: FilePath -> Shell Line #

Read lines of `Text` from a file

inhandle :: Handle -> Shell Line #

Read lines of `Text` from a `Handle`

stdout :: MonadIO io => Shell Line -> io () #

Stream lines of `Text` to standard output

output :: MonadIO io => FilePath -> Shell Line -> io () #

Stream lines of `Text` to a file

outhandle :: MonadIO io => Handle -> Shell Line -> io () #

Stream lines of `Text` to a `Handle`

append :: MonadIO io => FilePath -> Shell Line -> io () #

Stream lines of `Text` to append to a file

stderr :: MonadIO io => Shell Line -> io () #

Stream lines of `Text` to standard error

strict :: MonadIO io => Shell Line -> io Text #

Read in a stream's contents strictly

ls :: FilePath -> Shell FilePath #

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

lsif :: (FilePath -> IO Bool) -> FilePath -> Shell FilePath #

Stream all recursive descendents of the given directory

This skips any directories that fail the supplied predicate

    lstree = lsif (\_ -> return True)

lstree :: FilePath -> Shell FilePath #

Stream all recursive descendents of the given directory

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

Combine the output of multiple `Shell`s, in order

grep :: Pattern a -> Shell Line -> Shell Line #

Keep all lines that match the given `Pattern`

sed :: Pattern Text -> Shell Line -> Shell Line #

Replace all occurrences of a `Pattern` with its `Text` result

`sed` performs substitution on a line-by-line basis, meaning that substitutions may not span multiple lines. Additionally, substitutions may occur multiple times within the same line, like the behavior of `s/.../.../g`.

Warning: Do not use a `Pattern` that matches the empty string, since it will match an infinite number of times. `sed` tries to detect such `Pattern`s and `die` with an error message if they occur, but this detection is necessarily incomplete.

onFiles :: (Shell Text -> Shell Text) -> Shell FilePath -> Shell FilePath #

Make a `Shell Text -> Shell Text` function work on `FilePath`s instead. | Ignores any paths which cannot be decoded as valid `Text`.

inplace :: MonadIO io => Pattern Text -> FilePath -> io () #

Like `sed`, but operates in place on a `FilePath` (analogous to `sed -i`)

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

Search a directory recursively for all files matching the given `Pattern`

yes :: Shell Line #

A Stream of `"y"`s

nl :: Num n => Shell a -> Shell (n, a) #

Number each element of a `Shell` (starting at 0)

paste :: Shell a -> Shell b -> Shell (a, b) #

Merge two `Shell`s together, element-wise

If one `Shell` is longer than the other, the excess elements are truncated

endless :: Shell () #

A `Shell` that endlessly emits `()`

limit :: Int -> Shell a -> Shell a #

Limit a `Shell` to a fixed number of values

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

Limit a `Shell` to values that satisfy the predicate

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

cache :: (Read a, Show a) => FilePath -> Shell a -> Shell a #

Cache a `Shell`'s output so that repeated runs of the script will reuse the result of previous runs. You must supply a `FilePath` where the cached result will be stored.

The stored result is only reused if the `Shell` successfully ran to completion without any exceptions. Note: on some platforms Ctrl-C will flush standard input and signal end of file before killing the program, which may trick the program into "successfully" completing.

parallel :: [IO a] -> Shell a #

Run a list of IO actions in parallel using fork and wait.

    >>> view (parallel [(sleep 3) >> date, date, date])
    2016-12-01 17:22:10.83296 UTC
    2016-12-01 17:22:07.829876 UTC
    2016-12-01 17:22:07.829963 UTC

# Folds

countChars :: Integral n => Fold Line n #

Count the number of characters in the stream (like `wc -c`)

This uses the convention that the elements of the stream are implicitly ended by newlines that are one character wide

countWords :: Integral n => Fold Line n #

Count the number of words in the stream (like `wc -w`)

countLines :: Integral n => Fold Line n #

Count the number of lines in the stream (like `wc -l`)

This uses the convention that each element of the stream represents one line

# Text

cut :: Pattern a -> Text -> [Text] #

Split a line into chunks delimited by the given `Pattern`

# Subprocess management

proc #

Arguments

:: MonadIO io |
=> Text | Command
-> [Text] | Arguments
-> Shell Line | 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 #

Arguments

:: MonadIO io |
=> Text | Command line
-> Shell Line | 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

system #

Arguments

:: MonadIO io |
=> CreateProcess | Command
-> Shell Line | Lines of standard input
-> io ExitCode | Exit code

`system` generalizes `shell` and `proc` by allowing you to supply your own custom `CreateProcess`. This is for advanced users who feel comfortable using the lower-level `process` API

procs #

Arguments

:: MonadIO io |
=> Text | Command
-> [Text] | Arguments
-> Shell Line | Lines of standard input
-> io () |

This function is identical to `proc` except this throws `ProcFailed` for non-zero exit codes

shells #

Arguments

:: MonadIO io |
=> Text | Command line
-> Shell Line | Lines of standard input
-> io () | Exit code

This function is identical to `shell` except this throws `ShellFailed` for non-zero exit codes

inproc #

Arguments

:: Text | Command
-> [Text] | Arguments
-> Shell Line | Lines of standard input
-> Shell Line | Lines of standard output

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

The command inherits `stderr` for the current process

inshell #

Arguments

:: Text | Command line
-> Shell Line | Lines of standard input
-> Shell Line | 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

inprocWithErr #

Arguments

:: Text | Command
-> [Text] | Arguments
-> Shell Line | Lines of standard input
-> Shell (Either Line Line) | Lines of either standard output (`Right`) or standard error (`Left`)

Run a command using the shell, streaming `stdout` and `stderr` as lines of `Text`. Lines from `stdout` are wrapped in `Right` and lines from `stderr` are wrapped in `Left`. This does not throw an exception if the command returns a non-zero exit code

inshellWithErr #

Arguments

:: Text | Command line
-> Shell Line | Lines of standard input
-> Shell (Either Line Line) | Lines of either standard output (`Right`) or standard error (`Left`)

Run a command line using the shell, streaming `stdout` and `stderr` as lines of `Text`. Lines from `stdout` are wrapped in `Right` and lines from `stderr` are wrapped in `Left`. This does not throw an exception if the command returns a non-zero exit code

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

procStrict #

Arguments

:: MonadIO io |
=> Text | Command
-> [Text] | Arguments
-> Shell Line | Lines of standard input
-> io (ExitCode, Text) | Exit code and stdout

Run a command using `execvp`, retrieving the exit code and stdout as a non-lazy blob of Text

The command inherits `stderr` for the current process

shellStrict #

Arguments

:: MonadIO io |
=> Text | Command line
-> Shell Line | Lines of standard input
-> io (ExitCode, Text) | Exit code and stdout

Run a command line using the shell, retrieving the exit code and stdout as a non-lazy blob of Text

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 `stderr` for the current process

procStrictWithErr #

Arguments

:: MonadIO io |
=> Text | Command
-> [Text] | Arguments
-> Shell Line | Lines of standard input
-> io (ExitCode, Text, Text) | (Exit code, stdout, stderr)

Run a command using `execvp`, retrieving the exit code, stdout, and stderr as a non-lazy blob of Text

shellStrictWithErr #

Arguments

:: MonadIO io |
=> Text | Command line
-> Shell Line | Lines of standard input
-> io (ExitCode, Text, Text) | (Exit code, stdout, stderr)

Run a command line using the shell, retrieving the exit code, stdout, and stderr as a non-lazy blob of Text

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

# Permissions

data Permissions :: * #

Instances

Eq Permissions |
Methods (==) :: Permissions -> Permissions -> Bool # (/=) :: Permissions -> Permissions -> Bool #
Ord Permissions |
Methods compare :: Permissions -> Permissions -> Ordering # (<) :: Permissions -> Permissions -> Bool # (<=) :: Permissions -> Permissions -> Bool # (>) :: Permissions -> Permissions -> Bool # (>=) :: Permissions -> Permissions -> Bool # max :: Permissions -> Permissions -> Permissions # min :: Permissions -> Permissions -> Permissions #
Read Permissions |
Methods readsPrec :: Int -> ReadS Permissions # readList :: ReadS [Permissions] # readPrec :: ReadPrec Permissions # readListPrec :: ReadPrec [Permissions] #
Show Permissions |
Methods showsPrec :: Int -> Permissions -> ShowS # show :: Permissions -> String # showList :: [Permissions] -> ShowS #

chmod #

Arguments

:: MonadIO io |
=> (Permissions -> Permissions) | Permissions update function
-> FilePath | Path
-> io Permissions | Updated permissions

Update a file or directory's user permissions

    chmod rwo        "foo.txt"  -- chmod u=rw foo.txt
    chmod executable "foo.txt"  -- chmod u+x foo.txt
    chmod nonwritable "foo.txt" -- chmod u-w foo.txt

getmod :: MonadIO io => FilePath -> io Permissions #

Get a file or directory's user permissions

setmod :: MonadIO io => Permissions -> FilePath -> io () #

Set a file or directory's user permissions

copymod :: MonadIO io => FilePath -> FilePath -> io () #

Copy a file or directory's permissions (analogous to `chmod --reference`)

readable :: Permissions -> Permissions #

    +r

nonreadable :: Permissions -> Permissions #

    -r

writable :: Permissions -> Permissions #

    +w

nonwritable :: Permissions -> Permissions #

    -w

executable :: Permissions -> Permissions #

    +x

nonexecutable :: Permissions -> Permissions #

    -x

searchable :: Permissions -> Permissions #

    +s

nonsearchable :: Permissions -> Permissions #

    -s

ooo :: Permissions -> Permissions #

    -r -w -x

roo :: Permissions -> Permissions #

    +r -w -x

owo :: Permissions -> Permissions #

    -r +w -x

oox :: Permissions -> Permissions #

    -r -w +x

oos :: Permissions -> Permissions #

    -r -w +s

rwo :: Permissions -> Permissions #

    +r +w -x

rox :: Permissions -> Permissions #

    +r -w +x

ros :: Permissions -> Permissions #

    +r -w +s

owx :: Permissions -> Permissions #

    -r +w +x

rwx :: Permissions -> Permissions #

    +r +w +x

rws :: Permissions -> Permissions #

    +r +w +s

# File size

du :: MonadIO io => FilePath -> io Size #

Get the size of a file or a directory

data Size #

An abstract file size

Specify the units you want by using an accessor like `kilobytes`

The `Num` instance for `Size` interprets numeric literals as bytes

Instances

Eq Size # |
Methods (==) :: Size -> Size -> Bool # (/=) :: Size -> Size -> Bool #
Num Size # |
Methods (+) :: Size -> Size -> Size # (-) :: Size -> Size -> Size # (*) :: Size -> Size -> Size # negate :: Size -> Size # abs :: Size -> Size # signum :: Size -> Size # fromInteger :: Integer -> Size #
Ord Size # |
Methods compare :: Size -> Size -> Ordering # (<) :: Size -> Size -> Bool # (<=) :: Size -> Size -> Bool # (>) :: Size -> Size -> Bool # (>=) :: Size -> Size -> Bool # max :: Size -> Size -> Size # min :: Size -> Size -> Size #
Show Size # |
Methods showsPrec :: Int -> Size -> ShowS # show :: Size -> String # showList :: [Size] -> ShowS #

sz :: Format r (Size -> r) #

`Format` a `Size` using a human readable representation

    >>> format sz 42
    "42 B"
    >>> format sz 2309
    "2.309 KB"
    >>> format sz 949203
    "949.203 KB"
    >>> format sz 1600000000
    "1.600 GB"
    >>> format sz 999999999999999999
    "999999.999 TB"

bytes :: Integral n => Size -> n #

Extract a size in bytes

kilobytes :: Integral n => Size -> n #

    1 kilobyte = 1000 bytes

megabytes :: Integral n => Size -> n #

    1 megabyte = 1000 kilobytes

gigabytes :: Integral n => Size -> n #

    1 gigabyte = 1000 megabytes

terabytes :: Integral n => Size -> n #

    1 terabyte = 1000 gigabytes

kibibytes :: Integral n => Size -> n #

    1 kibibyte = 1024 bytes

mebibytes :: Integral n => Size -> n #

    1 mebibyte = 1024 kibibytes

gibibytes :: Integral n => Size -> n #

    1 gibibyte = 1024 mebibytes

tebibytes :: Integral n => Size -> n #

    1 tebibyte = 1024 gibibytes

# File status

data FileStatus :: * #

POSIX defines operations to get information, such as owner, permissions, size and access times, about a file. This information is represented by the `FileStatus` type.

Note: see `chmod`.

stat :: MonadIO io => FilePath -> io FileStatus #

Get the status of a file

lstat :: MonadIO io => FilePath -> io FileStatus #

Get the status of a file, but don't follow symbolic links

fileSize :: FileStatus -> Size #

Size of the file in bytes. Does not follow symlinks

accessTime :: FileStatus -> POSIXTime #

Time of last access

modificationTime :: FileStatus -> POSIXTime #

Time of last modification

statusChangeTime :: FileStatus -> POSIXTime #

Time of last status change (i.e. owner, group, link count, mode, etc.)

isBlockDevice :: FileStatus -> Bool #

Checks if this file is a block device.

isCharacterDevice :: FileStatus -> Bool #

Checks if this file is a character device.

isNamedPipe :: FileStatus -> Bool #

Checks if this file is a named pipe device.

isRegularFile :: FileStatus -> Bool #

Checks if this file is a regular file device.

isDirectory :: FileStatus -> Bool #

Checks if this file is a directory device.

isSymbolicLink :: FileStatus -> Bool #

Checks if this file is a symbolic link device.

isSocket :: FileStatus -> Bool #

Checks if this file is a socket device.

# Headers

data WithHeader a #

Constructors

Header a | The first line with the header
Row a a | Every other line: 1st element is header, 2nd element is original row

Instances

Show a => Show (WithHeader a) # |
Methods showsPrec :: Int -> WithHeader a -> ShowS # show :: WithHeader a -> String # showList :: [WithHeader a] -> ShowS #

header :: Shell a -> Shell (WithHeader a) #

# Exceptions

data ProcFailed #

Constructors

ProcFailed |
Fields procCommand :: Text procArguments :: [Text] procExitCode :: ExitCode

Instances

Show ProcFailed # |
Methods showsPrec :: Int -> ProcFailed -> ShowS # show :: ProcFailed -> String # showList :: [ProcFailed] -> ShowS #
Exception ProcFailed # |
Methods toException :: ProcFailed -> SomeException # fromException :: SomeException -> Maybe ProcFailed # displayException :: ProcFailed -> String #

data ShellFailed #

Constructors

ShellFailed |
Fields shellCommandLine :: Text shellExitCode :: ExitCode

Instances

Show ShellFailed # |
Methods showsPrec :: Int -> ShellFailed -> ShowS # show :: ShellFailed -> String # showList :: [ShellFailed] -> ShowS #
Exception ShellFailed # |
Methods toException :: ShellFailed -> SomeException # fromException :: SomeException -> Maybe ShellFailed # displayException :: ShellFailed -> String #