批处理文件回显开/关无法正常工作 [英] batch file echo on/off not working properly

查看:96
本文介绍了批处理文件回显开/关无法正常工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不是很习惯制作批处理文件,所以我可能做错了事,但是我真的在打开/关闭回声时遇到了麻烦. (也就是说,如果您发现我错过的任何其他错误,请随时指出)

I'm not really used to making batch files, so I'm probably doing something wrong, but I'm really having trouble with echo off/on. (That said, if you see any other error that I missed, feel free to point it out)

这是我的代码的简化版本:

Here's a simplified version of my code:

@echo off
setlocal
set args=
set dir="."

:getargs
IF "%2"=="" (
    set dir="%1"
    goto callbatch
)
set args=%args% %1
shift
goto getargs

:callbatch
for %%f in (%dir%\*.txt) do (
    echo processing %%f
    "%BATCHHOME%\batch.bat %args% %%f
    echo
)

因此,基本上,我在BATCHHOME中有一个批处理文件,该批处理文件对单个txt文件起作用,并且我想生成一个批处理文件,该批处理文件将处理给定目录中的所有txt文件.循环中唯一的回声是为了更好地说明问题.

So basically, I have a batch file in BATCHHOME that does something to a single txt file and I want to produce a batch file that will process all the txt files in a given directory. The lone echo in the loop is to better illustrate the problem.

现在,这是我遇到的问题.输出如下:

Now, here's where I have a problem. The output of this looks like:

processing foo\text1.txt
some output from batch.bat
ECHO is on.

C:\somedir>(
echo processing foo\text2.txt
   "C:\the\path\of\batch.bat" the arguments here foo\text2.txt
)
ECHO is on.

C:\somedir>(
echo processing foo\text3.txt
   "C:\the\path\of\batch.bat" the arguments here foo\text3.txt
)
ECHO is on.

(etc)

好吧...我不知道为什么我正在调用的批处理文件打开回显功能,但是我没有做到这一点,所以我每次都将其关闭!我将最后一部分更改为:

Ok... I don't know why the batch file I'm calling turns echo on, but I didn't make it, so I'll just turn it back off each time! I changed the last part to:

:callbatch
for %%f in (%dir%\*.txt) do (
    echo processing %%f
    "%BATCHHOME%\batch.bat %args% %%f
    echo off
)
echo
echo on
echo
echo Finished!

(同样,两个单独的"echo"在那里进行调试)所以现在的输出看起来像这样:

(Again, the two lone "echo" are there for debug) So now the output looks like this:

processing foo\text1.txt
some output from batch.bat
processing foo\text2.txt
some output from batch.bat
processing foo\text3.txt
some output from batch.bat
(etc.)
ECHO is off.
ECHO is on.
Finished!

这几乎是完美的,但是有些奇怪.如果打开echo,则为什么显示"Finished!"(完成!)而不是回音完成!"?然而,更大(但相关)的问题是,当批处理文件完成后,我的路径不再显示.换句话说,不是拥有:

This would be almost perfect, but there's something a bit odd. If echo is on, then why does it display "Finished!" instead of "echo Finished!"? The bigger (but related) problem however is that when the batch file is done, I don't get my path displayed any more. In other words, instead of having:

C:\Somedir>_

我刚得到

_

我需要手动键入"echo on"以获取再次显示的路径.我哪里出问题了?

I need to type "echo on" manually to get the path to show again. Where did I go wrong?

edit:为澄清起见,我知道"echo"本身会打印出echo的当前状态.那就是我的意图.在第一个代码中,它们在那里显示在我调用另一个批处理文件后神秘地打开了回显.在第二个示例中,该示例显示回显在批处理文件的末尾,但其行为似乎没有.那是我的问题.

edit: Just to clarify, I am aware that "echo" by itself prints the current status of echo. That is what I intended. In the first code, they are there to show that echo mysteriously turns on after I call the other batch file. In the second one, it is there to show that echo is on at the end of the batch file, yet the behaviour is as if it wasn't. THAT is my problem.

推荐答案

我现在看到了您的问题-这是一个有趣的问题.您正在从批处理文件中调用批处理文件,而无需使用CALL.

I see your problem now - and it is an interesting one. You are calling a batch file from within a batch file without using CALL.

如果批次A在没有CALL的情况下执行了批次B,则一旦批次B完成,整个批次处理将终止-批次A将不会从中断处恢复.批处理终止后,ECHO状态将返回到批处理开始之前的原始状态,通常为ON.

If batch A executes batch B without CALL, then the entire batch processing is terminated once batch B finishes - Batch A will not resume where it left off. Once batch processing is terminated the ECHO state is returned to the original state that existed before batch processing began, normally ON.

但是您的情况要复杂一些,因为您对第二批的调用"在一个FOR循环中.因此,即使批处理已终止,FOR循环仍将继续执行缓存在内存中的DO命令.现在,这些命令已在ECHO ON的命令行上下文中执行.

But your scenario is a bit more complicated because your "call" to the 2nd batch is within a FOR loop. So the FOR loop continues to execute the DO commands that are cached in memory, even though batch processing has terminated. The commands are now executing in a command line context with ECHO ON.

在第二种情况下,您可以在FOR DO块中明确关闭ECHO.在第一个呼叫"之后,您再次处于命令行上下文中,然后将ECHO关闭.因此,您需要手动打开ECHO.

In your 2nd scenario you explicitly turn ECHO OFF within the FOR DO block. After the 1st "call" you are again in command line context, and then you turn ECHO OFF. Hence your need to turn ECHO ON manually.

我不确定FOR循环后的行如何执行.您说您已经简化了代码,所以我假设您实际运行的代码在某种代码块中也具有这些额外的行.然后,这些行将被缓冲,即使在批处理终止后仍将执行.这也可以解释为什么打印"Finished!"的行.即使ECHO为ON,也不会回声.代码块内的所有命令均使用输入最外层代码块之前存在的ECHO状态.一个例外是FOR DO块使用进入DO块之前存在的ECHO状态.

I'm not sure how the lines after the FOR loop are getting executed. You said you have simplified the code, so I am assuming the code you are actually running has those additional lines in some kind of code block as well. The lines would then be buffered and would still execute even after batch processing terminates. This would also explain why the line that prints "Finished!" is not echoed even though ECHO is ON. All commands within a block of code use the ECHO state that existed prior to entering the outer most block of code. The one exception is a FOR DO block uses the ECHO state that existed prior to entering the DO block.

您发布的两套代码都不会运行,因为每组代码在调用"第二个批处理文件的行中都有不平衡的引号.

Both sets of code you posted do not run because each has an unbalanced quote in the line that "calls" the 2nd batch file.

解决方法是将CALL简单地添加到执行第二个批处理文件的语句中.然后批处理将继续,ECHO状态将保持为OFF,父批处理将从正确停止的地方恢复.

The fix is to simply add CALL to the statement that executes the 2nd batch file. Then batch processing will continue, the ECHO state will remain OFF, and the parent batch will resume where it left off properly.

我还改进了参数解析逻辑和引号的使用.您应该先使用~去除每个自变量的引号,然后再添加自己的引号.该参数可能已经有自己的引号.而且,无论何时将文件名或路径作为参数传递,都应在文件名或路径中包含空格或特殊字符的情况下将其引起引用.您需要跟踪变量中的值是否带引号.通常,我发现更容易保持变量值不加引号,然后在需要时显式添加引号.

I also improved the argument parsing logic and the use of quotes. You should strip quotes from each argument using ~ before explitly adding your own. The argument may already have its own quotes. And any time a file name or path is passed as an argument, it should be quoted in case it contains space or special characters. You need to keep track of whether the value in a variable is quoted or not. I generally find it easier to keep my variable values unquoted and then explicitly add quotes when I need them.

@echo off
setlocal
set args=
set "dir=."

:getargs
IF "%~2"=="" (
    if "%~1" neq "" set "dir=%~1"
    goto callbatch
)
set args=%args% %1
shift
goto getargs

:callbatch
for %%f in ("%dir%\*.txt") do (
    echo processing %%f
    call "%BATCHHOME%\batch.bat" %args% "%%f"
    echo
)

这篇关于批处理文件回显开/关无法正常工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆