[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Proposed doc updates

From: Eric Blake
Subject: Proposed doc updates
Date: Mon, 24 Jan 2005 06:22:04 -0700
User-agent: Mozilla Thunderbird 1.0 (Windows/20041206)

Hash: SHA1

My assignment is not yet on file, but I would like comments on my proposed
portability patches below.  I welcome any stylistic corrections (this is
my first time writing in texinfo), technical corrections, or additional
comments that should be added.  I did a visual check of the patch using
`make html'.

2005-01-24  Eric Blake  <address@hidden>

        * doc/autoconf.texi (Portable Shell): Autoconf uses functions.
        (Shellology): Add reference to POSIX. Ash is cygwin's default. Add
        more about /bin/sh on Solaris.
        (File Descriptors): Ash writes to stderr on `none 2> /dev/null'.
        (File System Conventions): Windows eats trailing dots and
        spaces. Document that control characters are not portable.
        (Shell Substitutions): Add section on $((arithmetic)).
        (Assignments): Array assignments are non-portable.
        (Special Shell Variables): Alphabetize. Add section on PATH and
        PATH-like variables.
        (Limitations of Builtins): Add sections on alias, function,
        unalias.  Add documentation of `export foo=bar', `set -h', `shift
        -n', `trap '' EXIT' non-portability.
        (Limitations of Usual Tools): Add cross-reference to
        EXEEXT. Document that FAT uses 2-second timestamp resolution.
        (Limitations of Make): Add section on MAKEFLAGS.

- --
Life is short - so eat dessert first!

Eric Blake             address@hidden
Version: GnuPG v1.4.0 (Cygwin)
Comment: Using GnuPG with Thunderbird -

? doc/autoconf
? doc/standards
Index: doc/autoconf.texi
RCS file: /cvsroot/autoconf/autoconf/doc/autoconf.texi,v
retrieving revision 1.866
diff -u -p -r1.866 autoconf.texi
--- doc/autoconf.texi   21 Jan 2005 19:31:51 -0000      1.866
+++ doc/autoconf.texi   24 Jan 2005 13:16:04 -0000
@@ -9503,11 +9503,12 @@ have evolved over the years, but to prev
 advantage of features that were added after Unix version 7, circa
 1977 (@pxref{Systemology}).
-You should not use shell functions, aliases, negated character
-classes, or other features that are not found in all Bourne-compatible
-shells; restrict yourself to the lowest common denominator.  Even
address@hidden is not supported by all shells!  Also, include a space
-after the exclamation point in interpreter specifications, like this:
+You should use shell functions with care, and should avoid aliases,
+negated character classes, or other features that are not found in all
+Bourne-compatible shells; restrict yourself to the lowest common
+denominator.  Even @code{unset} is not supported by all shells!  Also,
+include a space after the exclamation point in interpreter
+specifications, like this:
 #! /usr/bin/perl
@@ -9558,7 +9559,10 @@ and the C shell family which are deeply 
 write portable shell scripts, avoid members of the C shell family.  The
 @uref{, the
 Shell difference FAQ} includes a small history of Posix shells, and a
-comparison between several of them.
+comparison between several of them.  Posix has specified the standard
+behaviors that a compliant shell must provide at
+the Shell Command Language}.
 Below we describe some of the members of the Bourne shell family.
@@ -9569,7 +9573,8 @@ Ash is often used on @acronym{GNU}/Linux
 systems as a light-weight Bourne-compatible shell.  Ash 0.2 has some
 bugs that are fixed in the 0.3.x series, but portable shell scripts
 should work around them, since version 0.2 is still shipped with many
address@hidden/Linux distributions.
address@hidden/Linux distributions.  The version 0.3.x series is the
+default @command{/bin/sh} of Cygwin.
 To be compatible with Ash 0.2:
@@ -9673,6 +9678,14 @@ reason why portable shell code should no
 @code{"address@hidden"@dots{}\"@dots{}`"} constructs (@pxref{Shell
address@hidden Sh
address@hidden sh
+Posix requires that the system provide a shell by the name of sh.
+Usually, this file resides at @command{/bin/sh}, but is a link to one
+of the other Bourne shells.  On Solaris, @command{/bin/sh} is not a
+known derivative of any of the other shells listed here, so it comes
+with its own set of limitations.
 @item Zsh
 @cindex Zsh
 To detect whether you are running @command{zsh}, test whether
@@ -9831,6 +9844,18 @@ escape, while @samp{: `cd /zorglub 2>/de
 It is worth noting that Zsh (but not Ash nor Bash) makes it possible
 in assignments though: @samp{foo=`cd /zorglub` 2>/dev/null}.
+Ash checks that a command exists and is executable before performing
+redirections.  Therefore, a warning will escape to stderr.  The portable
+way to check for a command's existance is to redirect stderr of the
+subshell performing the check.
+$ @kbd{nonexistant 2> /dev/null}
address@hidden: not found
+$ @kbd{(nonexistant) 2> /dev/null}
address@hidden example
 Most shells, if not all (including Bash, Zsh, Ash), output traces on
 stderr, even for sub-shells.  This might result in undesirable content
 if you meant to capture the standard-error output of the inner command:
@@ -9951,6 +9976,11 @@ AC_OUTPUT
 @acronym{DOS} cannot handle file names that start with a dot.  This is usually
 not a very important issue for @command{autoconf}.
address@hidden No trailing dots or spaces (@sc{lfn})
+Windows strips all trailing dots and spaces from filenames.  Thus,
address@hidden'foo'}, @samp{'foo.'}, and @samp{'foo '} are the same file.
+Again, this is usually not a very important issue.
 @item Case insensitivity (@sc{lfn})
 @acronym{DOS} is case insensitive, so you cannot, for example, have both a
 file called @samp{INSTALL} and a directory called @samp{install}.  This
@@ -9967,19 +9997,20 @@ That means that @file{foobar-part1.c}, @
 The 8+3 limit is not usually a problem under Microsoft Windows, as it
-uses numeric
-tails in the short version of file names to make them unique.  However, a
-registry setting can turn this behavior off.  While this makes it
-possible to share file trees containing long file names between @sc{sfn}
-and @sc{lfn} environments, it also means the above problem applies there
-as well.
+uses numeric tails in the short version of file names to make them
+unique.  However, a registry setting can turn this behavior off.  While
+this makes it possible to share file trees containing long file names
+between @sc{sfn} and @sc{lfn} environments, it also means the above
+problem applies there as well.
 @item Invalid characters (@sc{lfn})
 Some characters are invalid in @acronym{DOS} file names, and should therefore
 be avoided.  In a @sc{lfn} environment, these are @samp{/}, @samp{\},
address@hidden, @samp{*}, @samp{:}, @samp{<}, @samp{>}, @samp{|} and @samp{"}.
-In a @sc{sfn} environment, other characters are also invalid.  These
-include @samp{+}, @samp{,}, @samp{[} and @samp{]}.
address@hidden, @samp{*}, @samp{:}, @samp{<}, @samp{>}, @samp{|} and @samp{"},
+and all control characters, such as @samp{\a}, @samp{\b}, @samp{\f},
address@hidden, @samp{\n}, @samp{\r}, @samp{\t}, and @samp{\v}.  In a
address@hidden environment, other characters are also invalid.  These include
address@hidden, @samp{,}, @samp{[}, @samp{]}, and space.
 @item Invalid names (@sc{lfn})
 Some @acronym{DOS} file names are reserved, and cause problems if you
@@ -10245,6 +10276,39 @@ a different notation @samp{$((@var{expre
 shells is an arithmetic expression not a command.  To avoid the
 confusion, insert a space between the two opening parentheses.
address@hidden $((@var{arithmetic}))
address@hidden $((@var{arithmetic}))
+Posix specifies that this construct will evaluate its contents as an
+arithmetic expression, with the value of the expression being the
+result.  However, Ash treats this as an undocumented quoting mechanism,
+resulting in the literal expression surrounded by 8-bit markers and an
+indication of the current quoting level.  Likewise, the
address@hidden/bin/sh} of Solaris 8 does not support it:
+$ @kbd{bash -c 'echo "x$((1+1))" | cat -A'}
+$ @kbd{ash -c 'echo "x$((1+1))" | cat -A'}
+$ @kbd{ash -c 'echo x$((1+1)) | cat -A'}
+xM-^F 1+1M-^G$
+$ @kbd{sh -c 'echo "x$((1+1))"|cat -A'}
+$ @kbd{sh -c 'echo x$((1+1))|cat -A'}
address@hidden/bin/sh: syntax error at line 1: `(' unexpected
address@hidden example
+The only portable way to perform arithmetic expansion is to use
address@hidden inside of a backtick subshell.  Of course, you must also
+be aware of the limitations of backticks and of @command{expr}; see
address@hidden of Builtins}.
+$ @kbd{foo=`expr 1 + 1`}
+$ @kbd{echo $foo}
address@hidden example
 @end table
@@ -10257,6 +10321,8 @@ evaluation is undefined.  For instance @
 gives @samp{1} with sh on Solaris, but @samp{2} with Bash.  You must use
 @samp{;} to enforce the order: @samp{foo=1; foo=2; echo $foo}.
+Array assignment is a Bash extension, and is not portable.
 Don't rely on the following to find @file{subdir/program}:
@@ -10607,21 +10673,27 @@ PS2='> '
 PS4='+ '
 @end example
address@hidden PWD
address@hidden PWD
-Posix 1003.1-2001 requires that @command{cd} and
address@hidden must update the @env{PWD} environment variable to point
-to the logical name of the current directory, but traditional shells
-do not support this.  This can cause confusion if one shell instance
-maintains @env{PWD} but a subsidiary and different shell does not know
-about @env{PWD} and executes @command{cd}; in this case @env{PWD} will
-point to the wrong directory.  Use @samp{`pwd`} rather than
address@hidden status
address@hidden status
-This variable is an alias to @samp{$?} for @code{zsh} (at least 3.1.6),
-hence read-only.  Do not use it.
address@hidden PATH
address@hidden PATH
+Not all @env{PATH} names are portable.  This is particularly noticeable
+in a default Cygwin installation, where @env{PATH} is inherited from the
address@hidden path, and typically includes directory components with
+spaces, such as @code{Program Files} or @code{Documents and Settings}.
+When handling a @code{$PATH} from a user, quote the variable to avoid
+inadvertant word splitting or other unexpected behavior.
+$ @kbd{echo $PATH}
+/usr/bin:/cygdrive/c/windows:/cygdrive/c/program files/program
+$ @kbd{eval PATH=/bin:$PATH}
address@hidden: files/program: command not found
address@hidden example
+Remember that Posix requires that a leading or trailing
address@hidden in a @env{PATH} implies the current directory.
+This applies to other @env{PATH}-like variables as well, such as
address@hidden  Therefore, if you do not want to add @samp{.} to
+a search path, first check that the path variable is not empty.
@@ -10638,12 +10710,29 @@ Bash uses to set up certain environment 
 @samp{;} as path separator.  So it is recommended to either unset this
 variable or set it to @samp{;}.
address@hidden PWD
address@hidden PWD
+Posix 1003.1-2001 requires that @command{cd} and
address@hidden must update the @env{PWD} environment variable to point
+to the logical name of the current directory, but traditional shells
+do not support this.  This can cause confusion if one shell instance
+maintains @env{PWD} but a subsidiary and different shell does not know
+about @env{PWD} and executes @command{cd}; in this case @env{PWD} will
+point to the wrong directory.  Use @samp{`pwd`} rather than
 @item RANDOM
 @evindex RANDOM
 Many shells provide @code{RANDOM}, a variable that returns a different
 integer each time it is used.  Most of the time, its value does not
 change when it is not used, but on @sc{irix} 6.5 the value changes all
 the time.  This can be observed by using @command{set}.
address@hidden status
address@hidden status
+This variable is an alias to @samp{$?} for @code{zsh} (at least 3.1.6),
+hence read-only.  Do not use it.
 @end table
@@ -10696,6 +10785,26 @@ More generally, one can always rewrite @
 if @var{command}; then (exit 1); else :; fi
 @end example
address@hidden @command{alias}
address@hidden ------------------
address@hidden @command{alias}
+Even though Posix requires it, Ash does not support aliases, and some
+shells only support @command{alias} in interactive mode.  Portable
+scripts should not use aliases.  See @command{unalias} if you are
+worried about existing aliases affecting your script.
+Most of the time, a Posix function can do everything that an alias can,
+and more.  However, in shells that support both, it is worth remembering
+that alias expansion occurs before filename expansion, leading to this
+useful alias from
address@hidden://} that
+supresses filename expansion for the duration of the find command:
+$ @kbd{alias find='_find() @{ find "$@@"; set +f; unset _find; @}; set -f; 
address@hidden example
 @item @command{break}
 @c ------------------
 @prindex @command{break}
@@ -10882,6 +10991,19 @@ alternately @samp{foo} and @samp{bar}, a
 Therefore you should @command{export} again each environment variable
 that you update.
+Posix requires shells to support assignments as arguments to
address@hidden, but this is not supported in older shells.  Even
address@hidden/bin/sh} of Solaris 8 still rejects this syntax. It may be
+possible to make the assignment before the @command{export}, but the
+most portable approach is to separate the assignment and the export into
+separate commands.
+$ @kbd{export foo=bar}
address@hidden: is not an identifier}
+$ @kbd{foo=bar; export foo}
address@hidden example
 @item @command{false}
 @c ------------------
@@ -10926,6 +11048,26 @@ But keep in mind that Zsh, even in Bourn
 word splitting on @address@hidden"$@@"@}}; see @ref{Shell Substitutions},
 item @samp{$@@}, for more.
+The Bash extension @code{for (( exp1; exp2; exp3 ))} is not portable.
address@hidden @command{function}
address@hidden ---------------------
address@hidden @command{function}
+The @command{function} command in Bash is a non-portable alternate to
+the Posix syntax for declaring a function; it should not be used.  Also,
+Posix requires that a function body be any compound command
+(@address@hidden@}}, @command{()}, @command{if}, @command{for},
address@hidden, @command{until}, and @command{case}), but when the
address@hidden keyword appears in Bash, the body must be in braces.
+$ @kbd{function foo if : ; then echo hi ; fi}
address@hidden: syntax error near unexpected token `if'
+$ @kbd{foo () if : ; then echo hi ; fi}
+$ @kbd{foo}
address@hidden example
 @item @command{if}
 @c ---------------
@@ -11044,12 +11186,14 @@ set x $my_list; shift
 Some shells have the "opposite" problem of not recognizing all options
 (e.g., @samp{set -e -x} assigns @samp{-x} to the command line).  It is
-better to elide these:
+better to combine these:
 set -ex
 @end example
+Ash does not recognize @samp{set -h} or @samp{set -o nolog}.
 @item @command{shift}
 @c ------------------
@@ -11058,6 +11202,9 @@ Not only is @command{shift}ing a bad ide
 shift, but in addition it is not portable: the shell of @acronym{MIPS
 RISC/OS} 4.52 refuses to do it.
+The syntax @command{shift n} is not supported in older shells; instead
+use a sequence of n repeated calls to @command{shift}.
 @item @command{source}
 @c -------------------
@@ -11180,6 +11327,20 @@ It is safe to trap at least the signals 
 trap 0, i.e., have the @command{trap} run when the script ends (either via an
 explicit @command{exit}, or the end of the script).
+You must use a signal number, as Ash, contrary to Posix, does not
+recognize signal names.
+$ @kbd{trap '' EXIT}
address@hidden: bad signal EXIT}
+$ @kbd{trap '' 0}
address@hidden example
+To reset a trap to the default behavior, use @samp{-} as the action,
+rather than omitting the argument.  Unpatched Bash 3.0 treats
address@hidden 1 2} as meaning run the script named 1 when trap 2 is
+encountered, rather than resetting both traps 1 and 2 to their default.
 Although Posix is not absolutely clear on this point, it is widely
 admitted that when entering the trap @samp{$?} should be set to the exit
 status of the last command run before the trap.  The ambiguity can be
@@ -11239,6 +11400,20 @@ for @command{true}.
 @end quotation
address@hidden @command{unalias}
address@hidden ------------------
address@hidden @command{unalias}
+Not all shells provide aliases, such as Ash.  However, unexpected alias
+expansion can interfere with portable scripts.  To be safe, you can
+unalias all variables by first checking for the existance of
address@hidden; remember to quote the command since some shells allow
+even @command{unalias} to be an alias.
+$ @kbd{(\unalias -a) 2> /dev/null && \unalias -a}
address@hidden example
 @item @command{unset}
 @c ------------------
 @prindex @command{unset}
@@ -11347,6 +11522,7 @@ HP-UX @command{cc} doesn't accept @file{
 assemble.  @samp{cc -c foo.S} will appear to succeed, but in fact does
+Some systems give executables a default extension, see @pxref{EXEEXT}.
 The default executable, produced by @samp{cc foo.c}, can be
@@ -11433,6 +11609,9 @@ coreutils 5.0.91 or later, and Solaris 8
 later.  Unfortunately as of September 2003 there is still no system
 call to set time stamps to the full nanosecond resolution.
+On the other extreme, the @acronym{FAT} file system of @acronym{DOS},
+still used by DJGPP and cygwin, has only a 2-second resolution.
 Bob Proulx notes that @samp{cp -p} always @emph{tries} to copy
 ownerships.  But whether it actually does copy ownerships or not is a
 system dependent policy decision implemented by the kernel.  If the
@@ -12253,6 +12432,30 @@ bar
 @end example
address@hidden The @code{MAKEFLAGS} macro
address@hidden @code{MAKEFLAGS} and @command{make}
address@hidden @command{make} and @code{MAKEFLAGS}
+Posix requires @command{make} to use @code{MAKEFLAGS} to affect the
+current and recursive invocations of make, but allows implementations
+several formats for the variable.  Therefore, attempting to parse
address@hidden to determine if @code{-s} for silent execution or
address@hidden for continued execution are in effect is inherently
+non-portable.  You cannot assume that the first space-separated word in
address@hidden contains single-letter options, since in the cygwin
+version of GNU make, it is either @code{--unix} or @code{--win32},
+moving the single-letter options to the second word.
+$ @kbd{cat Makefile}
+       @@echo $(MAKEFLAGS)
+$ @kbd{make}
+$ @kbd{make -k}
+--unix -k
address@hidden example
 @item Comments in rules
 @cindex Comments in @file{Makefile} rules
 @cindex @file{Makefile} rules and comments
@@ -12781,7 +12984,8 @@ timestamps with 1-nanosecond resolution.
 implementations look at the entire timestamp; others ignore the
 fractional part, which can lead to incorrect results.  Normally this
 is not a problem, but in some extreme cases you may need to use tricks
-like @samp{sleep 1} to work around timestamp truncation bugs.
+like @samp{sleep 2} to work around timestamp truncation bugs and the
+coarse 2-second granularity of @acronym{FAT} file systems.
 Commands like @samp{cp -p} and @samp{touch -r} typically do not copy
 file timestamps to their full resolutions (@pxref{Limitations of Usual

reply via email to

[Prev in Thread] Current Thread [Next in Thread]