【发布时间】:2016-10-21 23:52:29
【问题描述】:
我有一个列出所有服务的批处理脚本,采用 BINARY_PATH,删除任何包含 c"\windows" 的行并提供 BINARY_PATHS 列表。
我们的想法是将该列表传递给 ICACLS,以确定对每个可执行文件设置的权限。
我遇到的问题是一些 BINARY_PATHS 包含前导和尾随“。 所以我不得不通过在我的 for /f 语句中添加 delims=" 来解决这个问题。
下面是输出到 ECHO 的批处理文件
for /f "tokens=2" %%n in ('sc query state^= all ^| findstr SERVICE_NAME') do (
for /f "delims=: tokens=1*" %%r in (
'sc qc "%%~n" ^| findstr BINARY_PATH_NAME'
) do (
for /f tokens^=1-2^ delims^=^" %%x in ('echo %%~s^| findstr /V /I "c:\windows\system32"') do (
echo "%%~x%%~y"
)
)
)
ECHO 输出如下 - 一个很好的干净列表,它看起来与前导空格分开
" C:\Windows\Microsoft.NET\Framework\v2.0.50727\aspnet_state.exe"
" C:\Windows\Microsoft.NET\Framework\v2.0.50727\mscorsvw.exe"
" C:\Windows\Microsoft.Net\Framework\v3.0\WPF\PresentationFontCache.exe"
" C:\Windows\Microsoft.NET\Framework\v3.0\Windows Communication Foundation\infoc
ard.exe"
" C:\Windows\Microsoft.NET\Framework\v3.0\Windows Communication Foundation\SMSvc
Host.exe"
" C:\Program Files\Photodex\ProShow Producer\ScsiAccess.exe"
" C:\Windows\servicing\TrustedInstaller.exe"
" C:\Program Files\VMware\VMware Tools\vmtoolsd.exe"
当我尝试将输出传递给不带前导和尾随 " 的 icacls 时,它会崩溃,因为某些 PATH 中有空格。
ICACLS 批处理文件:
for /f "tokens=2" %%n in ('sc query state^= all ^| findstr SERVICE_NAME') do (
for /f "delims=: tokens=1*" %%r in (
'sc qc "%%~n" ^| findstr BINARY_PATH_NAME'
) do (
for /f tokens^=1-2^ delims^=^" %%x in ('echo %%~s ^| findstr /V /I "c:\windows\system32"') do (
icacls %%~x%%~y
)
)
)
ICACLS 批处理的一些输出:
C:\Windows\Microsoft.Net\Framework\v3.0\WPF\PresentationFontCache.exe NT SERVICE
\TrustedInstaller:(F)
BUILTIN\Ad
ministrators:(RX)
NT AUTHORI
TY\SYSTEM:(RX)
BUILTIN\Us
ers:(RX)
Successfully processed 1 files; Failed processing 0 files
Invalid parameter "Communication"
Invalid parameter "Communication"
Invalid parameter "Files\Photodex\ProShow"
C:\Windows\servicing\TrustedInstaller.exe NT SERVICE\TrustedInstaller:(F)
BUILTIN\Administrators:(RX)
NT AUTHORITY\SYSTEM:(RX)
BUILTIN\Users:(RX)
Successfully processed 1 files; Failed processing 0 files
Invalid parameter "Files\VMware\VMware"
有什么想法吗?
【问题讨论】:
-
最外面的
for /f循环使用变量%%n,最里面的循环也隐含地使用变量%%n,因为%%m和tokens=1-2选项;虽然它有效,但我建议对最内层循环使用不重叠的变量(例如,%%x,以及%%y)。要删除前导和尾随"",您不需要delims^=^"选项;只需声明for /f "delims=" %%x in ('echo %%~s') do echo %%~x(~修饰符删除引号)... -
问题更多的是前导和尾随空格而不是“”。
-
您的意思是前后双引号外部的前导/尾随空格?据我所见,
echo %%~s ^| findstr ...部分可以导致 trailing 空格,可以通过删除(转义)管道之前的空格来避免这种情况,例如echo %%~s^| findstr ...;我看不到 leading 空格的来源,但如果有,您可以通过for /F "tokens=*" %%l in (...) do echo %%l删除它们(记住默认分隔符 space 和 tab i>)... -
谢谢,抱歉我的解释可能不正确。如果您查看代码,我必须在输出周围添加“”以使其与 icacls 一起使用,此时有一个前导空格“c:\path\path\executable”
-
啊,我明白了!中间的
for /f循环是前导空格的来源;为避免这种情况,请将其更改为:for /f "tokens=1* delims=: " %%r;我只是交换了tokens和delims选项,并将 space 定义为最后一个分隔符(只有当它是选项字符串中的最后一个字符时,空格才被用作分隔符);这避免了前导空格并且可以工作,因为第一个标记本身不包含空格...
标签: batch-file for-loop cmd