HsShellScript – Haskell for Unix Shell Scripting Tasks
This is the homepage of the HsShellScript library. It allows to
use the Haskell language for tasks which are usually done by shell
- Command Line Arguments Parser
HsShellScript has facilities for managing command line arguments,
which are easier to use than the GHC library GetOpt. Command line
arguments are specified as lists of properties. HsShellScript builds
on top of GHC's GetOpt, but hides it completely. Command line
arguments handling has been added because GetOpt seemed too
Easy Interface to External Programs
Calling programs and recognizing errors (via exitcode or exception)
is made more easy. There are front end functions for common
programs, such as /bin/mv or /bin/chmod.
Dealing with paths is not as trivial as it sounds. Take, for example
../foo.bar//./../baz/ (and split off the extension of the
file name...). HsShellScript solves this thoroughly and provides
functions for such tasks as splitting a path in directory and file
name parts, splitting a path into path components, or syntactically
Redirecting Input and Output
HsShellScript defines operators like ->- and ->>-
which work like redirection operators in shells.
Reading the output of an external program, or piping the output of
one program into the input of another, is almost as easy as in
shells. HsShellScript provides corresponding operators.
Error handling is one thing which is done more thoroughly in
HsShellScript than in shells. Failed programs won't be silently
ignored. Exceptions are used for error handling. Non zero
exit codes get thrown in the form of expressive RunError exceptions.
- Quoting of Strings and Building Commands for Shells
- Taking care of shell metacharacters usually isn't done right. HsShellScript provides functions for doing it
- Non-broken, Secure Functions for Creating Temporary Files and Directories
The standard C library has mkstemp, mktemp, tempnam, tmpfile and tmpnam, which are all broken,
non-portable or unsuitable in some way.
HsShellScript is mature, documented and maintained. Most parts have been
tested in use by me since 2004. During that time, changes have mostly been
bug fixes and quality improvements, as well as portings to new GHC versions
(necessary because of incompatible changes). It should be pretty stable.
However, GHC is a moving target. Over time, there have been a lot of big
changes, This always are error sources.
The current version of HsShellScript is 3.5.0. It is tested with GHC-8.6.5, and
should also work with newer versions. Because of incompatible
changes in GHC, it does not work with GHC-7.6 and older.
HsShellScript has been uploaded
This means that you can easily install it, with the command
cabal install hsshellscript. However, then you won't get the (outdated) user
manual. You can also install it using the source package below. Of course, you can always
read the manual online, see "Documentation", below.
- 3.5.0 (released 2021-01-10)
- Small documentation improvement for the glob function.
- Added shared library version of HsShellScript, for dynamic linking.
- Updated to Cabal version 2.0
- 3.4.5 (released 2017-12-04)
- Fixed a little bug in make_usage_info / print_usage_info, which slipped my attention.
- 3.4.4 (released 2017-12-03)
- Fixed a bug in make_usage_info / print_usage_info
- Fixed a documentation bug in the argument parser example
- 3.4.3 (released 2017-12-03)
- Fixed a bug, which caused child not to flush stdout and stderr.
- 3.4.2 (released 2017-11-30)
- Fixed missing documentation for terminal_width and terminal_width_ioe
- Made ArgumentDescription non-abstract.
- Made the pretty printing of the command line arguments prettier. See print_usage_info.
- Some documentation improvements.
- 3.4.1 (released 2017-04-15)
- Fixed a bug which wont't let you link HsShellScript.
- 3.4.0 (released 2017-04-05)
- Improved usage message generation. See make_usage_message / print_usage_message.
- Documentation improvements
- Added glob_quote
- 3.3.4 (released 2015-11-16)
- Small documentation improvements.
- Fixed the bug of _exit not being in scope.
- 3.3.3 (released 2015-01-20)
- Fixed some incompatible changes of the Haskell libraries.
- 3.3.2 (released 2014-08-06)
- Ported to GHC version 7.8.3. It won't compile on to GHC
versions 7.6 and older. (Don't know about GHC 7.7).
- 3.3.1 (released 2012-09-30)
- Fixed bug in conjunction with text/binary mode of pipes and redirects.
- 3.3.0 (released 2012-09-30)
- Changed the mode of the handles used in pipes and redirects
from binary to text. Strictly speaking, under obscure
circumstances, this is
an incompatible change. But most of the time this will fix,
not cause bugs. Most likely, the binary mode should be regard a
- Added documentation.
- 3.2.0 (released 2012-08-28)
- Fixed a bug in the error reporting, in case a child process goes
wrong. Now prints the RunError instead of a general exception.
- Added a lot of documentation.
- Fixed a bug in lazy_pipe_from2.
- 3.1.0 (released 2012-04-02)
- Small Makefile improvements
- No longer using the haskell98 package, which in can't be
used in conjunction with the base package any longer.
- IOError has moved to a different module.
- Adapted to changed module names.
- 3.0.0 (released 2012-03-12)
- Ported to GHC version 7.0.4.
- 2.8.0 (released 2010-01-29)
- Exposed ArgumentDescription's structure to the user
and added an Ord instance declaration.
- Added system_runprog.
- Ported to GHC 6.10's new exception handling library. The old
exception handling scheme can no longer be used, since GHC's new
scheme isn't downwards compatible.
- The module HsShellSctipt in HsShellScript 2.7.1 and
earlier imported and
re-exported a lot of things from three system libraries.
These are Control.Exception (called Control.OldException in GHC 6.10),
Directory and System.Posix. This has been
abandoned. So you might need to add some imports to you program,
if you actually used the stuff.
- Updated the user manual
- 2.7.1 (released 2006-10-29)
- Modified exitcode to also work with runprog.
(This creates an incompatibility to 2.7.0, if you've actually
used them in conjunction before.)
- 2.7.0 (released 2006-10-21)
- Added runprog and subproc as replacements for
run and call, with much better error
handling, and some associated funtions.
- 2.6.5 (released 2006-10-21)
- Removed some code, which accidentally slipped into 2.6.4. It will appear in version 2.7.
- 2.6.4 (released 2006-10-20)
- Some code, which is meant for version 2.7, slipped into this
release (runprog etc.). These parts aren't quite ready for distribution. Please
- Port to GHC 6.6 (minor changes and cleanup in the build system an package
management). Thanks to Luis Francisco Araujo and Duncan Coutts.
- 2.6.3 (released 2006-08-14)
- Fixed a bug which prevented HsShellScript from being used with ghci.
Thanks to Luis Francisco Araujo for reporting.
- 2.6.2 (released 2006-07-23)
- Builds with code optimization (-O2) turned on
- Fixed some build bugs, which showed only when building with optimization
- More cleanup
- 2.6.1 (released 2006-07-21)
- Now both regular and profiling versions of the library are built.
- Makefile cleanup
- 2.6.0 (released 2005-05-04)
- Added glob, an interface to glob(3), which does wildcard expansion.
- Added outm and outm_.
- Fixed a bug in (-|-) / (=|-) / (-|=) / (=|=) which made them
affect the whole process, instead of just the forked portion.
(Doesn't occur when called like call (exec ... -|- exec
- Added redirect.
- 2.5.0 (released 2005-04-12)
- Changed the error reporting behavior of with_tmp_dir
and with_temp_dir. Now an exception is passed through,
when the temporary directory can't be removed. (That's a very
- Removed debugging output from du.
- Worked around a bug in GHC 6.4's GetOpt. The "--" argument wasn't recognized any longer.
- Worked around buggy GHC 6.4's GHC.Handle.hDuplicateTo.
- 2.4.1 (released 2005-04-06)
- (unuseable because of bugs in the GHC 6.4 libraries)
- Tried to work around a bug in GHC 6.4's implementation of hDuplicateTo.
- 2.4.0 (released 2005-04-06)
- (unuseable because of bugs in the GHC 6.4 libraries)
- Ported to GHC 6.4. Won't build with GHC 6.2 any longer.
- Removed the examples and the section "An example makefile" from the user manual. It was too much trouble maintaining them.
- 2.3.0 (released 2005-04-05)
- Added with_wd.
- Fixed a bug in unsplit_parts.
- Changed unsafe_getargs and
unsafe_getargs_ordered to throw an ArgError instead of
terminating the program with an error message, in case of argument
errors, so they're consistent with
getargs/getargs_ordered. That's a potentially an
incompatibilty to the last version.
- 2.2.2 (released 2005-03-17)
- Forgot to export child.
- Fixed no documentation being generated for fill_in_filename, fill_in_location, add_location
- 2.2.1 (released 2005-03-10)
- Fixed a bug which caused an ErrorCall to be thrown instead of a dynamic ArgError exception for unknown arguments.
- 2.2.0 (released 2005-02-27)
- Lots of cleanup, much more solid, some new features, improved doumentation...
- Added rename_mv and force_rename_mv.
- Added unsplit_parts.
- Added silently.
- Changed the return type of the exec... functions from () to a.
- Added functions for reading mount information.
- Added functions for colored error and log messages.
- Improved error messages (show_ioerror).
- Clarified, documented and fixed what happens to the standard handles and standard file descriptors of the parts of a pipe, and what
happens when a non-exec'ing child process terminates.
- No longer using the old hslibs, moved to the Hierarchical Libraries completely (invisible to the user).
- Fixed buggy path_exists'.
- Fixed missing compilation option -package-name which prevented to use HsShellScript in conjunction with GHC's --make
- Added the _exit system call as a Haskell function.
- Minor incompatible change. lazy_contents no longer returns the handle, since this is unnecessary. The previous
documentation told otherwise and was in fault.
- Improved and restructured the API documentation.
- Incompatible change: Changed err_to_out and out_to_err to apply to an IO action only, not to the whole
- The redirection operators now affect only the specified IO action, not the whole process.
(That's a potential incompatibilty to the last version).
- Incompatible change: Cleaned up the pipe_to, pipe_from, pipe_from2, h_pipe_from etc.
functions. Now they are uniform and return reasonable results. They also wait for the child process to finish, when appropriate.
- Added setFileMode'.
- Added fill_in_filename, fill_in_location and add_location.
- Added force_writeable and force_writeable2.
- Changed the return type of the specified action in call and spawn from () to a.
- Fixed a bug which would cause an Illegal Operation IOError because of possibly flushing a closed stdin or stderr.
- 2.1.0 (released 2004-10-17)
- Some fixes in the documentation.
- Extended unsplit_path.
- Added fileAccess'.
- Added a family of functions for creating temporary files and directories.
- 2.0.1 (released 2004-09-21)
Gregory Wright has contributed a section for the user manual on
installing HsShellScript with the Darwinports system.
- 2.0.0 (released 2004-09-21)
HsUnix has been renamed to HsShellScript. Please
replace any import HsUnix statements with import
HsShellScript. Also, the following names have changed:
HsUnixArguments. They probably don't occur in users'
programs. Replace them with ArgumentProperty,
ArgumentDescription, Arguments if necessary.
Now using hierarchical module names (doesn't affect the user).
Updated the user manual.
HsShellScript now registers itself with GHC's package management
system. hsunix-config is not longer needed. You only need
to specify -package hsshellscript now, for compiling and
It can now be used in conjunction with ghci.
Fixed serious bugs in the example makefile in the user manual
(didn't work at all).
Removed outdated umlinken.hs from the example programs. It
relied on an previous version of HsShellScript.
Gregory Wright has built HsShellScript on MacOS X, and packaged it
for the Darwinports software installation system.
- 1.7.0 (released 2004-09-17)
Added guess_dotdot and guess_dotdot_comps.
The shared library version of HsShellScript introduced in 1.6.0
causes strange problems. I've re-removed it. Delete
/usr/local/lib/libHsShellScript.so if you've installed
Fixed a bug in shell_quote.
Added absolute_path_by which supersedes absolute_path'.
absolute_path' should not be used any longer.
A shared library is now built, but I couldn't get it to work with
ghci so far.
Added dir_part and filename_part.
Removed the outdated system' and introduced system_throw
Added unsafe_getargs and unsafe_getargs_ordered.
Added argument value testers, and argname.
Added (-&>-), (-&>>-),
Added force_mv and force_cmd.
Incompatible change: Functions such as realpath or
symlink no longer throw an Errno as a dynamic
exception. Instead, an IOError is thrown (as a normal IO
monad exception). Additional data, beyond the mere errno
value is now included, such as the file name, accessible via
ioeGetFileName. This is in accordance to the
Foreign.C.Error library (see the errnoToIOError
function). Errno is no longer made typeable by
HsShellScript, and can't be thrown or catched dynamically any
Minor improvement in error reporting.
Added an interface to the fdupes program for finding
Fixed a bug in optarg_opt
Fixed a tiny mistake in the documentation, leading to a dead link.
Removed getcwd. Use getCurrentDirectory instead.
Small documentation completions.
User Manual (outdated)
(Insert an @-sign and a dot in the email addresses as necessary.)
- Volker Wysk <hsss volker-wysk de>
- Main author
- Gregory Wright <gwright antiope com>
- Build on MacOS X, port for the Darwinport packaging system
- Luis Francisco Araujo <araujo gentoo org>
- Maintainer of the Gentoo package for HsShellScript.
- Duncan Coutts <dcoutts gentoo org>
- Helped to port to GHC 6.6 (build, package management)
Please send any bug reports, suggestions or questions to the main
This is free software, released under the GNU
Lesser General Public License (LGPL), version 2.1, or any later
version. A copy of the license is included in the user manual.
The Glasgow Haskell Compiler
The Haskell Home Page
Haskell Cabal, A Common Architecture for Building Applications and
Last changed 2021-01-10