The following codepiece is a script used to install Apache. I run this script in-place when executing it from the heredoc block that wraps it (APACHE).
Note that inside this APACHE heredoc, I have an internal heredoc (MOD_REWRITE), which I can refer to as a "secondary" or "internal" heredoc.
Please also note that all the code inside APACHE is indented (tabulated), besides the code of the internal heredoc.
bash /dev/fd/10 10<<'APACHE'
# Setup basics:
apt-get update -y && apt-get upgrade -y
apt-get install tree zip unzip
a2enmod mcrypt && a2enmod mbstring
# Setup LAMP environment with enabled mod rewrite:
echo -e "\07" && echo -e "\077" # Insert password.
apt-get install lamp-server^ -y
a2enmod rewrite
cat <<MOD_REWRITE >> /etc/apache2/apache2.conf
<Directory /var/www/>
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
</Directory>
MOD_REWRITE
systemctl restart apache2.service
# Setup maldet:
cd /usr/local/src
wget http://www.rfxn.com/downloads/maldetect-current.tar.gz && tar -xzf maldetect-current.tar.gz
cd maldetect-* && bash ./install.sh
APACHE
If I indent it with commands with spaces instead of tabulations, I can run the script just fine (as long as it doesn't have the MOD_REWRITE inside it). If I add the MOD_REWRITE, the script brakes when executed; The same happens if I remove all space-indents whatsoever and totally replace them with tabulations, but AFAIK, the last time I tried to execute the script with tabulations, it also broke (even when I added an hyphen between bash /dev/fd/10 10<<
and 'APACHE'
.
My question:
What is the right way to indent the MOD_REWRITE heredoc inside the APACHE heredoc, so the script would be more unified and would execute without breakage?
Notes:
-
The reason I want to indent internal heredocs as well, just as I would do with any other command, is from aesthetic reasons — It makes it easier for me to read and organize my scripts.
-
This question is not the same as "Can't indent heredoc to match nesting's indent" because it asks about the correct way of indenting internal heredocs inside external heredocs, and not about indenting external heredocs themselves.
Best Answer
A here-document is a redirection of the form:
The optional
-
(inside the brackets above) changes the way the delimiter is matched and allows indenting each line inside the heredoc content, with tabulations (no spaces allowed)."Matched" means the delimiter is matched to the opener (as when
DELIMITER
matches<<DELIMITER
or<<-DELIMITER
, for example).Note that you may use one or more spaces between
<<
or<<-
, and the word that follows).So to sum up the basic laws for matching inside a singlar heredoc:
<<-DELIMITER
syntax.Since with the former syntax, no blanks can precede the heredoc opener, if you want to indent it, your only choice is to use the following syntax and you must exclusively use tabulations at the beginning of each line inside the heredoc's content.
Now you have two options with the
<<-
syntax.First option
Use the
<<-
syntax for the inner heredoc.(indentation is 4 spaces, tabulations are symbolized with
⇨
)The code seen by
bash
will be exactly what is written on your screen (i.e.bash
will see the indentation of each line as you see it now). When the inner heredoc is met, owing to the<<-
syntax,bash
will strip the tabulation characters leading each line until the MOD_REWRITE delimiter.Second option
Use the
<<-
syntax for the outer heredoc.This time, the code seen by
bash
will differ from what you see: it won't contain any leading tabulation. That's why this is not a problem that I use the<<
syntax for the inner heredoc: the MOD_REWRITE delimiter will be at the beginning of the line.In both cases, the MOD_REWRITE delimiter is recognized and your Apache configuration file
/etc/apache2/apache2.conf
is not indented. If you want to indent parts of it, your only option is to use spaces (after the initial tabulations that will be stripped).Of course, there is a third option: to use the
<<-
syntax for both heredocs, but that won't change anything from option 2 since all the leading tabulations are removed when the code is sent tobash
.