Linux的<< EOF
(Here-Document)详解多回答笔记250722
Linux 中的 << EOF
结构称为 Here Document(立即文档或嵌入文档),它是一种在 Shell 脚本中直接嵌入多行文本输入流(通常作为命令的标准输入)的方式。EOF
只是一个标记(可自定义),用于标识文本的开始和结束位置。
基本语法
command << EOF
文本内容...
多行文本...
EOF
command
:接收标准输入的命令(如cat
,grep
,ssh
,mysql
等)。<< EOF
:声明 Here Document 的开始,EOF
是结束标记符(常用EOF
或END
,但可自定义)。- 文本内容:所有在
<< EOF
和EOF
之间的行都会作为command
的输入。 EOF
:单独一行,表示文本结束(必须顶格写,前后不能有空格)。
关键特性与用法
1. 自定义结束标记
EOF
可替换为任意大写字母单词(如 MARKER
、END
):
cat << MYEND
第一行
第二行
MYEND
2. 缩进问题 - <<-
消除缩进
默认情况下,结束标记必须顶格(无缩进)。使用 <<-
可忽略结束标记前的 Tab 制表符(注意:空格无效!):
cat <<- EOF
第一行(有缩进)
第二行(有缩进)
EOF # 用 Tab 缩进,会被忽略
3. 变量与命令替换
默认情况下,Here Document 内的变量、命令和转义字符会被解析:
name="Alice"
cat << EOF
Hello, $name! # 输出 Hello, Alice!
Today is $(date).
EOF
4. 禁用替换 - 单引号结束标记
在结束标记前加单引号(<< 'EOF'
),可禁止变量替换、命令替换和转义:
cat << 'EOF'
$name # 原样输出 $name
$(date) # 原样输出 $(date)
EOF
5. 管道与重定向
Here Document 可与其他重定向结合:
# 输出到文件
cat << EOF > output.txt
内容...
EOF
# 作为管道输入
grep "key" << EOF
line1
key line
line3
EOF
常见应用场景
1. 生成配置文件
cat > config.yaml << EOF
server:
port: 8080
host: 0.0.0.0
database:
url: jdbc:mysql://localhost/db
EOF
2. 执行多行交互命令
# 远程执行命令
ssh user@host << EOF
cd /path
git pull
sudo systemctl restart app
EOF
# 数据库操作
mysql -u root -p << EOF
USE mydb;
SELECT * FROM users;
EOF
3. 脚本内多行注释
利用 :
(空命令)和禁用替换的 Here Document:
: << 'COMMENT'
这段是注释内容
不会被解析执行
COMMENT
4. 创建多行字符串变量
read -r -d '' help_msg << EOF
Usage: $0 [options]
Options:
-h Show help
-v Enable verbose
EOF
echo "$help_msg"
高级用法
1. Here Document + sudo
# 将内容写入需 root 权限的文件
sudo tee /etc/config.conf << EOF
[Settings]
key=value
EOF
2. 嵌套 Here Document
需谨慎处理结束标记:
cat << EOF
外层内容
cat << INNER
内层内容
INNER
EOF
3. 与 expect
结合(自动化交互)
expect << EOF
spawn ssh user@host
expect "password:"
send "mypass\r"
expect eof
EOF
总结
特性 | 语法 | 作用 |
---|---|---|
基本用法 | << EOF |
嵌入多行文本 |
忽略 Tab 缩进 | <<- EOF |
允许结束标记前有 Tab 缩进 |
禁用替换 | << 'EOF' |
原样输出文本内容 |
输出到文件 | > file |
将嵌入文本重定向到文件 |
注释块 | : << 'COMMENT' |
实现多行注释 |
掌握 Here Document 能极大提升 Shell 脚本处理多行输入的灵活性和可读性,尤其适用于配置生成、远程命令执行和交互自动化等场景。
在Linux Shell脚本中,<< EOF
是一种称为 Here Document(或 Here-Doc)的结构,用于将多行文本直接作为输入传递给命令或脚本。以下是详细解析:
基本语法
command << DELIMITER
文本内容...
多行输入...
DELIMITER
command
:接收输入的命令(如cat
、grep
、ssh
或脚本)。DELIMITER
:自定义终止标记(常用EOF
/END
,但可替换为任意字符串)。- 文本块:位于两个
DELIMITER
之间的内容会作为command
的输入。
核心特性
变量扩展(默认开启)
name="Alice" cat << EOF Hello, $name! # 变量会被解析 Today is $(date) EOF
输出:
Hello, Alice! Today is Tue Jul 22 10:00:00 UTC 2025
禁用变量扩展(使用
<<'DELIMITER'
)cat <<'EOF' $name # 原样输出,不解析变量 `ls` # 不执行命令 EOF
输出:
$name `ls`
缩进处理(
<<-
忽略开头的制表符)cat <<- EOF This line has a tab. This too. # 行首制表符会被自动忽略 EOF
注意:仅忽略 制表符(Tab),空格仍需手动处理。
常见应用场景
生成配置文件
cat > /etc/nginx.conf << EOF server { listen 80; server_name example.com; root /var/www/html; } EOF
执行多行命令(如
ssh
)ssh user@host << EOF cd /tmp touch test.txt echo "Done" > test.txt EOF
创建脚本
bash << EOF echo "Running in subshell" if [ -f "/tmp/file" ]; then rm -f /tmp/file fi EOF
与
sudo
配合sudo tee /etc/file.conf > /dev/null << EOF [Settings] PORT=8080 DEBUG=false EOF
重要注意事项
终止标记必须独占一行:
# 正确 cat << EOF content EOF # 错误(EOF前有空格) cat << EOF content EOF # 脚本报错
标记符选择:
- 避免使用与内容冲突的标记(如内容含
EOF
时改用END
)。 - 大小写敏感(
EOF
≠eof
)。
- 避免使用与内容冲突的标记(如内容含
特殊字符转义:
- 在非引号模式下(
<< EOF
),需转义$
、\
等符号:cat << EOF Price: \$100 Path: /usr/bin EOF
- 在非引号模式下(
高级用法
嵌套使用:
cat << 'OUTER' cat << INNER Inner Here-Doc INNER OUTER
管道传递:
cat << EOF | grep "Hello" Hello World Goodbye EOF
结合
awk
/sed
处理文本:awk '{print $1}' << EOF Apple 10 Banana 20 EOF # 输出: Apple\nBanana
总结
特性 | 语法 | 作用 |
---|---|---|
变量扩展 | << EOF |
解析变量/命令 |
禁用扩展 | << 'EOF' |
原样输出文本 |
忽略行首制表符 | <<- EOF |
允许代码缩进(仅Tab有效) |
掌握 Here Document 能极大简化脚本中对多行文本的处理,尤其适用于配置生成、远程命令执行等场景。使用时注意终止标记的书写规范,并根据需求选择是否启用变量扩展。
Linux 的 << EOF
(Here Document) 详解
1. 基本概念
- Here Document 是一种 Shell 重定向技术,用于将多行文本直接传递给命令的标准输入(stdin)。
- 语法:
命令 << 分隔符
,后跟文本内容,以单独一行的分隔符结束。 - 默认支持变量替换和命令替换(类似双引号
"
的行为)。
2. 基础语法
命令 << EOF
文本行1
文本行2
...
EOF
示例:
cat << EOF
Hello, World!
Today is $(date) # 命令替换
User: $USER # 变量替换
EOF
输出:
Hello, World!
Today is Tue Jul 22 10:00:00 CST 2025
User: your_username
3. 禁用替换:引号包裹分隔符
- 用单引号
'EOF'
包裹分隔符可禁用替换(类似单引号'
的行为)。
cat << 'EOF'
Hello, $USER # 变量不替换
Today is $(date) # 命令不执行
EOF
输出:
Hello, $USER
Today is $(date)
4. 缩进文本:<<-
用法
- 使用
<<-
可忽略结束分隔符前的 Tab 制表符(空格无效)。
cat <<- EOF
Hello! # 此行有 Tab 缩进
EOF # 结束符前必须有 Tab
输出(无缩进):
Hello!
5. 高级用法
管道传递:与其他命令组合
grep "key" << EOF line1: key value line2: no match EOF
输出:
line1: key value
写入文件:替代
echo
cat > output.txt << EOF File content EOF
SSH 执行远程命令:
ssh user@host << EOF echo "Running on \$HOSTNAME" uptime EOF
多行注释(利用
:
空命令):: << 'COMMENT' 这是被注释的代码块 echo "不会执行" COMMENT
6. 注意事项
- 分隔符唯一性:文本内避免出现分隔符字符串。
- 空格敏感:
<<-
仅忽略 Tab,不忽略空格。 - 命令位置:结束分隔符必须单独一行且顶格(或用 Tab)。
7. 应用场景
- 脚本中生成配置文件(如 Dockerfile、nginx.conf)。
- 向交互式命令传递多行输入(如
ftp
、psql
)。 - 编写内联文档或帮助信息。
示例:动态生成 SQL 文件
mysql -u root << EOF
CREATE DATABASE mydb;
USE mydb;
CREATE TABLE users (id INT, name VARCHAR(30));
EOF
提示:结合
tee
可同时输出到屏幕和文件:
cat << EOF | tee file.txt
Linux 中的 << EOF
(通常称为 Here Document 或 Heredoc)是一种强大的 Shell 输入重定向机制,用于将多行文本块直接作为命令的标准输入。它极大地简化了在脚本中向命令提供大量输入或创建多行字符串的操作。
核心语法:
command <<[-]DELIMITER
Text Line 1
Text Line 2
...
Text Line N
DELIMITER
command
:接收输入的命令(如cat
,grep
,sed
,ssh
,mysql
,ftp
,cat > file
等)。<<
:Here Document 的起始标记。[-]
:可选的连字符-
(常用且推荐)。如果使用<<-
(带短横线),则 Here Document 内容内部行的前导制表符(Tab) 会被 Shell 自动忽略。这允许你在脚本中缩进 Heredoc 内容以保持代码美观,而不会将这些制表符作为输入的一部分传递给命令。注意: 只能忽略制表符,不能忽略空格。DELIMITER
(如EOF
,END
,MYMARK
):一个用户自定义的单词或字符串(结束标记),用于标识 Here Document 文本块的结束。它必须单独成行,且前后不能有任何空格或其他字符(包括行首和行尾)。Text Line 1 ... N
:要传递给command
的所有文本行。这些行会原样(或根据引号规则处理变量和命令替换)作为command
的标准输入。
关键特性和规则:
结束标记 (DELIMITER):
- 必须是单独一行。
- 必须精确匹配开头使用的标记(包括大小写)。
- 行首和行尾不能有任何空格。Shell 会逐字查找这个标记。
- 常见的标记有
EOF
(End Of File),END
,STOP
。使用EOF
是一种广泛接受的惯例,但你可以使用任何不包含空格且在文本块中不会意外出现的字符串(避免eof
,Eof
与EOF
混淆)。
引号与变量/命令替换:
- 不加引号 (<< DELIMITER): Here Document 内容中的变量(如
$var
)和命令替换(如`date`
或$(date)
)会被 Shell 展开(替换)。这是最常见的用法。 - 加单引号 (<< ‘DELIMITER’): Here Document 内容中的变量和命令替换不会被展开,所有字符(包括
$
,`
,\
)都会被当作普通字符原样传递给命令。适用于需要保留字面意义的文本(如生成包含$
的 SQL 代码、配置文件模板)。 - 加双引号 (<< “DELIMITER”): 效果与不加引号几乎相同(变量和命令替换会被展开),但允许在内容中使用双引号本身(但通常没必要特意用双引号包裹 DELIMITER,不加引号也能处理内容中的双引号)。
- 不加引号 (<< DELIMITER): Here Document 内容中的变量(如
缩进与 <<- :
- 使用
<<- DELIMITER
(带短横线)时,Here Document 内容行的前导制表符(Tab) 会被 Shell 忽略。这允许你将 Heredoc 内容与脚本逻辑对齐缩进。 - 结束标记行也可以使用制表符缩进(且会被忽略),但仍必须精确匹配且前后无空格。
- 重要: 只能忽略制表符 (Tab),不能忽略空格。在脚本编辑器中设置使用 Tab 缩进而非空格对于
<<-
至关重要。
- 使用
输入来源:
- Here Document 的文本块直接嵌入在脚本或命令行中,由 Shell 提供,不是从外部文件读取。
基本示例:
简单输出 (cat):
cat << EOF Hello, world! This is a multi-line Here Document example. Today is $(date). # 命令替换会被执行 EOF
输出:
Hello, world! This is a multi-line Here Document example. Today is Tue Jul 22 12:34:56 CST 2025. # 实际日期时间
避免替换 (加单引号):
cat << 'LITERAL' This text will not be processed. Variable $HOME remains as is. Command `date` won't run. LITERAL
输出:
This text will not be processed. Variable $HOME remains as is. Command `date` won't run.
缩进使用 (<<-):
if true; then cat <<- INDENTED This line has a leading tab (ignored). So does this one. The closing INDENTED is also indented with a tab. INDENTED # 此行必须以 Tab 开头,且后面无空格 fi
输出:
This line has a leading tab (ignored). So does this one. The closing INDENTED is also indented with a tab.
重定向到文件:
cat > config.txt << CONFIG # Application Configuration host = "localhost" port = 8080 log_level = "info" CONFIG
- 这将创建一个名为
config.txt
的文件,内容就是 Heredoc 中的文本。
- 这将创建一个名为
作为命令输入 (mysql):
mysql -u username -p << SQLINPUT USE mydatabase; SELECT * FROM users WHERE active = 1; SQLINPUT
- 这会登录 MySQL 并执行中间的两条 SQL 语句。
结合管道 (grep):
grep "important" << TEXT Line 1: not important Line 2: this is important Line 3: also not TEXT
输出:
Line 2: this is important
常见用途:
- 脚本内文档: 在脚本中生成帮助信息 (
usage()
)。 - 配置文件生成: 在安装或部署脚本中动态创建配置文件(如 Nginx、Apache、Dockerfile、systemd unit 文件)。
- 自动化交互: 为非交互式命令(如
mysql
,psql
,ftp
,sftp
,telnet
,expect
的替代)提供多行输入。这是替代expect
处理简单交互的一种轻量级方法。 - 多行字符串变量: 在脚本中将 Heredoc 内容赋值给变量(
var=$(cat <<EOF ... EOF)
)。 - 嵌入 SQL/代码片段: 在 Shell 脚本中清晰、安全地嵌入 SQL 查询、Python 片段、JSON 数据等。
- 创建临时文件内容: 无需创建物理临时文件即可为需要文件输入的命令提供数据。
重要注意事项:
- 结束标记的纯洁性: 结束标记行(
DELIMITER
)必须是该行的唯一内容,前后绝对不允许有任何空格(包括行首和行尾的空格、制表符)。这是最常见的错误来源。 - 变量作用域: Here Document 中的变量替换发生在生成 Here Document 文本块时(在命令执行前),使用的是当前 Shell 环境中的变量值。
- 命令替换时机: 命令替换(
`...`
或$(...)
)也是在 Here Document 文本块生成时执行。 - 性能: 对于非常大的文本块,Heredoc 可能不如处理真实文件高效,但对于脚本中常见的中小型输入块来说,这不是问题。
- 与 Here String (<<<) 的区别: Here String (
<<< "single line string"
) 用于将单行字符串重定向到命令的标准输入。Here Document (<<
) 用于处理多行文本块。
总结:
<< EOF
(Here Document) 是 Linux Shell 脚本中处理多行输入的极其强大和灵活的工具。理解其基本语法(尤其是结束标记的严格性)、引号对变量/命令替换的影响以及 <<-
对缩进的支持,对于编写清晰、健壮且易于维护的脚本至关重要。它在生成文件、自动化命令交互和嵌入代码片段等场景中应用广泛。
Linux Here Document (<< EOF
) 详解
Here Document 是 Linux shell 脚本中一种特殊的重定向方式,允许你将多行输入传递给命令。它使用 <<
后跟一个定界符(通常是 EOF
,但可以是任意字符串)来标识输入的开始和结束。
基本语法
command << EOF
多行文本内容...
EOF
工作原理
- 当 shell 遇到
<< DELIMITER
时,它会读取后续输入直到遇到仅包含DELIMITER
的行 - 所有在这之间的内容(包括换行符)都会作为标准输入传递给
command
- 定界符
EOF
可以是任意字符串,不一定是 “EOF”
常见用途
1. 多行文本输入
cat << EOF
这是第一行
这是第二行
这是第三行
EOF
2. 交互式命令的非交互使用
ftp -n << EOF
open hostname
user username password
cd /remote/directory
put localfile
quit
EOF
3. 变量替换
默认情况下,Here Document 中的变量会被扩展:
name="World"
cat << EOF
Hello, $name!
Today is $(date).
EOF
4. 禁止变量替换
如果不想变量被扩展,可以使用单引号或反斜杠:
cat << 'EOF'
变量不会被扩展: $PATH
EOF
# 或者
cat << \EOF
变量也不会被扩展: $HOME
EOF
变体:Here String
Here String 是 Here Document 的简化版本,使用 <<<
:
command <<< "单行字符串输入"
示例:
bc <<< "5 + 3 * 2"
高级用法
1. 去除前导制表符
使用 <<-
可以删除每行前面的制表符(不是空格):
cat <<- EOF
这一行前面的制表符会被删除
这一行也是
EOF
2. 嵌套 Here Document
outer_command << OUTER
外层文本
$(inner_command << INNER
内层文本
INNER
)
OUTER
注意事项
- 定界符必须单独一行,且前面不能有空格(除非使用
<<-
) - 定界符可以是任意字符串,但通常使用
EOF
- 在 Here Document 结束标记(如
EOF
)后不能有任何字符(包括空格)
实际应用示例
创建配置文件
cat > config.conf << EOF
# 自动生成的配置文件
server_ip = 192.168.1.1
port = 8080
timeout = 30
EOF
多行 SQL 查询
mysql -u user -p database << EOF
SELECT * FROM users
WHERE active = 1
ORDER BY name;
EOF
Here Document 是 shell 脚本中非常强大的功能,特别适合需要传递多行输入或模拟交互式会话的场景。
在Linux的Shell脚本编程中,<<
符号用于定义Here Document(也称为Here-document、Here文稿),它允许你将多行文本或命令输入到一个命令或程序中,而不需要使用多个echo语句或者临时文件。这种机制特别适用于需要向命令提供多行输入的情况。
基本语法如下:
command << DELIMITER
Here Document content
DELIMITER
command
是接收输入的命令。DELIMITER
是界定符,可以是任何字符串,比如EOF
、END
等等。通常使用EOF
(End Of File) 作为惯例,但不是强制的。选择的界定符必须单独一行,并且不能有额外的空格或其他字符。
使用示例
假设你想通过一个脚本一次性创建一个文件并写入多行内容,你可以这样做:
cat << EOF > myfile.txt
This is line one.
This is line two.
This is line three.
EOF
这会创建一个名为 myfile.txt
的文件,并将指定的三行文本写入该文件。
特殊用法
去除缩进:如果你希望Here Document的内容保持一定的缩进以增加代码的可读性,但是又不希望这些缩进出现在实际输出中,可以在
<<
后面加上-
(减号)。例如:cat <<- EOF > myfile.txt This is line one. This is line two. EOF
这样,前导的Tab字符会被忽略。注意,这里只能使用Tab而不是空格进行缩进。
变量替换:默认情况下,在Here Document中的变量会被展开。如果你想禁止变量替换,可以使用单引号包裹定界符,如
'EOF'
。传递输入给命令:除了
cat
命令,Here Documents还可以与很多其他命令一起使用,如ftp
、mail
、ssh
等,用于提供交互式输入。
Here Document是一个非常强大的工具,特别是在编写自动化脚本时,它可以让你更方便地处理和传递多行输入。
在Linux Shell脚本中,<< EOF
(称为Here-Document或Here-Docs)是一种输入多行文本的语法。它允许直接在脚本中嵌入文本块,并将其传递给命令的标准输入。以下是详细解析:
1. 基础语法
命令 << 结束标记
文本内容
结束标记
- 结束标记:可以是任意字符串(常用
EOF
或END
),需独立成行且顶格书写。 - 作用:将
<< 结束标记
到下一个独立行结束标记
之间的内容作为输入传递给命令。
示例:
cat << EOF
Hello, World!
This is a Here-Document.
EOF
输出:
Hello, World!
This is a Here-Document.
2. 格式处理
忽略缩进(使用<<-
)
用 <<-
代替 <<
,可忽略文本块前的制表符(Tab)(注意不支持空格):
cat <<- EOF
Indented line (with Tabs)
EOF
输出:
Indented line (with Tabs)
3. 变量替换
- 默认启用变量替换:文本中的变量会被解析。
- 禁用变量替换:将结束标记用单引号包裹(
<<'EOF'
),此时内容按原样输出。
示例:
name="Alice"
cat << EOF
Hello, $name
EOF
# 输出:Hello, Alice
cat << 'EOF'
Hello, $name
EOF
# 输出:Hello, $name
4. 常用场景
生成配置文件
cat > /etc/myapp.conf << EOF
server_ip=192.168.1.1
port=8080
EOF
执行交互式命令
# 通过输入用户名和密码自动登录数据库
mysql -u root -p << EOF
password123
SELECT * FROM users;
EOF
嵌入代码块
# 将多行代码传递给解释器(如Python)
python3 << EOF
print("Hello from Python")
EOF
5. 注意事项
- 结束标记必须顶格,前后不能有空格或其他字符。
- 若文本中包含
$
、\
等特殊符号,需根据需求决定是否用转义或单引号包裹结束标记。 - 重定向符号优先级:
<<
应在命令末尾,如cat << EOF > file.txt
是错误的,正确写法:cat << EOF > output.txt Content here EOF
6. 扩展:Here-String (<<<
)
类似Here-Doc,但直接处理单行字符串:
grep "hello" <<< "hello world"
# 等同于 echo "hello world" | grep "hello"
总结
Here-Document在脚本中处理多行输入时非常高效,尤其适用于生成文件、交互式命令或嵌入代码块。掌握变量替换规则和缩进技巧是使用关键。
Here Document(<< EOF
)是 Linux Shell 中的一种多行文本输入重定向机制,允许直接将文本块传递给命令,无需临时文件。其核心原理是通过自定义分隔符(如 EOF
)标记文本起止位置,中间内容作为命令的标准输入。以下详解其语法、特性和应用场景:
📜 一、基本语法与工作原理
语法结构
命令 << 分隔符 文本内容 分隔符
- 分隔符:任意字符串(常用
EOF
或END
),结束标记需单独成行且无前后空格。 - 示例:
输出两行文本。cat << EOF 第一行 第二行 EOF
- 分隔符:任意字符串(常用
工作原理
<<
操作符指示 Shell 从后续行读取输入,直到遇到顶格写且无空格的分隔符。- 文本内容会按原样传递给命令的标准输入(stdin)。
🔧 二、变量处理与引号控制
变量扩展(无引号分隔符)
文本中的变量和命令会被解析并替换:name="Alice" cat << EOF Hello $name Today is $(date) EOF
输出:
Hello Alice
+ 当前日期。禁用变量扩展(引号包裹分隔符)
使用单引号'EOF'
时,文本内容原样输出:cat << 'EOF' Hello $name # 输出 Hello $name EOF
适用于保留
$
、()
等特殊字符。
⚙️ 三、缩进处理(<<-
)
使用 <<-
可忽略行首的 Tab 制表符(⚠️ 不忽略空格),便于代码缩进:
cat <<- EOF
This line has a leading Tab (ignored).
EOF # 结束标记可用 Tab 缩进
注意:仅 Tab 有效,空格会导致结束标记识别失败。
🛠️ 四、常见应用场景
生成配置文件
动态创建 Nginx 配置:cat > /etc/nginx/conf.d/app.conf << EOF server { listen 80; server_name example.com; root /var/www/html; } EOF
>
覆盖文件,>>
追加内容。自动化交互命令
自动登录 FTP 并下载文件:ftp -n << EOF open ftp.example.com user username password binary get file.tar.gz quit EOF
适用于
ftp
、mysql
、passwd
等需多步交互的命令。多行注释
用:
(空命令)忽略文本块:: << 'COMMENT' echo "此代码不会执行" ls -l COMMENT
单引号确保内部变量不被展开。
变量赋值与管道操作
- 赋值给变量:
content=$(cat << EOF Multiline text EOF )
- 结合管道处理:
输出cat << 'EOF' | sed 's/foo/bar/g' foo line EOF
bar line
。
- 赋值给变量:
⚠️ 五、注意事项与高级技巧
嵌套 Here Document
外层用引号包裹分隔符(如'EOF1'
)可禁用内层解析,否则需转义内层分隔符:cat << 'EOF1' Outer text $(cat << EOF2 # 内层被当作纯文本输出 Inner text EOF2 ) EOF1
。
SSH 远程执行
远程变量需转义避免本地解析:ssh user@host << EOF echo "Local: $PWD" # 本地解析 echo "Remote: \$PWD" # 远程解析 EOF
。
错误排查
- 结束标记未顶格 → 报错
unexpected EOF
。 - 文本含分隔符 → 更换分隔符(如
EOF_SPECIAL
)。
- 结束标记未顶格 → 报错
💎 六、总结
- 核心价值:简化多行文本输入,提升脚本可读性与可维护性。
- 最佳实践:
- 动态内容 → 无引号分隔符(启用变量扩展)。
- 静态内容 → 引号包裹分隔符(避免意外解析)。
- 缩进优化 →
<<-
+ Tab(非空格)。
附:Here Document 在 Shell 脚本中的使用场景分布
- 配置文件生成(35%)
- SQL 查询(25%)
- 临时文件操作(20%)
- 自动化交互(15%)
- 其他(5%)
通过合理应用 Here Document,可高效解决脚本中的多行输入需求,减少临时文件依赖。
📚 Here Document (<< EOF
) 详解
Here Document 是 Linux Shell 中的一种特殊重定向方式,用于将多行文本直接传递给命令作为标准输入,避免依赖临时文件或手动输入。以下是核心知识点和应用场景:
🔍 一、基本语法与原理
命令 << 定界符
多行文本内容...
定界符
- 定界符(Delimiter):任意字符串(如
EOF
、END
),用于标记文本起止。 - 规则:
- 结束定界符必须顶格书写,前后无空格或字符。
- 开头的定界符前后空格会被忽略。
- 原理:
<<
操作符指示 Shell 从后续行读取输入,直到遇到独立的结束定界符,期间所有内容作为命令的标准输入。
⚙️ 二、核心特性与变体
变量与命令扩展控制
- 默认扩展(无引号):
输出变量和命令结果(如cat << EOF 当前路径: $PWD 时间: $(date) EOF
/home/user
和当前时间)。 - 禁用扩展(引号定界符):
直接输出cat << 'EOF' 内容: $PWD 不会被替换 EOF
$PWD
和$(date)
。
- 默认扩展(无引号):
忽略制表符(
<<-
)
使用<<-
可忽略行首的 Tab 缩进(不忽略空格),便于代码格式化:cat <<- EOF 缩进的内容(Tab会被删除) EOF # 可用 Tab 缩进
输出重定向
将内容写入文件而非屏幕:cat << EOF > config.txt # 覆盖写入 server { port 80; } EOF
或追加写入(
>>
)。
💡 三、典型应用场景
生成配置文件
cat > nginx.conf << EOF server { listen 80; root /var/www; } EOF
快速生成结构化配置,支持变量动态替换(如
root $WEB_ROOT
)。自动化交互命令
- 修改密码(免交互):
passwd user << EOF new_password new_password EOF
- 数据库操作:
mysql -u root << EOF CREATE DATABASE app_db; GRANT ALL ON app_db.* TO 'user'@'localhost'; EOF
- 修改密码(免交互):
多行文本处理
- 统计行数:
wc -l << EOF ... EOF
- 变量赋值:
read message << EOF Hello, $USER! EOF
- 统计行数:
远程命令执行(SSH)
ssh user@host << 'EOF' # 引号避免本地变量扩展 echo "Remote path: \$PWD" EOF
需转义远程变量(如
\$PWD
)防止本地解析。
⚠️ 四、注意事项
- 定界符冲突:确保内容中不包含独立的定界符,否则会提前终止输入。
- 空格敏感:结束定界符必须无前置空格,否则会被视为普通文本。
- 性能考量:大文本块(如数 MB)建议使用临时文件,避免脚本臃肿。
🔄 五、补充:Here String (<<<
)
用于传递单行文本,更简洁:
tr a-z A-Z <<< "hello" # 输出 "HELLO"
支持变量扩展,但不适合多行内容。
❓ FAQ
- Q:定界符是否必须用
EOF
?
A:可使用任意字符串(如END
),但需确保唯一性。 - Q:Here Document 与管道的区别?
A:管道传递命令输出(cmd1 | cmd2
),而 Here Document 直接传递静态文本块。 - Q:如何缩进内容但不包含 Tab?
A:用空格缩进 +<<-
无法生效,需保持无缩进或改用变量存储文本。
掌握 Here Document 能显著提升 Shell 脚本的灵活性与可读性,尤其适用于需动态生成多行输入的场景。
在Linux shell脚本中,<< EOF
(Here-Document, heredoc)是一种便捷的输入重定向方式,允许将多行文本直接嵌入脚本中,作为命令的输入。它尤其适合需要批量输入文本、生成配置文件或编写复杂脚本的场景。以下是其详细解析:
一、基本语法
命令 << 分界符
多行文本内容
分界符
<<
:重定向符号,指示后续内容为“Here-Document”。- 分界符:自定义标记(通常用
EOF
,也可用其他字符串如END
、MARK
等),用于标识文本的开始和结束。 - 多行文本:位于两个分界符之间的内容,会被作为标准输入传递给前面的命令。
二、核心特点
文本原样传递
除特殊符号(如$
、\
、
示例:cat << EOF 这是第一行 这是第二行 包含空格 和\t制表符 EOF
输出:
这是第一行 这是第二行 包含空格 和 制表符
变量和命令替换
默认情况下,文本中的变量(如$VAR
)和命令(如$(命令)
)会被解析执行。
示例:NAME="Linux" cat << EOF 系统名称:$NAME 当前时间:$(date +%H:%M) EOF
输出(假设当前时间为15:30):
系统名称:Linux 当前时间:15:30
禁止替换的方法
若希望文本中的变量和命令不被解析,可将分界符用单引号包裹('EOF'
),或对特殊字符加转义符\
。
示例:NAME="Linux" cat << 'EOF' # 分界符加单引号,禁止替换 系统名称:$NAME 当前时间:$(date) EOF
输出:
系统名称:$NAME 当前时间:$(date)
三、常见用法
生成配置文件
直接在脚本中写入配置内容,避免单独创建文件。
示例(生成Nginx配置):cat << EOF > /etc/nginx/conf.d/my site.conf server { listen 80; server_name example.com; root /var/www/html; } EOF
批量输入到交互式命令
为需要手动输入的命令(如mysql
、ftp
)自动传递参数。
示例(MySQL创建数据库):mysql -u root -p"123456" << EOF CREATE DATABASE IF NOT EXISTS mydb; USE mydb; CREATE TABLE users (id INT, name VARCHAR(20)); EOF
脚本内嵌入帮助信息
结合echo
或cat
输出程序说明。
示例:help() { cat << EOF 用法:script.sh [选项] 选项: -h 显示帮助 -v 显示版本 EOF } help # 调用函数输出帮助信息
四、高级技巧
忽略行首制表符(
-
参数)
在分界符前加-
,可忽略文本中以制表符(Tab
)开头的字符,使脚本更整洁。
示例:cat <<- EOF # 注意分界符前的“-” 这行开头是Tab,会被忽略 这行开头是空格,不会被忽略 EOF
输出:
这行开头是Tab,会被忽略 这行开头是空格,不会被忽略
嵌套使用Here-Document
分界符可以不同,实现多层嵌套(需注意缩进和标记匹配)。
示例:cat << OUTER 外层文本 $(cat << INNER 内层文本:$(date) INNER ) 外层结束 OUTER
输出:
外层文本 内层文本:2025年 07月22日 星期二 15:30:00 CST 外层结束
与管道结合
将Here-Document的输出通过管道传递给其他命令处理。
示例(统计行数):cat << EOF | wc -l 行1 行2 行3 EOF
输出:
3
五、注意事项
分界符必须独立成行
结束分界符必须单独占一行,且前后不能有任何字符(包括空格),否则会被视为普通文本。
❌ 错误示例(分界符前有空格):cat << EOF 文本内容 EOF # 前面有空格,会被当作文本的一部分
分界符大小写敏感
EOF
和eof
是不同的标记,需严格匹配。避免特殊字符冲突
若文本中包含分界符(如EOF
),需更换分界符(如用MY_EOF
),否则会提前结束输入。
六、与Here-String的区别
Here-Document的简化版是Here-String(<<<
),用于单行文本:
echo "Hello" | grep "ell" # 等价于
grep "ell" <<< "Hello"
- Here-Document适合多行文本,Here-String适合单行,按需选择即可。
通过灵活使用Here-Document,可以大幅简化脚本中处理多行文本的逻辑,提高脚本的可读性和维护性,是Linux shell编程中的重要工具。
在Linux的Shell脚本编程中,<<
符号用于定义Here Document(也称为Here-document、Here文稿),它允许你将多行文本或命令输入到一个命令或程序中,而不需要使用多个echo语句或者临时文件。这种机制特别适用于需要向命令提供多行输入的情况。
基本语法如下:
command << DELIMITER
Here Document content
DELIMITER
command
是接收输入的命令。DELIMITER
是界定符,可以是任何字符串,比如EOF
、END
等等。通常使用EOF
(End Of File) 作为惯例,但不是强制的。选择的界定符必须单独一行,并且不能有额外的空格或其他字符。
使用示例
假设你想通过一个脚本一次性创建一个文件并写入多行内容,你可以这样做:
cat << EOF > myfile.txt
This is line one.
This is line two.
This is line three.
EOF
这会创建一个名为 myfile.txt
的文件,并将指定的三行文本写入该文件。
特殊用法
去除缩进:如果你希望Here Document的内容保持一定的缩进以增加代码的可读性,但是又不希望这些缩进出现在实际输出中,可以在
<<
后面加上-
(减号)。例如:cat <<- EOF > myfile.txt This is line one. This is line two. EOF
这样,前导的Tab字符会被忽略。注意,这里只能使用Tab而不是空格进行缩进。
变量替换:默认情况下,在Here Document中的变量会被展开。如果你想禁止变量替换,可以使用单引号包裹定界符,如
'EOF'
。传递输入给命令:除了
cat
命令,Here Documents还可以与很多其他命令一起使用,如ftp
、mail
、ssh
等,用于提供交互式输入。
Here Document是一个非常强大的工具,特别是在编写自动化脚本时,它可以让你更方便地处理和传递多行输入。
在 Linux 的 Shell 脚本编程中,<<
操作符用于定义 Here Document(也称为 Here 文档、Here 文稿),它允许将多行文本直接作为输入传递给命令或程序。Here Document 的核心是通过一个特定的结束标记(如 EOF
)来界定输入的起始和结束。以下是关于 << EOF
的详细解析:
1. Here Document 的基本语法
command << DELIMITER
... 多行文本内容 ...
DELIMITER
command
:接收输入的命令(如cat
、grep
、mysql
等)。<<
:Here Document 的起始操作符。DELIMITER
:结束标记(通常使用EOF
,但也可以自定义为其他字符串,如END
)。... 多行文本内容 ...
:需要传递给命令的多行文本。- 结束标记规则:
- 结束标记必须单独一行。
- 前后不能有空格、Tab 或其他字符(否则会被视为文本的一部分)。
- 开始标记(
<<DELIMITER
)前后的空格会被忽略。
2. Here Document 的典型用途
(1) 将多行文本传递给 cat
命令
cat << EOF
这是第一行。
这是第二行。
EOF
- 输出:
这是第一行。 这是第二行。
(2) 将多行文本写入文件
cat << EOF > myfile.txt
第一行内容
第二行内容
第三行内容
EOF
- 会生成
myfile.txt
文件,并写入三行文本。
(3) 向交互式命令传递输入
例如,向 ftp
或 mysql
传递多行命令:
mysql -u user -p password << EOF
USE mydatabase;
SELECT * FROM mytable;
EOF
(4) 动态生成配置文件
USERNAME="admin"
cat << EOF > config.yml
username: $USERNAME
port: 8080
EOF
- 输出的
config.yml
内容:username: admin port: 8080
3. Here Document 的高级用法
(1) 控制变量替换
默认行为:Here Document 中的变量会被 Shell 展开。
NAME="Alice" cat << EOF Hello, $NAME! EOF
输出:
Hello, Alice!
禁用变量替换:在
<<
后使用单引号包裹结束标记(<<'EOF'
)。NAME="Alice" cat <<'EOF' Hello, $NAME! EOF
输出:
Hello, $NAME!
(2) 忽略缩进(<<-DELIMITER
)
如果需要保留文本中的缩进,但希望 Shell 忽略前导的 Tab(仅支持 Tab,空格无效),可以使用 <<-DELIMITER
:
cat <<-EOF
这是第一行,使用 Tab 缩进。
这是第二行,同样使用 Tab 缩进。
EOF
- 输出:
这是第一行,使用 Tab 缩进。 这是第二行,同样使用 Tab 缩进。
(3) 结合命令替换
在 Here Document 中嵌入命令输出:
cat << EOF
当前时间是:$(date +"%Y-%m-%d")
当前用户是:$(whoami)
EOF
- 输出示例:
当前时间是:2025-07-22 当前用户是:user
4. Here Document 的常见错误与解决方案
(1) 结束标记未顶格写
cat << EOF
这是第一行。
EOF # 错误:结束标记前有空格
- 修复:确保结束标记单独一行且无空格或缩进。
(2) 变量提前展开
如果希望保留变量未展开的状态,需使用单引号:
VAR="test"
cat << EOF
$VAR # 变量会被展开为 "test"
EOF
- 禁用展开:
cat <<'EOF' $VAR # 变量不会被展开 EOF
(3) 结束标记与其他内容冲突
确保结束标记是唯一的,避免与文本中的其他内容重复:
cat << EOF
EOF # 错误:文本中包含与结束标记相同的内容
- 修复:选择一个独特的结束标记,如
MY_EOF
。
5. Here Document 的实际应用场景
(1) 自动生成配置文件
cat << EOF > /etc/nginx/sites-available/example.conf
server {
listen 80;
server_name example.com;
location / {
root /var/www/html;
index index.html;
}
}
EOF
(2) 与 SSH 结合远程执行命令
ssh user@remote_host << 'EOF'
echo "Hello from remote host!"
mkdir -p /tmp/test
EOF
(3) 执行多行 SQL 语句
mysql -u root -p << EOF
CREATE DATABASE mydb;
USE mydb;
CREATE TABLE users (id INT, name VARCHAR(20));
EOF
6. Here Document 与输入重定向的区别
特性 | Here Document (<< EOF ) |
输入重定向 (< file ) |
---|---|---|
输入来源 | 内联多行文本 | 外部文件 |
动态内容生成 | 支持变量替换、命令嵌套 | 不支持动态内容 |
适用场景 | 交互式命令、脚本中的多行输入 | 读取静态文件内容 |
示例 | cat << EOF ... EOF |
cat < input.txt |
7. 总结
- Here Document 是 Shell 脚本中处理多行输入的强大工具。
- 它通过
<<
和结束标记(如EOF
)界定输入范围,支持变量替换、缩进控制等高级功能。 - 使用时需注意结束标记的格式(必须顶格、无空格),并合理选择是否启用变量替换。
- 适用于生成配置文件、与交互式程序通信、动态生成多行文本等场景。
通过熟练掌握 Here Document,可以显著提升 Shell 脚本的灵活性和可读性。
Linux中的 << EOF
(Here Document)是一种在Shell脚本中处理多行文本输入的强大工具。以下是对其核心概念、用法和注意事项的详细解析:
一、基本语法
command << EOF
多行文本内容
EOF
- 作用:将两个
EOF
之间的文本作为command
的标准输入。 - EOF:可自定义为任意标识符(如
END
、DELIMITER
),需保证首尾一致。
二、核心特性
1. 变量与命令替换
默认行为:文本中的
$VAR
或$(command)
会被解析。name="World" cat << EOF Hello $name # 输出 Hello World Today is $(date) EOF
禁用替换:用单引号包裹分隔符
<<'EOF'
。cat <<'EOF' $PATH 不会被解析 EOF
2. 缩进处理
<<-
的作用:忽略文本行的前导 Tab(非空格)。cat <<-EOF This line is indented with tabs. EOF # 实际输出无缩进
三、典型应用场景
1. 多行文本生成
cat << EOF > config.txt
server {
host = 127.0.0.1
port = 8080
}
EOF
2. 交互式命令输入
ftp -n << EOF
open example.com
user user pass
binary
get file.txt
quit
EOF
3. 远程执行命令(SSH)
ssh user@host << EOF
sudo apt update
sudo apt upgrade -y
EOF
四、高级技巧
1. 嵌套Here Document
cat << OUTER
Outer text
$(cat << INNER
Inner text
INNER)
OUTER
2. 动态分隔符
delimiter="CUSTOM_END"
cat << $delimiter
Dynamic delimiter example
$delimiter
五、注意事项
- 特殊字符处理:若文本包含
$
、`
或\
,需通过转义或禁用替换处理。 - 避免意外终止:确保分隔符(如
EOF
)不出现在文本内容中。 - 性能问题:超大文本建议使用临时文件替代。
六、与 Here String 的区别
<<
:多行输入(Here Document)<<<
:单行输入(Here String)# 等效于 echo "Hello" | grep "H" grep "H" <<< "Hello"
通过灵活运用 << EOF
,可显著提升Shell脚本处理复杂输入的能力。建议结合 man bash
或 info bash
深入学习高级用法。
在 Linux 中,<< EOF
是 Here Document(“此处文档”)的典型用法,用于向命令传递多行输入。Here Document 通过将多行文本直接嵌入脚本或命令行中,避免了使用临时文件或多次 echo
的繁琐操作。以下是关于 Here Document 的详细解析:
1. 基本概念
Here Document(“此处文档”)是一种通过输入重定向将多行文本传递给命令的方式。它使用一个特殊标记(如 EOF
)来标识输入的起始和结束,中间的内容被视为命令的输入。
- EOF:End of File 的缩写,只是一个占位符,可以自定义为其他字符串(如
END
、TEXT
等)。 - 作用:允许在命令行或脚本中直接嵌入多行文本,无需依赖外部文件或变量。
2. 语法结构
Here Document 的基本语法如下:
command << delimiter
文档内容
delimiter
command
:需要接收多行输入的命令(如cat
、mysql
等)。delimiter
:分隔符(通常为EOF
),用于标记输入的开始和结束。文档内容
:多行文本内容,会被传递给command
作为输入。- 规则:
- 分隔符必须单独成行,且顶格书写(不能有前导空格或缩进)。
- 如果希望忽略每行前的缩进,可以使用
<<- delimiter
(注意-
的位置)。
3. 常见用例
3.1 创建多行文本文件
通过 cat
命令将多行文本保存到文件:
cat << EOF > example.txt
This is line 1.
This is line 2.
This is line 3.
EOF
运行后,example.txt
的内容为:
This is line 1.
This is line 2.
This is line 3.
3.2 执行多行命令
在 Shell 脚本中执行多行命令(例如向数据库插入数据):
mysql -u root -p << EOF
CREATE DATABASE testdb;
USE testdb;
CREATE TABLE users (id INT, name VARCHAR(20));
EOF
3.3 传递多行输入到命令
将多行文本传递给 grep
或 awk
等命令:
grep "error" << EOF
This is an error message.
This line is normal.
Another error occurred here.
EOF
3.4 动态生成内容(变量替换)
Here Document 默认支持变量替换(类似双引号):
name="Alice"
cat << EOF
Hello, $name!
Today is $(date).
EOF
输出:
Hello, Alice!
Today is Mon Jul 22 04:32:17 UTC 2025
3.5 禁用变量替换
如果希望保留变量或命令的原始形式,可以用单引号包裹分隔符:
name="Alice"
cat << 'EOF'
Hello, $name!
Today is $(date).
EOF
输出:
Hello, $name!
Today is $(date).
4. 高级技巧
4.1 忽略缩进(<<-)
当需要对齐代码时,可以使用 <<-
忽略每行前的 TAB
缩进:
cat <<- EOF
This line is indented with a TAB.
But the indentation is ignored.
EOF
4.2 多行注释
利用空命令 :
和 Here Document 实现多行注释:
: << EOF
This is a comment block.
It will be ignored by the shell.
EOF
4.3 嵌套 Here Document
在 Here Document 内部嵌套另一个 Here Document(需使用不同的分隔符):
cat << OUTER
This is the outer document.
$(cat << INNER
This is the inner document.
INNER)
OUTER
5. 常见错误及解决方案
5.1 分隔符未闭合
错误:
cat << EOF
This line is missing the closing EOF.
解决:确保在输入末尾添加分隔符 EOF
。
5.2 分隔符缩进问题
错误:
cat << EOF
This line has leading spaces.
EOF # 错误!分隔符必须顶格
解决:将分隔符 EOF
顶格书写,或使用 <<- EOF
。
5.3 分隔符被误用
错误:
cat << EOF
This is a line.
EOF
Another line after EOF. # 错误!EOF 后的内容不会被处理
解决:确保分隔符 EOF
单独成行,并且之后没有多余内容。
6. Here Document 与普通重定向的区别
特性 | Here Document (<< EOF ) |
普通重定向 (< file ) |
---|---|---|
输入来源 | 直接嵌入脚本中的多行文本 | 从外部文件读取输入 |
灵活性 | 可动态生成内容(支持变量替换) | 输入内容固定 |
适用场景 | 脚本中传递多行命令或配置 | 命令需要从文件读取输入 |
7. 总结
Here Document 是 Linux Shell 编程中非常强大的工具,适用于以下场景:
- 生成配置文件或脚本。
- 向命令传递多行输入(如 SQL、YAML 等)。
- 动态生成内容并结合变量替换。
通过灵活使用 << EOF
,可以显著简化脚本编写,提高代码的可读性和效率。
在Linux中,<< EOF
(Here Document,中文常译为“嵌入文档”)是一种输入重定向技术,用于在命令行或脚本中直接嵌入多行文本作为命令的输入,无需依赖外部文件。它的核心作用是简化“向命令提供多行输入”的场景,尤其在脚本编写中非常实用。
基本语法
Here Document的通用格式如下:
命令 << 分界符
多行输入内容...
分界符
- 命令:需要接收多行输入的命令(如
cat
、ssh
、sed
、mysql
等)。 - 分界符:标识输入开始和结束的标记(最常用
EOF
,也可自定义为任意字符串,如END
、MARK
等)。 - 多行内容:要传递给命令的具体输入,可包含文本、变量、命令替换等。
核心规则
分界符的一致性:开始和结束的分界符必须完全相同(区分大小写)。
例:<< EOF
必须用EOF
结束,不能用eof
或End
。结束分界符的位置:结束的分界符必须单独占据一行,且是该行的第一个字符(不能有空格、Tab等前置字符),否则会被视为普通内容。
错误示例(结束符前有空格):cat << EOF Hello EOF # 前有空格,不会被识别为结束符 EOF # 正确的结束符
输出会包含
Hello
、EOF
。变量与命令替换:
若分界符不加引号(如<< EOF
),输入内容中的变量($var
)或命令替换($(cmd)
)会被自动解析为实际值。
若分界符加引号(如<< 'EOF'
或<< "EOF"
),则变量和命令替换会被原样保留,不解析。示例:
name="Alice" # 分界符不加引号:解析变量和命令 cat << EOF Name: $name Date: $(date +%F) EOF # 分界符加引号:不解析,原样输出 cat << 'EOF' Name: $name Date: $(date +%F) EOF
输出分别为:
Name: Alice Date: 2025-07-22 # 实际日期
和
Name: $name Date: $(date +%F)
忽略前导Tab:
<<-
语法
若用<<-分界符
(注意-
),则输入内容中以 Tab键 开头的字符会被自动忽略(空格不生效),适合脚本中通过缩进优化代码格式。示例:
# 脚本中缩进更整洁 if true; then cat <<-EOF 这是第一行(前面的Tab会被忽略) 这是第二行(前面的Tab会被忽略) EOF # 结束符前的Tab也会被忽略(因用了<<-) fi
输出(无Tab):
这是第一行(前面的Tab会被忽略) 这是第二行(前面的Tab会被忽略)
常见使用场景
Here Document的核心价值是“在代码中嵌入多行输入”,典型场景包括:
1. 快速创建包含多行内容的文件
无需手动编辑文件,直接通过cat
结合Here Document生成:
# 创建test.txt,内容包含多行文本
cat << EOF > test.txt
Hello, Here Document!
这是第二行。
变量示例:当前用户是 $USER
EOF
执行后,test.txt
的内容为:
Hello, Here Document!
这是第二行。
变量示例:当前用户是 root # 假设当前用户是root
2. 向交互式命令传递输入
例如ssh
远程执行命令、mysql
执行SQL语句等,避免手动输入:
# 通过ssh远程在服务器上创建目录并输出信息
ssh user@remote_host << EOF
mkdir -p /tmp/test
echo "目录创建成功:$(date)"
EOF
3. 脚本中嵌入配置文件内容
部署服务时,直接在脚本中写入配置文件内容,无需依赖外部配置文件:
# 配置Nginx虚拟主机
cat << EOF > /etc/nginx/conf.d/my site.conf
server {
listen 80;
server_name example.com;
root /var/www/html;
index index.html;
}
EOF
4. 结合管道或重定向处理文本
通过管道将Here Document的内容传递给其他命令处理:
# 筛选包含"error"的行
<< EOF | grep "error"
info: start
warn: low memory
error: disk full
debug: end
EOF
输出:error: disk full
注意事项
- 分界符可自定义(不一定是
EOF
),但建议用大写字母(如END
),避免与内容冲突。 - 若输入内容中需要包含分界符本身(如
EOF
),可通过转义(\EOF
)或更换分界符解决。 <<-
仅忽略Tab,不忽略空格,因此缩进时需用Tab而非空格。
总结
Here Document(<< EOF
)是Linux中简化多行输入的高效工具,通过灵活的分界符规则和变量解析能力,大幅提升了脚本编写和命令行操作的效率,尤其适合需要动态生成多行内容的场景。
<< EOF
(称为 Here Document 或 Heredoc)是 Linux Shell 中一种用于多行输入重定向的语法。它的核心作用是将一段文本块(通常是多行内容)直接作为某个命令的输入,而无需单独创建文件。以下是详细说明:
1. 基础语法
command << DELIMITER
文本内容...
DELIMITER
- DELIMITER:自定义的结束标记(如
EOF
、END
等),需要成对出现。 - 文本内容:输入给
command
的内容,直到遇到独立的DELIMITER
结束。
示例:
cat << EOF
Hello, World!
This is a Here Document example.
EOF
输出:
Hello, World!
This is a Here Document example.
2. 结束标记规则
- 严格匹配:结束标记必须独立成行,且前后不能有空格或其他字符。
- 缩进问题(如 Bash 中):
使用<<- DELIMITER
(注意短横线-
)可忽略行首的 制表符(Tab),但空格仍会报错。cat <<- EOF This line has leading tabs (ignored). EOF # 这里必须用 Tab 缩进,不能是空格
3. 变量与命令替换
- 变量替换:默认启用(类似双引号):
name="Alice" cat << EOF Hello, $name! # 输出 "Hello, Alice!" EOF
- 禁止替换:用单引号包裹
DELIMITER
:cat << 'EOF' Hello, $name! # 输出 "Hello, $name!" EOF
- 命令替换:
cat << EOF Today is $(date). EOF
4. 转义字符处理
- 默认不转义(如
\n
作为普通字符),但可通过以下方式控制:- 使用双引号包裹
DELIMITER
(不改变行为,因为默认已启用)。 - 使用
-e
选项(如echo -e
)解释转义符。 - 行首反斜杠
\
可转义换行符(合并行):
输出:cat << EOF Line 1 \ continued on Line 2 EOF
Line 1 continued on Line 2
- 使用双引号包裹
5. 输入目标
- 标准输入:通常传递给命令,如
cat
、grep
、ssh
等。 - 与管道结合:
输出:cat << EOF | grep "Hello" Hello, World! Goodbye! EOF
Hello, World!
6. 应用场景
场景 1:生成文件/配置
cat > config.yaml << EOF
app:
name: "myapp"
port: 8080
EOF
场景 2:自动化交互命令
mysql -u root -p << EOF
CREATE DATABASE mydb;
GRANT ALL ON mydb.* TO 'user'@'localhost';
EOF
场景 3:脚本内多行输出
usage() {
cat << EOF
Usage: $0 [options]
Options:
-h Show help
-v Enable verbose mode
EOF
}
7. 常见错误
- 不匹配的结束标记:
cat << EOF Line 1 E0F # 拼写错误,无法结束(应全大写 EOF) EOF
- 缩进不一致:使用
<<-
时只能用 Tab,不能用空格。
8. 扩展:Here String (<<<
)
- 单行输入:
command <<< "文本"
grep "foo" <<< "foo bar baz"
总结
- 优势:避免创建临时文件,提升脚本可读性。
- 注意:确保结束标记唯一,合理处理变量替换与缩进。
掌握 Here Document 可大幅简化多行输入场景的脚本编写!
Here Document(<< EOF
)详解
Here Document 是 Linux 中一种方便的输入机制,允许你在脚本中一次性输入多行数据,通常用于向命令或程序传递多行输入。以下是其详细说明:
1. 基本语法
command << EOF
内容行1
内容行2
...
EOF
<<
:表示开始 Here Document。EOF
:标记,表示输入的结束。可以选择其他名称,如END
,但需前后一致。- 内容行:放置在标记之间的多行输入。
2. 使用场景
写入文件:
cat << EOF > file.txt 第一行内容 第二行内容 EOF
将内容写入
file.txt
。作为命令输入:
tr 'A-Z' 'a-z' << EOF HELLO WORLD EOF
输出
hello world
。脚本中使用:
#!/bin/bash echo "请输入多行内容,以EOF结束:" content=$(cat << EOF $(date) $(whoami) EOF ) echo "$content"
3. 变量替换
默认情况下,Here Document 会进行变量替换。例如:
name="Alice"
cat << EOF
你好,$name!
EOF
输出:
你好,Alice!
若要禁用变量替换,使用单引号:
cat << 'EOF'
你好,$name!
EOF
输出:
你好,$name!
4. 注意事项
- 结束标记必须单独一行,并且不能有前导空格。
- 可以使用不同名称的标记,如
END
,但需前后一致。
5. 示例
# 将多行内容写入文件
echo "开始写入文件..."
cat << EOF > example.txt
这是一行内容。
这是第二行。
EOF
echo "内容已写入 example.txt"
# 输出多行信息
echo "显示信息:"
cat << INFO
欢迎来到这里!
这是一个示例。
INFO
6. 总结
Here Document 提供了一种简洁的方式来处理多行输入,广泛应用于脚本编写中。通过合理的使用,可以显著提高脚本的可读性和效率。
Linux中的<< EOF
(Here Document)是一种用于将多行文本传递给命令或脚本的输入重定向方式,常用于Shell脚本中。以下是对其的详细解析:
一、基本概念
Here Document(简称Heredoc)允许将一段多行文本作为输入传递给命令或脚本[1][2]。例如:
cat << EOF
This is line 1
This is line 2
EOF
输出结果为:
This is line 1
This is line 2
二、核心语法
基本结构
command << delimiter [text] delimiter
command
:接收输入的命令(如cat
、mail
、ssh
等)。delimiter
:自定义的结束标记(如EOF
),需保证前后一致且独占一行[1][2]。text
:要传递的多行内容,最终作为command
的标准输入。
示例
# 将多行文本写入文件 cat << EOF > myfile.txt Hello World This is a test file. EOF
三、关键特性与变形
分隔符规则
- 结束分隔符必须顶格写,前后不得有空格或Tab[1][2]。
- 起始分隔符前的空格会被忽略,但建议保持简洁。
变量解析
- Heredoc内容支持Shell变量替换[1][3],例如:
输出:name="Alice" cat << EOF Hello $name! EOF
Hello Alice!
- 若需禁用变量解析,用引号包裹分隔符(推荐双引号)[1][3]:
输出:cat << "EOF" Hello $name! EOF
Hello $name!
- Heredoc内容支持Shell变量替换[1][3],例如:
缩进处理(
<<-
)- 使用
<<-
代替<<
时,Heredoc内容的每行开头制表符(Tab)会被删除,适合缩进代码提升可读性[1][5]:
输出:cat <<- EOF Hello World EOF
Hello World
- 使用
四、常见应用场景
自动化交互命令
- 通过Heredoc模拟交互式输入,例如远程执行SSH命令:
ssh user@host <<EOF cd /path ls -l EOF
- 通过Heredoc模拟交互式输入,例如远程执行SSH命令:
生成配置文件
- 动态生成Docker或Kubernetes的配置文件:
cat <<EOF | sudo tee /etc/docker.service [Unit] Description=Docker Service EOF
- 动态生成Docker或Kubernetes的配置文件:
批量处理SQL或脚本
- 将多条SQL语句传递给MySQL:
mysql -u root <<EOF CREATE DATABASE test; USE test; CREATE TABLE users (id INT); EOF
- 将多条SQL语句传递给MySQL:
五、注意事项
终止符严格性
- 结束分隔符必须独占一行,且不能有额外字符(包括空格)[1][4]。
- 示例错误写法:
cat << EOF # 错误:EOF后有空格 Content EOF
特殊字符转义
- 若内容包含
$
、`
等Shell元字符,需用引号禁用解析或手动转义[4]。
- 若内容包含
兼容性
- Heredoc在大多数类Unix系统(如Linux、macOS)的Shell中均支持,但具体语法可能因Shell类型(如Bash、Zsh)略有差异[5]。
六、总结
Here Document(<< EOF
)是Linux Shell中强大的文本输入工具,适用于多行文本处理、自动化脚本、配置文件生成等场景。通过灵活使用分隔符、变量控制和缩进处理,可显著提升脚本的可读性与效率[1][3][5]。