linux输入重定向接EOF的问题

看了下<<EOF的用法解释大概是“EOF与 << 结合使用,表示后续的输入作为子命令或子Shell的输入,直到遇到EOF为止,再返回到主调Shell”。
不是很明白这个“当作子shell输入,直到遇到EOF再返回主调shell” 有什么意思? 结合脚本来问一下吧
-----------------------------------------------------------------------------
脚本是这样的
#! /bin/bash
.....A.....
$ORACLE_HOME/bin/rman log=${RMAN_FILE}.log <<EOF
.....B......
EOF
.....C.....
exit
------------------------------------------------------------------------------
A部分主要是在设置变量,B是一个RMAN备份主体,C是跟日志相关的内容
我搞不懂把B这部分用<<EOF 来做重定向输入有什么意义呢?如果是按照问题开头查到的那个“当做子shell...再返回到主调shell”来理解,是为了改变执行顺序吗?

还是说把这2个EOF之间的B部分输入到${RMN_FILE}.log中?
--------------------------------------
补充一下,如果是把B部分输入到这个${RMAN_FILE}.log中的话,那么
$ORACLE_HOME/bin/rman log=${RMAN_FILE}.log <<EOF
这句话中前面的$ORACLE_HOME/bin/rman起到什么作用呢?

command <<EOF
(内容)
EOF
意思是把内容当作标准输入传给<<前的程序command
你的例子里,ORACLE_HOME/bin/rman log=${RMAN_FILE}.log 你可以看做是一条命令,“log=。。。”是rman的一个参数
”.....B......“在你说的情况下就是rman的命令,这样就不用交互式使用rman,而是一条条自动执行
rman所有命令执行完后,返回到shell,继续执行shell命令”.....C.....“部分

再给你举个例子:
sqlplus user/password <<EOF
select * from table1;
select * from table2;
EOF
两条select语句输入给sqlplus,这样就不用sqlplus中交互输入SQL语句了
不知道你看明白了吗追问

不是很明白您说的这个交互式。
如果这个脚本里面没有EOF这一段的话,脚本应该也是按顺序从A执行到B再到C吧?

您后面举的那个例子,如果没有EOF会怎样交互的处理呢?
我觉得也是登录sqlplus 然后执行选择2个表的内容吧?这里不知道重定向输入有什么别的作用吗?

而且脚本中那句 ORACLE_HOME/bin/rman 我没搞懂这个有什么作用
我觉得我还是没理解..我感觉我理解的>反过来了而已

追答

你输入

$ORACLE_HOME/bin/rman log=${RMAN_FILE}.log
回车后出来应该是
RMAN>
在此提示符下,你需要输入rman的命令,输入一行,rman执行一行,这就叫交互式
你可以将两个EOF之间(不用输入"
等待你输入一条sql语句,输入完回车,sqlplus执行,然后再输入一条,在执行。。。而例子中两条语句可以连续执行。

rman是ORACLE的一个工具,用于备份、还原和恢复oracle数据库
你可以这样理解:两个EOF之间的语句,可以一次性传给<<之前的命令,作为该命令的输入

追问

嗯,你说的这个交互式和EOF的意思我明白了。
我之前疑惑那个$ORACLE_HOME/bin/rman的作用,原来是启动RMAN
----
启动RMAN以后,就执行RMAN备份
因为前面还有 log=${RMAN_FILE}.log<<EOF 这句话,
那我想问下
是不是执行完备份之后,B部分会被输入到这个log中呢?

追答

你应该把“$ORACLE_HOME/bin/rman log=${RMAN_FILE}.log”看成一条命令,“log=...”是rman的参数,B部分作为这条命令的输入。
rman的执行过程输出结果记录到log里,而不是B部分的命令。
估计你老想着把命令的stdout和stderr重定向到log文件
这是输入重定向的一种用法。你只要记住

command << EOF
.......
EOF
是固定的用法,EOF之间的命令作为command的标准输入

追问

加了点分,继续就这个脚本请教一个RMAN备份的问题吧

我之前在windows/linux下做RMAN备份(不用脚本方式)的时候,通常的步骤是

    连接恢复目录数据库和目标数据库 2.run{...分配通道..指定备份路径、备份名字..释放通道}

大概就是上面写的这个样子,但是并没有这里的log=${RMAN_FILE}.log 这一步

这个log=..是shell脚本备份增加的一个参数?

追答

跟shell脚本没关系,你单独执行也可以输入log参数,只不过你没用而已
log就是个rman的命令参数,就像你输入rman target /里的target一样

看rman的命令参数:
rman --help

Argument Value Description
-----------------------------------------------------------------------------
target quoted-string connect-string for target database
catalog quoted-string connect-string for recovery catalog
nocatalog none if specified, then no recovery catalog
cmdfile quoted-string name of input command file
log quoted-string name of output message log file
trace quoted-string name of output debugging message log file
append none if specified, log is opened in append mode
debug optional-args activate debugging
msgno none show RMAN-nnnn prefix for all messages
。。。。

追问

重新测试了一下,把log这一句删除了也能执行...
看来是我之前的测试有误。
感谢耐心解答

追答

再给你说一句,EOF只是个标记,用其他的字符串可以替代,只要成对出现即可,只要中间包含的内容不含此字符串就可以

比如
command << END
.....
END

温馨提示:答案为网友推荐,仅供参考
第1个回答  2013-09-24
还在等什么,这么专业的问题,回答不了。赶紧给人家分吧追问

皇帝不急急死太监了?分当然是要给人家的,但是问题也是要问完的。

相似回答