views:

333

answers:

5

Script Example:

@SET APPLY_ORA=YES
@REM ...
IF %APPLY_ORA%==YES (
@ECHO Doing Oracle
CALL %SOME_ORACLE_SPECIFIC_COMMAND% %SOME_ORACLE_SPECIFIC_FLAGS%
CALL %ANOTHER_ORACLE_SPECIFIC_COMMAND% %SOME_ORACLE_SPECIFIC_FLAGS%
) ELSE (
@ECHO Skipping Oracle
)

The idea is that I do not want to see IF YES==YES ( ) ELSE ( ) printed, particularly because it is split amongst multiple lines. I do however want to see the actual commands following CALL printed to the screen.

Now, I can make IF silent by appending an @ in front of IF But that makes it too silent! I do not see the actual commands being used, only their output. How can I reach the point of perfection when using Dos Scripting. Thanks!

+6  A: 

Turn echo off first, and then on later when you want to see the command.

@echo off
@SET APPLY_ORA=YES
@REM ...
IF %APPLY_ORA%==YES (
    @ECHO Doing Oracle
    @echo on
    CALL %SOME_ORACLE_SPECIFIC_COMMAND% %SOME_ORACLE_SPECIFIC_FLAGS%
    CALL %ANOTHER_ORACLE_SPECIFIC_COMMAND% %SOME_ORACLE_SPECIFIC_FLAGS%
) ELSE (
    @ECHO Skipping Oracle
)
recursive
Thanks, I will try that. What if I want to restore the state of the echo to what it was before (it is a longish script)? It could be off or on previously.
Hamish Grubijan
Hm, I don't see a way to do this. You may be better off with Michael's solution if you need this.
recursive
+3  A: 

Something as simple (and ugly) as the following might work:

@SET APPLY_ORA=YES
@REM ...
@echo off
IF %APPLY_ORA%==YES (
@ECHO Doing Oracle
@echo on
CALL %SOME_ORACLE_SPECIFIC_COMMAND% %SOME_ORACLE_SPECIFIC_FLAGS%
CALL %ANOTHER_ORACLE_SPECIFIC_COMMAND% %SOME_ORACLE_SPECIFIC_FLAGS%
@echo off
) ELSE (
@ECHO Skipping Oracle
)

I have also used code like the following to give much more control over when a command is displayed. It's come in very handy for debugging scripts that I normally don't want to have the commands displayed, but do want to display them when things go wrong (which is quite often with cmd scripts):

(set COMMAND="%PROG_FILES%\Microsoft Visual Studio\VC98\Bin\cl" /GX /Zi -D_WIN32_WINNT=%WIN32_WINNT% %SOURCE_FILE% /link /INCREMENTAL:NO %LIBRARIES%)
call :exec %COMMAND%


rem ...

rem exec - a subroutine that executes a command and optionally displays it first
rem        depending on the value of the %ECHO_COMMANDLINE% variable
:exec
if {%ECHO_COMMANDLINE%} == {1} (
echo %*
)
%*
goto :eof

If you want to execute a command after displaying the command unconditionally, the following version of your script uses a simple variation of the above that does the trick:

@echo off
set SOME_ORACLE_SPECIFIC_COMMAND=ftype
set SOME_ORACLE_SPECIFIC_FLAGS=txtfile
set ANOTHER_ORACLE_SPECIFIC_COMMAND=dir

SET APPLY_ORA=YES
REM ...
IF %APPLY_ORA%==YES (
    ECHO Doing Oracle
    call :echoexec %SOME_ORACLE_SPECIFIC_COMMAND% %SOME_ORACLE_SPECIFIC_FLAGS%
    call :echoexec %ANOTHER_ORACLE_SPECIFIC_COMMAND% %SOME_ORACLE_SPECIFIC_FLAGS%
) ELSE (
    ECHO Skipping Oracle
)

rem done with the script
goto :eof


rem - subroutines

@rem echoexec - a subroutine that executes a command also displaying 
@rem         the command that's about to be exectued
:echoexec
@echo %*
@%*
@goto :eof

Finally, you mention that you want to determine the current state of the "echo" command. It's a little tricky because the "echo" command is a built-in intrinsic part of cmd.exe, and not a separate executable file (at least that's what I think makes it tricky). Here's a script that has a subroutine you can use to query the current "echo" status (as well as some commands that test/demonstrate it):

@rem - examples of using the "echo_state" subroutine

@echo
@call :get_echo_state
@echo echo state was %RET%

@echo off
@echo
@call :get_echo_state
@echo echo state was %RET%

@echo on
@echo
@call :get_echo_state
@echo echo state was %RET%

@goto :eof


@rem
@rem  echo_state - returns the current state of the script's echo setting
@rem
@rem    upon return, the environment variable RET will contian the word
@rem    'off' if echo is currently off and 'on' if it's on.  It does this
@rem    by parsing the output of the 'echo' command redirected ot a file.
@rem
@rem    For some reason I find that it's necessary to redirect to a file
@rem    to parse the state, becuase if I try to parse the output of 
@rem    the 'echo' command directly in the "for /f" command like so:
@rem
@rem        @for /f  "tokens=3" %%a in ('echo') do @if "%%a" == "on." set RET=on
@rem
@rem    it always returns that echo is "on" (I suspect this has something to 
@rem    with the 'echo' command being a builtin part of cmd.exe and not
@rem    an external command, but I'm not sure).
@rem

:get_echo_state
@setlocal
@echo > %temp%\echostate.txt
@set RET=off
@for /f  "tokens=3" %%a in (%temp%\echostate.txt) do @if "%%a" == "on." set RET=on
@endlocal & set RET=%RET%
@goto :eof

Personally, I like to immediately set "echo off" at the start of my scripts and use the technique in the my second script above (the 'exec' subroutine) to run a command that might have the command line displayed. I imagine that turning the echo state on and off throughout the script would be a pain to manage.

Michael Burr
A: 

To echo only the contents of the if-statement, have the if-statement call a subroutine. Turn @echo on at the start of the routine, and @echo off at the end.

:InnerIfStatements
@echo on
::Do stuff here
@echo off
goto :EOF

To set echo back to what it was previously instead, store the echo-status in a variable, and call @echo %ECHOSTATUS% instead.

echo > tempfile.tmp
for /f "tokens=3 delims= " %%i in (tempfile.tmp) do set ECHOSTATUS=%%i
set ECHOSTATUS=%ECHOSTATUS:~0,-1%
del tempfile.tmp

Here is a full, working example:

@echo off
echo Echo is now off

echo > tempfile.tmp
for /f "tokens=3 delims= " %%i in (tempfile.tmp) do set ECHOSTATUS=%%i
set ECHOSTATUS=%ECHOSTATUS:~0,-1%
del tempfile.tmp

if "1" == "1" call :InnerIfStatements

echo Echo should be off again.
pause
exit /b 0

:InnerIfStatements
@echo on
echo Echo is now on.
@echo %ECHOSTATUS%
goto :EOF

Here's the output:

Echo is now off

C:\Users\BlueRaja\Desktop>echo Echo is now on.
Echo is now on.
Echo should be off again.
Press any key to continue . . .

BlueRaja - Danny Pflughoeft
Could you provide a minimal sample with output please?
Hamish Grubijan
@Hamish: Check now. The previous example was incorrect; 'echo' (apparently) calls `echo` in a separate console, so that it always gets set to 'on.' This new solution works.
BlueRaja - Danny Pflughoeft
+1  A: 

This is what I would have done.....I took your code sample and remodified it

@ECHO OFF
@SET APPLY_ORA=YES
@REM ...
IF %APPLY_ORA%==YES (
    @ECHO Doing Oracle
    @ECHO ON
    CALL %SOME_ORACLE_SPECIFIC_COMMAND% %SOME_ORACLE_SPECIFIC_FLAGS%
    CALL %ANOTHER_ORACLE_SPECIFIC_COMMAND% %SOME_ORACLE_SPECIFIC_FLAGS%
    @ECHO OFF
) ELSE (
    @ECHO Skipping Oracle
    @ECHO ON
    REM Do Something Else
    @ECHO OFF
)
@ECHO ON

I'm not sure if that is what you're asking....

Output

Based from the edited sample, it'll display all commands between the @ECHO ON and @ECHO OFF instruction, (so basically, it'll do the 1st call, and display everything that is executed by the call, and execute the next call, etc.)

The Elite Gentleman
What is the sample output? Could you edit your post please?
Hamish Grubijan
Check my edit....
The Elite Gentleman
+2  A: 

The other answers are unnecessarily complex or do not save the state of the echo (on or off). Simply prefix the command with an ampersand and change your statement:

@SET APPLY_ORA=YES
@REM ...
@IF %APPLY_ORA%==YES GOTO :apply_ora ELSE GOTO :skip_ora

:apply_ora
@ECHO Doing Oracle
CALL %SOME_ORACLE_SPECIFIC_COMMAND% %SOME_ORACLE_SPECIFIC_FLAGS%
CALL %ANOTHER_ORACLE_SPECIFIC_COMMAND% %SOME_ORACLE_SPECIFIC_FLAGS%
@GOTO :end

:skip_ora
@ECHO Skipping Oracle

:end
JRL
If the script is as simple as the example that's a workable solution (but then maintaining the state of the echo wouldn't be an issue either). If the script is large, complex, and/or comprised of a set of scripts, going though and prefixing all the commands with an '@' (except the ones you don't want to silence) can be a chore. Also, if you're concerned about preserving the echo state, presumably the script might be run with it either on or off, in which case the commands without an '@' prefix might not echo as desired.
Michael Burr
@Michael: agreed. The question specifically only talks of the single `if`, but it could have been a simplified example.
JRL