4

如果我们有一个批处理文件被重定向到这样的日志:

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

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

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

通常这根本不是问题,但是我试图让这个白痴证明,因为我不会是在其他脚本/计划任务中实现批处理文件的人。

在这一点上,我似乎需要完全摆脱使用暂停,但我希望有一个我不需要的解决方案。谢谢您的帮助。

4

5 回答 5

3

没有很好的方法来确定标准输入或标准输出是否已使用本机批处理命令重定向。

但是在您的情况下无需担心重定向。只需将 PAUSE 标准输入和标准输出重定向到 con,您不必担心之前的重定向。

pause <con >con

更新

可以干净地检测标准输入和/或标准输出和/或标准错误是否可能已被重定向。但是我还没有想出一种方法来非破坏性地确定哪些句柄被重定向。

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

该技术依赖于这样一个事实,即无论何时重定向现有句柄,旧定义都会保存在最低可用的未定义句柄中。

如果没有任何重定向,则将2>nulstderr 保存在 3 中,并且 4 未定义。所以5>&4失败了,||分支被解雇了。

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

如果测试报告存在重定向,则以下至少一项必须为真:

  • 标准输入重定向
  • 标准输出重定向
  • 标准错误重定向
  • 处理 4 直接用类似 4>"log.txt" 的东西定义
  • 处理 5 直接用 5>"log.txt" 之类的东西定义

不幸的是,我无法确定以上哪些是正确的,除了......

在 DosTips 上,SiberiaMan 发布了一种简单的技术来确定标准输入是否已被重定向或正在接收管道:

2>nul >nul timeout /t 0 && (
  >con echo stdin not redirected or piped
) || (
  >con echo stdin has been redirected or is receiving piped input
)
于 2018-09-02T18:03:12.683 回答
2

我不知道仅使用批处理和标准命令的任何方法。但是,如果在 .bat 中包含另一个 .exe 对您来说足够重要,则可以从其他语言(例如本机 C 或 C# 程序)中使用一些技巧。

于 2013-03-20T20:57:51.470 回答
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
于 2013-03-20T21:01:21.350 回答
0

stdout您可以通过一个小技巧检查是否重定向。
它使用了在 TAB 将光标移回后输出退格键的事实,如果在这种情况下光标应移动到起始位置之前,则会创建一个错误以在日志文件中提示奇怪字符。

缺点是,它输出<FF><TAB>><BACKSPACE><BACKSPACE><CR><LF>到标准输出。
当 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
于 2018-09-17T13:32:08.033 回答
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

戴夫和杰布有一些东西。但我没有链接。

菲尔

于 2018-09-17T15:59:48.427 回答