我需要编写一个脚本,向程序(psql)输入多行输入。
在谷歌搜索了一下之后,我发现下面的语法是有效的:
cat << EOF | psql ---params
BEGIN;
`pg_dump ----something`
update table .... statement ...;
END;
EOF
这正确地构造了多行字符串(从BEGIN;to END;,包括在内)并将其作为输入管道输送到psql。
但是我不知道它是怎么工作的,有人能解释一下吗?
我主要指的是cat << EOF,我知道>输出到一个文件,>>附加到一个文件,<从文件读取输入。
<<到底是做什么的?
它有手册页吗?
这被称为heredoc格式,用于向stdin提供字符串。详情见https://en.wikipedia.org/wiki/Here_document#Unix_shells。
来自man bash:
Here Documents
This type of redirection instructs the shell to read input from
the current source until a line
containing only word (with no trailing
blanks) is seen.
All of the lines read up to that point are then used as the
standard input for a command.
The format of here-documents is:
<<[-]word
here-document
delimiter
No parameter expansion, command substitution, arithmetic expansion, or
pathname expansion is performed on
word. If any characters in word are
quoted, the
delimiter is the result of quote removal on word, and the lines
in the here-document are not expanded.
If word is unquoted, all lines of the
here-document are subjected to parameter expansion, command
substitution, and arithmetic
expansion. In the latter case, the
character sequence \<newline> is
ignored, and \ must be used to quote the characters \, $, and `.
If the redirection operator is <<-, then all leading tab characters
are stripped from input lines and the
line containing delimiter. This
allows here-documents within shell scripts to be indented in a natural fashion.
<< EoF的基本意思是:
<< - "读取从下一行开始的多行输入,并将其视为单独文件中的代码"
EoF -“在多行输入中发现单词EoF后立即停止阅读”
正如其他答案所解释的,多行输入称为Here文档
Here Document通常用于生成要传递给后续进程的输出。例如,cat << EoF可以使用Here Document生成所需的输出。
下面是一个使用Here Document动态创建文本文档的例子:
cat << EoF > ./my-document.txt
Hello world
Have a nice day
EoF
在你的例子中,“EOF”被称为“Here Tag”。基本上,<<Here告诉shell,您将输入一个多行字符串,直到“tag”在这里。你可以随意命名这个标签,通常是EOF或STOP。
关于Here标签的一些规则:
标签可以是任何字符串,大写或小写,尽管大多数人习惯使用大写。
如果该行中有其他单词,则该标记将不被视为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