Интерактивная система просмотра системных руководств (man-ов)
psh (1)
>> psh (1) ( Linux man: Команды и прикладные программы пользовательского уровня )
NAME
psh - Perl SHell
SYNOPSIS
psh [options] [file]
COPYRIGHT
Copyright (C) 1999-2001 Gregor N. Purdy. All rights reserved.
This script is free software. It may be copied or modified according
to the same terms as Perl itself.
DESCRIPTION
psh is a Perl program which executes a read-eval loop with enough
options so that general behavior reasonably similar to more
traditional shells like 'sh' or 'bash' can be achieved, while still
allowing arbitrary perl expressions to be evaluated.
By default within psh, the Perl -w flag and '"use strict"' are not
employed so that the user is not bound by their stipulations.
They can both be turned on via a command-line flag; or setting
"$^W = 1" will turn on warnings, and calling '"use strict"' will
(almost) do the usual thing if called by the user (see LIMITATIONS, below).
Each line of input is read. psh knows a number of possible
strategies for evaluating the line, such as "send it to "system()" if it
starts with the name of an executable visible in "$ENV{PATH}"". (See
below for a complete list.)
Each strategy in turn (from a user-definable
list) examines the command line to see if it can apply, and the first
matching strategy evaluates the line. There is a psh configuration
variable (see below) which controls whether the perl value of the
evaluation is saved and printed after each command.
psh automatically collects several lines of input into a unit
processed as a single line if there are unfinished Perl constructs on
the line. In particular, if there is an unmatched quote, paren, brace,
or square bracket, input is read until these characters match. If an
input line contains the Perl ``here document'' construct as in
"<<XXX", (anywhere on the line), then input is read and
accumulated until "XXX" occurs on a line by itself. Then the
accumulated input is processed as if it were a single line.
They are processed in the following order, regardless of what order
they are specified in:
* -w
Enables Perl's warning mode. The -w switch runs perl with the
-w switch and ``use strict;''.
* -d [debug options]
The -d option puts psh into ``debugging'' mode, which prints
diagnostic output. Note that you can also enter/leave this
debugging mode in a running psh via the "$Psh::debugging" variable.
* -i
Only for compatibility reasons and ignored by Perl Shell.
* -ffile
The -f option specifies a file of commands to be read in and
evaluated before processing begins. If it is not set, and
"$ENV{HOME}" is set, and the file $ENV{HOME}/.pshrc is present, it
will be used. If -r is not specified and the current directory is
different from "$ENV{HOME}" and it contains a .pshrc file, that
file will be read and executed in addition to
$ENV{HOME}/.pshrc.
* -cstring
If the -c flag is present, then commands are read from
"string", and then psh exits. In particular, any FILE1
... arguments will be ignored.
If any FILE1 ... arguments are specified on the command line, they
will be read and executed and then psh will exit. Otherwise, psh
will enter an interactive command loop.
TOKENIZATION
Some evaluation strategies examine the ``words'' of the input. These are
produced by a tokenizer which behaves very similarly to traditional
shells: words are broken at whitespace, '&' is a metacharacter which
means that it always forms its own word, and backslash and double and
single quotes act as quoting characters, preventing word breaks at
whitespace and the ``meta-ness'' of &.
If the description of the strategy does not mention the ``words'', then
the tokenization is irrelevant to that strategy.
STANDARD EVALUATION STRATEGIES
psh includes the following evaluation strategies, sorted by the
order we suggest for @Psh::strategies. For adding/removing evaluation
strategies we suggest the usage of the built-in command ``strategy''
from within psh.
* comment
* comment
If the first word of the input line begins with a '#' character, ignore
the line.
* bang
* bang
If the first word of the input line begins with a '!' character, send
everything after the '!' to system().
* brace
* brace
If the first word of the input line begins with a '{' character,
evaluate the entire line as a Perl expression (including the brace).
* built_in
* built_in
If the first word of the input line matches a psh ``built-in''
function, call the subroutine associated with that built-in; the
subroutine receives a single argument, which is the remainder of the
input line exactly as entered.
* perlfunc
* perlfunc
If the first word of the input line matches the name of a defined
Perl subroutine - or - if $Psh::Strategy::Perlfunc::builtins is set a built-in
Perl function (as determined by the %Psh::Strategy::Perlfunc::perl_builtins hash),
pass the line to eval. If "$Psh::Strategy::Perlfunc::expand_arguments" is
true and the line
contains no parens, or braces or commas (except for {a,b,c} as in
shell brace-expansion), then this strategy tries to
interpret the arguments on the command line in a ``shell-like'' manner:
strings are literal except for variable expansion, brace expansion,
and glob expansion.
The idea of this strategy is to allow perl functions, especially
subroutines in main, to be called like ``ordinary commands'' (i.e.,
executables on disk). Or put another way, the idea is to replace
bash's ``shell function'' capacity with ordinary Perl subroutines. The
slogan is, ``If the command line looks like an ordinary shell command,
interpret it like one, even if the first word is a Perl subroutine.''
* auto_resume (not enabled by default)
* auto_resume (not enabled by default)
If the input line matches the name of a stopped job then brings that
job to the foreground instead of starting a new programm with that
name.
* perlscript (not enabled by default)
* perlscript (not enabled by default)
If (1) the first word of the input line matches the name of a file found in
one of the directories listed in the path ("$ENV{PATH}"), and (2) that file
starts with "#!/.../perl", and (3) that "perl" is the
same as the Perl under which psh is running, psh will fork and run
the script using the already-loaded Perl interpreter. The idea is to
save the exec half of the fork-exec that the executable strategy would
do; typically the exec is more expensive. Right now this strategy can
only handle the -w command-line switch on the "#!" line. Note this
strategy only makes sense before the ``executable'' strategy; if it came
after, it could never trigger.
* executable
* executable
If the first word of the input line matches the name of an executable
file in the path given by "$ENV{PATH}", then pass the line to
system. Perl variable substitution will be done on the line first if
the "$Psh::executable_expand_arguments" configuration variable is
true and the binary which is executed does not match one of the
regular expresions in "@Psh::executable_noexpand"
* fallback_builtin
* fallback_builtin
If the first word of the input line is a ``fallback builtin'' provided
for operating systems that do not have common binaries --- such as
``ls'', ``env'', etc, then call the associated subroutine like an ordinary
builtin. If you want all of these commands to be executed within the
shell, you can move this strategy ahead of executable.
* eval
* eval
Pass the line to eval, regardless of any condition. This is a catch-all
strategy; strategies placed after it will never be triggered.
The list of evaluation strategies to try is kept in the configuration
variable "@Psh::strategies", which defaults to
"qw(comment bang brace built_in executable fallback_builtin eval)".
If you want to ensure that ``print'' (for example) refers to the Perl
function ``print'' and not ``/usr/bin/print'', try adding the ``perlfunc''
strategy before ``executable''.
GLOBBING
Globbing is used to expand filenames against patterns. Perl Shell
understands the sh '*' and '?' globbing characters (where * matches
any string and ? matches exactly one character).
In addition, Perl Shell knows the very powerful '**' globbing,
replacing many "find"s in your daily work. '**' will be replaced
by 'current directories and all sub directories'. For example:
grep foo lib/**/*.pm
will search for foo in all *.pm files which are somewhere
(recursivly) within the lib directory.
PIPELINES
Pipelines are used to construct processing chains.
cat a.txt b.txt | wc -l
MANIFEST FILTERS
A manifest filter is a chunk of code that causes the creation of a
filter process. They are handy for creating simple one-time filters
because they don't require creating a program file, setting permissions
and so on.
There are three kinds of manifest filters: quick, grep and substitution.
A quick filter consists of a block of code surrounded by curly braces,
with a trailing '"q"' modifier. The Perl Shell turns this into a line-by-line
filter. For the code in the braces, "$_" will contain the line as it was
read from input (including any end-of-line character). The filter block
should
ls | { print ++$i, ": $_"; }q
A grep filter consists of a block of code surrounded by curly braces,
with a trailing '"g"' modifier. The Perl Shell turns this into a line-by-line
filter. Only those lines for which the code in the braces returns a true
value will be printed. For the code in the braces, "@_" will contain the
results of splitting "$_" with the pattern "\s+".
netstat | { $_[1]>2; }g
A substitution filter consists of a perl-style s/// operator instance.
The Perl Shell will turn this into a line-by-line filter that performs the
substitution on each line, and then prints the line. For example:
ls | s/a/b/
A substitution filter is logically equivalent to a block filter containing
the substitution and a statement to print the resulting line. The example
above is equivalent to:
ls | { s/a/b/; print; }q
BUILT-IN FUNCTIONS
A list of built in functions is available from within "psh" using
the ``help'' command.
For details about the implementation of built-ins, please see the
pshdevel manpage.
PSH SCALAR VARIABLES
psh makes a number of variables and functions accessible to the
user in the "Psh::" package for configuration or utility
purposes. Their default values are given in parentheses below. If the
variable is also marked ``[late]'', then it is undefined at the start of
the .pshrc file, but any value given to it during that file will be
used instead of the default setting.
$Psh::bin (the basename of the file psh was invoked by)
The name of the current shell.
$Psh::cmd
The command serial number in the currently-executing processing loop.
$Psh::currently_active (0)
The pid of the process psh will currently forward signals to, or 0
if psh will handle the signals internally. Usually
0 unless psh is waiting for a process in the ``foreground''.
$Psh::debugging (the value of the -d option or 0)
Whether psh's internal debugging output should be produced. If this
variable is set to 1, all available debug output will be shown. If
this is set to a string to characters, only debug output belonging
to the classes signified by the characters will be shown. Debug
classes etc. are in pshdevel
$Psh::echo (0)
Controls whether the processing loop saves and displays the Perl value
of executing a line of input. Three cases are distinguished: a false
value, in which case no results are displayed; a subroutine reference,
in which case the subroutine is called with the results (this may be
multiple arguments if the eval returned an array) and should return
true to display, false to not; or a true (scalar) value, in which case
any non-undef, non-empty value is displayed.
In addition to displaying the value, it is pushed onto the array
determined by "$Psh::result_array".
Note that scalar values are pushed directly onto this array, but array
values are pushed by reference.
$Psh::eval_preamble (package main;)
$Psh::eval_preamble (``package main;'')
Every Perl expression that psh evaluates as part of its read-eval loop
is prepended with this string, intended primarily to set the expected
package context.
$Psh::executable_expand_arguments (0)
If this variable is true, then the following
procedure is applied to each argument ARG of the command line before
passing the command line on to ``system'':
If ARG starts with a single quote, it is untouched.
If ARG starts with a double quote, it is passed to ``eval'', and then double
quotes are placed around the result.
Otherwise, double quotes are placed around ARG, it is passed to eval,
and the result is used directly.
The intention of these steps is to do variable substitution of perl
variables that appear in the command line as the user would expect, and
in a way similar to shells such as bash. For example, if
@files = (file1, file2, file3), then
'ls @files' will expand to 'ls file1 file2 file3', whereas
'echo ``@files''' will expand to 'echo ``file1 file2 file3'''.
$Psh::handle_segfaults (0)
If set to true, psh will ignore all segfaults and attempt to
continue.
$Psh::ignore_die (0)
If set to true, psh will attempt to continue after internal
errors.
The filename psh will use to save the command history in from one
invocation to the next, if "$Psh::save_history" is true.
$Psh::history_length (50) [late]
The number of lines of command history to keep.
$Psh::host (the output of hostname -s) [late]
$Psh::host (the output of ``hostname -s'') [late]
The short host name of the machine psh is currently running on.
$Psh::interactive
This is not a customization variable but a flag which tells wether
you are currently in interactive mode (1) or processing a file (0)
$Psh::login_shell (0)
Set to true if psh is the user's login shell. On systems where this
does not apply, set to true unless called from another instance of psh.
$Psh::longhost (the output of hostname) [late]
$Psh::longhost (the output of ``hostname'') [late]
The fully qualified host name of the machine psh is running on.
$Psh::prompt ('\s\$') [late]
Controls the prompt string in interactive use, see below.
$Psh::prompt_cont ('> ') [late]
Just like $Psh::prompt, but for continuation lines when multi-line
input is being read.
$Psh::window_title ('\w')
Controls the window title in interactive use. See prompt evaluation
for escape codes.
$Psh::result_array ('Psh::val')
Controls where the results of Perl evaluations saved via "$Psh::echo"
will go. It may be a reference to an array, or the string name of an
array.
$Psh::save_history (1) [late]
If this is true, the command history is saved in "$Psh::history_file"
from one invocation of psh to the next.
$Psh::which_regexp ('^[-a-zA-Z0-9_~+]*$')
When "Psh::Util::which" is asked to locate a filename in the current
PATH, it will only look for filenames which match this regexp. Names
that do not match this regexp will automatically come back ``not found''.
$Psh::Strategy::Perlfunc::builtins (0)
If this variable is true, the perlfunc evaluation strategy will
also match those Perl builtins determined by %Psh::perl_builtins
$Psh::Strategy::Perlfunc::packages (1)
If this variable is true, the perlfunc evaluation strategy will
also match functions with full package specification
$Psh::Strategy::Perlfunc::expand_arguments (0)
If this variable is true, then command lines interpreted by the
perlfunc strategy which contain no parens, or braces or commas except
in bash-like brace-expansion expressions, will not
be simply evaluated. Rather, they will be interpreted much like
traditional shells do: the line will be spilt into words, which
undergo globbing, brace expansion, and variable expansion, and the
resulting array of words is passed to the specified function as its
arguments.
PSH ARRAY VARIABLES
@Psh::Completion::bookmarks ( from /etc/hosts )
Supposed to contain your most used IP numbers, hostnames or URLs.
Those will be eligible for TAB completion if you add a command
for completion using complete "-A" hostname command. "psh" will
initialize this list with your /etc/hosts file
@Psh::executable_noexpand ( whois, ^ezmlm-, etc. )
Contains regular expressions. If $Psh::executable_expand_arguments
is set commands which match one of these REs won't have perl
variables expanded. This is especially useful for commands which
expect email adresses, and therefore an at-sign.
@Psh::history
An array of lines to write to the history file when psh exits, only
filled when the ReadLine module doesn't handle the history file.
@Psh::mon ( Jan, Feb, etc. )
An array of month names used in printing dates, for example in prompt
strings.
The list of strategies for executing a line, tried in order.
@Psh::val
The default array where psh stores away the results of executing
lines, as described in "$Psh::echo" above.
@Psh::wday ( Mon, Tue, Wed, Thu, Fri, Sat)
An array of the weekday names used in printing dates, for example in
prompt strings.
PSH HASH VARIABLES
%Psh::array_exports
Contains a list of environment variables which should be tied
to arrays. The key of the hash is the name of the variable, the
value is the delimiter of the list (e.g. ':' in PATH). The
default value for array_exports currently contains PATH, CLASSPATH,
LD_LIBRARY_PATH, FIGNORE and CDPATH.
%Psh::built_ins
The keys are command names, the values do not matter. Builtins on this
list may be autoloaded. This is initialized on startup by &Psh::Builtins::built_autoload_list()
- please see pshdevel for more information.
%Psh::fallback_builtins
A list of fallback builtins Psh should provide. This currently defaults
to ls and env.
%Psh::Strategy::Perlfunc::perl_builtins (by default, all Perl builtins and keywords)
The perlfunc evaluation strategy uses this hash on the first word of a
command line to determine whether it should handle that command
line. If the first word is present as a key
in this hash, then the corresponding value determines the treatment: 0
means don't handle this line; any positive
value means do handle the line as long as it has at least that many
words. (Since the first word counts, a value of '1' will guarantee
that the perlfunc strategy handles the line.) Useful for example to
set "$Psh::perl_builtins{grep} = 0;" if you don't want ``grep'' to be
treated as a perl function.
Note that the perlfunc strategy will also handle the line if the first
word is not present as a key in this hash but a
Perl subroutine of that name is defined.
The keys of this hash never have their arguments expanded in a
shell-like fashion, even if $Psh::perlfunc_expand_arguments is true.
%Psh::prompt_vars
The keys of this hash are single characters, and the values are
subroutine references that implement the given escape character in
prompt strings. (See the PROMPT STRINGS entry elsewhere in this document below.)
%Psh::strategy_which
%Psh::strategy_eval
These hashes implement the named strategies used in psh's
evaluation of input lines. It is possible to add new strategies, see below.
PSH FUNCTIONS
&Psh::evl
&Psh::evl
This function takes a string, evaluates it as if it were a line of
psh input, and returns the value. Useful in loops like:
C<psh$ for $file (glob $pat) { Psh::evl("ls -ld $file"); }>
&Psh::is_number
&Psh::is_number
Returns true if its first argument is a number. Intended for use in
filter subroutines placed in $Psh::echo. For example,
"$Psh::echo = \&Psh::is_number;" will cause only numeric return
values to be printed.
These four functions are called whenever psh wants to produce -d-mode
output, error messages, normal output, and warnings,
respectively. They could conceivably be redefined to implement logging
or similar facilities.
&Psh::symbols
&Psh::symbols
Takes one argument, a package name, and shows all of the symbols in
that package.
There are other functions in the psh:: package, but they are probably
not useful except internally to psh.
PROMPT STRINGS
Setting the variable $Psh::prompt to a string will cause that string
to be used as the prompt-string. Setting it to a subroutine reference
causes the result of running that subroutine to be used each time.
For example,
$Psh::prompt = sub { $i++; "psh [$i]\$ "; }
will cause the prompt to be "psh [1]$" followed by "psh [2]$", and so on.
psh uses some of the same ``prompting variables'' as bash. They are
accessed by placing a backslash followed by the code in the prompt string,
either hard coded, or as returned by the prompt string function. The
variables supported are:
d The date in ``Weekday Month Day'' format
E The escape character
h The short hostname
H The long hostname
n A carriage return and line feed
s The name of the shell
t The current time in HH:MM:SS format
u The username of the current user
w The current working directory
W The basename of the current working directory
# The command number of the current command
$ `#' if the effective UID is zero, else `$'
[ ] Used for Term::ReadLine::Gnu to ignore control characters while determining the length of the prompt
Please note that bash's support of backticks to execute code from within the prompt is not supported in psh. Instead use the newer syntax \$(command) which is also support by bash.
Custom prompting variables may be added by adding entries to the array
%Psh::prompt_vars keyed by the single character code. The entries
should be subroutine references that return the replacement string.
LIMITATIONS
Due to limitations of the Win32 type of operating system there's no
job control available on those systems.
The loop inside psh will clobber $1 and other variables (including
possible $_) because it uses matches to implement some of its special
functions.
Right now, job control simply assumes that the POSIX interface is
fully implemented. There should be a way to turn job control off if
this is not the case.
The ``exit status'' of programs invoked in the foreground by the
``executable'' strategy (or even the ``bang'' strategy) isn't available
from within psh.
Note that since expressions like 'use foo' return undef when sent to
eval(), it is not possible to use that return value as indication of
an error. Instead, we use the heuristic that there was no error unless
the special Perl variable '$@' is non-empty. Note that the side
effects of 'use foo' as a psh command line appear to be exactly as
expected.
REQUIREMENTS
psh needs several optional Perl modules to offer full functionality:
Term::ReadLine::Gnu or Term::ReadLine::Perl for readline support (command history, special editing chars etc.).
Term::Size or Term::ReadKey to offer the ability to change the environment variables LINES and COLUMNS when the terminal window size changes while running as standard shell
OTHER PERL SHELLS
Larry Walls' Perl Shell
Larry Wall exhibits the simple Perl shell "while (<>) { eval; print $@; }" on
page 161 of the Camel Book (2nd Edition).
lpsh
Lee Eakin <leakin@dfw.nostrum.com> has written the Fancy Poor Man's Perl SHell
(called lpsh for Lee's Perl Shell), a simple Perl shell that he has used for a number of
years now (it is derived from Larry Wall's Perl Shell). He has added some numeric
conversion functions because he often uses it as a calculator.
Rich Graves <rcgraves@brandeis.edu> posted a comment to the original
psh-0.001 announcement on "http://freshmeat.net", which contained this
gem that leverages the Perl debugger: "perl -d -e 1";
perlsh
Hiroo Hayashi <hiroo.hayashi@computer.org> includes perlsh, a
``one-line perl evaluator with line editing function and variable name
completion function'' as an example with his Term::ReadLine::Gnu Perl module.
PSH.pm
In an example of convergent evolution, at "http://jenda.krynicky.cz/"
there is a Perl shell module called PSH.pm which is quite similar
to this psh. It is designed to provide a command line that can be called
inside some other program via "PSH::prompt();", but a small file
psh.pl is also included that uses PSH to provide a standalone
shell. Perhaps some merger of these efforts would be beneficial to all?
SoftList
Some versions of the Perl faq mention an interactive Perl shell called
SoftList, which can still be found at
"http://www.mit.edu/afs/sipb/contrib/perl/SoftList/". It predates
Term::Readline and was apparently last touched in 1993, so it seems to
be obsolescent.
timtosh
Tim Newsome, <nuisance@cmu.edu>, has developed a shell he calls
timtosh (There Is More Than One SHell). Per his web site
("http://www.wiw.org/~drz/timtosh"),
it is a shell written entirely in Perl. The goal is to get a shell which you
can extend in Perl and can do some other niceties related to
Perl (like perl re file matching). As of 1999-12-13 (Perl Shell 0.004 release date),
Tim says timtosh ``is focused quite differently than psh is, but is currently
still waiting for a rewrite of the command line parsing.
(It has been for almost a year now)''.
vbsh
Tom Christiansen and Nathan Torkington's book Perl Cookbook, published by
O'Reilly in 1998 (ISBN 1-56592-243-3) has ``Example 15-4. vbsh'' on page 531 for
section 15.11 (Editing Input). It stands for Very Bad SHell.
Comparison of perl shells
As an aid to comparing/contrasting these different shells, here is a
brief table indicating whether or not each has certain features.
Key to features:
PE : Perl evaluation of Perl expressions
SHE: shell-like evaluation of shell-like expressions, including
'exec'ing executables searched for in PATH
CLE: command-line editing
JC : job control
PL : pipelines
CDPATH - A list of paths of directories in which the "cd" builtin
should search for its argument. Defaults to ``.''.
FIGNORE - A list (separated by the path separator) of file endings to
ignore when performing TAB completion. No default.
HISTSIZE - The maximum number of lines to save in the history file.
Defaults to 50.
IGNOREEOF - Controls the action of the shell on receipt of an EOF character as the
sole input. If set, the value is the number of consecutive EOF characters typed
as the first characters on an input line before bash exits. If the variable exists
but does not have a numeric value, the default value is 10.
If it does not exist, EOF signifies the end of input to the shell.
LANG - Sets the language of the shell.
SHLVL - The number of shells deep that psh is nested. Initially set
to 1. Many other shells do not increment this variable, so it is not
authoritative.
PS1 - If $Psh::prompt is unset, psh will try to use this
environment variable as prompt.
PS2 - If $Psh::prompt_cont is unset, psh will try to use
this variable as continuation prompt.
PSH_TITLE - If $Psh::window_title is unset, psh will try to use
this variable as window title.
USER - The name of the current user
FILES
psh - The Perl Shell executable script.
.pshrc - The user's Perl Shell `profile'. May be in "$HOME" or the
current directory; if both are present, both will be read in the order
mentioned.
The following people have contributed to the development of "psh":
Prodigious Contributors
Markus Peter <warp@spin.de> added job and signal handling,
globbing, redirection, pipelines, parts of completion code, Win32 port,
i18n code, some bash compatibility builtins and environment variables
and some more minor updates.
Glen Whitney <gwhitney@post.harvard.edu> added evaluation
strategies, improved interrupt/job handling, "&Psh::evl", "$Psh::echo",
more extensive documentation, and other more minor features.
Omer Shenker <oshenker@iname.com> added file locking, Win32
code, login shell handling, various bits of documentation, and other minor
features and updates.
Hiroo Hayashi <hiroo.hayashi@computer.org> added the current,
bash compatible support for programmable completions and some small fixes
ReadLine Support
Code examples showing how to apply the Term::ReadLine package were contributed
by Billy Naylor <billy.naylor@eu.net> (in his "pash.pl" program,
which is his own Perl shell).
Symbol Table Dumping
Billy Naylor <billy.naylor@eu.net> also had an example of a symbol
table printing function that was used as the starting point for the "psh"
function "psh::symbols()". The "psh" version adds the ability to specify a
package name, and it also filters out some special variables. The implementation
technique is also different from Billy's.
Prompt String Variables
Matthew D. Allen <s2mdalle@titan.vcu.edu> contributed an enhanced
prompt string handling routine that emulates the "bash" prompt variables. This
was expanded into the form now present.