同样,这里有很多事情需要注意。
if errorlevel
的帮助if
说:
IF [NOT] ERRORLEVEL number command
作为if errorlevel
条件的语法。也就是说,您必须提供一个数字进行比较。请记住,如果退出代码至少为n ,则if errorlevel n
计算结果为true 。
所以
if errorlevel 1 ...
捕获任何错误(通过退出代码发出信号),而
if errorlevel 0 ...
简单地说总是正确的。
无论如何,你可能想要一个
if not errorlevel 1 ...
在这里,因为如果没有发生错误,则该条件为真。
跳线
该for /f
命令有一个参数skip=n
,可用于在开始时跳过行。如果您的输出以您不想要的两行开头,那么您可以这样做
for /f "skip=2 tokens=1" %%Q in ('query termserver') do
迭代多个已知值for /f
您的第二个代码片段的问题是for
迭代line-wise。所以当你给它一个单一的环境变量时,它会对其进行标记(并将标记放入不同的变量中),但循环每行只运行一次。另请注意,set
在这里使用有点容易出错,因为您可能会得到比您想要的更多的回报。就像是
for /f ... in ("%TermServers%") ...
本来会更容易。尽管如此,这并不能解决最初的问题。解决此问题的最简单方法可能如下所示:
rem space-separated list of servers
set TermServers=Server1 Server2 Server3 Server7 Server8 Server10
rem call the subroutine with the list of servers
call :query_servers %TermServers%
rem exit the batch file here, to prevent the subroutine from running again afterwards
goto :eof
rem Subroutine to iterate over the list of servers
:query_servers
rem Process the next server in the list
rem Note the usage of %1 here instead of a for loop variable
echo Checking %1
for /f "tokens=1" %%U in ('query user %UserID% /server:%1') do (echo %%Q)
rem Remove the first argument we just processed
shift
rem if there is still another server to be processed, then do so
rem we're mis-using the subroutine label as a jump target here too
if not [%1]==[] goto query_servers
rem This is kind of a "return" statement for subroutines
goto :eof
(未经测试,但应该可以工作。)
ETA:哎呀,我又一次错过了最明显的答案:
set TermServers=Server1 Server2 Server3 Server7 Server8 Server10
for %%S in (%TermServers%) do (
for /f "tokens=1" %%U in ('query user %UserID% /server:%1') do (echo %%Q)
)
请注意,这很简单for
,不是 for /f
,它将尽职尽责地遍历值列表。我不知道我是怎么错过的,对不起。