`<< EOF` 與 `<< ‘EOF‘` 與 `<< “EOF“`有無引號的區別多回答筆記250722

<< EOF<< 'EOF'<< "EOF"有無引號的區別多回答筆記250722

實測

自測代碼:

# 定義變量
hello="ni hao"# 無引號
tee << EOF      # 無引號
${hello} world  \n  $(date)      # 無引號
EOF# 單引號
tee << 'EOF'    # 單引號
${hello} world  \n  $(date)      # 單引號
EOF# 雙引號
tee << "EOF"    # 雙引號
${hello} world  \n  $(date)      # 雙引號
EOF

在 fedora 42 上的結果, 雙引號與單引號效果相同 (腳本必須將 CRLF 換成 LF )

ni hao world  \n  2025年 07月 22日 星期二 09:58:32 CST      # 無引號
${hello} world  \n  $(date)      # 單引號
${hello} world  \n  $(date)      # 雙引號

在 Ubuntu24.04 上的結果, 雙引號與單引號效果相同 (腳本必須將 CRLF 換成 LF )

ni hao world  \n  Tue Jul 22 10:01:59 AM CST 2025      # 無引號
${hello} world  \n  $(date)      # 單引號
${hello} world  \n  $(date)      # 雙引號

在 AlmaLinux9.6 上的結果, 雙引號與單引號效果相同 (腳本必須將 CRLF 換成 LF )

ni hao world  \n  Mon Jul 21 22:10:54 EDT 2025      # 無引號
${hello} world  \n  $(date)      # 單引號
${hello} world  \n  $(date)      # 雙引號

在 Debian10.12 上的結果, 雙引號與單引號效果相同 (腳本必須將 CRLF 換成 LF )

ni hao world  \n  Tue Jul 22 10:08:58 CST 2025      # 無引號
${hello} world  \n  $(date)      # 單引號
${hello} world  \n  $(date)      # 雙引號

在 Debian12 上的結果, 雙引號與單引號效果相同 (腳本必須將 CRLF 換成 LF )

ni hao world  \n  Tue Jul 22 10:57:39 CST 2025      # 無引號
${hello} world  \n  $(date)      # 單引號
${hello} world  \n  $(date)      # 雙引號

在 Ubuntu16.4.7 上的結果, 雙引號與單引號效果相同 (腳本必須將 CRLF 換成 LF )

ni hao world  \n  Tue Jul 22 10:30:26 CST 2025      # 無引號
${hello} world  \n  $(date)      # 單引號
${hello} world  \n  $(date)      # 雙引號

在 Ubuntu18.04.6 上的結果, 雙引號與單引號效果相同 (腳本必須將 CRLF 換成 LF )

ni hao world  \n  2025年 07月 22日 星期二 13:16:20 CST      # 無引號
${hello} world  \n  $(date)      # 單引號
${hello} world  \n  $(date)      # 雙引號

在 CentOS7 上的結果, 雙引號與單引號效果相同 (腳本必須將 CRLF 換成 LF )

ni hao world  \n  Thu Apr  3 03:37:20 CST 2025      # 無引號
${hello} world  \n  $(date)      # 單引號
${hello} world  \n  $(date)      # 雙引號

在 CentOS6 上的結果, 雙引號與單引號效果相同 (腳本必須將 CRLF 換成 LF )

sh *826.sh
ni hao world  \n  2025年 07月 22日 星期二 12:19:19 CST      # 無引號
${hello} world  \n  $(date)      # 單引號
${hello} world  \n  $(date)      # 雙引號

不知為何, 明明是:雙引號與單引號相同 , 很多AI的回答是: 雙引號與無引號相同










在 Linux Shell 的 Here Document 語法中,定界符(如 EOF)是否被引號包裹,會直接影響其內容的解析方式(如變量替換、命令替換和轉義規則)。以下是 << EOV<< 'EOF'<< "EOF" 三者的核心區別:


???? 1. << EOV(無引號定界符)

  • 行為
    • 內容中的變量、命令替換和轉義字符(如 \$會被解析
    • 類似雙引號字符串的行為:允許擴展內容中的變量和命令。
  • 示例
    name="Alice"
    cat << EOV
    Hello, $name        # 輸出 "Hello, Alice"
    Today is $(date)    # 輸出當前日期
    Escape: \$name      # 輸出 "Escape: $name"(\$ 轉義后輸出 $)
    EOV
    

???? 2. << 'EOF'(單引號定界符)

  • 行為
    • 內容中的所有字符(包括 $`\ 等)按原樣輸出,無任何解析。
    • 類似單引號字符串的行為:禁止任何變量替換和命令替換。
  • 示例
    name="Alice"
    cat << 'EOF'
    Hello, $name        # 輸出 "Hello, $name"
    Today is $(date)    # 輸出 "Today is $(date)"
    Escape: \$name      # 輸出 "Escape: \$name"
    EOF
    

???? 3. << "EOF"(雙引號定界符)

  • 行為
    • << 'EOF' 完全相同:雙引號在此場景下無效。
    • Shell 中 Here Document 的定界符引號規則與普通字符串不同:無論用單/雙引號包裹定界符,效果均是禁止解析內容。
  • 示例
    name="Alice"
    cat << "EOF"
    Hello, $name        # 輸出 "Hello, $name"
    Today is $(date)    # 輸出 "Today is $(date)"
    Escape: \$name      # 輸出 "Escape: \$name"
    EOF
    

???? 對比總結

語法變量替換命令替換轉義字符(如 \n, \$類似字符串行為
<< EOV??????(可轉義 $ 等)雙引號
<< 'EOF'???(按原樣輸出)單引號
<< "EOF"???(按原樣輸出)單引號

???? 關鍵注意事項

  1. 定界符的名稱(EOV/EOF 可以是任意字符串,但需保持一致。
  2. 引號僅影響內容解析,與定界符本身無關。例如 << 'EOF' 中的 'EOF' 是定界符的標記方式,而非包裹內容。
  3. 轉義行為的唯一例外
    • 在無引號的 Here Document 中,若需保留 $` 字面量,需用 \ 轉義(如 \$name)。

???? 使用場景建議

  • 禁用替換:當需輸出含 $` 的文本(如生成腳本模板)時,用 << 'EOF'
  • 啟用替換:當需動態插入變量(如配置文件中設置路徑)時,用 << EOV(無引號定界符)。

掌握這些區別可避免腳本中出現意外行為!










在 Linux Shell 的 Here Document 中,<< EOV<< 'EOF'<< "EOF" 的區別主要在于結束標記的寫法以及對文檔內容的處理方式。以下是詳細解析:


???? 1. << EOV(無引號標記)

  • 結束標記EOV(可自定義)
  • 內容處理:變量替換、命令替換和轉義字符會被解析
  • 行為:與 << EOF 完全相同
name="Alice"
cat << EOV
Hello, $name!    # 輸出 Hello, Alice!
Today is $(date) # 輸出當前日期
EOV

???? 2. << 'EOF'(單引號標記)

  • 結束標記EOF 前加單引號
  • 內容處理禁止所有替換和轉義
    • 變量(如 $var)原樣輸出
    • 命令替換(如 $(cmd))原樣輸出
    • 轉義字符(如 \n)原樣輸出
cat << 'EOF'
$USER          # 輸出 $USER(不會替換)
Path: \$PATH   # 輸出 Path: \$PATH
Today: $(date) # 輸出 Today: $(date)
EOF

???? 3. << "EOF"(雙引號標記)

  • 結束標記EOF 前加雙引號
  • 內容處理:行為與無引號標記 完全相同 (錯, 實測與單引號完全相同)
    • 變量替換、命令替換會被解析
    • 轉義字符會被解釋
# 雙引號標記(實際行為與無引號相同)
cat << "EOF"
$USER          # 輸出當前用戶名(被替換)
Path: \$PATH   # 輸出 Path: $PATH(\$被轉義)
EOF

💡 注意:根據 POSIX 標準,<< "EOF" 理論上應禁用替換,但大多數 Shell(如 Bash)實際行為與無引號相同。這是歷史兼容性問題,建議避免使用。


???? 關鍵區別總結

語法結束標記寫法變量/命令替換轉義處理可移植性
<< EOVEOV? 啟用? 啟用
<< 'EOF''EOF'? 禁用? 禁用
<< "EOF""EOF"?? 通常啟用?? 通常啟用低(行為不一致)

???? 使用場景建議
???????? ? 需要替換內容時 → 用 << MARKER

# 生成動態配置
cat << CONF > app.conf
user=$USER
port=8080
logdir=$HOME/logs
CONF

???????? ? 需要原樣輸出時 → 用 << 'MARKER'

# 寫入腳本模板(保留特殊字符)
cat << 'SCRIPT' > demo.sh
#!/bin/bash
echo "Path: \$PATH"  # 原樣保留 $PATH
SCRIPT

???????? ?? 避免使用 << "MARKER"

  • 因 Shell 實現差異(Bash 啟用替換,Dash 禁用替換),可移植性差

???? 擴展知識:轉義結束標記
用反斜杠轉義結束標記(<< \EOF)等價于單引號標記:

cat << \EOF
$PWD  # 輸出 $PWD(不會被替換)
EOF

效果等同于 << 'EOF'


???? 總結

需求推薦語法
動態生成內容(需替換)<< MARKER
靜態內容(原樣輸出)<< 'MARKER'
禁用替換(兼容寫法)<< \MARKER
高可移植腳本避免 << "MARKER"

掌握這些區別可確保 Here Document 在腳本中按預期處理特殊字符,尤其在生成配置文件、代碼模板或跨平臺腳本時至關重要。










在 Linux Shell 的 Here Document 中,定界符的引號使用方式會直接影響文本內容的解析行為。以下是 << EOV<< 'EOF'<< "EOF" 的詳細區別:


???? 1. << EOV(無引號定界符)

  • 行為:執行 變量擴展命令替換
  • 示例
    name="Alice"
    cat << EOV
    Hello $name          # 變量被解析
    Date: $(date)        # 命令被執行
    Literal: \$name      # 需轉義$符
    EOV
    
  • 輸出
    Hello Alice
    Date: Tue Jul 22 10:00:00 UTC 2025
    Literal: $name
    
  • 特點
    • $var$(cmd)`cmd` 會被解析
    • 需用 \ 轉義特殊字符(如 \$\\

???? 2. << 'EOF'(單引號定界符)

  • 行為禁用所有解析,內容完全原樣輸出
  • 示例
    name="Alice"
    cat << 'EOF'
    Hello $name          # 變量不解析
    Date: $(date)        # 命令不執行
    Unescaped: $name     # 無需轉義
    EOF
    
  • 輸出
    Hello $name
    Date: $(date)
    Unescaped: $name
    
  • 特點
    • 所有內容視為純文本
    • 無需轉義特殊字符
    • 性能稍優(無解析開銷)

???? 3. << "EOF"(雙引號定界符)

  • 行為:與 無引號 << EOF 完全相同(雙引號被忽略)
  • 示例
    name="Alice"
    cat << "EOF"
    Hello $name          # 變量被解析
    Date: $(date)        # 命令被執行
    EOF
    
  • 輸出
    Hello Alice
    Date: Tue Jul 22 10:00:00 UTC 2025
    
  • 關鍵點
    • Shell 會忽略 << 后的雙引號
    • 實際行為等同于 << EOF

???? 對比總結

語法變量擴展命令替換需轉義特殊字符內容處理方式
<< EOV???動態解析
<< 'EOF'???純文本原樣輸出
<< "EOF"???<< EOF(雙引號無效)

???? 使用建議

  1. 需要動態內容 → 用 << EOV<< EOF(如生成含變量的配置文件)

    cat > config.txt << END
    USER=$USER
    PATH=${PATH}
    END
    
  2. 需要原始文本 → 用 << 'EOF'(如輸出代碼模板、SQL語句)

    cat << 'SQL'
    SELECT * FROM users WHERE name="$name";  # $name 不會被解析
    SQL
    
  3. 避免使用 << "EOF"

    • 雙引號在 Here Document 中是冗余的,可能引起混淆
    • 所有 Shell(Bash/Zsh等)均會忽略 << 后的雙引號

???? 特殊說明:<< \EOF

  • 等同于 << 'EOF'(禁用解析)
  • 反斜杠是早期 Shell 的遺留語法,現代腳本建議用單引號
    cat << \EOF
    $PATH  # 原樣輸出
    EOF
    

掌握這些差異可避免腳本中的意外解析錯誤,特別是在處理包含 $\、` 等字符的文本時。










在 Linux Shell 的 Here Document 中,<< EOV<< 'EOF'<< "EOF" 的區別主要在于 定界符名稱的選擇內容是否進行替換解析。以下是詳細對比:


???? 1. << EOV(自定義定界符)

  • 作用:使用自定義字符串 EOV 作為結束標記(可替換為任意合法字符串)
  • 行為:內容會進行 變量替換命令替換
  • 示例
    cat << EOV
    Hello, $USER  # 變量會被替換
    Time: $(date) # 命令會被執行
    EOV            # 結束標記必須與開頭一致
    
    輸出
    Hello, alice
    Time: Tue Jul 22 10:00:00 CST 2025
    

???? 2. << 'EOF'(單引號定界符)

  • 作用禁用所有替換(變量/命令/轉義符)
  • 行為:內容完全原樣輸出(類似單引號字符串)
  • 示例
    cat << 'EOF'
    Hello, $USER   # 變量不會被替換
    Time: $(date)  # 命令不會被執行
    Path: ~        # 波浪號不擴展
    EOF
    
    輸出
    Hello, $USER
    Time: $(date)
    Path: ~
    

???? 3. << "EOF"(雙引號定界符)

  • 作用允許所有替換(默認行為,與不加引號相同)
  • 行為:進行變量替換、命令替換和轉義符解析(類似雙引號字符串)
  • 示例
    cat << "EOF"
    User: $USER          # 變量替換
    Date: $(date +%F)    # 命令替換
    Escape: \n => newline # 轉義符解析
    EOF
    
    輸出
    User: alice
    Date: 2025-07-22
    Escape: => newline   # \n 被解釋為換行符
    

???? 關鍵對比表

語法替換解析轉義符處理典型場景
<< EOV? 變量/命令替換? 解析轉義符需要動態內容
<< 'EOF'? 完全禁用替換? 原樣輸出保留原始格式(如代碼、SQL)
<< "EOF"? 變量/命令替換? 解析轉義符需要轉義符的特殊處理
<< EOF(無引號)<< "EOF"<< "EOF"標準動態內容

???? 使用技巧

  1. 禁用替換的場景

    # 生成包含$符的SQL語句
    psql << 'SQL_END'
    SELECT * FROM table WHERE price > $100;
    SQL_END
    
  2. 需要轉義符的場景

    # 使用轉義符創建多行文本
    cat << "EOF"
    Line1\nLine2\tTabbed
    EOF
    
  3. 自定義標記的場景

    # 避免與內容沖突(如內容含EOF)
    grep "error" << LOG_END
    This is EOF example  # 此處EOF不會被誤識別
    LOG_END
    

注意:根據 POSIX 標準,<< "EOF"<< EOF 行為完全一致,而 << 'EOF' 是禁用替換的唯一標準方式。某些 Shell(如 Bash)會忽略雙引號,但為保持兼容性,建議顯式使用 << 'EOF' 表示禁用替換。










在 Linux Shell 中,<< EOV<< 'EOF'<< "EOF" 都是 Here Document(Heredoc) 的語法變體,核心區別在于 對內容中變量、命令替換和轉義字符的處理方式。以下是詳細解析:


???? 1. << EOV無引號

  • 行為
    • 內容中的 變量($var)和命令替換(`cmd`$(cmd))會被 Shell 展開(替換)
    • 反斜杠 \ 會解釋為轉義字符(如 \n 換行、\t 制表符),但 \$ 可轉義 $ 避免變量展開。
  • 用途:動態生成內容(如插入變量值、命令輸出)。
  • 示例
    name="Alice"
    cat << EOV
    Hello, $name!          # 變量 $name 會被替換為 "Alice"
    Today is $(date).      # 命令替換會執行
    Path: \$HOME = $HOME   # 第一個 $ 被轉義,第二個 $HOME 被展開
    EOV
    
    輸出
    Hello, Alice!
    Today is Tue Jul 22 14:30:00 CST 2025.
    Path: $HOME = /home/alice
    

???? 2. << 'EOF'單引號

  • 行為
    • 內容完全按字面意義傳遞,所有字符(包括 $`\)均視為普通文本。
    • 禁止任何變量替換、命令替換和轉義
  • 用途:保留原始內容(如生成代碼、配置文件、SQL 語句)。
  • 示例
    cat << 'EOF'
    This is literal text.
    $USER will NOT be expanded.  # $USER 原樣輸出
    `ls` and $(date) are ignored. # 命令替換無效
    Escape: \n\t remains "\n\t".  # 反斜杠不轉義
    EOF
    
    輸出
    This is literal text.
    $USER will NOT be expanded.
    `ls` and $(date) are ignored.
    Escape: \n\t remains "\n\t".
    

???? 3. << "EOF"雙引號

  • 行為
    • 與無引號 << EOF 幾乎相同(變量和命令替換會被展開)。
    • 唯一區別:內容中的雙引號 " 不會被特殊處理(但通常無影響)。
  • 注意:雙引號形式極少使用,因為無引號形式已能滿足需求,且兩者行為基本一致。
  • 示例
    title="Message"
    cat << "EOF"
    Title: "$title"        # 變量 $title 被展開,雙引號保留
    Time: $(date +%T)      # 命令替換執行
    EOF
    
    輸出
    Title: "Message"
    Time: 14:35:00
    

???? ? 關鍵對比總結

語法變量/命令替換反斜杠轉義引號處理典型場景
<< EOV展開支持轉義內容中的引號保留動態內容(需插入變量/命令結果)
<< 'EOF'禁止禁止轉義所有字符原樣保留原始文本(代碼、配置模板)
<< "EOF"展開支持轉義內容中的引號保留同無引號(極少使用)

???? ?? 重要注意事項

  1. 結束標記必須純凈

    cat << ENDcontent...
    END      # 正確:END 前后無空格
    
    cat << ENDcontent...END    # 錯誤:行首有空格(Shell 找不到結束標記)
    
  2. 縮進必須用 <<- + Tab

    cat <<- EOFIndented with Tab   # 行首的 Tab 會被忽略
    EOF                   # 結束標記前的 Tab 也會被忽略
    

    注意:只能忽略 Tab,不能忽略空格。

  3. 定界符命名自由

    • EOVEOFEND_MARK_ 均可(需配對且區分大小寫)。
    • 避免使用可能出現在內容中的單詞(如 cat)。

???? 📌 終極選擇建議

  • 需要動態內容 → 用 << EOV(無引號)。
  • 需要完全原樣輸出 → 用 << 'EOF'(單引號)。
  • 雙引號形式 << "EOF" 可忽略(與無引號功能重復)。










在 Linux shell 的 Here Document 中,<< EOV<< 'EOF'<< "EOF" 的區別主要在于定界符的選擇是否允許變量擴展。以下是詳細解析:


1. << EOV(或任意定界符)

  • 定界符可以是任意字符串(如 EOFEOVSTOP 等),只要開始和結束標記一致
  • 默認行為
    • 允許變量擴展$var 會被替換為變量值)。
    • 允許命令替換`command`$(command) 會被執行)。

???? 示例:

name="Alice"
cat << EOV
Hello, $name!  # 變量 $name 會被替換為 "Alice"
Current date: $(date)  # 命令替換會被執行
EOV

輸出

Hello, Alice!
Current date: Wed Oct 25 12:34:56 UTC 2023

2. << 'EOF'(單引號包裹定界符)

  • 禁止變量擴展和命令替換
    • 單引號 ' ' 會讓 Here Document 中的所有內容原樣輸出,就像單引號字符串一樣。
    • 適合傳遞包含特殊字符(如 $`!)的文本。

???? 示例:

name="Alice"
cat << 'EOF'
Hello, $name!  # 變量不會被替換,原樣輸出 $name
Current date: $(date)  # 命令不會被執行
EOF

輸出

Hello, $name!
Current date: $(date)

3. << "EOF"(雙引號包裹定界符)

  • 允許變量擴展和命令替換(與無引號 << EOF 行為相同)。
  • 雙引號在這里的作用是明確語法,但實際效果和無引號一致。
  • 通常無需使用雙引號,除非需要與其他語法(如嵌套引號)配合。

???? 示例:

name="Alice"
cat << "EOF"
Hello, $name!  # 變量會被替換
Current date: $(date)  # 命令會被執行
EOF

輸出(與 << EOF 相同):

Hello, Alice!
Current date: Wed Oct 25 12:34:56 UTC 2023

關鍵區別總結

語法變量擴展命令替換定界符要求適用場景
<< EOF? 是? 是任意字符串默認情況,需要變量替換時
<< 'EOF'? 否? 否任意字符串輸出原始內容(如模板、代碼)
<< "EOF"? 是? 是任意字符串極少使用,與 << EOF 相同

其他注意事項

  1. 定界符可以自定義

    cat << STOP
    內容...
    STOP
    

    EOF 只是約定俗成的習慣,并非強制)

  2. 結束標記必須頂格
    結束標記(如 EOF)必須單獨一行且無前導空格(除非用 <<- 縮進)。

  3. <<- 縮進支持
    <<- 可以忽略每行開頭的制表符(Tab,非空格):

    cat <<- EOFThis line is indented with tabs.$var is still expanded.
    EOF
    

實際應用建議

  • 需要變量替換 → 用 << EOF<< "EOF"(兩者等價)。
  • 不需要變量替換(如生成配置文件、代碼模板)→ 用 << 'EOF'
  • 避免混淆 → 保持定界符風格一致(如全用 EOF 或全用 STOP)。

通過合理選擇定界符和引號,可以更靈活地控制 Here Document 的行為。










在 Linux Shell 腳本中,<< 操作符用于定義 Here Document,其結束標記(如 EOF)可以使用不同的引號包裹(或不使用引號),從而影響變量替換的行為。以下是 << EOV<< 'EOF'<< "EOF" 的詳細對比:


???? 1. << EOV(無引號)

  • 行為
    • 變量替換:啟用變量替換(即 Here Document 中的變量會被展開)。
    • 結束標記匹配:結束標記必須嚴格匹配(如 EOV),不能有空格、Tab 或其他字符。
  • 示例
    VAR="Hello"
    cat << EOV
    $VAR, World!
    EOV
    
    輸出
    Hello, World!
    

???? 2. << 'EOF'(單引號包裹)

  • 行為
    • 變量替換禁用變量替換(Here Document 中的變量不會被展開,直接作為普通文本處理)。
    • 結束標記匹配:結束標記必須嚴格匹配(如 EOF)。
  • 示例
    VAR="Hello"
    cat << 'EOF'
    $VAR, World!
    EOF
    
    輸出
    $VAR, World!
    

???? 3. << "EOF"(雙引號包裹)

  • 行為
    • 變量替換啟用變量替換(與 << EOF 相同)。
    • 結束標記匹配:結束標記必須嚴格匹配(如 EOF)。
    • 特殊處理:雙引號在 Shell 中通常用于保留空格和換行,但對 Here Document 的結束標記本身沒有額外影響(結束標記仍需嚴格匹配)。
  • 示例
    VAR="Hello"
    cat << "EOF"
    $VAR, World!
    EOF
    
    輸出
    Hello, World!
    

???? 4. 關鍵區別總結

語法變量替換結束標記規則適用場景
<< EOV? 啟用嚴格匹配(無空格/Tab)需要動態替換變量的場景
<< 'EOF'? 禁用嚴格匹配(無空格/Tab)保留變量原文(如配置文件模板)
<< "EOF"? 啟用嚴格匹配(無空格/Tab)<< EOF 相同,但語法上使用雙引號

???? 5. 注意事項

  1. 結束標記的格式

    • 結束標記必須單獨一行,前后不能有空格或 Tab。
    • 例如,以下寫法會導致錯誤:
      cat << EOF
      Content...EOF  # ? 錯誤:結束標記前有空格
      
  2. 縮進控制

    • 如果需要忽略前導的 Tab 縮進,可以使用 <<-EOF(僅支持 Tab,空格無效):
      cat <<-EOFThis line has leading tabs.These tabs will be ignored.
      EOF
      
  3. 雙引號的局限性

    • 雙引號包裹的 Here Document(<< "EOF")不會影響變量替換,但雙引號本身對 Here Document 的內容沒有特殊作用(如通配符展開、轉義字符等)。

???? 6. 實際應用場景
???????? (1) 動態生成配置文件

DB_USER="admin"
cat << EOF > config.env
DB_USER=$DB_USER
DB_PASSWORD=secret
EOF
  • 效果$DB_USER 會被替換為 admin

???????? (2) 保留變量原文

TEMPLATE="Hello, \$NAME"
cat << 'EOF' > template.txt
$TEMPLATE
EOF
  • 效果$TEMPLATE 會被原樣保留為 Hello, $NAME

???????? (3) 與命令結合使用

mysql -u root << EOF
CREATE DATABASE test;
USE test;
EOF
  • 效果:執行多行 SQL 命令。

???? 7. 總結

  • << EOV<< "EOF":啟用變量替換,適用于需要動態生成內容的場景。
  • << 'EOF':禁用變量替換,適用于保留原文或避免意外替換的場景。
  • 結束標記:必須嚴格匹配,且通常使用 EOF 作為慣例。










在Linux shell腳本中,<< EOV<< 'EOF'<< "EOF" 是Here-Document的三種不同語法,它們的核心區別在于對特殊字符(如變量$、命令替換$( ))的處理方式。以下是詳細解析:

???? 一、<< EOV(普通Here-Document)

  • 特點:變量和命令會被替換,轉義符\僅對特定字符生效(如\$、```)。
  • 示例
    NAME="Alice"
    cat << EOV
    Hello $NAME
    當前時間:$(date +%H:%M)
    轉義美元符:\$100
    EOV
    
    輸出(假設當前時間為15:30):
    Hello Alice
    當前時間:15:30
    轉義美元符:$100
    
  • 說明$NAME被替換為變量值,$(date)被執行,\$保持為$

???? 二、<< 'EOF'(單引號Here-Document)

  • 特點完全禁用變量和命令替換,所有特殊字符均被視為普通文本。
  • 示例
    NAME="Alice"
    cat << 'EOF'
    Hello $NAME
    當前時間:$(date +%H:%M)
    轉義美元符:\$100
    EOF
    
    輸出
    Hello $NAME
    當前時間:$(date +%H:%M)
    轉義美元符:\$100
    
  • 說明:所有特殊字符(包括$\)均按字面輸出,無需轉義。

???? 三、<< "EOF"(雙引號Here-Document)

  • 特點:與<< EOF(無引號)完全等價,變量和命令會被替換。
  • 示例
    NAME="Alice"
    cat << "EOF"
    Hello $NAME
    當前時間:$(date +%H:%M)
    轉義美元符:\$100
    EOF
    
    輸出(與<< EOF相同):
    Hello Alice
    當前時間:15:30
    轉義美元符:$100
    
  • 說明:雙引號在此處沒有實際作用,僅為語法兼容性保留。

???? 四、<< EOV<< 'EOF' 的選擇場景

場景<< EOV(普通)<< 'EOF'(單引號)
需要變量替換? 支持(如$NAMEAlice? 不支持(保留$NAME
需要執行命令? 支持(如$(date)→當前時間)? 不支持(保留$(date)
文本含大量特殊字符? 需要逐個轉義(如\$、```)? 無需轉義,直接輸出原始文本
生成配置文件? 可能意外替換配置中的$符號? 適合原樣輸出配置內容

???? 五、總結

  • << EOV:適用于需要動態生成文本,且包含變量或命令的場景。
  • << 'EOF':適用于需要保留文本原貌,禁用所有替換的場景(如生成代碼、配置文件)。
  • << "EOF":與<< EOF完全等價,不建議使用,避免混淆。

示例對比表

語法變量替換命令替換轉義符\作用
<< EOF??僅轉義$`
<< 'EOF'??無特殊作用
<< "EOF"??僅轉義$`
<< EOF(配合-??忽略行首Tab縮進

選擇時,根據文本中是否包含需要解析的變量/命令,或需要保留的特殊字符(如$)來決定是否使用單引號包裹分界符。










在Shell腳本的Here Document語法中,<< EOV<< 'EOF'<< "EOF" 的差異主要體現在分隔符的引號處理方式上,這直接影響文本塊中變量、命令替換和特殊字符的解析行為。以下是詳細對比及適用場景:


???? ?? 一、核心差異對比

語法形式變量/命令替換特殊字符處理結束標記要求典型用例
<< EOV? 自動展開解析 $\()必須頂格或Tab縮進需動態注入變量/命令的場景
<< 'EOF'? 禁用替換原樣輸出($PATH$PATH必須頂格或Tab縮進保留$%等符號的靜態文本
<< "EOF"? 自動展開<< EOV(解析特殊字符)必須頂格或Tab縮進<< EOV,但極少使用1

1 注:<< "EOF"<< EOF 行為幾乎一致,可視為冗余寫法。


???? 🔧 二、具體行為解析
???????? 1. << EOV(無引號分隔符)

  • 變量與命令替換:自動解析文本中的 $var$(command),例如:
    name="Alice"
    cat << EOV
    Hello $name, today is $(date)
    EOV
    
    → 輸出:Hello Alice, today is Tue Jul 22 09:14:24 CST 2025
  • 特殊字符\n 被解釋為換行符,$ 觸發變量替換。

???????? 2. << 'EOF'(單引號分隔符)

  • 原始文本輸出:所有內容(包括 $\())均按字面輸出:
    cat << 'EOF'
    Price: $100, Path: $PATH, Command: $(date)
    EOF
    
    → 輸出:Price: $100, Path: $PATH, Command: $(date)
  • 適用場景:生成配置文件時保留模板符號(如 ${{DOMAIN}})。

???????? 3. << "EOF"(雙引號分隔符)

  • 行為與 << EOF 相同:變量和命令替換均被解析,無實際區別。

    例外:某些Shell(如 dash)可能嚴格區分引號,但Bash/Zsh中無差異。


???? 🛠? 三、進階技巧與注意事項

  1. 縮進優化(<<-
    使用 <<- 可忽略行首的 Tab制表符(?? 不忽略空格),提升可讀性:

    cat <<- EOFIndented with Tab (ignored)
    EOF  # 結束標記可用Tab縮進
    
  2. 嵌套與轉義

    • 嵌套時內層需轉義分隔符或禁用擴展:
      cat << 'OUTER'
      Outer text
      $(cat << 'INNER'  # 內層禁用擴展
      Inner $text
      INNER
      )
      OUTER
      
    • 遠程執行時需轉義遠程變量(如 \$PWD):
      ssh user@host << EOF
      Local: $PWD       # 本地解析
      Remote: \$PWD     # 遠程解析
      EOF
      
  3. 結束標記避坑

    • 嚴格頂格:結束標記(如 EOF)必須獨占一行且無前后空格,否則報錯 unexpected EOF
    • 唯一性:避免文本內出現結束標記(如用 END_CONFIG 替代 EOF)。

???? 💎 四、使用建議

場景推薦語法原因
動態生成多行文本(含變量)<< EOF自動展開變量/命令,簡化腳本邏輯
保留模板符號(如$var<< 'EOF'禁用替換,避免誤解析
縮進優化(代碼可讀性)<<- 'EOF'忽略Tab縮進,結束標記可對齊代碼
跨平臺腳本printf + \n避免 echo -e 的兼容性問題(如 dash

總結

  • 動態內容<< EOF
  • 靜態模板<< 'EOF'
  • 縮進優化<<- + Tab
    雙引號形式 << "EOF" 可忽略,因其行為與無引號版本幾乎一致。










在 Shell 腳本的 here document 語法中,<< EOF 是用于定義一個多行輸入塊的語法,但其定界符(如 EOF)是否被引號包裹('EOF'"EOF" 或無引號)會導致不同的行為。以下是具體區別:


???? 1. << EOV(無引號)
行為
定界符無引號時,here document 的內容會進行變量替換、命令替換、反斜杠轉義等 Shell 擴展。
示例

cat << EOV
當前用戶:$USER
當前路徑:$(pwd)
EOV

輸出:

當前用戶:ubuntu
當前路徑:/home/ubuntu

???? 2. << 'EOF'(單引號包裹定界符)
行為
定界符被單引號包裹時,here document 的內容會完全按原樣輸出,不進行任何 Shell 擴展
示例

cat << 'EOF'
當前用戶:$USER
當前路徑:$(pwd)
EOF

輸出:

當前用戶:$USER
當前路徑:$(pwd)

???? 3. << "EOF"(雙引號包裹定界符)
行為
雙引號包裹定界符時,行為與單引號完全一致:內容按原樣輸出,不進行任何 Shell 擴展
(注意:實際使用中 << "EOF"<< 'EOF' 效果相同,雙引號在此場景并無特殊意義。)

示例

cat << "EOF"
當前用戶:$USER
當前路徑:$(pwd)
EOF

輸出:

當前用戶:$USER
當前路徑:$(pwd)

???? 總結

語法Shell 擴展輸出是否原樣典型場景
<< EOV?? 允許擴展需要動態生成內容時
<< 'EOF'? 禁止擴展需要保留特殊字符時
<< "EOF"? 禁止擴展同單引號,但通常不推薦

???? 關鍵區別

  • 引號存在與否是決定是否擴展的關鍵。
  • 引號的類型(單/雙引號)對 here document 的行為無影響,統一禁用擴展。
  • 若需保留 $\ 等字符,應使用單引號或無歧義的 << \EOF

建議始終明確使用 << 'EOF'<< EOF,避免不必要的混淆。










在 Linux Shell 腳本中,<< EOV<< 'EOF'<< "EOF"Here Document(多行文本輸入)的三種定界符寫法,主要區別在于 是否允許變量擴展和命令替換。以下是詳細對比:


???? 📌 核心區別總結

語法變量/命令擴展特殊字符處理典型場景
<< EOV? 允許$VAR$(cmd) 會被解析需動態插入變量或命令結果
<< 'EOF'? 禁止所有內容原樣輸出需保留 $\ 等符號的原始文本
<< "EOF"? 允許(同無引號)<< EOV 行為相同<< EOV 一致,較少使用

EOV 可替換為任意自定義字符串(如 ENDSTOP),但需保證起始/結束標記一致。


???? 🔧 詳細行為說明
???????? 1?? << EOV(無引號)

  • 行為
    文本中的變量($VAR)和命令替換($(cmd) 或 ````cmd` ```)會被解析并替換為實際值。
  • 示例
    name="Alice"
    cat << EOV
    Hello, $name!  
    Today is $(date).
    EOV
    
    輸出
    Hello, Alice!  
    Today is Tue Jul 22 09:20:03 UTC 2025.
    

???????? 2?? << 'EOF'(單引號定界符)

  • 行為
    所有內容(包括 $\())均原樣輸出,禁止任何擴展
  • 示例
    name="Alice"
    cat << 'EOF'
    Hello, $name!  
    Today is $(date).
    EOF
    
    輸出
    Hello, $name!  
    Today is $(date).
    

???????? 3?? << "EOF"(雙引號定界符)

  • 行為
    與無引號 << EOV 完全一致,支持變量和命令擴展。雙引號在定界符中無特殊作用,實際使用較少。
  • 示例
    name="Alice"
    cat << "EOF"
    Hello, $name!  
    EOF
    
    輸出
    Hello, Alice!
    

???? ?? 關鍵注意事項

  1. 結束標記必須獨立頂格
    結束定界符(如 EOF)需單獨一行且無前置空格,否則會被視為普通文本。

    cat << EOF
    Correct
    EOF  # ? 正確cat << EOF
    Error: EOF 前有空格EOF  # ? 錯誤(行首有空格)
    
  2. 縮進處理
    使用 <<- 可忽略行首的 Tab 縮進(不忽略空格),便于腳本格式化:

    cat <<- EOFThis line starts with a Tab (ignored).
    EOF  # 結束符可用 Tab 縮進
    
  3. 特殊字符沖突
    若文本中包含定界符字符串(如 EOF),需改用其他唯一標識符(如 END)。

  4. 遠程執行轉義
    通過 SSH 執行時,若使用無引號定界符,遠程變量需轉義(如 \$PWD),避免本地解析:

    ssh user@host << 'EOF'  # 單引號更安全
    echo "Remote path: \$PWD"
    EOF
    

???? 💡 應用場景建議

  • 動態生成配置 → 用 << EOV
    例:插入環境變量到 Nginx 配置。
  • 保留原始文本 → 用 << 'EOF'
    例:輸出含 $ 的代碼模板或 SQL 語句。
  • 腳本格式化 → 配合 <<- + Tab 縮進
    例:函數內多行文本對齊。

???? 🌰 綜合示例

# 動態生成文件(變量擴展)
cat << EOV > config.conf
user = $USER
log_dir = /var/log/${APP_NAME}
EOV# 輸出原始 SQL 語句(禁止擴展)
mysql << 'EOF'
SELECT * FROM table WHERE id = 1;
EOF# 縮進優化(Tab 縮進被忽略)
func() {cat <<- ENDIndented with TabEND
}

通過靈活選擇定界符,可精準控制文本解析行為,提升腳本可讀性與安全性。










在Linux的Shell腳本中,<< EOV<< 'EOF'<< "EOF"Here Document 的不同寫法,主要區別在于對變量、命令替換和轉義字符的處理方式。以下是詳細解釋:


???? 1. << EOV(無引號包裹結束標記)

  • 作用:將多行文本作為輸入傳遞給命令,允許變量替換和命令替換
  • 示例
    cat << EOV
    當前用戶是 $USER
    系統時間:$(date)
    EOV
    
  • 輸出
    當前用戶是 root
    系統時間:Mon Jul 1 12:34:56 UTC 2024
    
  • 特點
    • $VAR$(command) 會被解析。
    • 結束標記 EOV 可以是任意合法標識符(如 EOFSTOP 等)。

???? 2. << 'EOF'(單引號包裹結束標記)

  • 作用:禁用變量和命令替換,內容原樣輸出
  • 示例
    cat << 'EOF'
    當前用戶是 $USER
    系統時間:$(date)
    EOF
    
  • 輸出
    當前用戶是 $USER
    系統時間:$(date)
    
  • 特點
    • 單引號會強制整個文檔內容按字面值處理。
    • 結束標記必須嚴格匹配(包括大小寫)。

???? 3. << "EOF"(雙引號包裹結束標記)

  • 作用:允許變量和命令替換(與無引號行為一致)。
  • 示例
    cat << "EOF"
    當前用戶是 $USER
    系統時間:$(date)
    EOF
    
  • 輸出
    當前用戶是 root
    系統時間:Mon Jul 1 12:34:56 UTC 2024
    
  • 特點
    • 雙引號不會禁用替換,行為與 << EOF 相同。
    • 實際使用中,雙引號包裹結束標記的情況較少見。

???? 關鍵區別總結

語法變量替換命令替換轉義字符(如 \n結束標記靈活性
<< EOV? 允許? 允許? 解析高(任意標識符)
<< 'EOF'? 禁用? 禁用? 原樣輸出低(嚴格匹配)
<< "EOF"? 允許? 允許? 解析低(嚴格匹配)

???? 使用場景建議

  1. 需要動態內容(如插入變量) → 用 << EOF<< "EOF"
  2. 需要靜態內容(如模板文件) → 用 << 'EOF'
  3. 避免結束標記沖突 → 自定義結束標記(如 << END_OF_TEXT)。

???? 常見錯誤

  • 結束標記未頂格EOF 必須單獨成行且無縮進(除非用 <<- 忽略制表符)。
  • 標記不匹配:如定義 << EOV,但結束行寫成了 EOF
  • 引號誤用:如 << 'EOF' 中誤用雙引號,導致替換未禁用。

通過合理選擇語法,可以更靈活地控制Here Document的行為。










在 Linux 的 Here Document(<<)中,<< EOV<< 'EOF'<< "EOF" 的區別主要體現在 分隔符的引號處理內容中的變量/命令替換規則 上。以下是詳細對比:


???? 1. 基本語法與行為
???????? 1.1 << EOV(無引號包裹分隔符)

  • 行為
    • 分隔符 EOV 無需引號包裹。
    • 內容中的變量和命令替換會被解析(類似雙引號行為)。
    • 如果分隔符是 EOF,但拼寫錯誤為 EOV,則必須確保 EOV 是唯一且匹配的標記。
  • 示例
    name="Alice"
    cat << EOV
    Hello, $name!
    Today is $(date).
    EOV
    
    輸出
    Hello, Alice!
    Today is 2025-07-22 09:16:21
    

???????? 1.2 << 'EOF'(單引號包裹分隔符)

  • 行為
    • 分隔符 EOF 被單引號包裹。
    • 內容中的變量、命令替換均不會被解析(完全保留原樣)。
    • 適用于需要避免變量提前展開的場景(如遠程腳本傳遞)。
  • 示例
    name="Alice"
    cat << 'EOF'
    Hello, $name!
    Today is $(date).
    EOF
    
    輸出
    Hello, $name!
    Today is $(date).
    

???????? 1.3 << "EOF"(雙引號包裹分隔符)

  • 行為
    • 分隔符 EOF 被雙引號包裹。
    • 內容中的變量會被解析(類似雙引號行為),但 命令替換不會被解析
    • 這是 Shell 的默認行為,但需注意與單引號的區別。
  • 示例
    name="Alice"
    cat << "EOF"
    Hello, $name!
    Today is $(date).
    EOF
    
    輸出
    Hello, Alice!
    Today is $(date).
    

???? 2. 關鍵區別總結

語法變量替換命令替換適用場景
<< EOF??默認行為,動態生成內容
<< 'EOF'??避免變量/命令提前解析(如遠程腳本)
<< "EOF"??僅解析變量,保留命令替換原始值

???? 3. 實際應用場景
???????? 3.1 動態生成內容

name="Alice"
cat << EOF
Hello, $name!
Today is $(date).
EOF
  • 用途:生成包含動態變量的多行文本(如日志、報告)。
  • 輸出
    Hello, Alice!
    Today is 2025-07-22 09:16:21
    

???????? 3.2 遠程執行腳本(防止變量提前展開)

ssh user@remote_host 'bash -s' << 'EOF'
export PATH=$PATH:/opt/tool
echo "Remote path: $PATH"
EOF
  • 用途:確保變量 $PATH 在遠程主機上解析,而非本地。
  • 輸出(在遠程主機上):
    Remote path: /usr/local/sbin:/usr/bin:...:/opt/tool
    

???????? 3.3 保留命令替換原始值

cat << "EOF"
The date command is: $(date)
EOF
  • 用途:輸出命令替換的原始字符串,而非執行結果。
  • 輸出
    The date command is: $(date)
    

???? 4. 注意事項

  1. 分隔符必須頂格

    • 分隔符 EOF 必須單獨成行,且 無前導空格或縮進(除非使用 <<- EOF)。
    • 示例(錯誤):
      cat << EOFThis line has leading spaces.
      EOF  # 錯誤!分隔符必須頂格
      
    • 正確寫法:
      cat << EOF
      This line is correct.
      EOF
      
  2. 分隔符命名

    • 可自定義分隔符(如 EOVTIAN),但需保持前后一致。
    • 示例:
      cat << TIAN
      This is a custom delimiter.
      TIAN
      
  3. 縮進處理

    • 使用 <<- EOF 可忽略分隔符所在行的前導 Tab 縮進(但不推薦混用空格和 Tab)。
    • 示例:
      cat <<- EOFThis line has leading tabs.They will be ignored.
      EOF
      

???? 5. 總結

  • << EOF:默認行為,動態解析變量和命令。
  • << 'EOF':完全保留原始內容,適合遠程腳本傳遞。
  • << "EOF":僅解析變量,保留命令替換原始值。
  • 選擇依據:根據是否需要動態替換內容或避免提前解析變量來選擇合適的語法。










在Linux的Here Document(嵌入文檔)語法中,<< EOV<< 'EOF'<< "EOF" 是三種不同的分界符寫法,它們的核心區別在于對變量替換轉義字符的處理方式。以下是詳細對比:

???? 1. << EOV(無引號分界符)

  • 特點:分界符不加引號,shell會解析Here Document中的變量替換命令替換,但不解析轉義字符(如 \n 會被當作普通字符)。
  • 分界符選擇EOV 只是示例,可自定義為任意字符串(如 ENDMARK),建議用大寫避免與變量名沖突。

示例:

NAME="Alice"
cat << EOV
Hello $NAME          # 變量被替換為 Alice
Date: $(date +%F)    # 命令被替換為實際日期
Line 1\nLine 2       # \n 不被解釋為換行
EOV

輸出:

Hello Alice
Date: 2025-07-22  # 實際日期
Line 1\nLine 2    # 轉義字符未生效

???? 2. << 'EOF'(單引號分界符)

  • 特點:分界符用單引號包裹,Here Document中的所有內容都會被原樣保留,包括變量($VAR)、命令替換($(cmd))和轉義字符(\n)。
  • 分界符固定:通常用 EOF(End of File),但可自定義(如 'END')。

示例:

NAME="Alice"
cat << 'EOF'
Hello $NAME          # $NAME 原樣輸出
Date: $(date +%F)    # 命令不執行,原樣輸出
Line 1\nLine 2       # \n 不被解釋為換行
EOF

輸出:

Hello $NAME
Date: $(date +%F)
Line 1\nLine 2

???? 3. << "EOF"(雙引號分界符)

  • 特點:分界符用雙引號包裹,Here Document中的變量和命令會被替換,但轉義字符會被保留(與 << EOF 效果相同)。
  • 分界符固定:通常用 EOF,但可自定義(如 "END")。

示例:

NAME="Alice"
cat << "EOF"
Hello $NAME          # 變量被替換為 Alice
Date: $(date +%F)    # 命令被替換為實際日期
Line 1\nLine 2       # \n 不被解釋為換行
EOF

輸出:

Hello Alice
Date: 2025-07-22  # 實際日期
Line 1\nLine 2    # 轉義字符未生效

???? 4. 關鍵區別總結

分界符寫法變量替換($VAR命令替換($(cmd)轉義字符(\n
<< EOF? 解析? 執行? 保留為文本
<< 'EOF'? 保留為文本? 保留為文本? 保留為文本
<< "EOF"? 解析? 執行? 保留為文本

???? 5. 常見應用場景

  • << EOF(無引號):需要動態生成內容,且包含變量或命令替換(如配置文件、腳本生成)。

    # 生成配置文件,動態插入用戶名
    cat << EOF > app.conf
    user=$USER
    log_dir=/var/log/$USER
    EOF
    
  • << 'EOF'(單引號):原樣保留文本(如代碼片段、SQL語句),避免變量污染。

    # 執行SQL腳本,保留變量不解析
    mysql -u root << 'EOF'
    SELECT * FROM users WHERE name = '$USER';  # $USER 不被替換
    EOF
    
  • << "EOF"(雙引號):與 << EOF 幾乎相同,極少使用(語法冗余)。

???? 6. 分界符命名建議

  • EOF:最常用,代表“文件結束符”,適用于大多數場景。
  • 自定義名稱(如 EOVEND):當內容中需要包含 EOF 字符串時,避免沖突。
    # 內容包含 EOF,使用 EOV 作為分界符
    cat << EOV
    This line contains EOF without issues.
    EOV
    

???? 總結

  • << EOF:靈活處理動態內容,適合需要變量替換的場景。
  • << 'EOF':嚴格保留文本原貌,適合代碼片段或需要禁用解析的場景。
  • << "EOF":與無引號效果相同,語法上存在但很少使用。
    選擇分界符時,根據是否需要變量替換和轉義字符的解析行為來決定。










這三個寫法都是 Here Document(或 Here-String) 的語法,但它們在變量替換和轉義行為上有明顯區別。下面是詳細對比:


???? ? << EOV

  • 不加引號(默認行為)。
  • 變量會被替換(如 $var 會被展開)。
  • 反斜杠轉義生效(如 \n 會被解釋成換行)。
  • 命令替換生效(如 $(date) 會被執行)。

示例

name="world"
cat << EOV
Hello, $name
Current date: $(date)
EOV

輸出

Hello, world
Current date: Tue Jul 22 12:34:56 UTC 2025

???? ? << 'EOF'

  • 單引號包裹定界符'EOF')。
  • 完全禁止變量替換和轉義(純文本,所見即所得)。
  • 反斜杠和 $ 均按字面處理

示例

name="world"
cat << 'EOF'
Hello, $name
Current date: $(date)
EOF

輸出

Hello, $name
Current date: $(date)

???? ? << "EOF"

  • 雙引號包裹定界符"EOF")。
  • 行為與不加引號完全相同(即變量替換、轉義、命令替換均生效)。
  • 實際效果等價于 << EOF(雙引號無額外作用)。

示例

name="world"
cat << "EOF"
Hello, $name
Current date: $(date)
EOF

輸出

Hello, world
Current date: Tue Jul 22 12:34:56 UTC 2025

???? 📌 總結表

寫法變量替換命令替換轉義字符典型用途
<< EOF? 生效? 生效? 生效需要動態內容時
<< 'EOF'? 禁用? 禁用? 禁用需要純文本字面量時
<< "EOF"? 生效? 生效? 生效與無引號完全等價

???? ?? 注意

  • 定界符(如 EOFEOV本身的引號只是語法標記,不會出現在最終內容中
  • 如果定界符前加 -(如 <<-EOF),會忽略輸入中的前導制表符(縮進友好)。










在Shell腳本中,<< EOV<< 'EOF'<< "EOF" 是三種不同的 Here Document 語法變體,它們的核心區別在于 變量解析轉義字符處理分隔符的書寫規范。以下是具體分析:


???? 1. << EOV(無引號)

  • 變量解析:支持變量和命令替換(如 $VAR、$(cmd))。
  • 轉義字符:支持反斜杠轉義(如 \n 轉換為換行)。
  • 分隔符要求
    • 分隔符(如 EOV)需嚴格匹配,區分大小寫。
    • 分隔符前后不能有額外空格或制表符。
  • 示例
    var="World"
    cat << EOV
    Hello $var!
    Line with \t tab and \n newline.
    EOV
    
    輸出
    Hello World!
    Line with     tab and newline.
    

???? 2. << 'EOF'(單引號)

  • 變量解析:禁用所有變量和命令替換($VAR 原樣保留)。
  • 轉義字符:禁用反斜杠轉義(\n 視為普通字符)。
  • 分隔符要求
    • 分隔符(如 EOF)需嚴格匹配,區分大小寫。
    • 單引號僅作用于分隔符,內容仍遵循單引號規則。
  • 示例
    var="World"
    cat << 'EOF'
    Hello $var!
    Line with \t tab and \n newline.
    EOF
    
    輸出
    Hello $var!
    Line with \t tab and \n newline.
    

???? 3. << "EOF"(雙引號)

  • 變量解析:支持變量和命令替換(如 $VAR、$(cmd))。
  • 轉義字符:支持部分轉義字符(如 \n 換行、\t 制表符),但禁用命令替換(如 `cmd` 不執行)。
  • 分隔符要求
    • 分隔符(如 EOF)需嚴格匹配,區分大小寫。
    • 雙引號允許分隔符內包含變量(如 "EOF$VAR")。
  • 示例
    var="World"
    cat << "EOF"
    Hello $var!
    Line with \t tab and \n newline.
    EOF
    
    輸出
    Hello World!
    Line with	  tab and 
    newline.
    

???? 關鍵對比表

特性<< EOV<< 'EOF'<< "EOF"
變量解析???
命令替換???
轉義字符??? (部分)
分隔符大小寫敏感???

???? 注意事項

  1. 分隔符一致性:無論是否加引號,結束標記必須與起始標記完全一致(包括大小寫)。

    # 錯誤示例:大小寫不匹配
    cat << EOF
    Content
    eof  # 小寫會導致語法錯誤
    
  2. 縮進問題:若希望內容自動去除前導縮進,可改用 <<- 語法:

    cat <<- EOF
    Line 1Line 2 with indentation
    EOF
    
  3. 混合引號場景:可通過嵌套引號實現復雜需求,例如:

    cat << "EOF_$VAR"  # 動態分隔符(需確保變量安全)
    Content with variables: $VAR
    EOF_$VAR
    

通過合理選擇 Here Document 的形式,可以靈活控制文本內容的解析行為,滿足腳本編寫中的多樣化需求。










在 Shell 中,Heredoc 的不同引號形式(<< EOV、<< ‘EOF’、<< “EOF”)會直接影響變量和命令的解析行為。以下是詳細對比:


???? 1. << EOV(無引號)

  • 變量/命令擴展:啟用
    內容中的 VAR、VAR、VAR(command) 和 command 會被解析執行
  • 轉義字符:啟用
    反斜杠 \ 會解釋為轉義字符
  • 適用場景:需要動態生成內容時
  • 示例:
    bash name=“Alice” cat << EOV Hello $name Today is $(date) EOV
    輸出:
    Hello Alice Today is Fri May 10 12:00:00 UTC 2024

???? 2. << ‘EOF’(單引號)

  • 變量/命令擴展:完全禁用
    所有內容按原樣輸出(包括 $、` 等符號)
  • 轉義字符:禁用
    反斜杠 \ 直接輸出為普通字符
  • 適用場景:保留代碼模板或包含特殊符號的內容
  • 示例:
    bash cat << ‘EOF’ $PATH ls -l Line with \backslash EOF
    輸出(完全原樣):
    $PATH ls -l Line with \backslash

???? 3. << “EOF”(雙引號)

  • 變量/命令擴展:禁用(與單引號一致)

注意:在 Heredoc 中,單引號與雙引號效果完全相同,均會禁用擴展。這是 Heredoc 語法的特殊設計。

  • 轉義字符:禁用
    同單引號,反斜杠直接輸出
  • 示例:
cat << "EOF"   $USER $(date)   EOF   

輸出(原樣):

$USER $(date)  

???? 對比總結

形式變量/命令擴展轉義符處理典型用例
<< EOV? 啟用? 轉義生效生成動態內容
<< ‘EOF’? 禁用? 直接輸出保留特殊字符(如 $、\、)
<< “EOF”? 禁用? 直接輸出同上(與單引號完全等效)

???? ?? 關鍵細節 1.
引號位置:引號必須緊貼定界符(如<<‘EOF’),空格會導致行為變化:

  # 錯誤:引號與 << 之間帶空格(效果等同于無引號)    cat << 'EOF'   # 等效于 << EOF   
  1. 雙引號的歧義: 在普通字符串中 " "會保留變量擴展,但 Heredoc 的雙引號是語法糖,實際效果與單引號一致。這是為了語法一致性而設計的特殊行為。
  2. 定界符命名: EOV、EOF可任意命名(如<< END),只需首尾一致,但習慣用 EOF(End Of File)。 — 使用建議 - 需動態內容 → 無引號(<< EOF) - 需保留原樣內容 → 單引號(<< ‘EOF’`)

不推薦寫雙引號形式(容易引發誤解,用單引號更明確)










在Shell中,Heredoc(Here Document)的定界符(如EOF)可以不帶引號,也可以帶單引號或雙引號,這會影響其中變量、命令替換等是否被解析。

  1. << EOF(不帶引號)
    內容中的變量和命令替換會被解析。
    例如:
cat << EOF
Current path: $PWD
EOF

輸出:

Current path: /current/directory
  1. << 'EOF'(單引號)
    完全禁止解析。內容按原樣輸出,不解析變量、命令、轉義等。
    例如:
cat << 'EOF'
Current path: $PWD
EOF

輸出:(原樣輸出)

Current path: $PWD
  1. << "EOF"(雙引號)
    實際上,在Heredoc語法中,雙引號的效果等同于沒有引號(即會解析變量和命令替換)。但是,請注意:Heredoc的定界符通常不寫雙引號,而寫雙引號的行為在標準Shell中與不帶引號一致。
    然而,根據POSIX標準,Heredoc定界符的引號行為是:

若定界符被引號(單引號或雙引號)包圍,則Heredoc內容中的變量等不會被擴展(但請注意,實際上只有單引號被明確規定為完全禁止擴展,而雙引號在定界符上的使用并沒有特別改變行為,所以通常雙引號在這里等同于無引號)。

但是,在常見Shell(如Bash)中,<< “EOF” 和 << EOF 是等效的,都會擴展。而 << ‘EOF’ 則不擴展。 實際上,在Bash手冊中明確指出:如果定界符是加引號的(可以是任何引號形式,包括單引號、雙引號或反斜杠),那么Heredoc內容中的參數擴展、命令替換和算術擴展都不會被解析。換句話說,任何形式的引號(包括雙引號)都會使定界符被引用,從而禁止擴展。 然而,測試發現:
在Bash中:

cat << "EOF"
$HOME
EOF

輸出:

$HOME

(原樣輸出)—— 因為定界符用了雙引號,所以禁止擴展。

所以,結論是:
在Heredoc中,如果定界符用單引號、雙引號或反斜杠(即\EOF)引用,都會禁止Heredoc內容中的擴展。而沒有引號則允許擴展。
因此,
三種形式可以總結為:

<< EOF:擴展(變量、命令等會被解析)。
<< \EOF<< "EOF"<< 'EOF':均不擴展(原樣輸出)。

但請注意,盡管雙引號和單引號在禁止擴展上效果相同,但通常推薦使用單引號來明確表示完全不擴展,因為單引號在Shell中的語義就是完全按字面意思。而雙引號在Heredoc定界符中的使用相對少見。


示例對比
示例1:無引號(擴展)

name="Alice"
cat << EOF
Hello, $name
EOF

輸出:

Hello, Alice

示例2:單引號(不擴展)

name="Alice"
cat << 'EOF'
Hello, $name
EOF

輸出:

Hello, $name

示例3:雙引號(不擴展)

name="Alice"
cat << "EOF"
Hello, $name
EOF

輸出:

Hello, $name

示例4:反斜杠(不擴展)

name="Alice"
cat << \EOF
Hello, $name
EOF

輸出:

Hello, $name

注意事項
無論是否使用引號,Heredoc的內容都可以跨越多行,直到遇到定界符(必須單獨成行且前后無空白)。
如果需要在Heredoc內部按原樣輸出帶有特殊字符的內容,使用引號(單引號、雙引號或反斜杠)是最安全的方式。
總結
需要擴展:使用不帶引號的定界符(<< EOF)。
不需要擴展(原樣輸出):使用帶引號的定界符(單引號、雙引號或反斜杠),即<< ‘EOF’、<< "EOF"或<< \EOF。盡管雙引號和反斜杠也能達到效果,但通常更推薦使用單引號,因為其語義更清晰(完全按字面)。






























LinuxShell 的 Here-Document(<< EOF) 筆記250723







Linux的<< EOF(Here-Document)詳解多回答筆記250722







tee x << EOFcat > x << EOFcat << EOF > x 對比 筆記250709







tee x << EOFtee > x << EOFtee << EOF > xcat > x << EOFcat << EOF > x 對比 筆記250722







<< EOF<< ‘EOF‘<< “EOF“有無引號的區別多回答筆記250722







<< EOF<< \EOF<< ‘EOF‘<< “EOF“多講解筆記250722







Here-Document的<<<<-<<< 多解說筆記250722







Here-Document(EOF)與echo,printf多個比較筆記250723







比較Linux的Shell的 EOFechoprintf , 將文本輸出到文件







本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:
http://www.pswp.cn/diannao/92911.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/92911.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/92911.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

點擊按鈕滾動到底功能vue的v-on:scroll運用

使用vue自帶的監聽滾動功能v-on:scroll&#xff0c;滾動條變化時&#xff0c;會調用方法 checkScrollStatus&#xff0c;如果滾動條在容器底部時&#xff0c;則隱藏按鈕&#xff0c;否則顯示按鈕&#xff0c;點擊按鈕能一鍵滾動到底部。<div class"chat-area" ref…

Linux下編譯SLEPc

本文記錄在Linux下編譯安裝SLEPc的流程。 一、下載代碼 git clone https://github.com/slepc/slepc.git cd ./slepc二、安裝依賴 2.1 安裝PETSc 參見: <Linux下編譯安裝PETSc> 2.2 安裝intel oneAPI sudo apt install intel-oneapi-base-toolkit sudo apt install i…

【無標題】qwen3-8b 強化學習訓練后的模型,可以接著 進行其他grpo 強化學習訓練 嗎

ser_count’, 0),)} {((‘valid_user_count’, 1),)} 44 0.0 88 [0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.0, 0.6, 0.0, 0.6, 0.0, 0.6] 55 100%|???{‘loss’: 0.0132, ‘grad_norm’: 0.07552657276391983, ‘learning_rate’: 2e-06, ‘num_tokens’: 2098…

IDC權威認可:瑞數信息雙項入選《中國大模型安全保護市場概覽》

近日&#xff0c;國際數據公司IDC正式發布了《中國大模型安全保護市場概覽&#xff0c;2025&#xff1a;全方位安全檢測與防護構建可信AI》報告。本次報告中IDC結合全球統一定義以及中國市場特色&#xff0c;將中國大模型安全保護市場劃分為7個細分領域&#xff0c;并通過對中國…

多智能體(Multi-agent)策略模式:思維鏈CoT和ReAct

參考&#xff1a;https://zhuanlan.zhihu.com/p/704523060 &#x1f3af; 一句話記住 CoT&#xff1a;像“考試時在草稿紙上寫完所有步驟&#xff0c;再抄答案”。ReAct&#xff1a;像“玩密室逃脫&#xff0c;每開一個箱子就去找下一個線索”。 用小學生能聽懂的話 兩個小故事…

ChatGPT指令大全:輸入需求=輸出完整方案

ChatGPT指令大全提供數百個精煉過的指令語句 (提示詞)&#xff0c;讓你充分發揮 ChatGPT 的強大功能 一、核心功能模塊分類 1. 求職與面試 簡歷優化 專業反饋&#xff1a;按面試官視角分析簡歷并提出改進建議量化數據&#xff1a;為經歷添加具體數字&#xff08;如提升效率30…

Java零基礎入門學習知識點2-JDK安裝配置+Maven

文章目錄版本提示參考視頻Maven環境準備一、安裝Java開發工具包&#xff08;JDK&#xff09;二、JDK環境配置三、下載Maven安裝包*四、Maven環境配置&#xff08;可省略&#xff09;*五、驗證安裝&#xff08;上一步沒做&#xff0c;這步無法驗證&#xff0c;可省&#xff09;六…

基于單片機智能衣柜/智能衣櫥設計

傳送門 &#x1f449;&#x1f449;&#x1f449;&#x1f449;其他作品題目速選一覽表 &#x1f449;&#x1f449;&#x1f449;&#x1f449;其他作品題目功能速覽 概述 本設計實現了一種基于單片機的多功能智能衣柜&#xff0c;融合環境檢測、安全防護與用戶交互功能…

自動語音識別(ASR)技術詳解

語音識別&#xff08;Automatic Speech Recognition, ASR&#xff09;是人工智能和自然語言處理領域的重要技術&#xff0c;旨在將人類的語音信號轉換為對應的文本。近年來&#xff0c;深度學習的突破推動語音識別系統從實驗室走入日常生活&#xff0c;為智能助手、實時翻譯、醫…

【MySQL】MySQL 事務和鎖詳解

一、MySQL 事務 1.1 事務介紹 在 MySQL 中&#xff0c;事務&#xff08;Transaction&#xff09; 是一組不可分割的 SQL 操作序列&#xff0c;這些操作要么全部成功執行&#xff0c;要么全部失敗回滾&#xff0c;以此保證數據庫操作的完整性和一致性。 事務將數據庫從一種一致…

虛擬直線閾值告警人員計數算法暑期應用

智慧人員計數助力暑期&#xff1a;技術賦能安全管理的創新實踐一、背景&#xff1a;暑期人流激增下的安全管理挑戰暑期是旅游、商業、交通等場景的客流高峰期&#xff0c;人員密集區域易引發踩踏事故、管理混亂等安全隱患。傳統人工計數方式效率低、誤差大&#xff0c;難以滿足…

SQL164 2021年11月每天新用戶的次日留存率

SQL164 2021年11月每天新用戶的次日留存率 思路 ?找出新用戶?&#xff1a;確定每個用戶首次活躍的日期&#xff08;即新用戶&#xff09; 例如101用戶在11月1日首次出現 ?處理跨天活躍?&#xff1a;考慮用戶可能跨天活躍的情況&#xff08;in_time和out_time不在同一天&a…

基于單片機的數字電壓表設計

2 系統原理及基本框圖 如圖2.1所示&#xff0c;模擬電壓經過檔位切換到不同的分壓電路衰減后&#xff0c;經隔離干擾送到A/D轉換器進行A/D轉換&#xff0c;然后送到單片機中進行數據處理。處理后的數據送到LCD中顯示&#xff0c;同時通過串行通訊與上位機通信。圖2.1系統基本方…

[NLP]UPF基本語法及其在 native low power verification中的典型流程

UPF基本語法及其在 native low power verification中的典型流程 摘要:本文首先簡要介紹 UPF(Unified Power Format),然后解釋其在 native low power verification(原生低功耗驗證)中的典型流程。最后,我將使用50個具體例子來完整展示 UPF 的關鍵語法。這些例子基…

fish-speech 在50系列顯卡使用 --compile加速兼容

#環境說明 GPU: NVIDIA GeForce RTX 5080 Laptop GPU (sm_120) win11家庭版 24H2 #問題匯總 baize.exceptions.HTTPException: (500, "RuntimeError: ptxas failed with error code 4294967295: \\n\\n") 問題匯總 1 baize.exceptions.HTTPException: (500, "…

UI自動化測試實戰

Python接口自動化測試零基礎入門到精通&#xff08;2025最新版&#xff09;一、設計背景 隨著IT行業的發展&#xff0c;產品愈漸復雜&#xff0c;web端業務及流程更加繁瑣&#xff0c;目前UI測試僅是針對單一頁面&#xff0c;操作量大。為了滿足多頁面功能及流程的需求及節省工…

面試實戰,問題六,被問數據庫索引,怎么回答

Java開發面試&#xff1a;數據庫索引的原理及常見問題解答 在Java開發面試中&#xff0c;數據庫索引是核心知識點&#xff0c;涉及數據庫優化和性能調優。索引通過高效的數據結構加速數據檢索&#xff0c;降低磁盤IO成本&#xff0c;并支持排序操作。下面我將逐步解釋索引的原理…

ARM-I2C硬實現

硬件I2C-GD32F4系列的實現初始化操作在初始化函數里執行以下代碼uint32_t i2cx_scl_port_rcu RCU_GPIOB; uint32_t i2cx_scl_port GPIOB; uint32_t i2cx_scl_pin GPIO_PIN_6; uint32_t i2cx_scl_af GPIO_AF_4;uint32_t i2cx_sda_port_rcu RCU_GPIOB; uint32_t i2cx_sda_po…

WinUI3開發_過渡動畫

簡介 過渡動畫是當發生事件時控件UI狀態發生改變時以一種動畫形式來演變到另外一種狀態&#xff0c;而非瞬間改變&#xff0c;使用一種更加平滑的方式來進行切換&#xff0c;例如下圖是文字切換的交叉柵欄效果&#xff1a;還有頁面切換動畫&#xff1a;在或者是圖標動畫&#x…

Linux下提權root權限

現在AI工具這么豐富&#xff0c;稍微搜一下就有一個差不多的總結輸出。但是&#xff0c;可能還不夠詳細&#xff0c;或者給得太多~~~今天時間關系&#xff0c;今天只總結了在Linux如何提權到root&#xff0c;并沒有寫如何進行防護。后面有時間&#xff0c;我再總結一下。命令實…