有没有办法检查批处理文件中的重定向?

时间:2013-03-20 20:43:16

标签: windows batch-file logging cmd

如果我们将批处理文件重定向到如下日志:

C:\Testing\Example.bat > C:\Testing\Example.log

批处理文件中是否有任何方法可以确定标准输出重定向是否发生在日志文件中?

基本上我的批处理文件需要传递三个参数。省略参数时,批处理文件会打印一个与常规Windows命令非常相似的用法示例,并抛出“暂停”,以便可以读取指令。但是,如果在没有参数的情况下调用批处理并且它正在被记录,那么批处理文件将永远坐在那里等待键来暂停暂停,但不会在屏幕上显示任何内容。

通常情况下,这根本不是问题,但是我正在尝试使这种白痴证明,因为我不会在其他脚本/计划任务中实现批处理文件。

此时似乎我需要完全摆脱使用暂停,但我希望找到一个我不需要的解决方案。谢谢你的帮助。

5 个答案:

答案 0 :(得分:2)

没有很好的方法来确定是否已使用本机批处理命令重定向了stdin或stdout。

但是您无需担心重定向的情况。只需将PAUSE stdin和stdout重定向到con,就不必担心先前的重定向。

pause <con >con

更新

可以干净地检测stdin和/或stdout和/或stderr是否可能已被重定向。但是我还没有想出一种非破坏性地确定哪些句柄被重定向的方法。

@echo off
2>nul (5>&4 break) && (
  >con echo There has been redirection
) || (
  >con echo No redirection found
)

该技术依赖于whenever an existing handle is redirected, the old definition is saved in the lowest available undefined handle

如果没有任何重定向,则2>nul将stderr保存为3,并且未定义4。因此5>&4失败,并且||分支被触发。

如果存在重定向,则已经定义3以保留重定向句柄的原始值,因此2>nul将stderr保存为4(除非其他重定向也使用了4)。无论哪种方式,5>&4都会成功,因为定义了4,因此&&分支将触发。

如果测试报告已存在重定向,则必须至少满足以下条件之一:

  • stdin重定向
  • stdout重定向
  • stderr重定向
  • 直接用4>“ log.txt”
  • 之类定义的句柄4
  • 直接用5>“ log.txt”
  • 之类定义的句柄5

不幸的是,除了...之外,我无法确定上述哪一项是正确的。

Over at DosTips,SiberiaMan发布了一种简单的技术来确定stdin是否已重定向或正在接收管道:

2>nul >nul timeout /t 0 && (
  >con echo stdin not redirected or piped
) || (
  >con echo stdin has been redirected or is receiving piped input
)

答案 1 :(得分:1)

我不知道有任何方法只使用批处理和标准命令。但是,有一些技巧可以用于其他语言,如本机C或C#程序,如果它足够重要,你可以包含另一个.exe和.bat。

答案 2 :(得分:0)

标准Windows批处理文件(我知道)中没有办法确定STDOUT的重定向位置,或者即使重定向它。但是,您可能希望将您的使用示例写入STDERR而不是STDOUT,因此至少简单地重定向到文件将无法捕获使用信息。

示例test.cmd:

@ECHO OFF

ECHO Test output 1>&2
PAUSE 1>&2

然后叫它:

test.cmd > output.log

仍将输出:

Test output
Press any key to continue . . .

当然,对于在重定向STDERR的情况下调用文件时,这没有任何作用。

test.cmd 2> error.log

答案 3 :(得分:0)

您可以通过一个小技巧来检查stdout是否被重定向。
它使用以下事实:在TAB后将光标移回原处,并且在这种情况下如果将光标移到起始位置之前,将产生错误,以在日志文件中获得有关奇怪字符的提示。

缺点是它将<FF><TAB>><BACKSPACE><BACKSPACE><CR><LF>输出到stdout。
当stdout是控制台时,只需清除它即可。
但是,当stdout重定向到文件时,您可以将这些字符附加到文件中,但是可以用有意义的文本对其进行注释。

@echo off
setlocal
call :createTAB_BS

echo Script started, test for redirection:
cls
( echo %%TAB%%%%BS%%%%BS%%) | ( findstr "^"  2^> nul)
if %errorlevel% EQU 0 (
    >CON echo stdout is redirected
) ELSE (
    echo stdout goes to the console
)

exit /b

:createTAB_BS
for /f "tokens=1,2 delims=," %%A in ('forfiles /p "%~dp0." /m "%~nx0" /c "cmd /c echo(0x09,0x08"') do (
    set "TAB=%%A"
    set "BS=%%B"
)
exit /b

答案 4 :(得分:0)

我认为您只是问错了一个问题。您想找到一种在cmd模式下以额外的中断结束批处理的方法。并在不暂停的情况下以批处理模式停止。 您可以使用CMDpause 这将使一个名为cmdpause的变量 例子 https://www.administrator.de/wissen/batchcode-erstellen-fehler-batch-leichter-finden-184736.html https://www.dostips.com/forum/viewtopic.php?t=7257#p47510

Dave和jeb有一些东西。但是我没有链接。

菲尔