Shell programming style -- a plea for better shell scripts
matt%ucla-locus at sri-unix.UUCP
matt%ucla-locus at sri-unix.UUCP
Sun Feb 26 13:51:10 AEST 1984
From: Matthew J. Weinstein <matt at ucla-locus>
Firstly:
The Csh manual says that the standard shell will be invoked UNLESS the
file begins with a # character (for command files). From the Csh man
page on command files:
``... The shell opens this file, and saves its name for
possible resubstitution by `$0'. Since many systems use
either the standard version 6 or version 7 shells whose
shell scripts are not compatible with this shell, the shell
will execute such a `standard' shell if the first character
of a script is not a `#', i.e. if the script does not start
with a comment...''
As for #!, EXEC has been hacked on 4.x to look for #! as a special magic
number; I'm not sure that Bell Unix has that (although it may); anyway,
the man page for exec says:
``To aid execution of command files of various programs, if
the first two characters of the executable file are '#!'
then exec attempts to read a pathname from the executable
file and use that program as the command files command
interpreter. For example, the following command file
sequence would be used to begin a csh script:
#! /bin/csh
# This shell script computes the checksum on /dev/foobar
#
...
... The space (or tab) following the '#!' is mandatory, and
the pathname must be explicit (no paths are searched)...''
(By the way, you left out the space after #! in your last message, which is
mandatory).
Finally, there is no mention of # as a comment character in my sh man
page... If it's in yours, it's probably mentioned as a Csh compatability
hack.
Secondly:
The contention on names of programs stems from a difference in outlook
on name binding.
A few types of name binding are available to the shell programmer:
Static: A qualified pathname (one that contains a slash).
This is sort of a ``you said it, you got it'' kind of execution.
If that program doesn't work or isn't there, your command fails.
There are two flavors of this:
Absolute: This is a name that begins with a slash, and names
a particular object in the file hierarchy. "/bin/sort"
is an example of this. Note that a name of this sort is
note context-sensitive.
Useful if you want to make sure that you get a
PARTICULAR executable.
Relative: A partially qualified pathname. The name is RELATIVE
TO your current working directory, and IS context
sensitive. "./foo" is an example of one of these names.
Useful if the shell script changes working directories,
or if you are executing in a controlled environment.
Note that the execution path mechanism is not used in this case.
Dynamic: An unqualified pathname. This is the the kind of command
name most shell files utter. It has no slashes, and the command
is found by searching the execution path until an executable of
the same name is found.
The problem is, of course, that the particular program found may
not be the same kind of program as was originally intended.
The user may have his own `bzork' program in his bin directory.
When you execute what you think is /bin/bzork, what you really get
is the user's program instead.
A possible solution is to alter the ``search path''
to guarantee that the name-program binding is performed using
a specific ordered set of domains (directories). However, this
may lead to unpleasant side-effects (example: a script which invokes
an interactive program. The user forks a shell from that
interactive program. He is, however, unable to reference his
bin directory in the way he assumed he would be able to...).
Clearly, when a shell script may invoke an interactive program,
changing the path (or for that matter the working directory)
without warning is not a good idea.
In any case, this points out the fact that the semantics of commands may
vary in certain circumstances, and that the script writer should
consider his choices carefully.
My suggestions about defining names should thus be considered in the
light of the functionality required.
I think that work on the semantics of command language bindings (in Unix)
is overdue. We use a lot of ad-hoc mechanisms, and attempt to make
up for this with ``programming style''.
I am not sure who is doing compilable shell work, but they must have come
across this sort of thing before. Does anyone have any feedback on
this?
- Matt
More information about the Comp.unix
mailing list