当我从另一个 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
。是否可以完成而不在磁盘上创建任何文件
?
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)
结尾(这在每种语言中都应该一致;如果您知道一种不执行此操作的语言,请告诉我们)(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 关闭
时,光标不会改变,否则会移动到下一行。
然后代码读取光标的行号并恢复原始光标位置。
状态仅取决于检索到的行号。
@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
的答案,考虑到回声状态也可以用小写报告,并且他的答案不允许编辑。) 下面的前两行和最后一行保存和恢复回显状态。第 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
)