Here-Document

如何以正確的方式在heredoc中縮進heredoc?

  • April 19, 2017

以下程式碼片段是用於安裝 Apache 的腳本。當從包裝它的heredoc塊(APACHE)執行它時,我就地執行這個腳本。

請注意,在這個 APACHE heredoc 中,我有一個內部 heredoc (MOD_REWRITE),我可以將其稱為“次要”或“內部”heredoc。

另請注意,除了內部heredoc 的程式碼之外,APACHE 中的所有程式碼都是縮進的(列表)。

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

如果我使用帶有空格而不是列表的命令來縮進它,我可以很好地執行腳本(只要它裡面沒有 MOD_REWRITE)。如果我添加 MOD_REWRITE,腳本在執行時會剎車;如果我刪除所有空格縮進並用製表符完全替換它們,也會發生同樣的情況,但是AFAIK,上次我嘗試用製表符執行腳本時,它也壞了(即使我在bash /dev/fd/10 10<< and 'APACHE'之間添加了一個連字元。

我的問題:

在 APACHE heredoc 中縮進 MOD_REWRITE heredoc 的正確方法是什麼,這樣腳本會更加統一併且可以在不損壞的情況下執行?

筆記:

  • 就像我對任何其他命令一樣,我也想縮進內部 heredocs 的原因是出於審美原因 — 它使我更容易閱讀和組織我的腳本。
  • 這個問題與“ Can’t indent heredoc to match nesting’s indent ”不同,因為它詢問的是在外部 heredocs 中縮進內部 heredocs 的正確方法,而不是關於縮進外部 heredocs 本身。

here-document 是表單的重定向:

<<[-]DELIMITER
   ....
   ....
   ....
DELIMITER

可選的-(在上面的括號內)改變了分隔符的匹配方式,並允許縮進 heredoc 內容中的每一行,使用製表符(不允許空格)。

  • “匹配”表示分隔符與開始符匹配(例如DELIMITER匹配<<DELIMITER或時<<-DELIMITER)。
  • 請注意,您可以在<<or<<-和後面的單詞之間使用一個或多個空格)。

所以總結一下單個heredoc內部匹配的基本規律:

  1. 開場白必須以適用的語法放置在行首。
  2. 分隔符必須是其行的唯一單詞
  3. opener 下的所有內容(包括分隔符)都可以使用任意數量的tabulations縮進,使用<<-DELIMITER語法。

由於使用前一種語法,heredoc 開始符之前不能有空格,如果你想縮進它,你唯一的選擇是使用下面的語法,並且你必須在 heredoc 內容中的每一行的開頭專門使用製表符。

現在您有兩個<<-語法選項。

第一個選項

使用<<-內部 heredoc 的語法。

bash << APACHE
   ... 
   ... 
   cat <<- MOD_REWRITE
⇨       ...     
⇨       ....    
⇨       MOD_REWRITE
   ... 
   ... 
APACHE

(縮進為 4 個空格,表格用 符號表示

所看到的程式碼bash將與您螢幕上的內容完全相同(即bash,您現在看到的每一行的縮進)。當遇到內部heredoc時,由於<<-語法,bash將去除每行前導的製表符,直到MOD_REWRITE分隔符。

第二種選擇

使用<<-外部 heredoc 的語法。

bash <<- APACHE
⇨       ...
⇨       ...
⇨       cat << MOD_REWRITE
⇨       ⇨       ...
⇨       ⇨       ....
⇨       MOD_REWRITE
⇨       ...
⇨       ...
APACHE

這一次,您看到的程式碼bash將與您看到的不同:它不包含任何前導列表。這就是為什麼我使用<<內部 heredoc 的語法不是問題的原因:MOD_REWRITE 分隔符將位於行首。

在這兩種情況下,都會辨識 MOD_REWRITE 分隔符,並且您的 Apache 配置文件/etc/apache2/apache2.conf不會縮進。如果你想縮進它的一部分,你唯一的選擇是使用空格(在將被剝離的初始列表之後)。

當然,還有第三種選擇:使用<<-兩個 heredocs 的語法,但這不會改變選項 2 的任何內容,因為當程式碼發送到bash.

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