Return
|
You want to use filename shortcuts interactively to save time, and in scripts to enhance portability.
The Korn shell supports shell variables (analogous to DCL symbols) but does not have anything truely comparable to VMS logicals. Some imperfect work arounds are illustrated below.
Shell variables and DCL symbols are largely analogous constructs, and are used for many of the same purposes. Here's how they compare.
Environment variables are analogous to DCL global symbols, with one important difference. Any child process, including a shell script, can only inherit environment variables from the parent process. In other words, any changes to a variable disappear when the child process exits, the parent process never sees the change. (See the work-around below.)
In ksh, a 'local' variable is defined using the syntax:
name="value"
To make the variable 'global', export it after you define it:
export name
At this point it will now be inherited by any child process.
As with DCL, there are contexts when the shell expects to see
a variable name and will recognize it as such. The export
command above is a good example of this. For places where a
variable is not expected, use the $ character to
dereference it. For example:
ls -la $MYVAR
would be comparible to the DCL command:
dir/size/date/prot 'myvar'
In other words, the dereference syntax is used to force the
shell to interpret the given string as a variable name and
replace that name with it's contents before executing the
command.
An alternate
dereferencing syntax is ${name}.
For example:
ls -la ${DEFAULT}lib
This is useful when you need to dereference a variable that is
imbedded inside of another string, or for greater clarity:
Like DCL symbols, a program can access a shell variable
if it so chooses. This means that a program may look
for the presence of specific environment (global) variables,
such as EDITOR in order to determine the current
environment. But if the program is expecting a filename, and is
given a shell variable instead it will
interpret it as a filename, not attempt to expand it. The
dereferencing of a variable using the $ character
is done only by the shell on the command line, before
the program is called. (See logicals
below.)
As mentioned above, a child process cannot change the environment of the parent process. To define or modify shell variables in the parent process using a script, 'source' that script so that it is executed in the context of that process. For the Korn shell, the period is used to source a script into the current shell. Consider the following:
unix> cat set-editor #!/bin/sh EDITOR="vi"; export EDITOR echo "I set EDITOR to $EDITOR"; # EOF unix> chmod +x set-editor unix> echo $EDITOR emacs unix> ./set-editor I set EDITOR to vi unix> echo $EDITOR emacs unix> . ./set-editor I set EDITOR to vi unix> echo $EDITOR vi unix> |
chmod command was used
to make script executable so we could execute it directly
(see x.x). This
demonstration shows that when run as a child process, the script
could only change the variable's value for itself, not the
parent. The most common use of the source command is to use
scripts to setup interactive environment defaults. For example,
after changing a .profile
file, you would use the source command to apply the changes to
your current shell environment.
In VMS, logicals are identifiers that can be set for the life of the process, or can be shared by multiple processes. Like symbols, logicals can be inherited by a child process from the parent. What makes logicals so powerful, however, is that wherever a filename may be used, in either a script or inside a program, a logical may be used instead. When the operating system is given the logical name in a context where a file name would be expected, such as an open statement in a program, the operating system will automatically dereference the logical and use it's value to find the referenced file. This dereferencing is transparent to the program. Unfortunately Unix does not support this powerful feature. Two methods can be used to approximate VMS logicals.
If the program accepts filenames from the command line, use shell variables:
unix> dataset="/usr/local/app/data/old"
unix> ./myprog $dataset/sample.dat
program uses /usr/local/app/data/old/sample.dat
unix> dataset="/usr/local/app/data/new"
unix> ./myprog $dataset/sample.dat
program uses /usr/local/app/data/new/sample.dat
unix>
|
If the program must be 'hard wired' ahead of time with a fixed filespec, establish a standard naming scheme and use file links to make changes at run time. In this example, let's assume the program is written to always open the file
/tmp/app/sample.dat
Then to change inputs for each execution, we can create
a new file link from that file specification to the
actual input located someplace else.
unix> ln -s /usr/local/app/data/old/sample.dat /tmp/app/sample.dat
unix> ./myprog
program uses /usr/local/app/data/old/sample.dat
unix> ln -s /usr/local/app/data/new/sample.dat /tmp/app/sample.dat
unix> ./myprog
program uses /usr/local/app/data/new/sample.dat
unix>
|
Note that 'symbolic links' were used in the above example rather than the default 'hard link'. Since the object is to try and simulate a VMS logical name, a symbolic link is a (ahem) more logical choice for a number of reasons:
Symbolic links are easier to 'see' than hard links:
unix> ls -o link-* -rw-r--r-- 2 wfc 10510 Feb 13 16:33 link-1 lrwxrwxrwx 1 wfc 16 Feb 20 22:06 link-2 -> Temp/my.file unix>
link-1 is a hard link to the
file ?, whereas it's easy to see that link-2
is a link to the file Temp/my.file.A symbolic link simply contains the name of the file it is pointing to. If the original file it points to is deleted, the symbolic link still exists, but now is invalid; it no longer points to an existing file. This is known as a 'stale link'. However, if a new file is created in the same place with the same name, the link becomes valid again. Indeed the stale link can be used to create that new file by simply using the link as the output filespec. This is similar to what would happen with a VMS logical name under these same conditions.
However, what does the command:
rm /tmp/app/sample.dat
do? If this were really a logical, the original file would be
deleted. But in this case, it is the link that is removed, the
original file remains in place.
A hard link is indistinguishable from the original file.
In fact the original filename is itself a hard link. It just
happens to be the first one. So in fact any new links to a
file are really just alternate names for that file and are no
less valid than the original name. If we delete any of these
hard links, the original file will continue to exist until all
links have been deleted. Using our example again, if
/tmp/app/sample.dat was a hard link, deleting
that filename would just delete that directory entry, the
original would continue to exist. Just like with a symbolic
link. But if we instead delete the original filename, the
file will continue to exist, along with all the disk space it
consumes, because the /tmp/app/sample.dat is just
as valid a directory entry as the original. We'd have to find
all of the file's hard links to really get rid of it.
And finally, symbolic links can point across disk structures; hard links cannot.
1.3 - Aliases;
Chapter 3 of Unix for OpenVMS Users
;
Chapter 19 of Unix Power Tools
.
  Return
|
|
Colophon: |
|
||||
|
This page maintained by: Bill.Costa@unh.edu of the Enterprise Computing Group in the dept of Computing & Information Sevices at the University of New Hampshire |
|
||||