The shell module interface

The shell module is intended to provide UNIX shell-like commands,
such as you find on a modern UNIX system, and in addition shortcuts
for some common Perl idioms.

This module does not provide functionality to spawn a shell (as older
functions like run-shell-command and shell and newer ones like command-output
do). Instead, many commands that are available in a shell are
available in this module. These commands are available on UNIX and
Windows and work in a uniform fashion whatever the actual operating
system. No external programs are used to implement the functions in
this module, and as a result security issues associated with executing
external programs by spawning shells are finessed.

The shell module's package, :excl.shell, is
autoloaded when referenced. The module name is
shell. The module can be loaded by evaluating

Operators

Variables

Classes

=~

Function

Package: excl.shell

Arguments:
regexp string &rest keys&key &allow-other-keys

Return t if the regular expression
regexp matches string As a
side-effect, set the $1...$9 variables
to the corresponding group match. When there is no corresponding group
match, the associated variable is set to nil.
If regexp is a string, it is cached in case it is
used repeatedly -- it will only be compiled once for consecutive calls
to this function.

See `compile-regexp' for details on compilation of regular expressions.

Package: excl.shell

concat

Function

Package: excl.shell

Arguments: &rest things

Concatenate objects into a simple-string. This function is similar to
concatenate, except that
conversion of pathnames, numbers and symbols is done automatically
into a string. The conversion of these three types is done with
princ-to-string. For example:
(concat 1 2 3) will yield
"123", whereas (concatenate
'simple-string 1 2 3) will signal an error.

glob

Function

Package: excl.shell

Arguments:
string-or-pathname &key &allow-other-keys

Expand string-or-pathname, a pathname or string,
into a list of files matching the pattern in the argument. The call is
equivalent to calling common-lisp:directory on
string-or-pathname and signalling an error if it
returns nil.

-w

Function

Package: excl.shell

Return a non-nil value if file
filespec exists and is writable. A
filespec must be a string or pathname.

-x

Function

Package: excl.shell

Arguments:
filespec

Return a non-nil value if file
filespec exists and is executable.
filespec must be a string or pathname. On
Windows this function always returns t if
filespec exists.

-e

Function

Package: excl.shell

Arguments:
filespec

Return a non-nil value if file
filespec exists. A filespec
must be a string or pathname.

-f

Function

Package: excl.shell

Arguments:
filespe

Return a non-nil value if file
filespec exists and is a regular file.
filespec must be a string or pathname. Note,
-f will return true if given an
existing file that is not a directory, including, for example, a
symbolic link. This may be unintuituve (you might expect -f to return true only when given
an actual file), but it is how the test program works on UNIX.

-d

Function

Package: excl.shell

Arguments:
filespec

Return a non-nil value if file
filespec exists and is a directory.
filespec must be a string or pathname.

-l

Function

Package: excl.shell

Arguments:
filespec

Return a non-nil value if file
filespec exists and is a symbolic link.
filespec must be a string or pathname. Always
returns nil on Windows.

-s

Function

Package: excl.shell

Arguments:
filespec

Return a non-nil value if file
filespec exists and has a size greater than zero.
filespec must be a string or pathname.

touch

Function

Package: excl.shell

Update the access and modification times of
filespec to the current time. The various
keyword arguments augment this behavior:

if-does-not-exist: :create is
the default value, and other values are :error or
:ignore. :error causes touch to signal an error if the
file does not already exist. :ignore causes
touch to do nothing if the file
does not already exist.

atime: set the access time to the given universal
time.

mtime: set the modification time to the given
universal time.

time: set the access and modification times to
the given universal time.

reference-file: set the access and modification
times to the corresponding times on the file given by the value of
this keyword.

If a file does not exists and if-does-not-exist
is :ignore, touch returns
nil. Otherwise, touch returns
t if successful, or signals an error.

rm

Function

Package: excl.shell

Arguments:
filespec &key force recurse verbose no-execute

Remove filespec from the file system. By default
it does not remove directories. The keyword arguments to rm are:

force: ignore non-existent files

recurse: remove the contents of the directory recursively

verbose: explain what is being done as it happens

no-execute: when true, do not execute any
actions; just print information on what would be done.

This function copies the file specified by from
to a file specified by to. If
from is a directory and the
recurse keyword argument is is nil, or from and
to are the same file, then an error is signaled.
Other situations can also result in an error: they are described
below. from and to should be
objects accepted by pathname
(such as pathnames and strings).

The large number of keyword arguments allows for support of the modes
described next and support for fine tuning exactly how the copying is
done. Simply copying one file to another can be done with specifying
values for any keyword arguments.

This function has five modes:

link: this is the mode when the make-links
keyword argument is given a non-nil value. In
this mode, cp makes hard links instead of
copying files. Windows does not support links, so this mode is not
supported on Windows.

symlink: this is the mode when the
make-symbolic-links keyword argument is given a
non-nil value. In this mode, cp makes symbolic links instead of
copying files. If the value is `:relative', then relative symlinks
are created instead of absolute ones. Windows does not support links,
so this mode is not supported on Windows.

update: this is the mode when the update
keyword argument is given a non-nil value. In
this mode, cp only copies a file when the
source file (from) is newer than the destination
file (to), or when the destination file is
missing, or when the destination file is a different size.

sync: this is the mode when the sync
keyword argument is given a non-nil
value. This mode is like update mode, except when directories
are involved delete files which are in the destination
(to) but not in the source
(from).

normal: this is the mode when the none of the above keywords
(make-links,
make-symbolic-links, update,
and sync) have a non-nil
value. Plain vanilla copying of files is done

It is an error if more than one of make-links,
make-symbolic-links, update,
and sync is non-nil.

The following options control how the copy is done, aside from the modes
given above.

force: when specified true, if an existing
destination file (to) cannot be opened, remove it
and try again.

remove-destination: when specified true, remove
each destination file before copying.

ignore-files: if non-nil, the value should be a string which is a regular
expression, or the keyword :backup, or a list of
such strings with or without :backup. When
non-nil, ignore files that match the provided
regular expression, or any regular expression in the provided list of
regular expressions. :backup is shorthand for a
regular expression that matches GNU Emacs backup files (files that
start with # or end with
~). ignore-files is only applied to files
in subdirectories found when recursing.

one-filesystem: when true, skip subdirectories
that are on different filesystems from the one that the copy started
on.

preserve-symbolic-links: if non-nil, then symbolic links themselves are copied,
instead of the files or directories they reference. If nil, symbolic links which point to directories will
be followed, if the recurse keyword is given and
non-nil. Windows does not support links, so
this argument is not supported on Windows.

preserve-ownership: when true, preserve file
ownership (user and group, must be root).

recurse: when true, descend into directories when
copying.

prune-directories: when given an appropriate
non-nil, allow copy to abort descent into
certain directories. The value of this keyword has the same meaning as
the value of the keyword of the same name to the function map-over-directory.

no-execute: when true, do not execute any
actions, just print information on what would be done.

verbose: when true, print information about what
is being copied. The value can be a function which should expect
arguments: what (which will be one of the
following keywords: :skipping, :unlink,
:creating-directories, :link,
:symlink or :copy),
file1, a filename, and an optional
file2, a second filename. Specifying t is roughly equivalent to this functional value:

The type of the arguments (i.e. whether a file has a bearing on the
operation in each mode. The meaningful combinations are given in the
table below.

In the Comments column of the table the following notation is used:

@ means a symbolic link is dereferenced (the file to which the
symlink points to is what is used instead of the argument itself), and
if the file is not a symbolic link then the @ can be ignored.

a -> b means a is copied to b

[n]: refer to note n after the table.

The first two sections of this table are the default behavior, without
any keyword arguments (i.e., `normal' mode) specified non-nil. The first shows what happens when neither file
argument is a link. The second (which applies to UNIX only since
Windows does not support links) shows what happens when one or both of
the file arguments is a link. The third section of the table
represents non-default behavior using a non-nil value of
preserve-symbolic-links.

from (a)

to (b)

Comments

file (non-link)

[non-existent]

a -> b

file (non-link)

file (non-link)

a -> b [2]

directory (non-link)

[non-existent]

a -> b

file (non-link)

directory (non-link)

a -> b/a

directory (non-link)

directory (non-link)

a -> b/a

directory (non-link)

file (non-link)

error [1]

In this second section, one or both of the file arguments is a
link. Again, all keyword arguments are assumed to be nil. In particular
preserve-symbolic-links is nil so links are dereferenced. Windows does not
support links so this section of the table applies to UNIX only.

from (a)

to (b)

Comments

file (non-link)

file (link)

a -> @b [2]

file (link)

[non-existent]

@a -> b

directory (link)

[non-existent]

@a -> b

file (link)

file (non-link)

@a -> b [2]

file (link)

file (link)

@a -> @b [3]

file (link)

directory (non-link)

@a -> b/a

directory (link)

directory (non-link)

@a -> b/a

file (non-link)

directory (link)

a -> b/a

directory (non-link)

directory (link)

a -> b/a

file (link)

directory (link)

@a -> b/a

directory (link)

directory (link)

@a -> b/a

directory (non-link)

directory (link)

error [1]

directory (link)

directory (non-link)

error [1]

directory (link)

directory (link)

error [1]

In this third section, one or both of the file arguments is a
link. Again, all keyword arguments are assumed to be nil. In particular
preserve-symbolic-links is t so links are not dereferenced. Windows does not
support links so this section of the table applies to UNIX only.

from (a)

to (b)

Comments

file (non-link)

file (link)

a -> @b [3]

file (link)

[non-existent]

a -> b

file (link)

file (non-link)

a -> b [2]

file (link)

file (link)

a -> b [2]

directory (link)

file (non-link)

a -> b [2]

directory (link)

file (link)

a -> b [2]

directory (link)

[non-existent]

a -> b

file (link)

directory (non-link)

a -> b/a

directory (link)

directory (non-link)

a -> b/a

file (non-link)

directory (link)

a -> b/a

file (link)

directory (link)

a -> b/a

directory (link)

directory (link)

a -> b/a

directory (non-link)

directory (link)

a -> b/a

directory (non-link)

file (link)

error [1]

Notes:

only an error in the default case, where
remove-destination is nil.

destination file is overwritten if permissions and ownership allow,
and if they do not an error is signalled -- if the
force keyword value is non-nil, then the destination is forcibly removed before
the copy.

similiar to 2 except the file to which the destination symbolic
link points is the object of the operation.

cp return value

If successful the return value (an integer specifying a number of
files) for each mode is given by the following table, otherwise an
error is signaled:

mv

Function

Package: excl.shell

Move file from to to. If a
directory is moved across filesystem boundaries, then it is copied and
then the original is removed.

The keyword arguments are as follows:

force: when non-nil, the destination is forcibly removed before the
move.

dereference-source-directory: when non-nil and the source directory is a symbolic link, then
instead of moving the symbolic link, the file it points to is moved.
A non-nil value is the same as a trailing
slash on a source argument to GNU
mv.

no-execute: when non-nil, do not execute any actions, just print out what
would be done.

verbose: when true, print information about what
is being copied. The value can be a function which should expect
arguments: what (which will be one of the
following keywords: :remove, :move,
or :copy),
file1, a filename, and an optional
file2, a second filename. Specifying t is roughly equivalent to this functional value:

what will vary depending on whether a directory
is being moved to another filesystem.

The type of the file arguments (from and
to) has a bearing on the operation of mv. The meaningful combinations
are given in the table below.

In the Comments column of the table the following notation is used:

@ means a symbolic link is dereferenced (the file to which the
symlink points to is what is used instead of the argument itself), and
if the file is not a symbolic link then the @ can be ignored.

a -> b means a is moved to b

rm b means b is removed before the move.

[n]: refer to note n after the table.

The first two sections of this table are the default behavior, without
any keyword arguments specified non-nil. The
first shows what happens when no directory specified as a value of the
from is a link. The second shows what happens when a
directory specified as a value of the from is a
link and dereference-source-directory is nil. The third section of the table shows what
happens when a directory specified as a value of the
from is a link and
dereference-source-directory is non-nil.

from (a)

to (b)

Comments

file (non-link)

[non-existent]

a -> b

file (link)

[non-existent]

a -> b

directory (non-link)

[non-existent]

a -> b

file (non-link)

file (non-link)

rm b; a -> b

file (link)

file (non-link)

rm b; a -> b

file (non-link)

file (link)

rm b; a -> b

file (link)

file (link)

rm b; a -> b

file (non-link)

directory (non-link)

a -> b/a

directory (non-link)

directory (non-link)

a -> b/a

file (link)

directory (non-link)

a -> b/a

directory (non-link)

directory (link)

a -> b/a

file (non-link)

directory (link)

a -> b/a

file (link)

directory (link)

a -> b/a

directory (non-link)

file (non-link)

error

directory (non-link)

file (link)

error

In this second section, the from is a linked
directory and dereference-source-directory is
nil.

from (a)

to (b)

Comments

directory (link)

[non-existent]

a -> b

directory (link)

file (non-link)

rm b; a -> b

directory (link)

file (link)

rm b; a -> b

directory (link)

directory (non-link)

a -> b/a

directory (link)

directory (link)

a -> b/a

In this third section, the from is a linked
directory and dereference-source-directory is
non-nil.

from (a)

to (b)

Comments

directory (link)

file (non-link)

error

directory (link)

file (link)

error

directory (link)

[non-existent]

@a -> b [1]

directory (link)

directory (non-link)

@a -> b/a [1]

directory (link)

directory (link)

@a -> b/a [1]

Notes:

[1]
this operation leaves a dangling symbolic link. The GNU mv in
fileutils version 4.1 has a bug, in our estimation. If you do this:

mkdir dir
ln -s dir link
mv link/ dir2

The trailing slash is the same as
:dereference-source-directory t, according to the
fileutils documentation. The above commands cause
dir to be copied to dir2,
and not the correct result, a symbolic link link
that points to dir and dir
renamed to dir2. The fileutils documentation
says this:

Warning: If you try to move a symlink that points to a directory,
and you specify the symlink with a trailing slash, then `mv' doesn't
move the symlink but instead moves the directory referenced by the
symlink.

In other words, the fileutils documentation says that it will do the
right thing, but it does not.

mv return value

ln

Function

Package: excl.shell

This function creates a link to the from with the
name to. It works on UNIX only since Windows does
not support symbolic links.

The keyword arguments are:

symbolic: when true, create a symbolic instead of
hard link.

force: when true, remove existing destination
files before linking.

no-dereference-destination: if non-nil then treat to that is a
symbolic link to a directory as if it were a normal file.

relative: when true, do not do full merging on
from and to so that a
relative symbolic link can be created.

no-execute: when true, do not execute any actions, just print out a description of what would be done.

verbose: when true, print information about what
is being linked. The value can be a function which should expect
arguments: what (which will be one of the
following keywords: :symlink
or :link),
file1, a filename, and an optional
file2, a second filename. Specifying t is roughly equivalent to this functional value:

what will vary depending on whether symbolic or
hard links are being created.

The type of the arguments has a bearing on the operation of ln. The
meaningful combinations are given in the table below.

In the Comments column of the table the following notation is
used: b -> a means a link is made from b to a.

The first two sections of this table are the default behavior, without
any keyword arguments specified non-nil. The
first shows what happens when no directory specified as a value of the
to is a link. The second shows what happens when a
directory specified as a value of the to is a
link and no-dereference-destination is nil. The third section of the table shows what
happens when a directory specified as a value of the
to is a link and
no-dereference-destination is non-nil.

from (a)

to (b)

Comments

file (non-link)

[non-existent]

a -> b

file (link)

[non-existent]

a -> b

directory (non-link)

[non-existent]

a -> b

directory (link)

[non-existent]

a -> b

file (non-link)

file (non-link)

error

file (link)

file (non-link)

error

directory (non-link)

file (non-link)

error

directory (link)

file (non-link)

error

file (non-link)

file (link)

error

file (link)

file (link)

error

directory (non-link)

file (link)

error

directory (link)

file (link)

error

file (non-link)

directory (non-link)

b/a -> a

file (link)

directory (non-link)

b/a -> a

directory (non-link)

directory (non-link)

b/a -> a

directory (link)

directory (non-link)

b/a -> a

The second section of the table shows what happens when a
directory specified as a value of the to is a
link and no-dereference-destination is nil.

from (a)

to (b)

Comments

file (non-link)

directory (link)

b/a -> a

file (link)

directory (link)

b/a -> a

directory (non-link)

directory (link)

b/a -> a

directory (link)

directory (link)

b/a -> a

The third section of the table shows what happens when a directory
specified as a value of the to is a link and
no-dereference-destination is non-nil (such as when --no-dereference
is specified to ln).