Dos scripting - как заставить замолчать, если отображать вызываемые команды - PullRequest
0 голосов
/ 02 февраля 2010

Пример сценария:

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

6 голосов
/ 02 февраля 2010

Сначала отключите эхо, а затем включите, когда вы хотите увидеть команду.

@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
)
3 голосов
/ 02 февраля 2010

Что-то настолько простое (и безобразное), как может работать следующее:

@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, а не отдельным исполняемым файлом (по крайней мере, я думаю, что это сложно). Вот скрипт, в котором есть подпрограмма, которую вы можете использовать для запроса текущего статуса "эха" (а также некоторые команды, которые его тестируют / демонстрируют):

@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 голосов
/ 06 февраля 2010

Остальные ответы излишне сложны или не сохраняют состояние эха (включено или выключено).Просто добавьте к команде префикс с амперсандом и измените выражение:

@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
1 голос
/ 05 февраля 2010

Это то, что я бы сделал ..... Я взял твой пример кода и повторил его

@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 (так что в основном он будет выполнять первый вызов и отображать всекоторый выполняется вызовом и выполняет следующий вызов и т. д.)

0 голосов
/ 04 февраля 2010

Чтобы отобразить только содержимое оператора if, попросите оператор if вызвать подпрограмму. Поверните @echo on в начале процедуры и @echo off в конце.

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

Чтобы вернуть эхо обратно на прежнее значение, сохраните эхо-статус в переменной и вместо этого вызовите @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

Вот вывод:

Эхо отключено

C: \ Users \ BlueRaja \ Desktop> echo Echo теперь включено.
Эхо сейчас включено.
Эхо должно быть снова выключено.
Нажмите любую клавишу для продолжения . , .

...