Windows批处理文件有哪些不太为人所知,但很重要和有用的特性?

指南:

每个答案一个特征 给出特性的简短描述和示例,而不仅仅是文档链接 将答案限制在本地功能,即不需要额外的软件,如Windows资源包

澄清:这里我们指的是由cmd.exe处理的脚本,这是WinNT变体的默认值。

(请参见:Windows批处理文件:.bat vs .cmd?)


当前回答

批处理脚本最常见的需求之一是记录生成的输出,以供以后检查。是的,您可以将stdout和stderr重定向到一个文件,但是您无法看到发生了什么,除非您跟踪日志文件。

因此,考虑使用stdout/stderr日志记录工具运行您的批处理脚本,例如logger,它将使用时间戳记录输出,并且您仍然能够看到脚本进程。

另一个stdout/stderr日志记录实用程序

Yet another stdout/stderr logging utility [2010-08-05]
Copyright (C) 2010 LoRd_MuldeR <MuldeR2@GMX.de>
Released under the terms of the GNU General Public License (see License.txt)

Usage:
  logger.exe [logger options] : program.exe [program arguments]
  program.exe [program arguments] | logger.exe [logger options] : -

Options:
  -log <file name>  Name of the log file to create (default: "<program> <time>.log")
  -append           Append to the log file instead of replacing the existing file
  -mode <mode>      Write 'stdout' or 'stderr' or 'both' to log file (default: 'both')
  -format <format>  Format of log file, 'raw' or 'time' or 'full' (default: 'time')
  -filter <filter>  Don't write lines to log file that contain this string
  -invert           Invert filter, i.e. write only lines to log file that match filter
  -ignorecase       Apply filter in a case-insensitive way (default: case-sensitive)
  -nojobctrl        Don't add child process to job object (applies to Win2k and later)
  -noescape         Don't escape double quotes when forwarding command-line arguments
  -silent           Don't print additional information to the console
  -priority <flag>  Change process priority (idle/belownormal/normal/abovenormal/high)
  -inputcp <cpid>   Use the specified codepage for input processing (default: 'utf8')
  -outputcp <cpid>  Use the specified codepage for log file output (default: 'utf8')

其他回答

前面已经提到了%~dp0部分,但实际上还有更多内容: ~之后的字符定义了提取的信息。 返回补丁文件名时不包含字母 D -返回驱动器号 P -返回路径 S -返回短路径 X -返回文件扩展名 如果你在c:\Temp\long dir name\文件夹中执行test.bat脚本,

@echo off
echo %0
echo %~d0
echo %~p0
echo %~dp0
echo %~x0
echo %~s0
echo %~sp0

您将得到以下输出

测验 c: \Temp\长目录名\ c:\Temp\长目录名\ 。bat c: \ Temp \ \ test.bat LONGDI ~ 1 1 \ \ Temp \ LONGDI ~

如果一个参数被传递到你的脚本中 测试c: \ temp \ mysrc \ test.cpp 同样的操作也可以用于%1变量。

但是%0扩展的结果取决于位置! 在批处理的“顶层”,它扩展到当前批处理文件名。 在函数(调用)中,它展开为函数名。

@echo off
echo %0
call :test
goto :eof

:test
echo %0
echo %~0
echo %~n0

输出是(批处理文件以myBatch.bat开始)

myBatch.bat
:test
:test
myBatch

基于行的执行

虽然在大多数情况下没有明显的好处,但当试图在运行时更新内容时,它会有所帮助。例如:

UpdateSource.bat

copy UpdateSource.bat Current.bat
echo "Hi!"

Current.bat

copy UpdateSource.bat Current.bat

现在,执行Current.bat会产生这样的输出。

HI!

注意,批处理执行是按行号进行的。如果基本行没有完全相同的行号,这样的更新可能会导致跳过或向后移动一行。

批处理脚本最常见的需求之一是记录生成的输出,以供以后检查。是的,您可以将stdout和stderr重定向到一个文件,但是您无法看到发生了什么,除非您跟踪日志文件。

因此,考虑使用stdout/stderr日志记录工具运行您的批处理脚本,例如logger,它将使用时间戳记录输出,并且您仍然能够看到脚本进程。

另一个stdout/stderr日志记录实用程序

Yet another stdout/stderr logging utility [2010-08-05]
Copyright (C) 2010 LoRd_MuldeR <MuldeR2@GMX.de>
Released under the terms of the GNU General Public License (see License.txt)

Usage:
  logger.exe [logger options] : program.exe [program arguments]
  program.exe [program arguments] | logger.exe [logger options] : -

Options:
  -log <file name>  Name of the log file to create (default: "<program> <time>.log")
  -append           Append to the log file instead of replacing the existing file
  -mode <mode>      Write 'stdout' or 'stderr' or 'both' to log file (default: 'both')
  -format <format>  Format of log file, 'raw' or 'time' or 'full' (default: 'time')
  -filter <filter>  Don't write lines to log file that contain this string
  -invert           Invert filter, i.e. write only lines to log file that match filter
  -ignorecase       Apply filter in a case-insensitive way (default: case-sensitive)
  -nojobctrl        Don't add child process to job object (applies to Win2k and later)
  -noescape         Don't escape double quotes when forwarding command-line arguments
  -silent           Don't print additional information to the console
  -priority <flag>  Change process priority (idle/belownormal/normal/abovenormal/high)
  -inputcp <cpid>   Use the specified codepage for input processing (default: 'utf8')
  -outputcp <cpid>  Use the specified codepage for log file output (default: 'utf8')

抽取随机的文本行

@echo off

:: Get time (alas, it's only HH:MM xM

for /f %%a in ('time /t') do set zD1=%%a



:: Get last digit of MM

set zD2=%zD1:~4,1%



:: Seed the randomizer, if needed

if not defined zNUM1 set /a zNUM1=%zD2%


:: Get a kinda random number

set /a zNUM1=zNUM1 * 214013 + 2531011

set /a zNUM2=zNUM1 ^>^> 16 ^& 0x7fff


:: Pull off the first digit

:: (Last digit would be better, but it's late, and I'm tired)

set zIDX=%zNUM2:~0,1%


:: Map it down to 0-3

set /a zIDX=zIDX/3


:: Finally, we can set do some proper initialization

set /a zIIDX=0

set zLO=

set zLL=""


:: Step through each line in the file, looking for line zIDX

for /f "delims=@" %%a in (c:\lines.txt) do call :zoo  %zIDX%  %%a


:: If line zIDX wasn't found, we'll settle for zee LastLine

if "%zLO%"=="" set zLO=%zLL%

goto awdun


:: See if the current line is line zIDX

:zoo


:: Save string of all parms

set zALL=%*


:: Strip off the first parm (sure hope lines aren't longer than 254 chars)

set zWORDS=%zALL:~2,255%


:: Make this line zee LastLine

set zLL=%zWORDS%


:: If this is the line we're looking for, make it zee LineOut

if {%1}=={%zIIDX%} set zLO=%zWORDS%


:: Keep track of line numbers

set /a zIIDX=%zIIDX% + 1

goto :eof




:awdun

echo ==%zLO%==


:: Be socially responsible

set zALL=

set zD1=

set zD2=

set zIDX=

set zIIDX=

set zLL=

set zLO=

:: But don't mess with seed

::set zNUM1=

set zNUM2=

set zWORDS=

Forfiles非常有用,例如,递归删除所有超过两天的文件

forfiles /D -2 /P "C:\Temp" /S /C "cmd /c del @path"