autoconf: Here-Documents

1 
1 11.3 Here-Documents
1 ===================
1 
1 Don't rely on `\' being preserved just because it has no special
1 meaning together with the next symbol.  In the native `sh' on OpenBSD
1 2.7 `\"' expands to `"' in here-documents with unquoted delimiter.  As
1 a general rule, if `\\' expands to `\' use `\\' to get `\'.
1 
1    With OpenBSD 2.7's `sh'
1 
1      $ cat <<EOF
1      > \" \\
1      > EOF
1      " \
1 
1 and with Bash:
1 
1      bash-2.04$ cat <<EOF
1      > \" \\
1      > EOF
1      \" \
1 
1    Using command substitutions in a here-document that is fed to a shell
1 function is not portable.  For example, with Solaris 10 `/bin/sh':
1 
1      $ kitty () { cat; }
1      $ kitty <<EOF
1      > `echo ok`
1      > EOF
1      /tmp/sh199886: cannot open
1      $ echo $?
1      1
1 
1    Some shells mishandle large here-documents: for example, Solaris 10
1 `dtksh' and the UnixWare 7.1.1 Posix shell, which are derived from Korn
1 shell version M-12/28/93d, mishandle braced variable expansion that
1 crosses a 1024- or 4096-byte buffer boundary within a here-document.
1 Only the part of the variable name after the boundary is used.  For
1 example, `${variable}' could be replaced by the expansion of `${ble}'.
1 If the end of the variable name is aligned with the block boundary, the
1 shell reports an error, as if you used `${}'.  Instead of
1 `${variable-default}', the shell may expand `${riable-default}', or
1 even `${fault}'.  This bug can often be worked around by omitting the
1 braces: `$variable'.  The bug was fixed in `ksh93g' (1998-04-30) but as
1 of 2006 many operating systems were still shipping older versions with
1 the bug.
1 
1    Empty here-documents are not portable either; with the following
1 code, `zsh' up to at least version 4.3.10 creates a file with a single
1 newline, whereas other shells create an empty file:
1 
1      cat >file <<EOF
1      EOF
1 
1    Many shells (including the Bourne shell) implement here-documents
1 inefficiently.  In particular, some shells can be extremely inefficient
1 when a single statement contains many here-documents.  For instance if
1 your `configure.ac' includes something like:
1 
1      if <cross_compiling>; then
1        assume this and that
1      else
1        check this
1        check that
1        check something else
1        ...
1        on and on forever
1        ...
1      fi
1 
1    A shell parses the whole `if'/`fi' construct, creating temporary
1 files for each here-document in it.  Some shells create links for such
1 here-documents on every `fork', so that the clean-up code they had
1 installed correctly removes them.  It is creating the links that can
1 take the shell forever.
1 
1    Moving the tests out of the `if'/`fi', or creating multiple
1 `if'/`fi' constructs, would improve the performance significantly.
1 Anyway, this kind of construct is not exactly the typical use of
1 Autoconf.  In fact, it's even not recommended, because M4 macros can't
1 look into shell conditionals, so we may fail to expand a macro when it
1 was expanded before in a conditional path, and the condition turned out
1 to be false at runtime, and we end up not executing the macro at all.
1 
1    Be careful with the use of `<<-' to unindent here-documents.  The
1 behavior is only portable for stripping leading <TAB>s, and things can
1 silently break if an overzealous editor converts to using leading
1 spaces (not all shells are nice enough to warn about unterminated
1 here-documents).
1 
1      $ printf 'cat <<-x\n\t1\n\t 2\n\tx\n' | bash && echo done
1      1
1       2
1      done
1      $ printf 'cat <<-x\n 1\n  2\n x\n' | bash-3.2 && echo done
1       1
1        2
1       x
1      done
1