cmd /批处理文件未按顺序显示或记录其他程序的输出

时间:2015-12-23 09:02:38

标签: windows batch-file cmd echo

我在Windows cmd文件中有这个脚本,可以执行我想要的操作。它还显示并记录其输出,但显然该脚本中使用的程序的输出未按顺序显示或记录。 请参阅下面的脚本和输出。

[$compile:tplrt]

输出:

@ECHO OFF
:: script global variables 
SET log=nslookup-tests.log

::Logic
set LF=^



REM The two empty lines abive are required!!
set output=****%date% %time% -- NSLOOKUP from anywhere with DNS server from edpnet****
setlocal EnableDelayedExpansion

set output=!output!!LF!!LF!!LF!**youtube.com
set output=!output!!LF!!LF!*edpnet DNS
for /F "delims=" %%f in ('nslookup youtube.com 212.71.0.33') do (
 set output=!output!!LF!%%f
)
set output=!output!!LF!!LF!*google DNS
for /F "delims=" %%f in ('nslookup youtube.com 8.8.8.8') do (
 set output=!output!!LF!%%f
)

set output=!output!!LF!!LF!!LF!**bestofyoutube.com
set output=!output!!LF!!LF!*edpnet DNS
for /F "delims=" %%f in ('nslookup bestofyoutube.com 212.71.0.33') do (
 set output=!output!!LF!%%f
)
set output=!output!!LF!!LF!*google DNS
for /F "delims=" %%f in ('nslookup bestofyoutube.com 8.8.8.8') do (
 set output=!output!!LF!%%f
)

set output=!output!!LF!!LF!!LF!**vidzi.tv
set output=!output!!LF!!LF!*edpnet DNS
for /F "delims=" %%f in ('nslookup vidzi.tv 212.71.0.33') do (
 set output=!output!!LF!%%f
)
set output=!output!!LF!!LF!*google DNS
for /F "delims=" %%f in ('nslookup vidzi.tv 8.8.8.8') do (
 set output=!output!!LF!%%f
)

::output to screen and append to log file
echo !output!
echo !output!!LF!!LF!!LF!!LF! >> "!log!"

::Keep window open
cmd /k

输出的顺序有点有序,但有一堆****wo 23/12/2015 9:46:18,94 -- NSLOOKUP from anywhere with DNS server from edpnet**** Non-authoritative answer: Non-authoritative answer: Non-authoritative answer: Non-authoritative answer: Non-authoritative answer: Non-authoritative answer: ****do 24/12/2015 14:49:32,90 -- NSLOOKUP from anywhere with DNS server from edpnet**** **youtube.com *edpnet DNS Server: dns01.edpnet.net Address: 212.71.0.33 Name: youtube.com Addresses: 2a00:1450:4013:c00::5d 173.194.65.190 173.194.65.136 173.194.65.93 173.194.65.91 *google DNS Server: google-public-dns-a.google.com Address: 8.8.8.8 Name: youtube.com Addresses: 2a00:1450:400c:c07::5b 85.234.204.215 85.234.204.236 85.234.204.251 85.234.204.226 85.234.204.237 85.234.204.211 85.234.204.245 85.234.204.230 85.234.204.241 85.234.204.222 85.234.204.221 85.234.204.207 85.234.204.249 85.234.204.219 85.234.204.234 **bestofyoutube.com *edpnet DNS Server: dns01.edpnet.net Address: 212.71.0.33 Name: bestofyoutube.com Address: 104.238.110.149 *google DNS Server: google-public-dns-a.google.com Address: 8.8.8.8 Name: bestofyoutube.com Address: 104.238.110.149 **vidzi.tv *edpnet DNS Server: dns01.edpnet.net Address: 212.71.0.33 Name: vidzi.tv Addresses: 46.17.100.122 46.28.202.183 82.115.15.12 *google DNS Server: google-public-dns-a.google.com Address: 8.8.8.8 Name: vidzi.tv Addresses: 82.115.15.12 46.28.202.183 46.17.100.122 出现在顶部,而不是在日志文件中。它们似乎没有附加到输出变量。

程序是否在订单后执行而不等待它完成?这似乎是异步行为。

1 个答案:

答案 0 :(得分:1)

标准输出消息有 stdout ,错误消息有 stderr

Non-authoritative answer是写入 stderr 的错误消息。

默认情况下,只为 stdout 发送消息, 进程命令

可能更容易using command redirection operators并将 stdout stderr 直接重定向到日志文件,而不是收集环境变量中的所有消息行,最后写入环境变量的值为日志文件。

但是,使用2>&1 for 循环中将 nslookup stderr 重定向到 stdout 使用^转义尖括号和&符号以将2>&1应用于 nslookup 而不是命令将解决您的问题。

@echo off
:: script global variables
set log=nslookup-tests.log

::Logic
set LF=^



REM The two empty lines above are required!!

set output=****%date% %time% -- NSLOOKUP from anywhere with DNS server from edpnet****
setlocal EnableDelayedExpansion

set output=!output!!LF!!LF!!LF!**youtube.com
set output=!output!!LF!!LF!*edpnet DNS
for /F "delims=" %%f in ('nslookup youtube.com 212.71.0.33 2^>^&1') do (
    set output=!output!!LF!%%f
)
set output=!output!!LF!!LF!*google DNS
for /F "delims=" %%f in ('nslookup youtube.com 8.8.8.8 2^>^&1') do (
    set output=!output!!LF!%%f
)

set output=!output!!LF!!LF!!LF!**bestofyoutube.com
set output=!output!!LF!!LF!*edpnet DNS
for /F "delims=" %%f in ('nslookup bestofyoutube.com 212.71.0.33 2^>^&1') do (
    set output=!output!!LF!%%f
)
set output=!output!!LF!!LF!*google DNS
for /F "delims=" %%f in ('nslookup bestofyoutube.com 8.8.8.8 2^>^&1') do (
    set output=!output!!LF!%%f
)

set output=!output!!LF!!LF!!LF!**vidzi.tv
set output=!output!!LF!!LF!*edpnet DNS
for /F "delims=" %%f in ('nslookup vidzi.tv 212.71.0.33 2^>^&1') do (
    set output=!output!!LF!%%f
)
set output=!output!!LF!!LF!*google DNS
for /F "delims=" %%f in ('nslookup vidzi.tv 8.8.8.8 2^>^&1') do (
    set output=!output!!LF!%%f
)

::output to screen and append to log file
echo !output!
echo !output!!LF!!LF!!LF!!LF! >> "!log!"

::Keep window open
%SystemRoot%\System32\cmd.exe /k

以下是您的代码将 stderr stdout 直接重定向到日志文件。

@echo off
:: script global variables
set "log=nslookup-tests.log"

(
    echo ****%date% %time% -- NSLOOKUP from anywhere with DNS server from edpnet****
    echo.
    echo.
    echo **youtube.com
    echo.
    echo *edpnet DNS
    %SystemRoot%\System32\nslookup.exe youtube.com 212.71.0.33
    echo *google DNS
    %SystemRoot%\System32\nslookup.exe youtube.com 8.8.8.8

    echo.
    echo **bestofyoutube.com
    echo.
    echo *edpnet DNS
    %SystemRoot%\System32\nslookup.exe bestofyoutube.com 212.71.0.33
    echo *google DNS
    %SystemRoot%\System32\nslookup.exe bestofyoutube.com 8.8.8.8

    echo.
    echo **vidzi.tv
    echo.
    echo *edpnet DNS
    %SystemRoot%\System32\nslookup.exe vidzi.tv 212.71.0.33
    echo *google DNS
    %SystemRoot%\System32\nslookup.exe vidzi.tv 8.8.8.8
    echo.
) >"%TEMP%\%log%" 2>&1

rem Output to screen and append new log to previous log.
type "%TEMP%\%log%"
type "%TEMP%\%log%">>"%log%"
del "%TEMP%\%log%"

::Keep window open
%SystemRoot%\System32\cmd.exe /k