Link to home
Start Free TrialLog in
Avatar of Julie Kurpa
Julie KurpaFlag for United States of America

asked on

Batch Script to issue a command, store output, exit when Operator hits 'enter'

Hi,
I have a need to make a batch script of some sort to issue a command to shutdown, startup, or status an Oracle service running in Windows.  I am hoping to use the script you help me build to also issue sqlplus commands to shutdown/startup the Oracle database & listener.

My thoughts are that the user would click an icon on the desktop that opens a window where you could view the command being issued and the screen output.  When the command finishes, the screen remains until the operator presses enter or clicks something to acknowledge the completion.

If there are errors with the command that the user sees on the screen, rather than rely solely on the user's description of the error, I'd like the screen output to be sent to a log file.

In my perfect world, this script would ask the user which function they are performing  ("start", "stop", or "status" the service).  It would display the output from the command on the screen and also send the output to a log file.  And remain on the screen until the operator can confirm the success or failure of the command before closing the window.

I tried to put something together but the DOS window that opens disappears immediately after the command is finished.  I've got no log and it's amature.  I need something that my grandmother can execute and be able to see whether it was successful or not.

The commands being entered to status the service are:
set ORACLE_SID=orcl   <--this must be set automatically in the script.
cd E:\oracle\product\10.2.0\db_1\bin  <-- this is the directory that the command resides.
emctl status dbconsole  <-- this is the command itself

The commands being entered to stop the service are:
set ORACLE_SID=orcl
cd E:\oracle\product\10.2.0\db_1\bin
emctl stop dbconsole

The commands to start the service are:
set ORACLE_SID=orcl
cd E:\oracle\product\10.2.0\db_1\bin
emctl start dbconsole

I'd like the log sent to directory "E:\oracle\product\10.2.0\Scripts\OperatorScripts"
Thank you very much.

Avatar of Bill Bach
Bill Bach
Flag of United States of America image

It's a bit rudimentary, but you can expand on it...

@echo OFF
CLS
ECHO 1. Status the Service
ECHO 2. Stop the Service
Echo 3. Start the Service
SET /P Answer=Which Action Do You Want? (CR to Exit)
if "%Answer%" == "1" GOTO Status
if "%Answer%" == "2" GOTO Start
if "%Answer%" == "3" GOTO Stop
GOTO REALEND
:Status
set ORACLE_SID=orcl
E:
cd \oracle\product\10.2.0\db_1\bin
emctl status dbconsole  >E:\oracle\product\10.2.0\Scripts\OperatorScripts\Oracle.LOG
GOTO END
:Start
set ORACLE_SID=orcl
E:
cd \oracle\product\10.2.0\db_1\bin
emctl start dbconsole  >E:\oracle\product\10.2.0\Scripts\OperatorScripts\Oracle.LOG
GOTO END
:Stop
set ORACLE_SID=orcl
E:
cd \oracle\product\10.2.0\db_1\bin
emctl stop dbconsole >E:\oracle\product\10.2.0\Scripts\OperatorScripts\Oracle.LOG
GOTO END
:END
TYPE E:\oracle\product\10.2.0\Scripts\OperatorScripts\Oracle.LOG
pause
:REALEND

Open in new window

Avatar of Julie Kurpa

ASKER

That's very close to what I descibed.  Thank you!  I laughed when you said I could expand on it.  My ability to script is zero.  It may take me days and day, but I'll still take a stab at it.  But to save me hours of frustration, I am hoping you can help me further.

I've tested it and here's what I need adjusted if you could continue to assist me:

1. Can the answer required from the operator look for "start"  "stop"  or "status" instead of a number?
2. If they enter a response other than "start" "stop" or "status", can it simply not do anything or display an error and then loop back to the beginning?
3.  The output from the command doesn't show in the window.  Can it show the output from the command in the window as well as append to the log file?
4. Also the script closes the DOS Window when it's done.  Is it possible to have it stay on the screen to allow the user to review the messages before closing?

Thank you for your help.
1) Sure.  You can change the text and force them to reply with text, but then you run the risk of shift key being down, and other such problems.  Grandmothers often have problems with stuff like this due to failing vision.  I'd stick with numbers, which makes it less likely that someone will type in garbage.
2) Line 10 handles this -- it currently exits.  To have this loop, put a label before line 1 like ":Loop" and change line 10 to "GOTO Loop".  Might want to update the Prompt line, then, that they can press Ctrl-C to exit.  Again, Grandmothers have problems with multiple keypresses, which is why I left a simple way to exit -- anything that is garbage.
3/4) The output from EMCTL is being sent to the log file.  After running, the command transfers to the :END label, which should display the contents of the log file on-screen and then pause.  If you are not getting this, try changing all occurrences of "END" to "PrintLog" instead -- could be that END is a keyword that terminates immediately.
Hi.
I'm still having trouble with it.  
I added a loop tag so it would go back to beginning until "4" is entered to exit and then added the 'type', 'pause', and then 'goto loop' after the status to get it to pause, display the log (is that what's it's supposed to do?) and then go back to beginning.  

But it's not even updating the log in addition to exitting right after the command is issued.  There's only the beginning of the command being shown as feedback but not the result of the command as it would if I were doing this via command line.
Thank you.
:Loop
@echo OFF
CLS
ECHO 1. Status the Service
ECHO 2. Stop the Service
Echo 3. Start the Service
SET /P Answer=Which Action Do You Want?
if "%Answer%" == "1" GOTO Status
if "%Answer%" == "2" GOTO Start
if "%Answer%" == "3" GOTO Stop
if "%Answer%" == "4" GOTO End
GOTO LOOP
:Status
set ORACLE_SID=orcl
E:
cd \oracle\product\10.2.0\db_1\bin
emctl status dbconsole  
>E:\oracle\product\10.2.0\Scripts\OperatorScripts\Oracle.LOG
TYPE E:\oracle\product\10.2.0\Scripts\OperatorScripts\Oracle.LOG
pause
GOTO LOOP
:Start
set ORACLE_SID=orcl
E:
cd \oracle\product\10.2.0\db_1\bin
emctl start dbconsole  
>E:\oracle\product\10.2.0\Scripts\OperatorScripts\Oracle.LOG
TYPE E:\oracle\product\10.2.0\Scripts\OperatorScripts\Oracle.LOG
pause
GOTO LOOP
:Stop
set ORACLE_SID=orcl
E:
cd \oracle\product\10.2.0\db_1\bin
emctl stop dbconsole 
>E:\oracle\product\10.2.0\Scripts\OperatorScripts\Oracle.LOG
TYPE E:\oracle\product\10.2.0\Scripts\OperatorScripts\Oracle.LOG
pause
GOTO LOOP
:END
ECHO Exiting
SET /P Answer=Press ENTER to Exit.
 
 
 

Open in new window

Check your lines that call EMCTL -- the ">E:\Oracle...." text should be on the SAME line.  In
N the code you pasted, it appears to be on the NEXT line, which is incorrect.  Not sure if this is a true mistake or just a copy&paste error.
That was a "me" error.  It's fixed and the output is now going to the log file.  
However, the script is still exitting immediately after the command is issued so the user can't see what was done without opening the log file.  

Can the output be both sent to a log file and to the screen?
Not at the same time -- that is why the TYPE command was used to output the results from the log file back to the screen, right before the PAUSE.  The results of that command should be a display of the logfile.  Is THAT not working?

You may need to re-post the code again, for review.
Hi.
Correct.  The log is not being displayed after the command is finished.  It's as if the command itself contains some sort of exit.  The code is below.
Just for fun, I took out the 'emctl status dbconsole' command and just echoed some verbiage to the log file and it displayed on the screen fine.  The log file contained the previous output from the previous 'emctl status console' command along with my verbiage.

This making me wonder if I should create a batch script that executes two separate batch scripts:  One script  to do the 'emctl' stuff and one to display the log file.  Do you think that would work?
:Loop
@echo OFF
CLS
ECHO 1. Status the Service
ECHO 2. Stop the Service
Echo 3. Start the Service
ECHo 4. Exit
SET /P Answer=Which Action Do You Want?
if "%Answer%" == "1" GOTO Status
if "%Answer%" == "2" GOTO Start
if "%Answer%" == "3" GOTO Stop
if "%Answer%" == "4" GOTO End
GOTO LOOP
:Status
set ORACLE_SID=orcl
E:
cd \oracle\product\10.2.0\db_1\bin
emctl status dbconsole  >E:\oracle\product\10.2.0\Scripts\OperatorScripts\Oracle.LOG
TYPE E:\oracle\product\10.2.0\Scripts\OperatorScripts\Oracle.LOG
pause
GOTO LOOP
:Start
set ORACLE_SID=orcl
E:
cd \oracle\product\10.2.0\db_1\bin
emctl start dbconsole >E:\oracle\product\10.2.0\Scripts\OperatorScripts\Oracle.LOG
TYPE E:\oracle\product\10.2.0\Scripts\OperatorScripts\Oracle.LOG
pause
GOTO LOOP
:Stop
set ORACLE_SID=orcl
E:
cd \oracle\product\10.2.0\db_1\bin
emctl stop dbconsole >E:\oracle\product\10.2.0\Scripts\OperatorScripts\Oracle.LOG
TYPE E:\oracle\product\10.2.0\Scripts\OperatorScripts\Oracle.LOG
pause
GOTO LOOP
:END
ECHO Exiting
SET /P Answer=Press ENTER to Exit.

Open in new window

ASKER CERTIFIED SOLUTION
Avatar of Bill Bach
Bill Bach
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
I will do the "call" as you suggest, but for now...

While I was waiting for your reply, I was able to set it up to open a separate window to execute the 'emctl status dbconsole' command.  This was sort of nice because I could echo stuff like "this takes a minute..please be patient...".  

It ran the command, sent the output to the log and then closed the new window, returning control to the original window.
But.... <---don't you love those?
When it returns control back to the original window, it seems the original window had continued on with the rest of the script while the other window was doing the 'emct...' command.   So the part where it displays the log is displaying the old log from the previous time I ran the command; not with the output from the one running in the separate window.

Is there a way to make the first script wait until the 2nd command window is finished?
Here's the code that initiates the 2nd window and then displays the log.
:Loop
@echo OFF
CLS
ECHO 1. Status the Service
ECHO 2. Start the Service
Echo 3. Stop the Service
ECHo 4. Exit
SET /P Answer=Which Action Do You Want?
if "%Answer%" == "1" GOTO Status
if "%Answer%" == "2" GOTO Start
if "%Answer%" == "3" StopDBConsole.bat
if "%Answer%" == "4" GOTO End
GOTO LOOP
:Status
START cmd /c StatusDBConsole.bat
TYPE E:\oracle\product\10.2.0\Scripts\OperatorScripts\Oracle.LOG
pause
GOTO LOOP
:Start
START cmd /c StartDBConsole.bat
TYPE E:\oracle\product\10.2.0\Scripts\OperatorScripts\Oracle.LOG
pause
GOTO LOOP
:Stop
START cmd /c StopDBConsole.bat
TYPE E:\oracle\product\10.2.0\Scripts\OperatorScripts\Oracle.LOG
pause
GOTO LOOP
:END
ECHO Exiting
SET /P Answer=Press ENTER to Exit.
 
 
 

Open in new window

The START command fires a separate command window and returns immediately.  You can change this by adding /WAIT to your START lines:
     WAIT        Start application and wait for it to terminate


I'm not understanding where exactly to place the WAIT.  I've tried a couple of spots but it isn't working....
:Loop
@echo OFF
CLS
ECHO 1. Status the Service
ECHO 2. Start the Service
Echo 3. Stop the Service
ECHo 4. Exit
SET /P Answer=Which Action Do You Want?
if "%Answer%" == "1" GOTO Status
if "%Answer%" == "2" GOTO Start
if "%Answer%" == "3" StopDBConsole.bat
if "%Answer%" == "4" GOTO End
GOTO LOOP
:Status
START cmd /c StatusDBConsole.bat
TYPE E:\oracle\product\10.2.0\Scripts\OperatorScripts\Oracle.LOG
pause
GOTO LOOP
:Start
START cmd /c StartDBConsole.bat
TYPE E:\oracle\product\10.2.0\Scripts\OperatorScripts\Oracle.LOG
pause
GOTO LOOP
:Stop
START cmd /c StopDBConsole.bat
TYPE E:\oracle\product\10.2.0\Scripts\OperatorScripts\Oracle.LOG
pause
GOTO LOOP
:END
ECHO Exiting
SET /P Answer=Press ENTER to Exit.
 
 
 

Open in new window

Oop...I got it.  It was: START /wait cmd /c StatusDBConsole.bat

It works well.

The CALL command also works great.  The 'emctl' is indeed a batch program.  

You've been very helpful and I learned some neat stuff.  Thank you!