← 文章

Shell 重定向与 Heredoc 速记

Shell 重定向与 heredoc 速记:cat、输出重定向与多行输入。

cat 是什么

cat 会从标准输入读取内容,然后把内容输出到标准输出。

直接运行时:

cat

终端会等待你输入内容;你输入什么,它就输出什么。

> 输出重定向

> 是 shell 的输出重定向语法。

cat > note.txt

意思是:把 cat 原本要打印到终端的内容,写入 note.txt 文件。

例如:

cat > note.txt
hello
world

输入完成后按 Ctrl-D 结束,note.txt 内容就是:

hello
world

注意:> 会覆盖文件原内容。如果想追加,用 >>。

cat >> note.txt
another line

cat > "$pr_body" 是什么

cat > "$pr_body"

可以拆成两部分:

cat

读取输入。

> "$pr_body"

把输出写入 $pr_body 变量指向的文件。

所以整体意思是:从输入读取内容,并写入 $pr_body 这个文件。

"$pr_body" 外面的双引号是为了避免路径里有空格时命令出错。

Heredoc 是什么

Heredoc 是 shell 里给命令提供多行输入的语法。

基本形式:

命令 <<EOF
多行内容
EOF

例子:

cat <<EOF
hello
world
EOF

等价于把下面两行作为 cat 的输入:

hello
world

输出结果是:

hello
world

EOF 和 heredoc 的关系

EOF 是 heredoc 的结束标记。

cat <<EOF
hello
world
EOF

这里:

  • <<EOF 表示开始一个 heredoc。
  • 中间的内容会作为命令输入。
  • 最后一行单独的 EOF 表示 heredoc 结束。

EOF 不是固定关键字,只是常用名字,意思是 “End Of File”。你可以换成别的标记:

cat <<END
hello
world
END

效果一样。

<<EOF 和 <<'EOF' 的区别

不带引号时,heredoc 内容里的变量会被 shell 展开:

name=Alice
cat <<EOF
hello $name
EOF

输出:

hello Alice

带单引号时,内容会原样保留:

name=Alice
cat <<'EOF'
hello $name
EOF

输出:

hello $name

所以如果正文里可能有 $、反引号、引号、Markdown 代码块等内容,通常用:

cat > "$pr_body" <<'EOF'
这里是多行正文
EOF

这样可以避免 shell 误解析正文内容。

临时文件写法的完整例子

pr_body="$(mktemp)"
cat > "$pr_body" <<'EOF'
## Summary

- Add feature A
- Fix bug B

## Verification

- npm run typecheck
EOF

gh pr create --title "feat: add feature A" --body-file "$pr_body"
rm -f "$pr_body"

逐行解释:

pr_body="$(mktemp)"

创建一个临时文件,并把路径保存到变量 pr_body。

cat > "$pr_body" <<'EOF'
...
EOF

把 heredoc 中间的多行正文原样写入临时文件。

gh pr create --title "feat: add feature A" --body-file "$pr_body"

创建 PR,并从临时文件读取 PR body。

rm -f "$pr_body"

删除临时文件。

一句话总结

cat > "$file" <<'EOF'
内容
EOF

意思是:把中间这段多行内容原样写入 $file 指向的文件。