Penguin
Diff: PortabilityNotes
EditPageHistoryDiffInfoLikePages

Differences between version 2 and previous revision of PortabilityNotes.

Other diffs: Previous Major Revision, Previous Author, or view the Annotated Edit History

Newer page: version 2 Last edited on Friday, July 7, 2006 9:44:30 am by AristotlePagaltzis Revert
Older page: version 1 Last edited on Friday, July 7, 2006 9:16:45 am by AristotlePagaltzis Revert
@@ -1,21 +1,165 @@
-!!! Shell Syntax  
-See ShellPortabilityNotes for bash(1)/sh(1) portability notes.  
+!!! [ Shell] syntax  
  
-!!! Miscellaneous  
+Since the default [Shell] on almost all LinuxDistribution~s is bash(1), this page lists some common bash-isms that might fail on other sh-type shells on other [Unix](-like) OperatingSystem~s. If there is even the remote possibility that your script might be used by someone other than you, it's worth putting in a small bit of effort to use more portable constructs.  
  
-! tar  
+This little section is quoted from the documentation for autoconf(1) (do <tt>info autoconf</tt>, although personally I hate info pages). This demonstrates how stable the [Unix] programming environment is (don't use "new" features added since 1977 !).  
  
-tar(1) on [BSD] systems (including [MacOSX]) need an explicit dash (-) before the options. ( [GNU] tar doesn't) . Eg 
+> ! Portable Shell Programming  
+>  
+> When writing your own checks, there are some shell-script programming  
+> techniques you should avoid in order to make your code portable. The Bourne  
+> shell and upward-compatible shells like the Korn shell and Bash have evolved  
+> over the years, but to prevent trouble, do not take advantage of features  
+> that were added after UNIX version 7, circa 1977 .  
+>  
+> 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 <tt>unset</tt> is not supported  
+> by all shells! Also, include a space after the exclamation point in interpreter  
+> specifications, like this:  
+>  
+> <verbatim>  
+> #! /usr/bin/perl  
+> </verbatim>  
+>  
+> If you omit the space before the path, then 4.2BSD based systems (such as  
+> DYNIX) will ignore the line, because they interpret "<tt>#! /</tt>" as a  
+> 4-byte magic number. Some old systems have quite small limits on the length  
+> of the <tt>#!</tt> line too, for instance 32 bytes (not including the  
+> newline) on SunOS 4.  
+  
+!! The test(1) command  
+  
+Note that test(1) is a built-in function in many shells.  
+  
+! <i><tt>-z</tt>: tests if the length of STRING is zero</i>  
+  
+In bash, a non-existent variable is treated like "", but on some other shells it is treated like nothing.  
+  
+Bash, non-portable::  
+  
+ <verbatim>  
+ $ test -z $NON_EXISTENT_VARIABLE  
+ $ echo $?  
+  
+ </verbatim>  
+  
+Bash, more portable::  
+  
+ <verbatim>  
+ $ test -z "$NON_EXISTENT_VARIABLE"  
+ $ echo $?  
+  
+ </verbatim>  
+  
+Solaris sh::  
+  
+ <verbatim>  
+ $ test -z $NON_EXISTENT_VARIABLE  
+ test: argument expected  
+ $ echo $?  
+ 1  
+ $ test -z "$NON_EXISTENT_VARIABLE"  
+ $ echo $?  
+  
+ </verbatim>  
+  
+! <i><tt>-e</tt>: FILE exists</i>  
+  
+This seems to be a [GNU] extension – some shells don't allow <tt>-e</tt> as an option to test.  
+  
+Solaris sh::  
+  
+ <verbatim>  
+ $ test -e filename  
+ test: argument expected  
+ </verbatim>  
+  
+In most cases, you can use <tt>-r</tt> (for file is readable) instead.  
+  
+!! Variables  
+  
+Bash, non-portable:  
+  
+ <verbatim>  
+ $ export VAR1=foo  
+ $ echo $VAR1  
+ foo  
+ </verbatim>  
+  
+Bash, more portable:  
+  
+ <verbatim>  
+ $ VAR2=bar; export VAR2  
+ $ echo $VAR2  
+ bar  
+ </verbatim>  
+  
+Solaris sh:  
+  
+ <verbatim>  
+ $ export VAR1=foo  
+ VAR1=foo is not an indentifier  
+ $ echo $VAR1  
+ $ VAR2=bar; export VAR2  
+ $ echo $VAR2  
+ bar  
+ </verbatim>  
+  
+----  
+  
+!!! [Shell] tools  
+  
+!! tar(1)  
+  
+ tar(1) on [BSD] systems (including [MacOSX]) need an explicit dash (-) before the options, whereas [GNU] tar doesn't. Eg.:  
+  
+ <verbatim>  
  $ tar xf file.tar (gnu) 
  $ tar -xf file.tar (bsd) 
+ </verbatim>  
  
-Not all tars support the -z option for gzip(1) ' ped tar files . Pipe it instead. (Not all environments have the zcat(1) alias either)  
-<verbatim> 
+Not all tars support the <tt> -z</tt> option for [ gzip(1)] ped TarBall~s . Pipe it instead. (Not all environments have the zcat(1) alias either. )  
+  
+ <verbatim> 
  $ tar -zxf file.tar.gz # not portable 
  $ gzip -d -c file.tar.gz | tar -xf - 
-</verbatim> 
+ </verbatim>  
+  
+----  
+  
+!!! [C]  
+  
+!! File locking  
+  
+[BSD]-style unixes uses flock(2), which uses "advisory" locks. Ie, a process with sufficient read or write permission can ignore the lock and read/write a file. [SysV]-style unixes use either advisory locks or "mandatory" locks (if enabled in the FileSystem), and access them by the fcntl(2) command and a <tt>struct flock</tt> object.  
+  
+A more portable way ([POSIX] 1003.1-2001) is to use the lockf(3) function from unistd.h, which will do the correct type of locking for the unix it is compiled on. (In [Linux]/[GNU] libc, this function is a wrapper around fcntl(2)).  
+  
+!! printf(3) types  
+  
+! 64-bit-isms and fixed sized types  
+  
+If you have a fixed sized type (eg, uint64_t) and you want to use printf(3) to display it, you need to know the real type of the integer. Eg.:  
+  
+ <verbatim>  
+ uint64_t x;  
+ printf("%llu",x);  
+ </verbatim>  
+  
+This however will fail on 64bit machines as <tt>uint64_t</tt> is <tt>long</tt> not <tt>long long</tt>.  
+  
+[POSIX] defines some macros to use in this case, normally found in <tt>inttypes.h</tt>. Eg., for an unsigned 64 bit value, use the macro <tt>PRIu64</tt>. This will be substituted for whatever is appropriate on your host – either <tt>lu</tt> or <tt>llu</tt>, depending on if you are on a 32bit or 64bit host. Eg.:  
+  
+ <verbatim>  
+ uint64_t x;  
+ printf("%"PRIu64,x);  
+ </verbatim>  
+  
+!! See also  
+  
+* [HP] has [a set of C portability notes | http://docs.hp.com/en/5074/portability.html], although it targets HP-UX.  
+* [Intel] has [a similar set of notes | http://www.intel.com/cd/ids/developer/asmo-na/eng/technologies/64bit/200519.htm?page=1] (for porting to [ia64] and [amd64])  
  
-!!!Programming  
-[C] - see [CPortabilityNotes]  
 ---- 
 Part of CategoryProgramming