tracert 运行时批处理文件中的进度指示器

tracert 运行时批处理文件中的进度指示器

我有一个运行速度相当快的批处理文件,但有几个跟踪程序需要很长时间才能运行。我想找到一种方法来显示运行时正在发生某些事情(但不显示 tracert 结果)... 不必显示百分比或任何东西... 甚至只是一个覆盖的微调器( /-\| ),单个字符或只是一系列越来越长的“。”。不过诀窍是批处理文件需要基本上同时运行这两个,然后进度指示器在 tracert 完成时结束。

我看到过这个: https://stackoverflow.com/questions/14711188/batch-file-progress-spinning-wheel,但它似乎只在命令之间更新(而不是在单个命令仍在运行时进行多次更新)。

我还希望这是主批处理文件,而不是单独的文件(也不使用 Server 2003 或更高版本中尚未存在的任何第三方工具)。

可能不错,但怀疑是否真的可行...根据 tracert 当前所在的跳数显示更有限的进度(即:1/15、2/15、3/15)。(不需要接受答案,但对我来说会给你更多的超级答题者地位... ;)

答案1

@echo off
    setlocal enableextensions disabledelayedexpansion

    rem Assumming there is some kind of log where everything is being written
    set "logFile=output.txt"

    rem Variables we need
    rem .... a variable containing a carriage return for spinner output
    for /f %%a in ('copy "%~f0" nul /z') do set "CR=%%a"

    rem .... a lock file to be used as a indicator of file being written
    rem      we can use the same log file, but included just to handle the
    rem      case where there is no log file
    set "lockFile=%temp%\%~nx0.%random%%random%.lock"

    rem .... the spinner to show
    set "spin=/-\|"

    (   
        9>"%lockFile%" tracert 10.1.1.1 >> "%logFile%"
    ) | <nul >nul 2>&1 ( 
        cmd /v /q /c "for /l %%a in (0) do ( ping -n 2 localhost & set "spin=!spin:~1!!spin:~0,1!" & (( type nul >>"%lockFile%" )&&( del /q "%lockFile%" & exit )||( set /p"=Waiting !spin:~0,1!!CR!" >con  )))"
    )

一步一步解释(相同的代码,只是为了更好的屏幕阅读而分开)

@echo off
    setlocal enableextensions disabledelayedexpansion

    rem Assumming there is some kind of log where everything is being written
    set "logFile=output.txt"


    rem Variables we need
    rem .... a variable containing a carriage return for spinner output
    for /f %%a in ('copy "%~f0" nul /z') do set "CR=%%a"

    rem .... a lock file to be used as a indicator of file being written
    rem      we can use the same log file, but included just to handle the
    rem      case where there is no log file
    set "lockFile=%temp%\%~nx0.%random%%random%.lock"

    rem .... the spinner to show
    set "spin=/-\|"

    rem .... This set of variables just hold the code that will be used
    rem      for each of the steps. They can be removed and placed directly
    rem      in the code below, but as the same will be done by the parser
    rem      this will make documentation easier

    rem .... How we will wait forever until the traceroute process ends
    set "loop= for /l %%a in (0) do "

    rem .... How to include a wait state to save cpu.
    set "wait= ping -n 2 localhost "

    rem .... How to rotate the spinner to later show the correct element
    set "rotateSpin= set "spin=!spin:~1!!spin:~0,1!" "

    rem .... How to show the progress if the tracert is still working
    set "progress= set /p"=Waiting !spin:~0,1!!CR!" >con "

    rem .... How to check if the tracert has ended: Just try to append 
    rem      nothing to the lock file 
    set "check= type nul >>"%lockFile%" "

    rem .... What to do when the traceroute ends. To use the log file
    rem      insted of the generated lock, remember to remove the del
    rem      command, we do not want to delete the log
    set "atEnd= del /q "%lockFile%" & exit "

    rem And here everything is joined. The content of the variables is 
    rem replaced by the parser, generating the final command.

    rem A pipe is generated. The left part of the pipe (the generator)
    rem is the traceroute command, and the right part (the consumer) 
    rem is the code that will generate the spinner.

    rem The lock is hold by redirection of one of the user handles
    rem (here the handle 9 is used) if the left part of the pipe.
    rem When the traceroute command ends, the handle is released.

    rem The right part of the pipe just loops checking if the lock is 
    rem released and echoing the spinner if it has not. This code
    rem runs in a separate cmd instance.

    (   
        9>"%lockFile%" tracert 10.1.1.1 >> "%logFile%"
    ) | <nul >nul 2>&1 ( 
        cmd /v /q /c "%loop% ( %wait% & %rotateSpin% & (( %check% )&&( %atEnd% )||( %progress% )))"
    )

相关内容