g      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      Safe-Infered @Describes whether an option takes an argument or not, and if so 3 how the argument is injected into a value of type a. optional argument option requires argument no argument expected Each  describes a single option. The arguments to  are: ! list of short option characters & list of long option strings (without "--")  argument descriptor  explanation of option for user .What to do with options following non-options wrap non-options into options +freely intersperse options and non-options ,no option processing after first non-option @Return a string describing the usage of a command, derived from ? the header (first argument) and the options described by the  second argument. EProcess the command-line, and return the list of values that matched (and those that didn't). The arguments are:  The order requirements (see )  The option descriptions (see ) 9 The actual command line arguments (presumably got from   ).  = returns a triple, consisting of the argument values, a list of options that didn''t match, and a list of error messages.       Safe-Infered JGenerate command (for a shell) which corresponds to the specified program F name and argument list. The program name and arguments are the usual = parameters for calling an external program, like when using   runProcess or run. The generated shell command H would achieve the same effect. The name and the arguments are properly  quoted, using  . yNote: The quoted strings are correctly recognized in shell scripts. But the shell bash has an annoying history expansion "feature", which causes { it to choke on exclamation marks, when in interactive mode, even when quoted with double quotes. You can turn it off with set +o histexpand. Quote shell metacharacters. GThis function quotes strings, such that they are not misinterpreted by E the shell. It tries to be friendly to a human reader - when special J characters are present, then the string is quoted with double quotes. If  not, it is left unchanged. EThe list of exacly which characters need to be quoted has been taken J from the bash source code. Bash in turn, implements POSIX 1003.2. So the > result produced should be correct. From the bash info pages:  "B... the rules for evaluation and quoting are taken from the POSIX  1003.2 specification for the standard Unix shell." yNote: The quoted strings are correctly recognized in shell scripts. But the shell bash has an annoying history expansion "feature", which causes { it to choke on exclamation marks, when in interactive mode, even when quoted with double quotes. You can turn it off with set +o histexpand. See . 7Quote special characters inside a string for the shell @This quotes special characters inside a string, such that it is G recognized as one string by the shell when enclosed in double quotes.  Doesn't add the double quotes. yNote: The quoted strings are correctly recognized in shell scripts. But the shell bash has an annoying history expansion "feature", which causes { it to choke on exclamation marks, when in interactive mode, even when quoted with double quotes. You can turn it off with set +o histexpand. See ,  . Quote a string for the shell ?This encloses a string in double quotes and quotes any special G characters inside, such that it will be recognized as one string by a 7 shell. The double quotes are added even when they aren't needed for this  purpose. yNote: The quoted strings are correctly recognized in shell scripts. But the shell bash has an annoying history expansion "feature", which causes { it to choke on exclamation marks, when in interactive mode, even when quoted with double quotes. You can turn it off with set +o histexpand. See ,  .  name or path of the executable command line arguments shell command     Safe-Infered%Split a path in components. Repeated "/" characters don't lead to empty  components. "."K path components are removed. If the path is absolute, the first component will start with "/". ".."% components are left intact. They can' t be simply Kremoved, because the preceding component might be a symlink. In this case, realpath is probably what you need. 0The case that the path is empty is treated like "."*, yielding an empty path components list.  Examples:  slice_path "/" = ["/"] 'slice_path "/foo/bar" = ["/foo","bar"] slice_path "..//./" = [".."] slice_path "." = [] slice_path "" = [] See , realpath,  realpath_s. *Form a path from path components. This isn't the inverse of , since  .  normalises the path.  unslice_path [] = "." .unslice_path cs = concat (intersperse "/" cs) See , . 4Normalise a path. This is done by reducing repeated /! characters to one, and removing  . path components. ..@ path components are left intact, because of possible symlinks. !Note that the normalised path isn'qt 100% equivalent to the original one. Any trailing slash is removed. When the last path component is a symbolic Q link, then both paths denote the same thing, except for in the context of the readlink7 call. It will fail when the trailing slash is present r (because then the path denotes the directory which the link points to), but it will succeed when it is absent.  +normalise_path = unslice_path . slice_path See , . ESplit a file name in components. This are the base file name and the Lsuffixes, which are separated by dots. If the name starts with a dot, it is Eregarded as part of the base name. The result is a list of file name Kcomponents. The filename may be a path. In this case, everything up to the Hlast path component will be returned as part of the base file name. The path gets normalised thereby. BNo empty suffixes are returned. If the file name contains several Fconsecutive dots, they are regared as part of the preceding file name  component. BConcateneting the name components and adding dots, reproduces the 'original name, with a normalised path: concat . intersperse "." .  ==  normalise. +Note that the last path component might be "..". Then it is not (possible to deduce the refered directory's name from the path. An IO 4action for getting the real path is then necessary.  Examples:  >slice_filename "a.b//./.foo.tar.gz" = ["a.b/.foo","tar","gz"] 4slice_filename ".x..y." = [".x.", "y."] See , slice_filename'. This is a variant of  . It is like  , except for Lbeing more efficient, and the filename must not contain any preceding path, since this case isn't considered. See , . FForm file name from file name components, interspersing dots. This is the inverse of (, except for normalisation of any path.  - unslice_filename = concat . intersperse "." See . CSplit a path in directory and file name. Only in the case that the Asupplied path is empty, both parts are empty strings. Otherwise, "." is filled in Dfor the corresponding part, if necessary. Unless the path is empty, Iconcatenating the returned path and file name components with a slash in )between, makes a valid path to the file.  split_path* splits off the last path component. This isn'&t the same as the text after the last /. +Note that the last path component might be "..". Then it is not (possible to deduce the refered directory'!s name from the path. Then an IO /action for getting the real path is necessary.  Examples:  *split_path "/a/b/c" == ("/a/b", "c") )split_path "foo" == (".", "foo") +split_path "foo/bar" == ("foo", "bar") *split_path "foo/.." == ("foo", "..") 'split_path "." == (".", ".") %split_path "" == ("", "") )split_path "/foo" == ("/", "foo") )split_path "foo/" == (".", "foo") )split_path "foo/." == (".", "foo") +split_path "foo///./bar" == ("foo", "bar") 'split_path "/" == ("/", ".") See . "Get the directory part of a path.  dir_part = fst . split_path See . 'Get the last path component of a path.  !filename_part = snd . split_path  Examples:  !filename_part "foo/bar" == "bar" filename_part "." == "." See .  Inverse of , except for normalisation. 4This forms a path from two parts, and takes care of "."G and empty parts. When the two components are in normalised form, then  unsplit_path creates a normalised path. The definition:  unsplit_path ("", "") = "" -unsplit_path (p, q) = unsplit_parts [p, q]  Examples:   unsplit_path ("", "") == "" !unsplit_path (".", "") == "." !unsplit_path (".", ".") == "." #unsplit_path ("foo", ".") == "foo" See , , . rConcatenate a list of path parts. The idea is that you can throw in reasonably formed parts, and get a reasonably -formed version of the concatenated path out. "."/ parts are removed. Empty parts are treated as "."V parts. One leading slash in each of any but the first part is removed. The result is Zthen interspersed with slashes and string wise concatenated. The interior of the parts isn' t examined. ".." components aren't treated specially.  Examples:  .unsplit_parts [] == "." .unsplit_parts [""] == "." .unsplit_parts ["/"] == "/" 1unsplit_parts ["/", "foo"] == "/foo" 0unsplit_parts ["", "/foo"] == "foo" 5unsplit_parts ["/foo", "bar"] == "/foo/bar" 5unsplit_parts ["/foo", "/bar"] == "/foo/bar" 5unsplit_parts ["foo/", "bar"] == "foo//bar" 4unsplit_parts ["foo", "", ".", "bar"] == "foo/bar" <unsplit_parts ["foo", "bar//./baz/"] == "foo/bar//./baz/" See , , . 4Split a file name in prefix and suffix. If there isn't any suffix in Ithe file name, then return an empty suffix. A dot at the beginning or at 1the end is not regarded as introducing a suffix. 8The last path component is what is being split. This isn't the same as Esplitting the string at the last dot. For instance, if the file name doesn'2t contain any dot, dots in previous path component's aren' t mistaken as introducing suffixes. :The path part is returned in normalised form. This means, "." components are removed, and multiple "/"s are reduced to one. Note that there isn'Ht any plausibility check performed on the suffix. If the file name doesn'9t have a suffix, but happens to contain a dot, then this )dot is mistaken as introducing a suffix.  Examples:  Usplit_filename "path/to/foo.bar" = ("path/to/foo","bar") Rsplit_filename "path/to/foo" = ("path/to/foo","") Ssplit_filename "/path.to/foo" = ("/path.to/foo","") Jsplit_filename "a///./x" = ("a/x","") Psplit_filename "dir.suffix/./" = ("dir","suffix") rsplit_filename "Photographie, Das 20. Jahrhundert (300 dpi)" = ("Photographie, Das 20", " Jahrhundert (300 dpi)") See , 'split_filename\''  Variant of #. This is a more efficient version of +, for the case that you know the string is )is a pure file name without any slashes. See .  Inverse of (. Concatenate prefix and suffix, adding Na dot in between, iff the suffix is not empty. The path part of the prefix is  normalised. See . 6Split a path in directory, base file name and suffix. ;Form path from directory, base file name and suffix parts. 4Test a path for a specific suffix and split it off. 5If the path ends with the suffix, then the result is Just prefix, where prefix is the normalised path  without the suffix. Otherwise it's Nothing. !;Make a path absolute, using the current working directory. @This makes a relative path absolute with respect to the current <working directory. An absolute path is returned unmodified. 1The current working directory is determined with getCurrentDirectory Cwhich means that symbolic links in it are expanded and the path is #normalised. This is different from pwd. "Make a path absolute. @This makes a relative path absolute with respect to a specified 4directory. An absolute path is returned unmodified. #Make a path absolute. @This makes a relative path absolute with respect to a specified 4directory. An absolute path is returned unmodified. CThe order of the arguments can be confusing. You should rather use ".  absolute_path'* is included for backwards compatibility. $ Guess the ".."-component free form of a path, specified as a list of path components, by syntactically removing them, along with the preceding & path components. This will produce S erroneous results when the path contains symlinks. If the path contains leading ".." components, or more ".."# components than preceeding normal  components, then the ".." components can'2t be normalised away. In this case, the result is Nothing. % Guess the ".."T-component free, normalised form of a path. The transformation is purely syntactic. ".."( path components will be removed, along ; with their preceding path components. This will produce S erroneous results when the path contains symlinks. If the path contains leading ".." components, or more ".."# components than preceeding normal  components, then the ".." components can'2t be normalised away. In this case, the result is Nothing. Cguess_dotdot = fmap unslice_path . guess_dotdot_comps . slice_path %The path to be broken to components. List of path components. List of path components 8The path which consists of the supplied path components Path to be normalised Path in normalised form Path /List of components the file name is made up of File name without path /List of components the file name is made up of List of file name components ;Name of the file which consists of the supplied components Path to be split RDirectory and file name components of the path. The directory path is normalized. Directory and file name 3Path formed from the directory and file name parts #List of path parts to concatenate. +Formed path, which concatenates the parts. )Path including the file name to be split ?The normalised path with the file prefix, and the file suffix. Filename to be split Base name and the last suffix File name prefix and suffix Path Path to split 4Directory part, base file name part and suffix part 4Directory part, base file name part and suffix part (Path consisting of dir, base and suffix Suffix to split off  Path to test Prefix without the suffix or Nothing !The path to be made absolute  Absulte path ":The directory relative to which the path is made absolute The path to be made absolute Absolute path #The path to be made absolute :The directory relative to which the path is made absolute Absolute path $List of path components +In case the path could be transformed, the "..")-component free list of path components. %Path to be normalised 7In case the path could be transformed, the normalised, "..""-component free form of the path.  !"#$% !"#$% !"#$% Safe-Infered>&+Error thrown when there is an error in the  command line arguments. (/Error message generated by HsShellScript.Args. ):Usage information derived from the argument descriptions. *HThis represents the parsed contents of the command line. It is returned  by the getargs$... functions, and passed on to the ) value extraction functions by the user. See O, P,  'getargs\'', 'getargs_ordered\''. +BA property of a command line argument. These are generated by the  desc_)... functions, and condensed to argument  descriptions of type ArgumentDescription by argdesc. This type is abstract. ,ADescription of one command line argument. These are generated by  argdescI from a list of argument properties, and subsequently used by one of the  getargs&... functions. This type is abstract. .Short option names /Long option names 0-What about a possible value of the argument? 14Minimum and maximum of number of occurences allowed 2Name for argument' s value, for message generation 33Descrition of the argument, for message generation 4Argument value tester 5DArgument value tester function. This tests the format of an argument'8s value for errors. The tester function is specified by  H0 or such, as part of the argument description. SThe tester is passed the argument value. If the format is correct, then it returns Nothing(. If there is an error, then it returns  Just msgf,  with msgfx being an error message generation function. This function gets passed the argument description, and produces the error j message. The argument description typically is used to extract a descriptive name of the argument (using L or M) to be included  in the error message. 6.Does the command line argument take an value? 7Value optional 8Value required 9 No value :=Short name of the argument. This specifies a character for a ! one letter style argument, like -x. There can be specified = several for the same argument. Each argument needs at least  either a short or a long name. ;;Long name of the argument. This specifies a GNU style long  name for the argument, like --arg or  --arg=.... There can be specified C several names for the same argument. Each argument needs at least  either a short or a long name. <JSignal that this is the description of direct arguments. Direct arguments G are the ones not introduced by any short or long argument names (like  -x or --arg$), or which occur after the special  argument --. The presence of  desc_direct! in the argument properties list  signals argdesc, that this is the description of the direct 7 arguments. There may be at most one such description. =+Signal that the argument requires a value. >ESignal that the argument optionally has a value. The user may or may ' not specify a value to this argument. ?ESpecify lower and upper bound on the number of times an argument may  occur. @?Signal that the argument must be present exactly once. This is 7 meaningful only for arguments which can take a value. A7Signal that the argument must occur at least one time. B6Signal that the argument must occur at most one time. CDSignal that the argument must have at least the specified number of 3 occurences, and has no upper limit of occurences. D8Signal that the argument may occur any number of times. ELSignal that the argument does not need to be present, and may occur at most  the specified number of times. F6Specify the descriptive name for command line argument's value. Used for the A generation of the usage message. The name should be very short. GDSpecify a short description of what the argument does. Used for the H generation of the usage message. This is to fit on one line, after the G short and long argument names. It should be 40 characters long or so. HSpecify a tester for this argument. The tester is a function which tests the argument value for format errors. Typically, it tests whether the  value can be parsed to some target type. If the test fails, the tester produces an error message. When parsing the command line arguments (which  getargsT or related), all the testers are applied to the respective argument values, and an &* is thrown in case of failure. By using a  tester, it can be ensured that the argument values abide a specific format when extracting them, such that they can be parsed without errors, e.g.  &myarg = read (reqarg_req args d_myarg). )An argument tester is a function of type 5. See I, J, K, 5. I Build an argument tester from a readsM like function. Typically, a specialisation of the standard prelude function read is used.  Example:  readtester "Integer expected." (reads :: ReadS Int) JSpecify that the value of this argument, if present, is a positive integer. This will cause an error when the command line is parsed, and the  argument' s value doesn't specify an integer.  Qdesc_integer = desc_tester (readtester (reads :: ReadS Int) "Integer expected.") See H. KSpecify that the value of this argument, if present, is a non-negative integer. This will cause an error when the command line is parsed, and the  value doesn'"t specify a non-negative integer.  desc_nonneg_integer = desc_tester (readtester ((filter (\(a,_) -> a >= 0) . reads) :: ReadS Int) "Non-negative integer expected." ) See H. LGenerate a descriptive argument name from an argument description, suitable for use in error messages. This uses the long and short argument names  (as specified by : and ;7) and generates descriptive names of the argument like "-f", "-myflag", "-f/--myflag", etc. All the ? argument names are included. In case of direct arguments (see <), the descriptive name is "(direct argument)". MRGenerate a descriptive argument name from an argument description, beginning with "argument"2. This uses the long and short argument names (as  specified by : and ;7) and generates descriptive names of the argument like " argument -f", "argument -myflag", " argument  -f/--myflag"M, etc. All the argument names are included. In case of direct arguments (see <), the descriptive name is "direct argument". NFMake an argument description from a list of argument properties. This 0 condenses the list to an argument description,  which can be uses by the getargs... functions and the & argument value extraction functions. OEParse command line arguments. The arguments are taken from a call to  getArgs' and parsed. Any error is thrown as a  ArgError1 exception. The result is a value from which the 9 information in the command line can be extracted by the arg...,  reqarg... and optarg... functions. Named arguments (like -x or --arg ) and direct # arguments may occur in any order. PEParse command line arguments. The arguments are taken from a call to  getArgs' and parsed. Any error is thrown as a  ArgError1 exception. The result is a value from which the 9 information in the command line can be extracted by the arg...,  reqarg... and optarg... functions. EAll arguments after the first direct argument are regarded as direct 9 arguments. This means that argument names introduced by -  or -- no longer take effect. Q;Parse the specified command line. Any error is returned as Left  argerror0. In case of success, the result is returned as   Right res2. From the result, the information in the command  line can be extracted by the arg..., reqarg...  and optarg... functions. Named arguments (like -x or --arg ) and direct # arguments may occur in any order. R;Parse the specified command line. Any error is returned as Left  argerror0. In case of success, the result is returned as   Right res2. From the result, the information in the command  line can be extracted by the arg..., reqarg...  and optarg... functions. EAll arguments after the first direct argument are regarded as direct 9 arguments. This means that argument names introduced by -  or -- no longer take effect. SPQuery whether a certain switch is specified on the command line. A switch is an ? argument which is allowed zero or one time, and has no value. T/Query the number of occurences of an argument. UAQuery the values of an argument with optional value. This is for J arguments which take an optional value, and may occur several times. The * occurences with value are represented as  Just value, the occurences  without are represented as Nothing. VAQuery the values of an argument with required value. This is for ? arguments which require a value, and may occur several times. WGQuery the optional value of a required argument. This is for arguments A which must occur once, and may have a value. If the argument is % specified, its value is returned as  Just value . If it isn't, the result  is Nothing. XIQuery the value of a required argument. This is for arguments which must * occur exactly once, and require a value. YHQuery the optional value of an optional argument. This is for arguments J which may occur zero or one time, and which may or may not have a value.  If the argument doesn't occur, the result is Nothing. If it does occur, & but has no value, then the result is  Just Nothing. If it does occur with  value, the result is Just (Just value). ZHQuery the value of an optional argument. This is for optional arguments B which require a value, and may occur at most once. The result is   Just value if the argument occurs, and Nothing  if it doesn' t occur. [/None of the specifed arguments may be present. 8Throws an ArgError if any of the arguments are present. \0All of the specified arguments must be present. &Throws an ArgError if any is missing. ]8Exactly one of the specified arguments must be present. Otherwise throw an ArgError. ^7At most one of the specified arguments may be present. Otherwise throw an ArgError. _9At least one of the specified arguments must be present. Otherwise throw an ArgError. `YWhen the specified argument is present, then none of the other arguments may be present. Otherwise throw an ArgError. a<Whether the specified argument occurs in the command line. bDGet the usage information from the parsed arguments. The usage info 4 contains the header specified to the corresponding  getargs... ; function, and descriptions of the command line arguments. cgetargs} as a pure function, instead of an IO action. This allows to make evaluated command line arguments global values. This calls getargs ( to parse the command line arguments. GHC.IO.unsafePerformIO1 is used to take the result out of the IO monad.  Lunsafe_getargs header descs = GHC.IO.unsafePerformIO $ getargs header descs The getargsX action is performed on demand, when the parse result is evaluated. It may result in an &! being thrown. In order to avoid + this happening at unexpected times, the main& function should, start with the line seq args (return ()), where args is the result of  unsafe_getargs,. This will trigger any command line argument errors at the beginning of the program. (See section 6.2 of the Hakell Report for the  definition of seq). A typical use of unsafe_getargs looks like this:  header = "..." descs = [ d_myflag, ... ]  d_myflag = argdesc [ ... ]  #args = unsafe_getargs header descs "myflag = arg_switch args d_myflag  main = mainwrapper $ do  seq args (return ())  ... See O, d. dgetargs_orderedC as a pure function, instead of an IO action. This is exactly like unsafe_getargs , but using getargs_ordered instead of  getargs.  Ounsafe_getargs_ordered = GHC.IO.unsafePerformIO $ getargs_ordered header descs See c. Make ArgError an instance of  Exception., so we can throw and catch it, using GHC-6.10's new exception library. C&'()*+,-./0123456789:$The character to name the argument. %The corresponding argument property. ;The long name of the argument. %The corresponding argument property. <=>?4Lower bound of the allowed number of argdesc_times. 4Upper bound of the allowed number of argdesc_times. %The corresponding argument property. @%The corresponding argument property. A%The corresponding argument property. B%The corresponding argument property. CNumber of times. %The corresponding argument property. D%The corresponding argument property. ENumber of times. %The corresponding argument property. FName of the argument' s value. %The corresponding argument property. G#Short description of the argument. %The corresponding argument property. H*Argument tester to apply to this argument %The corresponding argument property. IJKLMN>List of properties, which describe the command line argument. (The corresponding argument description. O%Header to be used in the usage info. The argument descriptions. "The contents of the command line. P%Header to be used in the usage info. Descriptions of the arguments. "The contents of the command line. Q%Header to be used in the usage info. Command line to be parsed. The argument descriptions. "The contents of the command line. R%Header to be used in the usage info. Command line to be parsed. The argument descriptions. "The contents of the command line. SCommand line parse result. $Argument description of the switch. 3Whether the switch is present in the command line. TCommand line parse result. Description of the argument. %Number of times the argument occurs. UCommand line parse result. Description of the argument.  The occurences of the argument. VCommand line parse result. Description of the argument. The values of the argument. WCommand line parse result. Description of the argument. )The value of the argument, if it occurs. XCommand line parse result. Description of the argument. The value of the argument. YCommand line parse result. Description of the argument. 9The occurence of the argument and its value (see above). ZCommand line parse result. Description of the argument. )The value of the argument, if it occurs. [1List of the arguments which must not be present. Command line parse result. \-List of the arguments which must be present. Command line parse result. ]=List of the arguments, of which exactly one must be present. Command line parse result. ^<List of the arguments, of which at most one may be present. Command line parse result. _>List of the arguments, of which at least one must be present. Command line parse result. `Argument which doesn't tolerate the other arguments Arguments which aren'&t tolerated by the specified argument Command line parse result. aCommand line parse result. (Description of the respective argument. ;Whether the specified argument occurs in the command line. bc)The header used in the usage information The argument descriptions "The parsed command line arguments d)The header used in the usage information The argument descriptions "The parsed command line arguments ?&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcd?+,-./0123469875N:;<=>?@ABDCEFGHJKI*OPQRcdSTUVWXYZa[\]^_`&'()bLM5&'()*+,-./0123456987:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcd Safe-InferedFe<An error which occured when calling an external program via . 0 The fields specifiy the details of the call. See }, , , System.Posix.ProcessStatus. g Program name hProgram arguments i.The environment in use when the call was done j-The working directory when the call was done k"The process status of the failure lThe error (errno) code wImproved version of System.Posix.Files.setFileMode", which sets the file name in the IOError* which is thrown in case of an error. The 4 implementation in GHC 6.2.2 neglects to do this. setFileMode' path mode =  fill_in_filename path $  setFileMode path mode xGExecute an IO action as a separate process, and wait for it to finish.  Report errors as exceptions. EThe program forks a child process and performs the specified action. G Then it waits for the child process to finish. If it exits in any way  which indicates an error, the  ProcessStatus is thrown as an  exception. When the action throws an IOError#, it is transmitted to the parent. K It is then raised there, as if it happened locally. The child then aborts ! quietly with an exit code of 0. !When used in conjunction with an exec% variant, this means that the parent 8 process can tell the difference between failure of the exec call itself, 8 and failure of the program being executed. You get the IOError, which $ happened in the child when calling  executeFile (GHC hierarchical G libraries). Of course, the action can prevent this form happening, by  itself catching IOErrors. LThe parent process waits for the child process, if it has been stopped by a  signal. See HsShellScript#subr for further details.  Examples: -Run a program with the environment replaced:  0subproc (execpe "foobar" ["1","2","3"] new_env) This results in a  ProcessStatus exception:  subproc (exec "/bin/false" []) This results in an IOError (unless you actually have /frooble):  subproc (exec "/frooble" []) See , z, , , , . yGExecute an IO action as a separate process, and wait for it to finish.  Report errors as exceptions. KThis function is included only for backwards compatibility. New code should  use x instead", which has better error handling. EThe program forks a child process and performs the specified action. G Then it waits for the child process to finish. If it exits in any way  which indicates an error, the  ProcessStatus is thrown. MThe parent process waits for the child processes, which have been stopped by  a signal. See HsShellScript#subr for further details. See x, z. zIExecute an IO action as a separate process, and continue without waiting  for it to finish. WThe program forks a child process, which performs the specified action and terminates.  The child's process ID is returned. See HsShellScript#subr for further details. See x. |:Run an external program. This starts a program as a child I process, and waits for it to finish. The executable is searched via the  PATH. KThis function is included for backwards compatibility only. New code should  use ', which has much better error handling. When the specified program can'At be executed, an error message is printed, and the main process  gets a  ProcessStatus thrown, with the value Exited  (ExitFailure 1)&. This means that the main program can't distinguish between M failure of calling the program and the program exiting with an exit code of  1. However, an error message "Error calling ..."4, including the description in the IOError produced  by the failed execp call, is printed on stderr.  run prog par is essentially call (execp prog par).  Example:  'run "/usr/bin/foobar" ["some", "args"] ! `catch` (\ps -> do -- oops...  ) See , x, z. }5Make a readable error message. This includes all the  fields of RunError except for the environment. See e. ~+Generate a human-readable description of a  ProcessStatus. See ,  and System.Posix.ProcessStatus in the GHC hierarchical  library documentation.  Convert a RunError to an IOError. The IOError type isn'2t capable of holding all the information which is  contained in a RunError5. The environment is left out, and most of the other : fields are included only informally, in the description. The fields of the generated IOError are:  The handle ( ioeGetHandle): Nothing  The error type (ioeGetErrorType): GHC.IO.Exception.SystemError   ioe_location: "runprog"  ioe_description$: The error message, as procuded by  show_runerror.   ioe_filename : This is Just (shell_command prog pars), with prog  and pars& being the program and its arguments. See , , }. DCall the specified IO action (which is expected to contain calls of  runprog) and convert any RunError exceptions to IOErrors. The conversion is done by to_ioe. See , . LRun an external program, and report errors as exceptions. The executable is  searched via the PATH. DIn case the program exits in an way which indicates an error, or is  terminated by a signal, a RunError is thrown. It ' contains the details of the call. The runprog action can also be converted  to throw IOErrors instaed, by applying as_ioe to it. Either can be used + to generate an informative error message. 2In case of starting the program itself failed, an IOError is thrown. runprog prog par is essentially subproc (execp prog par).  Example 1:  "do runprog "foo" ["some", "args"]  ... +`catch` (\re -> do errm (show_runerror re)  ...  )  Example 2:  +do as_ioe $ runprog "foo" ["some", "args"]  ... ,`catch` (\ioe -> do errm (show_ioerror ioe)  ...  ) See x, z, e, }, , . 5Print an action as a shell command, then perform it. "This is used with actions such as ,  or x. For instance,  echo runprog prog args is a variant of runprog prog args, which prints what  is being done before doing it. See , x, . LExecute an external program. This replaces the running process. The path isn't searched, the environment isn't changed. In case of failure,  an IOError is thrown.  exec path args = ( execute_file path False args Nothing See , HsShellScript#exec. iExecute an external program. This replaces the running process. The path is searched, the environment isn't changed. In case of failure,  an IOError is thrown.  execp prog args = ' execute_file prog True args Nothing See , HsShellScript#exec. LExecute an external program. This replaces the running process. The path isn'Ct searched, the environment of the program is set as specified. In ( case of failure, an IOError is thrown.  exece path args env = + execute_file path False args (Just env) See , HsShellScript#exec. Execute an external program. This replaces the running process. The path is searched, the environment of the program is set as specified. In ( case of failure, an IOError is thrown.  execpe prog args env = * execute_file prog True args (Just env) See , HsShellScript#exec. "Build left handed pipe of stdout. "p -|- q"- builds an IO action from the two IO actions p and q.  q< is executed in an external process. The standard output of p is sent  to the standard input of q, through a pipe. The result action consists  of forking off q (connected with a pipe), and p. The result action does not run p% in a separate process. So, the pipe + itself can be seen as a modified action p, forking a connected q. The  pipe is called " left handed" , because p remains unforked, and not q. 'The exit code of q is silently ignored. The process ID of the forked  copy of q isn't returned to the caller, so it's lost. See HsShellScript#subr and  HsShellScript#exec for further details.  Examples:  9call (exec "/usr/bin/foo" [] -|- exec "/usr/bin/bar" [])  call ( execp "foo" ["..."] . -|= ( -- Do something with foo's output ( do cnt <- lazy_contents "-"  ...  )  ) See x, '(=|-)', '(-|=)'. "Build left handed pipe of stderr. "p =|- q"- builds an IO action from the two IO actions p and q.  qB is executed in an external process. The standard error output of p is sent  to the standard input of q, through a pipe. The result action consists  of forking off q (connected with a pipe), and p. The result action does not run p% in a separate process. So, the pipe + itself can be seen as a modified action p, forking a connected q. The  pipe is called " left handed" , because p has this property, and not q. 'The exit code of q is silently ignored. The process ID of the forked  copy of q isn't returned to the caller, so it's lost. See HsShellScript#subr and  HsShellScript#exec for further details.  Example:  9call (exec "/usr/bin/foo" [] =|- exec "/usr/bin/bar" []) See x, '(-|-)', '(-|=)'. #Build right handed pipe of stdout. "p -|= q"- builds an IO action from the two IO actions p and q.  p< is executed in an external process. The standard output of p is sent  to the standard input of q, through a pipe. The result action consists  of forking off p (connected with a pipe), and q. The result action does not run q% in a separate process. So, the pipe + itself can be seen as a modified action q, forking a connected p.  The pipe is called "right  handed" , because q has this property, and not p. 'The exit code of p is silently ignored. The process ID of the forked  copy of q isn't returned to the caller, so it's lost. See HsShellScript#subr and  HsShellScript#exec for further details.  Example:  E@call (exec \"\/usr\/bin\/foo\" [] -|= exec \"\/usr\/bin\/bar\" [])@ See x, '(=|-)', '(=|=)'. #Build right handed pipe of stderr. "p =|= q"- builds an IO action from the two IO actions p and q.  pB is executed in an external process. The standard error output of p is sent  to the standard input of q, through a pipe. The result action consists  of forking off p (connected with a pipe), and q. The result action does not run q% in a separate process. So, the pipe + itself can be seen as a modified action q, forking a connected p.  The pipe is called "right  handed" , because q has this property, and not p. 'The exit code of p is silently ignored. The process ID of the forked  copy of q isn't returned to the caller, so it's lost. See HsShellScript#subr and  HsShellScript#exec for further details.  Example:  : call (exec "/usr/bin/foo" [] =|= exec "/usr/bin/bar" []) See x, , . Temporarily replace a handle. This makes a backup copy of the original handle (typically a standard handle), overwrites it with the specified one, E runs the specified action, and restores the handle from the backup.  Example:  & h <- openFile "/tmp/log" WriteMode  redirect stdout h io  hClose h This is the same as   io ->- "/tmp/log" See , . wRedirect the standard output of the specified IO action to a file. The file will be overwritten, if it already exists. What's actually modified is the stdout( handle, not the file descriptor 1. The exec functions know about this. See HsShellScript#fdpipes and HsShellScript#exec for details.  Example:  )run "/some/program" [] ->- "/tmp/output"  Note: You can't redirect to "/dev/null" this way, because GHC 6.4's openFile throws an "invalid argument" ;IOError. (This may be a bug in the GHC 6.4 libraries). Use ->>- instead. See x, , , . |Redirect the standard output of the specified IO action to a file. If the file already exists, the output will be appended. What's actually modified is the stdout( handle, not the file descriptor 1. The exec functions know about this. See HsShellScript#fdpipes and HsShellScript#exec for details.  Example:  .run "/some/noisy/program" [] ->>- "/dev/null" See x, , '(->-)', '(=>>-)'. }Redirect the standard error output of the specified IO action to a file. If the file already exists, it will be overwritten. What's actually modified is the stderr( handle, not the file descriptor 2. The exec functions know about this. See HsShellScript#fdpipes and HsShellScript#exec for details.  Note: You can't redirect to "/dev/null" this way, because GHC 6.4's openFile throws an "invalid argument" ;IOError. (This may be a bug in the GHC 6.4 libraries). Use =>>- instead.  Example:  (run "/path/to/foo" [] =>- "/tmp/errlog" See x, , '(->-)', '(=>>-)'. Redirect the standard error output of the specified IO action to a file. If the file already exists, the output will be appended. What's actually modified is the stderr( handle, not the file descriptor 2. The exec functions know about this. See HsShellScript#fdpipes and HsShellScript#exec for details.  Example:  (run "/some/program" [] =>>- "/dev/null" See x, , '(->>-)', '(=>-)'. ERedirect both stdout and stderr to a file. This is equivalent to the shell's &>? operator. If the file already exists, it will be overwritten. What's actually modified are the stdout and stderr handles, not the file descriptors 1 and 2. The exec functions know about this. See HsShellScript#fdpipes and HsShellScript#exec for details.  Note: You can't redirect to "/dev/null" this way, because GHC 6.4's openFile throws an "invalid argument" ;IOError. (This may be a bug in the GHC 6.4 libraries). Use -&>>- instead.  ((-&>-) io path = err_to_out io ->- path  Example:   call (exec "/path/to/foo" [] -&>- "log")See '(-&>>-)', . KRedirect both stdout and stderr to a file. If the file already exists, the  output will be appended. What's actually modified are the stdout and stderr handles, not the file descriptors 1 and 2. The exec functions know about this. See HsShellScript#fdpipes and HsShellScript#exec for details.  /(-&>>-) io path = (err_to_out >> io) ->>- path  Example:  /run "/some/noisy/program" [] -&>>- "/dev/null" See '(-&>-)', . ERedirect stdin from a file. This modifies the specified action, such -that the standard input is read from a file. What's actually modified is the stdin handle, not the file  descriptor 0. The exec functions know about this. See  HsShellScript#fdpipes and HsShellScript#exec for details.  Example:   call (exec "/path/to/foo" [] -<- "bar")See , , '(->-)', '(=>-)'. FSend the error output of the specified action to its standard output. What's actually modified is the stdout( handle, not the file descriptor 1. The exec functions know about this. See HsShellScript#fdpipes and HsShellScript#exec for details.  $err_to_out = redirect stderr stdout See . FSend the output of the specified action to its standard error output. What's actually modified is the stderr( handle, not the file descriptor 2. The exec functions know about this. See HsShellScript#fdpipes and HsShellScript#exec for details.  redirect stdout stderr See . BRun an IO action as a separate process, and pipe some text to its stdin. E Then close the pipe and wait for the child process to finish. If it . exits in a way which indicates an error, the  ProcessStatus is thrown.  Example: pipe_to "blah" $ exec "/usr/bin/foo" ["bar"] See x, , , . See HsShellScript#fdpipes for more details. ;Run an IO action as a separate process, and connect to its stdin  with a pipe.  Example: h <- h_pipe_to $ exec "/usr/bin/foo" ["bar"] See , , , . See HsShellScript#fdpipes for more details. 5Run an IO action as a separate process, and read its stdout G strictly. Then wait for the child process to finish. This is like the  backquote feature of shells. :If the child process exits with a non-zero exit code, the   ProcessStatus is thrown. The whole output is returned, no trailing newline character is removed, like the shell does with backquotes. You may want to apply chomp  to the result.  Example:  .output <- pipe_from $ exec "/bin/foo" ["bar"] See , , , , , chomp, . See HsShellScript#fdpipes for more details. 5Run an IO action as a separate process, and read its stderr J strictly. Then wait for the child process to finish, and return the text  along with its exit code.  Example:  E(errmsg, ec) <- pipe_from2 $ exec "/bin/foo" ["bar"] ->- "/dev/null"  %when (ec /= Exited ExitSuccess) $ do  errm errmsg  ... See , , , , , . See HsShellScript#fdpipes for more details. ;Run an IO action as a separate process, and connect to its stdout  with a pipe. <A handle connected to the child process, and the process ID < of the child are returned. The process ID can be used with  System.Posix.getProcessStatus to get the child's exit code. You must either I ensure that all data has been read, or close the handle, before calling  getProcessStatus blockingly. Otherwise you'll get a deadlock. When you G close the handle before all data has been read, then the child gets a  SIGPIPE signal.  Example:  /h <- h_pipe_from $ exec "/usr/bin/foo" ["bar"] See , , , , , chomp, . See HsShellScript#fdpipes for more details. ;Run an IO action as a separate process, and connect to its stderr  with a pipe. 'A handle connected to the child process'+ standard error output, and the process ID < of the child are returned. The process ID can be used with  System.Posix.getProcessStatus to get the child's exit code. You must either I ensure that all data has been read, or close the handle, before calling  getProcessStatus blockingly. Otherwise you'll get a deadlock. When you G close the handle before all data has been read, then the child gets a  SIGPIPE@ signal. Of course, you can also use the process ID to kill the  child process.  Example:  0h <- h_pipe_from2 $ exec "/usr/bin/foo" ["bar"] See , , , , , chomp, . See HsShellScript#fdpipes for more details. 5Run an IO action as a separate process, and read its stdout, B This is like the backquote feature of shells. The output is read . lazily, as the returned string is evaluated.  The child'Ds output along with its process ID are returned. The process ID can  be used with System.Posix.getProcessStatus to get the child process' exit H code. Be aware that you must evaluate the whole string, before calling  getProcessStatus blockingly, or you'll get a deadlock. MThe whole output is returned, no trailing newline character is removed, like $ the shell does with backquotes. You'll possibly want to apply chomp to the  result.  Example:  ;(txt, pid) <- lazy_pipe_from $ exec "/usr/bin/foo" ["bar"] ... .-- Done, but must read the rest of the output seq (length txt) (return ()) -(Just ps) <- getProcessStatus True False pid See , , , , , . See HsShellScript#fdpipes for more details. 5Run an IO action as a separate process, and read its stderr . The output 6 is read lazily, as the returned string is evaluated.  The child'Cs error output along with its process ID are returned. The process  ID can be used with System.Posix.getProcessStatus to get the child process' M exit code. Be aware that you must evaluate the whole string, before calling  getProcessStatus blockingly, or you'll get a deadlock.  Example:  O(errmsg, pid) <- lazy_pipe_from2 $ exec "/usr/bin/foo" ["bar"] ->- "/dev/null" ... 4-- Read enough error messages, terminate the child. signalProcess killProcess pid  V-- Make sure the file descriptor gets closed, or you may run out of file descriptors.  seq (length errmsg) (return ()) See , , , , , . See HsShellScript#fdpipes for more details. FRun an IO action as a separate process, and optionally connect to its  stdin, its stdout and its stderr output with  pipes. See , , . GForcibly terminate the program, circumventing normal program shutdown.  This is the _exit(2)0 system call. No cleanup actions installed with bracket Eare performed, no data buffered by file handles is written out, etc. "Generate an error message from an errno value. This is the POSIX  strerror system library function. See the man page  strerror(3). 7Read the global system error number. This is the POSIX errno value. This  function is redundant. Use Foreign.C.Error.getErrno instead. 3Print error message corresponding to the specified errno error > number. This is similar to the POSIX system library function perror. See the man page  perror(3). 0Print error message corresponding to the global errno error ? number. This is the same as the POSIX system library function perror. See the man page  perror(3). Print a message to stderr and exit with an exit code  indicating an error. 1failIO msg = hPutStrLn stderr msg >> exitFailure FModify an IO action to return the exit code of a failed program call, # instead of throwing an exception. KThis is used to modify the error reporting behaviour of an IO action which  uses 'run'/'runprog' or 'call'/'subproc'&. When an external program exits with O an exit code which indicates an error, normally an exception is thrown. After  exitcode6 has been applied, the exit code is retruned instead. The caught exceptions are e and . Termination by a D signal is still reported by an exception, which is passed through.  Example: ec <- exitcode $ runprog "foo" ["bar"] See , x, |, y. Create and throw an IOError from the current errno6 value, an optional handle and an optional file name. #This is an extended version of the Foreign.C.Error.throwErrno function R from the GHC libraries, which additionally allows to specify a handle and a file  name to include in the IOError thrown. See Foreign.C.Error.throwErrno, Foreign.C.Error.errnoToIOError.  Convert an IOError to a string. $There is an instance declaration of IOError in Show in the GHC.IO library, but  show_ioerror$ produces a more readable, and more  complete, message. DCall the shell to execute a command. In case of an error, throw the  ProcessStatus (such as (Exited (ExitFailure ec))) as an exception. 6 This is like the Haskell standard library function systemH, except that error handling is brought in accordance with HsShellScript' s scheme. exitcode . system_throw is the same as the system^ function, except that when the called shell is terminated or stopped by a signal, this still  lead to the  ProcessStatusg being thrown. The Haskell library report says nothing about what happens in this case, when using the  system function.  3system_throw cmd = run "/bin/sh" ["-c", "--", cmd] 3This function is deprecated. You should rather use 2, which provides for much better error reporting. <Call the shell to execute a command. In case of an error, a RunError ist thrown. 6 This is like the Haskell standard library function systemH, except that error handling is brought in accordance with HsShellScript's scheme. (It is  not a front end to system.)  9system_runprog cmd = runprog "/bin/sh" ["-c", "--", cmd] Example: Call "foo" and report Errors as IOErrors, rather than RunErrors.  -as_ioe $ system_runprog "foo" ["bar", "baz"] See e,  ,Run a subroutine as a child process, but don't let it produce any messages.  Read its stdout and stderr- instead, and append it to the contents of a Kmutable variable. The idea is that you can run some commands silently, and Kreport them and their messages to the user only when something goes wrong. LIf the child process terminates in a way which indicates an error, then the -process status is thrown, in the same way as  does. If the subroutine  throws an  (Exited ec) exception (of type  ProcessStatus), such as thrown by F, then the child process exits with the same exit code, such that the 4parent process reports it to the caller, again as a  ProcessStatus exception. CWhen the subroutine finishes, the child process is terminated with  0. NWhen it throws an exception, an error message is printed and it is terminated with  1. See HsShellScript#subr for details. NThe standard output (and the standard error output) of the parent process are <flushed before the fork, such that no output appears twice.  Example:  6let handler :: IORef String -> ProcessStatus -> IO () h handler msgref ps = do hPutStrLn stderr ("Command failed with " ++ show ps ++ ". Actions so far: ") 3 msg <- readIORef msgref 0 hPutStrLn stderr msg 4 exitWith (ExitFailure 1)  msgref <- newIORef "" 5do silently msgref $ do putStrLn "Now doing foobar:" ; echo exec "/foo/bar" ["arguments"] 8 silently msgref $ echo exec "/bar/baz" ["arguments"] `catch` (handler msgref) See , x, , Data.IORef. JModify a subroutine action in order to make it suitable to run as a child  process. This is used by functions like y, ,  etc. The action H is executed. When it returns, the (child) process is terminated with  0  (after flushing stdout2), circumventing normal program shutdown. When it O throws an exception, an error message is printed and the (child) process is  terminated with  1. Print text to stdout. This is a shorthand for putStrLn , except for stderr being flushed A beforehand. This way normal output and error output appear in  order, even when they aren't buffered as by default. -An additional newline is printed at the end. outm msg = do  hFlush stderr  putStrLn msg Print text to stdout. This is a shorthand for putStr , except for stderr being flushed A beforehand. This way normal output and error output appear in  order, even when they aren't buffered as by default. "No newline is printed at the end. outm_ msg = do  hFlush stderr  putStr msg Colorful log message to stderr. This prints a message to stderr. When stderr is connected to a terminal  (as determined by  isatty(3),), additional escape sequences are printed, O which make the message appear in cyan. Additionally, a newline character is  output at the end. stdoutD is flushed beforehand. So normal output and error output appear in  order, even when they aren't buffered as by default. See , , . Colorful log message to stderr. This prints a message to stderr. When stderr is connected to a terminal  (as determined by  isatty(3),), additional escape sequences are printed, W which make the message appear in cyan. No a newline character is output at the end. stdoutD is flushed beforehand. So normal output and error output appear in  order, even when they aren't buffered as by default. See , , . Colorful error message to stderr. This prints a message to stderr. When stderr is connected to a terminal  (as determined by  isatty(3),), additional escape sequences are printed, N which make the message appear in red. Additionally, a newline character is  output at the end. stdoutD is flushed beforehand. So normal output and error output appear in  order, even when they aren't buffered as by default. See , , . Colorful error message to stderr. This prints a message to stderr. When stderr is connected to a terminal  (as determined by  isatty(3),), additional escape sequences are printed, V which make the message appear in red. No a newline character is output at the end. stdoutD is flushed beforehand. So normal output and error output appear in  order, even when they aren't buffered as by default. See , , . In case the specified action throws an IOError, fill in its filename field. This way, more useful error messages can be produced.  Example:  :-- Oh, the GHC libraries neglect to fill in the file name executeFile' prog a b c = 2 fill_in_filename prog $ executeFile prog a b c See , . In case the specified action throws an IOError, fill in its location field. This way, more useful error messages can be produced.  Example:  my_fun a b c = do  -- ... i fill_in_location "my_fun" $ -- Give the caller a more useful location information in case of failure  rename "foo" "bar"  -- ... See . In case the specified action throws an IOError, add a line to its location field. This way, more useful error messages can be produced. The  specified string is prepended to the old location, separating it with a newline from the previous location, if any. When using this thoroughly, you ) get a reverse call stack in IOErrors.  Example:   my_fun =  add_location "my_fun" $ do  -- ... See , . This is a replacement for  System.Posix.Process.executeFile . It does ' additional preparations, then calls  executeFile.  executeFile can't normally  <be used directly, because it doesn't do the things which are  outlined here. This are the differences to  executeFile:   stdout and stderr are flushed. K The standard file descriptors 0-2 are made copies of the file descriptors L which the standard handles currently use. This is necessary because they 1 might no longer use the standard handles. See HsShellScript#fdpipes. If the standard handles stdin, stdout, stderr aren't in closed state,  and they aren'4t already connected to the respective standard file M descriptors, their file descriptors are copied to the respective standard  file descriptors (with dup2&). Backup copies are made of the file R descriptors which are overwritten. If some of the standard handles are closed, C the corresponding standard file descriptors are closed as well.  N All file descriptors, except for the standard ones, are set to close-on-exec  (see fcntl(2)3), and will be closed on successful replacement of F the process. Before that, the old file descriptor flags are saved. I The standard file descriptors are set to blocking mode, since GHC 6.2.2 D sets file descriptors to non-blocking (except 0-2, which may get D overwritten by a non-blocking one in step 2). The called program  doesn't expect that. H In case replacing the process fails, the file descriptors are reset to M the original state. The file descriptors flags are restored, and the file L descriptors 0-2 are overwritten again, with their backup copies. Then an  IOError is thrown. < In any IOError, the program is filled in as the file name ( executeFile  neglects this).  The return type is a generic a, rather than ().  Also see HsShellScript#exec. .Check if a handle is connected to a terminal. This is a front end to the  isatty(3)( function (see man page). It is useful, B for instance, to determine if color escape sequences should be  generated. The GHC libraries don' t declare Foreign.C.Error.Errno as instance of  Show. This makes it up. befghijklmnopqrstuvwx%Action to execute in a child process y%action to execute as a child process z&Action to execute as a child process. Process ID of the new process. {|Name of the executable to run Command line arguments }~Name of the executable to run Command line arguments Action to perform &Name or path of the executable to run Command line arguments Full path to the executable Command line arguments Never returns Name or path of the executable Command line arguments Never returns Full path to the executable Command line arguments New environment Never returns Name or path of the executable Command line arguments New environment Never returns Action which won' t be forked 6Action which will be forked and connected with a pipe Result action Action which won' t be forked 6Action which will be forked and connected with a pipe Result action 6Action which will be forked and connected with a pipe Action which won' t be forked Result action 6Action which will be forked and connected with a pipe Action which won' t be forked Result action Handle to replace Handle to replace it with Action (Action, whose output will be redirected File to redirect the output to Result action (Action, whose output will be redirected File to redirect the output to Result action .Action, whose error output will be redirected %File to redirect the error output to Result action .Action, whose error output will be redirected %File to redirect the error output to Result action 9Action, whose output and error output will be redirected File to redirect to Result action 9Action, whose output and error output will be redirected File to redirect to Result action  Text to pipe 4Action to run as a separate process, and to pipe to 4Action to run as a separate process, and to pipe to RReturns handle connected to the standard input of the child process, and the child' s process ID $Action to run as a separate process The called program's standard output $Action to run as a separate process The called program's standard output 6Action to run as a separate process, and to pipe from SReturns handle connected to the standard output of the child process, and the child' s process ID 6Action to run as a separate process, and to pipe from SReturns handle connected to the standard output of the child process, and the child' s process ID $Action to run as a separate process  The action'6s lazy output and the process ID of the child process $Action to run as a separate process  The action'6s lazy output and the process ID of the child process Action to run in a new process Whether to make stdin pipe Whether to make stdout pipe Whether to make stderr pipe Pipes to the new process's stdin, stdout and stderr%, if applicable; and its process id.  Exit code Never returns errno value Corresponding error message errno value errno error number *Text to precede the message, separated by ": " *Text to precede the message, separated by ": " Action to modify Modified action BDescription of the location where the error occurs in the program Optional handle 5Optional file name (for failing operations on files) VA mutable variable, which gets the output (stdout and stderr) of the action appended. The IO action to run. Message to print Message to print Message to print File name to fill in IO action to modify Modified IO action Location name to fill in IO action to modify Modified IO action Location name to add IO action to modify Modified IO action Program to call Search PATH?  Arguments Optionally new environment Never returns Handle to check .Whether the handle is connected to a terminal ^efghijklmnopqrstuvwxyz{|}~^wxyz{|efghijkl}~vutsrqponm[efghijklmnopqrstuvwxyz{|}~ Safe-Infered4One entry of mount information. This is the same as  struct mntent from <mntent.h>. KA list of these is returned by the functions which read mount information. See , , .  Device file ("name of mounted file system")  Mount point Which kind of file system (" see mntent.h") Mount options (" see mntent.h") Dump frequency in days "Pass number on parallel fsck"  Format an Int9 with leading zeros. If the string representation of the IngG is longer than the number of characters to fill up, this produces as  many characters as needed. 1Remove trailing newlines. This is silimar to perl's chomp procedure. Get contents of a file or of stdin. This is a simple frontend to  hGetContents. A file name of "-") designates stdin. The contents are read #lazily as the string is evaluated. L(The handle which we read from will be in semi-closed state. Once all input Fhas read, it is closed automatically (Haskell Library Report 11.2.1). Therefore we don't need to return it). lazy_contents path = do H h <- if path == "-" then return stdin else openFile path ReadMode  hGetContents h Get contents of a file or of stdin eagerly. This is the  same as  lazy_contents , except for the contents being  read immediately. =Test for the existence of a path. This is the disjunction of  Directory.doesDirectoryExist and Directory.doesFileExist,. For an dangling symlink, this will return False. ,Test for the existence of a path. This uses  System.Posix.Files.getFileStatusF to determine whether the path exists in any form in the file system. ' For a dangling symlink, the result is True. 5Test if path points to a directory. This will return True* for a symlink pointing to a directory. It's a shortcut for  Directory.doesDirectoryExist. 6Test if path points to a file. This is a shortcut for  Directory.doesFileExist.  This is the  System.Posix.Files.getFileStatusW function from the GHC libraries, with improved error reporting. The GHC function doesn't include the  file name in the IOError> when the call fails, making error messages much less useful.  getFileStatus' rectifies this. See  .  This is the System.Posix.Files.fileAccessW function from the GHC libraries, with improved error reporting. The GHC function doesn't include the  file name in the IOError> when the call fails, making error messages much less useful.  fileAccess' rectifies this. See  . Create a temporary file. This will create a new, empty file, with a path which did not previously exist in the file system. The path consists  of the specified prefix, a sequence of random characters (digits and letters), and the specified suffix. The file is created with read-write  permissions for the user, and no permissons for the group and others. The ownership is set to the effective user ID of the process. The group  ownership is set either to the effective group ID of the process or to the group ID of the parent directory (depending on filesystem type and mount  options on Linux - see open(2) for details). See , , . Create a temporary directory. This will create a new directory, with a path which did not previously exist in the file system. The path consists  of the specified prefix, a sequence of random characters (digits and letters), and the specified suffix. The directory is normally created with  read-write-execute permissions for the user, and no permissons for the group and others. But this may be further restricted by the process's umask  in the usual way. The newly created directory will be owned by the effective uid of the process. If the directory containing the it has the set group  id bit set, or if the filesystem is mounted with BSD group semantics, the new directory will inherit the group ownership from its parent; F otherwise it will be owned by the effective gid of the process. (See mkdir(2)) See , , . Create a temporary file. This will create a new, empty file, with read-write permissions for the user, and no permissons for the group and others. c The path consists of the specified prefix, a dot, and six random characters (digits and letters).  )tmp_file prefix = temp_file 6 (prefix ++ ".") ""See , , . Create a temporary directory. This will create a new directory, with read-write-execute permissions for the user (unless further restricted by the  process'6s umask), and no permissons for the group and others. c The path consists of the specified prefix, a dot, and six random characters (digits and letters).  'tmp_dir prefix = temp_dir 6 (prefix ++ ".") ""See , , . tCreate and open a temporary file, perform some action with it, and delete it afterwards. This is a front end to the  function. The file  and its path are created in the same way. The IO action is passed a handle of the new file. When it finishes - normally or with an exception -  the file is deleted. See , , . pCreate a temporary directory, perform some action with it, and delete it afterwards. This is a front end to the  function. The directory  and its path are created in the same way. The IO action is passed the path of the new directory. When it finishes - normally or with an exception -  the directory is deleted. NThe action must clean up any files it creates inside the directory by itself.  with_temp_dir doesn',t delete any files inside, so the directory ' could be removed. If the directory isn' t empty, an IOErrorQ results (with the path filled in). When the action throws an exception, and the  temporary directory cannot be removed, then the exception is passed through, rather than replacing it with the IOError. (This is because it's B probably exactly because of that exception that the directory isn't empty and can't be removed). See , , . tCreate and open a temporary file, perform some action with it, and delete it afterwards. This is a front end to the  function. The file  and its path are created in the same way. The IO action is passed a handle of the new file. When it finishes - normally or with an exception -  the file is deleted. See , , . pCreate a temporary directory, perform some action with it, and delete it afterwards. This is a front end to the  function. The directory  and its path are created in the same way. The IO action is passed the path of the new directory. When it finishes - normally or with an exception -  the directory is deleted. NThe action must clean up any files it creates inside the directory by itself.  with_temp_dir doesn',t delete any files inside, so the directory ' could be removed. If the directory isn' t empty, an IOErrorQ results (with the path filled in). When the action throws an exception, and the  temporary directory cannot be removed, then the exception is passed through, rather than replacing it with the IOError. (This is because it's B probably exactly because of that exception that the directory isn't empty and can't be removed).  ?with_tmp_dir prefix io = with_temp_dir 6 (prefix ++ ".") "" io See , , . Create a temporary path. This will generate a path which does not yet exist in the file system. It consists of the specified prefix, a O sequence of random characters (digits and letters), and the specified suffix. DAvoid relying on the generated path not to exist in the file system. Or else you'Bll get a potential race condition, since some other process might  create the path after  temp_pathR, before you use it. This is a security risk. The global random number generator (Random.randomRIO ) is used to x generate the random characters. These might not be that random after all, and could potentially be guessed. Rather use  temp_file or temp_dir. See , . 3Read mount information. This is a front end to the  setmntent(3),  getmntent(3),  endmntent(3) system library functions.  When the  setmntent call fails, the errno value is converted to an IOError and thrown. See , . (Get the currently mounted file systems.  $read_mtab = read_mounts "/etc/mtab" See . 'Get the system wide file system table.  &read_fstab = read_mounts "/etc/fstab" See . Change the working directory temporarily. This executes the specified IO action with a new working directory, and restores it afterwards  (exception-safely). "This is an interface to the POSIX glob) function, which does wildcard expansion 4 in paths. The list of matched paths is returned. It's empty N for no match (rather than the original pattern). In case anything goes wrong 4 (such as permission denied), an IOError is thrown.  This does not> do tilde expansion, which is done (among many unwanted other  things) by wordexp%. The only flag used for the call to glob is GLOB_ERR. MThe behaviour in case of non-existing path components is inconsistent in the  GNU version of the underlying glob function. glob /doesnt_exist/foo will return  the empty list, whereas glob /doesnt_exist/* causes a No such file or directory  IOError. See man pages glob(3) and  wordexp(3). +How many characters to fill up Value to represent as a string MString representation of the value, using the specified number of characters String to be chomped 9Same string, except for no newline characters at the end Either the name of a file, or "-" (The lazily read contents of the file or stdin. either the name of a file, or "-" for stdin .the contents of the file or of standard input Path +Whether the path exists in the file system Path +Whether the path exists in the file system Path 3Whether the path exists and points to a directory. Path .Whether the path exists and points to a file. 0Path of the file, whose status is to be queried Status of the file aNumber of random characters to intersperse. Must be large enough, such that most combinations can' t already  exist. !Prefix for the path to generate. !Suffix for the path to generate. Path of the created file. aNumber of random characters to intersperse. Must be large enough, such that most combinations can' t already  exist. !Prefix for the path to generate. !Suffix for the path to generate. Generated path. !Prefix for the path to generate. Path of the created file. !Prefix for the path to generate. Path of the created directory. aNumber of random characters to intersperse. Must be large enough, such that most combinations can't  already exist. !Prefix for the path to generate. !Suffix for the path to generate. Action to perform. *Returns the value returned by the action. aNumber of random characters to intersperse. Must be large enough, such that most combinations can't  already exist. !Prefix for the path to generate. !Suffix for the path to generate. Action to perform. *Returns the value returned by the action. !Prefix for the path to generate. Action to perform. *Returns the value returned by the action. !Prefix for the path to generate. Action to perform. *Returns the value returned by the action. aNumber of random characters to intersperse. Must be large enough, such that most combinations can' t already  exist. !Prefix for the path to generate. !Suffix for the path to generate. Generated path. File to read (typically /etc/mtab or /etc/fstab) Mount information in that file New working directory Action to run Pattern Sorted list of matching paths ++$ Safe-InferedDo a call to the  realpath(3)t system library function. This makes the path absolute, normalizes it and expands all symbolic links. In case of an  error, an IOError is thrown. 7Determine the target of a symbolic link. This uses the  readlink(2)L 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.ioeGetFileNameg. 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". 7Determine the target of a symbolic link. This uses the  readlink(2)G system call. The target is converted, such that it is relative to the % current working directory, if it isn'mt 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. RDetermine whether a path is a symbolic link. The result for a dangling symlink is True8. The path must exist in the file system. In case of an  error, a proper IOError is thrown. Return the normalised, absolute version of a specified path. The path is made absolute with the current working directory, and is syntactically 5 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 6 called from a shell. The difference lies in the shell'-s idea of the current working directory. See  for details. See , . "Make a symbolic link. This is the  symlink(2)# function. Any error results in an IOError9 thrown. The path of the intended symlink is included in  the IOError and  can be accessed with ioeGetFileName# from the Haskell standard library IO.  Call the du program. See du(1). )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. 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. Remove file. This is Directory.removeFileF from the Haskell standard library, which is a direct frontend to the  unlink(2) system call in GHC. '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. 9Note 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 cdj 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'7m talking about bash, regardless of whether started as /bin/bash or in compatibility mode, as /bin/sh. I  presume it'7s the standard behavior for the POSIX standard shell.) See . 1Get program start working directory. This is the PWD environent G variable, which is kept by the shell (bash, at least). It records the I 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. Execute /bin/chmod chmod = run "/bin/chmod" Execute /bin/chown chown = run "/bin/chown" Execute the cp program Execute the mv program Run the command  mt status) for querying the tape drive status, and  parse its output. 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 C 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 a file. This first tries g, 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 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_mvp, 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 Pnew 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  , . :Move a file or directory, and cope with read only issues. ;This moves a file or directory, using the external command mvQ, sets the necessary write permissions beforehand, and restores them afterwards. This is less efficient than  force_rename, because the external program mvE needs to be called, but it can move files between file systems. See  force_cmd for a detailed description.  pforce_mv src tgt = fill_in_location "force_mv" $ force_cmd (\src tgt -> run "/bin/mv" ["--", src, tgt]) src tgt See  , .  Rename a file with , or when necessary with ", and cope with read only issues. fThe necessary write permissions are set, then the file is renamed, then the permissions are restored.  First, the | 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 , , ,  .  PCall a command which moves a file or directory, and cope with read only issues. zThis function is for calling a command, which renames files. Beforehand, write permissions are set in order to enable the boperation, and afterwards the permissions are restored. The command is meant to be something like rename or run "/bin/mv". WIn 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'7t know what this behaviour is supposed to be good for. /This function copes with the case that the file/adirectory 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 Kto 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 0write 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 Kforce_cmd (\from to -> run "/bin/mv" ["-i", "-v", "--", from, to]) from to See , , .  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.  Tforce_writeable path io = force_writeable2 path (io >>= \res -> return (path, res))  Example:  N-- Need to create a new directory in /foo/bar, even if that's write protected 2force_writeable "/foo/bar" $ mkdir "/foo/bar/baz" See  ,  .  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 t or directory. Therefore it returns the new name, along with another return value, which is passed to the caller. DThe writeable status is only changed back if it has been changed by force_writeable21 before. An IOError is raised when the user doesn'h have Q permission to make the file or directory writeable, or when the new path doesn' t exist. See  ,  .   Call the fdupes8 program in order to find identical files. It outputs a E 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 F action. It is split to a list of lists of paths, such that each list I of paths corresponds to one of the directories which have been searched  by the fdupesA program. If you just want groups of identical files, then apply  map concat to the result. The fdupes / program doesn'ut handle multiple occurences of the same directory, or in recursive mode one specified directory containing another, c properly. The same file may get reported multiple times, and identical files may not get reported./  The paths are normalised (using ). !path 8noramlized, absolute path, with symbolic links expanded Path of the symbolic link 4The link target - where the symbolic link points to path of the symbolic link *target; where the symbolic link points to path %Whether the path is a symbolic link. path <noramlized, absolute path, with symbolic links not expanded contents of the symlink (from) path of the symlink (to) block size, this is the  --block-size option. 7path of the file or directory to determine the size of size in blocks path path path path Command line arguments Command line arguments source  destination source  destination file and block number  Old path  New path  Old path  New path  Old path  New path  Old path New path or target directory   Old path  New path  3Command to execute after preparing the permissions  Old path New path or target directory  $File or directory to make writeable Action to perform 'Returns the return value of the action  $File or directory to make writeable Action to perform  Options for the fdupes program "Directories with files to compare qFor each set of identical files, and each of the specified directories, the paths of the identical files in this  directory. !     !     !      Safe-Infered Error reporting wrapper for the main function. This catches any + HsShellScript generated exceptions, and IOError s, prints # an error message and exits with  exitFailure. The main function  typically looks like this:  main = mainwrapper $ do ... The exceptions caught are &, e,  and IOError.  Should be main Wrapped main  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklwxyz|}~         w xzefghijkl}~y| !"#$%&'()*+,-./012344567899:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqqrstuvwxyz{|}~      !"#$%hsshellscript-3.1.0HsShellScript.GetOptHsShellScript.ShellHsShellScript.PathsHsShellScript.ArgsHsShellScript.ProcErrHsShellScript.MiscHsShellScript.Commands HsShellScriptSystem.EnvironmentgetArgsSystem.Posix.Files getFileStatus fileAccessArgDescrOptArgReqArgNoArgOptDescrOptionArgOrder ReturnInOrderPermute RequireOrder usageInfogetOpt shell_command shell_quotequote0quote slice_path unslice_pathnormalise_pathslice_filenameslice_filename'unslice_filename split_pathdir_part filename_part unsplit_path unsplit_partssplit_filenamesplit_filename'unsplit_filenamesplit3unsplit3 test_suffix absolute_pathabsolute_path_byabsolute_path'guess_dotdot_comps guess_dotdotArgErrorargerror_messageargerror_usageinfo ArgumentsArgumentPropertyArgumentDescriptionargdesc_short_argsargdesc_long_argsargdesc_argarg argdesc_timesargdesc_argargnameargdesc_argarg_descriptionargdesc_argarg_tester ArgtesterArgumentValueSpecArgumentValue_optionalArgumentValue_requiredArgumentValue_none desc_short desc_long desc_directdesc_value_requireddesc_value_optional desc_times desc_oncedesc_at_least_oncedesc_at_most_once desc_at_leastdesc_any_times desc_at_most desc_argnamedesc_description desc_tester readtester desc_integerdesc_nonneg_integerargname argname_aargdescgetargsgetargs_orderedgetargs'getargs_ordered' arg_switch arg_timesargs_optargs_req reqarg_opt reqarg_req optarg_opt optarg_req args_noneargs_allargs_oneargs_at_most_oneargs_at_least_one arg_conflicts arg_occurs usage_infounsafe_getargsunsafe_getargs_orderedRunErrorre_progre_parsre_envre_wdre_psre_errno hssh_c_isattydup2close c_fcntl_dupfdc_restore_fdflagsc_prepare_fd_flags_for_execc_save_fdflagsforeign_strerror _exit_primc_close_on_exec setFileMode'subproccallspawn spawn_locrun show_runerrorexplain_processstatusto_ioeas_ioerunprogechoexecexecpexeceexecpe-|-=|--|==|=redirectredirect_helper->-->>-=>-=>>--&>--&>>--<- err_to_out out_to_err pipe_fork_duppipe_to h_pipe_to pipe_from pipe_from2 h_pipe_from h_pipe_from2lazy_pipe_fromlazy_pipe_from2pipes_exitstrerrorerrnoperror'perrorfailIOexitcode throwErrno' show_ioerror system_throwsystem_runprogsilentlychildoutmoutm_logmlogm_errmerrm_fill_in_filenamefill_in_location add_location execute_fileunsafeWithHandleFdunsafeWithHandleFd'isatty flush_outerrtyCon_ProcessStatusreceive_ioerror send_ioerrorencode_ioerrordecode_ioerror ioe_types ioetype_num num_ioetypeMntent mnt_fsnamemnt_dirmnt_typemnt_optsmnt_freq mnt_passnoglobfreedo_glob c_getmntent endmntent setmntentc_mkdirc_closehsshellscript_open_nonvariadico_EXCLo_CREATzeroschomp lazy_contentscontents path_exists path_exists'is_diris_filegetFileStatus' fileAccess' temp_filetemp_dirtmp_filetmp_dirwith_temp_file with_temp_dir with_tmp_file with_tmp_dir temp_pathuntilIO read_mounts read_mtab read_fstabwith_wdglobforeign_renameforeign_symlinkhsshellscript_get_readlinkhsshellscript_get_realpathrealpathreadlink readlink' is_symlink realpath_ssymlinkdumkdirrmdirrmcdpwdchmodchowncpmvnumberparse_mt_status mt_statusrename rename_mv force_renameforce_mvforce_rename_mv force_cmdforce_writeableforce_writeable2fdupesreplace_location mainwrapper$fExceptionArgError$fShowArgError$fOrdArgumentDescription$fEqArgumentDescription unix-2.5.1.0System.Posix.Process.Internals ProcessStatus $fShowErrno$fExceptionProcessStatus$fTypeableProcessStatus$fExceptionRunError