简体   繁体   English

当我的 Windows.bat 被调用时,ECHO 是打开还是关闭?

[英]Was ECHO ON or OFF when my Windows .bat was CALLed?

When I CALL one Windows .bat file from another, can the called file tell whether ECHO was ON or OFF in the caller?当我从另一个CALL一个 Windows .bat文件时,被调用的文件能否告诉调用者的ECHOON还是OFF

When a .bat file is entered, ECHO is set to ON (even if it was OFF in the CALLER).输入.bat文件时, ECHO设置为ON (即使它在 CALLER 中为OFF )。

I want to preserve the caller's ECHO status in the called .bat so I can control both (possibly a chain of more than two nested calls) from a single place.我想在被调用的.bat中保留调用者的ECHO status ,这样我就可以从一个地方控制两者(可能是超过两个嵌套调用的链)。

I could pass a parameter or set my own environment variable but is there a better way?我可以传递一个参数或设置我自己的环境变量,但有更好的方法吗?

EDIT Just to clarify what's needed: callee.cmd needs to do things with echo off only for the duration of its run.编辑只是为了澄清需要什么:callee.cmd 需要在运行期间做一些 echo off 的事情。 Upon returning to its caller, it must restore the echo state the caller had.返回到其调用者后,它必须恢复调用者拥有的 echo state。

Please fill in the?????s in the script below:请填写以下脚本中的????s:

callee.cmd: callee.cmd:

@rem save the echo state
@ ???? HOW???? ????
@ set "savedEchoState=??????"

@rem the following commands must not be echoed
@echo off
command1
command2
command3

@rem restore the previous echo state
echo %savedEchoState%

caller1.cmd:来电者1.cmd:

@echo off
call callee.cmd
echo

caller2.cmd:来电者2.cmd:

@echo on
call callee.cmd
echo

Required output:必填 output:

caller1.cmd must print echo off and caller2.cmd must print echo on . caller1.cmd 必须打印echo off而 caller2.cmd 必须打印echo on

Can it be done without creating any files on a disk ?可以在不在磁盘上创建任何文件的情况下完成吗?

This is a tough one. 这是困难的一个。 Everything involving a pipe or a for doesn't work, as new processes get generated, which invalidates the echo status. 当生成新进程时,涉及管道或for所有内容都不起作用,这会使echo状态无效。 It is possible involving a temp file: 可能涉及临时文件:

A.BAT: 一只蝙蝠:

echo on
echo
call b.bat
echo off
echo
call b.bat
echo

B.BAT: B.BAT:

@(>tmp echo)
@type tmp|find "ON" >nul && (@set "oldEcho=ON") || (@set "OldEcho=OFF")
@echo off
echo B:echo was previously %OldEcho%
REM insert your payload here
REM restore previous Echo Status:
echo %OldEcho%

Result: 结果:

C:\Folder>a

C:\Folder>echo on

C:\Folder>echo
ECHO ist eingeschaltet (ON).

C:\Folder>call b.bat
B:echo was previously ON

C:\Folder>echo off
ECHO ist ausgeschaltet (OFF).
B:echo was previously OFF
ECHO ist ausgeschaltet (OFF).

To detect the ECHO state without dependency to the windows language you could use a temporary file. 要检测ECHO状态而不依赖于Windows语言,可以使用临时文件。
The file is empty when ECHO is OFF, else it contains the language string of ECHO IS ON . 当ECHO为OFF时,该文件为空,否则它包含ECHO IS ON的语言字符串。

@echo off
echo Testing detectEchoState

echo on
@call :detectEchoState

@echo off
@call :detectEchoState off
exit /b


:detectEchoState
@(
    (
        FOR /F %%L in ("1") do REM
    ) > "%TEMP%\echoCheck.tmp"

    FOR /F "delims=" %%F in ("%TEMP%\echoCheck.tmp") do @if %%~zF == 0 (set "EchoState=OFF" ) ELSE (set "EchoState=ON")
    del "%TEMP%\echoCheck.tmp"
    echo EchoState !EchoState!
)
@exit /b

I had the same problem, and ended up on this page.我遇到了同样的问题,最终出现在此页面上。
Here's a slightly improved version of jeb's script.这是 jeb 脚本的一个稍微改进的版本。

  • It uses (call,) instead of rem, which avoids having to put the ) on a separate line.它使用 (call,) 而不是 rem,这样可以避免将 )​​ 放在单独的行上。
  • It does not depend on delayed expansion being on for the testing.它不依赖于测试的延迟扩展。
@echo off
call :TestEchoState off
call :TestEchoState on
exit /b

:TestEchoState %1=ON or OFF
echo %1
@echo
@call :GetEchoState STATE
@echo off
echo STATE=%STATE%
exit /b

:GetEchoState %1=OUTVAR
@for /f %%F in ("%TEMP%\EchoState%PID%.tmp") do @(
  (FOR /f %%N in ("1") do call,) > "%%F"
  for %%S in ("%%F") do @if %%~zS==0 (set "%1=OFF") else (set "%1=ON")
  del "%%F"
)
@exit /b

And if you accept to just test the errorlevel, it's possible to make the detection routine even shorter:如果您接受仅测试错误级别,则可以使检测程序更短:

@echo off
call :TestEchoLevel off
call :TestEchoLevel on
exit /b

:TestEchoLevel %1=ON or OFF
echo %1
@echo
@call :GetEchoLevel
@echo off
if errorlevel 1 (echo STATE=ON) else (echo STATE=OFF)
exit /b

:GetEchoLevel # Returns errorlevel 0 if echo is off
@for /f %%F in ("%TEMP%\EchoLevel%PID%.tmp") do @(
  (for /F %%N in ("1") do call,) > "%%F"
  for %%S in ("%%F") do @del "%%F" & exit /b %%~zS
)

( Editing the answer from Stephan , considering the echo state can be also reported in lower case, and that his answer does not allow for edition. ) (编辑Stephan的答案,考虑到 echo state 也可以用小写形式报告,并且他的答案不允许编辑。)

The first 2 lines and the last one below save and restore the echo state. The lines 3 to 6 should be replaced by your code:下面的前两行和最后一行保存并恢复回显 state。第 3 到 6 行应替换为您的代码:

@(>tmp echo)
@type tmp|find /i "ON" >nul && (@set "oldEcho=ON") || (@set "OldEcho=OFF")
    @echo off                               &::line 3
    echo B:echo was previously %OldEcho%    &::line 4
    REM insert your payload here            &::line 5
    REM restore previous Echo Status:       &::line 6
echo %OldEcho%

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM