Board logo

标题: [文本处理] 【已解决】批处理如何利用findstr查询其他命令的输出并打印结果? [打印本页]

作者: we212320    时间: 2022-9-2 19:22     标题: 【已解决】批处理如何利用findstr查询其他命令的输出并打印结果?

本帖最后由 we212320 于 2022-9-7 11:18 编辑

需求:启动某个cmd命令后(命令持续运行),检查它的输出,若包含successful,则提示启动成功。
尝试1:
  1. start /B startup.cmd | findstr "successful" && echo started!
复制代码
;但并没有输出started!,似乎findstr仍在读取命令的输出;
尝试2:
  1. for /F %%t in ('start /B startup.cmd ') do (echo %%t | findstr "successfully"  && echo started! && goto next )
  2. :next
复制代码
,仍然没有输出started! 或者改为
  1. for    /F  "usebackq" %%t in (`start /B startup.cmd`)
复制代码
推测: 问题可能出在
  1. start /B
复制代码
上, 它使得cmd命令在当前窗口中运行,而一直未结束,所以一直在进行findstr ; 第2种尝试中cmd命令并没有启动 ;
请大佬帮忙指点,如何解决,或者更换其它思路。我并不希望把cmd输出重定向到文件中,然后在通过findstr去查找文件,因为cmd输出到successful所在行需要是时间不确定(尽管大约15s内)
作者: flashercs    时间: 2022-9-3 13:38

  1. call startup.cmd | findstr "successful" && echo started!
复制代码

作者: we212320    时间: 2022-9-3 19:46

本帖最后由 we212320 于 2022-9-3 19:51 编辑

回复 2# flashercs
  1. @echo off
  2. set MYSQL_HOME=D:\mysql
  3. start /B %MYSQL_HOME%\bin\mysqld --defaults-file="%MYSQL_HOME%\my.ini" && echo mysql started!
  4. set EOS_HOME=D:\eos82-dev1
  5. ::start /D %EOS_HOME%\nacos\bin /B startup.cmd | findstr "successful"   && echo Nacos started!
  6. pushd %EOS_HOME%\nacos\bin
  7. call startup.cmd | findstr "successful" && echo Nacos started!
  8. echo Done!
  9. pause
复制代码
这样的结果和上面注释掉命令效果一致,都不会输出Nacos started和Done; 命令似乎仍然在执行findstr ; 但是可以输出mysql started!。因此我去掉findstr 命令,使用call cmd时,仍未输出Nacos started和Done,但通过start /b 可以输出。 但我想通过successful标记来判断应用是否真的启动成功,而非命令执行的成功。(startup.cmd中最终启动的是一个java进程)
作者: flashercs    时间: 2022-9-3 21:17

本帖最后由 flashercs 于 2022-9-3 21:19 编辑
  1. 2>&1 start /D %EOS_HOME%\nacos\bin /B %comspec% /c startup.cmd | findstr "successful"   && echo Nacos started!
复制代码

作者: we212320    时间: 2022-9-4 00:34

本帖最后由 we212320 于 2022-9-4 00:49 编辑

回复 4# flashercs


    仍然未能生效。我写了下面一个示例:a.bat会输出1到5,然后pause代表一直运行;b.bat启动a.bat并查找字符串“2”并打印success;结果是“2”打印出来了,但success未能打印;因此我推测findstr仍然在执行中,它在期待下一个匹配。如果a.bat中没有pause,那么结果如我期望的那样输出正常,但实际上我要启动的服务是一直运行中。那么有没有能够匹配一次后就结束的命令来替换findstr呢?
a.bat
  1. @echo off
  2. for /l %%i in (1,1,5) do (echo %%i  )
  3. pause
复制代码
b.bat
  1. @echo off
  2. 2>&1 start /b %comspec% /c a.bat | (findstr "2" && echo success)
  3. echo Done!
  4. pause
复制代码

作者: we212320    时间: 2022-9-4 01:02

回复 4# flashercs


   将b.bat稍作改造,虽然能够输出success,但不能够输出Done,似乎没有运行goto,哪怕是把goto换作exit
  1. @echo off
  2. start /b %comspec% /c a.bat | find "2" |  (echo success &  goto next)
  3. :next
  4. echo Done!
  5. pause
复制代码

作者: xczxczxcz    时间: 2022-9-4 20:40

姿势不对, start 会另起窗口。 start /b 另起窗口后会把原来的窗口丢掉。所以你得不到数据。把 start /b 写到 a.bat  内部去。

还有 bat 与 bat 之间数据传递和变量延迟处理。 不需要用 find/findstr 那么 low 的方式, 直接获取所调bat 的回调数据,然后判断。
作者: we212320    时间: 2022-9-5 22:19

本帖最后由 we212320 于 2022-9-5 22:24 编辑

回复 7# xczxczxcz



    我并不想去修改 a.bat ,因为在实际业务中,这是由外部提供的,我只能启动它并检查它的结果是否正常。
另外不使用findstr有什么其他的命令吗?获取bat回调数据是需要什么操作呢?希望是在BAT命令范围之内,否则已经不那么简易,因为我可以人工去判断是否启动正常;恭候。。。
作者: flashercs    时间: 2022-9-6 10:46

批处理 "b.bat":缺点是 如果找到success后, a.bat 不退出,那么 b.bat 也不会退出.
  1. @echo off
  2. cd /d "%~dp0"
  3. start "title" /b %comspec% /c a.bat >aa.txt
  4. for /l %%I in (0,1,5) do (
  5.   findstr "success" aa.txt && goto next
  6.   >nul timeout /t 2
  7. )
  8. echo failed
  9. :next
  10. echo Done.
  11. pause
  12. exit /b
复制代码

作者: we212320    时间: 2022-9-7 10:47

回复 9# flashercs


    是的,事实确实是这样a.bat不退出,则b.bat不退出。 但我还是有些疑问,如我在6楼中的代码示例,为何已经输出success不能够执行goto ,我并没有退出b.bat ;同样,为什么将a.bat的输出重定向到文件中就可以继续往下执行了?答案可能正是使用了管道符的问题,管道内命令执行完毕才会执行下一行,哪怕管道内的命令主动退出
  无论如何,感谢!~




欢迎光临 批处理之家 (http://bbs.bathome.net/) Powered by Discuz! 7.2