Shell

在 cat heredocument 中重定向 Makefile 消失變數和換行符

  • March 30, 2017

執行:

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.
MAKE

創建這個,執行後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

如您所見,執行後,第二個範例中的相關行只是一個長行(沒有換行符,由反斜杠表示,並且變數$@沒有出現在任何地方。重定向後為什麼會發生這種情況?

Here Documents部分man bash

這里文件的格式是:

     <<[-]word
            here-document
     delimiter

不會對 word 執行參數和變數擴展、命令替換、算術擴展或路徑名擴展。如果 word 中的任何字元被引用,則分隔符是 word 上去除引號的結果,並且 here-document 中的行不展開。 如果 word 不被引用,則 here-document 的所有行都經過參數擴展、命令替換和算術擴展,字元序列 \ 被忽略,並且必須使用 \ 來引用字元 \、$ 和 `。

由於MAKE在您的範例中未引用,\因此被忽略並$@正在擴展(可能是空的參數列表)。

解決方案是引用標記(的任何部分),例如

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

或者

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

或提供所需的轉義,例如用於\\線路延續和\$@``$@

引用自:https://unix.stackexchange.com/questions/354683