如何使操作系统命令的标准错误以“!”运行转到 Sql*plus 线轴?
Posted
技术标签:
【中文标题】如何使操作系统命令的标准错误以“!”运行转到 Sql*plus 线轴?【英文标题】:How to make stderr of OS commands ran with "!" go to Sql*plus spool? 【发布时间】:2013-08-07 11:47:04 【问题描述】:背景
我有一个很长的 Sql*plus 脚本,由于某种原因需要使用感叹号语法运行一些 unix 命令。
我写入一个假脱机以便在进程结束时有一个日志文件。
问题在于,如果操作系统命令失败,stderr 会丢失并且不会转到假脱机文件。
示例代码
spool mylog.txt
!echo alter user xxx identified by yyyy;
alter user xxx identified by yyyy;
!echo cp file1 folder1/
!cp file1 folder1/
!echo alter user yyy identified by xxx;
alter user yyy identified by xxx;
!echo cp file2 folder2/
!cp file2 folder2/
spool off
如果一个cp
失败了,我不会只看mylog.txt 就知道
显然,执行!cp file1 folder1/ &> mylog.txt
只会以不可预知的方式搞乱被假脱机的日志。
问题
为了将 unix 命令的 stderr 写入到 spooled 到的文件中,可以做些什么?
更新
我尝试了 lc.'s 建议,在每个 cp 命令的末尾附加 2>&1
以便将 stderr 重定向到 stdout 但我得到了这个:
Enter value for 1:
更新 2
SET DEFINE OFF
使其不提示输入值。它让我发现不仅 stderr 没有被假脱机:stdout 也没有。似乎一切都用“!”执行是不可假脱机的。
【问题讨论】:
【参考方案1】:其实stdout和stderr并没有丢失,只是不会进入spool文件中。
给定脚本echo.sql
:
spool sql.out
select 1 from dual ;
!echo 1
!invalid command
spool off
如果您从 shell 启动脚本:
sqlplus *connect string* @echo.sql > host.out 2> host.err
您将在sql.out
中获得sql 命令的输出,在host.out
中获得echo 的输出,在host.err
中获得错误消息。如果您以非交互方式启动脚本 - 从 cron 或其他东西 - 您必须像执行任何其他非 sql*plus 脚本一样捕获 stdout/stderr。
编辑关于评论
使用脚本文件中的选项SET TERMOUT ON
,您将在假脱机文件和标准输出中都有sql命令的输出。
所以最后,如果你想要一个文件中的所有内容,你可以这样调用你的脚本:
sqlplus *connect string* @echo.sql &>echo.log
您仍然会在 spool 文件中仅获得 sql 的输出。
【讨论】:
问题是我需要生成一个日志。在日志中,条目的顺序必须与它们发生时的顺序相同。在一个文件中有 sql 输出,在另一个文件中有非 sql 输出对我没有帮助。在同一文件的末尾附加非 sql 输出也不是正确的日志。 您的回答以及 lc. 的回答引导我找到了解决方案。不过,我会接受你的,因为它更完整并且用于数据化的解释。我终于从 sql 文件中删除了 spool 命令,并通过 bash 使用sqlplus *connect string* @echo.sql 2>&1 | tee -a echo.log
生成了日志。这样我就可以看到当我以交互方式运行它时会发生什么,并且还可以得到一个包含 stderr、sdtout 和 Sql*plus 输出的日志。【参考方案2】:
您可以将2>&1
附加到每个命令以将stderr 重定向到stdout。
【讨论】:
我刚测试过,提示Enter value for 1:
顺便说一下,stdout 也不会被写入线轴。
以上内容应该适用于 bash。你碰巧知道!
正在使用哪个shell? (AFAIK,stdout 就是写入 spool 的东西,这里的问题在于 stderr 不是。因此解决方案应该是将 stderr 重定向到 stdout)
这是 Bash。问题是 sqlplus 将 &1 视为参数,因为 sql 脚本中的参数遵循 &1、&2 等形式。
这很奇怪。根据this FAQ,!
不应该执行变量替换(而HOST
会)。您可以尝试 SET DEFINE OFF
禁用提示(除非您在其他地方需要)【参考方案3】:
如果您想将 shell 命令输出发送到您的 sqlplus 假脱机文件,当 SPOOL 锁定文件以进行写入时,您无法执行此操作。以下是对我有用的 .sql 脚本中的序列:
SPOOL out.log
...这里有sql的东西...
阀芯关闭
主机 ps -eaf | grep 1>>out.log
SPOOL out.log 追加
...更多的 sql 东西...
【讨论】:
以上是关于如何使操作系统命令的标准错误以“!”运行转到 Sql*plus 线轴?的主要内容,如果未能解决你的问题,请参考以下文章