Windows批处理文件有哪些不太为人所知,但很重要和有用的特性?
指南:
每个答案一个特征 给出特性的简短描述和示例,而不仅仅是文档链接 将答案限制在本地功能,即不需要额外的软件,如Windows资源包
澄清:这里我们指的是由cmd.exe处理的脚本,这是WinNT变体的默认值。
(请参见:Windows批处理文件:.bat vs .cmd?)
Windows批处理文件有哪些不太为人所知,但很重要和有用的特性?
指南:
每个答案一个特征 给出特性的简短描述和示例,而不仅仅是文档链接 将答案限制在本地功能,即不需要额外的软件,如Windows资源包
澄清:这里我们指的是由cmd.exe处理的脚本,这是WinNT变体的默认值。
(请参见:Windows批处理文件:.bat vs .cmd?)
当前回答
softwarejedi已经提到了for命令,但我将再次提到它,因为它非常强大。
下面以YYYYMMDD格式输出当前日期,我在生成备份目录时使用此格式。
for /f "tokens=2-4 delims=/- " %a in ('DATE/T') do echo %c%b%a
其他回答
稍后可以使用call对名称求值,从而得到一些有用的属性。
call set SomeEnvVariable_%extension%=%%%somevalue%%%
使用调用来设置名称依赖于其他变量的变量。如果与某些变量命名规则一起使用,则可以通过使用谨慎的命名规则来模拟数组或字典等数据集合。somevalue周围的三个%是这样的,它将在调用之后和调用set之前计算为一个变量名,周围是一个%。这意味着一行中的两个%转义为一个%字符,然后它将再次展开它,因此somevalue实际上是一个名称指针。
call set TempVar=%%SomeEnvVariable_%extension%%%
将它与一个临时变量一起使用以检索值,然后可以在逻辑中使用该值。这在与延迟变量展开一起使用时非常有用。
要正确使用此方法,需要启用延迟变量扩展。因为它在默认情况下是关闭的,所以最好在脚本中启用它,将其作为第一个指令之一:
setlocal EnableDelayedExpansion
批处理脚本最常见的需求之一是记录生成的输出,以供以后检查。是的,您可以将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')
在脚本中使用命令扩展shell选项时,强烈建议您在脚本开始时执行以下技巧。
——从http://www.ss64.com/nt/setlocal.html粘贴的信息
如果给定一个参数,SETLOCAL将设置一个ERRORLEVEL。如果给出两个有效参数中的一个,它将为0,否则为1。 你可以在批处理文件中使用它来确定命令扩展名是否可用,使用以下技术:
VERIFY errors 2>nul
SETLOCAL ENABLEEXTENSIONS
IF ERRORLEVEL 1 echo Unable to enable extensions
这是因为“VERIFY errors”将ERRORLEVEL设置为1,然后如果扩展不可用(例如,如果脚本在command.com下运行),SETLOCAL将无法重置ERRORLEVEL值。 如果命令扩展被永久禁用,那么SETLOCAL ENABLEEXTENSIONS将不会恢复它们。
通过使用CALL, EXIT /B, SETLOCAL和ENDLOCAL可以实现带有局部变量的子例程。
例子:
@echo off
set x=xxxxx
call :sub 10
echo %x%
exit /b
:sub
setlocal
set /a x=%1 + 1
echo %x%
endlocal
exit /b
这将打印
11
xxxxx
尽管:sub修改了x。
我发现你可以轻松地将命令输出重定向到文件中非常有用:
DIR *.txt > tmp.txt
DIR *.exe >> tmp.txt
单箭头创建或覆盖文件,双箭头追加文件。现在我可以在我的文本编辑器中打开tmp.txt,做各种各样的事情。