【问题标题】:Turn on echo for a single command in a batch file为批处理文件中的单个命令打开 echo
【发布时间】:2019-11-06 14:48:29
【问题描述】:

在 Windows 批处理文件中,如果我启用了回显(默认设置),我可以通过添加 @ 前缀来禁用单个命令的回显,例如:

some_command_that_will_be_echoed
@some_command_that_wont_be_echoed

不过,我已经用@echo off 禁用了回显功能,但有时我想回显命令。有什么魔法等价物吗?例如:

@echo off
some_command_that_wont_be_echoed
<unknown_magic_prefix> some_command_that_will_be_echoed

我发现了这个问题:turn on echo temporarily,但这基本上是说“打开回声,做你的事情,然后再次关闭它”。我可以这样做,但我希望有更优雅的东西。

编辑:这个Windows batch file: how to enable inline echo of a command 出现在相关问题列表中;这基本上和我的问题一样,而且成功!

EDIT2:为了提供上下文,下面是我要做的一部分。请注意,为了这篇文章的好处,我用 C 风格的 cmets 装饰了它;它们不在真正的脚本中。

@echo off   // Because I don't want the bulk of the commands displayed. 
            // (In fact it's worse than that, this file is called from another
            //  with echo already disabled.)

title CMD Window with SVN enabled

set PATH=  ...  // my new path which happens to include SVN this time

svn --version --quiet   // This command outputs just the SVN version as a number
                        // but it gets rather lost on its own, and the 'full'
                        // output is too wordy.  My belief is that if the entire
                        // command was echoed, it would provide a perfect 
                        // context.

echo SVN version is:    // This is an obvious alternative, simply putting a
svn --version --quiet   // message before the actual command.

echo svn --version --quiet  // Or even just echoing the command 'by hand'
svn --version --quiet

+@svn --version --quiet   // This imaginary syntax would be the gold-standard

always_echo( svn --version --quiet )   // This function would be acceptable, but
                                       // its definition eludes me and seems 
                                       // clunky

<some batch file magic preamble>    // This would be okay, but would get arduous
svn --version --quiet               // if it was long-winded or had to be done a
<some batch file magic to close>    // few times or more.

但要强调的是,虽然这是一个相对容易“修复”的特定示例,但我正在寻求一个更通用的解决方案,我可以在其他可能不那么简单的情况下使用它。

@Compo 合理地指出@echo off 本身并不是很优雅。这很公平,但是 a) 在这种情况下它已经启用并且 b) 它非常地道。我喜欢这种清晰(想象的语法):

@echo off
command_1    // not echoed
command_2    // not echoed
+@command_3  // IS echoed and stands out
command_4    // not echoed

@command_1    // not echoed
@command_2    // not echoed
command_3     // IS echoed and gets a little lost
@command_4    // not echoed

显然这是一种主观意见,但归结为希望只装饰不常见的情况。

最后,如果它真的不可能,那也很公平,但是确定并没有什么坏处:)

【问题讨论】:

  • 我们谈论的是批处理文件,没有什么比这更优雅了。您那里的链接就是解决方案。
  • 好的,在some_wrapper_function( command_I_want_echoed ) 的意义上“更优雅”怎么样,它会将状态恢复到原来的状态,无论是关闭还是打开?
  • 不要使用@echo off来全局关闭echoing,它本身就很不雅。使用 @ 前缀,并在必要时将其删除,这是优雅的解决方案。
  • 谢谢,@Compo,这是一个非常公平的观点。尽管如此,我发现这会使事情变得混乱。突出特殊情况而普通情况不装饰不是更干净吗?
  • 你怎么样edit your question 包含一些真实的代码,然后告诉我们哪些行需要echoing,哪些不需要。这至少会让我们有机会提供您认为更优雅的解决方案。

标签: windows batch-file echo


【解决方案1】:

你可以使用一个小宏(%+@%),它会显示命令然后执行它。

@echo off    
call :define_macro

setlocal EnableDelayedExpansion
set var=content

%+@% ver
%+@% ver /?
%+@% echo %var% !var!
exit /b

:define_macro
(set \n=^^^

)
set ^"+@=for %%# in (1 2) do if %%#==2 (%\n%
    setlocal EnableDelayedExpansion %\n%
    for /F "tokens=1,*" %%1 in ("!time: =0! !argv!") do (%\n%
        endlocal%\n%
        echo %%1 Execute: %%2%\n%
        endlocal%\n%
        %%2%\n%
      )%\n%
    ) ELSE setlocal DisableDelayedExpansion ^& set argv="

exit /b

输出:

14:04:08,05 执行:ver

Microsoft Windows [版本 10.0.17134.1069]
14:04:08,05 执行:ver /?
显示 Windows 版本。

版本
14:04:08,05 执行:echo content !var!
内容内容

已编辑:根据 sst 的建议,我删除了辅助函数,但为了能够使用自定义和漂亮的前缀,我决定反对宏内的 echo on

【讨论】:

  • 不错的宏。对:__execHelper 的调用可以通过将其替换为echo on %\n% - for %%# in (%%#) do %%1 %\n% - echo off %\n% 来消除。并将for %%# in (1 2) do ... 替换为for %%# in (%%# 2) do ...。在这些修改之后,就不需要echo I will execute: !argv!%\n%
  • @sst 谢谢,避免使用辅助函数真的很简单。但是您的FOR 循环必须更改为FOR /F "tokens=*" ... 以避免与包括?* 在内的命令出现问题。但即使可以在宏中使用echo on,我也不喜欢杂乱的输出(带有当前提示和新行)。
  • 正如我所担心的那样,语法有点复杂,但解决方案的精神是正确的,谢谢。在执行之前只回显命令是一种很好的感觉,而不是改变回显模式本身。
  • @EddInglis Batch 宏几乎是 hairy,但您甚至可以将它们移动到自己的 library-batch 文件中,您不需要查看或了解它们
【解决方案2】:

这是一个可以帮助你的例子:

@(
    Echo On
    Title CMD Window with SVN enabled
    Set "PATH=%PATH%;D:\ummy\directory"
)
svn --version --quiet
@(
    Rem All other none echoed commands here
    Pause
    Echo Off
    Exit /B
)

【讨论】:

    【解决方案3】:
    :echo
        @echo on
        %*
        @set __echo_errorlevel=%ERRORLEVEL%
        @echo off
    exit /b %__echo_errorlevel%
    

    call :echo command arg1 arg2 arg3... 一样使用它。 (如果你打电话给:echo@echoon,这将变成off。)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-18
      • 1970-01-01
      • 1970-01-01
      • 2014-01-06
      • 2014-12-31
      相关资源
      最近更新 更多