我需要编写脚本以将多行输入输入到程序( psql
)。
经过一番谷歌搜索,我发现以下语法有效:
cat << EOF | psql ---params
BEGIN;
`pg_dump ----something`
update table .... statement ...;
END;
EOF
这样可以正确构造多行字符串(从BEGIN;
到END;
,包括两端),并将其作为输入传递给psql
。
但是我不知道它是如何 / 为什么起作用的,请解释一下吗?
我主要是指cat << EOF
,我知道>
输出到文件, >>
追加到文件, <
从文件中读取输入。
<<
到底是做什么的?
并有手册页吗?
当在 Bash 中处理多行文本时, cat <<EOF
将多行字符串分配给 shell 变量,文件或管道时。
cat <<EOF
语法用法的示例:$ sql=$(cat <<EOF
SELECT foo, bar FROM db
WHERE foo='baz'
EOF
)
$sql
变量现在也包含换行符。您可以使用echo -e "$sql"
进行验证。
$ cat <<EOF > print.sh
#!/bin/bash
echo \$PWD
echo $PWD
EOF
现在, print.sh
文件包含:
#!/bin/bash
echo $PWD
echo /home/user
$ cat <<EOF | grep 'b' | tee b.txt
foo
bar
baz
EOF
b.txt
文件包含bar
和baz
行。将相同的输出打印到stdout
。
这称为heredoc格式,以将字符串提供给 stdin。有关更多详细信息,请参见https://en.wikipedia.org/wiki/Here_document#Unix_shells。
来自man bash
:
此处文件
这种重定向指示外壳程序从当前源读取输入,直到看到仅包含单词(无尾随空格)的行。
读取到该点的所有行,然后用作命令的标准输入。
此处文档的格式为:
<<[-]word here-document delimiter
没有对 word执行参数扩展,命令替换,算术扩展或路径名扩展。如果对 word中的任何字符加引号,则定界符是对 word删除引号的结果,并且本文档中的行不会扩展。如果未引用word,则对本文的所有行进行参数扩展,命令替换和算术扩展。在后一种情况下,字符序列
\<newline>
被忽略,并且\
来引用字符\
,$
和`
。如果重定向运算符为
<<-
,则所有前导制表符将从输入行和包含定界符的行中除去。这允许以自然的方式缩进 shell 脚本中的 here-document。
在您的情况下,“EOF” 被称为 “此处标签”。基本上, <<Here
告诉外壳程序您将要输入多行字符串,直到 “tag” Here
为止。您可以根据需要命名该标签,通常是EOF
或STOP
。
有关 Here 标记的一些规则:
例子:
$ cat >> test <<HERE
> Hello world HERE <-- Not by itself on a separate line -> not considered end of string
> This is a test
> HERE <-- Leading space, so not considered end of string
> and a new line
> HERE <-- Now we have the end of the string