恢复以前的回声状态

Joe*_*Fan 7 batch-file subroutine

在DOS批处理文件子程序中,如何在子程序中关闭回声,但在返回之前,将其恢复到以前的状态(打开或关闭)?

例如,如果有一个命令被调用echo restore,我会像这样使用它:

echo on
... do stuff with echoing ...
call :mySub
... continue to do stuff with echoing ...
exit /b

:mySub
@echo off
... do stuff with no echoing ...
echo restore
goto :EOF
Run Code Online (Sandbox Code Playgroud)

Mic*_*sen 5

最简单的方法是首先不要关闭回声

相反,执行您当前echo off对子程序其余部分的行所做的操作- 在子程序中的所有命令前面加上一个@符号。这具有关闭该命令的回显的效果,但保留未来命令的回显状态。

如果您使用执行其他命令的命令,例如 IF 或 DO,您还需要在“子命令”前加上一个 @ 以防止在 echo 处于其他状态时打印它们。

  • 在调试期间,您希望看到打印的命令,但在发布后您不会。交换许多奇怪的“@”是一个维护噩梦。 (3认同)

dbe*_*ham 5

我的第一次尝试是完全失败 - 感谢jeb指出错误.对于那些感兴趣的人,编辑历史记录中提供了原始答案.

如果您不介意将子例程放在单独的文件中,Aacini有一个很好的解决方案.

这是一个无需第二批文件即可运行的解决方案.它实际上这次工作!:)

(编辑2 - 根据jeb在评论中的建议优化代码)

:mysub
::Silently get the echo state and turn echo off
@(
  setlocal
  call :getEchoState echoState
  echo off
)
::Do whatever
set return=returnValue
::Restore the echo state, pass the return value across endlocal, and return
(
  endlocal
  echo %echoState%
  set return=%return%
  exit /b
)

:getEchoState echoStateVar
@setlocal
@set file=%time%
@set file="%temp%\getEchoState%file::=_%_%random%.tmp"
@(
  for %%A in (dummy) do rem
) >%file%
@for %%A in (%file%) do @(
  endlocal
  if %%~zA equ 0 (set %~1=OFF) else set %~1=ON
  del %file%
  exit /b
)
Run Code Online (Sandbox Code Playgroud)

如果您愿意忍受同时尝试访问同一文件的两个进程的轻微风险,则可以简化:getEchoState例程,而无需SETLOCAL或临时变量.

:getEchoState echoStateVar
@(
  for %%A in (dummy) do rem
) >"%temp%\getEchoState.tmp"
@for %%A in ("%temp%\getEchoState.tmp") do @(
  if %%~zA equ 0 (set %~1=OFF) else set %~1=ON
  del "%temp%\getEchoState.tmp"
  exit /b
)
Run Code Online (Sandbox Code Playgroud)

  • 好主意,但它无法正常工作!由于`for/f"标记中的`echo` = 3 delims =."%% A in('echo')`将在新的cmd-context中执行,并且始终为"ON".第二个问题是,即使你得到它已经本地化的状态,就像我的系统一样,我得到了'ECHO ist eingeschaltet(ON). (2认同)

Aac*_*ini 5

最简单的方法是将子例程提取到另一个 .bat 文件并通过以下方式调用CMD /CCALL

echo on
... do stuff with echoing ...
cmd /C mySub
... continue to do stuff with echoing ...
exit /b
Run Code Online (Sandbox Code Playgroud)

mySub.bat:

@echo off
... do stuff with no echoing ...
exit /b
Run Code Online (Sandbox Code Playgroud)

这样,echo 状态将自动恢复到执行时的值CMD /C;这种方法的唯一缺点是执行速度稍慢......