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

问题描述 投票:0回答:4

当我从另一个 Windows

CALL
文件中调用另一个文件时,被调用的文件能否判断调用者中的
.bat
ECHO
还是
ON

当输入

OFF

文件时,

.bat
设置为
ECHO
(即使在 CALLER 中是
ON
)。

我想在被调用的

OFF

中保留调用者的

ECHO
status
,这样我就可以从一个地方控制这两个(可能是两个以上嵌套调用的链)。

我可以传递参数或设置自己的环境变量,但有更好的方法吗?

编辑

只是为了澄清需要什么: callee.cmd 仅需要在其运行期间执行 echo off 操作。返回调用方后,它必须恢复调用方的回显状态。 请填写以下脚本中的 ?????? :

被调用者.cmd:

.bat

caller1.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%

caller2.cmd:

@echo off call callee.cmd echo

所需输出:

caller1.cmd 必须打印

@echo on call callee.cmd echo

,caller2.cmd 必须打印

echo off

是否可以完成

而不在磁盘上创建任何文件

windows batch-file variables echo
4个回答
5
投票
echo on

的所有内容都不起作用,因为会生成新进程,这会使

for
状态无效。不过,它
可能涉及临时文件:
A.BAT:

echo

B.BAT:

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

结果:

@(>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%

这利用了(不直观的)事实,即开/关消息取决于语言(在上面的示例中是德语),但以英语后缀 
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).

(ON)
结尾(这在每种语言中都应该一致;如果您知道一种不执行此操作的语言,请告诉我们)
    


3
投票
当 ECHO 为 OFF 时,文件为空,否则包含

(OFF)
的语言字符串。

ECHO IS ON

Win10无需创建文件的解决方案(需要vt100)

@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

这使用 ansi 转义序列将光标移动到第 1 行。

echo 关闭
时,光标不会改变,否则会移动到下一行。 然后代码读取光标的行号并恢复原始光标位置。 状态仅取决于检索到的行号。


1
投票
这是 jeb 脚本的稍微改进版本。


它使用 (call,) 而不是 rem,这避免了必须将 ) 放在单独的行上。
  • 测试不依赖于延迟扩展。
  • @echo off for /F "delims=#" %%a in ('prompt #$E# ^& for %%a in ^(1^) do rem') do set "ESC=%%a" echo OFF @call :get_echo_state @echo state=%state% echo ON @call :get_echo_state @echo state=%state% @exit /b :get_echo_state @( setlocal EnableDelayedExpansion <nul set /p "=%ESC%7%ESC%[1H" set "prompt=%ESC%[" set "0=call " for %%a in (1) do !0! <nul set /p "=%ESC%[6n%ESC%8" endlocal ) > CON @( set "state=on" pause < con > NUL pause < con > NUL for /F "tokens=1 skip=1 eol=" %%C in ('"replace /w /u ? . < con"') do @( if "%%C" == "1" @set "state=off" ) exit /b )
如果您接受只测试错误级别,则可以使检测例程变得更短:

@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



1
投票
Stephan

的答案,考虑到回声状态也可以用小写报告,并且他的答案不允许编辑。) 下面的前两行和最后一行保存和恢复回显状态。第 3 至 6 行应替换为您的代码:

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

© www.soinside.com 2019 - 2024. All rights reserved.