我需要编写一个脚本,向程序(psql)输入多行输入。
在谷歌搜索了一下之后,我发现下面的语法是有效的:
cat << EOF | psql ---params
BEGIN;
`pg_dump ----something`
update table .... statement ...;
END;
EOF
这正确地构造了多行字符串(从BEGIN;to END;,包括在内)并将其作为输入管道输送到psql。
但是我不知道它是怎么工作的,有人能解释一下吗?
我主要指的是cat << EOF,我知道>输出到一个文件,>>附加到一个文件,<从文件读取输入。
<<到底是做什么的?
它有手册页吗?
<< EoF的基本意思是:
<< - "读取从下一行开始的多行输入,并将其视为单独文件中的代码"
EoF -“在多行输入中发现单词EoF后立即停止阅读”
正如其他答案所解释的,多行输入称为Here文档
Here Document通常用于生成要传递给后续进程的输出。例如,cat << EoF可以使用Here Document生成所需的输出。
下面是一个使用Here Document动态创建文本文档的例子:
cat << EoF > ./my-document.txt
Hello world
Have a nice day
EoF
值得注意的是,这里的文档也在bash循环中工作。
下面的例子展示了如何获取table的列列表:
export postgres_db_name='my_db'
export table_name='my_table_name'
# start copy
while read -r c; do test -z "$c" || echo $table_name.$c , ; done < <(cat << EOF | psql -t -q -d $postgres_db_name -v table_name="${table_name:-}"
SELECT column_name
FROM information_schema.columns
WHERE 1=1
AND table_schema = 'public'
AND table_name =:'table_name' ;
EOF
)
# stop copy , now paste straight into the bash shell ...
output:
my_table_name.guid ,
my_table_name.id ,
my_table_name.level ,
my_table_name.seq ,
或者甚至没有新的线条
while read -r c; do test -z "$c" || echo $table_name.$c , | perl -ne
's/\n//gm;print' ; done < <(cat << EOF | psql -t -q -d $postgres_db_name -v table_name="${table_name:-}"
SELECT column_name
FROM information_schema.columns
WHERE 1=1
AND table_schema = 'public'
AND table_name =:'table_name' ;
EOF
)
# output: daily_issues.guid ,daily_issues.id ,daily_issues.level ,daily_issues.seq ,daily_issues.prio ,daily_issues.weight ,daily_issues.status ,daily_issues.category ,daily_issues.name ,daily_issues.description ,daily_issues.type ,daily_issues.owner
在Bash中处理多行文本时,cat <<EOF语法非常有用。当将多行字符串分配给shell变量、文件或管道时。
在Bash中使用cat <<EOF语法的例子:
1. 为shell变量分配多行字符串
$ sql=$(cat <<EOF
SELECT foo, bar FROM db
WHERE foo='baz'
EOF
)
$sql变量现在也保存换行字符。你可以用echo -e "$sql"来验证。
2. 在Bash中传递多行字符串到文件
$ cat <<EOF > print.sh
#!/bin/bash
echo \$PWD
echo $PWD
EOF
print.sh文件现在包含:
#!/bin/bash
echo $PWD
echo /home/user
3.在Bash中将多行字符串传递给管道
$ cat <<EOF | grep 'b' | tee b.txt
foo
bar
baz
EOF
b.txt文件包含bar和baz行。相同的输出被打印到stdout。