cat <<MAKE >> /etc/apache2/sites-available/Makefile1
% :
    printf '%s\n' \
    '<VirtualHost *:80>' \
    'DocumentRoot "/var/www/html/$@">' \
    'ServerName $@' \
    '<Directory "/var/www/html/$@">' \
    'Options +SymLinksIfOwnerMatch' \
    'Require all granted' \
    '</Directory>' \
    'ServerAlias www.$@' \
    '</VirtualHost>' \
    > "$@"
    a2ensite "$@"
    systemctl restart apache2.service
    mv /etc/apache2/sites-available/$@ /etc/apache2/sites-available/$@.conf
    # Before quotes == Tabuilations. Inside quotes == Spaces. After quotes == Spaces (1 space before backslash for line break). Also avoid any other spaces.

Creates this, after running cd /etc/apache2/sites-available/ && make contentperhour.com:

% :
printf '%s\n' '<VirtualHost *:80>' 'DocumentRoot "/var/www/html/">' 'ServerName ' '<Directory "/var/www/html/">' 'Options +SymLinksIfOwnerMatch' 'Require all granted' '</Directory>' 'ServerAlias www.' '</VirtualHost>' > ""
a2ensite ""
systemctl restart apache2.service
mv /etc/apache2/sites-available/ /etc/apache2/sites-available/.conf

As you can see, after execution, the relevant line in the second example is just a long row (no line breaks, represented by backslashes, AND the variable $@ doesn't appear anywhere. Why would this happen after redirecting?

  • are you not just seeing the usual shell substitution of \ and $ due to the unquoted word MAKE? try cat <<\MAKE or cat <<"MAKE" (or backslash escape \ and $) – steeldriver Mar 29 '17 at 22:21

From the Here Documents section of man bash

The format of here-documents is:


No parameter and variable expansion, command substitution, arithmetic expansion, or pathname expansion is performed on word. If any characters in word are quoted, the delimiter is the result of quote removal on word, and the lines in the here-document are not expanded. If word is unquoted, all lines of the here-document are subjected to parameter expansion, command substitution, and arithmetic expansion, the charac‐ ter sequence \ is ignored, and \ must be used to quote the characters \, $, and `.

Since MAKE is unquoted in your example, \ is ignored and $@ is being expanded (to a presumably empty parameter list).

The solution is to quote (any part of) the marker e.g.

cat <<\MAKE >> /etc/apache2/sites-available/Makefile1


cat <<"MAKE" >> /etc/apache2/sites-available/Makefile1

or to provide the required escapes e.g. \\ for the line continuations and \$@ for $@

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy