Dos脚本 - 如何获取静默但是显示被调用的命令

时间:2010-02-02 16:14:33

标签: scripting batch-file

脚本示例:

@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
)

我的想法是我不希望看到IF YES == YES()ELSE()打印,特别是因为它被分成多行。但我想看到CALL后面的实际命令打印到屏幕上。

现在,我可以通过在@前面添加IF来使IF 无声 但这太沉默了!我没有看到正在使用的实际命令,只看到它们的输出。使用Dos Scripting时,如何达到完美的程度。谢谢!

5 个答案:

答案 0 :(得分:6)

首先关闭回声,然后在想要查看命令时关闭。

@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
)

答案 1 :(得分:3)

如下所示的简单(和丑陋)可能有用:

@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
)

我还使用了以下代码来更好地控制何时显示命令。它非常方便调试我通常不希望显示命令的脚本,但是当出现问题时(通常使用cmd脚本),它们确实希望显示它们:

(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

如果要在无条件显示命令后执行命令,则以下版本的脚本使用上述的简单变体来实现这一目的:

@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

最后,您提到要确定“echo”命令的当前状态。这有点棘手,因为“echo”命令是cmd.exe的内置固有部分,而不是一个单独的可执行文件(至少我觉得这很复杂)。这是一个脚本,它有一个子程序,可用于查询当前的“echo”状态(以及一些测试/演示它的命令):

@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

就我个人而言,我喜欢在我的脚本开头立即设置“echo off”,并在我上面的第二个脚本('exec'子例程)中使用该技术来运行可能显示命令行的命令。我想在整个剧本中打开和关闭回声状态将是一件痛苦的事情。

答案 2 :(得分:2)

其他答案不必要地复杂或者不保存回声的状态(打开或关闭)。只需在命令前添加一个&符号并更改您的语句:

@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

答案 3 :(得分:1)

这就是我要做的.....我拿了你的代码样本并重新修改了它

@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

我不确定这是不是你问的......

输出

根据编辑过的示例,它将显示@ECHO ON@ECHO OFF指令之间的所有命令(基本上,它将执行第一次调用,并显示由打电话,然后执行下一个电话等。)

答案 4 :(得分:0)

要仅回显if语句的内容,请将if语句调用为子例程。在例行程序开始时转动@echo on,在结束时转动@echo off

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

要将echo设置回以前的值,请将echo-status存储在变量中,然后调用@echo %ECHOSTATUS%

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

这是一个完整的,有效的例子:

@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

这是输出:

  

Echo现已关闭

     

C:\ Users \ BlueRaja \ Desktop> echo Echo现已开启。
  Echo现在开始了。
  回声应该再次关闭。
  按任意键继续 。 。