Shell
Most user interaction with the REAL/IX system is through
the shell. The default REAL/IX Operating System shell is the
Korn shell. It is located at /bin/ksh and its restricted version
at /bin/rksh. The shells /bin/sh and /bin/rsh
are linked to /bin/ksh and /bin/rksh, respectively.
The Bourne shell and its restricted version are renamed /bin/bsh
and /bin/rbsh, respectively. The references to shell
through-out the REAL/IX Operating System documentation apply to the
Korn shell. For more detailed information about the Korn shell, refer
to the Programmer's Guide or you may choose to refer to one
of the applicable publications listed in Chapter
10.
The shell is a command interpreter, allowing you to
communicate with the operating system, as well as a powerful programming
language that provides such features as variables, control structures,
subroutines, and parameter passing.
Shell Environment
The REAL/IX Operating System allows you to customize
your shell environment to meet your needs and preferences. This section
discusses how the shell environment is created and gives an overview
of how you can modify it.
Terminal Settings
Before logging on, ensure that your terminal is set
to the following configuration:
- Operation: - ON-LINE or REMOTE
- Terminal Mode: - FULL DUPLEX:
- Modem Mode: - FULL DUPLEX
- Character Generation: - LOWER CASE
- Parity: - NO PARITY
- Baud: - Check with System Administrator
Login Cycle
To login to the REAL/IX system, you supply your user
ID name and password in response to the prompts.
The init file controls processes that execute when the
computer changes run level. Among the processes executed when the
computer enters a multi-user run state are a series of getty
lines that define each terminal port on the system.
The last field on each getty line defines the
default baud rate for that line. This provides an index into a getty
file where the initial speed and terminal settings (IOCTL values)
are defined for the terminal. These settings and some that are coded
directly into the getty program are in effect when you begin the login
process. Among the settings defined are # to erase the last
character typed and @ to erase the current line.
After you provide your login name and password, the
login(1) process checks these against the entries in a login
verification file containing the login name, encrypted password, default
user directory, and various identification numbers associated with
the login name. If the login name and password match what is in the
appropriate entry in this file, the login process spawns a
shell.
As the shell is spawned, the specific environmental
definitions common to all terminals on the system are read from the
system's profile file, followed by the environmental definitions
from the your .profile file in your home directory ($HOME),
which is the default user directory into which the system places you
when you first login.
Figure 1 - The login Cycle
Customizing the Shell Environment
The first time you login to the REAL/IX system, a default
.profile is set up in your home directory. This is an ASCII
file that you may edit with any standard editor. In your .profile,
you can define such things as:
- TERM - termio file name for your terminal type
- EDITOR - default editor command
- PATH - directories to search for executable commands
- PS1 - customized promptumask complement of default file permission
for new files
- stty - terminal settings as specified on stty(1)
You can also specify commands and shell scripts to run
when you first log into the system.
Users can set their own local clock time set to a different
time zone than the system.
Block-Mode Display Processing
Block-mode display processing is required for commands
like vi(1) and any applications that use curses(3X) for screen
formatting. Such commands are very sensitive to the internal formatting
specifications of the terminal. To enable the same program to run
on a variety of terminal types, the TERM environmental variable is
set and exported (usually in the user's .profile file). TERM
references a "terminfo" file that defines the characteristics
of the terminal.
All terminfo files are stored under the /usr/lib/terminfo
directory. This directory has 39 subdirectories, named 1, 5, a,
b and so forth. Each terminal type has a name, such as tvi950
for the TeleVideoA 950 and vt100 for the DEC VT-100; the first
letter of that name determines the subdirectory in which the terminal
description is stored. So, the file for the TeleVideo 950 is /usr/lib/terminfo/t/tvi950.
This file is linked to the /usr/lib/terminfo/9/950 file, which
is for the same terminal type, to provide an alias name.
Names are given suffixes that begin with a hyphen, to
indicate modes for the hardware or user preferences. Table 7-1 defines
the conventional suffixes.
Table 1 - terminfo Suffixes
Most terminals you will want to use are already defined
in the terminfo files provided with the system. If you do not
know the terminfo name for the terminal in question, look for
files named for the model number or vendor initials. To confirm that
this is the correct file, read the compiled description file with
the cat -v command. Much of the output from this command appears
nonsensical, but the full terminal name is displayed in the first
line, along with synonymous names.
You can create new terminfo files for terminals
not already defined. The bibliography references articles that discuss
how to do this.
Interacting with the Shell
The REAL/IX shell serves as both a command interpreter
and a powerful interpretive programming language. The following sections
discuss how to get the most out of the shell as a command interpreter
and introduces the concept of shell programming. For more information
about the shell as a command interpreter refer to the Programmer's
Guide. For more information about shell programming refer to the
Languages and Support Tools Guide.
Metacharacters
The shell includes a set of metacharacters that can
save you typing and allow you to get more power out of a single command
execution. These are summarized below:
Table 2 - Metacharacters
Commands and Command Syntax
Most commands use the standard command syntax:
command -options argument(s)
Options are sometimes called flags or switches; they
are used to specify the functionality required. For instance, ls
-l (long form) lists access permissions, size, and access times
for the files; ls -lai lists this information plus the inode
for files, including files whose names begin with a . (dot);
ls -C and ls -x list just the file names in multi-column
format.
The argument is usually a file name (or several
file names). In most cases, if the command writes a file, it will
overwrite an existing file by the same name. For this reason, it is
wise to check the existing files before writing a new one, ensuring
you do not inadvertently overwrite a file that you intended to keep.
I/O Redirection
Most commands read their input from the standard input
(usually the user's terminal) and write their output to the standard
output (also usually the user's terminal). One of the things a newly
spawned process may do before execing a new program is to redirect
the program's I/O. The shell provides a very convenient notation for
redirecting a command's standard I/O before executing it. Suppose,
for example, that you want to save the output of the ls(1)
command in a file. This is done using the > (greater than sign)
to redirect the output to a file, as in:
If the file already exists, it is overwritten. Other
variations are listed below:
Table 3 - I/O Redirection
You may redirect I/O to and from devices as well as
files, because the operating system sees them as the same thing. A
particularly handy device (called a pseudo-device) is /dev/null.
Any output written to this device is simply thrown away; reading from
/dev/null results in an immediate end-of-stream condition.
Redirecting a program's standard output to /dev/null is useful
when running a command that produces a large amount of output that
is unneeded at the time. For example, suppose you have created a tar(1)
tape on device rmt/mt0 and want to see if the tape has no read
errors. A quick check to verify this tar is using the dd(1)
command to copy the tared tape to the NULL device (a successful
dd will report an equal number of records in and records out):
dd if=/dev/rmt/mt0 of=/dev/null
Pipelines
Pipelines, indicated by the "|" symbol, are
used to pass the standard output from one command as standard input
to the next command. The standard output of the last command in the
pipeline is written to your terminal or redirected to a file. For
instance, suppose you want a listing of all processes executing on
the system, excluding getty processes (which are idle terminals),
sorted in alphabetical order by user id. This is probably a long listing
and you may want to display it one page at a time, so pipe it to pg(1).
The following command provides you with the desired results:
ps -ef | grep -v getty | sort | pg
Issuing Multiple Commands on One
Line
You may string together multiple commands on one line,
using a semicolon in between commands. The shell executes the commands
serially, and displays a new prompt after the last command finishes.
As a simple example of this, the following string changes the present
working directory to the directory above where you currently are,
prints the present working directory, and lists the files in that
directory:
If one command fails, the system gives you an error
message and proceeds to execute the rest of the commands on the line.
Return Codes
Most commands issue a return code that indicate whether
the command executed properly. By convention, if the value returned
is 0 (zero), the command executed properly; any other value indicates
that it did not. The return code is not printed automatically, but
is available as the value of the shell special parameter $?.
After executing a command interactively, you can see its return code
by typing:
Creating Shell Scripts to Execute
Programs
You can create a simple shell script that contains one
or more commands that are executed in order. To create such a script,
use one of the editors discussed in Editors,
Chapter 8 to open a file, and input the commands you wish to execute.
For instance, a file that contains the following line issues an alphabetical
listing of all users currently logged onto the system:
You can also use variables in shell scripts, then supply
a value to the variable when you execute the script. The easiest way
is to use positional parameters. For instance, if the runit
shell script is:
and you execute:
file1 is used as the input argument to command,
and the output is redirected into file2. Each script can use
up to nine positional parameters, named $1 through $9. When you execute
the script, you must provide values for these variables in the order
they are given.
The special parameter, $*, is used rather like
the positional parameters, except there is no limit to the number
of variables that you may use, and the number can vary from time to
time. For instance, if the runit shell script is:
You could give any number of arguments to the runit
command and they are accepted (assuming that command accepts
multiple arguments).
The shell programming language also supports named variables
and the ability to prompt users for values for those variables. These
as well as the control structures and subroutines are discussed in
other documentation.
Installing Shell Scripts
The file that contains a shell script is usually put
into a directory that is in your path list (the PATH line of your
.profile file, which you may view by issuing the echo $PATH
command at the shell). If the script is for your private use, the
traditional location is in the bin directory under your $HOME
directory. If it is not in a directory in your path list, you can
execute it by giving its full path name.
You must make the file executable, and is accomplished
by issuing the following command:
Note that you should assign shell scripts names that
are not the same as any standard commands. To check a name, use the
whence name command in shell; if the system responds
with a directory location, that name is in use. Otherwise, it is available.
Job Control
To the shell, each separately entered command, sequence
of commands (separated by semicolons), and pipeline is a job. You
can easily create multiple jobs, run them in the background, or schedule
them to run at a later time.
Background Jobs
When running a job that may take a long time, it is
useful to free up your terminal for other work while waiting for the
job to complete. This is done by directing the shell to run the job
as a background job by adding an ampersand (&) metacharacter at
the end of the command line, as in the following:
After starting the job, the shell reports the job id
(which counts the jobs you have submitted to run in the background)
and the process id of each process it forks to start the job, then
issues a shell prompt. You can then enter more commands while the
job runs along in parallel in the background. Any terminal output
produced by the background process is written to the terminal (provided
that you do not redirect the output); when the job terminates, the
shell notifies you with a short message.
Use the jobs command to find out the status of
jobs. It lists the job id, the run state (running, stopped) and the
command line that invoked it, identifying the current job with a +
and the previous job with a - sign. To refer to a job in a command,
use a percent sign followed by the job's id.
For commands that output a number of status messages
to stderr, having execution stop every time such a message
is output is frustrating. You may use the nohup(1) command
with a shell script to redirect all stderr and stdout
messages to a file called nohup.out in the current directory.
For example:
nohup find / -name test -print &
runs the find(1) shell command in the background,
recursively searching for all occurrences of a file named test
beginning in the root directory, and redirecting all stderr
and stdout output to nohup.out. Note that the next time
you use nohup in this directory, it will append to nohup.out; you
should remember to delete this file when you no longer need it.
Using cron
cron(1M) is a system daemon that allows you to
schedule jobs by way of the command:
- at(1) - to run a job at a specified later time.
- batch(1) - to run a job when the system is not overloaded.
- crontab(1) - to run a job periodically.
You may use the at command to schedule a resource-intensive
job to run when the system load is light. For instance, the following
set of commands will run a job at 11:45 PM tonight that compiles several
programs:
at 23:45
cc <options> prog1.c
cc <options> prog2.c
...
<^d>
When the job completes, cron sends you mail with
all output that would otherwise have been directed to your terminal.
A number of formats are available with which to specify
the time, date, and so forth. The batch command is similar
to at, only the job is scheduled immediately, assuming the
system is not overloaded.
To schedule a job to run periodically, use the crontab
command. This takes as an argument a file that has six lines: the
first five specify when to run the command, and the last line specifies
the command to run.
Four files determine who has permission to use the cron
facilities: at.allow, at.deny, cron.allow, cron.deny.
These files are located in /usr/lib/cron. *.allow lists
users who are allowed to use cron or at; if the file
does not exist, the system looks at the appropriate *.deny
file to see who should be denied access to cron or at. If neither
*.allow nor *.deny file exists, only root is
allowed to use cron or at; if *.deny exists but
is empty, all users are allowed to use cron or at. The
REAL/IX Operating System is delivered with no *.allow files
and with empty *.deny files.
REAL/VU
The REAL/VU Graphical Environment provides an industry-standard,
network-based windowing system (the X Window SystemC), a graphical
user interface, a graphics development environment, and general purpose
graphics capabilities for the REAL/IX Operating System. The REAL/VU
user interface includes multiple windows, menus, and graphical icons
that provide an environment that is similar to that available on many
popular personal computers. The REAL/VU Graphical Environment consists
mainly of two components:
- MODCOMP's implementation of the X Window System, which includes
a number of standard applications, the Xlib library, and the X
toolkit. With this package, users can define and use screen graphics
and can communicate with other computer systems running the X
Window System.
- MODCOMP's implementation of the OSF/MotifC environment, which
provides the OSF/Motif "look, feel, and functionality"
and includes the MotifC Window Manager with a set of development
tools that enable the development of menus, icons, graphical displays,
and graphics-based applications.
The REAL/VU Graphical Environment requires a network
display terminal (X terminal), which is an intelligent terminal that
is defined as a node on the Ethernet
network discussed in Chapter 6.
Figure 7-2 gives an architectural diagram of the REAL/VU
Graphical Environment components and subcomponents:
Figure 2 - Architectural View of REAL/VU Components
The REAL/VU Graphical Environment provides user-oriented,
PC-style behavior and screen appearance that can enrich the development
environment. One terminal can support a number of "windows",
each running a shell or other program that is independent of the others
(or, if desired, may be related to the others). Each window can access
a different machine on the Ethernet network.
Widgets
A fundamental concept in the REAL/VU environment is
the widget, which defines input semantics and visual appearance.
Some widgets are pliable: their input semantics (mouse buttons, pointer
motion, keyboard input) are bound at run time, while other widgets
may have fixed semantics. Likewise, visual appearance (highlighting,
repositioning, or other animation) may be fixed or can be adjusted
at run time.
Widgets can be defined using the intrinsics in
the X Toolkit. The intrinsics are a set of user interface primitives
that are themselves free of visual and interaction style. The intrinsics
provide a uniform way for widget developers to handle the common chores
of widget construction: initialization, input event dispatching (including
enabling and disabling user input dispatch to sub-hierarchies of widgets),
run-time configurability, uniform handling of common events (such
as exposure and resize), cleanup, and others. The intrinsics also
include the uniform application programming interfaces for creating,
controlling, and destroying widgets.
Motif Toolkit
The REAL/VU Motif toolkit is a prepackaged widget library
that provides a particular "look and feel." These widgets
allow programmers to develop applications that present an industry-standard
user interface. Objects such as menus and pushbuttons have an attractive,
three-dimensional appearance.
MOTIF Window Manager
The Motif Window Manger provides window control and
manipulation using the same "look and feel" as that provided
by the Motif toolkit. For example, each window has a shaded, three-dimensional
border; windows can be created, destroyed, and changed in size by
clicking the mouse appropriately on a window menu.
Go to Chapter 8 TOC