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