I noticed that the last five code lines of the weekdate
not published in my article in the July/August magazine.
those lines, with the prior two for context.
# Set the exit status according to whether today is that day of the month
# If you'd rather output the day number, uncomment the next line and
# comment the test line.
#test $day -eq `date '+%d'`
Rezolution Computer Consulting
9085 Burst Court
Sacramento, CA 95826
From: Greg A. Woods <firstname.lastname@example.org>
I had to laugh over the letter from Christopher Calabrese
Reznick in the July/August 1993 issue of Sys Admin!
They're both "wrong"!
This is an excellent example of folks going out and
making a whole
lot of assumptions about how things should be, and how
to go about
something. Shell scripts aren't that hard to write,
and it should
be possible for anyone to learn most of the basic rules.
No, you might
never have time to master the subtleties of all the
tools, but the
basic (de facto) rules still apply, and should be followed.
First off, there is a valid reason for the construct
"X$1" = "X" ..." You must do
this exactly this
way if you wish to be portable to V7, 4.2BSD, etc. systems,
- "test" is the only portable way to invoke
the test(1) command
or shell builtin.
- The leading "X" is to prevent parsing (by
test(1)) of any
values with leading dashes, such as '-r'.
Indeed "if [ -z "$1" ] ..." is prettier,
just not portable.
Second, you should never use the test(1) "="
operator to compare
numeric values! Use "-eq", "-ne"
and their friends.
Third, the usage message in Christopher's re-implementation
follow any standard syntax I've ever run across! The
means the previous element may be repeated zero or more
Fourth, usage errors are often indicated by an exit
code of two (2).
Fifth, the "#!" interpreter file magic "number"
be "#! ". The space is required by many 4.2BSD
and is documented as so. This won't ensure that /bin/sh
runs the script
on some systems, such as older SCO Xenix machines where
shell is csh(1), and nor can any other portable solution,
Oh, and in the first sed(1) expression, the dots don't
have to be
escaped with backslashes -- this is only necessary in
the RE portion
of a substitute expression.
As a final note, I consider the possible separate execution
sed(1) processes to be a small price to pay for readability,
the assurance of avoiding bugs due to filenames containing
Yes, such occurrences should be tracked down and eradicated,
the programmer's job to predict and avoid the consequences
A better, different, but not much more portable, implementation,
from Christopher's, is in Listing 1 (and yes, I tested
Of course all of this is moot for most sh(1) or ksh(1)
can use the "type" builtin [or for ksh(1),
builtin, which is an alias for "whence -v"]
(except it doesn't
set an exit code, nor bore you with the path it searched
it can identify shell functions and for ksh(1), aliases).
csh(1) version of which(1) also knows to check for aliases.
for sh(1) users, an implementation of which(1) using
would have to be a shell function, set in $HOME/.profile
or some such
place, since any shell script would be unable to search
BTW, the font used for examples makes it impossible
between a single quote (') and a single back-quote (`).
Greg A. Woods
Larry Reznick responds: I agree with you completely
the "X$1" test has its place, given the conditions
My inclusion of it in the original script was a holdover
I knew less. Now that I know more, including what you
point out, I
won't apologize for it any more.
On other points: I also agree that test is the most
way to handle the program name, but the brackets just
seem more natural-looking
to me. Now that you bring it up, I do notice where Christopher
the "=" operator -- definitely a string operator
instead of the ".eq" operator. I missed that
when I looked
at his code. That sets up for strange troubles later.
About the usage error being 2: I've never seen that
anywhere. The only documentation on the convention I've
seen is the
zero/non-zero convention. I'd be interested in knowing
where you found
such a standard. I usually adhere to local standards
where I'm doing
the work. Without such standards, I've used 1 for usage,
2 for file
opening, 3 for read/write (3 for read & 4 for write
when I need to
distinguish), and 4 for memory. I don't recall if I've
needed to go
beyond that. This corresponds with the usual sequence
of events in
the program with the possible exchange of read/write
& memory, according
to the program.
BSD may require the "#!" be followed by a
I don't have access to a BSD machine any more to verify
that, so I
trust you. However, SVR4 doesn't require the space.
in csh(1) says, "the next word," when referring
to what follows.
That can certainly be interpreted as requiring a space,
but I have
a great deal of evidence that the space isn't required
in SVR4: every
shell script using that notation to start sh(1) but
not having the
space wouldn't run under csh. Here are the rules for
naming the shell
in a shell script:
1. If the first line begins with #!, what follows is
name of a shell or command to interpret the script.
2. When option 1 fails, if the first character of the
line begins with a #, csh is invoked.
3. When option 2 fails, invoke sh. As a tradition, I've
seen a colon ':' used as the only character on the first
line to avoid
putting a # in the first position.
Based on these rules, the colon you write on the second
line of your code serves no code purpose except that
the shell interprets
the colon as a null command, which does nothing successfully.
Finally, the which script that I use (I forgot about
type builtin -- thanks for the reminder) does announce
in precedence over commands using the same names. At
the end of the
original article, I challenged readers to add that facility.
for your contributions.
MM responds: We have a filter to catch the back-quote
but had not used it with New Messages! We will now do
From: Wolfgang Schrecker <email@example.com>
Hi, sorry to bother you. But as a customer who doesn't
what to type
all your goodies, is there a FTP site to get the sources
Start Informatik GmbH
Look for the "Source Code Availability" reference
in the contents on the cover of Sys Admin. All code
listings are available
either using UUCP or ftp. --rlw