\input texinfo   @c -*-texinfo-*-
@c @c @c @c @c @c @c @c @c @c @c @c @c @c @c @c @c @c @c @c @c @c @c @c @c @c 
@c %**start of header
@include version.texi
@setfilename pexec.info
@settitle pexec @value{VERSION}
@c %**end of header
@c @c @c @c @c @c @c @c @c @c @c @c @c @c @c @c @c @c @c @c @c @c @c @c @c @c 

@ifinfo
This manual page documents briefly the pexec program.
@end ifinfo

@c @c @c @c @c @c @c @c @c @c @c @c @c @c @c @c @c @c @c @c @c @c @c @c @c @c 

@copying
This manual page documents briefly the @code{pexec} program.

@quotation
This software was written by Andr@'{a}s P@'{a}l. The core part was written 
while working for the Hungarian-made Automated Telescope (HAT) project 
to make the data processing more easier and therefore find many-many 
extrasolar planets. See more information about this project: 
@code{http://hatnet.hu}. Another internal libraries (e.g. @file{numhash.[ch]}) 
were primarily written/developed for other projects.
@end quotation

This documentation: Copyright (C) 2007, 2008; Andr@'{a}s P@'{a}l.

@quotation
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.2
or any later version published by the Free Software Foundation;
with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
A copy of the license is included in the section entitled "GNU
Free Documentation License".
@end quotation
@end copying

@c @c @c @c @c @c @c @c @c @c @c @c @c @c @c @c @c @c @c @c @c @c @c @c @c @c 

@ifnottex
@node Top
@top pexec
@end ifnottex

@titlepage
@title pexec
@subtitle A program for executing commands or script pieces in parallel.
@subtitle @value{UPDATED}, pexec version @value{VERSION}

@author by Andr@'{a}s P@'{a}l (apal@@szofi.elte.hu)

@page
@vskip 0pt plus 1filll
@insertcopying 
@end titlepage

@c @c @c @c @c @c @c @c @c @c @c @c @c @c @c @c @c @c @c @c @c @c @c @c @c @c 

@menu
* General information::
* Command line options::
* Examples::
* Additional information::
* Copying This Manual::
@end menu

@c @c @c @c @c @c @c @c @c @c @c @c @c @c @c @c @c @c @c @c @c @c @c @c @c @c 

@node General information
@chapter General information

@menu
* General options::
* Redirecting standard streams::
* Execution using remote hosts::
* Mutual exclusions and atomic command execution::
* Hypervisor mode::
* Logging::
@end menu

@section Name
@code{pexec} - execute commands or shell scripts in parallel on a single
host or on remote hosts using a remote shell

@section Description
This manual page documents briefly the @code{pexec} program. @code{pexec}
executes in parallel the given command or shell script (e.g. parsed
by @code{/bin/sh}) on the local host or on remote hosts, 
while some of the execution parameters, namely the redirected standard input,
output or error and environmental variables can be varied.

The given program or script is executed as many times as how many 
parameters are specified in the command line or read from a given
parameter file. Each parameter is a simple string which can be used
either to pass to the program/script as the value of an environmental variable 
or it can be used in the format of the file names where the 
standard input, output or error are optionally redirected from or to.

Moreover, more than one shell command script can also be passed to
parallel execution, in this case there is no need for parameters or the number
of the parameters taken from command line (or read from a parameter file)
must be the same as the number of the distinct shell command scripts.

The program is capable to automatically swallow the standard output and
error (to @code{/dev/null}), or collecting them via pipes and dump to the 
invoker's standard output or error (with optional line headers or trailers which 
can be used to distinguish between the output of the distinctive processes).

The execution on remote hosts is done using a remote shell which 
both builds a tunnel between the invoking and the remote host(s) and
do the authentication and ensures the security (if a secure remote shell
is used). Hence, there is no need to run standalone daemons on the
remote side: the remote shell itself executes the @code{pexec} program
in daemon mode when the standard input and output of the latter is bound
to the remote shell to form a (secure and authenticated) tunnel. See
the appropriate section below for a more detailed explanation.

In order to avoid unexpected I/O load or to synchronize individual
tasks, @code{Bpexec} supports mutual exclusions 
(@i{mutex}es) and atomic command executions. 
The maximum number of simultaneous tasks can be controlled by a 
hypervisor daemon: with such a daemon, concurrent
@code{pexec} instances can start without an unexpectedly high load.

@section Synopsys

General invocation:

@code{pexec [options] [--] command [arguments]}

@code{pexec [options] -c [--] script}

@noindent
or

@code{pexec [options] -m [--] 'script1' ['script2'...]}

@noindent 
Remote control, mutual exclusions and atomic command exectuion:

@code{pexec [-j|--remote] [options]}

@code{pexec [-j|--remote] [options] [-l|-u <mutex>]}

@code{pexec [-j|--remote] [options] -a -m <mutex> [-c] [--] command [arguments]}

@noindent 
Hypervisor daemon:

@code{pexec [-H|--hypervisor] [options] start|stop}

@node Command line options
@chapter Command line options

@node General options
@section General options

@table @code
@item @code{-h}, @code{--help}
Gives general summary about the command line options. 

@item @code{--version}
Gives some version information about the program.

@item @code{-s}, @code{--shell} <@i{full shell path}>
Full path (e.g. @code{/bin/sh}) of the shell to be used for script execution.

@item @code{-c}, @code{--shell-command}
Use a shell (see @code{-s|--shell} also) to interpret the command(s)
instead of direct execution.

@item @code{-m}, @code{--multiple-command}
Allow multiple individual shell command scripts to be executed 
in parallel with the variation of the parameters (see notes at 
@code{-l|--list} or @code{-f|--listfile}).

@item @code{-e}, @code{--environment} <@i{environmental variable name}>
Name of an environmental variable which is set to the respective
parameter (taken from the command line or the parameter file)
before each execution and can be read from the program or shell script.
In shells like @code{/bin/bash}, such environmental variables can 
easily be read as if they would be a normal shell variable (see 
the examples also).

@item @code{-n}, @code{--number} <@i{number of parallel processes}> | @i{auto} | @i{managed} | @i{ncpu}
The maximal number of processes running simultaneously. 
By default (omitting @code{-n|--number} or specifying @code{-n|--number} @i{auto})
the program tries to connect to a local hypervisor which keeps track
the resources of the system (see sec. Hypervisor Mode for more details).
If the connection to the local hypervisor failed, the program
derives the number of available processing units on the local host
using the content of @code{/proc/cpuinfo} or other system-specific method
(on operating systems with different kernel than Linux). 
If the argument of @code{-n|--number} is @i{managed}, @code{pexec}
searches only for hypervisor and terminates with a non-zero exits status
if the connection is failed. If the argument for @code{-n|--number} is 
@i{ncpu}, the program does not try to connect to the hypervisor (even 
if it is running) but uses the available information 
(@code{/proc/cpuinfo} or other system-specific method) 
to figure out the number of processing units.

@item @code{-C}, @code{--control} [@i{<host>}:]@i{<port>}|@i{<path>}
This option specifies the control port of a hypervisor which is 
used to control the number of simultaneously run tasks.
By default, this is the UNIX doman socket @code{/tmp/pexec.sock}. 
If the specified port is a single number, @code{pexec} connects to the
given port on the localhost, if a host is specified, the program
connects to the given host and port; otherwise if it is a valid
path, @code{pexec} connects to that UNIX domain socket. Note that 
the hypervisor socket does not have a default port number, i.e. 
the port argument is mandatory after the host name. 
See sec. Hypervisor Mode for more details.

@item @code{-p}, @code{--list} <@i{space separated list of parameters}> [@code{-p} ...]
The single-argument form of main parameter list: each switch can accept 
one command line argument, thus if more than one parameter is defined 
after a single @code{-p} or @code{--list} option, the delimiter whitespace 
should be escaped somehow. Note that if there are more than one shell commands
to be executed, the total number of parameters should be the same
as the number of the individual shell commands or no parameters
should be declared.

@item @code{-r}, @code{--parameters} <@i{list of parameters up to the next switch}> [@code{-r} ....]
The multiple-argument form of the main parameter list: each switch
can be followed by multiple arguments up to the next switch, i.e. the
nearest command line argument which begins with at least a single dash. 
Note that if in either of the arguments there is a space (or 
there are more spaces), such arguments will be splitted among the delimiting
whitespaces. Note also that the parameter specifications by 
@code{-p|--list} and @code{-r|--parameters} can be mixed, depending
on the actual problem or convenience. See also some notes 
below at @code{-f|--listfile}.

@item @code{-f}, @code{--listfile} <@i{file containing the parameters}>
The main parameter list file. The parameters are read line by 
line while the parts of the file after a '#' (hashmark) are treated
as comments. By default, the parameter is the first whitespace
delimited column of the line if the line is not empty (or fully commented
out). The parameters can be gathered from another column (see
@code{-w|--column}) or the complete line can be threaded as a single
parameter (see @code{-t|--complete}). If the parameters are read from
a single column and some of the parameters are wanted 
to contain space(s), it can be put between double quotation marks ("..."). 
Note that if there are more than one shell commands
to be executed, the total number of parameters should be the same
as the number of the individual shell commands or no parameters 
should be declared. Note also that the parameters can only be defined
from command line @i{or} from this list file, i.e. @code{-f|--listfile}
and @code{-p|--list|-r|--parameters} cannot be mixed. 

@item @code{-w}, @code{--column} <@i{column index}>
The column from where the parameters should be taken if they are read
from a parameter file (see @code{-f|--listfile} above). If the given 
column is not exist in the current line, that line will silently be omitted.

@item @code{-t}, @code{--complete}
Threat the whole line as a single parameter if the parameters are 
read from a file. Empty lines and all parts in the line after a '#'
(hashmark) are omitted. Note that contrary to the argument splitting
near @code{-r|--parameters} (or @code{-p|--list}), the content
of a line won't be splitted into distinct parameters even if there
are whitespaces.

@item @code{-z}, @code{--nice} <@i{nice}>
Sets the scheduling priority of @code{pexec} and all children (executed
processes) to the priority defined by the nice value.

@item @code{--}
A marker after when the command begins. This is optional but useful
to limit the parameter list of @code{-r|--parameters} or 
when the command itself begins with a literal '@i{-}' (dash) character (the
latter is a rear case, as one can expect). This marker can also be used 
to emphasize the (beginning of the) command itself.

@end table

@node Redirecting standard streams
@section Redirecting standard input, output and error

@table @code

@item @code{-i}, @code{--input} <@i{input file format}>
The name of the input file which is used for redirecting the standard
input. If this argument is omitted, the standard input will be empty
(i.e. /dev/null) unless the other two standard file redirection specifications
are also omitted @i{and} there is not more than one parameter; 
in this case the standard streams are inherited by this single executed
process. If the input file argument is a single existing file, all command
execution processes will use the same file for input. If the argument
contains the format elements @i{%s} and @i{%d}, these are replaced
to the respective parameter name or the sequence number of the parameter
(which is between 1 and the total number of parameters). 

@item @code{-o}, @code{--output} <@i{output file format}>
The name of the output file which is used for redirecting the standard
output. If this argument is omitted, the standard output will be
swallowed (unless the other two redirections are also omitted, 
see @code{-i|--input} for this case). 
If the argument is a single file, all command
execution processes writes their output to this single file. If
the argument is a single dash or @code{-1}, all of the standard outputs are 
gathered to the invoker's standard output. If the argument is
@code{-2}, the standard outputs are gathered to the standard error
of the invoker.
If the argument contains the format elements @i{%s} or @i{%d}, 
these are replaced to the respective parameter name and the standard 
output will be a different file for each process. Note that in the
second case, when the output file is a single, non-formatted file name,
the outputs are collected via pipes and there is no guarantee for
subsequent data order, even the outputs of different processes can be
mixed (moreover, if the output is ASCII text, parts of lines can also
be mixed). This means that the processes will feel their standard outputs
as pipes not as regular files. Note also that if only @i{I%s} is
used in the formatted file name, the parameter list should contain
unique parameters, unless some of the output files will be lost and/or
written in parallel, yielding unexpected result.

@item @code{-u}, @code{--error}, @code{--output-error} <@i{output error file format}>
The name of the output file which is used for redirecting the standard
error. All of the properties of the standard error redirection mechanism
is the same as for the standard output, see @code{-o|--output} above
for a more detailed explanation. The only exception is the single dash: 
specifying a single dash to @code{-u|--error} results that the
standard errors are going to be collected to the standard error of the invoker.
To redirect the errors to the standard output, use @code{-1} as an argument.

@item @code{-R}, @code{--normal-redirection}
This is equivalent to specifying @code{--output -} @i{and} @code{--error -}
@i{and} @code{--input /dev/null}.
Since redirecting the @i{same} standard input to all of the executed commands
is nearly meaningless in a parallel environment, this argument implies
an expectable behaviour, i.e. the standard output and error streams 
of the commands are gathered to the invoker's standard output.

@item @code{-a}, @code{--output-format} <@i{Ioutput line format}>
The format of the final standard output redirection if the output of 
all of the processes are gathered into the same file. The format 
can contain any character, while the @i{%s} and @i{%d} format
elements are replaced as it was written in @code{-i|--input}. The
line itself without the trailing newline character is represented
by @i{%l}. Extra characters (e.g. tabulators, newlines) can also 
be inserted using the well-known escape sequences. Note that
the trailing newline is always set implicitly unless it is disabled
by @code{-x|--omit-newlines}. The line buffering yielded by the simple
format of @i{%l} can also
be useful if all of the standard outputs (or errors) are collected in a single
file and the invoker wants to avoid the inter-line confusion of output 
(i.e. if this redirection formatting is omitted, no line buffering
is done at all).

The @code{printf}-like alignment syntax can also be used near @i{%s},
@i{I%l} and @i{%d} (both in the post-formatting and in the redirection
file name formats): the number before the period indicates the minimum size
and its sign refers to the alignment (positive: right alignment, negative: left 
alignment) while the number after the period indicates the minimum number
of padding zeroes for numerical values. E.g the @i{%5.3d} would yield 
@i{" -042"} for -42.

@item @code{-b}, @code{--error-format} <@i{error line format}>
The same final redirection format for the standard error. 
See @code{-a|--output-format} for more details.

@item @code{-x}, @code{--omit-newlines}
If the final redirection of the standard output or error are re-formatted
using @code{-a|--output-format} and/or @code{-b|--error-format}, the
trailing newlines are disabled and only written if specified directly
using '@i{\n}'.

.PP
Note that in the case when no redirection is specified @i{and} the
number of the parameters is exactly one or less; the executed process
will inherit the standard files directly from the invoker. Otherwise,
if there is more than one parameter in the list, the redirection
will be defined by the @code{-i|--input}, @code{-o|--output} and @code{-u|--error}
options. It means if one of these options is omitted, the respecting standard
stream will be redirected from/to @code{/dev/null}. In other words, if
any of these redirection options is specified, the latter rules will
define the redirection, independently of the number of the parameters.

@end table

@node Execution using remote hosts
@section Execution using remote hosts

The execution on remote hosts is done using a remote shell which 
both builds a tunnel between the invoking and the remote host(s) and
do the authentication and ensures the security (if a secure remote shell
is used). It means that on the remote hosts(s) there should be:
@itemize @bullet
@item
an appropriate daemon for the remote shell to connect to;
@item
the appropriate version of @code{pexec} which is started in daemon mode;
@item
and the same file structure if the executed command rely on some files 
(see below the option @code{-k|--local-files} for more details about
this issue).
@end itemize
@noindent
The same file structure which might be required the script can be ensured by
an NFS or other types of network filesystem mounts. Note that in this case it 
is highly crucial since it is not determined which parameter is executed
on which host. I.e. the executed script and the underlying filesystem should
ensure the same result on every single host; otherwise one can get
unexpected results.

@table @code

@item @code{-g}, @code{--remote-shell} "<@i{remote_shell}> [<@i{arguments}>]"
The name or full path of the remote shell to be used for building the
tunnel between the local and the peer host(s). The default
remote shell is @code{/usr/bin/ssh} with no extra arguments. Note that
if additional arguments are defined for the remote shell, 
the whole argument of the switch should be escaped somehow (e.g. put
between quotation marks). The connection and authentication are performed
sequentially @i{before} executing anything and only once for each host: 
if the the authentication requires interactivity (e.g. typing a password), it 
is also done before the whole procedure starts.

@item @code{-n}, @code{--number} <@i{hostspec}>:[<@i{processes}>],...,[<@i{processes}>]
This more sophisticated form of the @code{-n|--number} option is used
to specify a comma-separated list of names and expected capacities 
of the remote hosts used for parallel execution. 
The @i{hostspec} argument is the host specification
argument passed directly to the remote shell which should be capable
to understand it. In the most cases, it is simply the name of the
peer machine, in the case of @code{ssh}, the username also can be 
passed using the well-known @i{username@@hostname} form.
The host specification must always be followed by a literal colon ('@i{:}').
Optionally, the maximum number of processes to run on that host can
follow the colon. If it is omitted, the maximum number of processes
are determined on the peer side automatically (yielding the same number
of processes as it is determined by @code{--number} @i{auto}, see above),
moreover the literal @i{auto}, @i{managed} and @i{ncpu} arguments
can also be used, like in the case of local host parallelization.
The number of processes executed on the invoker's host can simply be
specified by a single positive number, or by one of the 
keywords @i{auto}, @i{managed} and @i{ncpu} (just in the case
of simple local host execution).

Note that the host specifications are additive, i.e. if the same machine
(including the local one when the @i{hostspec} and its colon is omitted)
is defined more than once, the maximum number of processes are added. 
It can yield unexpected results if the number is omitted after the colon,
i.e. it is determined automatically, in this case the automatically
determined maximum number of processes are also added, yielding a
large load.

@item @code{-k}, @code{--local-files} [TBD]
If this option is enabled, the remote daemons will read or store the
redirected standard input, output and error files on the local side.
Otherwise (by default), these files are read from/stored to the invoker's host
and tunneled to/from the peer. 

Note that if the redirected files are parameter-specific @i{and} 
tunneled to/from the remote hosts, then these files 1/
on the invoker's host are seen as regular files;
2/ on the remote hosts are seen as pipes. Otherwise, if the redirection
is done from/to a single file, both the local and remote hosts will
see their standard outputs and errors as pipes but the standard input
is still a regular file on the local side and a pipe on the remote side.

@item @code{-P}, @code{--pexec} <@i{pexec-path}>
The full path of the @code{pexec} program on the remote hosts. If this
option is omitted, the invoker tries to figure out from the invoking
syntax (see @i{argv[0]}) and the current path. This issue can be a bottleneck
if the program is installed differently on the hosts since the remote shells
executes their commands in non-interactive and/or non-login modes which
might result different paths.

@item @code{-T}, @code{--tunnel} 
If this option is the first in the positional argument list of @code{pexec},
the program will start in tunnel daemon mode. This parameter is not used during
the regular usage but used by @code{pexec} itself to start daemons
via the remote shell tunnels.

@end table

@node Mutual exclusions and atomic command execution
@section Remote control, mutual exclusions and atomic command execution

Running instances of @code{pexec} can be controlled remotely to gather
some status information of the paralleled execution and implement
mutual exclusions.

@table @code

@item @code{-y}, @code{--bind} @i{inet}|@i{unix}|@i{<port>}|@i{/<path>}
This option lets @code{pexec} to be remote controlled via internet
(AF_INET family sockets) or via UNIX domain sockets. If the 
literal @i{inet} or @i{unix} is specified as an argument
for this switch, the port or the path of the named socket will be 
assigned randomly; but both of them can be specified directly by
a single integer number (referring to an INET port) or by an absolute
path (beginning with a literal slash, referring to an UNIX domain named
socket). In all cases, the currently assigned port or path will be
reported in the logs and will be exported as an environmental
variable with the name of @i{PEXEC_REMOTE_PORT} (by default, 
see also @code{-E|--pexec-connection-variable}). This environmental
variable is inherited by all processes executed on the local host
@i{and} tunneled to the remote hosts too and inherited by the
all of the processes executed by @code{pexec} daemons.

@item @code{-E}, @code{--pexec-connection-variable} <@i{environment_variable_name}>
This option overrides the default environment name @i{PEXEC_REMOTE_PORT}
to the specified value, which is used by the 
@code{-p|--connect} @i{auto} combination to determine the control
socket with which the running @code{pexec} instance can be controlled
or polled. Note that in practice there is no need to change this 
variable since separate @code{pexec} jobs uses different environment space
(i.e. a process which changes an environment variable affects the
variables of its childrend only).

@item @code{-j}, @code{--remote}
If this option is the first in the argument list of @code{pexec}, then
the program can be used to control and poll the status of 
other running instances of @code{pexec} @i{if} these other running
ones were started with enabling the remote control by @code{-y|--bind} 
(see above).

@item @code{-p}, @code{--connect} @i{auto}|[@i{<host>:}]@i{<port>}|@i{/<path>}
With this option one can specify the @code{pexec} instance which is to be
remote controlled. Since connecting to something is mandatory for
doing remote control, omitting this option is equivalent with
@code{--connect auto} and in this case the program gets the remote
port information using the environmental variable @i{PEXEC_REMOTE_PORT}
(by default, see also @code{-E|--pexec-connection-variable}).
If this environmental variable is not exist, the connection will fail
and @code{pexec} exits with an error. 

The @code{pexec} instance to be remote controlled can also be specified
directly by specifying either the INET host and port 
(in this case if host is omitted, @i{localhost} is used as default
but the port number is mandatory since there is no default port) 
or the absolute path of the UNIX domain socket. Note that in the most
shells @code{--connect auto} is equivalent to 
@code{--connect $PEXEC_REMOTE_PORT} (by default, see also 
@code{-E|--pexec-connection-variable}) since the environmental variables
can be referred as a normal shell variable.

@item @code{-t}, @code{--status}
This option prints the actual status of the running jobs in a human-readable
form to the invoker's standard output. It can be used for polling 
the progress of the whole paralleled execution.

@item @code{-l}, @code{--lock}, @code{--mutex-lock} @i{<mutex-name>}
@item @code{-u}, @code{--unlock}, @code{--mutex-unlock} @i{<mutex-name>}
With these options mutual exclusions (@i{mutex}es) 
can easily be implemented: if no one else performs the same locking, the 
program exists immediately, otherwise it would block until 
someone else releases the mutex (i.e. by calling @code{-u|--unlock|--mutex-unlock}
with the mutex of the same name).

@item @code{-m}, @code{--mutex} @i{<mutex-name>}
@item @code{-d}, @code{--dump} @i{<filename>} | @code{-s}, @code{--save} @i{<filename>} 
If one of the @code{-d|--dump} or @code{-s|--save}
options are specified, the program prints the content of the file
to standard output or stores the data read from the standard input to the
specified file, respectively (like @code{cat} or @code{tee} with the
difference that @code{-s|--save} does not copy the content to standard output
like @code{tee} does so). If a mutex is specified by @code{-m|--mutex},
@code{pexec} locks the mutex @i{before} the dump/save operation and
unlock @i{after} it is done, i.e. @code{pexec -j -d something.txt -m mymutex}
is equivalent with 
@code{( pexec -j -l mymutex && cat something.txt && pexec -j -u mymutex )}.

@item @code{-m}, @code{--mutex} @i{<mutex-name>}
@item @code{-a}, @code{--atomic} [@code{-c|--shell-command}] [@code{--}] @i{<command>} 
With this option, an atomic execution respective to a given mutex
(specified by @code{-m|--mutex}) of the command can be performed.
For example, @code{pexec -j -m mymutex -a cat something.txt}
is equivalent with 
@code{( pexec -j -l mymutex && cat something.txt && pexec -j -u mymutex )}.

@end table

@noindent
Note that if the lock and unlock operations are in the same pipeline
@i{and} these operations use the same mutex, the invoker should
ensure that the locking call exists before the unlock request could start 
(otherwise the whole parallel execution blocks infinitely).
Like so, if dump and a save operations with the same mutex present
in the same pipeline, the intermediate programs should delay the
data propagation: the save part must not get any data until the 
dump part flushes everything to its standard output
(otherwise even this single pipeline blocks infinitely).

Note also that the whole remote controlling procedure is transparent to the
remote host execution, i.e. every necessary parameter,
environmental variable and mutex lock/unlock request will propagate
via the remote shell tunnel. Therefore the end-user won't see any difference
(and do not have to bother with these details in his final invocation)
between the purely local and remote execution processes.

@node Hypervisor mode
@section Hypervisor mode

The program @code{pexec} is capable to run in hypervisor mode. 
The hypervisor daemon acts as a resource controller, i.e. other
running instances of @code{pexec} ask the hypervisor if there is
available resource or not. The main purpose of the hypervisor
daemon is to balance the usage between concurrent running @code{pexec}
instances in order to avoid unexpectedly high load.

@table @code

@item @code{-H}, @code{--hypervisor} [@i{start}|@i{stop}]
This option starts @code{pexec} in hypervisor mode. By default, the
hypervisor is not detached from the terminal. If @i{start} is
given, the deamon is detached and put into background. Such
running daemons can be stopped using the @i{stop} argument.

@item @code{-C}, @code{--control} @i{<port>}|@i{/<path>}
This option specifies the control port used by the hypervisor to listen
for connections. By default, this is the UNIX doman socket 
@code{/tmp/pexec.sock}. If the specified port is a single number, 
@code{pexec} creates an INET server socket, otherwise if it is a valid
path, an UNIX domain socket is created.

@item @code{-n}, @code{--number} <@i{number of parallel processes}> | @i{auto} | @i{ncpu}
The maximum number of parallel processes which is allowed to be executed
simultaneously by all of the connected @code{pexec} programs together. 
By default, @code{pexec} uses @code{/proc/cpuinfo} (or other system-dependent
way) to figure out the number of available processing units and use this
number as the maximum of parallel processes.

@item @code{-l}, @code{--load}, @code{--use-load} <@i{load}>
This option limits the number of processes to yield a normalized
load less than unity, still keeping the number of simultaneous 
processes not to be greater than the value specified by @code{-n|--number}. 
The normalized load is the actual load (averaged on 1, 5
or 15 minutes) divided by the maximum number of parallel processes.
The argument of this switch can be @i{0}, @i{1} or @i{2},
or @i{1min}, @i{5min} or @i{15min}, respectively. The @code{pexec}
hypervisor uses the specified time averaged load.

@end table

@node Logging
@section Logging

@table @code

@item @code{-L}, @code{--log} <@i{log file}>
The name of the log file where the details of the parallel executions
are written. By default, no such log file is created. 

@item @code{-W}, @code{--log-level} <@i{log level}>
The log level, an integer number between 0 and infinity. The more
large this number is, the more information is written to the log file.
If the log level is zero, no log file is created. The default log level
is 1. If the log level is specified directly, but @code{-l|--log} is omitted,
the log will be written to the invoker's standard error (maybe in parallel
with other messages gathered by @code{-u|--error -}. If neither
@code{-l|--log} nor @code{-v|--log-level} is specified, logging does not occur.

@item @code{-V}, @code{--verbose} 
Increase the log level (see @code{-v|--log-level}) by one. For example,
@code{--log-level 2} is equivalent to @code{-V -V}.

@end table

@node Examples
@chapter Examples

@section Identical execution
If all options are omitted, only the command and its arguments are specified
after @code{pexec}, the program simply runs the given process, as it
would happen without @code{pexec}:

@verbatim
	pexec ssh -X -l user host
@end verbatim

@section Calculate the square root of some numbers
Using directly the output of the command @code{seq}, let us calculate
the square root of the first ten integer numbers and store the results
in separate files [named @file{sqrt-@var{n}.dat}].
For the calculation itself, we use the program @code{bc}, a 
command-line driven arbitrary precision calculator:

@verbatim
	pexec -o sqrt-%s.dat -p "$(seq 10)" -e NUM -n 4 -c -- \
	  	'echo "scale=10000;sqrt($NUM)" | bc'
@end verbatim
@noindent 
Here we explicitly used 4 processors. The number itself is passed to the 
shell-script via the environmental variable @i{NUM}.


@section Sort some files
This example sorts some files which matches the a pre-defined search pattern.
The sorted versions of the files are stored in the files with the same
names but the suffix @code{.sort} is always appended.

@verbatim
	pexec -p "$(ls myfiles*.ext)" -i %s -o %s.sort -- sort
@end verbatim
@noindent 
Here we used explicit redirection from the input files to the output files.
Since the command itself is very simple, it is wise to put the dash-dash 
before the command to make the reading of the whole command easier.

@section Detect stars on astronomical images
In this example we assume that we have a list file of base names
of astronomical images, i.e. the images themselves have the base name
followed by the extension @code{*.fits}. Since we not expect so much errors,
the standard errors are collected in a single file (@code{star.log}, namely):

@verbatim
	pexec -f image.list -n auto -e B -u star.log -c -- \
	  	'fistar $B.fits -f 100 -F id,x,y,flux -o $B.star'
@end verbatim
@noindent 
The program @code{fistar} can be more tuned, depending on the actual problem. 
The base name of the image implies the base name of the star detection
output (@code{*.star}). Here also an environmental variable, @i{B} was
used to pass the varied information, i.e. the basename of the images.

@section Convert all PNG images in the current directory to JPEG format
If all of our images (@code{*.png}) have a name which does not start with a dash,
we can use the @code{-r|--parameters} switch too:

@verbatim
	pexec -r *.png -e IMG -c -o - -- \
	  	'convert $IMG ${IMG%.png}.jpeg ; "echo $IMG: done"'
@end verbatim

@noindent 
For the conversion the ImageMagick tool @code{convert} is used which
simply figures out the format from the extensions. The trailing @code{echo}
just report the images which are ready after conversion, these
"reports" are collected via the standard output and printed for the
invoker due to @code{-o -}. Another realization, using the NetPBM package:

@verbatim
	pexec -r *.png -i %s -o %s.jpg -c 'pngtopnm | pnmtojpeg'
@end verbatim

@noindent 
Note the difference between the two examples above. From a PNG file
named @file{something.png}, the first one creates a JPEG file
named @file{something.jpeg} while the output of the second call 
will be @file{something.png.jpg} (i.e. the argument @code{-o %s.jpg}
simply yield a concatenation of the @code{.jpg} extension to the 
existing file name). To get rid of this ``side effect'', one can say
@verbatim
	for p in *.png ; do echo ${p%.png} ; done | \
	pexec -f - -i %s.png -o %s.jpg -c 'pngtopnm | pnmtojpeg'
@end verbatim
@noindent 
or
@verbatim
	LIST=$(for p in *.png ; do echo ${p%.png} ; done)
	pexec -r $LIST -i %s.png -o %s.jpg -c 'pngtopnm | pnmtojpeg'
@end verbatim

@section Rescale all JPEGimages in the current directory, using mutexes:

In this example a simple usage of mutexes is demonstrated. 
The usage of mutexes prevents peaks of high disk accesses
if many processes would try to read/write the same disk simultaneously:

@verbatim
	pexec -n 8 -r *.jpg -y unix -e IMG -c \
	 	'pexec -j -m blockread -d $IMG | \
 		 jpegtopnm | pnmscale 0.5 | pnmtojpeg | \
	 	 pexec -j -m blockwrite -s th_$IMG'
@end verbatim
@noindent 
In the above example an UNIX domain socket is used to for the communication
between the main @code{pexec} program and the remote control calls. From
a given file, for example @file{something.jpg}, the above call would 
create a file named @file{th_something.jpg}.

@node Additional information
@chapter Additional information
@menu
* Bugs::
@end menu

@node Bugs
@section Bugs

@itemize

@item
The @code{-k|--local-files} option is still not implemented.

@item
Actually, in the
cases when the execution of the process fails (i.e. the program or shell
does not exists, access is denied or things like that),
the child of @code{pexec} prints an error to standard error and exits,
therefore unless the standard error is gathered somehow (see @code{-u|--error}),
the invoker won't be informed in such cases. And even if so, the invoker
is unable to distinguish this from the case when the successfully
executed process prints directly the same message to its standard error.
This is not a real bug but this behavior is planned to be changed in the
future.

@item
Another strange cases are when the child process is explicitly terminated,
killed or stopped/continued. These cases are handled somehow but should
be fine-tuned by the invoker in the further releases.

@item
The logging now is still poorish, it should also be improved
(esp. to log the above unexpected shutdowns).

@end itemize

@node Copying This Manual
@appendix Copying This Manual
@menu
* GNU Free Documentation License::
@end menu

@include gfdl.texi

@bye
