如果我知道Windows中的行号,如何获取命令行输出片段?

时间:2013-06-24 10:37:50

标签: windows shell service command-line pipe

情景:

我正在尝试找出一种shell脚本方式(命令行方法)来查找某些特定Windows服务的状态。例如,我选择了Telnet服务,它处于禁用模式(从services.msc检查)并且不会进入sc query命令。

sc query state= all工作正常并向我提供了所有服务的列表(活动/非活动)。现在我的问题已经减少,以找到从Windows服务显示名称(输出管道)获取服务状态的方法。

我试过sc query state= all | find /N "Telnet"但是这只会给我搜索行号及其内容,而不是服务状态,因为该信息比显示名称提前2-3行(通过管道搜索并返回)

问题:

在Windows中是否有办法从行号位置管道输出?就像在我的情况下,如果在第182行找到telnet服务,给我从第0行到第187行的命令输出?

如果您有任何想法,请随时告诉我解决问题的更好方法。

非常感谢!!

5 个答案:

答案 0 :(得分:1)

这是使用批处理文件执行此操作的一种方法,尽管它不是一个非常优雅的解决方案。

@echo off
setlocal

set currentservice=""
set servicestate=""
sc query state= all > services.txt
for /f "delims=:; tokens=1,2" %%a in (services.txt) do call :findservice "%%a" "%%b"
del services.txt

echo %servicestate%

endlocal
goto :end

:findservice
if not %1 == "SERVICE_NAME" goto :findstate
set currentservice=%2
goto :end

:findstate
if not %1 == "        STATE              " goto :end
if not %currentservice% == " Telnet" goto :end
set servicestate=%2
goto :end

:end

它首先将sc query的结果写入临时文件(services.txt)。然后它使用for循环来处理该文件的每一行。

当找到以SERVICE_NAME开头的行时,它会将该名称的值保存在 currentservice 变量中。然后,当它找到以STATE开头的行时,如果 currentservice 变量设置为" Telnet",则会在 servicestate 中保存状态值变量。

所以在最后,你应该在 servicestate 变量中有某种状态(我在示例代码中回应)。这类似于" 4 RUNNING "" 1 STOPPED "。如果找不到Telnet服务,它将为空白。

请注意,由于sc查询输出的处理方式,代码中的空格都很重要。请特别注意,您尝试匹配的服务名称必须以空格开头。

这可能会有所改善,但至少它是一个开始。

答案 1 :(得分:1)

@dbenham编写了一个名为repl.bat的工具,可以在http://www.dostips.com/forum/viewtopic.php?f=3&t=3855

找到

以下面的方式使用它,它提供了一个进程和状态列表:

sc query | findstr "SERVICE_NAME STATE" | repl "SERVICE_NAME..(.*)\r\n" "$1" m  | repl "(.*) *STATE.*:....(.*)." "$2 - $1"

这是Win 8 Pro 32位

下的输出示例

RUNNING - wcncsvc
跑步 - WdiServiceHost
运行 - WinDefend
RUNNING - WinHttpAutoProxySvc
运行 - winmgmt
运行 - WPDBusEnum
跑步 - wscsvc

要获得包含服务和显示名称的所有服务的完整列表,可以在此处使用:

sc query state= all | findstr "DISPLAY_NAME: SERVICE_NAME STATE" | repl "SERVICE_NAME..(.*)\r\n" "$1" m  | repl "DISPLAY_NAME:.(.*)\r\n" " - $1" m | repl "(.*) *STATE.*: .  (.*)."  "$2 - $1"

其中提供了这样的列表:

RUNNING - WPDBusEnum - 便携式设备枚举器服务
RUNNING - wscsvc - 安全中心
停止 - WSearch - Windows搜索
STOPPED - WSService - Windows应用商店服务(WSService)
停止 - wuauserv - Windows Update
STOPPED - wudfsvc - Windows Driver Foundation - 用户模式驱动程序框架
停止 - WwanSvc - WWAN AutoConfig

答案 2 :(得分:1)

这是另一种方法。我采取了一些快捷方式,使它有点慢,但它应该在所有具有我期望的SC的Windows版本上运行。

@echo off
for /f "tokens=1,* delims=:" %%a in ('sc query state^= all ^| findstr "DISPLAY_NAME: STATE" ') do (
echo %%a|find "DISP">nul && set /p "=%%b : "<nul
echo %%a|find "STATE">nul && (set /p "=%%b"<nul&echo.)
)
pause

这是输出:

家庭安全:1停止了 便携式设备枚举器服务:4 RUNNING
安全中心:4运行中 Windows搜索:1 STOPPED
Windows应用商店服务(WSService):1 STOPPED
Windows Update:1 STOPPED
Windows Driver Foundation - 用户模式驱动程序框架:1 STOPPED
WWAN AutoConfig:1 STOPPED

答案 3 :(得分:1)

这里有一些代码可以在display_name行上方显示两行,假设您的查询匹配在display_name行中。

“%1”是您所追求的服务名称 - 也使该术语成为唯一。

@echo off
set "n=-1"
sc query state= all |findstr /n "^" >Log.tmp
for /f "delims=:" %%a in (' findstr /i "%~1" ^<log.tmp ') do set n=%%a
set /a n=n+2
for /f "delims=" %%a in (' findstr /i "^%n%:" ^<log.tmp ') do set "line=%%a"
echo "%line%"
del log.tmp
pause

答案 4 :(得分:1)

PowerShell是一种选择吗?它内置于最近的Windows版本中,并将通过简单的命令获得您的服务状态。如果服务显示名称是Windows时间

get-service -DisplayName "windows time" | Select-Object Status