hsshellscript-3.3.1: Haskell for Unix shell scripting tasks

Safe HaskellNone

HsShellScript.Commands

Synopsis

Documentation

realpathSource

Arguments

:: String

path

-> IO String

noramlized, absolute path, with symbolic links expanded

Do a call to the realpath(3) system library function. This makes the path absolute, normalizes it and expands all symbolic links. In case of an error, an IOError is thrown.

readlinkSource

Arguments

:: String

Path of the symbolic link

-> IO String

The link target - where the symbolic link points to

Determine the target of a symbolic link. This uses the readlink(2) system call. The result is a path which is either absolute, or relative to the directory which the symlink is in. In case of an error, an IOError is thrown. The path is included and can be accessed with IO.ioeGetFileName. Note that, if the path to the symlink ends with a slash, this path denotes the directory pointed to, not the symlink. In this case the call to will fail because of "Invalid argument".

readlink'Source

Arguments

:: String

path of the symbolic link

-> IO String

target; where the symbolic link points to

Determine the target of a symbolic link. This uses the readlink(2) system call. The target is converted, such that it is relative to the current working directory, if it isn't absolute. Note that, if the path to the symlink ends with a slash, this path denotes the directory pointed to, not the symlink. In this case the call to readlink will fail with an IOError because of "Invalid argument". In case of any error, a proper IOError is thrown.

is_symlinkSource

Arguments

:: String

path

-> IO Bool

Whether the path is a symbolic link.

Determine whether a path is a symbolic link. The result for a dangling symlink is True. The path must exist in the file system. In case of an error, a proper IOError is thrown.

realpath_sSource

Arguments

:: String

path

-> IO String

noramlized, absolute path, with symbolic links not expanded

Return the normalised, absolute version of a specified path. The path is made absolute with the current working directory, and is syntactically normalised afterwards. This is the same as what the realpath program reports with the -s option. It's almost the same as what it reports when called from a shell. The difference lies in the shell's idea of the current working directory. See cd for details.

See cd, normalise_path.

symlinkSource

Arguments

:: String

contents of the symlink (from)

-> String

path of the symlink (to)

-> IO () 

Make a symbolic link. This is the symlink(2) function. Any error results in an IOError thrown. The path of the intended symlink is included in the IOError and can be accessed with ioeGetFileName from the Haskell standard library IO.

duSource

Arguments

:: (Integral int, Read int, Show int) 
=> int

block size, this is the --block-size option.

-> String

path of the file or directory to determine the size of

-> IO int

size in blocks

Call the du program. See du(1).

mkdirSource

Arguments

:: String

path

-> IO () 

Create directory. This is a shorthand to System.Directory.createDirectory from the Haskell standard library. In case of an error, the path is included in the IOError, which GHC's implementation neglects to do.

rmdirSource

Arguments

:: String

path

-> IO () 

Remove directory. This is Directory.removeDirectory from the Haskell standard library. In case of an error, the path is included in the IOError, which GHC's implementation neglects to do.

rmSource

Arguments

:: String

path

-> IO () 

Remove file. This is Directory.removeFile from the Haskell standard library, which is a direct frontend to the unlink(2) system call in GHC.

cdSource

Arguments

:: String

path

-> IO () 

Change directory. This is an alias for Directory.setCurrentDirectory from the Haskell standard library. In case of an error, the path is included in the IOError, which GHC's implementation neglects to do.

Note that this command is subtly different from the shell's cd command. It changes the process' working directory. This is always a realpath. Symlinks are expanded. The shell, on the other hand, keeps track of the current working directory separately, in a different way: symlinks are not expanded. The shell's idea of the working directory is different from the working directory which a process has.

This means that the same sequence of cd commands, when done in a real shell script, will lead into the same directory. But the working directory as reported by the shell's pwd command may differ from the corresponding one, reported by getCurrentDirectory.

(When talking about the "shell", I'm talking about bash, regardless of whether started as /bin/bash or in compatibility mode, as /bin/sh. I presume it's the standard behavior for the POSIX standard shell.)

See pwd.

pwd :: IO StringSource

Get program start working directory. This is the PWD environent variable, which is kept by the shell (bash, at least). It records the directory path in which the program has been started. Symbolic links in this path aren't expanded. In this way, it differs from getCurrentDirectory from the Haskell standard library.

chmodSource

Arguments

:: [String]

Command line arguments

-> IO () 

Execute /bin/chmod

chmod = run "/bin/chmod"

chownSource

Arguments

:: [String]

Command line arguments

-> IO () 

Execute /bin/chown

chown = run "/bin/chown"

cpSource

Arguments

:: String

source

-> String

destination

-> IO () 

Execute the cp program

mvSource

Arguments

:: String

source

-> String

destination

-> IO () 

Execute the mv program

mt_statusSource

Arguments

:: IO (Int, Int)

file and block number

Run the command mt status for querying the tape drive status, and parse its output.

renameSource

Arguments

:: String

Old path

-> String

New path

-> IO () 

The rename(2) system call to rename and/or move a file. The renameFile action from the Haskell standard library doesn't do it, because the two paths may not refer to directories. Failure results in an IOError thrown. The new path is included in the IOError and can be accessed with IO.ioeGetFileName.

rename_mvSource

Arguments

:: FilePath

Old path

-> FilePath

New path

-> IO () 

Rename a file. This first tries rename, which is most efficient. If it fails, because source and target path point to different file systems (as indicated by the errno value EXDEV), then /bin/mv is called.

See rename, mv.

force_renameSource

Arguments

:: String

Old path

-> String

New path

-> IO () 

Rename a file or directory, and cope with read only issues.

This renames a file or directory, using rename, sets the necessary write permissions beforehand, and restores them afterwards. This is more efficient than force_mv, because no external program needs to be called, but it can rename files only inside the same file system. See force_cmd for a detailed description.

The new path may be an existing directory. In this case, it is assumed that the old file is to be moved into this directory (like with mv). The new path is then completed with the file name component of the old path. You won't get an "already exists" error.

force_rename = force_cmd rename

See force_cmd, rename.

force_mvSource

Arguments

:: String

Old path

-> String

New path or target directory

-> IO () 

Move a file or directory, and cope with read only issues.

This moves a file or directory, using the external command mv, sets the necessary write permissions beforehand, and restores them afterwards. This is less efficient than force_rename, because the external program mv needs to be called, but it can move files between file systems. See force_cmd for a detailed description.

force_mv src tgt = fill_in_location "force_mv" $ force_cmd (\src tgt -> run "/bin/mv" ["--", src, tgt]) src tgt

See force_cmd, force_mv.

force_rename_mvSource

Arguments

:: FilePath

Old path

-> FilePath

New path

-> IO () 

Rename a file with rename, or when necessary with mv, and cope with read only issues.

The necessary write permissions are set, then the file is renamed, then the permissions are restored.

First, the rename system call is tried, which is most efficient. If it fails, because source and target path point to different file systems (as indicated by the errno value EXDEV), then /bin/mv is called.

force_rename_mv old new = fill_in_location "force_rename_mv" $ force_cmd rename_mv old new

See rename_mv, rename, mv, force_cmd.

force_cmdSource

Arguments

:: (String -> String -> IO ())

Command to execute after preparing the permissions

-> String

Old path

-> String

New path or target directory

-> IO () 

Call a command which moves a file or directory, and cope with read only issues.

This function is for calling a command, which renames files. Beforehand, write permissions are set in order to enable the operation, and afterwards the permissions are restored. The command is meant to be something like rename or run "/bin/mv".

In order to change the name of a file or dirctory, but leave it in the super directory it is in, the super directory must be writeable. In order to move a file or directory to a different super directory, both super directories and the file/directory to be moved must be writeable. I don't know what this behaviour is supposed to be good for.

This function copes with the case that the file/directory to be moved or renamed, or the super directories are read only. It makes the necessary places writeable, calls the command, and makes them read only again, if they were before. The user needs the necessary permissions for changing the corresponding write permissions. If an error occurs (such as file not found, or insufficient permissions), then the write permissions are restored to the state before, before the exception is passed through to the caller.

The command must take two arguments, the old path and the new path. It is expected to create the new path in the file system, such that the correct write permissions of the new path can be set by force_cmd after executing it.

The new path may be an existing directory. In this case, it is assumed that the old file is to be moved into this directory (like with mv). The new path is completed with the file name component of the old path, before it is passed to the command, such that the command is supplied the complete new path.

Examples:

force_cmd rename from to
force_cmd (\from to -> run "/bin/mv" ["-i", "-v", "--", from, to]) from to

See force_rename, force_mv, rename.

force_writeableSource

Arguments

:: String

File or directory to make writeable

-> IO a

Action to perform

-> IO a

Returns the return value of the action

Make a file or directory writeable for the user, perform an action, and restore its writeable status. An IOError is raised when the user doesn't have permission to make the file or directory writeable.

force_writeable path io = force_writeable2 path (io >>= \res -> return (path, res))

Example:

-- Need to create a new directory in /foo/bar, even if that's write protected
force_writeable "/foo/bar" $ mkdir "/foo/bar/baz"

See force_cmd, force_writeable2.

force_writeable2Source

Arguments

:: String

File or directory to make writeable

-> IO (String, a)

Action to perform

-> IO a 

Make a file or directory writeable for the user, perform an action, and restore its writeable status. The action may change the name of the file or directory. Therefore it returns the new name, along with another return value, which is passed to the caller.

The writeable status is only changed back if it has been changed by force_writeable2 before. An IOError is raised when the user doesn'h have permission to make the file or directory writeable, or when the new path doesn't exist.

See force_cmd, force_writeable.

fdupesSource

Arguments

:: [String]

Options for the fdupes program

-> [String]

Directories with files to compare

-> IO [[[String]]]

For each set of identical files, and each of the specified directories, the paths of the identical files in this directory.

Call the fdupes program in order to find identical files. It outputs a list of groups of file names, such that the files in each group are identical. Each of these groups is further analysed by the fdupes action. It is split to a list of lists of paths, such that each list of paths corresponds to one of the directories which have been searched by the fdupes program. If you just want groups of identical files, then apply map concat to the result.

The fdupes /program doesn't handle multiple occurences of the same directory, or in recursive mode one specified directory containing another, properly. The same file may get reported multiple times, and identical files may not get reported./

The paths are normalised (using normalise_path).