Reputation: 2639
I have a long Sql*plus script that for some reason needs to run some unix commands using the exclamation mark syntax.
I write to a spool in order to have a log file at the end of the process.
The problem is that if an OS command fails, the stderr is lost and doesn't go to the spooled file.
Example code
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
If one cp
fails, I wouldn't know just by looking at mylog.txt
Obviously doing !cp file1 folder1/ &> mylog.txt
would only mess up the log beeing spooled to in unpredictable ways.
What can be done in order for the the stderr of the unix commands be writen to the file beeing spooled to ?
I tried lc.'s suggestion, appending 2>&1
at the end of every cp command in order to redirect stderr to stdout but I get this:
Enter value for 1:
SET DEFINE OFF
made it to not prompt for a value. It allowed me to discover that it's not only stderr that doesn't get spooled: stdout doesn't either. It seems that everything executed with "!" is un-spool-able.
Upvotes: 1
Views: 2000
Reputation: 31
If you want to send shell command output to your sqlplus spool file, you can't do it while SPOOL has the file locked for writing. Here's the sequence in the .sql script that worked for me:
SPOOL out.log
...sql stuff here...
SPOOL OFF
host ps -eaf | grep something 1>>out.log
SPOOL out.log APPEND
...more sql stuff...
Upvotes: 0
Reputation: 933
Actually, the stdout and stderr are not lost but they won't go in the spool file.
Given the script echo.sql
:
spool sql.out
select 1 from dual ;
!echo 1
!invalid command
spool off
If you launch your script from a shell as so :
sqlplus *connect string* @echo.sql > host.out 2> host.err
You will get the output from your sql command in sql.out
, the output from echo in host.out
and the error message in host.err
. If you're launching your script non interactively -from a cron or something- you'll have to capture stdout/stderr as you would do any other non sql*plus script.
Edit regarding comment
With the option SET TERMOUT ON
in the script file you will have the output of your sql commands both in the spool file and stdout.
So finally, if you want everything in one file you can call your script as so :
sqlplus *connect string* @echo.sql &>echo.log
You will still have the output of just the sql in the spool file.
Upvotes: 2