Hamilton C shell(tm)
User Guide and Reference Manual
Release 2.2
March, 1996
Hamilton Laboratories, 21 Shadow Oak Drive, Sudbury, MA
01776-3165
Phone 508-440-8307 ú FAX 508-440-8308
Internet hamilton@bix.com ú BIX hamilton ú Telex
6503890321
Copyright (c) 1988 - 1996 by Hamilton Laboratories.
All rights reserved. No part of this publication may be
reproduced, stored in a retrieval system, or transmitted,
in any form or by any means, electronic, mechanical,
photocopying, recording, or otherwise without the prior
written permission from Hamilton Laboratories. Printed
in the United States of America.
AT, PS/2 and OS/2 are registered trademarks of
International Business Machines Corporation. Windows is
a registered trademark and Windows NT is a trademark of
Microsoft Corporation. UNIX is a registered trademark of
UNIX System Laboratories. Hamilton C shell is a
trademark of Hamilton Laboratories.
Table of Contents
Preface ................................... v
License Agreement........................ vii
Introduction .............................. 1
Installation Guide ........................ 5
Installation on Windows NT or Windows 95 5
Installation on OS/2 11
Common Problems .......................... 23
Product Support .......................... 35
User Guide ............................... 39
The Utilities 47
The Tar and MT Utilities 65
I/O Redirection and Piping 73
The History Mechanism 81
Variables 85
Wildcarding 95
Editing 103
Quoting 109
Expressions 113
Aliases 121
Programming Constructs 127
Scheduling 147
Order of Evaluation 155
Customizing the Shell 159
Summary 173
Examples ................................ 175
Factor.csh 175
Whereis.csh 176
Samples Directory 177
Compatibility Guide ..................... 183
Language Reference ...................... 193
Basic Statements 193
Condition Testing 194
Iteration 196
Procedures 197
Aliases 198
Variable and Expression Manipulation 199
Local Variables 200
Function Keys 202
Miscellaneous Statements 204
v
Statement Relationships 206
I/O Redirection 206
Expression Operators 208
File System Tests 210
Special Devices 211
ANSI Escape Sequences 213
Wildcarding and Pattern Matching 215
Filename Completion 216
Command Line Editing 218
History Recall 220
Command Completion 220
Quoting 222
Escape Sequences 222
Variable Substitution 224
Substitution Modifiers 225
Pathname Editing 227
Predefined Variables ................... 229
Environmental Variables 229
Process-Wide Variables 235
Per-Thread Variables 238
Variables, Sorted by Name 245
Built-in Procedures .................... 263
Utilities .............................. 269
Popular Aliases ........................ 277
Help Information ....................... 282
Help for the shell 283
Help for the utilities 287
Index .................................. 401
vi
Preface
Thank you for purchasing and using Hamilton C shell.
Our goal and guarantee is your satisfaction.
Hamilton C shell is an advanced command processing
language for Windows NT, Windows 95 and OS/2. It's a
professionally oriented language for manipulating files,
processes and threads and connections between these
objects. As a language, it offers what we think of as
the human characteristics of language: a useful
vocabulary and grammar, a limitless freedom of expression
and the ability to describe and relate events in time.
Most important, it projects your influence into the
future by allowing you to easily describe you want done
even if what you want is quite complex and dependent on
future events.
Hamilton C shell is a full implementation of the C
shell language popular on engineering workstations. It
was created initially in OS/2 protected mode and
meticulously ported as a true Win32 application to
Windows NT and Windows 95. Not one of the more than
130,000 lines of code in the current release was created
on or ported from anything but OS/2 or Windows NT.
This product complies with accepted standards for the
language and with the conventions of Windows NT, Windows
95 and OS/2. Users with previous experience with the
standard OS/2, Windows NT, Windows 95 or DOS command
processors or the original UNIX C shell should find
enough reasonably familiar language constructs and
features to make the product immediately productive.
Douglas A. Hamilton
Wayland, Massachusetts
December 9, 1988
(Last revised March 24, 1996, Sudbury, Massachusetts)
vii
IMPORTANT -- READ CAREFULLY BEFORE OPENING. By opening
this sealed package, you indicate your acceptance of the
following Hamilton Laboratories License Agreement.
Hamilton Laboratories License Agreement
This is a legal agreement between you, the end user, and
Hamilton Laboratories. By opening this sealed package,
you are agreeing to be bound by the terms of this
agreement. If you do not agree to the terms of this
agreement, promptly return the unopened package and any
accompanying items for a full refund.
HAMILTON LABORATORIES SOFTWARE LICENSE
1. GRANT OF LICENSE. Hamilton Laboratories grants to
you the right to use one copy of the enclosed Hamilton
Laboratories software program (the "SOFTWARE") on a
single terminal connected to a single computer (i.e.,
with a single CPU). You may not network the SOFTWARE or
otherwise use it on more than one computer or computer
terminal at the same time.
2. COPYRIGHT. The SOFTWARE is owned by Hamilton
Laboratories or its suppliers and is protected by United
States copyright laws and international treaty
provisions. Therefore, you must treat the SOFTWARE like
any other copyrighted material (e.g., a book or musical
recording) except that you may either (a) make a
reasonable number of copies of the SOFTWARE solely for
backup purposes or (b) transfer the SOFTWARE to a single
hard disk provided the original and any other copies are
kept solely for backup or archival purposes. You may not
copy the written materials accompanying the software.
3. OTHER RESTRICTIONS. You may not rent or lease the
SOFTWARE, but you may transfer the SOFTWARE and
accompanying written materials on a permanent basis
provided you retain no copies and the recipient agrees to
the terms of this Agreement. You may not reverse
engineer, decompile or disassemble the SOFTWARE. If
SOFTWARE is an update, any transfer must include the
update and all prior versions.
4. DUAL MEDIA SOFTWARE. If this SOFTWARE package
contains both 3 «" and 5 ¬" disks, you may use only the
disks appropriate for your single-user computer. You may
not use the other disks on another computer or loan,
rent, lease, or transfer them to another user except as
part of the permanent transfer (as provided above) of all
SOFTWARE and written materials.
LIMITED WARRANTY
LIMITED WARRANTY. Hamilton Laboratories warrants that
the SOFTWARE will perform substantially in accordance
with the accompanying written materials for a period of
90 days from the date of purchase. Some states do not
allow limitations on the duration of an implied warranty,
so the above may not apply to you.
CUSTOMER REMEDIES. Hamilton Laboratories' entire
liability and your exclusive remedy shall be, at Hamilton
Laboratories' option, either (a) return of the price paid
or (b) repair or replacement of the SOFTWARE that does
not meet this Limited Warranty and which is returned to
Hamilton Laboratories with a copy of your receipt.
During the first 90 days from the date of purchase, if
you determine that the SOFTWARE is unsatisfactory in any
way, you may return it with proof of purchase and a
written description of why the SOFTWARE was
unsatisfactory for a full refund.
NO OTHER WARRANTIES. Hamilton Laboratories disclaims all
other warranties, either express or implied, including,
but not limited to implied warranties of merchantability
and fitness for a particular purpose, with respect to the
SOFTWARE and accompanying written materials. This
limited warranty gives you specific legal rights. You
may have others, which vary from state to state.
NO LIABILITY FOR CONSEQUENTIAL DAMAGES. In no event
shall Hamilton Laboratories or its suppliers be liable
for any damages whatsoever (including, without
limitation, damages for loss of business profits,
business interruption, loss of business information, or
other pecuniary loss) arising out of the use of or
inability to use this Hamilton Laboratories product, even
if Hamilton Laboratories has been advised of the
possibility of such damages. Because some states do not
allow the exclusion or limitation of liability for
consequential or incidental damages, the above limitation
may not apply to you.
This Agreement is governed by the laws of the State of
Massachusetts.
Should you have any questions concerning this Agreement,
or if you wish to contact Hamilton Laboratories for any
reason, please write: Hamilton Laboratories Customer
Service, 21 Shadow Oak Drive, Sudbury, MA 01776-3165.
Introduction
Hamilton C shell(tm)
Introduction
Hamilton C shell is a language for interactively
using Windows NT, Windows 95 or OS/2. Compared to the
standard OS/2, Win95 and WinNT command processors, it
provides a vocabulary and grammar that allows much more
complex activities to be described. Some of its major
innovations include:
ú Command line editing of enormous statements with
arrow keys and filename and command completion.
ú User-definable function keys.
ú Fully recursive grammar. Statements can be
arbitrarily nested or piped without concern for
statement length or other arbitrary restrictions.
ú Procedures and aliases. The vocabulary of the
language is meant to be extensible by the user.
ú Variables, arrays and expressions. Integer and
floating point arithmetic, pattern matching
facilities and various file system tests and
editing operators provide an expressive grammar.
ú Threads and processes. Child threads and
processes can be spawned to run commands
asynchronously or in the background.
ú Command substitution. The output of one command
can be stuffed back on the command line as
arguments to another.
ú History. Past commands can be recalled and
edited.
ú Advanced filename wildcarding.
This product complies fully with industry-accepted
definitions for the C shell language. The user is not
asked to learn yet another new proprietary language not
available anywhere else. Instead, a tested, proven
framework has been adapted with modern compiler
technology for OS/2 and Windows NT and Windows 95:
1
Introduction
1. A modern top-down parser is used for better
language recognition and performance.
2. It's easier to use. The syntax and grammar have
been made flexible and more consistent with other
modern high level language conventions.
3. It knows about OS/2, Windows NT and Windows 95:
HPFS, NTFS, long filenames, environmental
variables, networks, international character sets,
and about all the various kinds of applications
supported by your system. Under OS/2, it has no
trouble starting PM and (under OS/2 2.x) seamless
Win3.x, 32-bit and Virtual DOS machine (VDM)
applications. Under Windows 95 and Windows NT, it
works with all DOS, Win3.x, Win32 and under
Windows NT, all POSIX and OS/2 character mode
applications.
4. You can customize the C shell to give you as
little or as much NT or OS/2 versus UNIX behavior
as you choose. For example, either \ or / can be
used in a filename. Either - or / can be used as
an option switch character for the utilities. You
can decide whether typing cd with no destination
directory means report the current directory (NT
or OS/2 style) or take you to the home directory,
and so on. (The chapter on customizing the C
shell, beginning on page 159, is devoted to this
topic.)
5. Threads are used extensively to achieve
performance and functionality not possible in
UNIX.
6. Feedback to the user, especially when reporting
errors has been improved. If you encounter an
error inside a complex script, you'll even get a
complete dump of the call stack showing how you
got there.
Who is it Designed For?
Most users of Hamilton C shell are relatively
technically oriented computer users. Often, they're
software developers. They have a business need for an
OS/2 or Windows NT or Windows 95 system.
Peering over their shoulders, they typically have
lots of windows open on the screen. Many of the windows
are running copies of this shell. Some copies are
transient, created to display with little snippets of
2
Introduction
information needed on the spur of the moment. Other
copies of the shell would be used for more long-running
projects: for example, getting a make working for a
major application.
A shell window is like any other application window
but with a different paradigm. Instead of data, rows
and columns of numbers or lines of text, the object being
manipulated is the machine itself.
A good shell tackles a different problem than icons
and windows. Instead of the point-and-shoot immediacy of
"do this single thing now," a shell offers language and
the ability to describe more customized or repetitive
actions, e.g., identify a suitable set of files, perform
some action against them and filter the results in some
interesting way.
3
Installation
Installation Guide
This section outlines how to install the Hamilton C shell
on your system. If you are installing the Win32 version
on Windows NT or Windows 95, follow the instructions
beginning on this page. To install the OS/2 version of
Hamilton C shell, please turn to page 11.
If you encounter problems, consult the "Common Problems"
section on page 23 or call us for technical support as
described on page 35.
Installation on Windows NT or Windows 95
System Requirements
Installation requires a 386-, 486- or Pentium-based
machine for the Intel x86 version, a MIPS R4000- or
R4400-based machine for the MIPS version or a DEC Alpha
AXP-based machine for the Alpha version of Hamilton C
shell. The machine must be running Windows 95 or Windows
NT 3.1 or later. Roughly 2.7 MB of disk space is used on
an Intel machine, 5.0 MB on a MIPS, 5.5 MB on an Alpha or
3.9 MB on a PowerPC.
Basic Installation
1.
Copy the bin and samples directories and other files
on these diskettes to your hard disk, putting them
anywhere you like. (Notice that the bin directory is
too big to fit on one diskette; you'll have to merge
the two or more diskettes, depending on which system
you have.) Most customers create a directory in the
root of one of their drives called "hamilton" to hold
everything.
2.
Copy the login.csh and startup.csh files into any
directory you care to designate as your "home"
directory. The significance of a home directory is
principally that it will be convenient to specify
pathnames relative to this directory. Most users
treat the home directory as a place for all their
5
Installation
personal files and subdirectories and give it their
own first name, e.g., C:\DOUG.
3.
Edit the login.csh and startup.csh files, customizing
them to meet your needs. If you're new to the C
shell, you'll probably want to get started by just
accepting them the way they came, but experienced
users may want to add their own aliases, etc.
4.
Edit the environment variables.
Windows NT:
Do this by opening the Control Panel and then,
within that, opening the system icon. To define a
variable through the Control Panel, type the
variable name in the "Variable:" fill-in box, the
value in the "Value:" box and click on the "Set"
button. You have a choice of whether to change the
system variables (seen by all users on your
machine) or just your own user variables.
Windows 95:
Do this by editing the c:\autoexec.bat file. To
define a variable, add a line of the form
set variable=value
where "variable" is the name of the variable and
"value" is the character string you want it set to.
Notice there are no spaces around the = sign.
On either system:
a.
Create or edit your entry for the PATH variable,
adding the full pathnames for the C shell's bin and
samples directories to the list.
b.
Create an entry for the HOME environment variable,
setting its value as the full pathname of the
directory where you placed login.csh and
startup.csh.
c.
You may also want to include definitions for TABS
and COLORS. The shell and all the utilities look
for TABS to see if you want them to display text
with tabs expanded out to something other than the
default of every 8 characters.
By default, the C shell displays white characters
on a black background. The COLORS variable lets
you choose a combination from this set: black, red,
green, yellow, blue, magenta (or blue red), cyan
6
Installation
(or blue green) and white. Foreground colors may
also be bright, dim, blink or reverse. The keyword
"on" introduces background colors. (Blink only
causes true blinking full-screen; in a text window,
it just makes the background brighter. Also,
yellow is a true yellow only if it's bright. These
are system limitations not related to the C shell.)
Other color settings you might want to specify now
or at some later time through the Control Panel are
MOREPROMPT, MOREFILLIN and MOREERROR (for
customizing the more utility's command line) and
DELETIONS and ADDITIONS (for customizing the diff
utility).
For more information on setting screen colors,
please refer to the colors.csh file in the samples
directory or to the Customization chapter.
Under Windows NT, here's an example of the settings
you might specify:
PATH=d:\hamilton\bin;d:\hamilton;samples
HOME=d:\doug
COLORS=white on blue
TABS=3
ADDITIONS=bright white on green
DELETIONS=bright white on red
MOREPROMPT=red on white
MOREFILLIN=black
MOREERROR=bright white on red
Under Windows 95, you might specify:
set PATH=d:\hamilton\bin;d:\hamilton;samples
set HOME=d:\doug
set COLORS=white on blue
set TABS=3
set ADDITIONS=bright white on green
set DELETIONS=bright white on red
set MOREPROMPT=red on white
set MOREFILLIN=black
set MOREERROR=bright white on red
5.
Set up an icon you can click on to start the C shell.
Windows NT:
a.
Add csh.exe with the title "Hamilton C shell" to
the Program Manager. To do this, pull-down "File"
and select "New". A pop-up will appear asking
that you confirm this will be a new Program Item.
On the next pop-up, fill in:
7
Installation
Description: Hamilton C shell
Command Line: ....as
appropriate....\csh.exe -L
The "-L" part tells csh.exe when it starts up that
it's a "login" shell, which means it should look
for a login.csh file.
Windows 95:
a.
Create a shortcut on the desktop to the C shell.
Open up "My Computer", then the appropriate disk,
etc., until you've gotten to the directory
containing csh.exe. Drag that to the desktop using
the right mouse button, replying "yes" to the popup
asking if you want to create a shortcut. You can
edit the title under the icon by slowly clicking
twice on the title. Press Enter when you've
finished.
b.
Left click on the icon and select Properties to
bring up the Properties window. To the "Shortcut"
page and edit the "Target" entry to add the "-L"
option. Type the name of your home directory in
the "Start in:" field.
c.
Since Windows 95 doesn't properly recognize icons
inside console applications in the current release
(this appears to be a bug in Win95), you'll have to
manually use the "Change Icon_" button to bring up
the popup where you can browse for csh.ico in the
bin directory where you put csh.exe. Press Apply,
then OK when you're done.
6.
Under Windows 95, you'll need to shutdown and restart
the machine to have any changes you make to
autoexec.bat take effect. Under Windows NT, the
changes you make via the Control Panel take effect
immediately.
7.
Additional customization:
Windows NT:
Most people find it useful to run the C shell in a
window with more than just 25 lines and an even
larger buffer with a scroll bar on the right. You
can resize the buffer and window using the setrows
command. For example,
setrows 300 35
will give you a 300-line buffer with a 35-line
window. Once you find a setting you like, you can
8
Installation
save this for future sessions by pulling down the
system button (the button in the upper left corner
of the window), selecting "Properties_", pressing
OK, then responding OK again when asked if you'd
like these properties applied to future windows
with the same title.
Windows 95:
Windows 95 doesn't support arbitrary-size console
windows or buffers reliably. The close button (the
"X" in the upper right corner) doesn't work right
with console applications. Even if you fix the
icon that's displayed with your shortcut (as
described above), the C shell will still show just
the default MS-DOS icon in its title bar when it
runs. The properties popup (right button) will let
you change some of this, but the values can't be
saved that way for future invocations of the C
shell.
The reason for these problems is that because Win95
is really a 16-bit system, it's using an
intermediate program, conagent.exe, to actually run
32-bit console applications like the C shell. If
you want to make changes in window size, or how the
close button works or what icon is used, you must
make the changes to conagent, not the C shell. To
do this, use the Win95 Explorer to open up the
\windows\system directory. Right-click on conagent
and select Properties. You can change the icon to
csh.ico on the Program page, set whatever screen
size you like on the Screen page, and enable the
close button by clearing the check box next to
"Warn if still active" on the Misc page.
Do bear in mind, however, that any changes you make
to conagent will affect all Win32 console apps you
run. (But note: the MS-DOS command.com program is
not a 32-bit application, so it will not be
affected.)
9
Installation
Installation on OS/2
The first few steps, copying files from diskette to your
hard disk and modifying your config.sys, are the same on
all releases of OS/2. The remaining steps -- those
associated with actually installing Hamilton C shell on
your OS/2 desktop -- depend on which release of OS/2
you're running. We suggest a "vanilla" installation
initially, but later you may want to customize it to your
own tastes. For help with that, read the chapter on
"Customizing the Shell," beginning on page 159.
Once you've gained familiarity with both OS/2 and the C
shell, you may want to set up the C shell as the default
command processor for OS/2, completely replacing cmd.exe
as described on page 18. The advantage to be gained
(except under the 6.167 Beta and LA builds of 2.0) is
that the C shell will then be able to change its own
title bar and icon when you run an external command.
System Requirements
Installation requires a 286, 386 or 486 or greater AT(R)
or PS/2(R) or compatible, running OS/2(R) 1.1
(Presentation Manager) or Microsoft SDK 1.06 or later.
Roughly 1.54 MB of disk space is used.
Hamilton C shell and the utilities supplied with it fully
support HPFS and long filenames when running under OS/2
1.2 or later. They will work properly in a Presentation
Manager text window or full-screen and with networks such
as LAN Manager or IBM LAN Server. If you're using OS/2
2.x, it knows how to run 32-bit applications and start up
Multiple Virtual DOS machines and run Win3.x applications
seamlessly on the desktop. The product is not copy
protected.
Basic Installation, Part I (All releases of OS/2)
1.
Copy the bin and samples directories and other files
on these diskettes to your hard disk, putting them
anywhere you like. Most customers create a directory
in the root of one of their drives called "hamilton"
to hold everything.
11
Installation
2.
Copy the login.csh and startup.csh files into any
directory you care to designate as your "home"
directory. The significance of a home directory is
principally that it will be convenient to specify
pathnames relative to this directory. Most users
treat the home directory as a place for all their
personal files and subdirectories and give it their
own first name, e.g., C:\DOUG.
3.
Edit config.sys:
a.
Add the ".", bin and samples directories to the
beginning of your search path.
b.
Add statements to define the HOME directory you've
chosen and to ensure you're configured for a
sufficient number of threads. (The default number
of threads is too small if you expect to have lots
of windows open.
c.
You may also want to include definitions for TABS
and COLORS. More.exe and some of the other
utilities look for TABS to see if you want them to
display text with tabs expanded out to something
other than the default of every 8 characters.
By default, the C shell displays white characters
on a black background. The COLORS variable lets
you choose something different from this set:
black, red, green, yellow, blue, magenta (or blue
red), cyan (or blue green) and white. Foreground
colors may also be bright, dim, blink or reverse.
The keyword "on" introduces background colors.
(Blink only causes true blinking full-screen; in a
text window, it just makes the background brighter.
Also, yellow is a true yellow only if it's bright.
These are OS/2 limitations not related to the C
shell.) For more information on setting screen
colors, please refer to the customization chapter
or to the colors.csh file in the samples directory.
Here's an example of what you might add to
config.sys:
SET PATH=.;C:\HAMILTON\BIN;C:\HAMILTON\SAMPLES;
C:\OS2;C:\OS2\SYSTEM;C:\OS2\INSTALL;C:\;
THREADS=255
SET HOME=D:\DOUG
SET TABS=3
SET COLORS=WHITE ON BLUE
(The "SET PATH=_" statement is too long to shown on
one line here but in your config.sys, it should be
one big long line.)
12
Installation
Please be sure your config.sys file contains only
upper-case alphabetics, no lower-case, if you're
using OS/2 1.1. Lower-case alphabetics were known
to cause random OS/2 system failures in that
release of OS/2. This was a known bug in the OS/2
kernel and was not application dependent.
4.
Edit the login.csh and startup.csh file, customizing
them to meet your needs. If you're new to the C
shell, you'll probably want to get started by just
accepting them the way they came, but experienced
users may want to add their own aliases, etc.
Unless you're convinced that you've set all your
environmental variables in your config.sys (and that
your PATH explicitly lists ".", the current
directory), use the dumpenv utility to paste a series
of setenv statements into the login.csh file to
recreate the environment you've been using with
cmd.exe:
dumpenv >>login.csh
(To see what dumpenv does, look at the source code
in samples directory or simply run dumpenv without
redirecting the output.)
The remaining steps depend on which release of OS/2
you're running.
Basic Installation, Part II (OS/2 1.1)
5.
Add csh.exe with the title "Hamilton C shell" to the
"Start Programs" menu. To do this, pull-down
"Program" and select "Add..." from the menu bar.
Fill in:
Program title.... Hamilton C shell
Path and file name ....as
appropriate....\csh.exe
Parameters.... -L
The "-L" part tells csh.exe when it starts up that
it's a "login" shell, which means it should look for
a login.csh file. (Refer to page 283 for additional
information on other options.)
6.
You will likely want to create a second entry for
running full-screen. It's more convenient if you're
mostly working with applications that only run full-
screen or if you want faster text display, especially
scrolling. To do that, from the "Start Programs"
13
Installation
menu, pull-down "Program" and select "Copy..." from
the menu bar. In the Copy Programs popup, fill in
the following and push the "Copy" button:
Change Title to: Hamilton C shell -- Full
Screen
Back in the "Start Programs" window, select the new
full screen title, pull-down "Program" and select
"Change..." In the Change Program Information popup,
push the "Change" button. This brings up the How to
Run the Program popup; select "Run the program full-
screen" and "Enter."
7.
Reboot your system before starting Hamilton C shell
for the first time. This causes the new statements
in config.sys to take effect.
14
Installation
Basic Installation, Part II (OS/2 1.2 or 1.3)
5.
Add csh.exe with the title "Hamilton C shell" to the
"Group - Main" menu. To do this, pull-down "Program"
and select "New..." from the menu bar. Fill in:
Program title: Hamilton C shell
Path and file name: ....as
appropriate....\csh.exe
Parameters: -L
The "-L" part tells csh.exe when it starts up that
it's a "login" shell, which means it should look for
a login.csh file. (Refer to page 283 for additional
information on other options.)
6.
You will likely want to create a second entry for
running full-screen. It's more convenient if you're
mostly working with applications that only run full-
screen or if you want faster text display, especially
scrolling. To do that, from the "Group - Main" menu,
pull-down "Program" and select "Copy..." from the
menu bar. In the Copy Programs popup, fill in the
following and push the "Copy" button:
Change Title to: Hamilton C shell -- Full
Screen
Back in the "Group - Main" window, select the new
full screen title, pull-down "Program" and select
"Properties..." In the Properties popup, push the
down arrow next to the "Program Type:" box and select
"OS/2 Full Screen" on the list that will appear and
then push the "Change" button.
7.
Reboot your system before starting Hamilton C shell
for the first time. This causes the new statements
in config.sys to take effect.
15
Installation
Basic Installation, Part II (OS/2 2.x)
5.
Open the Templates folder and drag a program object
to the desktop (or another folder) by pressing and
holding the right mouse button as you drag. On the
Program page of the "Program - Settings" window that
will appear, fill in:
Path and file name: ....as
appropriate....\csh.exe
Parameters: -L
The "-L" part tells csh.exe when it starts up that
it's a "login" shell, which means it should look for
a login.csh file. (Refer to page 283 for additional
information on other options.)
6.
On the Window page of the Settings, you will probably
want to set
Minimized button behavior: Minimize window to
desktop
Object open behavior: Create new window
Doing this will let you conveniently open up lots of
copies of the C shell as needed.
7.
On the General page of the Settings, set
Title: Hamilton C shell
Close the Settings by pressing Alt-F4.
8.
You will likely want to create a second entry for
running full-screen. It's more convenient if you're
mostly working with applications that only run full-
screen or if you want faster text display, especially
scrolling. To do that, copy the C shell icon you
just created by right-clicking on it and selecting
"Copy..." and then choosing an appropriate
destination folder (probably the desktop) for the
copy. You can also copy the icon by pressing and
holding the Ctrl key while dragging with the right
mouse button.
9.
Once you've made the copy, right-click on it and
select "Open" and then "Settings." On the "Session"
page, select "OS/2 full screen." Then go to the
"General" page and type a new title:
16
Installation
Title: Hamilton C shell
Full Screen
Close the Settings window for the copy by pressing
Alt-F4.
10.
Reboot your system before starting Hamilton C shell
for the first time. This causes the new statements
in config.sys to take effect.
17
Installation
Installation as the Default Command Processor
The C shell can also be installed as the default
command processor OS/2 protected mode, meaning you
specify it, not cmd.exe in your config.sys. The
principal advantage is that when the when the C shell is
run as the default command processor, PM allows the C
shell to change its own title bar and, under OS/2 1.3 or
2.x (but not the 6.167 Beta or LA builds), its own icon
to show what it's running. This can be quite helpful if
you have lots of copies of the shell running minimized
and would like to know what each one is doing.
The disadvantage is that the installation is slightly
messy and it does disable cmd.exe's ability to change its
title bar and icon. For these reasons, most users will
want to wait until they've gained some familiarity with
the C shell and with OS/2 before installing it this way.
To install the C shell as the default command processor,
follow the instructions for the basic installation but
then make these changes, as appropriate for your system:
Default Command Processor Installation Procedure (OS/2
1.2 or 1.3)
1.
Edit the PROTSHELL line in your config.sys, replacing
the pathname and any parameters for cmd.exe
(remembering what they were) with the pathname for
the C shell and a -L (login) parameter. The
resulting line should look something like this:
PROTSHELL=C:\OS2\PMSHELL.EXE C:\OS2\OS2.INI
C:\OS2\OS2SYS.INI C:\OS2\BIN\CSH.EXE -L
2.
Change the pathname you specify for the C shell in
Start Programs or Group-Main to * (an asterisk).
Also, change the parameters line to be either blank
(1.1 or 1.2) or (1.3):
/K "%*"
3.
Change the entries (probably named "OS/2 Window" or
"OS/2 Full Screen") in Group-Main or Start Programs
for cmd.exe to fill in the complete pathname for
cmd.exe instead of an asterisk. Set the parameters
to whatever you had specified following the pathname
for cmd.exe (if anything) in your config.sys before
changing it in step 1.
18
Installation
4.
Change any entries in any of your program groups that
invoke .cmd scripts to run them via cmd.exe
explicitly. For example, if you had an entry that
specified the program "c:\myapp\foo.cmd", change that
to:
Path and file name: c:\os2\cmd.exe
Parameters: /C c:\myapp\foo.cmd ...any
additional parameters...
5.
Reboot.
Default Command Processor Installation Procedure (OS/2
2.x)
1.
Edit your config.sys to set OS2_SHELL to point to the
C shell, specifying the -L (login) option, e.g.,
set OS2_SHELL=c:\hamilton\bin\csh.exe -L
2.
Modify the Settings for the OS/2 Window and OS/2 Full
Screen icons to show the full path for cmd.exe (e.g.,
"c:\os2\cmd.exe") rather than an asterisk on the
Program page.
3.
Modify the Settings for the Hamilton C shell icons to
specify an asterisk pathname (meaning the default
shell), deleting any mention of any startup
parameters and explicitly specifying the C shell icon
rather than the default icon:
a.
Right-click on the icon and open the Settings.
b.
On the Program page, set
Path and file name: *
Parameters:
c.
Select "Find..." next to the icon display.
d.
Select "Locate" on the Find screen.
e.
Select the "Path" page on the Locate Folder
screen.
f.
Type the pathname of the directory containing the
C shell's csh.ico icon file. (E.g.,
"c:\hamilton\bin".)
g.
Press the "OK" button on the Locate Folder screen.
h.
Type "csh.ico" in the Name field on the Find
screen.
19
Installation
i.
Press the "Find" button.
j.
The Find Results screen should appear with the C
shell icon highlighted. Press the "OK" button.
k.
Back in the General Settings screen, you should
now see the C shell's icon. Press Alt-F4 to close
the screen.
4.
When you reboot, the C shell will be the default
shell and it will appear with its correct icon both
for starting and when you minimize it.
20
Installation
21
Common Problems
Common Problems
When I try to start the C shell in a new window, it dies
and goes away before I can read its messages.
You've probably made an error on the "Parameters" line
under OS/2 or in the "Command Line" under NT. Under NT,
select the icon for Hamilton C shell and press Alt-Enter
to examine the properties.
Under OS/2, you can force the window will to stay up
after the shell exits so you can read the message by
following the instructions appropriate for your system:
1.
OS/2 1.1: Go to the "How to Run the Program" screen
by clicking on the C shell entry in "Start Programs"
and pulling down "Program" then selecting
"Change...". Click on the check box beside "Close
the window..." and press Enter.
2.
OS/2 1.2 or 1.3: Click on the C shell entry in
"Group - Main", pulling down "Program" and selecting
"Properties". Push the "Options..." button and click
on the check box next to "Close window on exit",
removing the X.
3.
OS/2 2.x: Right-click on the icon and select "Open"
followed by "Settings." On the Session page, click
on the check box next to "Close window on exit",
removing the check.
The shell doesn't know how to run an external command.
One of the environmental variables, particularly
HOME, PATH or COMSPEC is probably set incorrectly.
Typical symptoms are that the shell doesn't seem to know
how to find an external command or that it doesn't know
how to run a .cmd file, etc. Another variation might be
that it runs the old IBM more.com rather than the new
more.exe. If you experience symptoms like these, first
check that these variables are set sensibly.
The other common possibility under OS/2 1.x is that
you're using a network and have execute, but not read
access to the application you're trying to run. Due to a
bug in the OS/2 1.x kernel, the C shell cannot use the
23
Common Problems
kernel's DosQAppType function to determine whether the
application should be started full-screen, in a text
window or as a PM graphics application. Instead, the C
shell is forced to read the application's .exe header
itself; if it can't read it, it can't run it. The
solution is to be sure you have read access.
The close button doesn't work on the C shell under
Windows 95.
Microsoft has acknowledged that this is a bug in
Window 95. When you click the close button or shutdown
the system, all console applications are supposed to get
a signal telling them to exit. Windows NT implements
this correctly, but Windows 95 does not. The workaround,
turning off the "Warn if still active" property for
conagent.exe, is described on page 9 as part of the
installation for Windows 95.
The whole C shell window fills with all sorts of random
colored trash.
This is a known Windows 95 bug. Not all possible
size console windows work right. In general, only 25, 43
and 50-line windows actually work. If you try to set an
arbitrary size window (e.g., using the setrows utility),
chances are it's not going to work. One of the failure
modes is having the whole window fill with random colored
trash characters. There is no known workaround except to
set the window size back to a setting that works.
The C shell doesn't work right with a scroll bar under
Windows 95.
This is a known Windows 95 bug. If you try to set
the buffer size larger than the window size so you can
have a scroll bar on the C shell's window, chances are
you'll encounter problems such as not having the line
with the cursor pop into the window when you type, etc.
There is no known workaround except to set the buffer
size back to a setting that works.
24
Common Problems
How do I get the C shell to use its own icon, not the MS-
DOS icon?
Windows 95 does not know how to extract icons from
console applications so you'll have to setup the icon
manually. You'll need to do it once for any shortcut you
create on the desktop, then again for the conagent.exe
program that Windows 95 uses to actually run the C shell.
You'll find detailed instructions for doing beginning on
page 8.
Why can't I read or write a tape under Windows 95?
Windows 95 doesn't support the tape backup API used
by tar under Windows NT. As a consequence, tar has no
way of talking to the tape drive under Windows 95. The
only solution, if you need tape support, is to upgrade
from Windows 95 to Windows NT.
When I try to read a tar tape, tar says it was written
with a different blocksize or that the blocksize is
larger than my hardware can support.
Very likely, you're trying to read a DAT tape created
on a Silicon Graphics machine. A lot of SGI machines
were set up to write tapes with a default blocksize of
256K. That's much larger than most PC's can support.
Most PC's will only support a maximum blocksize of about
64K; PC's using a PCI bus will go to about 102K, but
still far short of what SGI uses. The workaround is to
rewrite the tape on the SGI using a more reasonable
blocksize. You can do this using the UNIX tar's "b"
option to specify a smaller "blocking factor." (You
multiply the UNIX blocking factor by 512 to get the
number of bytes/block.) A good choice is a blocking
factor of 20, meaning a 10,240-byte blocksize, which
corresponds to the POSIX standard for tar tapes. The
complete command line on the SGI will look something like
this:
tar cvb 20 _files to be added to the tape_
I know there's data on my tape, but tar acts like it's
blank.
There are two possibilities. If it's a DAT tape you
wrote yourself on this same machine, (or if you can
recreate the problem using a tape you create yourself),
25
Common Problems
it's likely your drive has a firmware bug in its variable
block support. (Variable block i/o allows tar to read a
tape without knowing what blocksize was used to write the
tape.) The workaround is to read the tape using the -V
option to tell tar not to use variable block i/o. If the
tape wasn't written with a standard blocksize, it may
take a while longer for tar to figure out what blocksize
was used (without variable blocksize support, it has to
try all the possibilities), but at least it will work.
The second possibility is that the tape was written
with hardware compression turned on, but your drive
doesn't support compression. You can find out if your
drive supports compression using the "mt status" command.
There isn't any workaround for reading a tape written
with compression on a drive that doesn't support it;
you'll have to rewrite the tape .
When I read or write a tape, what does it mean if some of
the files are listed in yellow?
It means those appear to be ASCII text files and that
tar has tried to convert the line endings between the PC
convention of a CarriageReturn-LineFeed combination at
the end of each line and the UNIX convention of just a
single LineFeed character. (The assumption is that since
the tar format is basically a UNIX standard, files in a
tar archive should follow the UNIX convention but be
stored in the PC convention on your hard disk.)
If you ever need to, you can suppress this automatic
conversion by using tar's "-r" option.
I can read the tapes I create, but they can't read them
on the UNIX machine.
There are a couple possibilities. One is that you've
written the tape in the wrong bytesex for the UNIX
machine and the other is that you've written the tape
using compression and that the drive on the UNIX machine
doesn't support compression.
By default tar creates tapes in little-endian format,
meaning that when it writes a 16-bit binary number on the
tape, it writes the byte with the least significant byes
(the little end) first. A lot of UNIX workstations
follow the opposite convention. The solution is to write
tapes in big-endian format using tar's "-bB" option. But
if that's not convenient, the workaround on the UNIX
machine is to read the tape using the following command
26
Common Problems
line, where tapedevice refers to the name of tape unit on
that UNIX machine:
dd conv=swab < /dev/tapedevice | tar xf -
Tar complains about "garbled headers."
There are two possibilities. One is that your tape
has a bad spot. The other is that your archive isn't
really a tar archive at all.
When reading an archive, tar expects the data to fit
a standard layout defined by the POSIX standard. Each
file in the archive is expected to be preceded by a 512-
byte header telling the filename, the timestamp, etc.
Each header has a checksum so tar can verify the data
really is good. If it encounters a header that doesn't
fit the standard, tar assumes it has it a bad spot in the
archive. But rather than just give up, tar scans down
through the rest of the archive, byte-by-byte, looking
for a new header that actually is valid.
Tapes do occasionally develop bad spots, and this
ability to scan forward can be invaluable in retrieving
data that otherwise would be completely lost. But if the
data really isn't a tar file at all, then scanning ahead
is not going to achieve anything.
When I write to lpt1: under Windows 95, it doesn't work.
This appears to be a bug in Windows 95 that prevents
Win32 console applications from writing to the printer.
We are not aware of a workaround.
The shell won't run my new program.
Path hashing can sometimes produce surprising results
if you create a newer version in your current directory
of a command that already exists in another of your path
directories. The shell won't know you've done this; its
hash will still only list the older version. To overcome
this problem, use either the rehash or unhash commands.
27
Common Problems
The shell won't execute commands in the current
directory.
You should add the current directory to the list of
directories in the PATH variable. Cmd.exe always checks
the current directory before looking in any of the PATH
directories. Hamilton C shell does not make this
assumption; if you want the current directory to be first
one checked, you should specify it explicitly as "." at
the beginning of the list. For example:
setenv PATH = '.;c:\os2;c:\os2\bin'
The shell keeps running the old version my shell
procedure.
If you define a shell procedure with proc in a .csh
script file and then execute the script, the procedure is
compiled into an internal form that's much faster to run
and it's kept around in memory to make it run the next
time even faster. If you change the text in the script
file but don't explicitly throw away the old definition
using unproc, the C shell won't know it's supposed to
recompile.
The shell won't run any cmd.exe internal commands.
Most probably, the shell is unable to find your
startup.csh file when it starts up. This is the file
that should hold the aliases the shell uses to intercept
cmd.exe's built-in commands. Check to see that your HOME
variable is set to the directory where you've placed
startup.csh and that your startup.csh file isn't garbled.
My C shell utilities hang when invoked by Perl under
Windows NT.
This appears to be an incompatibility between Windows
NT, Perl (even as distributed by Microsoft on the Window
NT 3.51 Resource Kit) and Microsoft Visual C++ 4.0, which
was used to build Hamilton C shell. Most applications
(including even a simple "hello, world" program) built
with VC++ 4.0 will hang when run from Perl. The only
workaround we're aware of is to invoke the utility via
cmd.exe or redirect stdin. For example:
perl -e 'print `hello.exe < nul`'
28
Common Problems
When I start an application from the C shell under OS/2,
it dies immediately.
Under OS/2, if you find that an application dies
immediately after starting, check that the .exe file is
properly marked with its type, i.e., full-screen, PM text
windowable or PM graphics. The shell tries to start up
an application in accordance with the way it's marked; if
it's marked wrong, the application just won't run. Even
very recently, a number of PM applications including even
e.exe, the System Editor, were being shipped unmarked,
which by convention is supposed to mean full-screen. To
look at or change how an application is marked, use the
markexe.exe utility. (Type "markexe -h" for help.)
Another possibility is that the application has a bug
that makes it fail if the maximum file handle count it
inherits from its parent process is greater than 20.
This problem has been seen in some past releases of the
Microsoft linker (discussed below) and of WordPerfect,
for example. You can force the C shell not to bump the
file limit when it starts up using the -Z option but this
option only works from the Start Programs (1.1) or Group
(1.2) menus, not from the command line. (A process
always inherits its initial maximum file handle count
from its parent; from there, a process can only raise its
own limit, never lower it.)
The Microsoft OS/2 linker fails under the C shell even
though it works fine under cmd.exe.
Microsoft has determined there was a bug in the
version of the C library used to build the link.exe
distributed with MS C 5.1. The linker can fail if it's
run as a child of a process that has a maximum file
handle count greater than 20; this is a problem because
the C shell sets its maximum to 255. If you're
encountering this problem, try patching your link.exe
file with the patchlnk.exe utility. (Type "patchlnk -h"
for help.)
When I try to run Microsoft's make.exe in the background
it hangs.
This is a known problem under OS/2 with make and
certain other applications that need to spawn child
processes of their own. The OS/2 process initialization
and completion logic requests a semaphore in KBDCALLS.DLL
that's already owned by whatever process in that window
is already sleeping in a KbdCharIn call. Until another
29
Common Problems
keystroke is pressed, that semaphore is never released
and the background processes are never allowed to cleanly
exit. This problem has been fixed in OS/2 2.x and
through CSD 5050 for OS/2 1.3 with a new KBDCALLS.DLL.
That DLL for 1.3 is available on request from Hamilton
Laboratories and can be downloaded from the listings area
in the "hamilton" conference on BIX.
copy or rename *.* doesn't work right.
Copy, xcopy, rename and del like to do their own
wildcard expansion. To make them work sensibly, be sure
your startup.csh file includes and that you use the
aliases and procedure definitions we supply to intercept
these commands to turn off shell wildcarding just long
enough to run them. These definitions can also serve as
a model if you discover other applications that must do
their own wildcarding. For more information, refer to
the discussion on page 99.
The -! option doesn't work.
The exclamation point is a special character for the
shell. The shell lets you pick up text out of previous
commands using history references that begin with "!"
followed by a string that tells what text you're
retrieving. To avoid having an exclamation confused as a
history reference, be sure the exclamation is at the end
of a word, so the next character is a space or a tab.
grep `^foo' doesn't work.
The circumflex has special meaning as the escape
character to the C shell, even inside quotes. If you
want to pass a literal "^" to grep (or anything else)
from the command line, you must type "^^" unless the
immediately preceding character was "[".
When I list a directory over the network, not everything
shows up.
This is a known bug in the OS/2 networking code, not
the C shell. The problem occurs if (1) the directory is
read over a network, (2) directory entries are being read
in blocks (for higher performance) rather than one-at-a-
time and (3) the total number of characters in all the
30
Common Problems
filenames in that directory happens to be just right. In
all cases observed, adding or deleting any arbitrary
entry in the directory makes the problem go away. The
bug affects the C shell and its utilities because they
use blocked reads; simpler programs like cmd.exe's DIR
are unaffected because they read one entry at a time.
The bug appears to have been introduced in IBM OS/2
EE CSD WR04098 and Microsoft Lan Manager 2.0, both issued
around year-end, 1990. IBM verified the problem and
developed a fix, which shipped as part of OS/2 EE 1.3.
Since then, the problem has come and gone from one
release to the next; apparently IBM has not been quite
diligent about regression testing!
The work-around is to disable the C shell's block
read feature. If you create an environmental variable,
NETWORKBUG, and set it equal to 1, directory reads will
be done only one-at-a-time, ensuring correct results at
all times, albeit with some degradation in performance.
You can do this either from the C shell:
setenv NETWORKBUG = 1
or in your config.sys:
SET NETWORKBUG=1
du, pwd and vol waste time sitting and spinning when they
hit a removable drive that's empty.
If you have a removable media device other than A: or
B:, these utilities will normally try to report them.
That's probably not you want, at least not usually; you
can specify just the set of drives you do want reported
using the DRIVEMASK environmental variable.
cd /foo doesn't work.
Hamilton C shell tries to serve users coming both
UNIX and MS-DOS backgrounds. To do this, the C shell and
all the utilities accept command line options starting
with either "-" (UNIX-style) or "/" (DOS-style). They
also recognize filenames typed with either forward or
backward slashes. When you type "cd /foo", the C shell
guesses wrong and thinks you're trying to give it a
command line option that it can't recognize.
If this is really not what you intend, set the
SWITCHCHARS environmental variable to just the specific
31
Common Problems
characters you want recognized. E.g., you might include
this in your config.sys to have only "-" recognized:
set SWITCHCHARS=-
I can't set my own screen colors.
Yes, you can. But you cannot do it just by embedding
ANSI escape sequences into your prompt since the C shell
will immediately reset the colors back to what it thinks
they should be. To set your own preferences for screen
colors, you must use the COLORS environmental variable.
See the chapter on customizing the shell or the
colors.csh script in the samples directory for more
information.
The C shell's icon won't display in Group-Main.
If you install the C shell as the default command
processor by specifying it on the PROTSHELL line in
config.sys and entering its path as "*" in Group-Main,
you will see only the default OS/2 icon in Group-Main if
you select View Icon. If you start, then minimize the C
shell, it will have the correct icon, however. This has
been reported to IBM. Their response is that, by design,
when the path is an "*," the Group code does not attempt
to resolve the actual pathname (and whether there's any
icon associated with it) until you actually click on the
entry to start it. They agree this means you will not
see the correct icon in the Group menu but claim this is
what they intended and that it's not a bug.
Alt-Enter doesn't work to grab commands from the history
list under Windows NT or Windows 95.
Under Windows NT and Windows 95, Alt-Enter is gobbled
up by the system as a keystroke combination used to
signal that an application should be toggled back and
forth between the desktop and a full-screen session.
Under the these systems, you'll have to type Ctrl-Shift-
Enter instead.
32
Common Problems
I just installed the C shell as the PROTSHELL and now
when I start Communications Manager, it dies immediately.
Communications Manager is invoked via a .cmd script
file. Follow the instructions in step 4 on page 18 to
rewrite that entry to start that script explicitly via
cmd.exe.
I can't wildcard filenames with $'s, spaces or quotes in
them.
Yes, you can. To do so, just quote or escape the
special characters. E.g., to get all the files that
begin with $, you might type ^$* or '$'* .
I can't run the C shell inside an Epsilon editor window
under OS/2.
The Epsilon editor tries to run whatever command
processor you use by creating a full-screen session and
doing a KbdRegister to intercept the KbdStringIn API
entry so that Epsilon can feed it whatever you type in
the editor window. Output (stdout and stderr) from the
child session is redirected over a pipe back to the
editor.
There are a couple problems in their approach: (1)
They neglected to consider that not all applications use
KbdStringIn; if stdin is attached to a keyboard, the C
shell reads a keystroke at a time using KbdCharIn and
those calls still end up tied to that full-screen session
rather than being redirected. (If stdin is attached to
anything else, it uses DosRead calls.) The authors of
Epsilon really should have intercepted the whole set of
Kbd calls, not just one of them. (2) Not all
applications write their output to stdout or stderr;
applications like more, that use Vio output, won't run
properly. Their output appears in that full-screen
session, not back in the editor window. Epsilon really
should be doing a VioRegister to grab the Vio output
also.
A partial workaround is to tell Epsilon to use a
separate program, which just reads input and pipes it to
the C shell. Marty Klos at IBM has written a small C
program to do that and placed it in the public domain. A
copy is available on request from us or may be downloaded
from the listings area of the "hamilton" vendor support
conference on BIX.
33
Common Problems
rm doesn't remove anything, it just puts everything in a
hidden directory.
You're using the notorious Microsoft rm command
instead of the Hamilton rm. The Microsoft rm doesn't
remove anything; it just puts things in a hidden system
directory. Hamilton rm is actually in hrm.exe under
Windows NT and should be aliased to rm in your
startup.csh file. Fix that and then, to get rid of all
those "deleted" directories:
cd \; rm -x `ls -1ra +H | dim | grep 'deleted$'`
34
Support
Product Support
If you encounter problems or would like to make
suggestions for a future revision, please contact us by
any of the following or by regular mail; we promise a
prompt response.
Phone: 508-440-8307
FAX: 508-440-8308
Telex: 6503890321
BIX: hamilton
Internet: hamilton@bix.com
Also, on BIX, we have a vendor support conference.
Do a "join hamilton" once you get on or follow the menus
into the conference system.
Bug Reports
If you encounter what you believe to be a bug, please
try to experiment to see what specific command or command
sequence seems to be failing before calling. A problem
that can be reproduced is obviously easier to fix. Built
in to Hamilton C shell are a number of consistency checks
to trap bugs before they cause damage and to snapshot
enough information to help us diagnose and repair the
problem. If the shell is actually crashing, look to see
if a new entry has been added to the error log,
crash.csh, in your home directory; that information will
be useful.
Rest assured, our policy is that if you find a
legitimate bug, we will fix it, no time limit, no charge,
no excuses. We believe you've paid for working software,
not non-working software and that's what we promise to
deliver.
Future Enhancements
Work continues on additional features and
enhancements. As they become available, we want you to
have them. To get them, all you have to do is call or
send email and request the latest build; most customers
find that requesting a new update every 12 to 18 months
or when they install a new release of the operating
system works well.
35
Support
Please return the registration form by mail or FAX.
Without that, we often have no way of knowing who you
are. This is particularly true if your copy was
purchased through your company's purchasing department
or through a retail distributor. Also, we very much look
forward to your feedback as we strive to improve the
product.
36
Support
37
Getting Started
User Guide
Getting Started
Starting Hamilton C shell is as simple as just
double-clicking the icon or typing "csh" as a command to
cmd.exe or, under Windows 95, to command.com. After the
initial greeting, you'll see the first prompt: (The
underscore is meant to be the cursor.)
Hamilton C shell(tm) Release 2.2
Copyright (c) 1988-1996 by Hamilton Laboratories.
All rights reserved.
1 D% _
This tells you that it will remember what you type as
command number 1 and that your current drive is D. The
"%" is traditional; rather like the ">" for DOS.
Naturally, you can change your prompt if you want, to be
anything you like. For example, to get a prompt that
looks like one you might get from cmd.exe*:
1 D% set prompt1 = '[$upper(cwd)] '
[D:\DOUG] _
This works by taking the value of the cwd (current
working directory) variable, turning it to upper case
using one of the built-in procedures and pasting left and
right brackets around it. The value is recalculated each
time a prompt is given, so it always displays an up-to-
date value. (Lists of all the built-in variables and
procedures are given in later sections.)
To set it back:
[D:\DOUG] set prompt1 = '$@ $CDISK% '
3 D% _
* We introduce this is as the first example with some
trepidation: the prompt seems to be the first thing
people want to change. But it can also be one of the
more daunting projects if you're getting started.
This example is offered more in the spirit of assurance
that, with a little experience, the prompt can be set
to anything you like.
39
Getting Started
Basic Statements
Generally speaking, whatever commands you might have
typed into cmd.exe (or command.com) will still work here.
Even an "internal" cmd.exe function like dir works:
3 D% dir
The volume label in drive D is USER.
Directory of D:\DOUG\SH\DOCS\SCRIPT\HELLO
.
2-23-89 2:13p
.. 2-23-89 2:13p
HELLO C 72 2-23-89 12:56p
HELLO EXE 7731 2-23-89 12:57p
MEMOS 2-23-89 1:46p
5 File(s) 1581056 bytes free
4 D% _
If the command you type refers to a .cmd batch file
or a cmd.exe internal function, Hamilton C shell passes
it to a child process running cmd.exe for evaluation.
(cmd.exe's built-in functions are intercepted with
aliases defined in your startup.csh file.) Everything
else is evaluated directly by Hamilton C shell. For
example, if you type the name of an .exe file, the
appropriate DosExecPgm( ) or DosStartSession( ) call to
the OS/2 kernel or CreateProcess( ) call to the NT kernel
to start that program will be done directly by Hamilton C
shell.
A bit-mapped hash mechanism is used so that when you
type the name of a command, the shell zeroes right in on
file you mean. It doesn't have to check every path
directory for every possible extension. Naturally, if
you type a command that doesn't exist, the shell
complains:
4 D% zork
csh: Couldn't find an executable file named 'zork'.
By being more than merely a "wrapper" around an
existing command processor, several advantages are
created: (1) performance is understandably (and
visibly!) much higher and (2) limitations on command line
lengths, etc., become the relatively generous limits of
OS/2 and NT, rather than the restrictive limits of
cmd.exe.
40
Getting Started
Customizing the Screen Colors
The C shell's default screen colors are white
characters on a black background. Highlighting and color
are used to make some things (special files, etc.) stand
out. All the use of color or highlighting is completely
customizable. You can choose anything you like. The
chapter on customization will go into this in detail, but
for now, let's suppose we'd simply like to pick something
a little easier on the eyes, like white characters on a
blue background:
5 D% setenv COLORS = white on blue
Command Line Editing
With command line editing, you'll notice immediately
how much easier it is do things quickly without a lot of
retyping. As you try the examples, notice how the arrow,
insert, delete, home, end and other keys can be used to
recall previous commands or make changes anywhere on the
line.
Command line editing is like having a full-screen
editor pasted onto the front end of the shell. Key
bindings are intuitive and follow accepted conventions.
You can create enormous commands that stretch over screen
after screen and move around with the arrow keys,
inserting or deleting anywhere. Watch changes ripple
almost instantly down even an entire screenful of text.
We think you'll find our command line editing superior to
anything you've seen or used elsewhere.
The basic key assignments are:
Toggle between insert and overstrike
modes. (The cursor is thicker when
you're inserting.)
Beginning/end of command line.
One character
left/right.
Up/down one command in the
history list.
Pressing Ctrl with the arrow keys lets you move by
words or lines. Pressing Alt instead does word or line
deletion. (The convention we follow is that the Alt key
is a little "more powerful" than the Ctrl key.) "now"
41
Getting Started
What you last deleted is kept in a scrap buffer and
can be pasted back elsewhere. To paste something from
the scrap buffer back into the command line, move the
cursor to where you want it done and press:
Ctrl- Paste one word at a time.
Alt- Paste the whole thing.
Command Completion
In addition to backing up through your previous
commands one at a time with and ,
you can also ask the shell to search back through any
previous commands you've typed for the last command that
either started with or contained the characters in the
previous word.
Ctrl- means "look for a command that started
with ...," and
Alt- (again, a little "stronger") means
"look for a command that contained the
string anywhere." (On Windows 95 and
Windows NT, it's necessary to type
Ctrl-Shift- because Alt-
is grabbed by the system to mean
switch to full-screen.)
Repeatedly pressing these keys cycles up through all
the matching commands you've previously typed. Command
completion uses something called the history mechanism to
recall commands you've previously typed. Later, we'll
devote a whole chapter to some of the more advanced uses
of history.
Filename Completion
Filename completion is another "creature comfort:"
you type just a fragment of a filename and let the shell
fill in the rest. There are three variations: using the
F key for basic filename completion, the D key if you
want all the duplicates listed and the Tab key for
walking one-by-one through the list of matches.
Alt-F or Ctrl-F Filename completion.
Look for a filename that starts with
preceding characters. If it matches a
42
Getting Started
single file, fill in the rest of the
name.
If more than one file matched, show
the part that was the same for all,
highlighted in green. (Bright red
means there were no matches at all.)
Alt-D or Ctrl-D Duplicate completions.
Show any/all matching filenames, one
after the other with spaces between.
Next match.
Show the new match in the list of
filenames that match the wildcard,
replacing the previous match. After
the last match, put the original
string back up, highlighting it in
bright red, then continue cycling
through the list again.
Shift- Previous match.
Same as the key, but rotate
backward through the list of matches.
(Since is normally bound to the filename
completion function, the regular tab character is typed
instead as Ctrl-. If you'd prefer to have the
key be the regular tab character and Ctrl- be
filename completion, invoke the C shell with the -T
option.)
Filename completion is done with wildcarding, pasting
an "*" onto the end of the previous word and then looking
for any matches. Unlike cmd.exe, Hamilton C shell does
any wildcarding before executing the command you type.
It uses a powerful recursive pattern match algorithm that
guarantees sensible matches even if you type a very
complex pattern. Wildcarding is the subject of a whole
chapter up ahead.
The Tour Begins Here
The following chapters introduce the various
facilities Hamilton C shell provides, starting with some
of its basic vocabulary: the simple utilities that come
with it.
43
Getting Started
Following discussion shifts to the intrinsic,
internal functions provided by the shell itself: i/o
redirection, pipes and command substitution; the history
mechanism and wildcarding.
Intermediate level discussion follows, describing
expressions, variables and aliases and the editing and
quoting facilities. The process and thread scheduling
mechanism is described, outlining how an activity can be
placed in the background.
The tour will then cross the threshold from
discussion of individual statements to discussion of
structures of statements. Structures for iteration and
condition-testing and procedural abstraction will be
introduced.
Finally, we'll wrap up with discussion of how to
customize the shell together with a section detailing
specific compatibility issues between the Hamilton and
original Berkeley C shells.
44
Getting Started
45
Utilities
The Utilities
Hamilton C shell comes with a lot of utilities that
form some of its vocabulary. They do small, but oft-
needed functions, often in a novel, faster or more
convenient way than you'd find in "plain vanilla" OS/2 or
NT. This section provides a quick tour, outlining some
of the capabilities and conventions.
ls: List files
ls is a somewhat nicer way to list a directory:
6 D% ls
memos hello.c hello.exe sysstuff
Subdirectories are highlighted (shown here in bold.) If
a file or directory has the system bit set, it's still
listed, displayed in green (shown here in italic.)*
Normally, ls lists everything in lower case for better
readability. In long format:
7 D% ls -l
D---- Feb 23 13:46 - memos
---A- Feb 23 12:56 72 hello.c
---A- Feb 23 12:57 7731 hello.exe
-S-A- Feb 23 13:22 15 sysstuff
Conventionally, ls lists things alphabetically, with
directories ahead of files. There might be hidden files
or directories, but to see them you have to ask:
8 D% ls +H
memos hello.c hello.exe hiding sysstuff
Conventions
To find out how any of the utilities work, just use
the -h option. For example,
9 D% ls -h
* All our examples will be given in terms of the default
screen colors. But these are easily changed to your
own preferences. See the chapter on customization or
the colors.csh script file in the samples directory.
47
Utilities
tells about options for more detailed listings, sorting
the list by date or by size, selecting only certain types
of files, etc. ls is a read-only activity; it never
makes any changes to the file system. Lists are always
sorted in memory; its speed and flexibility completely
obsolete the old (and dangerous) "directory sort"
utilities popular on DOS.
The names of the utilities were chosen to be
consistent with the names of similar functions on UNIX,
where they provided much of the vocabulary of the
original UNIX C shell. But changing the name of a
utility is a simple matter: just rename the
corresponding .exe file or, better still, create an alias
(discussed later.)
By convention, the utilities expect options to come
ahead of any files you specify. Options are case-
sensitive. We've tried to use mnemonic letters for
options (e.g., h for help) and to use the same letter to
mean the same thing across related utilities; achieving
that is simply more feasible with 52, not just 26
characters to choose from.
Our examples generally show options introduced with
"-", but you could equally well follow the DOS-style
convention of using "/" if you prefer. If indeed you
want only "-" or only "/" interpreted as an option
character, this can be set with the SWITCHCHARS
environmental variable, which can be set either from the
C shell or from your config.sys file on OS/2, from the
Control Panel on Windows NT or in your autoexec.bat file
under Windows 95. It won't have any effect on the
standard OS/2 or NT commands like dir or xcopy or on
applications you purchase elsewhere, but it will work on
all the commands supplied with the C shell. For example,
to have only "-" recognized as an option character, you
might type this into the C shell:
10 D% setenv SWITCHCHARS = -
or put this into config.sys (rebooting to make it take
effect):
set SWITCHCHARS=-
You can type options in any order (except where one
overrides another, in which case the last setting is
used) and you group them together or type them separately
as you choose. For example, "ls -L -d -w" is exactly the
same as "ls -dwL" and produces a (-L) long format (very
detailed) list of the current directory, sorted by (-d)
date (newest ones last), with sizes of any directories
filled in by (-w) walking down through the directory
48
Utilities
tree, adding up all the sizes of all the files found
there.
You can always unambiguously end the options with
"--" in case you have a filename or an argument string
that begins with one of option-introducing characters.
Also, since the shell does the wildcard expansion, it's a
bit more convenient and faster for the utilities to look
for any options right at the beginning of what could be a
very long list (up to 64 kilobytes under OS/2; 32
kilobytes under NT) of filenames or other command-line
text.
We'll always follow the OS/2 and NT convention of
using "\" in filenames in this book and we generally
advise that you do too, not so much because the C shell
cares but because so much other OS/2 and NT software
does. To some fair degree, it's a case of "when in Rome,
doing as the Romans do." But if you really do prefer,
you can generally use "/" with the C shell and all the
utilities. Do remember, however, that if you type a
filename starting with "/" to mean the root, you have to
be careful that it can't be confused as the start of an
option. (This is a good use for the "--" option or the
SWITCHCHARS variable.)
echo
echo is a little different than the vanilla OS/2 or
NT echo. It does only one thing: it prints whatever
arguments words you give it; there's no echo on or echo
off-style status reporting function. But it does offer
much finer control over what gets printed: you can write
binary values, choose not to append a new line and write
to stderr instead stdout.
Here's an example where the ANSI escape sequences*
turning brightness on and off are embedded into a string
being echoed. The ANSI escape character is octal 033;
binary values or special characters like "[" are
introduced by the "^" shell escape.
11 D% echo Have a ^033^[1mnice^033^[0m day.
Have a nice day.
Processing of the ^ escape sequences is done by the
shell before any command ever sees it. As a result, you
can use escape sequences to construct command line
* Later in the book, in the discussion of procedures,
you'll learn an even better way of setting colors and
highlighting using the built-in ansi() function.
49
Utilities
arguments for any command; this feature is introduced
here only because it tends to be most often used with
echo.
mv, cp and rm: Move, copy and remove
The mv (move), cp (copy) and rm (remove) trio allows
files and directories to be treated as simple objects.
mv will move either files or directories treating
them simply as objects, even across disk partitions.
In this example, the two hello files are moved into a new
directory, illustrating how mv understands that if
there's a many-to-one relationship, the destination has
to be a directory.
12 D% mv hello* hello
13 D% ls
hello memos sysstuff
14 D% ls hello
hello.c hello.exe
Similarly, cp will copy a file or even an entire
directory. The copies cp produces are always exact
logical copies, with correct timestamps* and attribute
bits and including any hidden or system files.
15 D% cp hello newhello
16 D% ls
hello memos newhello sysstuff
17 D% ls -l hello
---A- Feb 23 12:56 72 hello.c
---A- Feb 23 12:57 7731 hello.exe
18 D% ls -l newhello
---A- Feb 23 12:56 72 hello.c
---A- Feb 23 12:57 7731 hello.exe
cp does not consider it an error to copy over an existing
file unless the file about to be overwritten has its
read-only bit set.
Finally, rm can be used to remove a file or even an
entire directory. But it does insist that you tell it
you really mean it if you ask to remove a directory
that's not empty or anything that's marked with the
system bit.
* Files only under OS/2 1.1. New directories always get
the current timestamp unless you're running OS/2 1.2 or
later.
50
Utilities
19 D% rm sysstuff
rm: Can't remove system file 'systuff' without -S
option.
20 D% rm -S sysstuff
21 D% ls
hello memos newhello
22 D% rm newhello
rm: Can't remove non-empty directory 'newhello'
without -r option.
23 D% rm -r newhello
24 D% ls
hello memos
As you can see from these examples, the general style
of the utilities is fairly terse. Like the proverbial
Vermont farmer, they don't say anything unless they've
got something to say. Even copying or removing a
directory happens without fanfare as long as the
appropriate "yes, I really mean it" options are supplied.
more
more is an especially fast browsing filter. There
are two ways to use more. The first is in a pipeline,
the way "vanilla" more might be used when you suspect the
data may be longer than a screenful:
25 D% ls -l c:\os2\bin | more
:
:
If the output turns out to be less than a screenful, it's
as though you'd just typed the ls command by itself. In
fact, there's not even a noticeable performance penalty.
But if it's more than a screenful, more switches to an
interactive mode where you can use the arrow keys, etc.,
to browse up and down through the listing.
more can also be used for browsing a list of the
files you give it on the command line:
26 D% more *.c
more incorporates the Berkeley notion referred to,
tongue-in-cheek, as "more is less*": it's a good paging
* The story is now a part of computer folk history: at
first, more only went forward. Then someone created a
filter that went backwards, which he aptly named less.
When later versions of Berkeley's more incorporated
this feature, they were heralded by announcements that,
finally, "more was less."
51
Utilities
filter that lets you go forwards and backwards. It also
offers a number of different ways of looking at or
searching the data including binary, as control
characters, line-numbered, etc. Perhaps most important,
it's fast.
Part of more's speed comes from an internal cache
coupled to an indexing structure that it builds on the
fly as it reads the input. When you move forward or
backward within the cache, screen redraw rates are the
limiting factor in performance. Outside of range of the
cache, if the input is from a disk file, the indexing
structure, technically an ISAM, tells more how to seek to
the new location.
Under Windows NT or Windows 95, there's only one
version of more and its cache is sized dynamically
depending on whether the input is from a file or a pipe.
When reading a file, it uses a cache about 100K
characters; otherwise, the cache is about 4M characters.
Under OS/2, there is also a small, but faster version
that uses a cache of about 11K characters.
touch
touch lets you change the timestamps of individual
files or directories* or, using the -r (recursive)
option, of everything in a whole directory tree.
If the desired timestamp isn't given, touch uses the
current time. If the filename doesn't exist, it's
created as a zero-length file.
27 D% ls
hello memos
28 D% touch zork
29 D% ls
hello memos zork
chmod
chmod lets you set a file's attributes but leaves the
timestamp alone. Here is an example, first setting the
* On an OS/2 1.1 system or under Windows 95, the kernel
allows you to change the timestamps only on files, not
directories. touch'ing a directory does nothing unless
you use the -r option to recursively touch the
directory's contents.
52
Utilities
system bit (making it show up in green), then making it
hidden:
30 D% chmod +S zork
31 D% ls
hello memos zork
32 D% chmod +H zork
33 D% ls
hello memos
Of course, the file is still there and you can continue
to manipulate its attributes:
34 D% ls -l zork
-SHA- Feb 23 13:16 0 zork
35 D% ls +a
. hello zork
.. memos
36 D% chmod +R zork
37 D% ls -l zork
-SHAR Feb 23 13:16 0 zork
Many users will find that a file's system bit is more
useful than they'd thought before. With chmod, it's easy
to set or clear the bit and setting it doesn't make the
file hidden. Quite the contrary, ls makes it stands out
in green. Also, a file marked "system" is a little safer
from accidental deletion or overwriting. These are often
convenient characteristics to attach a few specific files
within a large directory. For example, the author tends
to routinely mark make files within a C source code
directory as "system" just so they'll stand out.
du, vol and pwd
du, vol and pwd provide quick snapshots of your disk
partitions: du tells how much of the partition is used;
vol displays the label; and pwd shows the current
directory on each partition.
38 D% du
c: 31.904 M Total = 29.465 M Used + 2.439 M ( 7.65%)
Free root
d: 23.920 M Total = 22.438 M Used + 1.482 M ( 6.20%)
Free user
e: 13.957 M Total = 8.520 M Used + 5.438 M (38.96%)
Free misc
39 D% pwd
c:\os2\include
d:\doug\sh\docs
e:\tmp
40 D% vol
53
Utilities
c: Jan 24 22:32:10 1988 root
d: Nov 27 20:34:58 1988 user
e: Jan 17 17:12:20 1988 misc
A common convention observed by the utilities is that
if one entry on a list is more current or special than
the others, it's highlighted. du, vol and pwd each
highlight the entry describing the current disk.
For the benefit of those who have lots of partitions,
some of which they don't want to bother listing all the
time, du, vol and pwd look for a DRIVEMASK environmental
variable which can be used to mask off just the drive you
want. This is especially useful for excluding drives
that take removable media; if they're empty, they can
waste a lot of time trying to read a diskette that's not
there.
dirs, pushd, popd and rotd
The shell provides a built-in mechanism for keeping
several directories "handy." This mechanism is the
directory stack, which always contains a list of fully-
qualified directory pathnames with the current directory
at the top. You can display the list with the dirs
command:
41 D% dirs
d:\doug\sh\docs
Initially the list contains only your current
directory. When you push a new directory on the stack
with pushd, that becomes your new current disk and
current directory. pushd also reports the resulting
stack contents.
42 D% pushd c:
c:\os2\include
d:\doug\sh\docs
43 C% pushd e:
e:\tmp
c:\os2\include
d:\doug\sh\docs
Calling pushd without any arguments just swaps the
top two directories:
44 E% pushd
c:\os2\include
e:\tmp
d:\doug\sh\docs
54
Utilities
Popping elements off the stack is done with popd,
which also reports the resulting stack.
45 C% popd
e:\tmp
d:\doug\sh\docs
The stack can also be rotated with rotd. (We'll push
another directory first so we can see that rotation is
upward, with the top item going to the bottom of the
stack.)
46 E% pushd \
e:\
e:\tmp
d:\doug\sh\docs
47 E% rotd
e:\tmp
d:\doug\sh\docs
e:\
You can pop multiple directory entries at once, but
if you ask to pop more than exist, you'll get a message:
48 E% popd 5
csh: The built-in popd command can only accept a
integer argument n, where n > 0 && n < number of
elements on the directory stack. The default for n
is 1.
49 E% popd
d:\doug\sh\docs
e:\
fgrep and grep
fgrep and grep are fast string search utilities.
Their names and the regular expression syntax are
traditional; it's an accepted standard and we've followed
it.
fgrep and grep are used to scan through long lists
of files or filter data coming through a pipe for strings
or patterns you specify. They'll quickly report all the
matching lines. If you like, you can get more or less
detail in the output, e.g., have line numbers shown or
just get a total count of all the matches.
fgrep and grep both have the ability to look for a
large number of patterns in parallel (using the -s or -f
options) with almost no discernible performance
degradation. They're very fast. Both precompile and
optimize their search patterns, use direct kernel API
55
Utilities
calls for all i/o and use a very high performance
buffering structure to allow extremely fast scanning of
large amounts of data.
fgrep
fgrep is the simpler and slightly faster of the two
search utilities. It does a simple string compare
between the string you're looking for and the characters
on each line. If the search string is found anywhere on
the line, it's a match. There are some options for
ignoring differences in upper-/lower-case or in the
amount of white space (spaces and tabs) between words but
mostly it's quite simple comparison.
Here's an example of using fgrep to search a very
simple personal phone directory where each record is just
a line of text and we'll search it . (Later we'll learn
how to package things like this up into aliases or shell
procedures so you can call them with just a few
keystrokes.)
50 D% fgrep -i doctor \phone
Doctor James Gardner 508-999-0000 12 Canton St
Doctor Karen Strickland 508-721-1223 N.E. Medical
Offices
grep
grep looks for special patterns called regular
expressions, which are similar to (but slightly different
from) filename wildcarding. The grammar is recursive,
meaning a regular expression to be matched can be
written, in turn, as a nested series of regular
expressions in decreasing precedence:
c Any ordinary character matches itself.
\c Match the literal character c. Certain
characters are treated specially:
\a Audible Alert (Bell)
\b Backspace
\f Form Feed
\n NewLine
\r Carriage Return
\t Tab
\v Vertical Tab
\\ Single BackSlash
\x The next one or two digits are treated
as hex digits specifying the character
code.
56
Utilities
^ Beginning of line.
$ End of line.
. Match any single character.
[...] Match any single character in the list.
[^...] Match any single character not in the list.
\n Match whatever literal text the n'th tagged
\(...\) expression matched.
r* Match zero or more occurrences of r.
r\{n\} Match exactly n occurrences of r, where n is
an unsigned decimal integer.
r\{n,\} Match at least n occurrences of r.
r\{n,m\} Match at least n, but not more than m
occurrences of r.
r\{,m\} Match at most m occurrences of r.
r1r2 Match expression r1 followed by r2.
\(r\) Tagged regular expression. Match the pattern
inside the \(...\), and remember the literal
text that matched.
At the lowest layer, you give a character or set of
characters to be matched anchored, if you want, to match
just the beginning or just the end of a line. At the
next layer, the "*" character lets you match a variable
number of repetitions of a pattern.
When you type a regular expression on the command
line, keep in mind: (1) Many of the characters have
special meaning to the C shell and have to be inside
quotes. (2) You have to type two "^'s" to get just one
because "^" is the shell's literal escape character. (3)
"*" is a postfix operator. It operates on the preceding
regular expression; by itself, it is not a "match zero or
more characters" wildcard character as you may be used to
with filenames.
Here's an example of searching through all the source
code for a large application, looking for all occurrences
of lines that begin with "statement" followed by a "y"
somewhere on the line and showing the line numbers of any
matches. (The -s option tells pushd and popd to work
silently.)
51 D% pushd -s ~\sh
52 D% grep -n '^^statement.*y' *.c
allocate.c:418:statement_obj
*allocate_statement(size, type)
53 D% popd -s
sed
sed is a stream editor. Just as you might think of
using a regular editor to edit a file, deleting or
inserting lines, doing search/replace operations, etc.,
57
Utilities
sed lets you edit a stream of data: individual lines are
read from stdin, edited according to the script you give
and written to stdout. A very simple sort of script
might be given right on the command line. Here's a
simple search/replace:
54 D% echo hello world | sed s/world/everybody/
hello everybody
sed uses the same regular expressions used by grep.
It's possible to pick up pieces of the input as tagged
expressions and move them around. In this example, the
two strings on either side of the space are tagged, then
swapped around. Quotes are used around the
search/replace command so the C shell will treat it as
one long literal string to be passed to sed.
(Parentheses, spaces and asterisks otherwise have special
meaning.) Notice how the "*" construct, meaning match
zero or more occurrences actually matches as many
repetitions as possible.
55 D% echo hello world | sed 's/\(.*\) \(.*\)/\2
\1/'
world hello
For more complex operations, sed offers a wide array
of operators including even conditional branches and a
hold buffer where a string can be saved temporarily from
one line to the next. If your script is very long, the
-f option lets you specify it in a file.
diff
diff is an extremely fast and flexible utility for
quickly comparing ASCII files, looking for differences.
In the simplest form, you simply give it two filenames
corresponding to the old and new versions and let it go
to work, reporting sections that have been deleted or
added in a traditional format. For example, a software
developer might use it to compare old and new versions of
a C program:
56 D% diff archive\parse.c parse.c
1493 c 1493
< d->inline_cnt = src->inline_cnt++;
---
> d->inline_cnt = ++src->inline_cnt;
Each change is reported in terms of the line number or
range in the old version, whether it's an addition,
change or deletion, the line numbers in the new version
58
Utilities
and then the affected lines from each file, separated by
a line of "---".
diff supports the traditional options for ignoring
differences in upper-/lower-case or in the amount of
white space on the line, for recursively comparing entire
directory trees of files, etc.
One of diff's most novel features is its ability with
the -! option to generate a merged listing where text
that's deleted is shown in red, new text is shown in
green and the rest is displayed normally. This makes it
extremely easy to view your changes in context. (To use
this option, remember that "!" is a special character to
the shell; type it at the end of the option list so
there'll be a space following.)
head and tail
head and tail are used to display just the first or
last few lines or characters of a file. Normally, they
expand any tabs into spaces so you don't need to filter
them through more.
tail is particularly interesting. If all you want is
the end of a very large file, tail doesn't waste time
reading the whole file from start to finish. Instead, it
jumps right to the end and reads it backwards! If the
file is truly large (on the order of several megabytes)
and all you want is a little bit off the end, this is the
difference between chugging along for several seconds
versus getting an almost instantaneous response.
tail also has a -f follow option. What that means is
that when it gets to the end of file, it enters an
endless loop, sleeping for a second, then waking up to
see if more has been added. This is particularly useful
if, e.g., you have an operation, say a large make, active
in one window with its output redirected to a file. From
another window you can periodically check in on the
progress by typing:
57 D% tail -f e:\tmp\make.log
:
^C
tail lets you watch lines get added without consuming
much processor resource (since it sleeps in the kernel
most of the time) so you can watch a background activity
progress without affecting its performance. After you've
watched for a while, just type Ctrl-C to interrupt and
get out. The interrupt only goes to the tail program;
59
Utilities
the application off in the background or in another
window creating the file is not affected and will go on
about its business until you come back once again to
check on it.
cut
cut is a simple filter for selecting out just certain
fields or character positions of each line of input. You
choose what characters should be interpreted as the field
delimiters and which fields should be copied to the
output. For example, if you kept your phone book in
\phone, you might strip off just the first word from each
line to get everyone's first names:
58 D% cut -f1 -d' ' \phone
Ed
Helen
Jack
Vickie
:
The -f option means you want to count by fields,
selecting the first field and that the delimiter is a
space character. (Notice the quotes around the space.)
split
split lets you break up a large file into smaller,
fixed-size pieces counting either by lines or by
characters. Each of the smaller files it creates are
numbered, e.g., chunk.001, chunk.002, chunk.003, etc.
One example of where you might use split might be if
you had a very large file you wanted to transmit over a
modem. If the line dropped suddenly, you wouldn't want
to have to start all over on a 2M file. If you split it
first into 200K chunks, you'd stand to lose a lot less.
Another example might be if you had a truly enormous text
file that was just too big to easily edit with your
favorite editor. Splitting it up into chunks of only 10K
lines each might be a solution.
tabs
tabs lets you expand or unexpand tab characters based
on a set of tab settings you give it. Tab settings are
religious. I like them every 3 spaces but you probably
60
Utilities
like something else. If you're composing something to be
sent as email or posted on a bulletin board, it's
probably nice to expand it out before you send it so
everyone sees what you see.
tr
tr is a another simple filter for translating
characters from input to output. For example, you could
translate everything from lower to upper case by typing:
59 D% tr a-z A-Z
hello world
HELLO WORLD
^Z
We typed the first hello world and tr has just echoed it
in upper case. ^Z is the end-of-file character defined
by OS/2 and NT.
tr also has a number of options for squeezing out
repeated sequences of the same character or editing out
just certain characters and even for normalizing the text
in a file, ensuring that every line ends with a carriage
return/line feed combination. That's handy if you're
importing a file from another operating system.
strings
strings lets you simply list out all the ASCII
strings in an otherwise binary file. Sometimes this can
be useful for spelunking around through a file when
you're really not sure at all just what's inside it.
Various options are available to trimming the output so
only strings of a minimum length, etc., will be shown.
For example,
60 D% strings hello.exe
!This program cannot be run in DOS mode.
:
Hello, world
:
Another example might be if you suspected an
application was carrying a virus. Naturally, strings
can't guarantee something's free of any virus, but on the
other hand, if you scan it with strings and find
something like this, obviously you should be careful:
61
Utilities
61 D% strings a:suspect.exe
:
Aha! Gotcha! I just blew away your hard disk!
dskread and dskwrite
This pair of utilities can be used to quickly copy,
format or mass duplicate diskettes in a single pass.
Here's an example using dskread to read a whole diskette
image onto your hard disk and then write it back out onto
a new floppy with dskwrite. The dskwrite -a option means
autoformat, i.e., if the new disk isn't already
formatted, format each track as it's written. The -v
option means read back and verify each write to be sure a
good copy was made.
62 D% dskread a: >disk.image # Read the whole
diskette
63 D% dskwrite -av a: g:big.zip
Other Utilities
Other utilities provide means for sleeping for a
timed period, counting the number of words in a file and
so on. Part of the appeal of Hamilton C shell is that
it's relatively easy to continue expanding the vocabulary
with simple utilities that may each be only a few hundred
lines long.
This has been a fast introduction. Fortunately, you
don't have to learn the utilities just from the book.
All have on-line information available with -h. We
encourage you to experiment.
As this is being written, we're still giving thought
to additional utilities. If you have favorites you'd
like to see included or maybe offered as new products,
please contact us.
63
TAR and MT
The TAR and MT Utilities
The tar utility can be used to read and write tar
format files, tapes and diskettes. The mt utility lets
you check the status of a tape drive, rewind or erase a
tape, set various features, etc. Because the use of tar
and mt to read or tapes is so important to so many users,
particularly for interchange with UNIX machines, it
deserves a chapter of their own.
Most QIC (quarter-inch cartridge), 4mm DAT and 8mm
Exabyte drives are supported by Windows NT and will work
just fine with tar.
But note: tape device support is included only with
Windows NT, not Windows 95 or OS/2. If you would like to
read/write tar tapes, you must be running Windows NT.
Choosing a Suitable Tape Drive
If you don't yet own a tape drive and you're trying
to choose the one that might be best for your own
application, your first consideration should be the types
of drives on any machines with which you want to exchange
data. If your colleague's machine has a QIC and you buy
a DAT, this is not going to work!
If you have a choice, we generally recommend 4mm DAT
drives. A single $10 DAT tape cartridge, weighing only
1.4 ounces, can store 2 gigabytes or more -- no other
tape format comes close in terms of cost per megabyte or
weight per megabyte for media. If you have to store
large amounts of data or if you're concerned about
shipping costs, DAT drives win hands down. Also, under
release 3.5 and later builds of Windows NT, DAT drives
are better-supported than any other type of drive. For
example, on a DAT drive, you'll have more flexibility in
the choice of a blocksize (which could be important if
someone else is sending you tapes and you have little
control over how they're written). Also, DAT drives
allow rewriting of the last block on the tape; that's
useful with tar because it means you can add files onto
the end of a tar tape on DAT; with other types of drives,
you may have to just rewrite the whole tape to add even
one file.
That said, both QIC and Exabyte drives do work quite
well. QIC drives using DC-6525, DC-300, DC-600 and
65
TAR and MT
similar full-size, quarter-inch, streaming cartridges are
based on technology that's been popular on engineering
workstations for close to twenty years; they're very
reliable. Exabyte 8mm drives are also quite good, but if
you have an older Exabyte that just refuses to work, you
may need a firmware upgrade from Exabyte.
The only drives we do not recommend are the so-called
"floppy tapes" -- those using DC2120 and similar
minicartridges. Floppy tapes do not seem to work at all
with Windows NT; no one we've talked to has ever been
successful. On the other hand, even if they were better
supported under NT, you still wouldn't want one. The
technology is inherently unreliable, using a timing track
that must be preformatted onto the tape to indicate where
"sectors" are to be written. Floppy tapes are notorious
for not being able to read their timing tracks, meaning
any data is lost.
Rewinding a Tape
Tar normally rewinds the tape before and after
reading or writing it. You can suppress that with the -N
(no rewind) option. You can also manually rewind the
tape using the mt utility:
66 D% mt rewind
Listing the Contents of a TAR Tape
To list the contents of a tape using the -L (Long
Listing) option so you can see in detail what's there:
67 D% tar -L \\.\tape0
The tape device is \\.\tape0 under Windows NT. That
name was chosen by Microsoft. If you have more than one
tape, the others will be called \\.\tape1, \\.\tape2,
etc.
When reading a tape, tar will automatically recognize
either tar or cpio formats (including both ASCII and
binary versions of cpio) and will automatically do
whatever "byte-flipping" is required if the tape was
written on machine with a different bytesex. (More about
bytesex later.) Also, tar will do its best to determine
what blocksize used even if you don't tell it. Under
Windows NT 3.5, the blocksize does have to be a multiple
of 512 bytes to be readable; tar will iterate through all
the possibilities until it finds the right one. Under
66
TAR and MT
Windows NT 3.51 or later, if your tape drive supports
"variable block i/o," tar can directly determine the
blocksize just by reading the first record on the tape.
For a little more diagnostic information from tar,
you can use the -v (verbose) option instead of -L.
You'll get some additional information about what format
(tar versus cpio), bytesex and blocksize tar is using and
the offsets from the beginning of the archive at which
each file in the archive appears.
Extracting the contents of a TAR tape
If you can list the contents of a tar tape, you can
extract it. Do this using the same procedure you used to
list the contents of the tape, but adding the -x
(Extract) option.
68 D% tar -Lx \\.\tape0
By default, tar will extract everything on the tape
into the current directory. If all you want is just a
particular file, you can specify it on the command line.
Wildcards can also be used. But remember that the C
shell normally expands wildcards before it starts up the
application you've asked for. To make sure that any
wildcards get passed through to tar so it can do the
pattern matching, put single or double quotes around each
word that contains any wildcards. For example, to
extract all the *.c files:
69 D% tar -Lx \\.\tape0 "*.c"
What to do if You Can't Read a Tape
Most users will never have any trouble at all reading
any tape they're ever given. But if you do encounter
difficulty, it's likely because of one of the following
reasons:
1.
You don't have the tape device driver installed.
You should see a message from tar complaining that it
wasn't able to open \\.\tape0. The solution is
simple: open up the Windows NT Setup applet in Group
Main, pull down Options, select "Add/Remove Tape
Devices..." and add the driver you need.
2.
The tape itself is just not compatible with your
drive. Every tape drive technology is constantly
being improved. New generation drives can usually
67
TAR and MT
read tapes written on the older drives, but because
the newer drives typically use newer, higher-density
media and more sophisticated recording formats, that
compatibility can be one-way only.
Examples are trying to read a DDS-2 DAT tape on a
DDS-1 drive or a DC-6525 (525MB) QIC tape on a drive
that only accepts DC-600's or an Exabyte 8500 tape on
an Exabyte 8200 drive. In each case, you just won't
be able to read anything. The tape will appear to be
blank. And because a blank tape is a perfectly
legal, albeit empty archive, you won't even see any
messages. Just nothing. That's what makes this
failure mode frustrating.
Often, it is possible to force the drive to write in
an older, lower-density format. With QIC and DAT
drives, it's as simple as just being sure to use low-
density media. With an Exabyte, the solution is to
set a jumper on the drive to configure it to act like
the older models.
3.
The blocksize that was used is not supported with
your drive under the release of Windows NT you're
running.
For example, to pack the absolute greatest possible
amount of data onto a tape, some UNIX machines
support writing tapes with incredibly large
blocksizes, sometimes 200KB or more. This is often a
problem trying to read tapes from SGI workstations.
Very few if any Windows NT machines support
blocksizes that large.
Another example would be tape that was written with a
blocksize that's not a multiple of 512 bytes. That's
no problem if you're running Windows NT 3.51 or
later, but it's not supported by the device drivers
that Microsoft shipped with Windows NT 3.5; you'll
need to upgrade the operating system to read that
tape.
Finally, while the blocksize might indeed be a
multiple of 512, it might not be a multiple that's
supported by your drive. For example, QIC drives
often will support only a limited set of blocksizes.
If it's a problem with the blocksize, you should
generally get a message from tar that makes that
clear. The solution is to ask that the tape be
rewritten using a blocksize you can read; some good
choices might be 10,240 bytes (the POSIX standard),
1024 bytes (which everything can read and write) or
the drive's default, which you can learn by typing
68
TAR and MT
"mt status". To rewrite the tape on the UNIX machine
with a 10,240-byte blocksize, the UNIX "tar -b"
(blocking factor) option should be used to specify a
blocking factor of 20. (On UNIX, you multiply the
blocking factor times 512 to get the number of bytes
per block.)
4.
You need a firmware update for your tape drive. This
is a particularly likely source of trouble if you've
scavenged your drive from an older system. All tape
drives today are microprocessor-controlled and the
manufacturers have made a lot changes to the firmware
embedded in these drives over the years. Windows NT
depends on that firmware being up-to-date so it can
properly handshake with the drive.
Updating the firmware is generally quite simple.
Usually, you put a special update tape from the
manufacturer in the drive and the drive will
automatically recognize it and do the update.
Contact your drive vendor for more information if you
suspect a firmware problem.
5.
Your drive has a firmware bug. Some drives may claim
to support variable block i/o but not actually
implement it properly. If the drive claims to
support this mode, tar will use it because it allows
tapes be read quickly and easily even if the
blocksize is unknown. But if the drive has a
firmware bug, the tape may look blank in this mode.
The workaround is to use tar's -V option to tell tar
to ignore the drive's claims of supporting variable
block i/o.
If you find that none of these explanations seems to
fit the problems you're having, it's time to try writing
a scratch tape just to see if your drive can at least
read its own tapes.
Writing a New TAR Tape
To create a new tape with one or more files or
directories in the archive, use the -c (create) option:
70 D% tar -Lc \\.\tape0 file1 file2 file3 ... filen
You can list as many files or directories on the line
as you like. All the usual wildcards can be used and
since it's okay to let the C shell do the wildcard
expansion, you don't need to put quotes around anything.
If one of the items is a directory, the entire contents
of that directory will be copied to the tape.
69
TAR and MT
By default, tar will try use a blocksize of 10,240
bytes, which is generally considered standard on most
UNIX machines. (It's actually specified in the POSIX
standard for tar-format tapes.) If your drive doesn't
support that blocksize, tar will choose something that is
supported.
Adding More Files to an Existing TAR Tape
To add one or more files or directories to an
existing archive, use the -a (append) option:
71 D% tar -La \\.\tape0 file1 file2 file3 ... filen
Not all drives support this function since it
requires that tar be able to read the entire archive,
then back up to overwrite just the last record before
continuing with the new files. If you get a message from
tar telling you it wasn't able to write to archive when
you use -a, that's probably the reason. In that case,
you'll have to use the -c option instead and just plan on
writing everything you want on the tape in a single
operation.
Check That You Can Read the Tape You Just Wrote!
After writing a tape, do be sure to check that you
can read it back. This is just a safety precaution the
first time you try using your drive or a new setting for
blocksize, etc.
Exchanging Tapes with a UNIX System
If the UNIX machine can read the data from your tape,
but it comes out garbled, the problem is probably that
you've written the data in the wrong bytesex for that
machine. Bytesex refers to the order in which the bytes
are laid out on the tape. A little-endian machine (which
is what all Windows NT machines are by edict from
Microsoft) writes the data out starting with the byte
containing the least significant bits (the "little" end).
Many UNIX machines are big-endian, meaning they start at
the other end.
Reading a tape from any UNIX machine, regardless of
bytesex, is no problem since Hamilton tar knows how to
detect the bytesex and automatically do any byteswapping
that might be required. UNIX tar utilities lack this
70
TAR and MT
feature and leave it up to the operator to figure out
what's going on and, if necessary, to use a separate "dd'
utility to swap bytes.
You can verify that this is the problem if you have a
tape written on the UNIX machine. Read it using the -v
(verbose) option and tar will tell you what bytesex was
used.
This is easy to fix. Use the tar -b (bytesex) option
to specify a different ordering when you write the tape
next time. Here's an example, writing all the .c and .h
files in the current directory to a tape in big-endian
format:
72 D% tar -LcbB \\.\tape0 *.[ch]
If the tape is simply unreadable or appears blank on
the UNIX machine, chances are they have an older drive
that does not support compression. (Since most NT
machines are fairly new, the drives installed in most of
them use hardware compression to pack more data onto a
tape. But this is a recent improvement in tape
technology; an older UNIX machine may have been built
before hardware compression was available.) To write
tapes with hardware compression turned off, use the -Hoff
option:
73 D% tar -LcHoff \\.\tape0 *.[ch]
ASCII Text versus Binary Files
One final consideration is that UNIX and NT differ on
their line-end conventions. UNIX uses a single newline
(\n) character to mark the end of a line; NT uses a
carriage return-newline (\r\n) combination. Hamilton tar
assumes that because tar is fundamentally a UNIX format,
that any ASCII files stored in a tar file will probably
follow the UNIX convention. Consequently, when
extracting an ASCII text file, tar will convert from \n
to \r\n; when adding a file to the archive, it will do
the reverse. Binary files are not converted.
You can override this default behavior by specifying
either -r to turn off any conversions. The -R option
causes conversions to always be done, even on files that
appear to be binary. You can also use the TARBINARY and
TARASCII environment variables to list files that should
be considered as being one type versus the other based on
the filename, regardless of content. For example,
database products often create files with a lot of ASCII
data but which really should be considered as binary.
71
TAR and MT
Postscript files with encapsulated images are another
example. These files should never translated as if they
were ordinary ASCII files. You can indicate that by
setting the TARBINARY environment variable. For example,
in the System applet in the Control Panel, you might set
TARBINARY = *.ps to make it treat all Postscript files as
binary data.
72
I/O Redirection
I/O Redirection and Piping
I/O Redirection
You can redirect or pipe i/o in much the way you
might under cmd.exe. Here's a simple example redirecting
stdout from the word count of the famous "Hello, world"
program. cat just copies from any files you tell it or,
by default, from stdin to stdout.
74 E% cd hello
75 D% ls
hello.c hello.exe
76 D% cat hello.c
#include
main ()
{
printf("Hello, world.\n");
}
77 D% wc hello.c >hello.wc
78 D% cat " exists, it's first
truncated to zero length (discarding the old contents);
if the file doesn't exist, it's created. With "<", it's
an error if the file doesn't exist.
Data can be appended to a file with the ">>"
operator:
79 D% echo that^'s all folks >>hello.wc
80 D% cat hello.wc
5 8 72 hello.c
that's all folks
81 D% _
When you append with ">>", if the file exists, data is
written onto the end; if it doesn't exist, it's created.
(The single quote character has special meaning to the
shell on the command line; the special meaning is turned
off by the shell's escape character,"^".)
73
I/O Redirection
noclobber
Not everyone is comfortable with letting the shell
glibly toss away an existing file if you type ">" when
you meant ">>" or lose it somewhere if you mistype an
existing filename with ">>". The noclobber variable lets
you tell the shell you want this to be caught, so you can
decide if this was really what you meant.
If you set noclobber, you have to type ">!" to
redirect to an existing file:
81 D% set noclobber = 1
82 D% echo trash this file > hello.c
csh: Couldn't open 'hello.c' as a redirected
standard output.
Come to think of it, let's not overwrite that file.
Similarly if you want to append to something that
doesn't already exist:
83 D% echo appended data >> newdata
csh: Couldn't open 'newdata' as a redirected
standard output.
84 D% echo appended data >>! newdata
85 D% cat newdata
appended data
86 D% rm newdata
Protection Attributes
If a file has any of the special protection
attributes, hidden, read-only or system, set, you cannot
overwrite it by redirecting i/o to it. Even when you
type "!", you still can't. Before you can redirect to
it, you must clear all these attribute bits.
87 D% ls -l zork
-SHAR Feb 23 13:16 0 zork
88 D% echo new zork data >! zork
csh: Couldn't open 'zork' as a redirected standard
output.
89 D% chmod -R zork
90 D% echo new zork data >! zork
csh: Couldn't open 'zork' as a redirected standard
output.
91 D% chmod -SH zork
92 D% ls -l zork
---A- Feb 23 13:16 0 zork
93 D% echo new zork data > zork
94 D% _
74
I/O Redirection
Stdout and Stderr
Redirecting both stdout and stderr together is done
by adding an ampersand. For example, using echo's "-2"
option to deliberately write to stderr and parentheses
for a simple grouping:
94 D% (echo -2 error; echo standard) > zork
error
95 D% cat zork
standard
96 D% (echo -2 error; echo standard) >& zork
97 D% cat zork
error
standard
98 D% _
Separately redirecting stderr and stdout to different
files is a little tricky: first you redirect them both,
then redirect stdout by itself. Here's an example
running the C compiler with stdout to log and stderr
going to errors.
98 D% cl hello.c >& errors > log
You can type as many i/o redirections in a row as you
like. The shell evaluates them one after another. If
you redirect to a new file, then redirect to something
else, the effect is just like touch'ing the file.
Pipes
Pipes are a way of connecting a series of activities
together so that the output of one is read as input to
the next. Each of the activities runs asynchronously and
concurrently with the others. Data is passed completely
in memory and is very fast.
The syntax is similar to i/o redirection in its use
of the "&" character. To pipe just stdout, use "|" by
itself:
99 D% ls -L | more
To pipe both stdout and stderr together, use "|&":
100 D% cl hello\hello.c |& more
The leftmost part of the pipeline is evaluated
directly by the shell's current thread. The successive
right parts are evaluated by child threads. (This is so
that piping a command that lists status information on
75
I/O Redirection
the current thread through a filter like more operates
sensibly.) Each part of the pipeline can be an
arbitrarily complex statement, perhaps even run as a
separate OS/2 screen group or in a separate NT window.
Pipes are much faster and more responsive than with
vanilla OS/2 or NT due to improved buffering and
scheduling technology. A long pipeline finishes much
faster. Also, when you type ^C to interrupt, it comes
back immediately without a lot of nuisance messages.
Command Substitution
A particularly novel way of piping statements
together is to use the output of one as command line
arguments of another. This is called command
substitution and you indicate it by typing backquotes,
`...`, around a command.
101 D% ls +a
. hello zork
.. memos
102 D% echo `ls +a`
. hello zork .. memos
103 D% _
When command substitution is done, all the extra
"white space" (space characters, tabs and newlines) is
squeezed out. Also, any ANSI escape sequences that might
have turned on highlighting or color, etc., are deleted.
You just get the list of words the backquoted command
wrote to stdout. In this example, the order of the files
is a bit scrambled when the line ends are removed; the -1
(numeric one) single column option can fix this. (Try it
again using ls +a1 inside the backquotes.)
Command substitution is especially useful anywhere
you need to give a list of filenames as arguments to a
command. Here's an example using ls to give a detailed
listing of itself:
103 D% whereis ls
c:\hamilton\bin\ls.exe
104 D% ls -l `whereis ls`
---A-- Mar 13 17:00 57344
c:\hamilton\bin\ls.exe
If there are any variable substitutions inside the
backquotes, they're done by the child, not the parent.
This lets you easily embed for loops and other
programming constructs into the command substitution.
76
I/O Redirection
Inside backquotes, only the backquote character needs
to be escaped to avoid having it processed by the parent
thread.
Inline Data
A novel variation on i/o redirection is inline data,
also called "here" documents: literal text you want the
shell to feed a command as stdin. Here's an example:
105 D% cat <, <, (, ), &&, ||, >> or <<,
occurs. Only inline data escapes being broken up into
words this way. Each command may be thought of as an
array of words, indexed from 0.*
To reuse the text or maybe just a few words from a
previous command, you type an exclamation point, "!",
followed by a few characters to identify what you want to
reuse. You can do this anywhere and whatever you select
is just stuffed back on the command line to be
interpreted as whatever the context suggests. For
convenience, the exclamation point is not treated as a
history reference if it's followed by white space (a
space, tab or newline) or by "=", "~" or "(".
* Array indices always start with zero.
81
History
Retrieving a Whole Command Line
There several ways of picking up a whole command
line. You already know how to do it interactively with
arrow keys and command completion. You can also use a
shorthand notation that can be more convenient if you
want to do something a bit more complex. The simplest
shorthand is "!!", which picks up the text of the
immediately preceding command:
128 D% echo !!
echo history 12
history 12
129 D% !!
echo history 12
history 12
130 D% _
The shell first echoes your command showing the effects
of the substitutions and then runs it. The other quick
ways of referring to a whole command line from history
are by the command number,
130 D% !104
ls -l whereis ls`
---A-- Mar 13 17:00 57344
c:\hamilton\bin\ls.exe
relative to the immediately preceding command*,
131 D% echo one
one
132 D% echo two
two
133 D% echo three
three
134 D% !-1
echo two
two
135 D% _
or by mentioning some of the text to look for. A
question mark after the exclamation point means you'll
accept the match anywhere on the line; otherwise it has
to be at the start.
* In this context, the history list can be thought of as
an array starting with the zeroth element being the
immediately preceding command line. The negative index
captures the notion of counting backwards in time and
differentiates the syntax from references by command
number. See also the bsdhistory variable.
82
History
135 D% !h
history 12
124 The ^$home directory is $home.
125 Today's date is `date`.
126 ***
127 history 12
128 echo history 12
129 echo history 12
130 ls -l `whereis ls`
131 echo one
132 echo two
133 echo three
134 echo two
135 history 12
A search string ends at the first word boundary. This is
so it's convenient to type additional text following
without having it be confused as part of the search
string. For example:
136 D% !?one;!?two;!?thr
echo one ; echo two ; echo three
one
two
three
137 D% _
Retrieving Individual Words
To pick off individual words of the immediately
preceding command, there's some convenient shorthand.
"!*" gets all the argument words:
137 D% echo now is the time
now is the time
138 D% echo Finally, !* to begin
echo Finally, now is the time to begin
Finally, now is the time to begin
139 D% _
"!$" gets just the last word:
139 D% echo the last word was !$.
echo the last word was begin.
the last word was begin.
140 D% _
and "!^" gets just the first argument word:
140 D% echo ===!^=== time is here
echo ===the=== time is here
83
History
===the=== time is here
141 D% _
Notice that a history substitution can be smashed right
up against other literal text.
In the chapter on editing, additional facilities for
selecting individual words or doing a search/replace will
be introduced.
History Short-Form
Recognizing how frequently one would like to make a
simple change to the immediately preceding command to
correct a typo, the history mechanism provides a short
form for just that purpose. "%" typed as the first
character on the command line indicates that a
search/replace pair follows:
141 D% echo hello world
hello world
142 D% %world%friends%
echo hello friends
hello friends
Typing "%%" matches the beginning of the line:
143 D% %%echo %
echo echo hello friends
echo hello friends
It's also possible to refer to the search string in
the replacement string by using an ampersand. (This
example also illustrates that the trailing "%" isn't
required unless you want to explicitly mark the end of
the replacement.)
144 D% %friends%family, & and neighbors
echo echo hello family, friends and neighbors
echo hello family, friends and neighbors
145 D% _
Obviously, that raises the question: how do you put
a literal ampersand in the replacement? Simple. Just
quote it with "^", the shell escape character.
145 D% %and%^&
echo hello family, friends & neighbors
hello family, friends & neighbors
146 D% _
84
Variables
Variables
As with any conventional programming language, the
shell provides a facility for storing values in
variables.
Environmental Variables
Some of the variables are part of the environment,
passed along to any child process or screen group. Many
of the environment variables will have been created just
this way, e.g., set to a value passed along when you
start the C shell from the Program Manager on Windows NT
or the Workplace Shell on OS/2. To list those currently
defined, use the setenv command.
146 D% setenv
COMSPEC d:\winnt\system32\cmd.exe
COLORS white on blue
HOME d:\doug
INCLUDE d:\doug\include;d:\msdev\include
LIB d:\doug\lib;d:\msdev\lib
PATH .;d:\hamilton\bin;d:\hamilton\samples;d
:\winnt\system32;d:\winnt
PROMPT1 $@ $CDISK%
PROMPT2 $@ $CDISK?
SHELL d:\hamilton\bin\csh.exe
TABS 3
TMP e:\tmp
Variable names are case-sensitive on OS/2 but case-
insensitive on NT. They can be of arbitrary length. A
name must start with an upper- or lower-case alphabetic
character or underscore ("_") or at-sign ("@"); remaining
characters may any of these or decimal digits. Many of
the environmental variables have specific meanings. For
example, the PATH variable tells where to look for
executable files, etc. Details describing the meaning of
each variable are given in the language reference
section.
The setenv command can also be used to create a new
environmental variable or alter or display the value of
an existing one:
147 D% setenv zork = this is the zork variable
148 D% setenv zork
85
Variables
zork this is the zork variable
149 D% _
If the list of words being assigned to the variable
includes any special tokens, it's often useful to use the
parenthesized variant of setenv. In this example, the
">" would have been confused as an i/o redirection if it
weren't inside parenthesis. Notice that the parenthesis
are stripped off before the assignment is made.
149 D% setenv greatest = (At Berkeley, they say 4.3
> V)
150 D% setenv greatest
greatest At Berkeley, they say 4.3 > V
Even though the special meaning is lost, text inside
the parenthesis is still broken down into words, as shown
in this example:
151 D% setenv pdirs =
(.;c:\os2\bin;c:\os2\cmds;c:\os2;)
152 D% setenv pdirs
pdirs . ; c:\os2\bin ; c:\os2\cmds ; c:\os2
(To avoid having the text broken up into words, use
single or double quotes around the string instead.)
Set Variables
Set variables do not get passed to a child process
but are shared among all threads. To get a list of those
currently defined, use the set command:
153 D% set
CDISK D
argv
cdhome 0
cdisk d
:
:
path . c:\os2\bin c:\os2\cmds c:\os2
precision 6
:
:
Some of the set variables are linked to the
environmental variables: you change one, and the other
changes too. For example, path contains the same
information as PATH but, because it's been parsed into
individual words, it's often a bit more useful.
86
Variables
On NT, this linkage can pose a bit of a problem.
Since the convention on NT is that environmental
variables are supposed to be case-insensitive, there
clearly is a conflict between, for example, the PATH
environmental and path set variables. The C shell
resolves this by making the set, unset and @ statements
case-sensitive (so you can still create set variables
that differ from environmental variables only by case)
but the setenv and unsetenv and $var and other variable
references first try case-sensitive, then case
insensitive variable lookups.
Many of the set variables are pre-defined by the
shell to control various aspects of how errors are
handled, etc. In some cases, each thread maintains its
own copy. For example, it wouldn't do to insist that all
threads must use the same value for the cwd (current
working directory) variable! The rest of the variables,
including any defined by the user, are shared among all
threads: if one thread changes a value, all the other
threads see the change immediately. As we'll see later,
this has some implications when spawning background
activities.
In other respects, set works just like setenv:
154 D% set privatezork = this is the private zork
variable
155 D% set privatezork
privatezork this is the private zork variable
156 D% _
Once a variable has been created as either a set or
an environmental variable, it stays that way: to change
it from set to environmental, you must first unset
(unsetenv) it, then redefine it.
Local Variables
We just mentioned that not all the pre-defined set
variables are shared. Individual threads get their own
private copies of some because to do otherwise wouldn't
be sensible. Sometimes you need the same sort of control
over the variables you create. You don't want to share a
variable with other threads or even with commands outside
a very narrow context.
You accomplish this making the variable local, which
means it's hidden from outer control blocks or other
threads. Local variables are really important, as we'll
see later, for recursive procedures or for procedures you
want to use from multiple threads. To define a variable
87
Variables
as local, use the local statement, which accepts a list,
separated with commas, of all the variable names you want
to be local. When a new local variable is created, its
initial value is always null (zero words), even if there
was a previous definition. Here you can see how the
variable i is redefined inside the nested statements but
once you exit from the nest, the old value of i is again
visible:
156 D% set i = hello world
157 D% echo $i
hello world
158 D% (local i; echo $i; set i = how are you; echo
$i)
how are you
159 D% echo $i
hello world
When you spawn a child thread, e.g., as a background
activity or as the second or following stage of a
pipeline, it gets copies of all your local variables,
snapshotted at the time it's spawned. If either the
parent or the child later changes to the value of any
those local variables, they affect only its own copy.
Variable Substitutions
The simplest way to use a variable is in a simple
substitution, where a dollar sign is used to indicate
that a variable name follows. (Similar to using a "%"
in cmd.exe.) The value is substituted in and the
statement is evaluated.
160 D% echo $HOME
d:\doug
Text surrounding the variable reference is generally
just pasted around the value that's substituted in:
161 D% echo My home directory is ---$HOME---
My home directory is ---d:\doug---
If the surrounding text would be confused as part of
the variable name, it's necessary to insulate the
variable reference with braces. For example:
162 D% echo ${HOME}XXX
d:\dougXXX
88
Variables
nonovar
If you try to reference a variable, procedure or an
alias and it doesn't exist, it's considered an error
unless you set the nonovar variable to indicate how you
want the situation treated.
163 D% echo $nonesuch
csh: The variable 'nonesuch' is not defined. To
suppress this error, set nonovar = 1 (pass through)
or 2 (discard).
164 D% set nonovar = 1
165 D% !e
echo $nonesuch
$nonesuch
166 D% set nonovar = 2
167 D% !e
echo $nonesuch
168 D% set nonovar = 0
How Variables are Stored
Each variable is kept internally as a list (an array)
of objects. An individual object can be a (possibly
null) character string, a 32-bit integer or a 64-bit
floating point value. Generally speaking, it's not
necessary to worry too much about how a specific object
is represented, though, since the shell automatically
does any necessary conversions to allow a value to be
used sensibly in any given context.
Notice, however, that even though the value of an
environmental variable may be a list, it is always
rendered as a simple character string when it's passed to
a child process. Here's an example using the "$#"
notation to ask how many words are in a variable's value:
169 D% echo $zork
this is the zork variable
170 D% echo $#zork
5
171 D% csh
Hamilton C shell(tm) Release 2.2
Copyright (c) 1988-1996 by Hamilton Laboratories.
All rights reserved.
1 D% echo $zork
this is the zork variable
2 D% echo $#zork
1
3 D% exit
172 D% _
89
Variables
In this example, zork holds five words: "this," "is,"
"the," "
zork," and "variable." But when we start up a
new child process running the shell, the child process
sees zork as holding only a single word: "this is the
zork variable".
Here's another example where we assign a floating
point value to an environmental variable. In the current
process, the exact binary floating representation is
used. When it's passed to a child process, the value is
first converted to a character string, losing some of the
precision. This example also introduces the calc
statement which evaluates an expression and prints the
value. In an expression, a variable name is recognized
even without a "$" to introduce it; in fact, that's the
preferable way to do it. If you use a "$"-style variable
substitution, the shell pastes in a character-string
representation, again losing precision. Also, the full
range of C language expression operators is available.
172 D% setenv envVar = 0
173 D% calc ++envVar
1
174 D% calc envVar /= 7
0.142857
175 D% calc envVar*7
1.000000
176 D% csh <$x[999]<---"
---><---
198 D% calc x[999] = "does not work"
csh: Illegal subscript in variable reference
'x[999]'.
The use of the "--" option and of double quotes was
important: "--" told echo that it had reached the end of
any options, allowing it to print something that began
with a minus sign. The quotes were used, in the first
case, to turn off recognition of redirection characters
">" and "<" but still get the variable substitution. The
second time, it was to make the string, "does not work" a
single word. (If you try leaving off the quotes or not
using "--," you'll see that the error messages are what
you'd expect.)
92
Variables
93
Wildcarding
Wildcarding
The notion of wildcarding is pretty simple: the user
gives just a few characters describing the filename he's
looking for and system fills in the rest. With "vanilla"
OS/2 or NT, wildcarding is the responsibility of each
application, based on the command-line arguments it's
given. Typically, the application designer fulfills this
by linking in a library routine which does a simple-
minded half-hearted wildcarding.
Hamilton C shell does the wildcarding before invoking
the application. The shell's wildcarding includes five
components: home directory expansion, wildcarding
characters, ranges, alternation and indefinite
directories. A powerful recursive match algorithm is
employed to guarantee a sensible result no matter how
complex the pattern.
Home Directory Expansion
The tilde character, "~", is recognized as shorthand
for the home directory. In the simplest form, we can use
it just by itself:
199 D? echo $home
d:\doug
200 D% cd ~
201 D% cd
d:\doug
There's also shorthand for children or siblings of
the home directory:
202 D% cd ~\samples
203 D% cd
d:\doug\samples
204 D% cd ~carol
205 D% cd
d:\carol
Wildcard Characters
The wildcard characters, "*" and "?", provide
shorthand for "match any string" and "match any single
character," respectively.
95
Wildcarding
Suppose the home directory contained the following
contents:
206 D% cd ~
207 D% ls
bcs mandel sh ex.rc
release.csh
bix mba testcode icon.ico
ring.ico
channel.one online util login.csh
snapshot.csh
dial postscpt word mail
startup.csh
excel regressn backup.csh os2init.cmd
vi.ini
games resume brite.csh popup.txt
icon samples class.txt prime.c
The following example shows the use of "?" to match
any single character. Wildcard results are always shown
alphabetically in lower case. No distinction is made
between directories and files.
208 D% echo ????
dial icon mail util word
209 D% echo b??
bcs bix
The "*" can match zero or more arbitrary characters
except ":" or "\"; in contrast to DOS-style wildcarding,
"*" can match ".". If there are ordinary characters in
the pattern, they must also be matched.
210 D% echo *mp*e*
samples
Because the wildcarding is done before the command is
invoked (without the command even being aware),
wildcarding can even be done on a cd command:
211 D% cd !$
cd *mp*e*
212 D% cd
d:\doug\samples
Wildcarding is most emphatically not restricted to
matches only against a single directory level. Here's an
example that wildcards across all the subdirectories,
looking for .c files that begin with "a".
213 D% cd ..
214 D% echo *\a*.c
samples\args.c sh\allocate.c
96
Wildcarding
Wildcarding can even be done against driveletters.
For example:
215 D% echo *:\*\q*
i:\mail\quotes.doc i:\tmp\query.out
j:\doug\quantity.disc
When wildcarding against driveletters, the shell
restricts the set of drives it will search down to just
those specified by the DRIVEMASK environment variable.
If you don't specify a DRIVEMASK, the default is all
drives except the floppies a: and b:. The search is
restricted so you don't waste time trying to access slow
removable media that may not even be ready.
Ranges
Ranges describe a set of characters, any one of which
will be matched. It's specified as a list of acceptable
characters inside "[...]" brackets. The range "[be]"
means either "b" or "e"; "[b-e]" is shorthand for any
character in the sequence "b" through "e". Within the
brackets, any number of hyphenated sequences and single
characters can pasted one after the other in any order.
For example, "[a-cu-zgkmp]" is a perfectly legal range.
Here are a couple examples. Notice that ranges can also
be used with driveletters.
216 D% echo [be]*
backup.csh bcs bix brite.csh ex.rc excel
217 D% echo[d-g]:\[s-t]*
d:\taxes d:\tmp e:\spool e:\startup.cmd e:\temp
e:\toolkit.sys f:\swap f:\tmp f:\toys g:\skip
g:\temp g:\tmp
An exclusion range is written as a set of characters
inside the brackets that starts with a circumflex. It'll
match any single character not in the range.
218 D% echo [^a-t]*
util vi.ini word
Alternation
Alternation, specified with "{...}" braces, is a
shorthand way of specifying that all the combinations of
frontparts and backparts should be generated. There isn't
any requirement that the filenames constructed actually
exist.
97
Wildcarding
219 D% echo {zork,gadzooks}.csh
zork.csh gadzooks.csh
220 D% echo {a,b}{c,d}{e,f}
ace acf ade adf bce bcf bde bdf
Alternation can be combined arbitrarily with the
other wildcard constructs:
221 D% echo {[bc],*r}*i*
bix brite.csh brite.csh ring.ico
Indefinite Directories
The ellipsis, "...", is an indefinite definite
directory wildcard. It'll match zero or more arbitrary
directory levels -- whatever it takes to make the rest of
the wildcard match. To be recognized as a wildcard, the
context must indicate it's really a filename, i.e., it
must be preceded by "\", "/", "~" or ":" or followed by
"\" or "/". For example, to find all the .inf files
anywhere on the C: drive, one might type:
222 D% ls c:\...\*.inf
c:\os2\book\cmdref.inf
As with all the wildcard constructs, the indefinite
directory construct can be used completely arbitrarily.
It can even be used several times in the same wildcard.
But do notice if you do that, there is a possibility of
getting the same file listed more than once:
223 D% ls f:\...\a*\...\money*
f:\os2\aldus\art\moneycht.eps
f:\os2\aldus\art\moneycht.eps
This can happen if there's more than one possible way
to match the same pathname. In this example, the "a*"
part could matched either "aldus" or "art" with the first
"..." matching either "os2\aldus" or "os2" and the second
"..." matching either "art" or just zero levels.
Match Failures
When you specify a sequence of wildcard patterns and
none of them match, it's normally treated as an error.
In this example, the first command causes an error
because there's no file or directory name with a "z" in
it. The second command executes without error because,
out of the sequence of patterns, there's at least one
match.
98
Wildcarding
224 D% echo *z*
csh: Wildcarding failed to produce any matches. To
suppress this error, set nonomatch = 1 (pass
through) or 2 (discard).
225 D% echo *z* sa*
samples
In this context, the fact that alternation caused
something to be generated is not the same as a match. In
the next example, "{zork,gadzooks,*z*}.csh" is the same
as "zork.csh gadzooks.csh *z*.csh"; only the last element
involves any matching, and it fails.
226 D% echo {zork,gadzooks,*z*}.csh
csh: Wildcarding failed to produce any matches. To
suppress this error, set nonomatch = 1 (pass
through) or 2 (discard).
The nonomatch variable lets you control how a
wildcard failure is treated. It works just the way
nonovar works when you reference to a non-existent
variable.
227 D% set nonomatch = 1
228 D% echo *z*
*z*
229 D% !s:s/1/2/
set nonomatch = 2
230 D% !e
echo *z*
231 D% !s:s/2/0/
set nonomatch = 0
232 D% !e
echo *z*
csh: Wildcarding failed to produce any matches. To
suppress this error, set nonomatch = 1 (pass
through) or 2 (discard).
Caution: The copy, xcopy, rename and del commands
Hamilton C shell expands out wildcards before it
invokes the application you name. This is not what the
copy, xcopy, rename, and del commands expect! Suppose
there are two files, file.a and file.b on your diskette
a:, that you wanted to copy to your current drive. Under
cmd.exe, it would be natural to type:
[D:\DOUG] xcopy.exe a:*.*
Source files are being read...
A:FILE.A
99
Wildcarding
A:FILE.B
2 file(s) copied.
The destination is implicit. xcopy understands the
wildcarding to mean "copy everything on drive a: to the
current disk and directory." That is not what would
happen under the C shell! Because the wildcard would be
expanded first, it would act instead as if you had typed:
[D:\DOUG] xcopy.exe a:file.a a:file.b
Source files are being read...
A:FILE.A
1 file(s) copied.
Do you see what happens? If wildcarding is done
first, the xcopy command sees just the two filenames and
figures you mean to copy one right over the other.
file.b is lost! For this reason, the normal startup.csh
file contains some carefully constructed aliases and
procedures to intercept the copy, xcopy, rename and del
commands:
proc safecopy(files)
cmd /c copy $files; @ nowild = s; unlocal s
end
alias copy (local s; @ s = nowild; @ nowild = 1;
safecopy)
proc safexcopy(files)
xcopy.exe $files; @ nowild = s; unlocal s
end
alias xcopy (local s; @ s = nowild; @ nowild = 1;
safexcopy)
proc saferename(files)
cmd /c rename $files; @ nowild = s; unlocal s
end
alias rename (local s; @ s = nowild; @ nowild = 1;
saferename)
alias ren rename
proc safedel(files)
cmd /c del $files; @ nowild = s; unlocal s
end
alias del (local s; @ s = nowild; @ nowild = 1;
safedel)
alias erase del
The way this works by saving the current value of
nowild (which tells whether wildcarding is should be
done), turning off wildcarding, invoking the copy, xcopy,
100
Wildcarding
rename or del command, then restoring the wildcarding
state. s is a temporary variable that gets discarded
after its been used.
Be sure to always invoke copy, xcopy, rename and del
via these aliases. If you encounter other applications
that really must do their own wildcarding, use this same
technique with them.
101
Editing
Editing
Often, the text returned by a history, variable or
command substitution isn't quite what you want. For
example, you may want to select only certain words, do a
search/replace, or manipulate a filename that's been
returned. The editing facilities provide these
capabilities.
The examples in this chapter show a sampling of
various combinations of editing commands and types of
substitutions. There simply isn't room to show all the
possibilities nor is there really a need to: with two
exceptions (":%"and ":p"), any editing command can be
applied against any substitution type or against the
result of another editing command.
Word Selections
Editing modifiers begin with a colon, ":", followed
by an editing command. You can select words either by
number or symbolically: first, last, all, etc. Here are
examples of the ":*", ":$" and ":^" modifiers to select
all, last, and first argument words, respectively.
Notice that any number of editing modifiers may strung
together. For example, ":*:^" means the first argument
word (word 1) of the sequence formed of all the original
argument words, i.e., word 2.
233 D% echo Finally, now is the time
Finally, now is the time
234 D% echo !!:$
time
235 D% echo !?Fin:*:^
echo now
now
It is also possible to select words by indexing
through the array associated with a given substitution.
The words are counted from zero.
236 D% echo `echo now is the time`:2
the
Ranges of words can also be specified with a hyphen
between the beginning and ending word indices. In this
context, the minus sign indicates a range, not
subtraction.
103
Editing
237 D% set x = now is the time for all good men
238 D% echo $x:1-5
is the time for all
When the operand is a "!?"-style history
substitution, there's a special operator, ":%", for
selecting the particular word that triggered the match:
239 D% echo !?Fin:%
echo Finally
Finally
Each of the three symbolic word selectors, "^", "$"
and "%", can be used anywhere a decimal word number would
be acceptable. For example:
240 D% echo !?time:%-$
echo time for all good men
time for all good men
Search/Replace Operations
A search/replace operation looks for and replaces a
simple character string. (For those familiar with such
things, it does not use regular expressions.) If the
search string isn't given, the one used last time is used
again. If the replace string contains an ampersand, "&",
that isn't escaped with the circumflex, it's expanded
into the search string. Here are a few examples. Notice
that putting a "g" at the start of an operation makes it
"global."
241 D% echo !?now:%-$:s/o/O/
echo nOw is the time for all good men
nOw is the time for all good men
242 D% !!:gs/t/T/
echo nOw is The Time for all good men
nOw is The Time for all good men
243 D% !!:s/nOw is/& really/
echo nOw is The Time for all good men
nOw is really The Time for all good men
Pathname Editing
Another set of operators allows filenames to be
easily manipulated. As with the search/replace operator,
pathname editing is normally applied to only the first
operand word; if you want the operation performed on all
the words, you must make it global. In this example, the
104
Editing
":h" (head) operator is used, which returns the name of
the directory containing the given file.
244 D% echo *\a*.c
samples\args.c sh\allocate.c
245 D% set dotc = !$
set dotc = *\a*.c
246 D% echo $dotc
samples\args.c sh\allocate.c
247 D% echo $dotc:h
samples sh\allocate.c
248 D% echo $dotc:gh
samples sh
Specialized Operations
Specialized operations are provided for scanning a
character string and breaking it up into words and
applying quotes around each word.
The ":x" operator for breaking up a string into
words, single-quoting each word, is particularly useful
for parsing text read with the getline pseudo-variable,
which always returns the line read as a single character
string:
249 D% @ data = $<
(I typed -->this<-- in)
250 D% echo $#data $data
1 (I typed -->this<-- in)
251 D% set data = $data:x
252 D% echo $#data $data
10 ( I typed -- > this < -- in )
The ":q" operator pastes single quote marks around
every word in the operand list. As we'll see in the
chapter on quoting, this prevents any further wildcard,
variable or command substitutions from being done.
253 D% echo sa?pl?s *\a*.c
samples samples\args.c sh\allocate.c
254 D% echo !*:q
echo 'sa?pl?s' '*\a*.c'
sa?pl?s *\a*.c
History Edits
For history substitutions, the ":p" operator can be
used to cause the result of the history substitution to
be echoed and entered into the history list but for the
105
Editing
command not to be executed. This is helpful when you're
trying a complicated edit and not sure if the result is
going to be what you want.
255 D% !?Fin:p
echo Finally
256 D% !!
echo Finally
Finally
257 D% _
106
Editing
107
Quoting
Quoting
The shell has several quoting mechanisms for marking
a section of a command for special processing. One of
them, command substitution, which used the `...` syntax,
was already discussed in the chapter on i/o redirection;
that discussion won't be repeated here.
The other quoting mechanisms focus more simply on the
problem of overriding the special meanings that certain
characters have.
Double Quotes
Double quotes are of use when you want to pass a
character string containing a space or other word
separator to an application. Normally, if you called a C
program, it would see these words as separate argv
entries instead of a single character string; double
quotes prevents this breakup into words. We can
demonstrate this using the simple myecho program in the
samples directory which prints out the argv list it
receives with single quotes around each entry:
257 D% cd ~\samples
258 D% myecho hello world
'myecho' 'hello' 'world'
arg length = 19 characters
259 D% myecho "hello world"
'myecho' 'hello world'
arg length = 19 characters
Double quotes also turn off the special meaning of
the various wildcard characters and the single quote:
260 D% echo "* isn't a wildcard character inside
quotes"
* isn't a wildcard character inside quotes
261 D% echo "~"
~
262 D% _
Command, history and variable substitutions inside
double quotes are still done:
262 D% echo "*** The home directory is $home ***"
*** The home directory is d:\doug ***
263 D% echo "`echo ~`"
109
Quoting
d:\doug
264 D% echo "myecho.c is `wc -l < myecho.c` lines
long"
myecho.c is 24 lines long
265 D% echo "!?samples"
echo "cd ~\samples"
cd ~\samples
Single Quotes
Single quotes are a little more brute force way to
turn off special meanings. Wildcards, variables and
command substitutions are all treated as ordinary text.
Only history references are recognized inside single
quotes.
266 D% echo '*'
*
267 D% echo '$cwd'
$cwd
268 D% echo '`echo hello`'
`echo hello`
269 D% echo '!?samples'
echo 'echo "cd ~\samples"'
echo "cd ~\samples"
270 D% _
It is not necessary to quote an entire word. It's
possible (and often useful) to selectively quote just as
much as desired. The quoting characters are processed
out just before invoking the command. Example:
270 D% echo 'no'w is "t"h'e' `echo time`
now is the time
Shell Escape Character
The shell escape character is normally the
circumflex*, "^". It has two uses: preceding any of the
special characters, it turns off that special meaning.
When followed by an alphabetic character or hex or octal
number, it can be used to enter binary data or characters
that couldn't easily be typed. To get a literal escape
* The circumflex was chosen as the default shell escape
character to be consistent with OS/2 and Windows NT.
Choosing the UNIX backslash instead would have
conflicted badly with their filename conventions.
Nonetheless, the escapesym variable does allow the
adventuresome to make a different choice.
110
Quoting
character, type two escapes in a row. These specific
escape sequences have special meaning:
^a Audible Alert (Bell) ^r Carriage Return
^b BackSpace ^t Tab
^f Form Feed ^v Vertical Tab
^n NewLine ^^ Single escapesym
At the very end of a line, the escape has a special
meaning: the next line is a continuation line. Inside a
quoted string, the "^"-newline combination will be
replaced with a simple newline; anywhere else, the
combination is just turned into a space. The other
special case is when it immediately follows "[". Since
"[^...]" is a wildcard exclusion range, the "^" in this
case is treated as a literal character so you won't have
to type two of them in a row.
Escape characters work even inside single or double
quotes.
271 D% echo now ^
is the time
now is the time
272 D% echo "now ^
is the time"
now
is the time
273 D% _
Quoting just part of a Word
It's possible to combine the quoting mechanisms or
use them on just the part of a string you want quoted.
For example,
273 D% echo '$cwd='$cwd
$cwd=d:\doug
Here's another example, searching through a series of
.csh files, looking for those that are self-loading
procedures. For example, we can spot that whereis.csh is
self-loading because it contains a line like this:
whereis $argv
To look for occurrences of this sort, we might loop
through a list of .csh files, grep'ing each for the
filename (minus the directory and .csh extension)
followed by white space followed by "$argv":
111
Quoting
274 D% foreach i (~\samples\*.csh)
275 D? grep $i:b'[ ^t]*$argv' $i
276 D? end
bits $argv
bumpdate $argv
caldate $argv
calendar $argv
:
Notice how the "$i:b" part is outside the quotes so that
the filename can be substituted in and edited to strip
off the directory and extension. Conversely, the
"[ ^t]*" and "$argv" portions are inside the quotes to
avoid having them confused as a wildcard or variable
substitution, respectively.
Wildcarding with Special Characters
If you'd like to wildcard filenames that have literal
$'s, [`s, quotes or other special characters, you'll have
to quote or escape the special characters to turn off
their special meanings. For example,
277 D% ls g:\tmp
$abc [hello this name has spaces
278 D% ls '$'*
$abc
279 D% ls *^ *
this name has spaces
112
Expressions
Expressions
As we've seen, sometimes a character like "*" means
wildcard and sometimes it means multiply. The meaning of
what you type is determined by the context. The shell
makes a distinction between words, used as arguments to a
command versus an expression context.
In general, expressions are expected wherever the
context would seem to suggest that it would be more
natural to think of calculating a value as opposed to
using wildcarding to produce a list of filenames.
Expressions
The shell's expression grammar is based on that of
the C language and provides the full range of arithmetic,
logical, bit, indexing and relation-testing and
assignment operators. In addition, there are file system
tests and pattern matching string compares. To use the
shell as simple calculator, use the calc statement. This
example shows a call to the square root routine, one of
the built-in procedures.
280 D% calc sqrt(2*pi)
2.506628
which writes its result to stdout. If you want to do the
calculation silently, use the "@" variant:*
281 D% @ r = 12
282 D% @ area = pi * r**2
283 D% calc area
452.389345
In addition to the calc and @ statements, other
examples where an expression is expected include a
variable index inside "[...]" brackets, in a procedure
argument list and, as we'll see, a number of the
structured programming constructs such as the for
statement.
* The choice of @ is a pun: "at-sign-ment" statement.
113
Expressions
Expression Parsing
All commands are first broken down into words. A
word is anything separated by a space or a tab or one of
the following special strings: & ,|, ;, >, <, (, ), &&,
||, >> or <<.
After a command line has already been broken up into
words, if the context is an expression, it's further
broken up into tokens. A token is a variable or
procedure name, a character or numeric literal, or one of
the expression operators. Spacing between tokens is
more-or-less arbitrary: for example, there's certainly
no need to put spaces around an arithmetic operator to
separate it from a variable name beside it.
Tokens are separated by any of these characters or
character pairs: &, |, ^, ,
+ -, *, /, %, //, =, !, ~, <,
>, (, ), , ,
,
[ ] , :, ,
; -A, -D, -H, -S, -d, -e, -f, -o,
-w, -x , ++
, -z , --, ,
** <<, >>, ==, !=, =~, !~, +=, -=,
*=, /=, %=, //=, ^= and **=. The <=, >=, <<=, >>=, &=,
and |= are always broken up into separate words before
expression parsing begins; for consistency, the parser
will accept any of "op=" assignment operators with a
space between the "op" and "=" parts.*
Since the shell knows that any names it encounters in
an expression must refer to variables or procedures it's
not necessary to use a dollar sign to introduce a
variable name. In fact, you'll find that performance is
actually a bit better if you do not use a dollar sign.
The reason is because a $-style variable substitution is
evaluated by converting the internal value of the
variable to a string and pasting that into the expression
where quite often the next step is just to convert it
right back again into the integer or floating point value
it started out as. Also, if floating point is involved,
you may notice some loss of precision. (But don't
misunderstand, it is still perfectly legal to use $-style
variable and other substitutions in an expression.)
Character literals must appear inside single or
double quotes. Numeric literals can be entered in
decimal, octal or hex. Octal numbers can contain only
the digits 0 through 7 and must begin with 0. Hex
numbers must start with "0x" and contain only 0 through
f. (Either upper or lower case is acceptable.)
* The grammar is not perfectly lr(1): proper recognition
of the file system tests and the assignment operator
requires that parsing decisions in some places have to
look ahead two tokens, not just one.
114
Expressions
Expression Operators
Expressions are evaluated according to the relative
precedence of each operator in the expression. For
example, multiplication is done before addition. The
complete precedence hierarchy is shown in tabular form in
the language reference.
284 D% calc 2 + 3*5
17
Some of the operators will be foreign, though we
trust, not too difficult to use. The file system tests
are unary operators. Each takes the name of a file or
directory and tests it for existence, zero-length or some
other interesting characteristic. Since the operand is a
pathname, the parser temporarily shifts to word mode to
read it because word mode is more natural for pathnames.
The pathname can include wildcards and should not be
enclosed in quotes. In the example that follows, "-e"
tests for existence; "-D" tests whether the name is a
directory.
285 D% cd ~\samples
286 D% ls
args.c colors.csh factor.csh mcvisa.csh
readme
args.exe deltaday.csh finance.csh myecho.c
ts.csh
bits.csh dumpenv.c getprio.c myecho.exe
viopaste.c
bumpdate.csh dumpenv.exe getprio.exe newfiles.csh
viopaste.exe
caldate.csh duplicat.csh julian.csh rcode.c
weekday.csh
calendar.csh easter.csh makecpgm.csh rcode.exe
287 D% echo a*c
args.c
288 D% calc -e a*c
1
289 D% calc -D !$
calc -D a*c
0
File System Tests
The value returned from a file system test is always
1 or 0; there are no restrictions on how the value might
be used in further calculations.
115
Expressions
290 D% calc 1 + (!*) + (-e myecho.c)
calc 1 + ( -D a*c ) + ( -e myecho.c )
2
Increment and Decrement Operators
The unary incrementing and decrementing operators are
"++" and "--". Pasting one in front of a variable name
bumps the variable, then returns the value. Pasting one
after the name bumps the variable but returns the prior
state.
291 D% calc x = 1
1
292 D% calc ++x
2
293 D% calc x++
2
294 D% calc x
3
295 D% calc --x
2
Bit Shifting
The "<<" and ">>" bit shifting operators shift an
integer value on the left by the number of bit positions
given by the integer value on the right. Bits shifted
off the end are lost; values shifted in are always 0.
296 D% calc x << 3
8
297 D% calc x >> 10
0
Bit Not Operation
The unary "~" operator returns the bit-wise not of an
integer operand. As this example shows, integers are 32-
bit signed values.
298 D% calc ~5
-6
299 D% calc 0xfffffffa
-6
300 D% calc ~!$
calc ~0xfffffffa
5
116
Expressions
Logical Not
The unary "!" operator returns the logical not. If
the operand is non-zero, 0 is returned, otherwise 1. In
this example, the parentheses or space after the
exclamation are deliberate to avoid having the expression
confused as a history reference.
301 D% calc !(5.1)
0
302 D% calc ! 0
1
Exponentiation
The "**" operator is for exponentiation. The left
operand is raised to power of the right operand.
303 D% calc 2 ** 500
3.27339061e+150
Modulo and Integer Division
The "%" operator is for modulo division and returns
the remainder.
304 D% calc 22 % 7
1
A related "//" operator does integer division. Where
the standard "/" operator might return a floating point
result, "//" gives just the integer part of any division.
305 D% calc 8/3
2.666667
306 D% calc 8//3
2
Comparison Operators
The "==" operator tests for equality; the single "="
means assignment. The "!=", "<", "<=", ">=", and ">"
operators are all straight-forward tests of "not equal,"
"less than," "less than or equal," etc. Comparisons of
strings are as easy as of numbers.
307 D% calc x = 3
3
117
Expressions
308 D% calc x == 5
0
309 D% calc "able" < "baker"
1
When the shell is asked to compare two expressions,
it first tries to coerce them to numeric values. This is
so that, e.g., a string containing "16" compares greater
than "2" even though a simple string compare would give
the opposite result.
Pattern Matching Operators
The "=~" and "!~" are the "pattern matches" and
"pattern fails" tests. These are done in pretty much the
same way wildcarding is done. On the right is a pattern
string possibly containing wildcard characters. It's
compared against the string on the left the same way a
wildcard expansion would be done except that here,
comparisons are case-sensitive and where alternation
appears, the match succeeds if any of the alternates
matches.
310 D% calc "Now is" =~ "N*i*"
1
311 D% calc "Now is" !~ "Now is"
0
312 D% calc "Now is" =~ "n*i*"
0
313 D% calc "Now is" =~ "{n,No}*i{s,the}"
1
Bitwise And, Xor and Or Operators
The "&", "^" and "|" operators perform bit-wise and,
xor and or operations on integer operands.
314 D% calc 5 & 4
4
315 D% calc 5 ^ 3
6
316 D% calc 5 | 3
7
Logical And and Or
The "&&" and "||" operators perform logical and and
or operations:
118
Expressions
317 D% calc 5 && 4
1
318 D% calc 0 && 4
0
319 D% calc 5 || 3
1
320 D% calc 5 || 0
1
The ?: Operator
The "?:" trinary operator selects between two
alternate expressions based on the logical (i.e., true or
false) value of the first operand.
321 D% calc 0 ? "hello" : "goodbye"
goodbye
322 D% calc (5 > 3) ? "hit" : "miss"
hit
The {...} Operator
The "{...}" grouping operator allows you to run a
command and evaluate its result as a 1 if it succeeds or
a zero if it fails. For example:
323 D% calc {echo hello}
hello
1
324 D% calc {cd \nonexistent}
csh: Couldn't change the current directory to
'\nonexistent'.
0
The Op= Operators
Finally, the various "op=" operators apply the op to
the left and right operands, then assign the result to
the left operand.
325 D% calc x = 2
2
326 D% calc x **= 500
3.27339061e+150
327 D% calc x
3.27339061e+150
119
Expressions
Type Conversions
The shell always tries to evaluate expressions
"sensibly" by doing any type conversions that might seem
necessary. If an integer calculation results in an
overflow, the shell shifts automatically to floating
point.
328 D% calc 2**30
1073741824
329 D% calc 2**200
1.606938e+060
If a character string was given but an integer is
needed, the shell tries to do that conversion also.
Because these conversions happen automatically, without
any fanfare, the following literals all compare equal:
27 27.0 033 0x1B " 27 " ' 0x1b '
(Null strings and strings consisting only of white space
are considered equal to zero. This is particularly
convenient for local variables, which are initially set
to null strings.)
The shell does automatic conversions to a character
string format when the result is being printed. Numeric
results are always shown in decimal. In this example, a
procedure, the built-in square root routine, is invoked
as a command; the value it returns is converted from
floating point to character string and printed.
330 D% sqrt 2
1.414213
The shell also converts to a character string when
you reference an array but use it as if it were not.
331 D% set x = Now is the time
332 D% cd ~\samples; myecho $x
'myecho' 'Now' 'is' 'the' 'time'
arg length = 23 characters
333 D% @ y = x
334 D% myecho $y
'myecho' 'Now is the time'
arg length = 23 characters
120
Aliases
Aliases
Aliases are a quick shorthand technique. If you type
an alias at the beginning of a command, it's replaced by
whatever the alias is defined as. They're intended to be
used for relatively simple abbreviations: if any
arguments are needed, you have to be able to type them
onto the end. (More complex situations will have to wait
until we cover procedures.)
To list the aliases currently defined, use the alias
command:
335 D% alias
cdd cd +c
copy local s ; @ s = nowild ; @ nowild = 1 ;
safecopy
date dt
del local s ; @ s = nowild ; @ nowild = 1 ;
safedel
dir cmd /c dir
erase del
h history
help helpmsg
label cmd /c label
ll ls -L
md mkdir
mi more -i
rd rmdir
ren rename
rename local s ; @ s = nowild ; @ nowild = 1 ;
saferename
ro rotd
start cmd /c start
type cat
vol vl
xcopy local s ; @ s = nowild ; @ nowild = 1 ;
safexcopy
Some aliases are used to intercept references to
cmd.exe's built-in commands. For example, this is how
dir is run. Other aliases give simple alternate names to
a command, e.g., rename for mv. Still others are used to
customize a command with a useful option. For example,
mi runs more but starts it immediately in interactive
mode, which means the screen is cleared first; in a
console window, this tends to run faster.
121
Aliases
To find out how any particular alias is defined, use
the alias command with only the name you're interested in
as an operand.
336 D% alias mi
mi more -i
To create a new alias, type the alias command
followed by the name of alias being created and word list
it should be expanded into:
337 D% alias hello echo hello world
338 D% hello
hello world
If you define an alias that refers to itself, either
directly or via other aliases, the shell traps the
reference rather than allowing it to expand without
limit:
339 D% alias hello (echo infinite; hello again)
340 D% hello
csh: A loop in the alias definitions was
encountered and trapped.
This raises the question how you might define an
alias, say, ls, that intercepts references to the ls
utility without getting into a loop. The answer is that
the shell considers it a special case if the first word
in the expansion of the alias is the same as its name.
Here's an alias that causes ls to always display all
files:
341 D% alias ls ls +a
Other ways around the problem would be to use the full
"ls.exe" name inside the alias or put quotes around the
"ls".
Wildcards and Special Characters in an Alias
Recall that any wildcards or escape characters in a
command are always processed before the command itself is
run. Suppose you wanted to define an alias to list all
your .exe files in the current directory. Watch what
happens if we're not careful:
342 D% cd
d:\hamilton\samples
343 D% alias lexe ls *.exe
344 D% lexe
args.exe dumpenv.exe rcode.exe
122
Aliases
blksize.exe myecho.exe winerror.exe
345 D% cd ..\bin
346 D% lexe
ls: 'args.exe' does not exist.
ls: 'blksize.exe' does not exist.
ls: 'dumpenv.exe' does not exist.
ls: 'myecho.exe' does not exist.
ls: 'rcode.exe' does not exist.
ls: 'winerror.exe' does not exist.
What happened? Why didn't lexe give us the files in
our new current directory? The answer is clear if we
list the alias definition:
347 D% alias lexe
lexe ls args.exe blksize.exe dumpenv.exe
myecho.exe rcode.exe winerror.exe
The "*.exe" wildcard got expanded before the alias
definition was processed. If we want to defer processing
of the wildcard until later, when the alias is used, we
need to escape the "*" character:
348 D% alias lexe ls ^*.exe
349 D% alias lexe
lexe ls *.exe
It's just a little trickier if we want to turn off
the special meaning not only when defining the alias but
also when we use it. That's done by embedding an extra
"^^" sequence into what we type, knowing that'll turn
into a single escape character in the definition. Here's
an example:
350 D% alias hello echo How are you^^^?
351 D% alias hello
hello How are you^?
352 D% hello
How are you?
Arguments to Aliases
Normally, any words on the line following the
reference to the alias will simply be tacked onto the
expansion. For example:
353 D% alias hello echo hello world
354 D% hello how are you
hello world how are you
But suppose you'd like to paste the arguments into
the middle of the expansion? The way to do that is with
123
Aliases
a very special adaptation of the history mechanism. If
the expansion contains any history references, the C
shell treats this as a special case. It temporarily adds
the original text of that command to the history list.
Note that only the command itself -- starting with the
alias name and ending just before any semicolon, closing
parenthesis or pipe symbol terminating the command -- not
the whole line is added. Any history references in the
definition of the alias are processed and the result
taken as the final command text. The temporary history
entry is then discarded along with the original string of
argument words. Here's an example:
355 D% alias hello echo hi ^!^^, how are you^^^?
356 D% alias hello
hello echo hi !^ how are you^?
357 D% echo x; hello Frank; echo y
x
hi Frank, how are you?
y
Notice the use of the escape characters to embed the
history reference, "!^" and the literal "?" into the
alias definition.
It is not necessary for the alias to use all the
argument words. Any that it doesn't reference using the
history mechanism are just discarded. Notice that this
alias grabbed only the first argument word from history.
Suppose there were other words on the line:
358 D% hi Frank and Bob
hi Frank, how are you?
See how the rest were just discarded?
Implementation Details
The alias mechanism is actually part of the parsing
mechanism rather than a run-time feature of the C shell.
What that means is that the alias expansion is done when
the statement is first read, not when it's executed.
Here's an example where we attempt to change the
definition of an alias inside a loop. Notice that it
doesn't have any effect until we exit the loop. That's
because the whole loop is being compiled as a block
before any part of it is executed.
359 D% alias foo echo this is life
360 D% foreach i (hello world)
361 D? alias foo echo $i
362 D? foo
124
Aliases
363 D? end
this is life
this is life
364 D% foo
world
Also, when an alias substitution is done, the
expansion is taken as the series of words the alias was
defined as; it's not reparsed into words all over again.
For example:
365 D% alias test myecho "this is a test"
366 D% alias test
test myecho this is a test
367 D% test
'myecho' 'this is a test'
arg length = 22 characters
Notice that you can't really see that the test alias
is defined as just two words, "myecho" and
"this is a test" when you list it (it's just like listing
a variable set to a list of words some of which contain
spaces), but that's what it is. These word boundaries
are maintained even if the alias contains history
references.
125
Programming Constructs
Programming Constructs
This chapter outlines the various structures provided
for connecting statements together: describing serial
relationships, conditional execution, iteration and how
procedures are defined and used.
Serial Execution
As we've seen already, commands typed on successive
lines are executed serially, one after the other.
Writing several commands on one line with semicolons
between them does the same thing.
368 D% echo hello; echo world
hello
world
369 D% _
Notice that in contrast to cmd.exe, the shell doesn't
pass the semicolon to the application you invoke. If you
really do want to pass a semicolon, e.g., to the linker
to indicate the end of the arguments, you have to escape
it or put it inside quotes.
A non-zero return code is not normally considered an
error: regardless of the return code from any particular
command, serial execution continues. We can demonstrate
this with the rcode utility in the samples directory
which prints, then exits with the return code value you
pass it on the command line. This example also shows how
you can retrieve the return code of the last child
process by referring to the built-in status variable.
369 D% cd ~\samples
370 D% rcode 1; rcode 2
1
2
371 D% calc status
2
It's also possible to describe a conditional serial
relationship. If statements are joined by "&&", the
second one is executed only if the return code from the
first one is 0, i.e., if the first statement succeeds.
If statements are joined by "||", the second is executed
only if the first one fails, i.e., returns a non-zero
return code.
127
Programming Constructs
372 D% rcode 0 || rcode 1
0
373 D% rcode 1 || rcode 2
1
2
374 D% rcode 0 && rcode 1
0
1
375 D% rcode 1 && rcode 2
1
Statements and Statement Lists
I/O redirectors and statement connectors are
recognized according to a precedence. Just as in
expressions, where "*" is done before "+", statements are
parsed so that some things are done before others. I/O
redirection comes before piping which comes before
conditional execution which comes before serializing with
semicolons. For example:
376 D% echo hello; echo world | wc
hello
1 1 7
The shell makes a special distinction between
individual statements, no matter how complex, and lists
of statements typed on separate lines or separated by
semicolons.
Here's an example using the time command, which runs
a statement and prints out the hours, minutes and seconds
it took. time expects a single statement as a operand; if
you type a semicolon, the time command (together with its
operand) becomes just one statement in the list.
377 D% time echo hello world | wc
1 2 13_
0:00:00.50
378 D% time echo hello; echo world
hello
0:00:00.00
world
Parenthesis
There are two ways to group a list of statements
together to make them act like a single statement. The
simplest way is with parenthesis, which work the way they
128
Programming Constructs
would in an expression: even if the operator inside the
parentheses are of lower precedence, they're done first.
379 D% (echo hello; echo world) | wc
2 2 14
380 D% time (echo hello; echo world)
hello
world
0:00:00.00
A parenthesized group gets its own copy of the
current directory and disk. This makes it convenient to
change directories inside the group and go do something
without having to change back afterward.
381 D% cd
d:\doug\samples
382 D% (cd ..; cd)
d:\doug
383 D% cd
d:\doug\samples
The actual implementation uses the directory stack
mechanism: at entry to the group, the current directory
is pushed onto the directory stack and at exit, the top
entry is popped.
384 D% dirs
d:\doug\samples
385 D% (dirs )
d:\doug\samples
d:\doug\samples
386 D% dirs
d:\doug\samples
Control Structures
The more general way of connecting statements
together is with control structures, which provide ways
of describing conditional or iterative execution or even
(with procedures) adding new vocabulary to the language.
You can use a control structure anywhere a statement is
allowed.
The language is completely recursive: control
structures can be nested inside control structures, etc.
A statement can be arbitrarily complex. Here's an
example timing a statement that turns out to be a for
loop piped to a wc and inside the for loop ...
387 D% time for i = 1 to 3 do
388 D? time echo hello world | wc
129
Programming Constructs
389 D? end | wc
6 12 126_
0:00:01.03
If Statement
The if statement comes in two forms. The short form
is convenient if the choice is only between executing and
not executing a single statement, which appears on the
same line.
390 D% if (5 == 2 + 3) echo yes
yes
391 D% if (5 == 10) echo really
392 D% _
The longer form provides the more traditional if-
then-else structure. Indentation is a matter of choice,
it's used in these examples merely to improve
readability.
392 D% if (5 == 10) then
393 D? echo 5 == 10
394 D? else
395 D? echo 5 is not 10
396 D? end
5 is not 10
397 D% _
Switch Statement
The switch statement works by attempting to pattern
match the switch value against a series of alternative
cases. The switch and case values can all be arbitrary
expressions. If any pattern match succeeds, execution
begins with the next statement following and continues,
skipping over any interspersed case clauses until either
the end of the switch block or a break statement is
reached.
397 D% switch ("hello world")
398 D? case 5:
399 D? echo hit 5
400 D? case "h*":
401 D? echo hit "h*"
402 D? case "x*":
403 D? echo hit "x*"
404 D? break
405 D? case 43.2:
406 D? echo hit 43.2
130
Programming Constructs
407 D? default:
408 D? echo did not hit
409 D? end
hit h*
hit x*
The break statement used here causes execution to
"break out of" the innermost control structure. If
you're nested several layers deep into control structures
and want to break out of a higher level structure you can
label the higher level structure and specify that name on
the break statement.
Foreach Statement
The foreach statement is designed for iterating over
a series of words. In this example, i is iterated over
the list of all the files in the samples directory. Each
one, in turn, is tested to see if it's executable (i.e.,
has a .csh, .cmd, .exe or .com extension.)
410 D% cd ~\samples
411 D% ls
args.c dumpenv.c finance.csh myecho.exe
readme
args.exe dumpenv.exe makecpgm.csh rcode.c
bits.csh factor.csh myecho.c rcode.exe
412 D% foreach i (*)
413 D? if (-x $i) echo $i is executable
414 D? end
args.exe is executable
bits.csh is executable
dumpenv.exe is executable
factor.csh is executable
finance.csh is executable
makecpgm.csh is executable
myecho.exe is executable
rcode.exe is executable
For Statement
The for statement provides more traditional iteration
over numerical values. If you specify a range (e.g., "1
to 3") but don't specify the increment, 1 is assumed.
Although this example shows iteration over integer
values, floating point values are equally acceptable.
415 D% for i = 1 to 3 do
416 D? echo $i
417 D? end
131
Programming Constructs
1
2
3
You can also iterate over a list of ranges or
individual values. The to and by clauses may be
specified in either order.
418 D% for i = 1, 4, 7, 12, -4 to 6 by 3 do
419 D? echo $i
420 D? end
1
4
7
12
-4
-1
2
5
While Statement
The while statement works in the traditional manner,
iterating so long as the while condition is true. This
example keeps popping up through the various levels of
parent directories until it reaches the root. fullpath is
one of the built-in procedures; it return the fully-
qualified pathname of its argument. Notice that fullpath
is invoked in three different ways: on line 421, as if
it were a command, on 422 in more conventional procedure
syntax and on 423, where it's substituted in as if it
were a variable.
421 D% fullpath .
d:\doug\samples
422 D% while (fullpath(".") !~ "[a-zA-Z]:\")
423 D? echo $fullpath(".")
424 D? cd ..
425 D? end
d:\doug\samples
d:\doug
426 D% cd
d:\
Repeat Statement
The repeat statement has two forms. In the short
form, a numeric constant (not an expression) specifies
the number of times to execute the statement following on
the same line.
132
Programming Constructs
427 D% repeat 4 echo do this again
do this again
do this again
do this again
do this again
In the long form, repeat provides the more
conventional repeat structure, iterating until some exit
condition satisfied.
428 D% calc i = 1
1
429 D% repeat
430 D? calc i++
431 D? until (i > 5)
1
2
3
4
5
Procedures
Procedures, as in any high-level language, are a
convenient way to package together a series of statements
as a more convenient operation. Once you've defined a
procedure, you can invoke it simply as if it were a new
command.
432 D% proc hello()
433 D? echo hello world
434 D? end
435 D% hello
hello world
The proc statement can also be used to ask what
procedures are already defined or what arguments a
particular procedure takes:
436 D% proc hello
hello ( )
437 D% proc | mi
abs ( x )
acos ( x )
asin ( x )
:
:
samepath ( a, b )
sin ( x )
sinh ( x )
--- more --- (Press H for Help)
133
Programming Constructs
You can explicitly discard a definition with unproc;
otherwise the shell remembers any procedure you tell it
until you exit the shell or give it a new definition.
438 D% unproc hello
439 D% hello
csh: Couldn't find an executable file named
'hello'.
When you give the shell a procedure definition, the
shell compiles it into an internal form so that the next
time you refer to it, it'll save the reparsing time and
run much faster. As an example, unproc the whereis
procedure to make the shell reload the definition from
the .csh file and see what that does to the execution
time:
440 D% unproc whereis
441 D% time whereis ls
f:\os2\bin\ls.exe
0:00:02.15
442 D% !!
time whereis ls
f:\os2\bin\ls.exe
0:00:01.28
The namespace for procedures is shared among all the
threads: if one thread creates a new procedure, it
becomes usable immediately by all the other threads.
Arguments
You can write a procedure so it expects arguments,
just as you would in any other high level language.
Argument names are somewhat like local variables: their
initial values are set at entry to a procedure, hiding
any previous definition; they go away as soon you exit
the procedure code. Here's a simple example which
compares the timestamps on two files.
443 D% proc comparedates(a, b)
444 D? if (`newer $a $b`) then
445 D? echo $a is newer than $b
446 D? else
447 D? if (samepath(a, b)) then
448 D? echo $a and $b are the same file!
449 D? else
450 D? echo $a is older than $b
451 D? end
452 D? end
453 D? end
454 D% comparedates `whereis more`
134
Programming Constructs
c:\os2\bin\more.exe is newer than
c:\os2\cmds\more.com
455 D% _
When you pass arguments to a procedure on the command
line, the individual argument words are paired up, one-
by-one, with the argument names you gave. If the shell
runs out of names before it runs out of words, the last
named argument gets all the remaining words:
455 D% proc xx(a, b)
456 D? echo $#a $a
457 D? echo $#b $b
458 D? end
459 D% xx now is the time
1 now
3 is the time
If you pass arguments to a procedure that doesn't take
any, they're evaluated but quietly ignored.
If a procedure does take an argument, it always get
some value, even if it's zero words long. So if you want
to know if you got passed a value, just count the number
of words:
460 D% proc xx(a)
461 D? echo $#a ">>$a<<"
462 D? if (a == "") echo null argument!
463 D? end
464 D% xx
0 >><<
null argument!
In a more serious vein, here's a simple procedure
definition I use all the time (I have it in my
startup.csh file) to implement a real quick and dirty
(but very easy to use!) personal phone index:
465 D% proc ppi(name)
466 D? grep -i "$name" h:\phone
467 D? end
468 D% ppi hamilton
Hamilton Laboratories 508-440-8307 Fax: 508-440-
8308
As you add lines to your \phone file, you merely add any
interesting search phrases or other tidbits onto the same
line with the person's name. Totally free format. Add
anything you like and search on anything you like and
it's fast.
135
Programming Constructs
Return Values
Procedures are also important in expressions, where
it's generally useful to think of the procedure as
returning a value, just as it might in any other
language. The type and value of what you choose to
return is arbitrary. Here's a purely mathematical
example from finance.csh in the samples directory:
469 D% proc FV_PresentAmount(i, n)
470 D? # Calculate the multiplier to convert $1
now to a
471 D? # future value, given interest rate i
472 D? return 1/(1 + i/100)**n
473 D? end
474 D% # Calculate the future value of $500 invested
475 D% # for 10 years at 8% interest.
476 D% calc 500*FV_PresentAmount(8, 10)
1079.462499
If you call a procedure that returns a value as if it
were a command, whatever it returns is printed:
477 D% FV_PresentAmount 8 10
2.158925
Recursion
A procedure can call other procedures or even itself.
When a procedure calls itself, it's called recursion.
Typical uses of recursion are in cases where the problem
itself is recursive, or self-replicating. For example,
here's a procedure to walk down two directory trees A and
B that are thought to be related and list any non-hidden
files in A that are not in B. (If you set nonohidden =
1, it'll compare hidden files also.)
478 D% proc comparetrees(a, b)
479 D? local i, f
480 D? foreach i ($a\*)
481 D? @ f = $i:t
482 D? if (! -e $b\$f) then
483 D? echo $b\$f is missing
484 D? else
485 D? if (-d $i) comparetrees $i $b\$f
486 D? end
487 D? end
488 D? end
489 D% comparetrees c:\src\projectx a:\src
Notice that i and f were declared as local variables.
If the variables were simply set variables, one instance
136
Programming Constructs
of them would be shared by all the levels of recursion.
In this particular example, that would still have worked,
but only because each level calls the next only after
anything involving f or i has been evaluated; it wouldn't
matter if f or i was trampled by the next call. Here's
an example where obviously that would not be true: a
clumsy attempt at a "post-order" traversal of a directory
tree:
490 D% proc traverse(a) # Don't do it this way
491 D? foreach i ($a\*)
492 D? if (-d $i) traverse $i
493 D? echo $i
494 D? end
495 D? end
496 D% traverse . | more
If you carefully examine the output of this traverse,
you'll see that subdirectories don't get listed properly:
instead of being listed by themselves, the name of their
last child is listed twice. For a correct result, try it
again with i defined as a local variable. (Use the
key to help you quickly re-enter the lines that
stay the same.)
Calling a Procedure
As you may have spotted, there are two ways to invoke
a procedure. Sometimes, the arguments are inside
parentheses, separated by commas, and sometimes they're
not. What's the difference?
The difference is whether the context is an
expression or a command. As discussed when we first
introduced expressions, the shell always begins to parse
statements by first breaking them up into words. That's
fine for normal commands, e.g., running an external
utility. And it works also when you want to use a
procedure as if it were a command, just typing the name
of the procedure followed by a list of arguments
separated by spaces, e.g.,
497 D% proc power(a, b)
498 D? return a**b
499 D? end
500 D% power 2 3
8
501 D% _
But this style of parsing wouldn't be very suitable
in those instances where the point is to do some kind of
calculation or expression evaluation. So when the shell
137
Programming Constructs
encounters something that normally takes an expression,
e.g., following the calc keyword, or inside the test in
an if statement, it shifts to a different style of
parsing, further breaking up the words into tokens, so
that "*" isn't misunderstood as a wildcard, so we don't
need to type spaces around all the operators, so we can
type variable names without having to put a "$" in front
of them and so on. All of this is so that the rules for
typing an expression can bear some resemblance to those
followed by other programming languages like C, FORTRAN,
Pascal, etc.
When we call a procedure from within an expression,
all these same arguments still apply. We want it to act
pretty much like any other high level languages. We want
to be able to pass it arbitrarily complex expressions as
arguments. We want to be able to take the value it
returns and use that value as a term in still other
expressions.
So there's a real problem: to call a procedure from
within an expression and pass other expressions as
arguments, we need a way of separating one argument from
the next (obviously, it can't be just a space as it would
be when the procedure is used as if it were a command)
and for separating the whole procedure call and its
arguments from the rest of the expression. That's why
the common high-level language convention of separating
arguments by commas and putting parentheses around the
whole list is used. Here's an example of what that looks
like:
501 D% calc 5.5 + power(2, 3)*9
77.500000
If you try using a procedure as a command but
accidentally type the argument list with parenthesis,
it's an error:
502 D% power(2, 3)
csh(line 490): Couldn't evaluate expression
operands as numeric as required by the expression
operator.
> in power( "(", "2,", "3", ")" ) defined at line
597
< called from line 502
The reason this is an error is because, since this was
typed as a command, the shell took the words following
the word power as literal arguments. It couldn't tell
you meant this as an expression. Let's redefine that
procedure, putting some echo statements in there so we
can see what happened:
138
Programming Constructs
503 D% proc power(a, b)
504 D? echo a is $a
505 D? echo b is $b
506 D? return a**b
507 D? end
508 D% power(2, 3)
a is (
b is 2, 3 )
csh(line 506): Couldn't evaluate expression
operands as numeric as required by the expression
operator.
> in power( "(", "2,", "3", ")" ) defined at line
503
< called from line 508
As you can see, the expression "a**b" failed to evaluate
properly because a was set to the first argument word,
"(", and b was set to a string concatenation of all the
rest of the words. Neither was a number.
If you want to call a procedure and substitute the
value back onto the command line even when the context is
not an expression, it can be done, however. One way is
with command substitution:
509 D% echo `power 2 3`
a is 2 b is 3 8
This is a bit expensive, though, because the shell
will have to create a new thread to run the power
procedure and set up a pipe to read the result. And as
you see, if the procedure also writes to stdout, you'll
pick up that text also, probably unintentionally.
Another, better way, is to use a dollar sign to introduce
the substitution just as if it was a variable
substitution:
510 D% echo $power(2, 3)
a is 2
b is 3
8
Notice that when use the dollar sign-style procedure
reference, the rest of the syntax is as if the procedure
had been called from within an expression. The arguments
do need to be within parenthesis and they do need to be
separated by commas. The reason is just the same one as
for why a procedure call in an expression has to be done
this way: without the parentheses, there'd be no way to
tell where the arguments ended. A nice benefit is that
in the argument list, we get to use the full expression
grammar:
139
Programming Constructs
511 D% echo $power(2, 3*sin(1/2))
a is 2
b is 1.438277
2.709970
Shell Scripts
Scripts are a final way of bundling up a series of
statements to be called up and executed as a single
command. To create a script, create a file with a .csh
extension:
512 D% cat >trythis.csh
echo hello from trythis
^Z
513 D% trythis
hello from trythis
When you tell the shell to run a script, it first
creates a new thread to run it. This is partly a
holdover from original UNIX language definition, partly a
response to a provision in OS/2 and NT for threads, but
not a fork mechanism and partly due to a genuine need to
inexpensively separate some of the script's environment
from that of its caller. (The next chapter has a longer
discussion of threads.)
Shell Script Arguments
Arguments to a shell script are passed to it as the
argv variable. argv will be a list of any words that
appeared on the command line following the name of the
shell script. (You can access the name of the script as
the scriptname variable.) You can access argv like any
other variable:
514 D% cat >tryargv.csh
echo $#argv $argv
^Z
515 D% tryargv hello how are you
4 hello how are you
There are also some shorthand forms for getting
individual words of argv. $0 through $9 is the same as
$argv[0] through $argv[9]. (Remember that unless you
have nullwords set, subscripting errors will be caught.)
140
Programming Constructs
ignorestatus
If you write a script with serially connected
statements the only thing that would cause the shell to
quit before it gets to the end would be an explicit
failure: an application name that couldn't be found, a
child process that terminated with a segment fault, or
something else of an equally serious nature. Often in a
script, that's not what you want: you've written the
script with the expectation that everything will work (as
you planned) from one step to the next. If something is
wrong, you'd like the script to quit as soon as possible,
before any damage is done.
The way you do this is by setting ignorestatus = 0,
which means you do not want to ignore the status codes
coming back to this thread from its children. Here's an
example in the main thread:
516 D% set ignorestatus = 0
517 D% rcode 10
10
csh: The child process running 'rcode' exited with
a non-zero status = 10.
In the main thread, the shell will keep on going and
prompt for the next command because interactively that's
most sensible. The shell knows to do this because
ignoreerrors = 1. But in a script, errors cause the
shell to quit:
518 D% cat >trythis.csh
calc ignoreerrors
set ignorestatus = 0
rcode 10
echo doesn^'t print
^Z
519 D% trythis
0
10
csh(d:\doug\trythis.csh:line 3): The child process
running 'rcode' exited with a non-zero status = 10.
> in d:\doug\trythis.csh
< called from line 519
csh: The csh script file
'd:\doug\samples\trythis.csh' exited with a non-zero
status = 10.
Notice that in this case we got two messages, one from
the threads executing the script and one from the main
thread, reporting what the script returned. Let's return
to the normal mode of ignoring status:
520 D% set ignorestatus = 1
141
Programming Constructs
source statement
The examples so far have shown how a script is
normally run somewhat isolated in a separate thread. It
is also possible to run a script in your current thread
using the source statement. You might want to do this if
you wanted to the script to change your current thread's
private variables or its current directories or disk.
Here's an example to showing how a sourced script runs in
the same thread:
521 D% cat >trythis.csh
echo argv = $argv, threadid = $threadid
^Z
522 D% echo $threadid
6
523 D% trythis hello world
argv = hello world, threadid = 7
524 D% source trythis hello world
argv = hello world, threadid = 6
526 D% _
Notice how the argv argument vector is set up the same in
either case. Also, notice that the statement number
skipped by one. When you source a script, the effect is
precisely as if you typed those lines in directly to the
shell. The lines read by source are even entered into
the history list:
526 D% h 5
522 echo $threadid
523 trythis hello world
524 source trythis hello world
525 echo argv = $argv, threadid = $threadid
526 h 5
Caution: Labels and Gotos
We haven't mentioned labels and gotos yet but it
probably isn't a surprise that the C shell allows them.
Indeed:
527 D% cat >trythis.csh
goto next
echo this does not print
next: echo this prints
^Z
528 D% trythis
this prints
If you want to use gotos to labels, you should be
aware that forward references can be little trickier than
142
Programming Constructs
a more conventional compiled language. The C shell
allows you to redefine a label anytime you like. But if
you type a goto that refers to previously defined label,
the shell has no way of knowing that you intend it to
redefine it up ahead. You can keep running the last
example over and over this way with exactly the same
result: because a new thread is started each time with
no prior definition of next, the shell knows it must be a
forward reference. But imagine how repeatedly sourcing
this script would fail in an infinite loop:
% source trythis
this prints
% source trythis
this prints
this prints
this prints
this prints
this prints
:
(Beware of actually trying this: you may find it
difficult to interrupt out of it.)
The reason sourcing the script a second time turns
into an infinite loop is that the label next is already
defined after the first run. The second time, when the
goto is read from the script, the history list would look
something like this:
source trythis
goto next
echo does not print
next: echo this prints
source trythis
goto next
What particularly gets the shell into a muddle is the way
this recurses indefinitely: each time through the loop,
it recurses through an another level of sourcing.
Ultimately, it runs out of stack space and fails. This
is not a nice way to treat the shell!
In general, it's hard to recommend gotos in any
programming language nowadays; in a script you intend to
run using source, they can be particularly nasty.
The shell does automatically age labels and throw
them away after a while even if they haven't been
redefined. When it discards a label, it also discards
any compiled statements it's been holding onto that could
have been executed only by a goto to that label. The
cutoff point where the shell begins to discard labels is
143
Programming Constructs
set by the gotowindow variable. Let's now clean up after
ourselves and move along:
529 D% rm trythis.csh
Interrupts
Normally, when you type Ctrl-C, you interrupt the
foreground activity. But what if you were in the midst
of a complex script and needed to do some kind of cleanup
before you exited? What if you wanted to be sure you had
a chance to delete any temporary files you might have
littered around?
The solution is the onintr statement, which allows
you to define the action to be taken when an interrupt is
received. It causes whatever's running to be interrupted
all the way back up to the block in which the onintr
routine was defined and for the interrupt routine to be
run in that current thread. Within that interrupt
routine, you could, for example, remove all your
temporary files and goto the end of the script or return
a special value from a procedure or whatever else might
be appropriate.
530 D% onintr echo hello
531 D% for i = 1 to 5 do
532 D? echo $i
533 D? sleep 1
534 D? end
1
^C
hello
Here's another example, returning from a procedure.
Note how the value returned (and printed) is the one
produced by the onintr statement.
535 D% proc foobar()
536 D? onintr return 5
537 D? for i = 1 to 5 do
538 D? echo $i
539 D? sleep 1
540 D? end
541 D? return 2
542 D? end
543 D% foobar
1
^C
5
144
Programming Constructs
When execution leaves the block in which an onintr is
defined, the previous onintr (if any) again takes effect.
Note that a null onintr routine does not mean that
interrupts are ignored, merely that after processing
bubbles back up to the level where that onintr was
defined, that it will continue with the next statement.
Notice how, in this example, when the Ctrl-C is received
when obviously execution is stuck in the infinite loop
inside bar, that the "onintr goto xx" causes a branch to
xx in the same block in which the onintr was defined, not
the xx in the block where execution was going on. Also,
notice that once both procedures have been exited, we're
back to the same onintr routine we defined a few
statements earlier.
544 D% proc foo()
545 D? onintr goto xx
546 D? bar
547 D? xx: echo this is foo
548 D? end
549 D% proc bar()
550 D? while (1) # Deliberately infinite loop
551 D? end
552 D? xx: echo this is bar
553 D? end
554 D% foo
^C
this is foo
555 D% ^C
hello
555 D% _
Masking Interrupts
In cases where you'd like to simply turn off
interrupts or defer processing them, use the irqmask
variable. By default, it's set to 0, meaning interrupts
will be accepted immediately. Setting it to 1 means
interrupts will be deferred until the mask is cleared
again. Setting it to 2 means interrupts will be totally
ignored.
irqmask is a per-thread variable, meaning each thread
can independently decide how it will respond to
interrupts. Each new thread always starts out with
irqmask = 0 (interrupts enabled).
145
Scheduling
Scheduling
Foreground Activities
Whenever you type any command, the shell's normal
behavior is to start up that child activity and then go
to sleep waiting for it to complete. This is a
foreground activity. If you start something and then
decide you want to stop it, type Control-C, which wakes
up the shell and causes it to stop the foreground
activities.
If the application is going to run in its own
separate window (or, under OS/2, in a separate screen
group), that's treated specially. For example, under
Windows NT or Windows 95, typing:
555 D% notepad
causes notepad, which is a graphical application, to
appear in a new window. In that case, unless the command
is in script or part of a more complex structure (a
sequence of statements joined by semicolons or &&'s or
||'s, for example), there's no reason for the shell to
wait for the child's completion. After all, if you want
to wait `till it's done you can do that yourself!
The way the shell figures out what type of
application you're starting is by actually examining the
executable file itself. Under Windows NT or Windows 95,
it can tell the difference between console and graphical
applications. Under OS/2, it knows about full-screen,
text-windowable and full Presentation Manager
applications*. Under any of these systems, when you
start an application that needs a new window, the shell
comes right back for the next command.
* Under OS/2, the shell depends on the .exe file being
properly marked with the application type.
Unfortunately, not all developers obey this rule. For
example, in some releases of OS/2, even IBM forgot to
mark some applications such as the control panel.
Unmarked applications are, by default, started full-
screen; a PM application that's started this way dies
immediately. If you spot this behavior, you should
mark the offending application using the markexe
utility. (Type "markexe -h" for more information.)
147
Scheduling
Also, if the child is a graphical application and
stdout or stderr is tied to the console window where the
C shell's running, the C shell recognizes that that
handle won't be inheritable by the child and instead will
create a pipe. It'll give the write end to the child and
create a background thread in the C shell to read
anything coming back over the pipe from the child and
copy it to the console window. This means that with the
C shell, you can still use ordinary printf's in an OS/2
PM or Windows NT graphical application and not lose any
output.
Background Activities
If you want to run something but don't want to wait
for it complete, just type an ampersand at the end of the
statement:
556 D% wc hello.c >linecnt &
1
557 D% _
This creates a child process to run word count in the
background, with its output directed to a file. The "1"
message means that a new background job (job 1) has been
spawned to process the command while you continue to
work. The job starts as a new thread. If, as in this
case, a separate process is needed, that thread will
create it with a CreateProcess call to the Windows NT
kernel (or DosExecPgm call to the OS/2 kernel , as
appropriate) then exit. Each new thread, process or
screen group spawned by a background job will inherit its
parent's job number. Every time a new background job is
created, the job number is incremented.
The use of i/o redirection in combination with a
background activity is not accidental. If it's not
redirected, it goes to your terminal, intermixing with
the output of any foreground activities. Occasionally,
that might be exactly what you want. For example, here's
a timer to wake you up in 5 minutes (300 seconds):
557 D% (sleep 300; echo ^aWake Up, Sleepyhead.) &
2
:
:
Beep
Wake Up, Sleepyhead.
The ampersand works consistently for things that need
a new window:
148
Scheduling
558 D% notepad
3
59 D% _
A new job starts up and announces itself, then realizes
that the control panel has to be run in a separate
session. Once it's started the child session, the thread
exits and its children are adopted by its parent thread
and child is left running as job 3.
Under both OS/2 and Windows NT, background activities
are, in a sense, detached: typing Ctrl-C doesn't
interrupt them (unless they explicitly ask to be
notified.) You can start a large number of background
activities and check on their status using the ps
(process status) command. Here's what you'd see on NT;
the output under OS/2 would be fairly similar.
559 D% ps
Job ID Parent State Activity
- t131 - running
interrupt_handler
- t134 t131 running
keyboard_reader
- t135 t131 running
main_thread
- t99 t131 running
console_io
3 p114 t135 running notepad
Several threads are always running in the background.
Each spends most of the time asleep, waking up to do some
housekeeping only when an interrupt or the signal that a
child activity has completed is received. One thread is
dedicated to reading characters from the keyboard on
request from other threads. Another thread is the
foreground command processor. The console_io thread was
spawned when the C shell realized that notepad is a
graphical application and that a pipe would be needed to
capture any stdio output from the child. Other entries
in the ps report come and go as you type commands.
If you want to explicitly terminate a background
activity, use the kill command. But do keep in mind that
under NT, there are two ways to kill a process: If it's
a console (text window) application, it can be done by
sending it a Ctrl-C signal; that's what kill does by
default. But if it's a graphical application, it can
only be done using the TerminateProcess call, a very
brute force way of killing something; any DLL's that were
being used by that process will not any notification that
the process has died and, thus, will not know to do any
cleanup they might normally do.
149
Scheduling
560 D% kill -x! 3
561 D% ps
Job ID Parent State Activity
- t131 - running
interrupt_handler
- t134 t131 running
keyboard_reader
- t135 t131 running
main_thread
- t99 t131 running
console_io
Variables and Threads
User-defined variables are shared between all active
threads unless they're declared as local: if one changes
a variable's value, the other threads see that change
immediately. Because the individual threads run
asynchronously, this can cause some surprising results.
In this example, the foreground thread spawns new
background threads and increments the variable i faster
than the children can execute. By the time any the
children actually start, the loop has finished and every
thread sees i as having the value 5.
562 D% for i = 1 to 3 do
563 D? echo $i &
564 D? end
4
5
6
565 D% 5
5
5
One solution is to use the eval statement. eval
parses the text it's passed at run-time, after any
variable substitutions have been done. Because the
ampersand is inside the quotes, its special meaning isn't
detected until run-time.
565 D% for i = 1 to 3 do
566 D? eval "echo $i &"
567 D? end
7
8
9
568 D% 1
2
3
150
Scheduling
A better solution is to make i a local variable,
since locals are snapshotted and copied when the child is
spawned:
568 D% local i; for i = 1 to 3 do
569 D% echo $i &
570 D% end
10
11
12
571 D% 1
2
3
Re-entrancy
Threads also introduce the possibility of re-
entrancy. In the next example, we define a procedure for
summing all the integers 1 to n. Notice that it works
fine if it's run by itself, but gives the wrong answers
if two threads try to run it simultaneously:
571 D% proc sum(n)
572 D? @ s = 0
573 D? for i = 1 to n do
574 D? @ s += i
575 D? end
576 D? end
577 D% sum 100
5050
578 D% sum 100 &; sum 100
13
6780
579 D% 7177
Here also, the solution is simply to include a
statement defining i and s as local inside the procedure.
Threads: An advanced discussion
In building Hamilton C shell, a conscious and
fundamental decision was made to use threads in many
situations where earlier shells might have created
separate processes. The result is a dramatically more
responsive tool albeit one with some subtle semantic
differences from the original.
The UNIX C shell language definition called for
individual stages of a pipeline, command substitutions
and scripts each to be run in a separate process cloned
151
Scheduling
by forking the main process. Using forking, the child
inherited all of its parent's state (current directory,
open file handles, environmental and set variables, etc.)
but any changes it made only affected itself. On a UNIX
system with paging hardware and the fork mechanism built
into the kernel, it's pretty fast.
But OS/2 and the NT Win32 API's do not have fork*,
and trying to recreate precisely this language semantic
under OS/2 or NT would have been foolishly expensive,
potentially adding several seconds to the startup time
each time you invoked a shell script. On the other hand,
these systems do offer threads. A process can have lots
of threads and each one can run along at its own pace.
When a thread calls the kernel to do something that takes
a long time (e.g., a disk read), it goes to sleep and
doesn't wake up until the data's ready. When one thread
goes to sleep, the kernel looks around for another that's
ready to run. By using threads, it's possible to ensure
that if one thing's got to wait, that won't hold up
everything else.
Threads turn out to be even faster than a fork
(regardless of the hardware), because the amount of state
information associated with a thread is so little
compared to that of a process. As viewed by the kernel,
a thread "owns" only a register set, a stack and an
instruction pointer. Everything else, memory, current
directories, etc., is shared among all the threads in a
process. This means creating a thread is very fast, as
is switching between threads.
On the other hand, using threads to best advantage
imposed some significant design challenges in Hamilton C
shell. Certainly, for example, few would consider it
acceptable if a script running in the background could
>Boom< change your foreground current disk! The problem
was to create a way for threads to cooperatively share
the process resources but without giving away all the
performance advantage we'd started with by using threads.
Also, some of the elegance of threads is the idea you can
keep creating new ones. Each is just like the next: any
* The decision not to provide a fork semantic under OS/2
was probably forced by the decision that initial
releases of OS/2 would run on 286-based machines.
Lacking paging hardware, a fork on a 286 would likely
have been unacceptably slow, no matter how the software
was designed. Under Windows NT, the problem would have
been deciding what to do about the message queue: if
both parent and child got the same message queue (which
certainly they would have if they were true clones as
fork requires), how would the problem of both processes
fighting the same message events been resolved.
152
Scheduling
given thread can run just as complex a program as the
next and each can spawn new threads. It would be a shame
to lose that recursive characteristic by clumsiness in
the language design.
Starting with a clean sheet of paper, our solution
was a highly multi-threaded architecture. It expects you
to start lots of threads: stages in a pipe, background
activities, etc. To our knowledge, no other command
processor on any system employs this technology.
Certainly, all the code in Hamilton C shell is re-
entrant: there is a minimum of global, statically-
allocated data; the few variables that are global tend to
be pointers to the roots of various dynamically-allocated
information trees for managing variables, threads,
processes, file handles and other resources. When the
shell creates a new thread, it creates the appropriate
records and links them in. Some characteristics given
the new thread are inherited from its parent and some
always get set to specific defaults.
Shared variables and other resources are semaphored:
before using a resource, a thread requests it; if
several resources are needed simultaneously, they're
always requested in the same order to avoid deadlocks.
Critical resources are held only for short periods.
There's no polling anywhere. "Handle" mechanisms are
used so that, e.g., a thread can decide if its current
disk and directories are set up by simply comparing an
integer. Path hashing structures are shared with a "copy
on write" mechanism in case they change directories and
need slightly different hash structures. Any thread can
do what any other can: compile or execute an arbitrarily
complex C shell program or even spawn or pipe child
threads.
Given the enormous advantage offered by threads and
the unique technology we've developed to exploit them, we
expect Hamilton C shell should easily outperform any UNIX
shell on comparable hardware.
153
Order of Evaluation
Order of Evaluation
Finally, to put everything in perspective, here's a
summary of roughly the procedure by which the C shell
reads, parses and evaluates your commands:
1.
The command is read. If stdin appears to be a
keyboard, the command line editing routines are used
to read a keystroke at a time, entering them into the
command buffer and doing whatever editing is
indicated. Otherwise, the shell simply uses the
kernel's DosRead (OS/2) or WriteFile (Win32)
functions to read small chunks until the end of the
statement has been found.
2.
History substitution is done. The "!" and "%"-style
history references are expanded.
3.
The text is broken up into separate words. Unless
it's part of a quoted string, white space (tabs and
spaces) separates words. Also, these special strings
are interpreted as separate words even if they're run
together with other text:
& | ; > < ( ) && || >> << >&
>! >&!
4.
The command is added to the history list. The fact
that this is done after the text has been broken up
into separate words explains why the commands in the
history list will look a bit different than the way
you typed them. It's done this way on purpose so
that you can refer to individual words in previous
commands, e.g., with "!$" to get just the last word
of the last command.
5.
The command is compiled into an internal form using a
recursive descent parser, recognizing the language
constructs and whether a given portion of a command
is really an expression or just a series of words.
Compilation at this stage is at the level of a whole
construct, e.g., a whole foreach statement or proc
definition and everything inside it. That's so that
every time through a loop or every time a procedure
is run, the shell won't waste time recompiling
statements that could have been compiled the first
time. Also, aliases are expanded at this stage and
some minor optimizations are done, e.g., pre-
155
Order of Evaluation
compiling static patterns appearing in pattern-
matching expressions, etc.
6.
The internal form is executed. The various quoting
and other substitution activities are done, in
effect, in this order:
a.
Threads are spawned for separate stages of a
pipeline or for background execution. That's to
avoid serializing any blocking events as, for
example, the shell hits the disk, looking through
the search path for executable files, etc. By
spawning separate threads, those blocking events
can be overlapped.
b.
I/O redirection is performed. If the filename
being redirected to/from is actually a wildcard or
a command or some kind of substitution, that word
will be expanded.
c.
Single and double quoted strings are processed.
If the quoted string contains any wildcard
characters, they're escaped so that they'll appear
as literal characters when wildcarding is done but
still be unescaped right after that.
In the compiled internal form, double-quoted
strings containing variable or command
substitutions are already specially broken up to
look, at this stage, like a series double-quoted
strings and substitutions concatenated together.
d.
Variable and command substitutions are done.
e.
Wildcarding is done.
f.
Escape characters are processed.
g.
The series of words is passed to the command as
arguments. (It's at this point, if it's an eval
command, that the argument text is passed back
through the parser and then to the evaluation
logic)
Commands are searched for in this order:
(1)
User-defined procedures.
(2)
Built-in procedures and commands.
(3)
External commands, searched for in the PATH
directories in this order within each
directory:
156
Order of Evaluation
.csh .exe .com .cmd .bat
(.bat files can be run only under OS/2 2.x,
Windows 95 or Windows NT.)
7.
The internal form of each compiled statement is
discarded once it's no longer needed, i.e., if
there's no way you might invoke that code from a
later statement.
For example, once you define a procedure, it's always
accessible; you can call it at any time, so that
compiled code is never discarded unless you redefine
the procedure or explicitly unproc it. But an
ordinary statement typed at the command line could be
re-run (without re-entering it using history or by
retyping it) only if it was part of a larger control
structure or if there was a way to goto it, meaning
there would have to have been a label preceding it.
157
Customizing the Shell
Customizing the Shell
Depending on your tastes and what you're used to (and
whether you come from a DOS or a UNIX background),
Hamilton C shell can be customized in a number of ways.
This section will outline:
1. Various options you have when installing the
shell, including setting it up as the default
command processor,
2. How shell starts up, and how it uses the login.csh
and startup.csh files,
3. How to set the environmental variables, screen
colors and the prompt strings,
4. How to create aliases you always want available,
5. Customizing the cd command and how history
references work, and
6. Telling the shell how it should respond to certain
special situations.
Installation Options
You have a fair amount of choice about where the
various files associated with Hamilton C shell go and
also about how it starts up. You won't necessarily want
to fool with all this when you first install the shell,
but you may want to look at some of this as you get a
sense of your own preferences.
The C shell .exe and .csh files can go anywhere as
long as they're on your search path. Most people find it
most convenient to keep them in a separate directory. We
do suggest it be ahead of the directory containing the
standard more.com on your search path since we provide a
new, vastly improved more.
You choose any directory on any drive as your "home"
directory. The significance of a home directory is that
the shell will make references to it or relative to it
very convenient using the "~" wildcard character. Also,
this is where the shell will look for your login.csh and
startup.csh files. If HOME isn't defined in the
environment when the shell starts up, it defaults to the
159
Customizing the Shell
current directory. It's usually most convenient to
define the HOME variable in your config.sys but if you
prefer, you can pass it to the shell on the command line
using "-C setenv HOME=..." (The "-C" means what follows
is a command.)
Additional customization is usually done with the
login.csh and startup.csh files.
Installing as the Default OS/2 Command Processor
OS/2 gives whatever default command processor you
specify on the PROTSHELL line of your config.sys special
privileges to change its own title bar and, under OS/2
1.3 or 2.x, its own icon. This can be quite useful if
you have a lot of copies of the shell running minimized
and you'd like to know what they're doing.
Under OS/2 1.1 or 1.2, the C shell uses the
undocumented DosSMSetTitle kernel API entry to change its
own title; under 1.3 or 2.x, it uses the new
WinSetTitleAndIcon API to change both the title and icon.
Unfortunately, these API entries are disabled if you're
not running in a window whose root process was the
default command processor.
To install the C shell as the default command
processor, follow the instructions given in the
installation section of this manual. In a nutshell, the
idea is to replace the reference to cmd.exe and any
parameters to cmd.exe on the PROTSHELL or OS2_SHELL
(under 2.x) line with the full pathname of the C shell
plus a "-L" option to indicate it's a login shell.
Next, fix the entries for cmd.exe and the C shell in
the Group-Main or Start Programs menus. To make it a
default command processor, the C shell must be listed
with an "*" (asterisk) for a pathname (on the "Path and
file name:" line if you pull-down "Program" and select
"Properties..." in Group-Main) or else the title bar and
icon changes will be disabled. Also, for some reason, if
you specify any startup parameters (other than
"/K "%*""), that also disables the title and icon
changes. (The "/K "%*"" option has special significance
for the default command processor and is used when OS/2
boots up if it finds a startup.cmd file in the root
directory; otherwise, it's ignored.)
Conversely, you have to change the asterisk path and
any arguments for the cmd.exe entries to the actual path
for cmd.exe and enter whatever arguments (if any) you had
160
Customizing the Shell
been specifying for it on the PROTSHELL or OS2_SHELL line
in your config.sys.
login.csh
login.csh is read only by copies of csh.exe started
with the "-L" option to make them login or root shells.
Typically, this is a new window. startup.csh is read by
each new copy of the shell, even if it's invoked as a
child of the C shell.
The main objective of the login.csh file is to let
you set up those characteristics that are inheritable
from parent to child process but which might not be set
up if you're starting from the Start Programs menu (OS/2
1.1), a Group menu (OS/2 1.2 or 1.3),from the desktop
(OS/2 2.x) or from the Program Manager (Windows NT). In
addition, it lets you do a little special customization
of these highest-level shells.
The important inheritable characteristics are the
environmental variables together with the current
directories and current disk settings.
The Environmental Variables
Most users prefer to create the bulk of their
environmental variables with SET statements in config.sys
under OS/2 or through the Control Panel under Windows NT
(to be inherited by every process on the system) rather
than in login.csh. It means just one copy of the
definitions in one place, so it's easier to make changes.
It also runs faster since it's all set up when the shell
starts; the shell doesn't have read all those commands.
But if you're using an initialization script to set some
of your environmentals for cmd.exe, you'll want to do
that for the C shell also in login.csh.
But there are cases where it's more convenient to set
up some environmental in your login.csh. For example,
you might prefer to set your PATH statement there. Since
the C shell hashes your search path, you'll find it's
much faster finding things even with a very long list of
path directories. (If you actually had 50 or so
directories, the difference in startup time for something
in that last directory would be around 6 seconds or so!)
So you might find it more natural to have a much longer
PATH with the C shell than with cmd.exe.
161
Customizing the Shell
Also, if you were going to use an application that
needed mixed case characters in some of its environment
strings and you were running on OS/2 1.1, you'd want to
define them in login.csh, not config.sys. (Using lower
case characters in config.sys was unreliable on OS/2 1.1;
many users found it caused random system failures, e.g.,
OS/2 crashing while formatting a series of floppies.)
In addition to PATH, the environmental variables used
by Hamilton C shell include HOME, PROMPT1 and PROMPT2,
CSHTITLE, TABS, CDPATH, DRIVEMASK, MIXEDCASEDRIVES,
SWITCHCHARS and a number of screen color configuration
variables.
PROMPT1 or PROMPT2 or their aliases prompt1 and
prompt2 control the prompt strings you'll see for a new
command or a continuation line. CSHTITLE or its alias,
cshtitle, give you similar control over the text in the
title bar.
TABS is used by more.exe, head.exe, tail.exe and
other utilities to expand out any tab characters it sees
into space characters on the screen. For example,
setting TABS = 3 means tabstops every 3 character cells.
CDPATH is used by cd and pushd to specify other
directories in addition to the current directory in which
to search for a subdirectory you're trying to change to.
Its format is the same as that as PATH: a list of
directories separated by colons, but there's no need to
list the current directory.
DRIVEMASK lets you confine the default list of drives
you want searched when you wildcard a driveletter (e.g.,
"*:\hamilton") or reported on by the du, pwd and vol
utilities. The value should be a list of upper- or
lower-case alphabetic characters or ranges of characters
representing the drives you're interested in. For
example, setting DRIVEMASK = cf-h means you want drives
C:, F:, G: and H: reported, assuming they exist.
MIXEDCASEDRIVES is used by ls.exe, by the shell's
fullname and wildcarding functions (including filename
completion), by the current directory functions (cd,
pushd, popd and dirs) and by pwd.exe to tell which drives
you want reported in the actual upper or lower case
characters returned by the OS/2 kernel. If you have HPFS
or NTFS drives, it's possible to create filenames that
have mixed upper and lower characters and you may not
want these all routinely shifted to lower case. You set
MIXEDCASEDRIVES just like DRIVEMASK, giving it a list of
drives. It's also possible to list UNC names that should
be considered mixed case. For example, typing
162
Customizing the Shell
setenv MIXEDCASEDRIVES = a-z,\\
sets all drive a: through z: and all UNC names on all
networked machines as mixed case. Or for example, typing
setenv MIXEDCASEDRIVES = \\alpha,\\ps2\d$
sets all the drives on the alpha machine and only the d:
drive on ps2 as mixed case. You can list as many entries
in MIXEDCASEDRIVES, separated by commas, semicolons or
spaces, as you wish.
SWITCHCHARS is used by the shell and all the
utilities supplied with it to indicate what characters
you intend as introducing one of the option switches. By
default, the C shell tries to satisfy users coming from
both DOS, OS/2 or NT and UNIX backgrounds and will accept
either "-" (DOS-style) or "/" (UNIX-style) as introducing
an option. Folks coming from a straight UNIX background
may find that inconvenient, particularly if they're used
to typing filenames using the forward slash; "cd /foo"
will certainly not do what they want, for example. The
solution is to "setenv SWITCHCHARS = -", causing only
those words that start with "-" to be recognized as
options.
Prompt Strings and Title Bar
Prompt strings and title bars are fairly personal
matters. This really is beauty in the eye of the
beholder only!
For the prompt, there are two situations:
1. The main prompt, when the shell expects a new
command. Set this with PROMPT1.
2. Continuation lines, where the shell is collecting
more text before running something. An example
would be whatever commands you type inside a
foreach loop. Set this with PROMPT2.
When the shell needs to prompt you, it looks at the
appropriate PROMPTx string and evaluates it as if it were
looking at a double quoted string. Any backquoted
strings or variable substitutions it finds there are
evaluated and whatever results is printed. Wildcards are
not replaced nor is the spacing affected. It's quite
literally double-quoted: the shell actually pastes
double quote characters around the string before passing
it to the parser.
163
Customizing the Shell
If you always wanted the same literal text string
displayed, that would be easy but probably not too
interesting:
579 D% set PROMPT1 = "Hello from CSH! "
Hello from CSH! _
The difficult part of setting your prompt is
remembering that if you want a substitution re-evaluated
each time a new prompt is printed, you have to quote the
string when you define it to defer the evaluation.
Here's the wrong, then the right way to create a default
MS-DOS-style prompt with your current directory inside
rectangular brackets.
Hello from CSH! set PROMPT1 = "[$upper(cwd)] " #
Wrong way
[D:\DOUG] cdd c:\ # Notice that the prompt
won't change
[D:\DOUG] set PROMPT1 '[$upper(cwd)] ' # Right way
[C:\] _
Notice how we're using the built-in upper procedure
as if it were a variable substitution with the "$" in
front. When the shell sees it's really a procedure
reference, what's inside the parentheses is evaluated as
an expression list. That's why the cwd variable didn't
need its own "$."
There's really no limit to what you can put inside a
prompt string. You can have command substitution and
special characters. It can even stretch over multiple
lines if you put in carriage return/newline character
combinations:
[C:\] set PROMPT1 = '`date`^r^n$cwd '
Mon Oct 23 1989 11:15:15.03
c:\ _
The title bar environmental variable, CSHTITLE, and
its shell variable alias, cshtitle, work pretty much the
same way as the prompt variables. The title bar is
recomputed every time the shell prompts for a new
command. If CSHTITLE is null, "Hamilton C shell" is
displayed. If CSHTITLE is explicitly unset, the title
bar text inherited at startup is displayed. Otherwise
the CSHTITLE string is evaluated as if it were a double-
quoted string.
The tradeoff to remember in creating a prompt or
title string is that whatever you put there is going to
be run every time you need a new prompt. If you make it
too complex, it'll still run, but it could be annoyingly
slow. Remember that it takes longer to run external
164
Customizing the Shell
programs than to use shell variables or procedures. If
you want something really unusual, try writing a
procedure that calculates and returns the string you
want.
User-Defined Colors
All of the screen colors used by the C shell and any
of the utilities are completely under your control. Here
are the variables that control the color settings and
default values:
Name
Use Default
ADDITIONS Lines added found by diff. Bright Green
COLORS Normal screen colors. White on Black
DELETIONS Lines deleted found by diff. Bright Red
DIRECTORIES Directories listed by ls. Bright
DUPLICATES When filename completion matches Green
more than one name.
FOREIGNFILES Filetypes in a tar file that have no
Bright Red
counterpart on OS/2 or NT.
HIGHLIGHT Current disk or directory. Bright
MATCHFAIL When filename or command completion
Bright Red
doesn't match anything.
MOREEOF End or Top of File in more. Green
MOREERROR Unrecognizable command to more. Bright
Yellow
MOREFILLIN User response to more prompt. White
MOREPROMPT Prompt line in more. Green
MORETOPMEM Top of Memory message from more. Bright
Yellow
READONLYDIRS Directories marked read-only. Same as
DIRECTORIES
READONLYFILES Files marked
read-only. Same as COLORS
SYSTEMDIRS Directories with the System bit on.
Bright Green
SYSTEMFILES Files with the System bit on. Green
You can choose any color combinations you like from
the following set: black, red, green, yellow, blue,
magenta (or blue red), cyan (or blue green) and white.
Foreground colors may also be bright, dim (meaning
simply, "not bright"), blink or reverse. The keyword
"on" introduces background colors. Blink only causes
true blinking full-screen; in a text window, it just
makes the background brighter. Also, yellow is a true
165
Customizing the Shell
yellow only if it's bright. These are system limitations
not related to the C shell.
The names of the colors and the keywords bright, dim,
blink, reverse and on are not case sensitive and may be
typed in any combination of upper or lower case
characters. The names of the environmental variables
themselves must be all in upper case.
If a foreground or background color is left
unspecified, that plane is considered transparent and
inherits the color underneath it.
You can set the colors either from within the C shell
itself by simply typing the appropriate setenv statements
or by including them in your login.csh file. Here's an
example color scheme that's a little more colorful than
the defaults:
setenv COLORS = white on blue
setenv DELETIONS = bright white on red
setenv ADDITIONS = bright white on green
setenv MOREPROMPT = red on white
setenv MOREFILLIN = black
setenv MOREERROR = bright white on red
These settings can be embedded into your Windows 95
autoexec.bat or your OS/2 config.sys as the
corresponding SET statements:
SET COLORS=WHITE ON BLUE
SET DELETIONS=BRIGHT WHITE ON RED
SET ADDITIONS=BRIGHT WHITE ON GREEN
SET MOREPROMPT=RED ON WHITE
SET MOREFILLIN=BLACK
SET MOREERROR=BRIGHT WHITE ON RED
(Notice that if you choose to use SET statements in an
autoexec.bat or config.sys file, you should be sure not
to leave any space around the equal signs. Also, if
you're running OS/2 1.1, type everything in upper case.)
On Windows NT, these settings are made through the
Control Panel's System applet.
Initial Current Directories
The login.csh file is also a convenient place to set
up all you initial current directories. The Start
Programs menu lets you specify a particular current disk
and directory but not what your current directories are
on the other disks when you start up; the current
166
Customizing the Shell
directories on those other disks are always "\".
Generally, people find it convenient to be able to choose
something else and they do this by putting the
appropriate "cd" statements in login.csh.
The final use for login.csh is in setting up certain
local variables that you want different in the login
shell. For example, a login shell normally dumps a
history list when it exits; you may want to turn this off
by setting savehist = 0. Also, you may not want an end-
of-file (from accidentally hitting ^Z once to many
times) to cause the shell to exit; you can tell to insist
on an exit statement by setting ignoreeof = 1.
startup.csh
The startup.csh file is read by all copies of the C
shell, not just login or root level copies. If you don't
want the startup file read, you have to specifically tell
it with the "-F" (Faster startup) option. startup.csh is
read after login.csh whenever both are being read. This
means you can depend on the environmental variables being
set up already when the startup file runs.
startup.csh is a good place to define any aliases or
function key definitions you use, since you'd probably
always want them available but can't pass them in the
environment to any child copies of csh.exe. The
startup.csh file that comes with the shell defines a
number of popular aliases including some for getting at
some of cmd.exe's internal functions; most people add a
few of their own.
The other thing you may want to add to your
startup.csh file are settings for some of the set
variables that customize how the shell runs. These
aren't passed in the environment. Look through the lists
in the Language Reference section. Some you may want to
set differently than the defaults are bsdhistory, cdhome,
chgdisk, escapesym, histchars, ignoreerrors,
ignorestatus, noclobber, nonomatch, nullwords and
tailstatus. A lot of what you choose will depend on
whether you're coming from a DOS or a UNIX background.
Change Directory
If your background is DOS, you'll probably want cd to
just report the current directory if you don't give it an
argument. Those with a UNIX background may want it to
mean "change to the home disk and directory." That's
167
Customizing the Shell
determined with the cdhome variable; the default is a
DOS-style reporting only.
Another customization you may to do is to intercept
cd so that you can capture your last current directory
whenever you change directories:
proc cd(dest)
# Capture the last working directory
@ lwd = cwd
if ($dest == "") then
chdir
else
chdir $dest
end
end
Berkeley-style History and Escapes
Also, if your fingers learned to use the "!-n" style
of history references on a Berkeley UNIX system, you'll
want to set bsdhistory = 1. True die-hard (and perhaps
daring) former UNIX users may want try setting the
escapesym back to a backslash; it'll work with the C
shell but you're on your own with other applications or
tools.
Berkeley Compatibility Mode
Hamilton C shell does implement a substantial number
of significant improvements over the original Berkeley C
shell. By and large, we expect most users to find these
changes welcome. But if you're trying to run a script
developed using the Berkeley C shell or if you simply
want get a more precise "Berkeley mode" interactively,
you can do that.
Following a common convention on UNIX that the first
line of a script can identify the language processor to
be used with it, if the C shell encounters a script that
starts with
#!/bin/csh
it will shift to a fairly precise emulation of the
original Berkeley C shell.
To enter this mode for interactive work, start the C
shell with the "-B" (Berkeley compatibility) option.
168
Customizing the Shell
For more details on differences between the Hamilton
and Berkeley C shells and on Berkeley compatibility mode,
please refer to the Compatibility section beginning on
page 183.
Error Handling
ignoreerrors, ignorestatus, noclobber, nonomatch and
nullwords let you tailor how the shell responds to
various exception situations. They let you determine
whether you think certain things are errors. For
example, should a child process that returns a non-zero
return code but otherwise seems to run okay be considered
an error? If you set ignorestatus = 0, it will be.
Similarly, noclobber lets you intercept accidental
attempts to overwrite an existing file with i/o
redirection. nonomatch tells what should happen if
wildcarding doesn't match anything. nullwords tells
whether you think it's an error to use a subscript that's
off the end of an array.
Calling the C shell from Other Applications
Many applications, e.g., editors, make utilities and
so on, depend on being able to call up the command
processor. For example, make uses cmd.exe to actually
process each command in the make file that it determines
should be run. Most editors (and many other
applications) provide a way of temporarily suspending
themselves and invoking cmd.exe so you can run a few
commands and then exit to return back to the editor.
Usually, these applications look at the COMSPEC
environmental variable to determine the full pathname for
cmd.exe (or command.com under Windows NT). If, like
make, they're just calling it with a single command on
the command line, they use cmd.exe's /C option.
If you'd like to use the C shell instead of cmd.exe
with these applications, set COMSPEC to point to the C
shell instead and use the CSHOPTIONS environmental
variable to tell the C shell to interpret the /C option
flag in a way that's compatible with the meaning cmd.exe
would attach to it:
setenv COMSPEC = c:\hamilton\bin\csh.exe
setenv CSHOPTIONS = -X
Alternately, you can put these definitions right into
your standard environment using the NT System applet in
169
Customizing the Shell
the control panel or by adding these statements to your
OS/2 config.sys:
set COMSPEC=c:\hamilton\bin\csh.exe
set CSHOPTIONS=-X
When the C shell starts up, if it discovers that
COMSPEC points to itself, it will look through the search
path to find the real cmd.exe. This is to make sure it
will still be able to run .cmd files. Since the -X
option is a toggling option, you can still get at the
original meaning of the -C option by typing -XC to toggle
back.
170
Customizing the Shell
171
Summary
Summary
The next few pages show a couple of somewhat more
full-blown examples and outline the contents of the
samples directory. There's also detailed discussion of
the compatibility issues between the Hamilton and
original Berkeley C shells.
Try some experiments. We hope you'll find this
product powerful, fast, reliable and easy to use. We
hope it will help you get your work done faster and
perhaps, more pleasantly.
173
Summary
174
Examples
Examples
Factor.csh: A self-loading procedure which prints a list
of the factors of a number, illustrating the use of
recursion.
proc factor(n)
if (n > 2) then
for i = 2 to floor(sqrt(n)) do
if (n % i == 0) then
echo $i
return factor(n/i)
end
end
end
return n
end
factor $argv
Invoked as:
factor 6324489
It would print:
3
3
702721
To print the factors on one line and time how long it
takes:
time echo `factor 6324489`
The `...` sequence means command substitution: run
what's inside the backquotes and substitute the output
back onto the command line. This would print:
3 3 702721
0:00:00.16
175
Examples
Whereis.csh: A self-loading procedure to find all the
files anywhere on the search path corresponding to the
command name, illustrating pattern matching and file
system tests.
proc whereis(name)
local i, j
if (name =~ "*.*") then
foreach i ($path)
if (i =~ "*\") then
if (-e $i$name) echo $i$name
else
if (-e $i\$name) echo $i\$name
end
end
else
foreach i ($path)
if (i =~ "*\") then
foreach j (.csh .exe .com .cmd)
if (-e $i$name$j) echo $i$name$j
end
else
foreach j (.csh .exe .com .cmd)
if (-e $i\$name$j) echo $i\$name$j
end
end
end
end
end
whereis $argv
Invoked as:
whereis ls
It would print:
d:\hamilton\bin\ls.exe
ls.exe is the file directory lister. Invoked as:
ls -l `whereis ls`
It would show the timestamp and size of the file:
---A-- Mar 13 17:00 57344 d:\hamilton\ls.exe
176
Examples
Samples Directory
The sample C programs and C shell scripts in the
samples directory are meant to help you install or
experiment with Hamilton C shell. Deliberately, they're
relatively trivial. All were created assuming TABS=3.
args.c A simple C program that prints out the
*argv[] (argument) and *envp[]
(environmental variable) arrays. Notice
that wildcarding, variable substitutions,
quoting and command substitutions are done
before the C program is started. If you
do a lot of wildcarding, you can create
and pass very long parameter lists (up 64K
characters on OS/2 or 32K on NT.) Try
some of these commands:
% args "ho"w 'no'w
% args "$cwd" '$cwd'
% args * "*" '*'
% args `whereis more`
% args '`whereis more`'
% args * *\* *\*\* | more
bits.csh A simple self-loading procedure that
calculates the minimum bits required to
represent the argument it's passed as a
binary integer.
blksize.c A simple C program that reads from Stdin,
copying to Stdout, using the specified
blocksize. This program can be useful to
read or write tape devices that only
support certain blocksizes. (Only
supplied with the Windows NT version.)
bumpdate.csh Print the date n number of days forward or
backward from a given date. If only the
bump value is given, today's date is
bumped.
caldate.csh Print the date corresponding to a given
Julian day.
calendar.csh A C shell script for printing out the
calendar for any given month, highlighting
the current date. If no date is given,
this month's calendar is printed.
177
Examples
cl.csh On NT only, run the compiler and linker
for an NT program. Avoids having to fool
with a make file just to compile hello,
world. Works pretty much just like the cl
command on DOS would.
colors.csh Instructions and examples on customizing
the screen colors.
deltaday.csh Print the number of days separating two
dates. If only one date is given, the
difference between it and today's date is
returned.
dumpenv.c This C program writes out the environment
it's passed in the form of setenv
commands. If you're installing Hamilton C
shell for the first time, dumpenv is a
convenient way to snapshot the
environmental variables you've been using
with cmd.exe in a form you can append to
your login.csh file.
duplicat.csh Look for duplicate files anywhere in a
directory tree.
easter.csh A C shell script that calculates when
Easter will occur in any given year. If
no year is given, the current year is
assumed.
f2c.csh A simple C shell script for converting
between Fahrenheit to Celsius.
c2f.csh A simple C shell script for converting
between Celsius and Fahrenheit.
factor.csh The simple factor C shell script shown in
the User Guide. It's intended to show to
show the use of recursion, expressions,
and a self-loading procedure.
finance.csh Another C shell script showing expression
evaluation. This defines a number of
routines for calculating financial
conversion factors, e.g., from present to
future value.
fixup.csh Fixup source files to discard any
extraneous tabs or spaces at the end of
the lines, to ensure that all lines end
properly with \r\n and to ensure that the
timestamps can be exactly represented on a
FAT or HPFS partition.
178
Examples
getprio.c This C program (supplied with the OS/2
version) retrieves and prints its
scheduling priority, demonstrating the
effect of using the eval command to run a
command at a higher or lower priority.
Try these examples:
% getprio
% eval -i getprio
% eval +20 (getprio; eval +20
getprio; getprio); getprio
julian.csh Calculate the Julian day number (number of
days since January 1, 4713 B.C.) for any
given date. If you don't give a date, it
uses today's date.
makecpgm.csh A simple C shell script showing how a
"make" function might be written in the C
shell language. This one rebuilds any
.exe files in the current directory that
are older than the corresponding .c file
or any of the .h files.
mcvisa.csh A simple C shell script that constructs a
special checksum of a credit card number
to tell if the card number is plausible or
not. The checksum used is designed to
catch transposed or incorrect digits. Try
it on the cards in your wallet.
member.csh Test whether the first argument word
appears somewhere in the list given by the
second argument.
myecho.c A variation on the built-in echo command
that prints its *argv[] (argument) list
with quotes around each word it's passed
and tells the total character count. Try
these examples:
% myecho now is the
% myecho "now is" the
% myecho `ls`
% myecho `echo`
% myecho `echo hello`
% myecho * *\* *\*\* | more
newfiles.csh List all the files or directories in the
current directory that do not occur in the
specified directory.
postage.csh Calculate the U.S. first class postage
required for a given weight in ounces.
179
Examples
posxpath.csh Convert ordinary filenames to POSIX
format. (Supplied with the NT version
only.)
rcode.c A trivial C program that just prints, then
exits with the return code value you pass
it. You can use this routine to see how
the status variable is set and also, how
the ";", "||" and "&&" statement
connectors work. Try these examples:
% rcode
% calc status
% rcode 1
% calc status
% echo $status
% echo status
% rcode 2
% calc status
% rcode 0 || rcode 1
% rcode 1 || rcode 2
% rcode 0 && rcode 1
% rcode 1 && rcode 2
% rcode 0; rcode 1
% rcode 1; rcode 2
rcode also illustrates another aspect of
return codes to consider: if you use C
library stdio (as rcode.c does) and you
exit with a non-zero return code, stdio
thinks it was an error and discards
anything in the stdio buffers. In the
following example, stdio writes to the
screen are unbuffered so it works; but
pipes are buffered, so nothing gets
written to it:
% rcode 1
1
% rcode 1 | more
--- End of file ---
%
If you're writing an application that uses
return codes, you should remember to
explicitly flush the buffers with stdio
fflush() or use the kernel calls directly.
renet.csh A script for attempting to reconnect any
unavailable LanMgr network resources.
sh_2_csh.csh A script for converting Bourne or Korn
shell scripts into Hamilton C shell
180
Examples
scripts using a set of sed scripts
contained in the sh_2_csh directory.
sizeof.csh A short C shell script that calculates and
prints the cumulative size of any number
of files or directories.
sunrise.csh Calculate sunrise and sunset times given
the date, latitude and longitude.
timestmp.csh Extract a timestamp from a file or
directory in the format needed by
touch.exe.
trapz.csh A C shell script that does numeric
integration using the trapezoidal rule.
ts.csh A C shell script that searches for
occurrences of a simple string in all the
files with a given extension anywhere in a
directory tree.
unixprof A directory of tools for profiling a
source tree, tallying up all the calls to
the UNIX system and library routines.
viopaste.c A short C program (supplied with the OS/2
version) to enable pasting into a
Presentation Manager text window under
OS/2 1.2 or 1.3.
weekday.csh Print the day of the week corresponding to
any given date.
winerror.csh Print the Win32 message corresponding to a
given error code. (Only supplied with the
Windows NT version.)
181
Compatibility
Compatibility Guide
This section details the specific differences between the
Hamilton C shell and the original UNIX C shell.* It also
describes the Hamilton C shell's Berkeley compatibility
mode, used for running Berkeley C shell scripts.
Berkeley 4.3 Buglist problems have been fixed.
1.
Shell procedures have been provided as a more
powerful alternative to the clumsy argument mechanism
for aliases.
2.
Commands typed within loops or other control
structures are properly added to the history list.
3.
Control structures are recursively parsed, allowing
piping between them. For example:
foreach i (a b c) echo $a; end | wc
properly displays
3 3 12
4.
Any of the ":" editing modifiers can be used on any
substitution. Also, a space inside the search string
in a ":s/.../.../" command will match the space
between two words. In the UNIX C shell, only certain
modifiers could be used on a given type of
substitution and it is not possible to perform a
search/replace that crossed word boundaries.
The language has been regularized.
1.
The set, setenv and alias commands will now accept
the same basic syntax. The UNIX C shell had a number
of anomalies: an "=" sign was required for a set but
not for setenv and alias; parenthesis were required
around a word list for a set but not for setenv and
* The references used for comparison are the Berkeley
4.3 UNIX User's Manual: Reference Guide (University of
California, 1986) and The UNIX C Shell Field Guide by
Gail and Paul Anderson (Prentice Hall, 1986.)
183
Compatibility
alias; the set statement ignored all but the first
argument word but alias would not, etc.
2.
Variables or word lists are always indexed counting
the first word as element zero. The UNIX C shell
counted from zero when indexing with ":n" notation
but from one when using "[n]" notation. argv[0] is
the first argument word, not the name of the shell
script being executed. The name of the script is
kept in the local variable $scriptname. This can be
overridden by setting the inheritable per-thread
variable bsdargv = 1, causing argv[0] to be the name
of the script.
3.
In keeping with the desire to consistently index from
zero, the last command entered into the history list,
"!!", is considered the 0-th element; "!-1" is the
line before it. The UNIX C shell considered these to
be the same. A built-in variable, bsdhistory, is
provided for those whose fingers prefer the Berkeley
numbering convention: if you set bsdhistory = 1,
"!!" and "!-1" are the same.
4.
Where an expression is expected, conventional high
level language syntax is now acceptable. The UNIX C
shell required spaces around any expression
operators, a variable reference required a "$" to
introduce it, parenthesis were required to avoid
confusing "less than" with i/o redirection, etc.
What had to be typed as
@ i = ($j + 3 * $k < 10)
under the UNIX C shell can now be typed (for example)
as
@ i = j+3*k < 10
(The original UNIX C shell expression syntax is still
entirely acceptable and will still produce correct
results.)
5.
Inside a "[...]" array index, the shell always looks
for an expression, never an editing-style word
select. Syntax and keying rules are the same as with
any expression.
6.
The case statement now accepts an expression to be
matched rather than only a pattern. (To specify a
static pattern, enclose it in quotes.) To determine
a match against a case clause, the case expression is
evaluated, converted to a string and then used as a
pattern to compare against the switch value.
184
Compatibility
7.
The various different end statements used by the UNIX
C shell, end, endif and endsw, have been replaced by
a single end statement. Similarly, the two break
statements, break and breaksw, have been replaced
with a single break statement. For compatibility
with existing scripts, the obsolete keywords are
implemented as aliases in the default startup.csh
script supplied with the product.
8.
Since Hamilton C shell is free format (i.e., new
statements need not begin on a new line), the UNIX C
shell convention of chaining if statements with a
single end if the else and if are on the same line
isn't sensible (though it is supported in Berkeley
Compatibility Mode explicitly for compatibility).
Instead, an elif keyword has been added.
9.
The obscure use of several break statements in a row
on a single line to break out of several levels of
control statements at once has been eliminated. In
its place, a label may be specified as an operand to
indicate the control structure out of which it
should break.
Modern compiler technology has been employed.
Statements are parsed and compiled into an internal
form before any substitutions or other evaluation is
attempted. This offers an enormous performance
improvement, particularly when iteration is involved.
(The UNIX C shell would actually reparse each statement
inside a foreach loop each time through the loop.)
If command- or variable-substitution creates any of
the following reserved words or tokens, the special
semantic meaning will be lost since substitution is done
after parsing of statement structure. Instead, they will
simply be treated as character strings. These reserved
words are:
Introducing a clause in a structured statement:
alias elif if setkey unproc
break else local source unset
by end onintr switch unsetenv
calc eval proc then unsetkey
case exit repeat time until
continue for return to while
default foreach set unalias @
do goto setenv unlocal
Anywhere:
185
Compatibility
( ) < > & | ;
In an expression:
+ - * / % =
Similarly, labels cannot be run-time evaluated to see
what the label on a statement is; it must be evaluated
when the statement is first parsed.
Extensions
1.
Command line editing with the arrow keys, etc., and
the setkey statements are new.
2.
The procedure mechanism, the proc, unproc and return
statements and the various built-in procedures are
new.
3.
Local variables and the local and unlocal statements
are new.
4.
The use of color highlighting to indicate exception
situations in filename or command completion is new.
5.
The for statement, providing numeric iteration, and
the calc statement, which writes the result of
expression evaluation to stdout, are new.
6.
The "**" and "**=" exponentiation operators are new.
7.
Floating point arithmetic is new.
8.
The path hashing mechanism is substantially less
sensitive to blindspots caused by creating a new
executable in one of the path directories and not
manually specifying rehash. The UNIX C shell would
not be able to find the new file; this shell makes a
second pass through the path directories whenever
hashing fails, looking for this sort of problem
before it reports failure. If it finds a blindspot,
it automatically rehashes that directory.
9.
History references are allowed in the inline text
supplied with the "<<" i/o redirection mechanism.
Also, the inline text is remembered in the history
list, each line as a single word. This avoids the
user having to remember and retype the inline text
any time one of these statements is recalled from the
history list or if the history list is dumped for use
in a script file.
186
Compatibility
10.
Exclusion ranges, e.g., "[^a-z]," can be used in a
wildcard pattern.
11.
Escape sequences to encode special characters (e.g.,
"^a" for audible bell or "^b" for backspace) are
recognized in the arguments to any command, not just
echo. Because this processing is internal to the
shell, it is not necessary to type two escapes in a
row to access this feature. (Refer to the echo
command help screen for a complete list.)
12.
Argument lists passed to a child process can be much
larger than are allowed under UNIX. The UNIX C shell
allows only roughly 6K characters to be passed,
depending on the revision level; this shell allows up
to 64K to be passed to a child process under OS/2 or
32K under NT, the kernel limits on these systems.
There is no command line limit to an internal command
such as echo. This is of particular importance when
wildcarding is used heavily.
13.
Quoted strings are shown in the history list exactly
as they would have to be typed. (The Berkeley UNIX C
shell marked a character as quoted by setting its
high-order bit; setting aside portability issues, it
had the side-effect of not being visible in the
history list.)
14.
Parentheses in an argument list to an executable
statement need not be escaped, so long as they are
matched. Semicolons, i/o redirection symbols, etc.,
inside these parentheses are treated simply as text
and are passed straight through to the application.
15.
The ":b" (base), ":#" (count), ":A" (alternate
shortname) ":L" (longname), ":m" (mixedpath) and ":M"
(mixedcase fullpath) editing operators are new.
16.
The indefinite directory wildcard construct, "...",
is new.
Restrictions and unimplemented features
1.
Job control is not supported. Job control is not
currently feasible under Windows 95, Windows NT or
OS/2 because once one thread from any process within
a window has started to read the keyboard, the read
can not be interrupted. (Fortunately, one can always
open more windows.)
187
Compatibility
2.
The use of "\!" inside a prompt string to get the
statement number is not supported. Use $@ or
$stmtnumber instead.
3.
The following statements, all fairly specific to
UNIX, are not supported: alloc, glob, limit, notify,
stop.
Adaptation for OS/2 and Windows NT
1.
OS/2 and Win32 do not provide a fork( ) call for
inexpensively cloning an independent copy of a
running process, complete with its own separate
memory image. Instead, OS/2 and Win32 provide a
faster alternative called threads, which creates an
separately scheduled flow of control through the
memory space of a single process.
In general, Hamilton C shell spawns a new thread
anywhere the Berkeley UNIX C shell would have used a
process. Using a new thread instead of a new
invocation of Hamilton C shell saves over a second
each time. Individual threads manage their own
notions of current directories and current disk and
certain per-thread variables but the dictionary of
aliases, procedures and most variables is shared
among all threads.
The result is that background activities and C shell
scripts can change variables, define procedures,
etc., for use by the other threads. For example,
procedures can be written as self-loading scripts.
(See the whereis.csh file for an example.)
2.
OS/2 and NT conventions are followed: either the "\"
or the "/" characters can be used in a filename; the
"^" character is normally the escape character;
directories in the PATH environment variable are
separated by semicolons, etc.
3.
Labels cannot be a single letter. (This is to avoid
confusing the drive letter in the pathname of an
executable file as a label.)
4.
Since OS/2 and most NT filenames are case-
insensitive, they are routinely translated to lower
case for better readability. (This can be overridden
using the MIXEDCASEDRIVES variable.)
5.
Executable files are recognized by their extension.
The following extensions are recognized (in this
order): .csh, .exe, .com, .cmd, .bat. .csh files
188
Compatibility
are interpreted as C shell scripts by a new thread,
.exe and .com files are executed with the DosExecPgm
and DosStartSession kernel functions under OS/2 or
with the CreateProcess kernel function under Windows
95 or Windows NT. .Cmd files are interpreted by a
child process running cmd.exe. .Bat files are
passed to a Virtual DOS machine (VDM) under OS/2 2.x
or to cmd.exe under Windows NT.
6.
PROMPT1 and PROMPT2 variables are used to set the
primary and secondary prompt strings. Using the UNIX
C shell variable PROMPT would have conflicted with
cmd.exe's use of the same name and would have meant a
nonsense prompt string any time either command
processor was invoked by other.
7.
The following startup or other files have been
renamed to be more consistent with OS/2 and NT
filename conventions: ~/.cshrc as ~\startup.csh;
~/.login as ~\login.csh; ~/.logout as ~\logout.csh;
and ~/.history as ~\history.csh. The ~\login.csh
file is read before, rather than after the
~\startup.csh file. When starting the shell as a new
session, very little environmental information may be
passed; the login.csh is more usefully the first
file read in this situation. When starting a
subshell, either from csh.exe or cmd.exe, the
environment is presumably already set up.
8.
The comment character, #, must be followed by some
white space to be considered the start of a valid
comment (except in Berkeley Compatibility Mode).
(That's because # is a legal character in a filename
under both NT and OS/2.)
Berkeley Compatibility Mode
Berkeley Compatibility Mode provides fairly strict
compatibility with the original BSD C shell. Triggered
by a script that starts with #!/bin/csh or interactively
if the shell is invoked with the -B option, it causes the
C shell to process statements in a more fully Berkeley-
compatible fashion. (Scripts that do not start with
#!/bin/csh will still be processed according to Hamilton
C shell rules, even if the -B option is used to request
Berkeley compatibility interactively.) In compatibility
mode:
1.
The status variable will reflect the return code from
the rightmost stage of a pipeline. The tailstatus
variable will be ignored.
189
Compatibility
2.
All the shell variables will be snapshotted and all
new variables made local to the thread.
3.
Berkeley-style $var[...] indexing notation will be
used, where the indexing is by word selection
operators (like the :-editing operators) rather than
by expression.
4.
All variable arrays (except argv) will start with
element 1. Accessing element 0 will give a null.
5.
$0 or $argv[0] will be the scriptname. $argv will be
the rest of the argument vector. The bsdargv
variable will be ignored.
6.
The # character will not need to be followed by white
space to be considered the start of a comment.
7.
The patterns in a case test (inside a switch) will be
strings and need not be quoted, rather than arbitrary
expressions. Also, the switch value is evaluated as
a wordlist which may contain variable or command
substitutions and wildcards and then rendered as a
string.
8.
endif and endsw will be predefined aliases for end
(but only when closing an if or switch,
respectively). break will only break out of an
enclosing loop (foreach or while). breaksw will only
break out of a switch statement.
9.
The special-case use of "else if" on a single line is
recognized as a way to chain several if statements
together with a single endif at the end.
10.
"set foo" and "setenv foo" will set foo to a null
string, not dump its value.
11.
/ and /= will perform integer division.
12.
The right operand of the =~ and !~ pattern matching
operators will be taken as a word which may contain
wildcards.
13.
In an expression, a variable name must be preceded by
$. If it isn't, it'll be taken as a literal string.
14.
:-style editing operators will not be recognized
after a command substitution.
These changes should allow most scripts to run
without problems. However, there will still be a few
differences:
190
Compatibility
1.
The escape character will still be controlled by the
escapesym variable (shared across all threads), which
defaults to ^, not \.
2.
Environmental variables will still be shared.
Changing them in a script will change them as seen by
the parent.
3.
The special meaning of several break statements on
one line will not be supported.
4.
The following commands are not supported: bg, exec,
fg, glob, jobs, limit, nice (but eval gives similar
functionality), nohup, notify, stop, suspend, unlimit
and %job.
5.
No attempt is made to process any command-line
arguments following the #!/bin/csh at the start of a
script, nor is any attempt made to implement the
generalized UNIX convention to allow other shells or
language processors to be invoked based on the
contents of that first line.
191
Compatibility
192
Language Reference
Language Reference
Basic Statements
Same as cmd.exe: a file reference + arguments.
Examples: notepad hello.txt
cp hello.* a:
Individual statements are parsed into a series of
words separated by white space (spaces or tabs) or
these special tokens:
& | ; > < ( ) && ||
>> << >& >! >&!
Wildcarding is done by the shell before invoking the
child.
Under OS/2, up to 64K of environmental and 64K of
command-line argument data can be passed to a child
process.
Under Windows NT or Windows 95, up to 32K of
command-line data can be passed. These are the
limits of the kernels, not the C shell; there is no
limit on overall command line length in the C shell
itself.
Hamilton C shell maintains a hash structure which
allows it to quickly search for a suitable .csh,
.exe, .com, .cmd or .bat file (on OS/2 2.x, Windows
NT or Windows 95) in that order in each of as many
as 256 path directories.
193
Language Reference
Condition-Testing
Hamilton C shell provides both if and switch
constructs. The if statement comes in both short
and long forms. The long form uses a then keyword
and allows an optional else clause.
if ( expr ) then
statement_list
else
statement_list
end
if ( expr ) then
statement_list
end
The short form, which must be typed on one line,
dispenses with the then keyword and accepts a single
statement to be executed if the condition is
satisfied.
if ( expr ) statement
Where an expression is expected, a conventional high
level language syntax is accepted: e.g., names
refer to variables, "*" means multiply, not wildcard
and ">" means greater than, not i/o redirection.
194
Language Reference
if statements can also be chained using the elif
keyword. The last if in the chain may be either a
short- or a long-form if statement.
if ( expr ) then
statement_list
elif ( expr ) then
statement_list
else
statement_list
end
if ( expr ) then
statement_list
elif ( expr ) then
statement_list
end
if ( expr ) then
statement_list
elif ( expr ) statement
In a switch statement, expressions are compared by
pattern match: the case expression can be a string
with wildcard characters. Comparisons are made down
the list of alternatives until one matches. All
following statements are executed until a break is
encountered. A default clause is optional but is
always satisfied if no other case matches.
switch ( expr )
case expr:
statement_list
case expr:
statement_list
default:
statement_list
end
195
Language Reference
Iteration
The foreach statement is intended for iteration over
a list of words, often specified by wildcarding.
foreach name ( wordlist )
statement_list
end
The for statement offers the more conventional
numeric iteration. Multiple iteration ranges,
separated by commas, can be specified on the for
statement.
for name = expr [ to expr ] [ by expr ] do
statement_list
end
The while statement iterates so long as the control
expression continues to evaluate as non-zero.
while ( expr )
statement_list
end
The repeat statement has two variations. The first
provides for the iteration of a single statement an
integer number of times.
repeat number statement
The second form of the repeat iterates until the
control expression evaluates as non-zero, allowing
it to exit.
repeat
statement_list
until ( expr )
196
Language Reference
Procedures
Procedures defined by the proc statement can
recursively call other procedures. They can be
referred to inside an expression or as a new
command, in which case any value returned is written
to stdout. There is an implicit return statement at
the end of every procedure definition.
proc name ( [ namelist ] )
statement_list
return [ expr ]
end
The proc statement with no arguments prints a list
of all the procedures that have been defined; if the
argument is a name, that one procedure is listed; if
the argument is a pattern, all procedures whose
names match the pattern are listed.
proc
proc name
proc pattern
unproc namelist (where namelist is a series of names
separated by commas) discards the specified
procedures. unproc pattern discards all procedures
whose names match the pattern are discarded.
unproc namelist
unproc pattern
197
Language Reference
Aliases
Aliases provide a way of conveniently recalling
frequently used commands with a user-defined
shorthand name. The alias statement associates a
list of words with an alias name. The "=" is
optional. Parentheses are used around the wordlist
if it contains special characters such as i/o
redirection operators that should be part of the
alias definition.
alias name [ = ] ( wordlist )
alias name [ = ] wordlist
alias name prints the definition of that alias;
alias pattern prints the definitions of all the
aliases whose names match the pattern. alias
without any arguments prints the definitions of all
the aliases.
alias
alias name
alias pattern
unalias namelist discards the specified aliases;
unalias pattern discards all the aliases whose names
match the pattern.
unalias namelist
unalias pattern
198
Language Reference
Variable and Expression Manipulation
The @ and calc statements will each calculate the
value of an expression; the @ statement does it
silently while the calc statement writes the result
to stdout.
@ expr
calc expr
The set, setenv and shift statements manipulate
variables as words rather than expressions. set
defines a variable that's shared between all threads
in the shell; setenv puts it into the environment
which is inherited by child processes.
set named_ref [ = ] ( wordlist )
set named_ref [ = ] wordlist
setenv named_ref [ = ] ( wordlist )
setenv named_ref [ = ] wordlist
shift [ name ]
set or setenv with no operands prints a list of all
defined variables of that type. set name or
setenv name with no arguments prints the value of
the named variable. set pattern or setenv pattern
prints the values of all the variables whose names
match the pattern. To resolve the ambiguity between
a pattern and an indexed variable reference, pattern
arguments to set or setenv cannot use the "[" as the
first wildcard character in the string.
set
set name
set pattern
setenv
setenv name
setenv pattern
199
Language Reference
unset namelist or unsetenv namelist discard the
specified variables. unset pattern or
unsetenv pattern discard all the shell or
environment variables, respectively, that match the
pattern.
unset namelist
unset pattern
unsetenv namelist
unsetenv pattern
(Under Windows NT and Windows 95, environment
variable names are case-insensitive, so any patterns
used with setenv or unsetenv are also considered
case-insensitive.)
Local Variables
The local command lets you define a list of variable
names that you don't to share with other routines or
other processes or threads (except your own child
threads). When you define a local variable it hides
any previous definition from any outer statement
list. (But you are not permitted to redefine any of
the built-in set or setenv variable names.)
local namelist
local
local pattern
The namelist should be typed with commas between the
names. When you create a new local variable, its
initial value is always a null string. local with no
operands reports the currently defined and
accessible local variables, if any. local pattern
lists all the local variables whose names match the
pattern.
200
Language Reference
When you spawn a child thread either implicitly,
e.g., to run the second or following stage of a
pipeline or explicitly, by typing an ampersand at
the end of a command to run it in the background all
your current local variables are snapshotted and
copied to the child. If, following that, either the
parent or the child changes the value of any of
these local variables, it affects only its own copy.
Local variables are automatically discarded as soon
as execution leaves the statement nesting level in
which the variable was created. You can also
explicitly discard local variables using the
unlocal command.
unlocal namelist
unlocal pattern
unlocal namelist discards the specified local
variables. unlocal pattern discards all those whose
names match the pattern.
In all other respects, local variables act just like
any other variables, though you may find they're
slightly faster since the shell doesn't need to
semaphore its use of them.
201
Language Reference
Function Keys
setkey command
The setkey command lets you define a list of words
that should be stuffed back onto the command-line
whenever you press a particular function key. The
syntax is exactly the same as used in the set,
setenv and alias commands:
setkey fkey [ = ] ( wordlist )
setkey fkey [ = ] wordlist
where fkey is any of the function keys f1 (or F1)
through f12 (or F12.)
setkey with no operands reports the current function
key bindings, if any. setkey pattern lists the
bindings for any keys whose names match the pattern.
The corresponding unsetkey command discards key
bindings:
setkey
setkey pattern
unsetkey fkeylist
unsetkey pattern
The fkeylist should be typed with commas between the
keys. For example:
unsetkey f1, f2
202
Language Reference
Using the Function Keys
Key
Meaning
Clear the command line, post the text
bound to this key and execute the
command.
Alt- Insert the text bound to this key at
the cursor location but don't execute
it yet.
Ctrl- Clear the command line and post the
text bound to this key but don't
execute it yet.
Since the function key's bound text is written back into
the command line inside command line editor, the
substitution happens ahead of any parsing of the command
line into words or expansion of history "!..." or "%..."
references so it is possible to meaningfully embed these
kinds of references into the key binding.
203
Language Reference
Miscellaneous Statements
Statement
Function
drive: Change current drive.
label: statement Define a label.
(statement_list ) Group a list of statements, saving
and restoring the current
directory during execution
break [ name ] Exit from the named or, by
default, the innermost switch,
foreach, for, while or repeat
statement.
continue [ name ] Continue with the next iteration
of the named or innermost foreach,
for, while or repeat.
exit [ expr ] Exit from this thread or, if this
is the main thread, from the C
shell.
goto name Continue at the labeled statement.
onintr statement Define the action to be taken if
an interrupt is signaled.
Whatever's running is interrupted
all the way back up to the block
in which the onintr was defined.
That statement is run in the
current thread and execution
continues with the next statement
in the block where the onintr was
defined. When execution leaves a
block in which an onintr is
defined, the previous onintr (if
any) again takes effect. To
ignore or defer interrupts, use
the irqmask variable.
source wordargs Read and process statements from a
file as if they were typed into
this thread.
time statement Execute the statement and report
how long it took.
204
Language Reference
# Comment text up to the end of the
line. (To be recognized as a
valid comment, the # must be
followed by at least one space or
tab.)
205
Language Reference
Statement Relationships
In order of decreasing precedence:
Operator
Meaning
( ) Grouping
> >! >& >&! >> >>! >>& >>&!
< <<
I/O Redirection
| |& Piping (stdout only or stdout +
stderr) between concurrent
operations
... & Background thread or process
&& || Conditional execution: only if
first succeeds or only if first
fails
; Serial execution
I/O Redirection
Operator
Meaning
> >! >& >&! Output to a file ("!"
allows an existing file to be
overwritten; "&" redirects both
stdout and stderr.)
>> >>! >>& >>&!Append to a file
< In from a file
<< string Inline data: the text on the
following lines, up to the line
containing only the specified
string will be fed as stdin to the
statement. Unless part of string
is escaped or single, double or
backquoted, command and variable
substitution will be done on the
inline text.
206
Language Reference
The grammar is completely recursive, so statements of
arbitrary complexity can be freely nested, conditionally
executed, piped or redirected.
207
Language Reference
Expression Operators
In order of decreasing precedence:
Operator
Meaning
( ) Grouping or Procedure call
arguments
{ } Run the enclosed statement list and
return 1 if it succeeds or 0
otherwise.
[ ] Array indexing. (The first element
is element 0.)
-A -C -D -H -R -S -d -e -f -o -w
-x -z
File system tests
++ -- Prefix and postfix
increment/decrement
~ - ! + Bitwise, arithmetic and logical
complements and unary plus
** Exponentiation
* / % // Multiplication, Division, Remainder
and Integer Division
+ - Addition and Subtraction
<< >> Bit Shifting
== != =~ !~ < <= >= >
Relation-testing and pattern-
matching operators
& Bit And
^ Bit Xor
| Bit Or
&& Logical And
|| Logical Or
?: Conditional selection
208
Language Reference
= += -=
*= /= %= //= >>= <<= &=
^= |= **=
Assignment operators
Expressions result in sensible types, considering both
the types and the values of the operands. For example,
10/2 returns the integer 5 but 5/2 produces the floating
point value 2.5. Also, the integer 1, the floating point
value 1.0 and the string "1" all compare equal.
209
Language Reference
File System Tests
The operand of a file system test is interpreted as a
word, not an expression, and may involve wildcarding. If
wildcarding produces more than one match, the test is
done on the first one.
Prefix Operator
True if
-A Archive Bit Set
-C File or Directory is Compressed
-D -d Directory
-H Hidden File or Directory
-R Read-only File or Directory
-S System File or Directory
-e File or Directory Exists
-f Ordinary File
-o Ownership (Same as Existence on an
OS/2 or NT FAT file system)
-r Readable (Same as ordinary file on
an OS/2 or NT FAT file system)
-w Writable (Not Read-only and not a
directory)
-x Executable (Has a .csh, .exe, .com
or .cmd extension and, if it's an
.exe or a .com file, appears to be
a valid OS/2 or NT binary
executable.)
-z Zero-length File
Example: if (-d $a) then
echo $a is a directory
end
210
Language Reference
Special Devices
Name
Use
\\.\a: The diskette as a raw device.
(Windows NT.)
\\.\tape0 The tape drive as a raw device.
(Windows NT.)
aux_ The auxiliary port.
clock$_ The OS/2 system clock.
con The OS/2 console. This is the text
window the shell is running in.
Reading from it reads the keyboard;
writing to it writes to the screen.
conin$ The Win32 console keyboard. A
read-only device. (Inheritable
under Windows 95 but not under
Windows NT.)
conout$ The Win32 console display. A
write-only device. (Inheritable
under Windows 95 but not under
Windows NT.)
com1 .. com7 The various async communication
ports you may have. They can be
read or written.
kbd$ The OS/2 keyboard. A read-only
device.
lpt1 .. lpt4 The line printer ports. (Windows
NT and OS/2 only.)
nul The null device. Reads return
end-of-file; writes are discarded.
prn The print spooler queue.
pointer$_ The OS/2 mouse and on-screen
pointer combination. Reads from
the mouse; writes to the screen.
screen$ The OS/2 text window. A write-only
device.
211
Language Reference
Hamilton C shell recognizes the OS/2 and Windows NT
special device names regardless of whether they are typed
in upper or lower case and regardless of whether there is
a trailing colon. For example, COM1:, COM1 and com1 all
refer to the same device. Not all devices will be
installed on any particular machine. Devices marked with
_ should only be accessed with some caution.
212
Language Reference
ANSI Escape Sequences
The C shell and all the utilities that come with it
generate the following ANSI escape sequences when writing
to a file or pipe. When writing to the console, they
interpret these sequences. In this table, Esc refers to
the 0x1b escape character.
Escape Sequence
Meaning
Esc [ row; col H Set cursor position, counting from
(1, 1) in upper left-hand corner.
Esc [ row; col f Set cursor position, counting from
(1, 1) in upper left-hand corner.
Esc [ n A Cursor up n rows.
Esc [ n B Cursor down n rows.
Esc [ n C Cursor forward n rows.
Esc [ n D Cursor backward n rows.
Esc [ s Save cursor position.
Esc [ u Restore cursor position.
Esc [ 2 J Erase display and move cursor to
upper left-hand corner.
Esc [ K Erase to end of line.
213
Language Reference
ANSI Escape Sequences
Escape Sequence
Meaning
Esc [ g m Set graphics rendition (color,
etc.). More than one change can be
specified by using semicolons
between each g value:
Basic attributes:
0 Normal
1 Bright
2 Dim
5 Bright background
7 Reverse video
8 Hidden
Foreground colors:
30 Black
31 Red
32 Green
33 Yellow
34 Blue
35 Magenta
36 Cyan
37 White
Background colors:
40 Black
41 Red
42 Green
43 Yellow
44 Blue
45 Magenta
46 Cyan
47 White
214
Language Reference
Wildcarding and Pattern Matching
Characters
Meaning
? Match any single character,
including "." but not "\" or "/".
* Match any number of characters,
including "." but not "\" or "/".
[a-z] An example range: match any
character a through z.
[^a-z] An example exclusion range: match
any character not in the set a
through z.
{a,b}c Alternation: generate both ac and
bc.
... Indefinite Directory: match any
number of directory levels -- zero
or more -- whatever it takes to
make the rest of the pattern match.
Patterns are used both for traditional filename
wildcarding in word mode and for examining strings in
expression mode. Patterns are nestable arbitrarily and a
recursive comparison algorithm is used to guarantee a
sensible result no matter how complex the pattern. For
example: *r* or even *\[a-c]*.[ch] operate sensibly.
Even drive letters can be wildcarded, e.g., *:winnt*.
Filename wildcards can be used wherever a word is
expected and will match any filename except "." and ".."
unless it's marked "hidden." (To allow wildcarding to
match hidden files, set nonohidden = 1.) Quoting the
word prevents wildcarding. Since filenames are not case
sensitive, filename wildcarding isn't either.
A pattern can also be used to examine a string in a
switch statement or with the "=~" (pattern matches) and
"!~" ( pattern fails) expression operators. In this
context, the pattern must be inside quotes, since
otherwise it would be parsed as an expression, with "*"
being viewed as the multiply operator, etc. When
examining a string with a pattern that uses alternation,
the pattern "matches" if any of the alternatives matches.
When matching strings, case does matter.
When using a pattern to examine a string with "=~" or
215
Language Reference
"!~" or with a switch, the string being tested is the
left operand and the pattern is on the right.
Filename Completion
Filename completion lets you type just the first part of
a filename and have the shell fill in the rest. The
variations are: using the F key for basic filename
completion, the D key if you want all the duplicates
listed or Tab or Shift-Tab (BackTab) to move forward or
backward through the list one-by-one.
Key
Meaning
Alt-F or Ctrl-F Filename completion. Appending the
"*" wildcard character onto the end,
use the previous word as a wildcard
pattern. If it matches a single
file, substitute it in with a space
following. (If you don't want a
space following, use the -N option
when you start the C shell.)
If there were multiple matches, but
they all had some common front-part
that fully "used up" the pattern,
substitute in just that common front-
part and show it in the color
specified by the DUPLICATES variable
(default is green).
If substitution wasn't possible,
highlight the pattern in the color
specified by the MATCHFAIL variable
(default is bright red). (Any
highlighting color is turned off when
you press the next keystroke.)
Alt-D or Ctrl-D Duplicate completions. Same
wildcarding, but if there are
multiple matches, show them all with
a space following. (Here again, if
you don't want a space following, use
the -N option when you start the C
shell.) If there were no matches,
highlight the pattern in the color
specified by the MATCHFAIL variable
(default is bright red).
Next filename. Move one-by-one
through the list of matching
216
Language Reference
filenames. After the last, paste the
original back in place, highlighting
with the MATCHFAIL color, then
continue, with the next Tab, cycling
through the list again. (To type an
ordinary tab character, use Ctrl-
. Alternately, if the C shell
is started with the -T option, the
Tab key generates a plain tab
character and Ctrl- is the
filename completion key.)
Shift- Previous filename. Same as Tab, but
cycling in reverse through the list.
217
Language Reference
Command Line Editing
Key
Meaning
Accept the command as typed. Move to the
end (if not there already) and carriage
return to a new line.
Beginning of command line.
End of command line.
Up one command in the history list. Each
time it's pressed, it displays the
preceding entry in the history list. Any
"!..." or "%..." history references in the
original text will have been fixed up
unless it was the immediately preceding
command and it had one these references
that failed. If already at the first
entry, the command line is highlighted in
bright red.
Down one command line in the history list.
If already at the latest entry, the
command line is highlighted in bright red.
One character left.
One character right.
Ctrl- Move to the upper-leftmost character in
the current screenful if the command is
long enough that it actually wraps across
several screens.
Ctrl- Move to the lower-rightmost character in
the current screenful.
Ctrl-
Up one row on the screen if the command is
long enough that it runs over a row.
Ctrl-
Down one row on the screen.
Ctrl-
Backup word.
Ctrl-
Forward word.
Alt- Delete all preceding characters on the
command line.
Alt- Delete all following characters.
Alt-
Delete up one row on the screen if the
command runs over a row.
Alt-
Delete down one row.
218
Language Reference
Alt-
Delete preceding word.
Ctrl-
Alt- Toggle insert/overstrike mode. When
inserting, the cursor is slightly thicker.
Ctrl-
Insert the next word from the last section
of deleted text. When it reaches the end
of the deleted text, it starts over.
Alt- Insert all the rest of the previously
deleted text.
Backup to one past the last history
reference. (Repeatedly typing
is a convenient way of picking up
a whole series of commands from history.)
Forward to the newest entry in the history
list.
Clear the command line.
Note: Users lacking separate arrow keys must press
Ctrl-Shift instead of Alt
219
Language Reference
History Recall
History recall allows a previous statement to be quickly
recalled and re-executed. It's a very fast shorthand,
especially in the edit/compile/debug loop or to fix a
typo. For convenience, "!" is taken as an ordinary
character if followed by white space, "=", "~" or "(".
If you want, you can choose different characters to
introduce history references by changing the histchars
variable.
Command
Meaning
!! Last command
!^ First argument word of last command
!$ Last word of last command
!* All arguments of last command
!n Command n
!-n nth command from the last
!str Last command starting with str
!?str? Last command containing str
%str1%str2% Substitute str2 for str1 in last
command. (Used only at the
beginning of a line.)
Command Completion
Command completion lets you type just part of a previous
command and have the shell fill in the rest. As with
filename completion, if no match is found, color
highlighting as defined by the MATCHFAIL variable
(default is bright red) will be used. Consecutive
depressions cause the search to continue on back through
the history list.
Key
Meaning
220
Language Reference
Ctrl- Search for the last command that
starts with the characters in the
previous word.
Alt- Search for the last command that
contains the characters in the
previous word anywhere on the
command line.
221
Language Reference
Quoting
String
Meaning
'...' Literal character string. Only do
history substitutions.
"..." Single word. Typically used if there are
embedded blanks or wildcard characters
you want treated as ordinary. Has no
effect on command or variable
substitutions: they're still done.
`...` Command substitution. Evaluate the
string as a separate command and
substitute its output back onto the
command line. Newlines are turned into
spaces and ANSI escape sequences (for
highlighting, etc.) are filtered out.
^ Quote just the next character. Use to
remove any special meaning from the next
character, to specify a character by its
binary value or to specify one following
non-printable characters. If the NewLine
character at the end of a line is quoted
this way, it's treated as ordinary white
space. (You can choose a different
escape character by changing the
escapesym variable.)
Escape Sequences
String
Meaning
^a Audible alert (bell)
^b Backspace
^f Form Feed
^n New Line
^r Carriage Return
^t Tab
222
Language Reference
^v Vertical Tab
^^ Single escapesym character
223
Language Reference
Variable Substitution
Variable substitution is typically used to pass the value
of a variable as an argument to a command. For example:
echo $message
The ${...} variations are used to isolate the variable
substitution from whatever text (including any colons)
may follow.
Reference
Meaning
$var Value of variable var
${var} Same as $var except separated from
anything following.
$var[expr] Value of var, indexed by an
arbitrarily complex expression
${var[expr]} Same as $var[expr] except
separated from anything following.
$#var Number of words in var
${#var} Same as $#var except isolated from
anything following.
$?var 1 if var exists; 0 otherwise
${?var} Same as $?var except isolated from
anything following.
$procname( argument list ) Procedure reference, used
as a variable substitution. The
arguments are expressions,
separated by commas. Any value
returned by the procedure will be
substituted in place.
$< Pseudo-variable result of reading
one line from stdin each time it's
evaluated. Same as $getline.
$* Same as $argv
$0 .. $9 Same as $argv[0] .. $argv[9]
224
Language Reference
Substitution Modifiers
Substitution modifiers can be applied to any command,
variable or history substitution. Also, any number in a
row can be applied, as desired.
Operator
Meaning
:n nth word
:# Count the number of words
:^ Word number 1, counting from 0
:$ Last word
:% Word matched by a !?str? history
search
:n-m nth through mth words
:-n 0 through nth words
:n- nth through next-to-last words
:n* nth through last word
:* 1 through last word
:q Single-quote each word
:s/str1/str2/ Substitute str2 for str1 and then
reparse into words. Match
failures are considered to be
errors unless ignoreerrors == 2.
:S/str1/str2/ Substitute str2 for str1 but leave
it as a single string. Also,
failure to match is not considered
an error.
:& Repeat last substitution
:g Global editing: as a prefix
character to any of the other
editing operators, it means apply
the edit operation everywhere it
matches, not just the first
occurrence.
225
Language Reference
:x Treat each word as a string, break
it up into words, then single-
quote each word.
:p Print the substitution but don't
execute the statement. (Ignored
except in history substitutions.)
226
Language Reference
Pathname Editing on x\y\z.c
Pathname editing can be applied to any command, variable
or history substitution. Also, any number of pathname
editing operations can be applied, one after the other,
to a given substitution.
Operator
Name
Description
Result
:h head Directory containing x\y
:r root Path w/o .ext x\y\z
:t tail Simple filename z.c
:b base Filename w/o .ext z
:e ext .ext w/o the "." c
:f fullpath Fully-qualified named:\bob\x\y\z.c
:m mixedpath Mixed-case pathname X\y\Z.c
:M fullmixedpath Mixed-case
pathname d:\Bob\X\y\Z.c
Windows NT and Windows 95 only:
:A shortname Short 8.3 filename
:L longname Long filename
The shortname function depends on support from the
filesystem. Long filenames read over the network from an
HPFS partition do not have shortnames, for example.
227
Predefined Variables
Environmental Variables Recognized
Environmental variables are passed to any child processes
or screens you create by invoking an external utility or
application. When Hamilton C shell starts up it looks
for the ones shown here to be defined in the environment
it inherits. COLORS, COMSPEC, CSHTITLE, DUPLICATES,
HIGHLIGHT, HOME, MATCHFAIL, PATH, PROMPT1, PROMPT2, and
SHELL are special: if they're not already defined, then
the shell creates them.
On Windows NT, environmental variables are not case-
sensitive, so, e.g., Path and PATH refer to the same
thing.
Name Default Use
ADDITIONSBright Green Lines added found by diff.
ASCIICONVERTBright Yellow ASCII file
CDPATH List of directories to search for
the subdirectory specified as the
new current directory.
COLORS White on Black Normal screen colors.
COMSPEC Usually, this is the pathname of
cmd.exe. If you set it to point
to the C shell, e.g., so other
programs will invoke the C shell
rather than cmd.exe, the C shell
will try to look through the
search path for cmd.exe if it
needs to run a .cmd file.
CSHOPTIONS Default set of command line
options to be pasted ahead of any
other command line options passed
to csh.exe.
CSHTITLE Template for the title bar.
Setting it to a null string causes
the title bar inherited at startup
to be displayed. Unsetting it
causes "Hamilton C shell" to be
displayed. Other values will be
evaluated for command and variable
substitutions the same way the
prompt variables are interpreted.
229
Predefined Variables
DELETIONS Bright Red Lines deleted found by diff.
230
Predefined Variables
Environmental Variables Recognized
Name Default Use
DIRECTORIES Bright Directories listed by ls.
DRIVEMASK Used by du, pwd and vol and drive
wildcarding (e.g., "*:foo.*") to
limit the default list of drives
it will report on. Written as a
list of alphabetic characters
representing the drives you want
listed; ranges are allowed. If
you don't define this variable,
all drives beginning with C: are
normally reported.
DUPLICATES Green When filename completion matches
more than one name.
ESCAPESYM ^ Character to be interpreted as a
literal escape character. Placed
in the environment only if it is
not the default circumflex.
FOREIGNFILESBright Red Filetypes in a tar file that have
no counterparts on OS/2.
HIGHLIGHT Bright Current disk or directory.
HOME Home directory (default is the
initial current directory.)
LATITUDE Latitude setting used by
sunrise.csh to calculate sunrise
and sunset times..
LONGITUDE Longitude setting used by
sunrise.csh to calculate sunrise
and sunset times..
LSOPTIONS Default set of command line
options to be pasted ahead of any
other command line options passed
to ls.
MATCHFAIL Bright Red When filename or command
completion doesn't match anything.
231
Predefined Variables
Environmental Variables Recognized
Name Default Use
MIXEDCASEDRIVES List of drives and UNC names for
which ls, pwd, wildcarding and
the fullname and current directory
functions should report filenames
in mixed case rather than all
lower case.
MOREEOF Green End or Top of File in more.
MOREERRORBright Yellow Unrecognizable command to more.
MOREFILLIN White User response to more prompt.
MOREPROMPT Green Prompt line in more.
MORETOPMEMBright Yellow Top of Memor
NETWORKBUG If NETWORKBUG = 1, the shell and
all the utilities will read
directory entries only one-at-a-
time as a workaround for a
networking bug. (Not used on NT.)
PATH Search path for executable files.
PROMPT1 $@ $CDISK% Primary command prompt template.
PROMPT2 $@ $CDISK? Continuation line prompt template.
RADIX 16 Default radix used by more and
other utilities when displaying
binary data.
READONLYDIRS Used by ls and other utilities for
directories marked read-only.
READONLYFILES Used by ls and other utilities for
files marked read-only.
SHELL Always set to the pathname of the
Hamilton C shell csh file.
SWITCHCHARS -/ Characters that can be used as
option introducers for the shell
and utilities.
232
Predefined Variables
SYSTEMDIRSBright Green Used by ls for directories with
the System bit on.
233
Predefined Variables
Environmental Variables Recognized
Name Default Use
SYSTEMFILES Green Used by ls for files with the
System bit on.
TABS 8 Used by more, head, tail and tabs
to tell them how many character
positions there are between tab
stops.
TAPE \\.\tape0 Used by mt under Windows NT to
specify the pathname of the
default tape drive.
TARASCII Used by tar to identify files,
using a list of wildcards, that
should be considered as ASCII,
regardless of content.
TARBINARY Used by tar to identify files,
using a list of wildcards, that
should be considered as binary,
regardless of content.
TZ Used by tar under OS/2 to tell it
how to convert between local time
and GMT. (Under Windows NT, the
system keeps track of the
difference between local time and
GMT, so the TZ variable is not
needed.) The TZ variable should
be of the form of a three-letter
timezone, e.g., EST, followed by a
signed number giving the
difference in hours between GMT
and local time, followed by an
optional daylight savings
timezone. Examples are EST5EDT in
New York or PST8PDT in California.
234
Predefined Variables
Predefined Process-Wide Variables
Name Default Use
$ A synonym for the processid
variable.
bsdhistory 0 By default, "!!" is the
immediately preceding command and
"!-1" is the one before that.
Setting bsdhistory = 1 makes them
the same.
cdpath null Same as the CDPATH environmental
variable, broken into words.
cshtitle Same as the CSHTITLE environmental
variable.
escapesym ^ Character to be interpreted as a
literal escape character.
histchars !% Characters which introduce long-
form and short-form history
references, respectively.
home Same as the HOME environmental
variable.
NTVersion Obsolete name for the WinBuild
variable.
OperatingSystem Name of the operating system on
which the shell is running.
Possible values are "Windows NT",
"Windows 95" and "OS/2"
os2version Version number of the OS/2 system
on which the shell is running.
(Not defined on NT.)
path Same as the PATH environmental
variable, broken into words.
processid The unique process ID assigned by
the OS/2 or NT kernel to this copy
of the C shell.
prompt1 $@ $CDISK% Same as PROMPT1 environmental
variable.
235
Predefined Variables
prompt2 $@ $CDISK? Same as PROMPT2 environmental
variable.
savehist 0 Save the history contents into
history.csh in the home directory.
shell Same as SHELL environmental
variable.
236
Predefined Variables
Predefined Process-Wide Variables
Name Default Use
WinBuild Build number of the Windows NT or
Windows 95 system on which the
shell is running, e.g., 1057 for
Windows NT 3.51. (Not defined on
OS/2.)
WinVersion Version number of the Windows API
on which the shell is running,
e.g., 3.51 for the Summer, 1995
release of Windows NT. (Not
defined on OS/2.)
Any user-defined variables (with the exception of the
parameter names of a procedure or those variables
explicitly defined as local) are shared globally by all
threads.
237
Predefined Variables
Predefined Per-Thread Variables
Inherited from the parent thread:
Name Default Use
argv Any argument words passed to the
shell or to a .csh batch file.
bsdargv 0 If set, $argv[0] contains the name
of the script, just as it would
under the original Berkeley C
shell; by default, $argv[0] is the
first argument word.
cdhome 0 If set, "cd" with no argument is
the same as "cd $home"; default is
to simply print the current
directory name.
cdisk Current disk, not including colon.
CDISK Same as cdisk, but in upper case.
chgdisk 0 If set, cd automatically changes
the current disk if the path is on
another disk.
cwd Full pathname of the current
directory.
echoallinput 0 Copy the input to stdout as it's
read. (Similar to echoinput, but
inherited from parent to child
threads.)
gotowindow 50 Number of statements a goto can
jump over (when not inside a
nested block) without being
considered an error.
nohashing 0 Determine how/whether path hashing
is done: 0 means full path
hashing of the directories on the
search path; 1 means turn off
hashing completely; 2 means hash
only the directories which do not
depend on the setting of the
current directory.
238
Predefined Variables
noclobber 0 If True, don't allow redirection
to overwrite an existing file
unless the "!" override is given.
noglob A synonym for the nowild variable.
239
Predefined Variables
Predefined Per-Thread Variables
Inherited from the parent thread:
Name Default Use
nonohidden 0 Determine whether wildcarding will
match against hidden files: 0
means don't match hidden files; 1
means hidden files will be found.
nonomatch 0 Determine the response to a
wildcard that doesn't match
anything: 0 means it's an error;
1 means pass it through to the
application; 2 means simply
discard it.
nonovar 0 Determine the response to a
reference to a non-existent
variable, procedure or alias.
Same encoding as nonomatch.
nowild 0 If True, turn off filename
wildcarding.
nullwords 0 Determines whether an array index
off the end of a list is an error
(0) or returns a null word (1).
precision 6 Number of decimal places to print
when displaying floating point
values.
tailstatus 0 Determines whether the status
variable will reflect the reflect
the return code from the leftmost
or rightmost stage of a pipeline:
0 means leftmost; 1 means
rightmost.
verbose 0 If True, print out all available
information when reporting errors.
Each new thread is initialized with default on-interrupt
processing (a forced exit), and null search and replace
strings. echoinput, ignoreerrors and interactive are
initialized for the main thread based on command-line
options.
240
Predefined Variables
Each thread also has its own independent notion of
current disk and current directories, initially inherited
from its parent.
241
Predefined Variables
Predefined Per-Thread Variables
Always initialized to the default for each new child
thread:
Name Default Use
* A synonym for the argv variable.
< A synonym for the getline
variable.
@ A synonym for the stmtnumber
variable.
child 0 Identification number of the last
child process spawned.
echoinput 0 Copy the input to stdout as it's
read. (Similar to echoallinput
but not inherited to a child
thread.)
eofgetline 0 Pseudo-variable to indicate if the
last reference to getline
encountered an end-of-file
condition.
getchar Read one character from stdin
without echoing. If stdin is tied
to the keyboard, outboard keys are
returned as two-character strings.
getline Read one line from stdin pseudo-
variable. If stdin is tied to the
keyboard, keystrokes are echoed as
they're typed.
history 0 Number of statements to remember
on the history list; 0 turns off
the history mechanism. (If the
thread is interactive, history is
automatically set to 100.)
ignoreeof 0 If True, don't exit at EOF on
stdin; insist on an exit command.
242
Predefined Variables
ignoreerrors 0 Determine whether execution should
continue if an error occurs: 0
means the thread exits; 1 (the
default for an interactive thread)
means exit from loops or
procedures and try to read a new
command; 2 means ignore all
errors.
243
Predefined Variables
Predefined Per-Thread Variables
Always initialized to the default for each new child
thread:
Name Default Use
ignorestatus 1 If True, a non-zero status code
from a child process is ignored.
Otherwise, it's an error.
interactive 0 If True, prompt for input.
irqmask 0 Determines whether interrupts are
enabled (0), deferred until the
mask is cleared again (1) or
ignored (2).
scriptname Name of the C shell script file
being executed, if any.
status 0 Exit code of the last child
process.
stmtnumber 1 Autoincremented statement number
used with the history list and in
prompting.
threadid Thread id of the currently
executing thread.
244
Predefined Variables
Predefined Variables
Sorted by Name
Legend for this table:
COURIER A setenv environmental variable. Environmental
variables are passed to any child processes or
screens you create by invoking an external
utility or application. When Hamilton C shell
starts up it looks for the ones shown here to
be defined in the environment it inherits; if
they're not already defined, the shell creates
them.
bold A set variable shared by all threads: if one
makes a change, all will see it.
normal Each thread gets its own copy but the initial
value is inherited from its parent.
italics Each thread gets its own copy but the
initialization is always to a defined value.
Name Default Use
$ A synonym for the processid
variable.
* A synonym for the argv variable.
< A synonym for the getline
variable.
@ A synonym for the stmtnumber
variable.
ADDITIONSBright Green Lines added found by diff.
argv Any argument words passed to the
shell or to a .csh batch file.
ASCIICONVERTBright Yellow ASCII file
bsdargv 0 If set, $argv[0] contains the name
of the script, just as it would
under the original Berkeley C
shell; by default, $argv[0] is the
first argument word.
245
Predefined Variables
bsdhistory 0 By default, "!!" is the
immediately preceding command and
"!-1" is the one before that.
Setting bsdhistory = 1 makes them
the same.
246
Predefined Variables
Predefined Variables
Sorted by Name
Name Default Use
cdhome 0 If set, "cd" with no argument is
the same as "cd $home"; default is
to simply print the current
directory name.
cdisk Current disk, not including colon.
CDISK Same as cdisk, but in upper case.
CDPATH List of directories to search for
the subdirectory specified as the
new current directory.
cdpath null Same as the CDPATH environmental
variable, broken into words.
chgdisk 0 If set, cd automatically changes
the current disk setting if the
path is on another disk.
child 0 Identification number of the last
child process spawned.
COLORS White on Black Normal screen colors.
COMSPEC Usually, this is the pathname of
cmd. If you set it to point to
the C shell, e.g., so other
programs will invoke the C shell
rather than cmd.exe, the C shell
will try to look through the
search path for cmd.exe if it
needs to run a .cmd file.
CSHOPTIONS Default set of command line
options to be pasted ahead of any
other command line options passed
to csh.exe.
247
Predefined Variables
Predefined Variables
Sorted by Name
Name Default Use
CSHTITLE Template for the title bar.
Setting it to a null string causes
the title bar inherited at startup
to be displayed. Unsetting it
causes "Hamilton C shell" to be
displayed. Other values will be
evaluated for command and variable
substitutions the same way the
prompt variables are interpreted.
cshtitle Same as the CSHPROMPT
environmental variable.
cwd Full pathname of the current
directory.
DELETIONS Bright Red Lines deleted found by diff.
DIRECTORIES Bright Directories listed by ls.
DUPLICATES Green When filename completion matches
more than one name.
DRIVEMASK Used by du, pwd and vol and by
drive wildcarding (e.g.,
"*:foo.*") to limit the default
list of drives it will report on.
Written as a list of alphabetic
characters representing the drives
you want listed; ranges are
allowed. If you don't define this
variable, all drives beginning
with C: are normally reported.
echoallinput 0 Copy the input to stdout as it's
read. (Similar to echoinput, but
inherited from parent to child
threads.)
echoinput 0 Copy the input to stdout as it's
read. (Similar to echoallinput
but not inherited to a child
thread.)
248
Predefined Variables
eofgetline 0 Pseudo-variable to indicate if the
last reference to getline
encountered an end-of-file
condition.
249
Predefined Variables
Predefined Variables
Sorted by Name
Name Default Use
ESCAPESYM ^ Character to be interpreted as a
literal escape character. Placed
in the environment only if it is
not the default circumflex.
escapesym ^ Same as the ESCAPESYM
environmental variable.
FOREIGNFILESBright Red Filetypes in a tar file that have
no counterparts on OS/2 or NT.
getchar Read one character from stdin
without echoing. If stdin is tied
to the keyboard, outboard keys are
returned as two-character strings.
getline Read one line from stdin pseudo-
variable. If stdin is tied to the
keyboard, keystrokes are echoed as
they're typed.
gotowindow 50 Number of statements a goto can
jump over (when not inside a
nested block) without being
considered an error.
HIGHLIGHT Bright Current disk or directory.
histchars !% Characters which introduce long-
form and short-form history
references, respectively.
history 0 Number of statements to remember
on the history list; 0 turns off
the history mechanism. (If the
thread is interactive, history is
automatically set to 100.)
HOME Home directory (default is the
initial current directory.)
home Same as the HOME environmental
variable.
250
Predefined Variables
ignoreeof 0 If True, don't exit at EOF on
stdin; insist on an exit command.
251
Predefined Variables
Predefined Variables
Sorted by Name
Name Default Use
ignoreerrors 0 Determine whether execution should
continue if an error occurs: 0
means the thread exits; 1 (the
default for an interactive thread)
means exit from loops or
procedures and try to read a new
command; 2 means ignore all
errors.
ignorestatus 1 If True, a non-zero status code
from a child process is ignored.
Otherwise, it's an error.
interactive 0 If True, prompt for input.
irqmask 0 Determines whether interrupts are
enabled (0), deferred until the
mask is cleared again (1) or
ignored (2).
LATITUDE Latitude setting used by
sunrise.csh to calculate sunrise
and sunset times..
LONGITUDE Longitude setting used by
sunrise.csh to calculate sunrise
and sunset times..
LSOPTIONS Default set of command line
options to be pasted ahead of any
other command line options passed
to ls.
MATCHFAIL Bright Red When filename or command
completion doesn't match anything.
MIXEDCASEDRIVES List of drives and UNC names for
which ls, pwd, wildcarding and
the fullname and current directory
functions should report filenames
in mixed case rather than all
lower case.
MOREEOF Green End or Top of File in more.
252
Predefined Variables
MOREERRORBright Yellow Unrecognizable command to more.
MOREFILLIN White User response to more prompt.
MOREPROMPT Green Prompt line in more.
253
Predefined Variables
Predefined Variables
Sorted by Name
Name Default Use
MORETOPMEMBright Yellow Top of Memor
NETWORKBUG If NETWORKBUG = 1, the shell and
all the utilities will read
directory entries only one-at-a-
time as a workaround for a
networking bug. (Not used on NT.)
nohashing 0 Determine how/whether path hashing
is done: 0 means full path
hashing of the directories on the
search path; 1 means turn off
hashing completely; 2 means hash
only the directories which do not
depend on the setting of the
current directory.
noclobber 0 If True, don't allow redirection
to overwrite an existing file
unless the "!" override is given.
noglob A synonym for the nowild variable.
nonohidden 0 Determine whether wildcarding will
match against hidden files: 0
means don't match hidden files; 1
means hidden files will be found.
nonomatch 0 Determine the response to a
wildcard that doesn't match
anything: 0 means it's an error;
1 means pass it through to the
application; 2 means simply
discard it.
nonovar 0 Determine the response to a non-
existent variable, procedure or
alias. Same encoding as
nonomatch.
nowild 0 If True, turn off filename
wildcarding.
254
Predefined Variables
NTVersion Obsolete name for the WinBuild
variable.
255
Predefined Variables
Predefined Variables
Sorted by Name
Name Default Use
nullwords 0 Determines whether an array index
off the end of a list is an error
(0) or returns a null word (1).
OperatingSystem Name of the operating system on
which the shell is running.
Possible values are "Windows NT",
"Windows 95" and "OS/2"
os2version Version number of the OS/2 system
on which the shell is running.
(Not defined on NT.)
PATH Search path for executable files.
path Same as the PATH environmental
variable, broken into words.
precision 6 Number of decimal places to print
when displaying floating point
values.
processid The unique process ID assigned by
the OS/2 or NT kernel to this copy
of the C shell.
PROMPT1 $@ $CDISK% Primary command prompt template.
prompt1 Same as the PROMPT1 environmental
variable.
PROMPT2 $@ $CDISK? Continuation line prompt template.
prompt2 Same as the PROMPT2 environmental
variable.
RADIX 16 Default radix used by more and
other utilities when displaying
binary data.
READONLYDIRS Used by ls and other utilities for
directories marked read-only.
256
Predefined Variables
READONLYFILES Used by ls and other utilities for
files marked read-only.
savehist 0 Save the history contents into
history.csh in the home directory.
257
Predefined Variables
Predefined Variables
Sorted by Name
Name Default Use
scriptname Name of the C shell script file
being executed, if any.
SHELL Always set to the pathname of the
Hamilton C shell csh.exe file.
shell Same as the SHELL environmental
variable.
status 0 Exit code of the last child
process.
stmtnumber 1 Autoincremented statement number
used with the history list and in
prompting.
SWITCHCHARS -/ Characters that can be used as
option introducers for the shell
and utilities.
SYSTEMDIRSBright Green Used by ls for directories with
the System bit on.
SYSTEMFILES Green Used by ls for files with the
System bit on.
TABS 8 Used by more to tell it how many
character positions there are
between tab stops.
tailstatus 0 Determines whether the status
variable will reflect the reflect
the return code from the leftmost
or rightmost stage of a pipeline:
0 means leftmost; 1 means
rightmost.
TAPE \\.\tape0 Used by mt under Windows NT to
specify the pathname of the
default tape drive.
258
Predefined Variables
TARASCII Used by tar to identify files,
using a list of wildcards, that
should be considered as ASCII,
regardless of content.
TARBINARY Used by tar to identify files,
using a list of wildcards, that
should be considered as binary,
regardless of content.
threadid Thread id of the currently
executing thread.
259
Predefined Variables
Predefined Variables
Sorted by Name
Name Default Use
TZ Used by tar.exe under OS/2 to tell
it how to convert between local
time and GMT. (Under Windows NT,
the system keeps track of the
difference between local time and
GMT, so the TZ variable is not
needed.) The TZ variable should
be in the form of a three-letter
timezone, e.g., EST, followed by a
signed number giving the
difference in hours between GMT
and local time, followed by an
optional daylight savings
timezone. Examples are EST5EDT in
New York or PST8PDT in California.
verbose 0 If True, print out all available
information when reporting errors.
WinBuild Build number of the Windows NT or
Windows 95 system on which the
shell is running, e.g., 1057 for
Windows NT 3.51. (Not defined on
OS/2.)
WinVersion Version number of the Windows API
on which the shell is running,
e.g., 3.51 for the Summer, 1995
release of Windows NT. (Not
defined on OS/2.)
260
Predefined Variables
261
Built-in Procedures
Built-in Procedures
Name
Function
Filename Functions
childpath(p, c) Test whether filename c could be
in a subdirectory of p. (Does not
test for actual existence of
either c or p.)
driveno(p) Drive number implied by pathname
p.
fullpath(p) Fully resolve pathname p.
fullmixedpath(p) Fully resolve pathname p and set
it into the precise mixed-case
representation actually stored in
the filesystem.
longname(p) Return the long filename
corresponding to the path p. (Not
supported under OS/2.)
mixedpath(p) Resolve pathname p into the
precise mixed-case representation
actually stored in the filesystem.
Under Windows NT or Windows 95,
any shortname segments will be
expanded out to the long form.
samepath(a, b) Test whether two filenames, a and
b, point to the same file. The
calculation is done by fully
resolving the two names and
comparing them but can be mistaken
if the two paths are based on
different UNC names which refer to
the same directories.
shortname(p) Return the 8.3 short filename
corresponding to the path p,
assuming there is one. Useful for
preparing arguments to be passed
to DOS or Win3.x applications.
(Not supported under OS/2.)
263
Built-in Procedures
Built-in Procedures
Name
Function
Math Functions
abs(x) Absolute value
acos(x) asin(x) atan(x) cos(x) sin(x) tan(x)
Trigonometric functions
cosh(x) sinh(x) tanh(x)
Hyperbolic functions
ceil(x) Ceiling (lowest integer >= x)
exp(x) log(x) log2(x) log10(x)
Exponential and logarithmic
functions
floor(x) Floor (highest integer <= x)
round(x) floor(x + 0.5)
sqrt(x) Square root
264
Built-in Procedures
Built-in Procedures
Name
Function
String Functions
ansi(color) Return an ANSI escape sequence
which will produce the specified
screen colors. If the argument is
ambiguous, e.g., simply "bright,"
it's taken as a modification of
the default colors specified by
the COLORS variable.
char(i) Return the character corresponding
to the numeric value i.
code(c) Return the numeric encoding of the
character c.
concat(a, b, ...) Concatenation of a series of
strings.
isinteger(x) Test whether x is an integer.
(Remember that null strings and
strings consisting only of white
space are considered equal to 0.)
isnumber(x) Test whether x is a number.
printf(fmt, ...) Perform C language-style print
formatting, returning the result
as a string. (See table of format
conversions on following page.)
reverse(s) Reverse the order of characters in
s.
strindex(a, b) Return the position in a of the
first occurrence of b. (0 means b
was not found.)
strlen(s) Number of characters in s,
represented as a string.
substr(s, b, i) Substring of length i beginning at
bth character of s. (i = 0 means
"rest of s")
265
Built-in Procedures
upper(s) lower(s) Translate a string to all upper-
or all lower-case.
266
Built-in Procedures
Printf Format Directives
These argument formats are recognized by printf:
%c Single character.
%d Decimal number.
%e [-]d.dddddde[+-]ddd
%f [-]ddd.dddddd
%g %e or %f formatting, whichever is
shorter.
%o Unsigned octal number.
%s String.
%x Unsigned hexadecimal number.
%% Literal % character.
Additional parameters may lie between the % and
the control letter:
- Left-justify expression in its field.
width Pad field to this width as needed;
leading 0 pads with zeros.
.prec Maximum string width or digits to
right of decimal point.
267
Utilities
Built-in Utilities
Command
Function
cd Change working directory.
Optionally, change disk.
chcp Change code page. (Not
implemented on NT.)
chdir A synonym for cd.
cls Clear the screen.
dirs Print the directory stack.
echo Echo arguments to stdout.
eval Defer parsing of the word
list until the evaluation
phase.
hashstat Print path hash statistics.
heapstat Print heap usage
statistics.
history Display the history list.
kill Kill background activity.
popd Pop directory stack.
ps List process and thread
status.
pushd Push a new current
directory on the directory
stack or exchange the top
two items.
rehash Rehash the path
directories.
rotd Rotate the directory stack.
sleep Sleep for a specified
period.
source Read commands from a file.
269
Utilities
unhash Turn off path list hashing.
verify Turn on write verification
mode.
wait Wait for children to
complete.
All built-in utilities self-document with the -h
option.
270
Utilities
External Utilities
Command
Function
binedit Binary edit.
cat Concatenate files.
chmod Change mode bits of file.
cmp Binary compare two files or
directories.
cp Copy files or directories.
cron Run commands at specified
times.
cut Cut out selected fields of
each line of text.
des Encrypt or decrypt data
using the Data Encryption
Standard (DES). Due to
U.S. Federal Law, this
utility cannot be exported
outside the U.S. or Canada.
date Display the date and time.
diff Compare files or
directories.
dim Discard any ansi escape
sequences in the input
stream.
dskread Read raw sectors from a
disk.
dskwrite Write raw sectors to a
disk.
du Display disk usage.
fgrep Fast string search (fast
grep) of text files.
grep Regular expression pattern
search of text files.
271
Utilities
head Copy the first few lines or
bytes of a file to stdout.
label Read/Write the volume
label.
ls List directory contents.
markexe Mark an .exe file to
indicate what sort of
application it is. (OS/2
only.)
272
Utilities
External Utilities
Command
Function
mkdir Make a new directory.
more A better more utility.
(Able to search forward or
backward or to a specific
line.)
moreh A large model version of
more. (OS/2 only.)
mt Manipulate the tape device.
(NT only.)
mv Move files or directories.
newer Test whether first file is
newer than the others.
older Test whether first file is
older than the others.
paste Merge corresponding or
subsequent lines.
patchlnk A (very) special-purpose
utility to patch a bug in
the Microsoft linker on
OS/2.
pwd Print the working
directories.
rm Remove files or
directories.
rmdir Remove directories.
sed Stream editor.
setrows Set or report the number of
rows in the display window.
sort Sort and/or merge files.
split Split a large file into
equal-sized chunks.
273
Utilities
startwin Start Win3.x applications
under OS/2 2.x.
strings Extract ASCII strings from
a file.
sum Checksum the contents of a
file.
274
Utilities
External Utilities
Command
Function
tabs Expand/Unexpand tabs.
tail Copy the last few lines or
bytes of a file to stdout.
tar Read/Write UNIX TAR and
CPIO format files.
tee Pipe fitting.
touch Update the time-stamp on a
file.
tr Translate characters.
uniq Report unique lines in text
files.
uudecode Uudecode binary data.
uuencode Uuencode binary data for
email transmission.
ver Display the current system
and Hamilton C shell
version numbers.
vol Display the disk volume
label.
wc Count lines, words and
characters.
whereis Tell which PATH directory a
given executable is in.
xd Hex dump a file to stdout.
All external utilities except whereis self-
document with the -h option. Any external utility
may be renamed simply by renaming the executable
file.
275
Popular Aliases
Popular Aliases
Command Definition Function
app cat >> Append to a file.
beep eval echo -n ^a
Beep sound.
breaksw break Older BSD4.3 name for a
break statement inside a
switch.
cdd cd +c Change the directory and
disk in one command.
copy local s; @ s = $nowild; @ nowild = 1; safecopy
Invoke the standard IBM/MS
copy command with shell
wildcarding turned off so
copy will work sensibly.
date dt Display the current time
and date.
del local s; @ s = $nowild; @ nowild = 1; safedel
Invoke the del command with
shell wildcarding turned
off so "del *.*" will still
produce the "Are you sure?"
message.
di diff -b! Run the diff command,
ignoring white space
differences and using color
to highlight the changes.
dir cmd /c dir Invoke the cmd.exe dir
command. (Alternately, you
may wish to intercept dir
the same way copy or del is
done, turning off shell
wildcarding before running
the command.)
duc du -c Disk usage for the current
disk only.
dumphist history -s > ~\history.csh
Dump out the history list.
277
Popular Aliases
278
Popular Aliases
Popular Aliases
Command Definition Function
endif end Older BSD4.3 name for the
end of an if statement.
endsw end Older BSD4.3 name for the
end of switch statement.
erase del Alternate name for del.
f fgrep Quicker name for fgrep.
fn fgrep -n Fgrep and print line
numbers.
g grep Quicker name for grep.
h history Quicker name for history.
help Under OS/2, invoke the
IBM/Microsoft help command.
Under Windows NT or Windows
95, this is a procedure
using winerror (in the
samples directory) to print
the message corresponding
to the return code from the
last command.
home cdd ~ Change to the home disk and
directory.
ld ls -a +D -. List only the
subdirectories.
ll ls -L List directories, long
format.
loadhist source -n ~\history.csh
Load the history list
without executing any of
it.
md mkdir Make directories.
279
Popular Aliases
Popular Aliases
Command Definition Function
mi more -i Quick interactive startup
of your favorite version
more. Clears the screen
when it starts up and
doesn't just exit if
there's less than a
screenful.
mih moreh -i Huge interactive more.
(OS/2 only.)
mis more -i Small interactive more.
(OS/2 only.)
pause echo -n Press any key when ready ...;
@ getchar; echo
Pause, waiting for any
keystroke or character from
stdin.
q exit Exit the C shell
rd rmdir Remove empty directories.
ren rename Another name for the rename
alias.
rename local s; @ s = nowild; @ nowild = 1; saferename
Invoke the standard IBM/MS
rename command with shell
wildcarding turned off so
the rename will work
sensibly.
rot13 tr 'n-za-mN-ZA-M' 'a-zA-Z'
Encoder/Decoder for off-
color jokes on Internet.
start cmd /c start Start a new session via the
cmd.exe start command.
type cat Copy files to stdout.
uud uudecode Uudecode binary data.
280
Popular Aliases
uue uuencode -c Uuencode using cp-style
syntax.
vol vl List volume labels.
281
Popular Aliases
Popular Aliases
Command Definition Function
w (wait; beep) Wait for background
processes and beep.
xcopy local s; @ s = nowild; @ nowild = 1; safexcopy
Invoke the standard IBM/MS
xcopy command with shell
wildcarding turned off so
xcopy will work sensibly.
282
Help
Help for Hamilton C shell
csh: Startup Hamilton C shell
Usage: csh [-!BbefFhHiKLlNnsTtuXYZ-]
[-IO] [
+IO] [-cC command ] [
arguments ... ]
Options:
-! Ignore errors: Continue execution even if a
command terminates abnormally. (Implied by
interactive.)
-B Berkeley mode for better compatibility with
the BSD4.3 C shell for commands typed, not
just those read from a script starting with
#!/bin/csh.
-b No Berkeley compatibility mode at all, not
even on scripts starting with #!/bin/csh.
-c Execute the command following on the command
line, then exit. (Implies not interactive.)
-C Normally, this means immediately run the
command on the command line, then continue
with normal startup and processing of stdin.
But for compatibility with cmd.exe, the -X
option may be used to toggle this to have
the same meaning as -c but with the initial
greeting and copyright notice suppressed.
-e Echo the raw input to stdout. (Sets
echoallinput = 1.)
-f Fast startup: Don't look for a startup.csh
file.
-F Faster startup: Don't look for a
startup.csh file and don't hash the path
directories.
-H Heapstats. At some penalty in performance,
this causes the shell to keep a count of the
number and total size of all objects
allocated or freed from the heap.
Statistics can be displayed using the
heapstat command.
283
Help
-i Interactive (even if stdin appears to be a
file or a pipe): Prompt for input and show
the result of history substitutions.
-I Start with command-line editing in insert
mode.
+I Start every command in insert mode.
-K Do a fast startup, skipping both the
login.csh and startup.csh files, run the
command on the command line, and exit.
-L Login shell: Look for login.csh and
logout.csh and do history save at exit if
savehist == 1.
-l same as -L.
-N No space after the last filename generated
by filename completion. (It's convenient to
set this with CSHOPTIONS.)
-n No execution: Parse commands looking for
syntax errors but don't execute them.
-O Start with command-line editing in
overstrike (default) mode.
+O Start every command in overstrike mode.
-s Read and execute a single line from stdin.
(Implies not interactive.)
-T Plain Tab key. Tab and BackTab are
normally used to do filename completion and
to walk file-by-file through the list of
filenames that were matched. To type an
ordinary Tab character, Ctrl-Tab is used.
This option reverses Tab and Ctrl-Tab,
making Tab a plain character and Ctrl-Tab
the filename completion key.
-t Suppress callstack tracing. Error messages
will not include a dump of the callstack but
performance will be improved slightly.
-u Reads from devices or pipes should be
unbuffered. (Intended to all the shell to
be used over a comm line.)
-X Toggle between the normal meaning of -C and
a cmd.exe-compatible interpretation. You
can set this with the CSHOPTIONS
284
Help
environmental variable in combination with
setting COMSPEC to point to the C shell to
allow programs that use /C to pass commands
to cmd.exe to be used with the C shell
instead.
-Y No interrupts. Don't install an interrupt
handler during startup under OS/2. Under
Windows NT or Windows 95, leave the keyboard
in whatever state it was in at startup;
don't force Ctrl-C to be an interrupt.
(Useful for running the C shell inside an
Emacs buffer.)
-Z Very special purpose: Don't bump the
maximum file handle count during shell
initialization. Use this option under OS/2
as a workaround if you encounter an
application that fails if it inherits a
larger limit. This option only works from
the Start Programs or Group menus, not the
command line. Under NT, this option affects
only the limit on the number of open file
handles on a FAT filesystem; it has no
effect on HPFS or NTFS files.
-h Help.
-- End of options.
(If preferred, the slash, "/," may be used in place of a
minus to introduce options.)
285
Help
286
Help
Help for the Utilities
binedit: Binary Edit
Usage: binedit [-ih!-] [-r replace ] search
file1 [ file2 ... ]
binedit is a very simple utility for scanning
arbitrary files, looking for and optionally
changing any references to the search argument to
the replacement value. binedit is quite useful
patching binary files, e.g., to replace all
occurrences of C:\OS2 with C:\1.X.
Occurrences will be reported as hex offsets from
the start of the files you name. You can use
these numbers to go examine the file with IBM/MS
patch.exe if you like and make the change
manually.
You can also ask binedit to make the change,
using the -r (replace) option. Nothing fancy.
It just changes all occurrences to the string you
specify and quits.
Neither the search nor the replace string may
contain null characters, but otherwise there are
no restrictions.
Options:
-h Help. (This screen.)
-i Ignore character case in the search
argument.
-r replace Replace any occurrences of the search
string with this replacement value.
-! Pad with nulls or truncate the replace
string to be the same length as the search
string. (Otherwise, it's an error if
they're different lengths.)
-- End of options.
287
Help
cat: Concatenate Files to Stdout
Usage: cat [-h-] [ file1 file2 ... ]
cat copies the files you specify, one immediately
after another, onto stdout. No end-of-file or
other delimiter characters are inserted between
files.
Options:
-h Help.
-- End of options.
cd: Change to a New Current Directory
Usage: cd [-chr-] [+chr] [ directory ]
cd works exactly like the one in cmd.exe by
default: if you specify a directory, it tries to
make that the current on appropriate disk but
won't change your current disk. If you don't
specify a directory, it reports the current
setting.
If the path you specify is just 3 or more dots,
cd will interpret that specially. Just as ".."
means go up one level, "..." means up 2 levels,
"...." means up 3 levels, etc. Note that "..."
is also a wildcard notation for zero or more
directory levels, but only if it's preceded by
"\", /
" ", ~
" " or ":" or followed by "\" or "/",
so usually there's no conflict with this notation
for going up multiple directories with cd. The
exception is when you'd like to go up multiple
directories on an explicitly specified drive; in
that case, you'll have to quote the word to turn
off the wildcarding.
This version of cd also supports CDPATH. If you
specify a path that isn't found, cd will look
through the list of any directories you specify
in the CDPATH environmental variable (or the
equivalent cdpath shell variable) to see if the
directory you want is in one of those
directories. The syntax for CDPATH and cdpath is
the same as for PATH or path except that the
current directory need not be listed.
288
Help
(See also the dirs, pushd, popd and rotd
commands.)
Options:
If you set the chgdisk variable equal to 1 (its
default is 0), cd will automatically change
current disks if the directory is on another
drive. The +c and -c options allow you to
manually control this drive switching:
+c Automatically change the current disk.
-c Don't automatically change current disk.
If you set the cdhome variable to 1 (its default
is 0), cd will change to your home directory if
you specify one instead of reporting your current
position. You can manually control this with the
+r and -r options:
+r Report but don't change the current
directory if no destination directory is
specified.
-r Change to the home directory in this
situation.
-h Help.
-- End of options.
chcp: Report or Change the Code Page
Usage: chcp [-h-] [ page ]
Change to the specified OS/2 character set code
page. If no page is specified, report the
current active and prepared pages. (This command
is not supported under Windows NT.)
Options:
-h Help.
-- End of options.
289
Help
chmod: Change Mode Bits on Files or Directories
Usage: chmod [-+] [rRAHSCwh] pathname1 [ pathname2
... ]
Options:
-r Recursively change contents of directories.
+R Read-only mode is set. (The file is write-
protected.)
-R Read-only mode is turned off.
+A Archive bit is set.
-A Archive bit is turned off.
+H Hidden mode is set.
-H Hidden mode is turned off.
+S Mark as a System file.
-S Mark as a normal user file.
+C Compress the file or, if it's a directory,
mark it so any new files created there will
be compressed. (Supported only under
Windows NT release 3.51 or later and only if
supported by the filesystem.)
-C De-compress the file or, if it's a
directory, mark it so new files created
there will not be compressed.
-w Give a warning message but continue trying
to chmod any remaining files or directories
even if problems were encountered with some
of them.
-h Help.
-- End of options.
cls: Clear the Screen
Usage: cls [-h-]
Options:
-h Help.
290
Help
-- End of options.
cmp: Binary Compare Two Files or Directories
Usage: cmp [ ]
-lsdxoph- [-rradix ] file1 file2
cmp compares files and directories, byte by byte.
If they are identical, cmp writes no output and
exits with a return code of 0. If they differ,
cmp will, by default, report the location of the
first difference and exit with a return code of
1.
If one operand is a directory and the other is a
file, cmp will look for and compare against a
file of that same name in the directory.
Comparing directories, cmp builds lists of all
the files they contain, searching all the way
down through the tree. The lists are sorted,
then compared. If the same filename exists in
each directory tree, they are compared.
The first difference will be reported by line
number, always in decimal, and offset from the
start of the file, in the radix specified with
the -d, -x, -o or -r option, or by the RADIX
environment variable, if set, or in the default
radix 16 (hex).
Options:
-l List all the differences, showing, for each,
the offset from the beginning of the file
and the values of the differing characters.
Offsets and character values will be shown
in the radix chosen by the user.
-s Write nothing for differing files; just set
the return code.
-p POSIX-compatible reporting: any message
text will be presented exactly as specified
by the POSIX 1003.2 standard, offsets within
the files will be counted starting at 1, not
0, and the values of any differing bytes
will be shown in octal.
-d Decimal radix.
-x Hex.
291
Help
-o Octal.
-rradixUser-specified radix. If a radix < 8 is
specified, only the character values will
be shown in that radix; offsets will be
shown in hex.
-h Help. (This screen.)
cp: Copy Files or Directories
Usage: cp [-filmh-] source1 [ source2 ... ]
destination
cp can copy both files and directories. If the
destination is an existing directory, the source
object(s) will be copied into that directory. If
more than one source object is specified, the
destination must be a directory, but it need not
already exist.
If a destination file already exists, it will be
overwritten; this is not considered an error and
no diagnostic message is given.
Options:
-f Force read-only files to be overwritten.
-i Interactive: ask before copying each object
on the command line.
-l Logging is on: display the name of each
file or directory as it's copied.
-m Merge sub-directories of same name in source
and destination.
-h Help.
-- End of options. (Useful if filenames start
with "-".)
292
Help
cron: Run Commands at Specified Times
Usage: cron [ ]
-asLwW!h- [-oopt] [-d dir ]
[ crontab1 crontab2 ... ] |
-install [-N name ] [-D dispname ]
[-u user ] [-p password ]
[-H directory ] [-MI]
arguments |
-start [-N name ] [-D dispname ]
arguments |
-stop [-N name ] [-D dispname ] |
-pause [-N name ] [-D dispname ] |
-continue [-N name ] [-D dispname ] |
-delete [-N name ] [-D dispname ] |
-status [-N name ] [-D dispname ]
cron executes commands at times according to the
crontab (.crt) files specified. If any path
specified is a directory, cron will run any
crontab files in that directory or any
subdirectory. If no files are specified, cron
will read the crontab from stdin.
Each file is expected to contain a list of
activities to be run at certain times, specified
one per line. There are six fields per line,
separated by white space. The first five
specify:
minute (0-59)
hour (0-23)
day of the month (1-31)
month of the year (1-12)
day of the week (0-6, 0 is Sunday)
Each of these fields may be an asterisk (meaning
all legal values) or a comma-separated list of
elements, where each element is either a single
number or a range, given as two numbers separated
by a minus. If either end of a range is omitted,
it defaults to the highest/lowest legal value, as
appropriate. If the days are specified in both
day of the month and day of the week fields, the
union of those fields is used; to specify the
days by only one field, the other should be an
asterisk. For example, 0 0 1 * 1 means run the
command at midnight on the first of every month
and also on every Monday.
The sixth field of each line is a command that is
to be executed by the shell at the specified
times. Any percent characters in this field
293
Help
(unless escaped by the escape character) are
translated to carriage return/newline
combinations. Only the first line (up to the
first % or end of line) is passed as a command;
the other lines are written to the shell as
stdin. If no input lines are given, the shell
will inherit stdin opened to the nul device.
Blank lines and any lines beginning with # will
be considered as comments.
If the crontab was read from a file, the shell
will inherit stdout and stderr handles for
writing (appending, if the file already exists)
to a file created by replacing the .crt extension
on the crontab file with .nnn, where nnn is the
linenumber in the .crt file. (If the crontab was
read from stdin, then the shell will inherit the
stdout and stderr that cron inherited when it
started.)
If a syntax or other error is encountered in a
crontab, that line, but not the rest of the file
will be ignored. The rationale is that cron
should continue running even if it encounters
problems; it should not be necessary to restart
it just because one entry in one crontab
contained an error.
By default, if the crontab is read from a file,
commands will be run asynchronously, meaning that
all entries that are ready to run at any given
time will be quickly spawned, one right after
another, without waiting for each to complete
before the next is spawned. If the crontab is
read from stdin, the default will be synchronous
execution, meaning each must complete before the
next starts; that's so any output from one won't
be jumbled with that of another. These defaults
can be overridden with command-line options.
Once it's started, cron will make an initial scan
of the crontab files or directories. Once every
minute after that it will look for any changes by
comparing timestamps on the files.
Running cron as a Service:
Under Windows NT, there are two ways to run cron.
The simplest is as an ordinary process. But cron
can also be run as a service, which means it can
run even under a different ID than the person
currently logged in or even when no one is logged
in. When run as a service, cron can be set up to
294
Help
start up automatically when Windows NT is booted
or for manual startup using the Services applet
in the Control Panel. Finally, as service, cron
can be either interactive, meaning it and its
children get access to the console, or non-
interactive, meaning it and its children will run
invisibly, with no display output and no means
for input through the keyboard or mouse.
The choice of running cron as either an
interactive or non- interactive service is this:
if you run it interactively, then there may be a
security hole since windows will appear and your
users may be able to interact with the
applications cron invokes in ways you didn't
intend. Also, the user might be annoyed to see
windows popping up and going away for all those
activities scheduled with cron.
On the other hand, if you run cron non-
interactively, then you may not be able to use it
to schedule everything you need. For example, if
you start notepad from a non-interactive copy of
cron, notepad will hang because it simply can't
run properly without access to the console.
Also, you won't be able to kill the notepad
process without rebooting due to the way the
security mechanism works.
An alternative to deciding between these
differing ways of running cron is to run several
copies instead. Each can be set up with its own
startup and interactive/non-interactive
characteristics. But each copy must have a
unique service and display name.
Service Options:
-install Install cron as a service. The
following options may be specified
with -install:
-u user Run cron under the specified
user name. The user name should
be in the form
DomainName\Username or, if the
account is in the current
domain, as .\Username. The
default is to run under the
LocalSystem ID.
To be able to start a service
under a user ID, that user must
have the right to log on as a
295
Help
service. To grant that right,
use the User Manager. Pull down
Policies, select User Rights and
in the popup, check Show
Advanced User Rights. You can
then select "Log on as a
service" and grant that right to
selected groups or users.
-p password Login password for the specified
user name.
-H directory Home directory that the
cron service should start up in.
Default is the current directory
at the time the install was
done.
-M Manual startup. Default is to
startup automatically when
Windows NT is booted.
-I Interactive. Default is non-
interactive. A service can not
be installed as interactive if
the -u option is specified.
arguments Any run-time arguments to be
passed to cron when it starts.
Note that any options being set
up for the service must follow
any -install options. The first
option that's not an -install
option is assumed to be a run-
time option. No syntax or other
checks are made during
installation that the run-time
arguments are sensible.
-start arguments Start the previously
installed cron service, passing
it whatever arguments may be
desired. If the -install
operation also specified an
argument list, this argument
list will override it.
-stop Stop the cron service.
-pause Pause the cron service.
-continue Allow cron to continue execution
after having been paused.
296
Help
-delete Delete (uninstall) the cron service.
-status Report the status of the cron
service.
All the service options above accept the
following additional options for specifying the
name of the service:
-N name Service name for naming the
entry in the Registry.
-D dispname Display name for use in the
Services applet.
Under NT, each service has two names: one is the
service name, which is the name under which all
the information about that service is stored in
the registry. The second is the display name,
which is the more human-readable name shown in
the Services applet in the Control Panel. By
default, the service name for cron is
"Hamilton_Cron" and the display name is "Hamilton
Cron Service".
When installing a service, both the service name
and the display name must be unique; that is,
there can't be any other services already
installed with that service name or with that
display name. Once installed, either name may be
used to refer to the service.
General Options:
-a Asynchronous execution. Don't wait for one
command to complete before spawning the
next, even if the crontab was read from
stdin.
-s Synchronous execution. Always wait for one
command to complete before spawning the
next, even if the crontab was read from a
file.
-L Logging. As each command is spawned,
timestamp and log it to stdout and to the
output file if that's not the same as
stdout.
-w Wait `till whole minute. If cron wasn't
started near a whole minute (i.e., zero to
three seconds past a whole minute mark),
wait `till the next whole minute before
beginning to schedule cron events.
297
Help
-oopt Remainder of word contains options to
be passed to the C shell with any
commands. E.g., -oF means C shell
should do fast startup when running
commands.
-d dir Output files should be created in the
specified directory, not the
directory where the .crt files were
found.
-! Install a interrupt handler to shield cron
and its children from Ctrl-C and Ctrl-Break
interrupts. (Remember to type this option
at the end of the list so the space
afterward will prevent it from being
confused as a history reference.)
-W Open a new console window rather than using
the current one. Only meaningful for cron
run as an ordinary process, but useful if
the -! option is specified.
-h Help. (This screen.)
-- End of options.
298
Help
cut: Cut out Selected Fields of Each Line of Text
Usage: cut [-hsr-] [-clist ] [-flist ] [-ddelims ]
[ file1 file2 ... ]
cut can be used to select certain columns or
fields from each line of input. If the -c option
is used, fields are defined as specific character
positions. If the -f option is used, the fields
can be of variable length, each field separated
from the next by the delimiter character. If no
files are specified, cut reads input data from
stdin.
A list of fields or character positions is
specified as a comma-separated list of integers.
The minus sign can be used to indicate a range.
Here are some examples: 1,4,7; 1-3,8; -5,10
(short for 1-5,10); or 3- (short for third
through last field.)
Options:
-h Help. (This screen.)
-s Suppress lines with no delimiters in case of
-f option. Otherwise, lines with no
delimiters are passed through unchanged.
-clist The list specifies character
positions.
-flist The list specifies field numbers.
-ddelims The specified characters are used as
the field delimiters with the -f
option. Any number of delimiters can
be specified. The default is the tab
character.
-r Repeated delimiters are treated as if only a
single delimiter had appeared.
299
Help
date: Print the Date and Time
Usage: date [-nh-] [ +format ]
date prints the date and time to stdout. The
default format shows the day of the week, the
date and time of day in 24-hour notation. If an
operand beginning with + is given, the format of
the output is controlled by the field descriptors
and other text in that operand.
This command is normally stored in the file
dt.exe and invoked with an alias so it can be
used from cmd.exe without colliding with the
internal cmd.exe date function.
Options:
+format When a format string is specified,
each field descriptor is replaced
with its corresponding value. All
other characters are copied to the
output without change.
Field Descriptors:
%a Abbreviated weekday.
%A Full weekday name.
%b Abbreviated month.
%B Full month.
%c Date and time in the format
mm/dd/yy hh:mm:ss.
%C Century as a decimal number 00
to 99.
%d Day of the month, 01 to 31.
%D Date in the format mm/dd/yy.
%e Day of the month as a 2-digit
number with leading space
fill.
%h A synonym for %b.
%H Hour (24 h clock), 00 to 23.
%I Hour (12 h clock), 01 to 12.
%j Day of the year, 001 to 366.
%m Month, 01 to 12.
%M Minute, 00 to 59.
%n CarriageReturn/NewLine
combination.
%p AM or PM.
%r Time, same as "%I:%M:%S %p".
%s Hundredths of seconds, 00 to
99.
%S Seconds, 00 to 61.
300
Help
%t A tab character.
%u Weekday as a decimal number, 1
= Monday to 7 = Sunday.
%U Week of year (Sunday as the
first day of each week), 01 to
53.
%V Week of year (Monday as the
first day of each week), 01 to
53.
%w Weekday as a decimal number, 0
= Sunday to 6 = Saturday.
%W Week of year (Monday as the
first day of each week), 00 to
53.
%x Date in mm/dd/yy format.
%X Time in hh:mm:ss format.
%y Year, 00 to 99.
%Y Year with century.
%Z Timezone name or no characters
if the timezone cannot be
determined.
%% Percent sign character.
-n Don't automatically append a Carriage
Return/Line Feed sequence to the end
of the output.
-h Help.
-- End of options.
301
Help
des: DES Data Encryption
Usage: des [-edbhnrz-] [-k key ] [ file1 file2 ...
]
des is a filter that encrypts or decrypts data
read from the files you specify, one after
another, to stdout with the Data Encryption
Standard (DES). If no files are given, des reads
from stdin. If there are multiple files, they're
simply concatenated as they're read.
Either -e (encrypt) or -d (decrypt) must be
specified. If the key is not given on the command
line with the -k option, des will prompt for it,
suppressing echo.
Distribution of this software is controlled by
U.S. Federal Law under Title 22, Code of Federal
Regulations, Subchapter M, Category XIII(b). It
may not be exported outside the U.S. or Canada
without an export license.
Options:
-e Encrypt.
-d Decrypt.
-b Electronic Code Book (ECB) mode is used.
The default is to use DES Cipher Block
Chaining (CBC) mode with an initial vector
(IV) of all zeros. Under ECB mode, each
block of 8 bytes is enciphered
independently, depending only on the key.
Under CBC mode, the enciphering of each
block also depends on the data in the
previous blocks. The default CBC mode is
considered somewhat more secure.
-k key Encryption key, typed as a simple
ASCII string. With an ASCII key, DES
ignores the low order bit of each key
byte but the high order bit is set
for odd parity, thus retaining the
information contained in the low
order bit.
-x Hex key. The key string is a sequence of up
to 16 hex characters, right padded with
zeros. With a hex key, the low order bit of
each byte is again ignored per the DES
302
Help
algorithm. This allows the use of any
arbitrary 56-bit key, including bytes
representing control characters that could
not be typed.
-h Help. (This screen.)
Special Interchange Options:
Not all DES implementations are the same. There
are a number of early implementations in
circulation that either poorly or improperly
implement DES. Cipher Block Chaining may not be
supported, forcing the use of the -b option. You
may also discover other flaws, necessitating that
you experiment with some of these special
options:
-n Suppress parity calculation on an ASCII key.
Just use the low-order 7 bits of each
character as-is.
-r Convert all \r\n sequences to \n on input
and all \n characters to \r\n sequences on
output. (Some implementers have used the C
library stdio read and write routines but
have forgotten to use binary mode.)
-z Do not mark the last block with a length;
just fill it with binary zeros. If you
encipher, then decipher a file this way, the
result will be padded with zeros out to an
8-byte boundary.
If you encounter problems exchanging encrypted
data with another DES implementation, you should
try all the various combinations of the -b, -n,
-r and -z options. (We've seen one very poor
implementation of DES that had all these flaws.)
Notes:
1. If you lose the key to a file encrypted with
DES, there is no known way to decrypt it.
The data is lost.
2. When choosing keys, avoid anything obvious
that someone else might easily guess. E.g.,
don't use just your name or your date of
birth or a common word. Instead, choose a
key with a seemingly random mix of
alphanumeric and punctuation characters.
303
Help
3. No encryption system should be considered
perfectly secure. Although there are no
known practical methods for attacking DES,
such methods may exist.
4. Encryption can only protect data that's
actually encrypted. If you have copies of
the clear text on your disk, anyone with
access to your machine may be able to read
the data. Also, even when a file is
deleted, the contents may remain on your
disk, accessible to anyone with knowledge of
the file system.
5. If you would like to compress encrypted
data, e.g., with utilities such as PKZip or
ARC, compress first, then encrypt. The
encryption process tends to destroy the
redundancy in the data that compression
programs depend on.
diff: Compare Files or Directories
Usage: diff [-bBeEfhiNqrvw!-] [-m minmatch ]
[-n maxbest
] [-Dstring ] [-dstring ]
oldpath newpath
diff produces a list of differences between two
files or directories. The working assumption is
that newpath is a newer version of whatever's in
oldpath. If they're files, diff assumes they
contain ASCII text but if it encounters a file
containing lots of binary data, it switches to a
binary comparison mode to avoid dumping gibberish
to the screen.
Comparing files, diff looks for minimal sections
of change. Each difference is shown as an add,
delete or change with the appropriate line
numbers or line number ranges for each file.
Following are texts of the differing section.
Lines that have been deleted are flagged with
`<'; lines that have been added are flagged with
`>'. Alternately, diff can be used to produce
merged listings with #ifdefs for the C compiler
or highlighting for quick visual scanning.
The algorithm for comparing files is to maintain
sliding windows into each of the two files,
adding new lines to each window until there is a
matching sequence of some minimal number of lines
304
Help
at the bottom of each window. That minimum can
be configured via the -m option.
Once that minimal match is found, diff begins to
compare the two windows in an attempt to minimize
the number of lines in each that cannot be
matched against the other. If the combined total
number of lines in the two windows is less than
some heuristic limit, set via the -n option, diff
will do this comparison with a recursive
algorithm guaranteed to find the absolute best
solution. But because the computation involved
in this approach grows very quickly as the number
of lines increases, diff switches to a heuristic
approach for more complex window comparisons,
breaking the windows down into smaller segments
against which the exhaustive approach can be
used.
Comparing directories, diff builds lists of all
the files they contain, searching all the way
down through the tree. The lists are sorted,
then compared. If the same filename exists in
each directory tree, a quick binary comparison is
normally made of whether they contain the same or
different data. If -r is specified, the diff
text comparison is done recursively the whole way
down the two trees.
If one of the arguments to diff is a file and the
other is a directory, diff will look for and
compare against a file of that same name in the
directory.
Options:
-b Blank spaces of any length compare equal.
Ignore any leading or trailing white space
on each line.
-B Binary comparison even on text files.
-Dstring Produce a merged #ifdef'ed listing,
with the string being defined meaning
use the older version. (Newer version
is intentionally the default.)
-dstring Same as -Dstring, but add comments of
the form /* string */ to the #else
and #endif directives that are
generated.
-e Produce an ed script which, when a w (the
write command) is appended to it, can be
305
Help
used to transform the first file into the
second.
-E Turn off highlighting of empty lines. By
default, if highlighting is used to show
areas of change, even empty lines will have
ANSI sequences at the beginning and end so
that if more is used to display the output
with the default color stretch mode on,
empty lines will still be highlighted.
-f Force diff-style comparison to continue even
on files that appear to contain binary data.
-i Ignore character case.
-m minmatch Minimum match length to insist
on before resynchronizing two files.
(Default is 20 lines.)
-n maxbest Maximum total number of lines in the
two windows against which diff will
attempt an absolute best match. If
the total is larger, it will attempt
to break the problem down with
heuristics.
-N Ignore differences in line endings. NewLine
and CarriageReturn-NewLine endings will be
considered equal.
-q Quiet: suppress warnings about files
containing binary data.
-r Recursively diff the contents of any
subdirectories.
-v Verbose listing of all the contents of any
entire subdirectory added or deleted.
-h Help. (This screen.)
-w White space is ignored totally.
-! Produce merged, highlighted version. Text
that's unchanged is normal, deleted text is
red, new text is green.
-- End of options.
Colors:
You may set your own choices for screen colors
using these environmental variables:
306
Help
Name
Use
Default
COLORS Normal screen colors White on
Black
ADDITIONS Lines added Bright Green
DELETIONS Lines deleted Bright Red
Colors recognized are black, red, green, yellow,
blue, magenta (or red blue), cyan (or blue green)
or white. Foreground colors may also be bright
or blink. The names of the colors and the words
bright, blink and on may be in either upper or
lower or mixed case but the names of the
environmental variables themselves must be all
upper case.
Either or both the foreground and background
colors may be specified; if you don't specify a
value, it's considered transparent and inherits
the color underneath it. ADDITIONS and
DELETIONS inherit from COLORS.
dim: Discard any ANSI escape sequences in the input
stream
Usage: dim [-h-] [ file1 file2 ... ]
dim deletes any ANSI escape sequences as it
copies text from each of the files you specify
onto stdout. If several files are given, they're
concatenated one after another to the output.
If no files are given, dim reads from stdin.
Options:
-h Help. (This screen.)
-- End of options.
dirs: List the Current Directory Stack
Usage: dirs [-h-]
Show the list of fully-qualified directory
pathnames on the current directory stack,
highlighting the current disk:directory pair.
307
Help
Hamilton C shell maintains a stack representing
the current directory and any previous current
directories has saved there.
(See also the cd, pushd, popd and rotd commands.)
Options:
-h Help.
-- End of options.
308
Help
dskread: Read Raw Sectors from a Disk
Usage: dskread [-bcdhEHL-] [-n name ] [-N sectors ]
[-s size ] [-t tracks ] [ disk: ] [
sectorlist ]
dskread copies low-level raw sectors on the disk
you specify to stdout.
In conjunction with dskwrite, dskread is most
useful as a quick diskette duplication utility:
you can read a whole diskette image into a file
with dskread, then write it back out with
dskwrite to a new diskette. But it's also useful
for restoring a long stream of data dumped across
a series of diskettes with dskwrite.
The disk is given as a single alphabetic drive
letter plus a colon. If no disk is specified,
the first logical drive is assumed (in most
machines, this is the a: drive).
Note: Windows 95 does not provide the raw device
interface offered by Windows NT. Therefore,
dskread and dskwrite are not yet supported under
Windows 95.
Operation:
dskread normally starts at cylinder 0, head 0,
sector 0 and walks through the whole disk,
reading all the sectors on a track under one head
and then all tracks in a cylinder before
repositioning the heads to the next cylinder.
dskread always reads whole sectors except when
reading from a file using the -d option.
Options:
-b Boot record. Skip sector 0 on the
assumption it simply contains a standard
boot record and parameter block
corresponding to the particular media.
-c Continuation. Assume the data has been
split across several diskettes. After each
disk has been read, prompt for the next one.
If -d is specified also, the filename
extension on each disk will be the disk
number, i.e., 001, 002, 003, etc.
309
Help
-d Dummy filesystem. Assume the data is in a
single file on the disk. If neither the -d
nor the -b options is given, the disk will
be read beginning with sector 0.
-h Help. (This screen.)
-n name The filename to look for if the -d
(dummy file- system) option is used.
Default is `bindata'.
-- End of options.
Formatting:
Default is to let OS/2 or Windows NT try to
determine the formatting that was used. If the
disk was written in an unusual format or has non-
standard data in sector 0, the following options
can be used to override OS/2 or Windows NT's
attempt to guess the format:
-E Extended density (2.88M) format.
-H High density format.
-L Low density format.
-N sectors Sectors per track.
-s size Sector size. Normally only 512 is
supported but, depending on your
hardware, you may also be able to
create 128, 256 or 1024-byte sectors.
-t tracks Number of tracks.
Sector lists:
Optionally, you can specify a list of sectors you
want read. Sectors are given in
(cylinder, head, sector)
coordinates with parentheses around and commas or
white space to separate the numeric values you
write. Cylinders, heads and sectors are counted
from zero and can be specified in decimal, hex or
octal.
A single sector specified alone means just that
sector. Listing several separated by commas or
spaces means each one individually.
310
Help
A pair of sectors joined by a hyphen means a
range: all the consecutive sectors beginning
with the first and running through to the second.
Specifying a negative number as an ordinate means
use the highest possible value for that disk.
If any of the ordinates of a sector are omitted,
they're assumed to be zero except when it closes
a range, in which case it means use the highest
possible value.
Examples:
1. To duplicate a whole diskette image,
autoformatting the output media if it's not
already formatted:
dskread a: > dskimage.a
dskwrite -av a: < dskimage.a
2. To use a diskette as a serial archive media:
The -d option allows you to request just
enough dummy file system "envelope" around
the otherwise arbitrary data you intend to
write to ensure the disk can still be used
with other OS/2 or Windows NT utilities.
Here's an example writing the result of a
tar'ing (archiving) a whole directory to a
series of diskettes, again autoformatting:
tar -cs mydir < nul | dskwrite -avcd -n
mydir a:
It's restored with
dskread -dc -n mydir a: | tar -xs
The diskettes used do not all have to be the
same density; any mix of high and low is
okay. But remember that if a disk isn't
already formatted, there's no way for
dskwrite to tell whether it should be high
or low density; any disks it has to format
will all be formatted the same way.
3. Reading or writing tar-format floppies:
Many UNIX machines support the use of a
floppy as a tar archive media, just as if it
were a tape. Every sector contains data;
there's no filesystem and no boot record at
all. This allows the greatest possible
311
Help
amount of data to be written to the disk and
it does allow interchange with a UNIX
machine, but tar-format floppies are not
readable by any ordinary utilities.
Here's an example, tar'ing mydir to a single
tar-format floppy:
tar -cs mydir < nul | dskwrite -vx a:
It's restored with
dskread a: | tar -xs
If the amount of data you're archiving is
more than will fit on one diskette, use the
-c option with dskread and dskwrite. But
since there's no labeling recorded on the
diskette and the data just runs continuously
from one diskette to the next, you will need
to pay attention to the order in which the
disks were written or read.
dskwrite: Write Raw Sectors to a Disk
Usage: dskwrite [-abcdEfFhHLTvxz-
] [-Z!] [-n name ]
[-N sectors ] [-s size ] [-t tracks ]
[-V volid ]
[ disk: ] [ sectorlist ]
dskwrite copies stdin to the low-level raw
sectors on the disk you specify.
In conjunction with dskread, dskwrite is most
useful as a quick diskette duplication utility:
you can read a whole diskette image into a file
with dskread, then write it back out with
dskwrite to a new diskette. But it's also useful
for dumping a long stream of data across a series
of diskettes, formatting and filling each with as
much as possible before requesting the next one.
The disk is given as a single alphabetic drive
letter plus a colon. If no disk is specified,
the first logical drive is assumed. (In most
machines, this is the a: drive.)
Note: Windows 95 does not provide the raw device
interface offered by Windows NT. Therefore,
dskread and dskwrite are not yet supported under
Windows 95.
312
Help
Operation:
dskwrite normally starts at cylinder 0, head 0,
sector 0 and walks through the whole disk,
writing all the sectors on a track under one head
and then all tracks in a cylinder before
repositioning the heads to the next cylinder.
You can also cause dskwrite to write to just
specific sectors by giving it a sector list.
dskwrite always writes whole sectors and, if
requested, formats whole tracks. If the last
sector is only partially-used, dskwrite fills it
out with binary zeros.
To avoid conflicts with other applications,
dskwrite always locks a drive before actually
writing to it.
Basic Options:
-a Autoformat. If the disk appears to be
unformatted, automatically do a low-level
format of the entire disk.
-f Low-level format the entire disk as data is
copied to it from stdin.
-F Low-level format the entire disk and create
an empty FAT filesystem. Do not read
anything from stdin.
-v Verify. Read back and verify each write.
-h Help. (This screen.)
-- End of options.
Options for using the disk as a serial media:
-b Boot record. Write a simple non-system disk
boot record and parameter block
corresponding to the particular media into
sector 0. If writing the entire disk,
continue with the next sector.
-c Continuation. If there's more data on stdin
after an entire disk has been written,
prompt for a new disk to be inserted and
continue. If -d is specified also, the
filename extension on each disk will be the
disk number, i.e., 001, 002, 003, etc.
313
Help
-d Dummy filesystem. Write a boot record and a
FAT filesystem into the initial sectors
allocating whatever is written to a single
file.
-n name The filename to be given to any data
written onto the disk if the -d
(dummy filesystem) option is used.
Default is `bindata'.
Formatting:
Default is to let OS/2 or Windows NT try to
determine how the media has been formatted and
not to reformat the disk.
If the disk isn't already formatted and the -a
(autoformat) option is selected or if formatting
is explicitly requested with the -f or -F
options, dskwrite will do a low-level format of
the media.
dskwrite takes its specification of the format
(e.g., low- or high-density) from the following
sources, in decreasing priority:
1. Explicit specifications on the command line.
2. The OS/2 or Windows NT kernel's guess at the
media format, assuming the disk is already
formatted and not being re-formatted.
3. The format parameters in the boot sector
copied from stdin, assuming neither the -b
nor the -d options is given.
4. The previous format of the media, assuming
it's already formatted in a standard
configuration but being reformatted.
5. The highest-density format supported by the
drive.
Unless you specify -b or -d, dskwrite will expect
to copy a compatible disk image from stdin
including a suitable boot sector, etc. That
happens automatically when dskread'ing a whole
disk is paired with dskwrite'ing a whole disk but
not otherwise.
Explicit Format Specification Options:
-E Extended density (2.88M) format.
314
Help
-H High density format.
-L Low density format.
-N sectors Sectors per track.
-s size Sector size. Normally only 512 is
supported but, depending on your
hardware, you may also be able to
create 128, 256 or 1024-byte sectors.
-t tracks Number of tracks.
Other Advanced Options:
-T Low-level format the media track-at-a-time
as the disk is written. Only as much of the
disk as is being written to will be
formatted.
-V volid The volume identifier to be written
into the dummy filesystem header if
-F or -d is used. (Ignored
otherwise.)
-x Force use of a non-standard format or
writing of non-standard format parameters to
the boot sector.
-z Zero-length files written with -d option
should still be added to the directory.
(Otherwise, they're ignored.)
-Z! Force write to a hard disk. Warning! Very
risky unless you know exactly what you're
doing.
Sector lists:
Optionally, you can specify a list of sectors you
want written. Sectors are given in
(cylinder, head, sector)
coordinates with parentheses around and commas or
white space to separate the numeric values you
write. Cylinders, heads and sectors are counted
from zero and can be specified in decimal, hex or
octal.
A single sector specified alone means just that
sector. Listing several separated by commas or
spaces means each one individually.
315
Help
A pair of sectors joined by a hyphen means a
range: all the consecutive sectors beginning
with the first and running through to the second.
Specifying a negative number as an ordinate means
use the highest possible value for that disk.
If any of the ordinates of a sector are omitted,
they're assumed to be zero except when it closes
a range, in which case it means use the highest
possible value.
Examples:
1. To duplicate a whole diskette image,
autoformatting the output media if it's not
already formatted:
dskread a: > dskimage.a
dskwrite -av a: < dskimage.a
2. To use dskwrite to format a disk with an
empty FAT file system, use either:
dskwrite -F a:
or:
dskwrite -df a: = n: Display commands numbered n
through m.
if m < n: Display m commands, beginning at
command n.
(The size of the list is controlled by the
history variable, changed using the set command.)
Options:
-s Short form: Leave off the command numbers.
-r Reverse order: Show the oldest first.
-h Help.
-- End of options.
328
Help
kill: Kill Specified Process or Thread Activity
Usage: kill [-x!h-] scheduling_id [ scheduling_id
... ]
Terminate specific activities. Normally, only
direct child screen groups and processes can be
killed. Only certain threads will respond to a
kill; you cannot inadvertently kill normal
internal housekeeping.
Under Windows NT or Windows 95, requests to kill
a process are normally carried out by sending a
Ctrl-Break event to the process and its children.
Ctrl-Break isn't guaranteed to work (any given
process may choose to ignore it) but it does,
it's guaranteed that process will terminate
cleanly, releasing any DLL's it's using.
Scheduling_ids are the thread, process or screen
group identifiers as reported by the ps command.
An id beginning with `t' indicates a thread; `p'
indicates a process; under OS/2, `s' indicates a
screen group.
Options:
-x Kill even processes that are not direct
children. (Has no effect on OS/2 screen
groups that are not direct children; this is
an OS/2 kernel restriction.)
-! Under Windows NT or Windows 95, kill
processes using TerminateProcess, not Ctrl-
Break. This will kill almost anything (a
process cannot ignore it) but since its
effect is immediate, any DLL's in use will
not necessarily clean up properly.
-h Help.
-- End of options.
329
Help
label: Read/Write the Volume Label
Usage: label [-h-] [ disk: ] [ label ]
label reads or writes the label on the specified
disk, given as a single alphabetic drive letter
plus a colon. If no disk is specified, the
current disk is assumed. If no label is
specified, the current label name is printed.
Otherwise label tries to set the label to
specified name. Spacing between the disk: and
the label operands is optional.
The principal differences between this and the
standard OS/2 or Windows NT or Windows 95 label
commands are that (1) it can be invoked directly
from the C shell (the standard OS/2 label had a
bug in its command line processing that meant it
had to be invoked only via cmd.exe), and (2) it
never prompts, making it more suitable in
scripts.
Options:
-h Help. (This screen.)
-- End of options.
330
Help
ls: List Files or Directories
Usage: ls [-+][lL!rqhx- ndtsez mU DHSARC.a 0-9
FTwME]
path1 [ path2 ... ]
ls lists the specified files or directories.
Directory names are highlighted; names of files
or directories with the system bit set are shown
in green.
File and directory names are normally converted
to lower case for better readability. But ls
will look for an environmental variable,
MIXEDCASEDRIVES, giving a list of drives, e.g.,
f-hq, meaning drives F: through H: and drive Q:,
which should be displayed in mixed case.
To customize ls with a default behavior of your
own choosing, use the LSOPTIONS environmental
variable. ls will first process any options
specified in LSOPTIONS before any specified on
the command line.
General Options:
-l Long format listings of the files or
directories.
-L Very Long format listings. (Under OS/2 1.1,
used and allocated media space is always
reported. Under 1.2, the size of any
extended attributes is shown instead of
media space if -E is specified. Also, under
1.2, root directories do not have a
timestamp and are reported as midnight,
Jan 1, 1980)
-! List just the names specified, not the
contents of any directories. (Remember to
type this option at the end of the list so
the space afterward will prevent it being
confused as a history reference.)
-r Recursively list contents of any
subdirectories.
-q Quiet. Don't generate an error message for
non-existent files.
-h Help (short list.)
331
Help
-hx Extended help (this description.)
-- End of options. (Useful if filenames start
with "-".)
Sorting Options:
Sorts may be done in any order; default is -nds.
(The filename is the most important sort criteria
and ties are broken by date or size.)
-n Name (lowest alphabetic first.)
-d Date (oldest first.)
-t Time (newest first; same as -dz)
-s Size (largest first.)
-e Extension (lowest alphabetic first.)
-z Reverse the major or last specified sort.
-m Merge the listings of directories and files.
-U Unordered (in order of appearance in the
directory.)
Selection Criteria:
+type Include files/directories fitting
this pattern.
-type Leave out anything fitting this
pattern.
where type is a combination of following
characters:
D Directories.
H Hidden files or directories.
S System files or directories.
A Archive bit set.
R Read-only files or directories.
C Compressed files or directories. (Supported
only under Windows NT 3.51 or later.)
. "." and ".." files.
332
Help
a All files or directories regardless of
attributes.
The default is "+a -. -H", meaning list anything
other than "." and ".." not marked Hidden.
Anything specified is added to/subtracted from
this set. Ordering of additions or subtractions
does make a difference. If the slash, "/", is
used to introduce options, it is treated as a
plus when used with selection criteria.
Selection criteria normally applies only to
directories and files found by listing a
directory. All names given on the command line
will be listed if they exist regardless of
whether they match the selection criteria unless
the -c option is specified.
-c Command line names must match criteria also,
unless only one name is given.
Listing Options:
-integer Specified number of columns.
-0 Standard multi-columns on an 80-column
screen.
-F Put a backslash after each directory name.
-C True mixed-case. Display filenames in the
upper- or lower-case characters actually
stored in the file system.
-w Walk subdirectories to show true sizes in
long format listings.
-M Media allocation is shown instead of amount
used with -l. (Only under OS/2.)
-E Extended attribute size is shown instead of
media allocation with -L under OS/2. (-E is
ignored under OS/2 1.1, which doesn't report
media allocations.)
Colors:
You may set your own choices for screen colors
using these environmental variables:
Name
Use
Default
COLORS Normal screen colors White on
Black
333
Help
READONLYFILES Files marked read-only same as
COLORS
SYSTEMFILES Files with system bit set Green
DIRECTORIES Directories Bright
READONLYDIRS Directories marked same as
read-only DIRECTORIES
SYSTEMDIRS Directories with system (see
below)
bit set
Colors recognized are black, red, green, yellow,
blue, magenta (or red blue), cyan (or blue green)
or white. Foreground colors may also be bright
or blink. The names of the colors and the words
bright, blink and on may be in either upper or
lower or mixed case but the names of the
environmental variables themselves must be all
upper case.
Either or both the foreground and background
colors may be specified; if you don't specify a
value, it's considered transparent and inherits
the color underneath it.
SYSTEMDIRS normally inherits a merging of the
DIRECTORIES and SYSTEMFILES colors. DIRECTORIES
and SYSTEMFILES inherit from COLORS. If a file
or directory has both the system and read-only
bits set, the system colors will be used.
markexe: Mark the Application Type Bits in an .exe File
Usage: markexe [-ftpzslh-] file1 [ file2 ... ]
markexe reports or sets the application type bits
on OS/2 .exe files to indicate how the
application should be started, i.e., whether they
must run full-screen, can run in a text window or
must be started as full PM graphics applications.
If the .exe is a 16-bit application, markexe can
also be used to indicate whether it supports long
filenames. (All 32-bit applications must, by
definition, support long filenames.)
If no flags are specified, the types are reported
but not altered.
Application Types:
-f Full-screen.
334
Help
-t Text windowable.
-p PM graphics.
-z Zero the type bits. (Undefined type.)
Long Filename Support (ignored for 32-bit .exe
files):
-s Short filenames only.
-l Long (HPFS-style) filenames supported.
Other Options:
-h Help. (This screen.)
-- End of options.
mkdir: Make Directories
Usage: mkdir [-rwh-] directory1 [ directory2 ... ]
Options:
-r Recursive: if any parent directory levels
are missing, create those also.
-w Give a warning message, but continue trying
to make any remaining directories even if
problems were encountered with some of them.
-h Help.
-- End of options.
more: A Better More Filter
Usage: more [-#IinNcvbodxCh-] [-rradix ]
[-ttabs ] [-sscroll ] [ file1 file2
... ]
This more provides a number of advantages over
the standard more.com filter. It's faster, goes
backwards and forwards through a file, can search
for character strings and display binary data
embedded in the text. As it reads a file, it
builds an ISAM structure on-the-fly that lets it
jump to a specific line number almost
335
Help
instantaneously. It's designed for very fast
browsing.
On-line help is available to the key bindings by
pressing "h" when you see the Press H for Help
prompt at the bottom of a screenful of data.
For OS/2, there are two versions of more:
more.exe is built in small model and can cache
about 11K characters; a "huge" version,
moreh.exe, is built in large model and while
slightly slower, can cache about 4M characters.
Where speed is less important than being able to
scroll all the way back through a large amount of
text coming through a pipe, use moreh.exe, which
was compiled in large model.
Options:
-# Show line numbers.
-C Don't clear the screen before each new
screenful.
-I Start up in case-independent search mode.
-i Go into Interactive mode immediately, which
means clear the screen first for faster
painting and put up the Press H for Help
prompt rather than just exiting if there's
less than a screenful of input.
-N No stretch. Don't stretch color changes out
to the right edge of the screen.
-n Next file option. Pressing space bar when
the end-of-file message is displayed causes
more to continue with the next file or to
exit if there are no more files.
-sscroll Set the integer default scroll
amount.
-ttabs Set tabs every integer number of
spaces.
-c Show non-printables in C language style.
-v Make non-printables Visible as control
characters.
-b Show Binary values of non-printable
characters.
336
Help
-o Use Octal for binary data.
-d Use Decimal for binary data.
-x Use Hexadecimal for binary data.
-rradix Use user-specified radix for binary
data.
-h Help.
-- End of options. (Useful if a filename
begins with "-".)
Initial tab settings and radix values are taken
from the environmental TABS and RADIX variables
if they're defined. Otherwise, tabs = 8 and
radix = 16 is assumed.
Colors:
You may set your own choices for screen colors
using these environmental variables:
Name
Use
Default
COLORS Normal screen colors White on
Black
MOREEOF End or Top of File messages
Green
MORETOPMEM Top of Memory message Bright
Yellow
MOREPROMPT Prompt line at the bottom Green
MOREFILLIN Characters typed at the White
prompt
MOREERROR Unrecognizable command Bright
Yellow
errors
Colors recognized are black, red, green, yellow,
blue, magenta (or red blue), cyan (or blue green)
or white. Foreground colors may also be bright
or blink. The names of the colors and the words
bright, blink and on may be in either upper or
lower or mixed case but the names of the
environmental variables themselves must be all
upper case.
Either or both the foreground and background
colors may be specified; if you don't specify a
value, it's considered transparent and inherits
the color underneath it. MOREERROR and
MOREFILLIN inherit from MOREPROMPT. MOREPROMPT,
MORETOPMEM and MOREEOF inherit from COLORS.
337
Help
338
Help
mt: Magnetic Tape Device Operations (Windows NT
only)
Usage: mt [ ]
-Vvh- [-f device ] command1 [ command2
... ]
mt is used to give commands to the tape device.
If a device is not specified, the device
specified by the TAPE environment variable is
used. If TAPE is not defined, \\.\tape0 is used.
By default, each command is performed once. Many
operations may be performed multiple times by
specifying a count.
These are the available commands. Only as many
characters as are required to uniquely identify a
command need be given. If no commands are
specified, status is given.
fss [n] Forward space n setmarks.
fsqs [n] Forward space to n sequential
setmarks.
fsf [n] Forward space n filemarks.
fsqf [n] Forward space to n sequential
filemarks.
fsr [n] Forward space n records.
bss [n] Back space n setmarks.
bsqs [n] Back space to n sequential
setmarks.
bsf [n] Back space n filemark.
bsqf [n] Back space to n sequential
filemarks.
bsr [n] Back space n records.
stp [n [p]] Set tape position to block n in
partition p. Default is block
1 in current partition.
stpa [n] Set tape position absolute. Go
to block n counting from the
beginning of the tape.
eod [p] Goto to end of data in
partition p.
weod Write end of data at current
position.
wfm [n] Write n filemarks.
wsfm [n] Write n short filemarks.
wlfm [n] Write n long filemarks.
wsm [n] Write n setmarks.
339
Help
rewind Rewind the tape.
load Load the tape and move to the
beginning.
lock Lock the tape ejection
mechanism.
tension Adjust tension by moving to the
end of tape and then rewinding.
unload Rewind and unload the tape.
eject Same as unload.
unlock Unlock the tape ejection
mechanism.
blksize [n] Set blocksize. (Default is
device default.)
compress [n] Enable (1) or disable (0)
compression.
ecc [n] Enable (1) or disable (0) ECC.
eot [n] Set the end-of-tape warning
zone size in bytes. (Default
is 0.)
setmarks [1] Enable (1) or disable (0)
setmark reporting.
warning [1] Set end-of-tape warning size.
padding [1] Enable (1) or disable (0) data
padding.
status Print status information about
the tape device. Note: if the
drive does not support variable
blocksize i/o, the media
blocksize displayed will be
just as reported by the device
driver (just whatever blocksize
was used for the last i/o
operation), not the result of
actually reading the tape.
erase Erase from current position to
end of partition.
eraseshort Just write an erase gap or end-
of-data market at the current
position.
create [n [size]] Create partitions of device
default number and size.
Default number and size are
determined by the device.
340
Help
Options:
-V Don't use variable block I/O even if the
drive claims it supports it. Useful as a
workaround if your drive's firmware has a
bug.
-v Verbose. Status command should dump out a
complete feature list for the drive.
Default is to give just status, position and
brief information about the media and drive.
-f device Name of the tape device to open.
-h Help
-- End of options.
mv: Move Files or Directories
Usage: mv [-filmh-] source1 [ source2 ... ]
destination
mv is an intelligent file or directory mover.
It's able to move either files or directories as
objects regardless of whether the source and
destination are in the same directory or even the
same drive.
Files being moved anywhere on the same partition
are simply renamed; the data stays where it is.
Moving a file to a different partition is done by
copying the file and then deleting the original.
If you move a directory but it keeps the same
parent, that also is a simple rename. Moving a
directory to a new parent is done by a mkdir in
the new parent and moving all the directory
contents using the same "rename where possible"
strategy recursively.
Options:
-f Force read-only files to be overwritten.
-i Interactive: ask before moving each object
on the command line.
-l Logging is on: display the name of each
file or directory
-m Merge sub-directories of same name in source
and destination.
341
Help
-h Help.
-- End of options. (Useful if filenames start
with "-".)
342
Help
newer: Test whether file1 is newer than all the others
Usage: newer [-2h-] [ file1 file2 ... ]
Prints "1" if file1 is newer, otherwise prints
"0".
Options:
-2 Two-second granularity for comparing
timestamps. Timestamps on NTFS have a 100
nanosecond granularity. But if the file is
copied to a FAT or HPFS partition, where the
granularity is only in two-second
increments, the timestamp may be rounded up
or down, somewhat arbitrarily. (NT rounds
down but OS/2 rounds up.) This option
causes any two timestamps within any given
two-second window (endpoints included) to
compare equal.
-h Help.
-- End of options.
older: Test whether file1 is older than all the others
Usage: older [-2h-] [ file1 file2 ... ]
Prints "1" if file1 is older, otherwise prints
"0".
Options:
-2 Two-second granularity for comparing
timestamps. Timestamps on NTFS have a 100
nanosecond granularity. But if the file is
copied to a FAT or HPFS partition, where the
granularity is only in two-second
increments, the timestamp may be rounded up
or down, somewhat arbitrarily. (NT rounds
down but OS/2 rounds up.) This option
causes any two timestamps within any given
two-second window (endpoints included) to
compare equal.
-h Help.
-- End of options.
343
Help
344
Help
paste: Merge Corresponding or Subsequent Lines
Usage: paste [-sh-] [-d list ] file ...
Concatenate corresponding lines of the input
files, writing the output to stdout. Any
newlines or carriage return-newline combinations
at the end of any lines except those read from
the last file are replaced with tab characters.
If end-of-file is encountered on some but not all
the files, paste behaves as if it were reading
empty lines from those files.
A filename of a single "-" (minus) character is a
special case and will be interpreted as referring
to stdin.
Options:
-d list Specifies a list of delimiters to be
used instead the default tab
character when pasting lines
together. If more than one character
is given, paste will use them
circularly, resetting back to the
beginning of the list after each line
of output. The list may contain the
following special escape sequences:
\n Carriage return-newline
combination
\t Tab
\\ Backslash
\0 Empty string (not a null
character).
-s Concatenate subsequent lines of each
file rather than merging lines from
different files. The end of data
from each file will be terminated
with the line-end combination found
there or a carriage return-newline
combination if there was no line end.
-h Help. (This screen.)
-- End of options.
345
Help
patchlnk: Patch "The linker bug" (OS/2 only)
Usage: patchlnk [-hcw-] filename
patchlnk can be used to patch a specific bug in
your linker if you're having problems linking
under the Hamilton C shell on OS/2. (See also the
discussion under "Known Bugs" in the readme.too
file sent with Hamilton C shell.)
If you're having problems linking long lists of
.obj files, you should save a copy of your
link.exe the way it is, then patch your linker
with this program and see if the problem goes
away.
Microsoft has discovered they had a bug in the
version of the C library used to build their
link.exe releases (roughly) 5.01.21 through (and
possibly past) 5.03. In the file open routine,
they had an "off by one error" that caused
problems if the DosSetMaxFH (maximum file
handles) parameter for the process allowed more
than 20 file handles to be open. There's a JLE
(0x7e) that should have been a JB (0x72). It
occurs in the following byte string (in hex):
3b 06 ?? ?? 7e 0d 9a
where the ?'s mark bytes that can change because
they refer to data locations that move from one
build of link.exe to the next.
(Since the problem is in the MS C library, the
bug could affect any C program that tries to
simultaneously open 20 or more handles with
stdio. So far, MS link.exe is only application
known to do this but there could be others.
patchlnk should work on them also and probably
even on your MS C library .lib files.)
patchlnk will scan through the file, looking for
occurrences, which it will report as hex offsets
from the start of the file you name. You can use
these numbers to go examine the file with IBM/MS
patch.exe if you like and make the change
manually.
You can also ask patchlnk to make the change,
using the -w (write) option. Nothing fancy. It
just changes the first occurrence and quits. (If
you really think you want any other occurrences
346
Help
patched, just keep rerunning this.) If want to
look for changes already made, use -c.
Options:
-h Help. (This screen.)
-c Look for changes already made.
-w Write the first change.
-- End of options.
popd: Pop a new Current Directory and Disk off the
Stack
Usage: popd [-dsh-] [ n ]
Pop an integer n directory paths from the top of
the stack, making the top one remaining the new
current directory and disk. The default for n is
1.
(See also the cd, dirs, pushd and rotd commands.)
Options:
-d Discard just stack entry n, counting from 0
at the top, popping everything below it up
one level
-s Silent. Don't print the resulting directory
stack.
-h Help.
-- End of options.
347
Help
ps: Print Process & Thread Status
Usage: ps [-sh-]
Show the status of all the screen groups (OS/2
only), processes and threads related to this
invocation of Hamilton C shell, highlighting the
current thread.
Screen groups are created when a command you type
requires a different style of window than is
currently running. Screen ids begin with `s'.
Processes are created when commands are typed
that require other executable programs to run.
Process ids begin with `p'. OS/2 and NT will only
provide information on direct child processes.
Threads are concurrent activities going on inside
Hamilton C shell. Some, such as the cleanup
activities that watch for other threads or
processes to end always run in the background.
Others are created when a command requires that
an internal function be run in the background.
Thread ids begin with `t'.
Options:
-s List details of all processes system-wide.
-h Help.
-- End of options.
348
Help
pushd: Push a new Current Directory and Disk onto the
Stack
Usage: pushd [ ]
-hs- [-c [n] ] [ directory ]
Go to a new current directory and disk, saving
the old values on the directory stack. If no
operands are given, swap the top two elements of
the stack. If the path you specify is just 3 or
more dots, pushd will interpret that specially.
Just as ".." means go up one level, "..." means
up 2 levels, "...." means up 3 levels, etc. If
the directory isn't found, the CDPATH is
searched.
(See also the cd, dirs, popd and rotd commands.)
Options:
-c Copy an item already on the stack onto the
top. This form takes an optional parameter
n which specifies the integer item number
counting from 0 at the top. Default is
n == 0.
-s Silent. Don't print the resulting directory
stack.
-h Help.
-- End of options.
349
Help
pwd: Print the Current Working Directories
Usage: pwd [-ch-] [ disk1 disk2 ... ]
pwd prints a list of the current directories. If
no disks are specified, pwd looks for a DRIVEMASK
environmental variable that can be used to mask
off just the drive you want reported. The
DRIVEMASK is specified as a list of drive
letters; ranges are allowed. Otherwise, all the
fixed disk partitions beginning with c: are
reported. The current directory on the current
drive is highlighted.
pwd routinely reports everything in lower case
for better readability. But pwd will look for an
environmental variable, MIXEDCASEDRIVES, giving a
list of drives, e.g., f-hq, meaning drives F:
through H: and drive Q:, which should be
displayed in mixed case.
Options:
-a If no disks are specified, report on all
disks.
-c If no disks are specified, report on just
the current disk.
-h Help.
-- End of options.
Colors:
You may set your own choices for screen colors
using these environmental variables:
Name
Use
Default
COLORS Normal screen colors White on
Black
HIGHLIGHT Current disk Bright
Colors recognized are black, red, green, yellow,
blue, magenta (or red blue), cyan (or blue green)
or white. Foreground colors may also be bright
or blink. The names of the colors and the words
bright, blink and on may be in either upper or
lower or mixed case but the names of the
environmental variables themselves must be all
upper case.
350
Help
Either or both the foreground and background
colors may be specified; if you don't specify a
value, it's considered transparent and inherits
the color underneath it. HIGHLIGHT inherits from
COLORS.
rehash: Reinitialize Path Hashing
Usage: rehash [-h-]
Hamilton C shell uses a hashing mechanism to
speed up searches of the path directories. If
you're performing system administration work,
moving files in the path directories, the hash
mechanism may not always reflect the latest
changes you've made. The rehash command allows
you to turn re-initialize the hash by re-reading
all the path directories and setting nohashing =
0. (The unhash command can be used to turn
hashing off.)
Options:
-h Help.
-- End of options.
351
Help
rm: Remove Files or Directories
Usage: rm [-rfHSxZilh-] pathname1 [ pathname2 ... ]
rm can delete both files and directories. If
you try to remove a file with one of the special
mode bits set (see chmod) or a directory that's
not empty, it'll refuse unless you use one of the
options to let it know that's really what you
mean.
Options:
-r Recursively remove non-empty directories.
-f Force read-only files or directories to be
removed.
-H Hidden files or directories can be removed.
-S System files or directories can be removed.
-x All of the above.
-Z Write binary zeros across any files being
deleted before removing them, thus
preventing anyone from recovering the data
using an "undelete" program.
-i Interactive: ask before removing each
object on the command line.
-l Logging is on: display the name of each
file or directory as it's removed.
-h Help.
-- End of options. (Useful if filenames start
with "-".)
rmdir: Remove Directories
Usage: rmdir [-h-] directory1 [ directory2 ... ]
rmdir will only remove empty directories. Mode
bits (system, hidden or read-only) are ignored.
Options:
-h Help.
352
Help
-- End of options.
rotd: Rotate the Directory Stack
Usage: rotd [-hs-] [ n ]
Rotate the directory stack an integer n
positions. Positive values cause upward
rotation; negative values cause downward
rotation. The default is upward rotation by one
position.)
(See also the cd, dirs, pushd and popd commands.)
Options:
-s Silent. Don't print the resulting directory
stack.
-h Help.
-- End of options.
353
Help
sed: Stream Editor
Usage: sed [-hinNs-] [-f scriptfile ] [-e script ]
[ script ] [ file1 file2 ...]
sed is a special text editor for use on streams
of data where it cycles, reading a line from
input, applying the editing operations you've
specified, and writing the result to stdout. The
input is read in a single pass and each line is
acted on only once.
The editing script can be specified on the
command line or, if it's long and complex, in a
file. If you want to combine a script on the
command line with any other script, you must use
the -e option. The editing operations available
are the usual search/replace, insert/delete, etc.
With each operation, you generally can specify
the lines in the file it should affect either by
line number or matching a pattern or a range of
lines.
Options:
-h Help. (This screen.)
-f scriptfile Read the script from a file.
Multiple -f options are allowed and
the scripts are concatenated.
-e script Take the following argument word as a
script. Multiple -e options are
allowed.
-i Ignore character case.
-n Don't automatically write the
contents of the edit buffer to stdout
at the end of each cycle.
-N Normalize any input to use the UNIX
convention of a simple \n character
to terminate each line, then re-
expand the text on output to follow
the \r\n convention used on a PC.
This option is useful in porting sed
scripts from a UNIX system.
-s Read the script from stdin. (The
input stream to be edited must be in
a file.)
354
Help
-- End of options.
Scripts:
The script is written as a series of commands,
each separated from the next by a line end or a
semicolon. The format of a command is:
[ address1 [ , address2 ] ] operation
Spacing between fields is arbitrary: you can use
spaces or tabs between fields or have none at all
as you prefer. Here are the fields:
address is a line number or regular
expression to be matched. When a
regular expression is used as an
address, it's normally written as
/regexp/ but it's also possible to
use the syntax \?regexp? where ? is
any character.
Zero- or One-Address Operations:
If you don't give an address, the
operation is applied to all lines.
If you give a single address, the
operation is done on each line that
matches.
Ranges:
When you give two addresses, you
define a range. A range can be a
single line, e.g., "3,3", or a whole
group of lines. If the addresses
involve pattern matching, e.g.,
/^#ifdef/,/^#endif/
the range might occur over and over
in the input and will be acted on
each time.
Most operations, e.g.,
search/replace, are done against all
lines in the range. The exceptions
are i\ (insert), which is acted on at
entry to the range; a\ (append), and
q (quit), which are acted on at the
end; and c\ (change), which deletes
all the lines in the range but
doesn't write any output until the
355
Help
end of the range.
operation is one of the 28 basic operations
provided, together with any arguments
it takes.
Operations:
There are two buffers in sed: the edit buffer and
the hold buffer. Most of the editing operations
work on the edit buffer, doing search/replace
operations, translating characters, and saving or
retrieving text in the hold buffer. sed
automatically puts each new line into the edit
buffer (along with its trailing line end) at the
start of each cycle unless there was something
left over after a D (delete head) command.
A second group of operations provide ways of
inserting blocks of static text.
The next group of operations provide rudimentary
ways of condition-testing and branching and of
nesting a series of operations together.
Finally there operations for printing and doing
other i/o and for other miscellaneous things.
Basic Editing:
d Delete this section. Start the next
cycle.
D Delete from the beginning of edit
buffer through and including the
first line ending. If there's text
remaining, immediately start over at
the top of the script without reading
a new line.
s/.../.../[ngpw] Search/replace using
regular expressions. In the replace
string, "&" means whatever the search
string matched. "\n", where n is a
number, means whatever matched that
tagged expression in the search
string. The search and replace
strings are shown here delimited with
/, but you may choose any character
you like that doesn't occur in either
string. The following modifiers are
accepted:
356
Help
n A decimal number from 1 to
65,535. Substitute for just
the n'th occurrence of the
search pattern.
g Global. Substitute all
occurrences.
p Print the edit buffer if a
change was made.
w file Write the edit buffer onto the
end of the file if a change
was made.
y/.../.../[c] Translate all occurrences of
characters in the first string to the
corresponding characters in the
second string. As in the tr utility,
ranges are allowed, as in
"y/a-z/A-Z/". The optional "c" flag
can be used to complement the input
range. Either string can contain \r
and \n characters. If the first
string is longer than the second, all
the extra characters are mapped to
the last character in the replacement
string or to a null if there was
none. If the second string is
longer, the extras are ignored.
Using the Hold Buffer:
g Get from the hold buffer. Replace
the current contents of the edit
buffer.
G Get from the hold buffer and paste
onto the end of the edit buffer.
h Hold. Replace the contents of the
hold buffer with a copy of the edit
buffer.
H Append to hold. Copy the edit buffer
contents onto the end of the hold
buffer.
x Exchange the edit and hold buffers.
Inserting blocks of Static Text:
a\
text Append the text to the output at the
end of the cycle if this is the last
line in the range. All but the last
line of text should have a "\" just
before the \r\n sequence at the end
357
Help
of each line.
c\
text Change this section to read as shown
in the following text. Start the
next cycle.
i\
text Insert. Immediately copy the
following text to stdout if this is
the start of the range.
Condition-Testing, Branching and Grouping
operations:
b label Branch to the label elsewhere in the
script. (If no label is given, it's
to the end of the script.)
q If this is the end of the range,
quit.
t label Branch to the label if search/replace
changes have been made since the most
recent input line was read or a t
operation was run.
: label Label. (No address prefix is
allowed.)
{...} Group a series of operations
together.
Printing:
= Write the line number to stdout.
l List the contents of the edit buffer
in C language style with escape
sequences for binary characters.
p Print. Write the contents of the
edit buffer to stdout.
P Print from the beginning of the edit
buffer through and including the
first line ending.
#n Suppress any automatic output at the
end of each cycle.
358
Help
Other I/O operations:
n Next line. Write the contents of the
edit buffer to stdout, dump any
appended text and read a new line
from stdin to the edit buffer.
N Read the next line onto the end of
the edit buffer with a \r\n sequence
in between.
r file Copy the contents of this file to
stdout at the end of the cycle.
w file Write the edit butter onto the end of
the file, creating it if it doesn't
exist.
Miscellaneous:
! operation Don't apply this function unless
the addressing doesn't match. Invert
the line selections.
; Null statement.
# comment Comments and blank lines are ignored.
If multiple a\ (append) or r (read file)
instructions are executed (or the same one is
iterated in a loop), a new entry is made on the
end of a list of all the appended text blocks to
be copied to stdout at the end of the cycle.
When the end of the cycle is finally reached, the
whole list is dumped, in order from the top.
Regular Expressions:
Search patterns are specified as regular
expressions like those used by grep. Regular
expressions are written in this notation, in
decreasing precedence:
c Any ordinary character matches
itself.
\c Match the literal character c.
Certain characters are treated
specially:
\a Audible Alert (Bell)
\b BackSpace
\f Form Feed
\n NewLine
359
Help
\r Carriage Return
\t Tab
\v Vertical Tab
\\ Single BackSlash
\x The next one or two characters
are treated as hex digits
specifying the character code.
^ Beginning of line.
$ End of line.
. Match any single character.
[...] Match any single character in the
list.
[^...] Match any single character not in the
list.
\n Match whatever literal text the n'th
tagged \(...\) expression matched.
r* Match zero or more occurrences of r.
r\{n\} Match exactly n occurrences of r,
where n is an unsigned decimal
integer.
r\{n,\} Match at least n occurrences of r.
r\{n,m\} Match at least n, but not more than m
occurrences of r.
r\{,m\} Match at most m occurrences of r.
r1r2 Match expression r1 followed by r2.
\(r\) Tagged regular expression. Match the
pattern inside the \(...\), and
remember the literal text that
matched.
A regular expression pattern cannot contain Nulls
but it can contain NewLine or CarriageReturn
characters (which may be useful with the N or G
commands.)
When typing a regular expression on the command
line, remember that $, [, ], ^, ( and ) have
special meaning to Hamilton C shell. Put single
quotes around the string to turn off that special
meaning. Also, even inside quotes, type ^^ to
mean ^ except when it immediately follows [.
360
Help
Also, / at the beginning of a word on the command
line is taken as introducing an option. If you
mean it to be the start of a script, use the "--"
option ahead of it.
361
Help
setrows: Set/Report the Number of Rows in the Display
Window
(OS/2 Version)
Usage: setrows [-h-] [ rows ]
setrows will try to set the vertical height of
the current window to the specified number of
rows. In a PM text window, almost any reasonable
number of rows can be chosen, but full-screen,
you can choose only from this set: 12, 14, 21,
23, 24, 25, 27 to 30, 33, 34, 39 to 43, 45 to 50
and 54 to 60. (Your hardware may not support all
these possibilities.)
If the number of rows is not specified, setrows
just reports the current value.
Options:
-h Help. (This screen.)
-- End of options.
362
Help
setrows: Set/Report the Number of Rows in the Display
Window
(Win32 Version)
Usage: setrows [-h-] [ buffer_rows [
[buffer_columns]
window_rows [windows_columns] ] ]
setrows will try to set the sizes of the console
buffer and of the visible window into it.
The exact effects of setrows, in addition to
reporting the current values, depends on the
number of arguments:
0 Don't change any settings.
1 Set the number of buffer rows, shrinking the
number of window rows as necessary.
2 Set the buffer and window rows.
3 Set the buffer and window rows and window
columns.
4 Set everything.
If the no arguments are specified, setrows just
reports the current values.
Note: Under Windows 95, not all settings
actually work. For example, attempting to set a
larger buffer size than window size (so you can
have a vertical scroll bar) is not generally
usable due to limitations in Windows 95.
Options:
-h Help. (This screen.)
-- End of options.
363
Help
sleep: Sleep for a Specified Period
Usage: sleep [-hm-] [ seconds ]
Sleep the specified integer number of seconds
(rounded to the next clock tick.) Default is 1
second or until an interrupt occurs.
Options:
-m Sleep interval is in milliseconds rather
than seconds.
-h Help.
-- End of options.
364
Help
sort: Sort and/or Merge Files
Usage: sort [-cmh] [-o output ] [-udfinNWrb] [-tT
char ]
[-k keydef ] ... [+pos1 [-pos2] ] ...
[ file ...]
Sort or merge lines of text from the named files
or from stdin if no file specification is given.
Comparisons are based on one or more sort keys
extracted from each line. By default, there is
one sort key, the entire line (minus any line
termination characters), and ordering is done
according to the ASCII collate sequence.
Options:
-c Check that the input is ordered as
specified. No output is produced.
Only the exit code is affected.
-m Merge only. The input files are
assumed to be already sorted.
-o output Write the output to file specified.
This can be the same as one of the
input files.
-u Unique: suppress all but one in each
set of lines having equal keys. If
used with -c, check that there are no
lines with equal keys.
Comparison Options:
The following options override default ordering
rules. When these options appear independent of
any key field specification, they apply globally
to all sort keys. When attached to a specific
key, they override any global ordering options.
-d Only blanks and alphanumeric
characters are considered in
comparing keys.
-f Case-independent comparison: upper
and lower case characters will
compare equal.
-i Ignore any non-printable characters.
365
Help
-n Interpret the field as integer data
which may contain optional leading
spaces, plus or minus sign, radix
character, commas as thousands
separators.
-N Like -n, but also accepts floating
point data containing fractional
components or exponents expressed in
E-notation, e.g., 1.0E-03 to mean
.001.
-W Use the Win32 CompareString function
to compare strings according to the
collate sequence specified by the
user's locale descriptor. Otherwise,
by default, the standard ASCII
collate sequence is used for much
greater performance. (Not supported
under OS/2.)
-r Reverse the sense of comparisons.
Field Separator Options:
-b Ignore leading or trailing spaces
when determining the starting and
ending positions of a sort key.
-t char Use char as the field separator
character; char is not considered to
be part of a field. Each occurrence
of char is significant so, e.g., char
char delimits an empty field.
-T char Like -t, but each maximal sequence of
char characters is considered a
single field separator. By default,
each maximal sequence of spaces is a
field separator.
Sort Key Specification:
-k keydef Define a sort key field. The format
of keydef is
field_start[type][,field_end[type]
]
where field_start and field_end
define the beginning and ending
points of a field as:
366
Help
field_number[.first_character]
where both fields and characters are
numbered starting from 1 and
specified as positive decimal
integers. If .first_character is
omitted from a field_start, the sort
key begins with the first character
of the field; if it's omitted from a
field_end, the key ends with the last
character of the field.
As a special case, a field number of
0 specifies the entire record. A
character number of 0 specifies the
last character of the field.
The type modifiers can be any
combination of b, d, f, i, n, N or r,
which behave just like the
corresponding options, except as a
modifier they affect only the
specified sort key. The b modifier
applies only to the field_start or
field_end to which it is attached.
If the -b option or b type modifier
is specified, characters within the
field are counted from the first non-
blank character.
When there are multiple key fields,
later keys are compared only after
all earlier keys compare equally.
Except when -u is specified, lines
that otherwise compare equally are
ordered as if no -d, -f, -i, -n, -N
or -k options were present and with
all bytes in the lines significant to
the comparison.
+pos1 [-pos2] An older form of key field
specification, now considered
obsolete by POSIX. The pos1 and pos2
entries specify the start and end of
a key just the way the -k option
would except that in this form,
fields and characters are numbered
starting at 0, not 1. A fully-
specified key of the form +pos1 -pos2
with type modifiers T and U:
+w.xT-y.zU
367
Help
is equivalent to:
-k (w+1).(x+1)T,y.0U (z == 0)
-k (w+1).(x+1)T,(y+1).zU (z > 0)
-h Help (short list.)
-- End of options.
Exit status:
0 All the input was sorted
successfully, or -c was specified and
the input was already sorted.
1 The -c option was specified and the
input was not ordered correctly or -
cu was specified and two lines sorted
equal.
>1 An error occurred.
source: Read Commands from a File
Usage: source [-eLnsh-
] [ filename ] [ arguments ]
Commands are executed just as if they were typed
directly in to this thread of Hamilton C shell
and can change local variables and current
directory settings.
(This differs from typing the name of a C shell
script file as a command; if you do that, a
separate thread is created.)
Options:
-e Execute only. No logging to history.
-L Load the history list only. No syntax
checking.
-n No Execute. Just do a syntax check and load
the history list.
-s Read commands from stdin.
-h Help.
-- End of options.
368
Help
369
Help
split: Split a Large File into Chunks
Usage: split [-bhssize-] [ infile [prefix] ]
split breaks up a large file into chunks, written
to a series of output files formed of the prefix
plus a .nnn extension, where nnn is a 3-digit
decimal number. The default prefix is `chunk'.
Each chunk will be of the specified number of
lines or bytes. If only one operand is given,
it's assumed to be the input filename unless -s
is specified.
Options:
-h Help. (This screen.)
-b Count bytes. (Default is lines.)
-s Stdin is split. (Implied if no files are
specified.)
-size Chunk size. (Defaults are 3000
lines/300000 bytes.)
-- End of options.
startwin: Start Win3.x Applications under OS/2 2.x
Usage: startwin [-h-] [-s type] [ file ] [
arguments ]
Start the specified Win3.x application in a
Virtual DOS machine using the WinStartApp API
call. This separate invisible PM application is
used to run the Windows application because:
(a) WinStartApp is the only way to start Win3.x
apps in seamless mode and
(b) the only way to find out when the Win3.x
child started by WinStartApp completes is
via a message queue -- and only PM
applications may have a message queue.
By default, standard mode is used under OS/2 2.0
and enhanced mode under OS/2 2.1. If seamless
support appears to be available, the default is
to run the application in a window using a common
370
Help
(shared) copy of the Windows code; otherwise, a
full-screen Windows session is used by default.
If the filename specified to startwin is not
fully-qualified, startwin will search for it in
the PATH directories. Just as with the C shell,
the current directory will be searched only if it
appears in the PATH list or if the file specified
is clearly a relative path (i.e., it contains a \
or / or a drive specification). If necessary,
startwin will append .exe to the name specified.
startwin is called automatically by the C shell
if you type the name of a Win3.x app as a command
under OS/2 2.x. The only reason you might
manually invoke startwin would be to override the
default session type.
Options:
-s type Session type to be used, overriding
the default type. Session type
numbers are as given in the OS/2
pmshl.h header, including the
following:
3.0 Standard Full-screen 11
3.0 Standard Seamless VDM 13
3.0 Standard Seamless Common 14 ª
2.0 default
3.1 Enhanced Seamless VDM 17
3.1 Enhanced Seamless Common 18 ª
2.1 default
3.1 Enhanced Full-screen 19
-h Help.
-- End of options.
371
Help
strings: Extract ASCII strings from a file
Usage: strings [-habetqvlodx-] [-min ] [-rradix ]
[ file1 file2 ... ]
strings will search for any occurrences of ASCII
text in the files you give it. The presumption
is that the files are mostly binary and perhaps
quite large, making it impractical to look at
them directly.
A string is normally defined as 4 or more
printable ASCII characters terminated by a Null,
CarriageReturn, a NewLine or a CarriageReturn-
NewLine combination. All the white space
characters are considered printable and are
included in the length count except when they
terminate a string. (To C programmers, these
printable ASCII characters are the isprint() and
isspace() characters.)
If you specify a series of files, they're
searched one after the other, each one introduced
by name unless you specify Quiet mode. Each
string that's found is listed on a separate line.
Note that if a particular string contains NewLine
or CarriageReturn characters, it will be
displayed as a series of (possibly) very short
substrings, one per line.
Options:
-h Help. (This screen.)
-min Minimum string length to report,
specified as a decimal integer.
-a Any string, even if not terminated with a
line ending or a null character.
-t Trim leading white space from each string.
-b Discard strings containing only white space.
-e European characters (accented alphabetics
and European punctuation) will be considered
as ordinary printable text.
-n Control characters other than Tab,
CarriageReturn and NewLine will be
considered to be string terminators just
like the null character.
372
Help
-q Quiet mode. Don't announce the name of each
file as it's read.
-v Verbose. Paste the name of the file in
which it occurs onto the front of each
string.
-l Long mode. Show where each string occurs,
counting bytes from the beginning of the
file. The radix used can be explicitly
chosen with -o, -d, -x, or -r; it defaults
to the value specified by the RADIX
environmental variable if defined or 16
otherwise.
-o Octal offsets.
-d Decimal offsets.
-x Hex offsets shown.
-rradix User-specified radix.
-- End of options.
373
Help
sum: Checksum the Contents of a File
Usage: sum [-prxh-] [ file1 file2 ... ]
sum checksums the contents of each of the files
you specify, writing the results to stdout along
with a count of the number of 512-byte blocks it
read (including any partial blocks.) If no files
are given, sum reads from stdin. sum is
typically used to validate a file communicated
over a possibly noisy communications line.
sum treats the characters it reads as 8-bit
unsigned integers and normally just adds them
together to form a 16-bit unsigned result.
Overflows are ignored.
Options:
-p POSIX checksum. Use the ISO-8802-3 CRC-32
polynomial to calculate a cyclic redundancy
check for each input file and to write that
value along with a count of the number of
bytes (not blocks) to stdout.
-r Rotated checksum. Rotate the accumulated
checksum right one bit position before
adding each character.
-x Xor'ed checksum. For each new character, c,
the checksum, i, is calculated as
i += (i << 1) ^ c.
-h Help. (This screen.)
-- End of options.
(The default and rotated checksums are the same
as those calculated by the UNIX System V sum
command; the xor checksum is unique to this
implementation.)
374
Help
tabs: Expand/Unexpand Tabs
Usage: tabs [-hua-] [-tabs ] [ file1 file2 ... ]
tabs expands tab characters into spaces or, if -u
is specified, unexpands spaces into tabs as it
copies the input files to stdout. If no files
are given, tabs reads from stdin. If multiple
files are given, they're concatenated one after
the other to stdout.
When unexpanding, only leading white space is
normally converted to tabs. If -a is specified,
tabs are inserted anywhere they would replace two
or more characters.
Options:
-h Help. (This screen.)
-u Unexpand tabs.
-a Unexpand all tabs.
-tabs Tab settings to use for viewing text.
Default is to use value given by the
TABS environment variable or, if
that's undefined, to assume tabstops
every 8 characters. If desired, a
list of tabstops can specified,
separated by commas; the difference
between the last two tabs given is
used a standard increment for
following tabs.
-- End of options.
375
Help
tail: Copy the Last Few Lines or Bytes of a File to
Stdout
Usage: tail [-hcfnq-] [-isec ] [-mmsec ] [-+start ]
[-ttabs ] [ file1 file2 ... ]
tail copies the last part of the file you specify
onto stdout. You may specify where to begin
copying in either lines or bytes measured from
either the beginning or the end of the file. If
no file is given, tail reads from stdin. If
several files are given, each is announced unless
you specify quiet mode.
Options:
-h Help. (This screen.)
-c Count characters. (Default is lines.)
-f Follow. At end of file, go into an endless
loop, sleeping for a second, then waking up
to see if more data's been added. (Use ^C
to exit.) The follow option is not valid if
more than one file is specified and is
ignored if data is being read from a pipe.
-isec Interval in seconds between checking
for more data if -f option is used.
(If the interval specified is greater
than one second, tail will
temporarily drop back to a one second
interval anytime it finds new data
when it does wake up.)
-mmsec Interval in milliseconds between
checking for more data if -f option
is used.
-start Starting point, relative to the end
of the file. (Default is last 10
lines or 512 bytes.)
+start Starting point, relative to the start
of the file.
-ttabs Tab settings to use for viewing text.
(Default is to use value given by the
TABS environment variable or, if
that's undefined, to do no tab
expansion.)
376
Help
-n No tab expansion.
-q Quiet mode. Don't announce the name of each
file it's read.
-- End of options.
377
Help
tar: Read/Write UNIX TAR and CPIO Format Files
Usage: tar [-acCtMxXyh ADNFLvpPqsS!rRTfQVwWZ-]
[-d dir ] [-m map ] [-g hours ] [-G
hours ]
[-O offset
] [-E endset ] [-b sex ]
[-B blksize ]
[-Hon|-Hoff] [-I include ] [ tarfile
]
[ file1 file2 ... ]
tar is used to read or write a simple archive
format popular for exchanging files between
dissimilar machines.
tar normally expects the archive to be in a file
specified by the tarfile operand. When listing
or extracting files, the file names that follow
are considered to be in the name space of what's
in the archive; if wildcards are used, they
should be enclosed in single or double quotes so
the C shell won't try expanding them before tar
sees them. When adding files, the names are in
the user's normal file name space and wildcards
can be used in the normal fashion.
When reading an archive, this tar program
automatically detects whether it was written in
CPIO or TAR format and what bytesex was used.
When extracting files, this version of tar
incorporates logic to interactively crunch up a
filename in the archive into something legal on
an OS/2 or NT filesystem. If -F is specified (or
you're using OS/2 1.1), FAT naming rules are
enforced. Otherwise, HPFS or NTFS rules are
assumed, meaning long filenames are assumed to be
legal. Any renamings will be listed in a .map
file.
tar also incorporates logic to automatically
convert between the \n line endings used in an
archive and the \r\n line endings used under NT
unless the file appears to be binary, based on
its content. The environment variables TARBINARY
and TARASCII can also be used to specify sets of
files by name which are to be considered binary
or ASCII, respectively, regardless of content.
Each of these variables may contain a list of
wildcards. If a filename or just the tail of it
(i.e., just the name + extension, leaving off the
preceding path) matches one of the wildcards in
378
Help
the list, that file is considered to be of the
specified type. If a filename matches both lists
or if it matches neither list, the usual test
based on file content will be made. Files that
receive line end conversions are highlighted in
the listings produced by tar in the ASCIICONVERT
color for easy review.
Under Windows NT, the tarfile can be the tape
device, called \\.\tape0 (or \\.\tape1,
\\.\tape2, etc., if you have more than one).
When reading/writing to a tape, tar rewinds the
tape when it starts up and again when it finishes
unless -N is specified.
Note: Tape devices are not currently supported
under Windows 95. Tar can still be used
read/write tar-format archives stored as ordinary
files under Windows 95, however.
Basic Commands:
-a Add files to the end of the archive. Under
Windows NT, if the archive is on a tape
device, this operation may not be possible,
depending on whether your drive supports
repositioning and rewriting the last
physical block on the tape. For example, it
works with DAT drives but not with QIC
drives. If -a does not work with your
drive, you'll have to use -c instead.
-c Create a new archive, truncating any
existing archive to zero bytes before
writing to it.
-C Copy entire archive segments (including
headers and any padding) to stdout. After
the last segment, write a trailer to mark
the end of the archive. (If you intend to
concatenate archives, use the -Z option to
suppress writing the trailer.)
-t List the contents of the archive. This is
the default.
-M Just build a mapfile for renaming files in
the archive to OS/2 or Windows NT
conventions; don't extract anything.
-x Extract files from the archive. Default is
all files in the archive.
379
Help
-X Extract everything except the specified
files from the archive.
-y Copy the specified files in the archive to
stdout.
-h Help. (This screen.)
Basic Options:
-A The Archive bit is reset for any files or
directories copied to a TAR or CPIO archive
file. (When extracting files, the -A option
is ignored and the Archive bit is always
set.)
-D Dim. Don't insert ANSI escape sequences
into the output to highlight anything.
-N No rewind. If the tarfile is on a tape
device, don't do the automatic rewinding tar
would normally when it starts and finishes.
-F FAT filesystem naming. (Automatically
chosen if the OS/2 release level < 1.2.)
-B blksize Use specified blocksize when creating
a new archive. Default is 10240
bytes if supported by the device.
When reading or adding to an existing
archive, tar tries to determine and
use whatever blocksize was used when
the archive was created. How it does
that depends on what release of
Windows NT you're running and on
whether your drive supports variable
blocksizes. If you're running NT
3.51 or later and variable blocksizes
are supported, this option is ignored
and the actual blocksize is
determined directly using variable
blocksize support. Otherwise, tar
first tries this specified blocksize;
if that doesn't work, it tries all
the possible multiples of 512 bytes
up to the maximum supported on your
machine.
-V Don't use variable block I/O even if the
drive claims it supports it. Useful as a
workaround if your drive's firmware has a
bug.
380
Help
-Hon Hardware compression on, if
supported. (Default is to use the
current setting for compression.)
-Hoff Hardware compression off.
-L Long listing similar to ls -L showing the
attributes, timestamp and length of each
file in the archive.
-v Verbose. Like -L, but also show the offset
of each file from the beginning of the
archive and what archive format and bytesex
was used. Also turns on warnings about
line-end conversions being turned off on
binary files.
-p CPIO format, using binary headers.
-P CPIO format, using ASCII headers.
-q Quiet. tar normally prints the header of
each file as it's extracted (-x) or added (-
a or -c) to the archive. This option turns
that off.
-s Read the archive from stdin when listing
table of contents or extracting. Write the
archive to stdout when adding files.
(Implies non-interactive.)
-S Stop if a file is encountered that cannot be
extracted. Normally, a warning message is
given but processing continues.
-! Non-interactive. Files are renamed as
necessary for OS/2 or Windows NT
conventions. (Particularly useful with -M
when trying to read a new, large archive
file.)
-r CarriageReturn/NewLine expansion is turned
off. (Default is normally to convert between
\n in the archive and \r\n under OS/2 or NT
unless the file appears to be binary.)
-R CarriageReturn/NewLine expansion is forced
ON, even for files that appear to be binary.
-T Total the sizes of all selected files.
-- End of options.
381
Help
Advanced Options:
-d dir Default destination drive and
directory when extracting files.
-m map Specific filename to be used for
showing mappings from names in the
archive to names used on OS/2 or
Windows NT. (If -M is specified, but
-m isn't used to specify a name for
the mapfile, the default is to paste
a .map extension onto the name of the
tar file; if -s is specified, no map
file is used unless -m is given.)
-f Fullpath option. Put the full
pathname (minus any disk prefix)
specified on the command line into
the archive header when adding. (In
this context, the full path means the
full name given on the command line,
not the fully-qualified name starting
from the root directory.) When
extracting, use the full pathname
given in the header to determine
where the files will go.
-ff Another variation on the fullpath
option that will put the entire
pathname, even including the drive
letter into the tar archive. The
resulting name isn't really legal in
a tar file, but it's useful for doing
backups of several drives at once.
-g hours The number of hours GMT is ahead of
the local zone, e.g., 5 hours in New
York or 8 hours in California. U.S.
daylight savings is assumed in the
summer months. (OS/2 only.)
-G hours Same as -g, but without daylight
savings adjustments. (Under OS/2, if
neither -g nor -G is specified, tar
looks for a TZ variable in the
environment; if it's not defined, tar
ignores the difference between local
time and GMT used in the archive.
Under Windows NT, the -g and -G
options and the TZ variable are
unnecessary since the system keeps
track of the difference between local
time and GMT.)
382
Help
-O offset Offset at which to start reading the
archive file. Given in bytes from
beginning of the file.
-E endset Offset at which to stop reading the
archive file.
-b sex Bytesex in the archive: abcd (little
endian), badc (big-endian), cdab or
dcba. Default is to autosense
bytesex in existing archives and to
use abcd in new archives.
-bL Little-Endian bytesex. (An alias for
-b abcd.)
-bH Big-Endian bytesex. (An alias for -b
badc.)
Note: To write an archive intended
to be read on a RISC or
Motorola-based UNIX machine,
use -b badc or -bB (big-
endian).
-I include Files to be added to or read from the
archive are specified in the include
file. If the name of the include
file is given as "-", the names will
be read from stdin. If more than one
-I include file is given, the lists
of names they hold will be
concatenated, one after another. Any
files specified on the command line
will be added onto the end.
-Q Very Quiet. tar normally warns of
any garbled sections that it skipped;
this turns off those warnings also.
-w Share all files being copied to the
archive for read/write access by
other processes. (Default is to do
that only with files already open by
another process.)
-W Warnings. Show just the files that
can't be extracted to OS/2 or NT
because of their file types. (Shown
in the FOREIGNFILES color.)
-Z Suppress writing the trailer normally
written following the last segment
extracted from an archive with the -C
option. (Useful for concatenating
383
Help
segments extracted from several
separate archives.)
Examples:
1. To list the contents of a tar file on tape,
showing the timestamps and sizes of the
files:
tar -L \\.\tape0
(All these examples of reading or writing an
archive on tape assume Windows NT; if you're
on OS/2, substitute the name of a file on
disk for \\.\tape0.)
2. To extract everything on the tape into the
current directory, again showing timestamps
and sizes:
tar -xL \\.\tape0
3. To copy all the *.c files in the current
directory to a new tar tape, overwriting
anything that may already be on the tape,
again showing timestamps and sizes:
tar -cL \\.\tape0 *.c
4. Same as (3), but write it in big-endian
format, suitable for a UNIX RISC machine
(Sparc, SGI, etc.):
tar -cLbB \\.\tape0 *.c
5. Same as (3), but adding files to an existing
archive on the tape rather than overwriting
it:
tar -aL \\.\tape0 *.c
Note: Adding to an archive on tape isn't
supported by all types of tape drives. See
the comments regarding the -a operation
above.
6. Extract everything on a tar-format floppy
into the current directory:
dskread a: | tar -xsL
7. Write all the *.c files in the current
directory to a tar-format floppy in big-
384
Help
endian format, verifying each write
operation along the way:
tar -cs *.c | dskwrite -vx a:
TAR Format:
Tar files are organized as a series of 512-byte
blocks. Individual files always start on a block
boundary with a header block followed by the
uncompressed data in the file. At the end of the
file are two blocks filled with binary zeros.
The header has the following format:
typedef struct {
char name[100],
mode[8],
userid[8],
groupid[8],
filesize[12],
timestamp[12],
checksum[8],
linkflag,
linkname[100];
unused_chars[255];
} tar_header;
Everything is in ASCII with nulls and spaces to
punctuate the fields. Numbers are always in
octal. The mode, user and group ids aren't
meaningful on OS/2 and NT and are ignored when
extracting and just filled in with read/write for
owner, owned by root when adding. The timestamp
is in seconds since Jan 1 00:00:00 GMT 1970. The
checksum is calculated as if the field contained
spaces. The linkflag tells the file type,
reported in the long listing as one of the
following:
- Normal File
D Directory
L Link (not a separate file,
just another name for one that
already exists)
S Symbolic Link
C Character Device
B Block Device
F FIFO
385
Help
Under OS/2 and NT, only the normal files and
directories have any meaning. Directories are
highlighted. The other file types are reported
in bright red but otherwise ignored.
CPIO Format:
If -p is specified, tar will read and write cpio
format files, using binary headers of the
following format:
typedef struct {
short magic, /* Always 0x71c7 ==
Octal 070707 */
dev; /* Device containing
directory
entry for this
file. */
ushort inode, /* UNIX inode number.
*/
mode,
userid,
groupid,
nlink,
rdev; /* Device ID for
special
files. */
ulong timestamp;
ushort namelen; /* including trailing
null. */
ulong filesize;
char name[ namelen rounded to word ];
} cpio_header;
The dev, inode, mode, userid, groupid, nlink and
rdev fields are not meaningful on NT and are
ignored when extracting and filled in with 0,
read/write by owner, 0, 0, 1 and 0, respectively,
when writing.
If -P is specified, tar will read and write cpio
format files using the alternate ASCII format
headers, where each ushort is written as a 6-
character octal number, each ulong as an 11-
character octal number, and name is null-
terminated.
In a cpio file, data immediately follows the
header and is not padded to a block boundary.
Colors:
You may set your own choices for screen colors
using these environmental variables:
386
Help
Name
Use
Default
COLORS Normal screen colors White on
Black
DIRECTORIES Directories Bright
ASCIICONVERT ASCII files receiving Bright
Yellow
line end conversion
FOREIGNFILES Filetypes not supported Bright
Red
by OS/2 and NT
Colors recognized are black, red, green, yellow,
blue, magenta (or red blue), cyan (or blue green)
or white. Foreground colors may also be bright
or blink. The names of the colors and the words
bright, blink and on may be in either upper or
lower or mixed case but the names of the
environmental variables themselves must be all
upper case.
Either or both the foreground and background
colors may be specified; if you don't specify a
value, it's considered transparent and inherits
the color underneath it. DIRECTORIES,
FOREIGNFILES, and ASCIICONVERT inherit from
COLORS.
If the -D (dim) option is specified, all
highlighting is turned off, regardless of the
settings for these environment variables.
tee: Copy Stdin to Stdout and to Each File Specified
Usage: tee [-ah-] file1 [ file2 ... ]
tee is a "pipe-fitting" utility for snapshotting
the data passing through the middle of a
pipeline.
Options:
-a Append to any output files that already
exist instead of truncating and overwriting
them.
-h Help.
-- End of Options.
387
Help
touch: Create File or Set Modification Time
Usage: touch [-rfc2wh-] [ mmddhhmm[ss][[yy]yy]] ]
pathname1 [ pathname2 ... ]
touch sets the timestamp on a file to the current
or specified date and time. If the file doesn't
exist, the normal action is to create it.
Windows 95 and OS/2 1.1 ignores attempts to
change a directory timestamp. It works under
Windows NT or OS/2 1.2 or later.
Options:
mmddhhmmssyyyy Month, Day, Hour, Minutes,
Seconds and Year in decimal.
(If the century isn't specified,
81 to 99 is interpreted as 2000
to 2080.) If only 10 digits are
specified, touch interprets the
last two digits as seconds if
they're less than 60; otherwise,
it interprets them as the year.
-r Recursively touch contents of directories.
-f Force Read-only files to be touched also.
-c File is not created if it doesn't already
exist.
-2 Two second granularity for compatibility
with FAT and HPFS filesystems.
-w Give a warning message but continue trying
to touch any remaining files or directories
even if problems were encountered with some
of them.
-h Help.
-- End of options.
388
Help
tr: Translate Characters Filter
Usage: tr [-cdsnh-] [ string1 [string2] ]
tr is used to perform simple character
substitutions as it copies data from stdin to
stdout. Individual characters in string1 are
mapped to the corresponding characters of
string2. If string2 is too short, it is padded by
duplicating its last character. In either
string, the minus sign can be used to indicate a
range of characters.
Here's an example which creates a list of all
the words in file1, one per line, in file2, where
a word is taken as a maximal string of
alphabetics. (The ^n character is expanded by
the C shell into a newline character.)
% tr -csn A-Za-z ^n file2
Options:
-h Help. (This screen.)
-c Complement the set of characters in string1.
-d Delete any occurrences of the characters in
string1. (If present, string2 is ignored.)
-s Squeeze all strings of repeated output
characters in string2 to single characters.
-n Normalize line endings. Ensure that every
line ends with \r\n. Fixup any \r or \n by
itself or any reversed \n\r character pair.
When squeezing, normalization also causes
repeated \r\n sequences to be squeezed if
either \r or \n is in string2.
-- End of options.
389
Help
unhash: Turn off Path Hashing
Usage: unhash [-h-]
Normally, a hashing mechanism is used in an
attempt to speed up searches of the path
directories. If you're performing system
administration work, moving files in the path
directories, the hash mechanism may not always
reflect the latest changes you've made. The
unhash command can be used to turn hashing off,
setting nohashing = 1.
(See also the rehash and hashstat commands.)
Options:
-h Help.
-- End of options.
390
Help
uniq: Report Unique Lines in Text Files
Usage: uniq [-hbcdiuw-] [-f fields ] [-s chars ]
[-n] [+m] [ file1 file2 ... ]
uniq does a quick, simple string comparison of
adjacent lines in text files, normally just
discarding any duplicates as it copies its input
to stdout.
There are some diff-style options for ignoring
upper-/lower-case differences or treating white
spaces of any length as equal, etc. Also, you
can optionally choose to list only the lines that
occur just once or only those that have
duplicates.
If several files are given, the effect is the
same as if they were pasted together, one right
after another into one long file.
Options:
-h Help.
-b Blank spaces of any length compare equal.
Ignore any leading or trailing white space
on each line.
-c Preface each line with a count of the number
of times it occurred.
-d Duplicates. Only the lines which have at
least one duplicate are reported.
-i Ignore character case.
-u Unique lines. Only the lines which occur
only once are reported.
-w White space is ignored totally.
-f fields Ignore the first fields fields on
each input line when doing
comparisons, where fields is a
positive decimal integer. A field is
defined as a maximal string of tabs
or spaces followed by non-tab, non-
space characters.
-s chars Ignore the first chars characters
when doing comparisons. If used in
391
Help
conjunction with the -f option, the
first chars characters after the
first fields fields will be ignored.
-n An older form of field specification, now
considered obsolete by POSIX. Equivalent to
-f n.
+m An older form of character specification, no
considered obsolete by POSIX. Equivalent to
-s m.
-- End of options.
Uuencode or Uudecode Binary Data
Usage: uudecode [-h-] [ file1 file2 ... ]
uuencode [-h-] [
-m mode ] [ file ]
decode_pathname [-ca- source1
[ source2 ... ] destination ]
Uuencode and uudecode are used to encode
arbitrary binary data into a sequence consisting
solely of printable ASCII characters, thus
allowing the data to be sent over mail systems,
etc., that cannot handle binary data.
Uuencode reads from the source file (or stdin if
no source file is specified), writing the encoded
version to stdout.
Uudecode reads the encoded file (or stdin),
strips off any leading and trailing lines and
recreates the original file, giving it the name
that had been specified to uuencode as the
decode_pathname parameter.
Uuencode format:
The encoded form consists of a header line
followed by a number of body lines and a trailer
line. The header is of the form:
begin mode decode_pathname
where the mode field indicates the read/write
permissions to be given to the file. The file
ends with a line of the form:
end
392
Help
Both these lines shall have no preceding or
trailing text or white space.
The POSIX standard specifies that the "end" line
should be the only indicator of the end of data.
Most existing uudecode implementations do not
adhere to this specification, however. Instead,
they require that there be an immediately
preceding line marked as containing 0 bytes of
data. To ensure compatibility with these flawed
uudecodes, this uuencode/uudecode pair will write
that dummy line when encoding and ignore it when
decoding.
Data is encoded three bytes at a time into four
printable ASCII characters by splitting the input
at 6 bit intervals into 4 bytes, each containing
data in only the lower 6 bits. The hex value
0x20 is then added to each byte, producing a
value in the range 0x20 to 0x5f, which are all
printable ASCII characters. Thus, three bytes A,
B and C of raw data are converted to the four
ASCII characters:
0x20 + (( A >> 2 ) & 0x3f)
0x20 + (((A << 4) | ((B >> 4) & 0xf)) & 0x3f)
0x20 + (((B << 2) | ((C >> 6) & 0x3)) & 0x3f)
0x20 + (( C ) & 0x3f)
The encoded data is arranged into lines of no
more than 60 characters (representing at most 45
bytes of raw data) preceded by a length
character, equal to the number of raw characters
encoded plus 0x20.
Some existing uuencode implementations do not
correctly follow this specification. If the
resulting character is a space, they'll write a
backquote instead. Their decoding procedure is
to extract only the low 7 bits after subtracting
0x20. This extra step is, fortunately, innocuous
on correctly encoded data, so for compatibility
with existing uuencodes, this version of uudecode
performs that mask operation also.
Although not required by the POSIX standard, this
version of uudecode has a number of enhancements:
1. It will accept input streams containing any
number of uuencoded files concatenated
together. Each will be properly extracted
as a separate file.
393
Help
2. If any directory levels in the output are
missing, an attempt will be made to create
them.
3. The tilde is recognized as a home directory
reference in the decode_pathname.
Uuencode Options:
-m mode Mode to be specified for the file.
Default is to simply fill in 666,
meaning read/write access by everyone
for normal files or 444, meaning
read-only access by everyone for
files marked as read-only.
-c Alternate cp-style syntax. Instead of using
stdout to write the output and having to
explicitly specify the name to be given to
each file in the uuencoded form, this option
allows one to simply copy any number of
files or directories into the uuencoded
output file. The name that will be written
into the header will be just the tail of the
filename, just as cp would do.
-a Like -c, but appending. If the output file
already exists, this will append onto the
end.
General Options:
-h Help. (This screen.)
-- End of options.
verify: Turn Write Verification Mode On or Off
Usage: verify [-h-] [ mode ]
When verification mode is turned on, the system
will always verify that any data written to a
disk can be read back. The mode can be specified
as 0 or off, the default, or 1 or on. If no
arguments are given, verify simply reports the
current mode. Under Windows NT, verify is always
on.
Options:
-h Help.
394
Help
-- End of options.
395
Help
vol: List Volume Labels
Usage: vol [-ach-] [ disk1 disk2 ... ]
vol reports the volume label information on each
of the specified disks. If no disks are
specified, vol looks for a DRIVEMASK
environmental variable that can be used to mask
off just the drive you want reported. The
DRIVEMASK is specified as a list of drive
letters; ranges are allowed. Otherwise, all the
partitions beginning with c: are reported. The
current disk's label information is highlighted.
This command is normally stored in the file
vl.exe and invoked via an alias so it can be used
from cmd.exe without colliding with the internal
cmd.exe vol function.
Options:
-a If no disks are specified, report on all
disks.
-c If no disks are specified, report on just
the current disk.
-h Help.
-- End of options.
Colors:
You may set your own choices for screen colors
using these environmental variables:
Name
Use
Default
COLORS Normal screen colors White on
Black
HIGHLIGHT Current disk Bright
Colors recognized are black, red, green, yellow,
blue, magenta (or red blue), cyan (or blue green)
or white. Foreground colors may also be bright
or blink. The names of the colors and the words
bright, blink and on may be in either upper or
lower or mixed case but the names of the
environmental variables themselves must be all
upper case.
396
Help
Either or both the foreground and background
colors may be specified; if you don't specify a
value, it's considered transparent and inherits
the color underneath it. HIGHLIGHT inherits from
COLORS.
wait: Wait for Children to Complete
Usage: wait [-h-]
Sleep until a child thread or process completes
or until an interrupt occurs.
Options:
-h Help.
-- End of options.
wc: Count Words (and lines and characters)
Usage: wc [-lwr-] [ file1 file2 ... ]
wc prints counts all the lines, words and/or
characters in each of the files specified, and
totals for the whole list. If no files are
specified, it counts stdin.
Options:
-l Count lines
-w Count words
-c Count characters
-h Help.
-- End of options.
The default is -lwc.
397
Help
whereis: Find where executable files are located
Usage: whereis command
whereis is a self-loading procedure that searches
all the directories on the path, looking for a
.csh, .exe, .com, or .cmd file corresponding to
the command specified. All occurrences are
printed.
xd: Hex Dump a File to Stdout
Usage: xd [-hbwlFD Zdxor nNq-] [-rradix ]
[-O offset ] [-E endset ]
[-L[items] ] [ file1 file2 ... ]
xd dumps its input, presumed to be in binary, in
variety of formats, the default being hex. If
more than one file is given, each is dumped in
sequence. If no files are specified, xd reads
from stdin. Sequences of lines containing the
same data are collapsed out and replaced by an
asterisk.
Options:
-h Help. (This screen.)
Basic display formats:
-b Bytes. (Default.)
-w 16-bit words.
-l 32-bit long words.
-F Short 4-byte floating point. Floating point
values are always displayed in decimal.
-D Double-precision 8-byte floating point.
-Z Suppress leading zeros. Normally, leading
zeros are shown except when displaying in
decimal.
Radix to be used for offsets and data:
-d Decimal (unsigned).
-x Hex.
398
Help
-o Octal.
-rradix User-specified radix. If a radix < 8
is chosen, offsets are always shown
in hex.
Other options:
-O offset Offset at which to begin dumping.
-E endset Offset at which to stop dumping.
-L[items] Number of items (bytes, words, etc.)
to dump. If -L is specified, the
default is one.
-n No ASCII column.
-N No offset column.
-q Quiet mode. Don't announce the name of each
file as it's read.
-v Verbose. Show lines of repeated data.
-- End of options.
399
Help
400
Index
INDEX
-- 114, 116, 208 * 95, 114, 208, 215,
- 114, 208
! 81, 114, 117, 206, ** 114, 117, 186, 208
208, 239, 254 **= 114, 186, 209
-! option 30, 59 *= 114, 209
242, 245
!! 82, 184, 220, 246 ... 98, 215
!$ 83, 220 .cshrc 189
!* 83, 220 .history 189
!? 83, 104, 220 .login 189
!^ 83, 220 .logout 189
!~ 114, 118, 208, 215, / 114, 208
216 // 114, 117, 208
!= 114, 117, 208 //= 209
!-1 184, 246 /= 114, 209
!-n 220 /K "%*" 160
!n 220 :# 187, 225
!str 220 :$ 103, 104, 225
"_" 109, 222 :% 103, 104, 225
# 189, 205 :& 225
#!/bin/csh 189, 191 :* 103, 225
$#var 224 :^ 103, 104, 225
$$ 235, 245 :A 187, 227
$* 224 :b 187, 227
$?var 224 :e 227
${var} 88, 224 :f 227
$< 224 :g 104, 225
$0 .. $9 140, 224 :h 105, 227
$var 88, 224 :L 187, 227
% 84, 114, 117, 208, :m 187, 227
220 :n 103, 225
%% 84, 267 :n- 225
%= 114, 209 :n* 225
%c 267 :n-m 104, 225
%d 267 :p 103, 105, 226
%e 267 :q 105, 225
%f 267 :r 227
%g 267 :s/str1/str2/ 104,
%o 267 225
%s 267 :t 227
%x 267 :x 105, 226
& 104, 114, 118, 148, ; 114
206, 208 ? 95, 215
&& 114, 118, 119, 127, ?: 119, 208
128, 206, 208 @ statement 91, 113,
&= 114, 209 199, 245
( ) 114, 206, 208 @ variable 242
401
Index
[ ] 113, 114, 184,
208
=~ 114, 118, 208, 215
[^a-z] 215 73, 74, 114, 117,
== 114, 117, 208
>
[a-z] 215 206, 208
\.\a: 211 >! 74, 206
\.\tape0 211, 234, >& 75, 206
258, 339, 379 >&! 206
^ 73, 84, 110, 114, >= 114, 117, 208
118, 208, 222, 231, >> 73, 74, 114, 116,
235, 250 206, 208
^^ 111, 223 >>! 74, 206
^= 114, 209 >>& 206
^a 111, 222 >>&! 206
^b 111, 222 >>= 114, 209
^f 111, 222 '_' 110, 222
^n 111, 222 -A 114, 208, 210
^r 111, 222 abs() 264
^t 111, 222 Absolute value 264
^v 111, 223 acos() 264
^Z 61, 167 ADDITIONS 165, 229,
`_` 76, 77, 222 245, 307
{ } 119, 208 Alias arguments 123
{a,b}c 215 Alias statement 28,
| 75, 114, 118, 206, 30, 40, 100, 101, 121,
208 122, 167, 183, 185,
|& 75, 206 188, 198, 277, 279, 280
|| 114, 118, 119, 127, Alt key 41
128, 206, 208 Alt- 218
|= 114, 209 Alt- 218
~ 95, 114, 116, 208 Alt- 42, 221
+ 114, 208 Alt- 203
++ 114, 116, 208 Alt- 218
+= 114, 209 Alt- 42, 219
< 114, 117, 206, 208, Alt- 219
242, 245 Alt- 219
<< 77, 114, 116, 206, Alt- 218
208 Alt-D 43, 216
<<= 114, 209 Alt-Enter 32
<= 114, 117, 208 Alternation 95, 97, 98,
41, 42, 218 99, 118, 215
41, 218 Alt-F 42, 216
219 ANSI escapes 32, 49, 76,
203 187, 213, 222, 265,
41, 218 271, 307
41 ansi() 265
218 app 277
219 Append to a file 206
219 arc 62
41, 218 Archive bit 210, 290
216 args 177
41, 42, 218 argv 140, 142, 177,
-= 114, 209 184, 224, 238, 242, 245
= 114, 117, 209 Arrays 90
=// 114
402
Index
ASCIICONVERT 229, 245, bsdhistory 167, 168,
379, 387 184, 235, 246
asin() 264 Bug Reports 35
Assignment operators Built-in Procedures
117, 209 263
atan() 264 Built-in Utilities
Attribute bits 50 269
Audible alert 222 bumpdate.csh 177
aux port 211 bytesex 70, 383
Background activities -C 208, 210
87, 148, 149, 153, c:\autoexec.bat 6, 8
188, 206, 282 c2f.csh 178
Background colors 165 calc statement 113,
Backquotes 76, 77, 222 186, 199
Backspace 222 caldate.csh 177
bad blocks 318 calendar.csh 177
base operator 227 Calling a Procedure
Basic statements 40, 137
193 callstack tracing 284
beep 277 Carriage Return 222
bell 222 case statement 130,
Berkeley 4.3 Buglist 184, 195
183 cat 271, 288
Berkeley Compatibility cd 162, 269, 288
Mode 183, 189 cdd 277
Berkeley-style History cdhome 167, 168, 238,
168 247, 289
big-endian 70 cdisk 238, 247
Binary Compare 291 CDPATH 162, 229, 235,
binedit 271, 287 247, 288, 349
Bit And 118, 208 ceil() 264
Bit Not 116 char() 265
Bit Or 118, 208 chcp 269, 289
Bit Shifting 208 chdir 269
Bit Xor 118, 208 Checksum 374
bits.csh 177 chgdisk 167, 238, 247,
BIX 35 289
black 165 child 242, 247
Blindspots 186, 326 childpath() 263
blink 165, 166 chmod 52, 53, 74, 271,
blksize.c 177 290
blue 165 Cipher Block Chaining
blue green 165 302, 303
blue red 165 cl.csh 178
boot record 309, 313, Clear the screen 269,
317 290
boot sector 316 clock$ 211
Bourne shell 180 cls 269, 290
break statement 131, cmd.exe 18, 121, 160,
195, 204 169, 170, 189, 247, 283
breaksw 185, 277 cmd.exe internal commands
bright 165, 166 28, 40
bsdargv 184, 238, 245 cmp 271, 291
Code Pages 269, 289
403
Index
code() 265 Control Panel 6, 7
Colon operators 103, Control structures
104, 105, 114, 225, 227 129, 131, 183
COLORS copy 50, 99, 100, 277
cos() 264
307, 319, 333, 334, cosh() 264
337, 350, 351, 387, cp 50, 271, 292
396, 397 cp 50
colors.csh 178 cpio 378
211 crash.csh 35
165, 229, 247, 265,
6, 12, 32, 41,
com1 .. com7
Comma operator 114 CreateProcess 40,
Command completion 148
42, 82, 165, 186, cron 271, 293, 294,
220, 231, 252 295, 296, 297
Command Line Editing crontab 293, 294
41, 186, 218 csh command line options
Command line options 283
31, 48 csh.exe 161, 232
Command Substitution CSHOPTIONS 169, 170,
76, 77, 103, 109, 229, 247, 284
164, 175, 222 CSHTITLE 162, 164,
Comments 189, 205 229, 235, 248
Common Problems 23 Ctrl key 41
Communication ports Ctrl- 219
211 Ctrl- 218
Communications Manager Ctrl- 218
33 Ctrl- 42, 221
Compare files 271, Ctrl- 203
304 Ctrl- 42,
Comparisons of strings 219
117 Ctrl- 218
Compatibility guide Ctrl- 218
183 Ctrl- 218
Compressed files 290 Ctrl-C 144, 145, 149
Compression 210 Ctrl-D 43, 216
COMSPEC 23, 169, 170, Ctrl-F 42, 216
229, 247, 285 Ctrl-Z 61, 167
con device 211 Current directory 27,
concat() 265 28, 53, 54, 87, 129,
Conditional execution 152, 160, 167, 168,
127, 206 204, 229, 231, 238,
Conditional selection 247, 248, 250, 269,
208 288, 289, 307, 347,
Condition-testing 194 349, 350
config.sys 12, 13, 14, Current drive 204
15, 17, 18, 48, 160, Customizing the Shell
161, 166, 170 159
conin$ 211 cut 60, 271, 299
conout$ 211 cwd 87, 238, 248
Console 211 cyan 165
Continuation lines -D 114, 116, 208, 210
163, 256 Data Encryption Standard
continue statement 271, 302, 303, 304
204 date 271, 277, 300
404
Index
Daylight Savings 234, dumphist 277
duplicat.csh
195
Default Command Processor 248
18, 160 114, 116, 208, 210
260, 382 178
default clause DUPLICATES 165, 231,
-e
del 30, 99, 100, easter.csh 178
101, 277 echo 49, 269, 319
DELETIONS 165, 230, echoallinput 238, 248
248, 307 echoinput 240, 242,
deltaday.csh 178 248
DES 271, 302, 303, Editing 103
304 Electronic Code Book
di 277 302
diff 58, 59, 165, elif 185, 195
229, 230, 245, 248, elif clause 195
271, 277, 304 ellipsis 98
dim 165, 166, 271, else clause 194, 195
307 encryption 271, 302,
dir 40, 121, 277 303, 304
DIRECTORIES 165, 231, End of file 61
248, 334, 387 endif 185, 279
Directory listing 272 endsw 185, 279
Directory stack 54, Environment variables 6
55, 129, 269, 307, 347, Environmental variables
349, 353 23, 85, 86, 161, 167,
dirs 54, 162, 269, 178, 229, 231, 232,
307 234, 245
Disk usage 271, 318 eofgetline 242, 249
diskette duplication Epsilon 33
309, 311, 312, 316 Equality test operator
DosExecPgm 40, 148, 117
189 erase 100, 279
DosQAppType 24 Error handling 169
DosRead 79 escape character 84,
DosSetMaxFH 346 110, 168, 187, 188,
DosSMSetTitle 160 191, 231, 235, 250, 319
DosStartSession 40, Escape sequences 49,
189 76, 111, 187, 222, 271,
Double quotes 92, 307, 319
109, 114, 222 escapesym 84, 110,
DRIVEMASK 31, 54, 97, 111, 167, 168, 188,
162, 231, 248, 318, 191, 222, 223, 231,
350, 396 235, 250, 319
driveno() 263 eval 150, 179, 269,
dskread 62, 271, 309, 321
316, 317 Exclusion ranges 187,
dskwrite 62, 271, 215
309, 311, 312, 313, Executable files 188,
314, 316, 317, 318 210
dt 277, 300 exit statement 204,
du 31, 53, 54, 162, 231, 242, 251, 280
248, 271, 277, 318 exp() 264
duc 277 Exponentiation 117
dumpenv 13, 178
405
Index
Export restrictions Full-screen applications
302 13, 14, 15, 16, 24,
Expression operators 29, 147, 334
90, 114, 115, 184, Function keys 202,
208, 215 203
Expression parsing g 279
114 getchar 242, 250
Expressions 113, 115, getline 105, 242, 245,
120, 136, 178, 194, 249, 250
195, 199, 209 getprio.c 179
extension operator Global editing 104,
227 225
Extensions 186, 188 GMT 234, 260, 382
External Utilities goto statement 142,
271, 273, 275 143, 204, 238, 250
-f 114, 208, 210 gotowindow 144, 238,
f 279 250
f2c.csh 178 green 165
Factor.csh 175, 178 grep 30, 55, 56, 57,
FAX 35 58, 271, 279, 324
fgrep 55, 56, 271, Group - Main 15
279, 322 Group menu 161
File exists 210 Grouping statements
File system tests 113, 204
115, 176, 208, 210 Group-Main 18
Filename completion h 279
42, 43, 165, 216, -H 114, 208, 210
220, 231, 248, 252, 284 -h option 47, 270,
Filename functions 275
263 Hashing of path
finance.csh 178 directories 186,
fixup 178 283
Floating point arithmetic hashstat 269, 326
186, 240 head 59, 234, 272,
floor() 264 327
fn 279 head operator 227
for statement 113, heap usage 328
131, 132, 186, 196, 204 heapstat 269, 283,
foreach statement 131, 328
196, 204 help 279
Foreground activities Help information 47
147, 148 Hex dump 275, 398
Foreground colors 165 Hex numbers 114
Foreground priority Hidden files 47, 50, 62,
321 136, 210, 215, 240,
FOREIGNFILES 165, 231, 254, 290
250, 387 HIGHLIGHT 165, 231,
Form Feed 222 250, 319, 350, 351,
Formatting a diskette 396, 397
313 histchars 167, 220,
fullmixedpath() 227, 235, 250
263 history 30, 41, 42, 81,
fullname 162 82, 84, 103, 104, 105,
fullpath() 227, 263 109, 117, 142, 143,
406
Index
167, 168, 183, 184, irqmask 145, 204, 244,
186, 187, 203, 218, 252
219, 220, 222, 225, isinteger() 265
226, 227, 235, 236, isnumber() 265
242, 244, 250, 257, Iteration 127, 131,
258, 269, 277, 279, 186, 196, 204
Julian date 177, 179
105 julian.csh 179
History long-form 82, kbd$ 211
235, 250 kill 149, 150, 269,
History short-form 329
84, 235, 250 Korn shell 180
history.csh -L 160
History editing
284, 328 189
home 5, 6, 7, 23, 28, label command 272,
160, 229, 231, 235, 330
250, 279 Labels and Gotos 142,
Home directory expansion 188, 204
95 LAN manager 11
HPFS 2, 11, 162, 335 Language Reference
Hyperbolic functions 167, 193
264 LATITUDE 231, 252
I/O Redirection 73, ld 279
77, 128, 148, 169, 184, Less than operator
186, 187, 194, 206 117
icon 160 Less than or equal
Icon for the C shell 8 operator 117
Idle time 321 line-end conventions
if statement 130, 194, 71
195, 279 Link command 29
ignoreeof 167, 242, link.exe 346
251 List directory 331
ignoreerrors 141, 167, little-endian 70
169, 240, 243, 252 ll 279
ignorestatus 141, 167, loadhist 279
169, 244, 252 local statement 88,
Indefinite Directories 200
95, 98, 215 Local time 234, 260,
Initial current 382
directories 166 Local variables 87,
Inline data 77, 78, 79, 134, 136, 151, 167,
81, 206 186, 200, 201
Installation as Default log() 264
Command Processor log10() 264
18 log2() 264
Installation on OS/2 Logical And 118, 208
11 Logical Not 117
Installation Options Logical Or 118, 208
159 login.csh 5, 6, 13,
interactive 240, 244, 15, 16, 159, 160, 161,
252, 283, 284 162, 166, 167, 178,
Internet 35 189, 284
Interrupts 59, 76, logout.csh 189
143, 144, 204, 240, Long filenames 2, 11,
244, 252 62, 334
407
Index
LONGITUDE 231, 252 mt 65, 234, 258, 273,
longname() 227, 263 339
lower() 266 mv 50, 273, 341
Low-level format 313, myecho 109, 179
315 NETWORKBUG 31, 232,
211 254
ls 47, 48, 162, 165, New Line 222
231, 233, 234, 248, newer 273, 343
272, 331 newfiles.csh 179
LSOPTIONS 231, 252, noclobber 74, 167,
331 169, 239, 254
magenta 165 noglob 239, 254
Mailing binary files nohashing 238, 254
lpt1 .. lpt4
392 nonohidden 136, 215,
Make directories 335 240, 254
make.exe 29 nonomatch 99, 167,
makecpgm.csh 179 169, 240, 254
markexe 29, 272, 334 nonovar 89, 99, 240, 254
Masking Interrupts Not equal operator
145 117
Match failures 98 nowild 100, 239, 240,
MATCHFAIL 165, 220, 254
231, 252 NTFS 2, 162
Math functions 264 NTVersion 235, 255
mcvisa.csh 179 nul 211
md 279 null device 211
member.csh 179 nullwords 91, 92,
mi 121, 122, 280 140, 167, 169, 240, 256
mih 280 Numeric literals 114
mis 280 -o 114, 208, 210
MIXEDCASEDRIVES 162, Octal numbers 114
232, 252, 331, 350 older 273, 343
mixedpath() 227, 263 onintr 144, 145
mkdir 273, 279, 335 onintr statement 204
Mode bits 271, 290 op= operators 119
Modulo division 117 OperatingSystem 235,
more 51, 52, 59, 76, 256
121, 122, 159, 165, Order of Evaluation
232, 234, 252, 253, 155
254, 256, 258, 273, Ordinary file 210
280, 335, 336 OS/2 1.1 11, 13, 29,
MOREEOF 165, 232, 252, 160, 161
337 OS/2 1.2 11, 29,
MOREERROR 165, 232, 160, 161
253, 337 OS/2 1.3 18, 160,
MOREFILLIN 165, 232, 161
253, 337 OS/2 2.x 160, 161,
moreh 273, 280, 336 370, 371
MOREPROMPT 165, 232, os2version 235, 256
253, 337 Ownership 210
MORETOPMEM 165, 232, Parenthesis 86, 128,
254, 337 129, 183, 184
move 50 paste 273, 345
Move files 341
408
Index
patchlnk 29, 273, procedures 87, 100,
6, 7, 13, 23,
232, 235, 256
Path hashing
346 113, 114, 121, 127,
165, 183, 186, 188,
269, 326, 197, 224, 263, 264, 265
PATH 129, 133, 134, 136,
351, 390 Process list 269
Path hashing 40, 161 Process Status 348
Pathname editing 104, Processes 348
227 processid 235, 245,
Pattern fails operator 256
118, 215 Process-wide variables
Pattern matches operator 235, 237
215 Product Support 35
Pattern matches operators Program Manager 7
118 Programming constructs
Pattern matching 113, 113, 127
176, 208, 215, 355 Prompt strings 162,
pause 280 163, 189
Perl 28 prompt1 39, 162, 163,
Per-thread variables 164, 189, 232, 235, 256
188, 238, 240, 242, prompt2 77, 162, 163,
244 189, 232, 236, 256
Pipes 73, 75, 76, 128, Protection attributes
183, 206, 240 74
pkzip 62 PROTSHELL 18, 33,
PM applications 24, 160, 161
29, 334, 335 ps 149, 150, 269, 329,
pointer$ 211 348
popd 54, 55, 57, 162, pushd 54, 55, 57, 162,
269, 347 269, 349
Popular Aliases 277, pwd 31, 53, 54, 162,
279, 280 231, 248, 273, 350
postage.csh 179 q 280
posxpath.csh 180 Quotes 86
Precedence 115, 128, Quoting 105, 109, 110,
206, 208, 324, 359 177, 187, 215, 222
precision 90, 91, -R 208, 210
240, 256 RADIX 232, 256, 291,
Predefined variables 337, 373
245, 247, 248, 250, Ranges 95, 97, 103,
254, 256, 258, 260 215, 396
Print formatting 265, Raw Sectors 309, 312
267 rcode 127, 131, 180
Print spooler 211 rd 280
Printer ports 211 Read-only files 210,
printf() 265, 267 290
priority 321 READONLYDIRS 165, 232,
prn 211 256, 334
Problems 23 READONLYFILES 165,
proc statement 28, 232, 257, 334
133, 134, 135, 136, recursion 87, 136,
137, 151, 186, 197 137, 175, 178
Procedure arguments red 165
134 Re-entrancy 151
409
Index
Regular expressions Semicolon 206
55, 56, 58, 104, 271, Separate arrow keys
324, 355, 356, 359 219
rehash 27, 186, 269, serial archive media
351 309, 311, 312, 316
Relation-testing 208 Serial execution 127,
Removable drives 31 206
remove 50 Serial ports 211
Remove directories Service 294
352 set statement 86,
Remove files 352 87, 183, 199, 200
ren 280 Set variables 86, 87
rename 30, 99, 100, setenv statement 85,
101, 121, 280, 341 86, 87, 166, 178, 183,
renet.csh 180 199, 200, 202, 245
repeat statement 132, Setenv variables 23,
133, 196, 204 85, 86, 161, 167, 178,
Restrictions 187 229, 231, 232, 234, 245
return statement 136, setkey statement 186,
186, 197 202
reverse video 166 setrows 273, 362, 363
reverse() 265 sh_2_csh.csh 180
rm 34, 50, 51, 273 SHELL 232, 236, 258
rmdir 273, 280, 352 Shell scripts 140,
root operator 227 177, 188, 189
rot13 280 shift statement 199
rotd 54, 55, 269, 353 Shift- 217
round() 264 Shortcut to the C shell
-S 114, 208, 210 8
safecopy() 100 shortname() 227, 263
safedel() 100 sin() 264
saferename() 100 Single quotes 109,
safexcopy() 100 110, 222, 325, 360
samepath() 263 sinh() 264
samples directory 173, sizeof.csh 181
177 sleep 148, 269, 364,
savehist 167, 236, 397
257, 284 sort 273, 365
Scheduling 147 source statement 142,
Scheduling IDs 329 143, 204, 269, 368
Screen colors 32, Special devices 211
165 split 60, 273, 370
screen$ 211 sqrt() 264
scriptname 140, 184, start 280
244, 258 Start Programs 13,
SDK 1.06 11 14, 18, 29, 161, 166
Seamless Windows 370 startup.cmd 160
Search path 13, 159, startup.csh 5, 6, 28,
161, 176, 232, 238, 30, 40, 100, 159, 160,
254, 256 161, 167, 189, 283, 284
Search/replace operations startwin 274, 370,
57, 104, 225, 356 371
sed 57, 58, 273, Statement lists 128,
354, 356 204
410
Index
Statement relationships 316, 317, 378, 381,
206 382, 383, 385
status
240, 244, 252, 258, 348
75 TARBINARY
75, 127, 141, TARASCII 71, 234,
259, 378
Stdout and Stderr 71, 234,
stmtnumber 188, 242, 259, 378
244, 245, 258 tar-format floppies
Stream editor 57, 311, 317
273, 354 tee 275, 387
strindex() 265 Telex 35
String functions 265 Text-windowable
String search 55, applications 24,
271, 322 29, 147, 334, 335
strings 61, 274, 372 Thread list 269
strlen() 265 threadid 142, 244,
Subscripting errors 259
140 Threads 75, 87, 134,
Substitution modifiers 140, 141, 142, 143,
225 149, 150, 151, 152,
substr() 265 153, 188, 189, 199,
sum 274, 374 200, 206, 244, 245,
sunrise.csh 181 259, 321, 348
switch statement 130, time 134, 204
184, 195, 204, 215, Time critical 321
216, 277, 279 Timestamps 50, 388
SWITCHCHARS 31, 48, timestmp.csh 181
163, 232, 258 Timezone 234, 260
System files 50, 165, Title bar 18, 160,
210, 234, 258, 290, 334 163
System status 269 touch 52, 75, 275, 388
SYSTEMDIRS 165, 233, touch.exe 181
258, 334 tr 61, 275, 389
SYSTEMFILES 165, 234, Translate characters
258, 334 389
Tab character 222 trapz.csh 181
Tab Key 284 Trigonometric functions
tabs 60, 76, 162, 264
177, 234, 258, 275, ts.csh 181
327, 337, 375 type 280
Tagged expressions Type conversions 120
57, 58 TZ 234, 260, 382
tail 59, 234, 275, unalias statement 198
376 unbuffered i/o 284
tail operator 227 unhash 27, 270, 390
tailstatus 167, 240, uniq 275, 391
258 UNIX 48, 159
tan() 264 unixprof 181
tanh() 264 unlocal statement 186,
TAPE 234, 258 201
Tape device 339 unproc statement 28,
tape drives 65 134, 186, 197
tar 65, 165, 229, unset statement 87,
231, 234, 245, 250, 200
259, 260, 275, 311,
411
Index
unsetenv statement wc
weekday.csh
unsetkey statement
73, 275, 397
87, 200 181
whereis 134, 176, 188,
202 275, 398
until statement 133, while statement 132,
196 196, 204
upper() 266 white 165
User-Defined Colors Wildcard characters
165 95, 109, 118, 195,
uud 280 222
uudecode 275, 392 Wildcarding 30, 33, 43,
uue 281 56, 95, 96, 99, 100,
uuencode 275, 392 101, 113, 118, 162,
Variable substitutions 169, 177, 187, 193,
88, 92, 164, 224 196, 210, 215, 216,
variables 85, 87, 90, 240, 248, 254
114, 136, 150, 152, WinBuild 237, 260
161, 165, 167, 184, Windows 95 24, 25
188, 189, 194, 199, 201 winerror.csh 181
ver 275 WinSetTitleAndIcon
verbose 240, 260 160
verify 270, 394 WinVersion 237, 260
Vertical Tab 223 Word selections 103
viopaste.c 181 Write verification
vl 281 394
vl.exe 396 WriteFile 79
vol 31, 53, 54, 162, -x 114, 208, 210
231, 248, 275, 281, 396 xcopy 30, 99, 100,
Volume labels 272, 101, 282
330, 396 xd 275, 398
-w 114, 208, 210 yellow 165
w 282 -z 114, 208, 210
wait 270, 282, 397 Zero-length files 210
412
Index
413