[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
返回列表 发帖

[讨论]如何判断cmd的echo 处于开启还是关闭状态?

这个问题在调试代码时比较有用,只是看似简单的问题,并不简单;
用for /f 抓取的并不是当前的环境,和doskey/h问题很相似。

不知大家有什么高招?(最好别生成临时文件)

菜鸟不知所云~~~~~:

TOP

回复 17# CrLf


神奇也~
我到for中的‘’是创建另一个进程来执行的也~
我一直以为是但单进程的也~

又长知识了~

TOP

回复 16# garyng


    for /f 从命令获取输入的时候,其实是将 (' ') 中的内容传递给 cmd /c,
  1. for /f "delims=" %%a in ('tasklist /nh /fi "imagename eq cmd.exe"') do echo %%a
  2. ::可以看到新开了一个 cmd 进程
  3. for /f "delims=" %%a in ('echo %%cmdcmdline%%') do echo %%a
  4. ::可以看到其命令行参数
复制代码

TOP

这个?
  1. for /f "delims=" %%i in ('echo') do (echo %%i)
复制代码
也会开多几个进程内!
为什么?

TOP

  1. echo
  2. @Echo off
  3. echo
  4. pause
  5. echo ------------------
  6. @echo on
  7. echo |findstr "打开"
  8. @echo off
  9. echo |findstr "关闭"
  10. pause
  11. echo ------------------
  12. @echo on
  13. echo >nul
  14. echo >nul 2>nul
  15. echo ------------------
  16. @echo off
  17. echo >nul
  18. echo >nul 2>nul
  19. pause
  20. echo ------------------
  21. @echo on
  22. echo &&echo ok
  23. echo||echo no
  24. echo ------------------
  25. @echo off
  26. echo &&echo ok
  27. echo||echo no
  28. pause
  29. echo ------------------
  30. @echo on
  31. echo |findstr "打开"
  32. echo 1
  33. echo |findstr "关闭"
  34. echo 2
  35. @echo off
  36. echo |findstr "打开"
  37. echo 3
  38. echo |findstr "关闭"
  39. echo 4
  40. pause
  41. echo ------------------
复制代码
寂寞是黑白的,但黑白不是寂寞,是永恒。BAT 需要的不是可能,而是智慧。

TOP

5# tmplinshi
程序具有很大局限性
比如下面的程序
虽然可能通过一定的代码构造大致解决这个问题
但这不是最佳的方案
  1. @echo off
  2. if "%1" == "echo" echo & exit
  3. echo on
  4. for /f "tokens=*" %%a in ('%0 echo') do set status=%%a
  5. set status
  6. pause
复制代码
最佳的方案仍然是临时文件(2楼的方案)
简单、有效并且适用面广
不明白楼主为何不看好这个方案
是否楼主也有非TMP的情结?
天的白色影子

TOP

12# zm900612
哪有如此复杂
简而言之
管道必然会开启新进程
扩展开来
管道是将后一个进程的输入句柄指向前一个进程的输出句柄
而对于内部命令来说
是不存在独立的操作句柄的
所以必然会启动其宿主程序cmd.exe
天的白色影子

TOP

'echo' 会开启一个新的 cmd.exe 进程来输出信息,是通过 cmd.exe /c echo 传递给 for 的。
但是并不等同于 'cmd /c echo',这样系统仍会处理成 cmd.exe cmd /c echo。

------------------------------------ ...
tmplinshi 发表于 2011-6-20 16:12


我原以为只有从语块中获取输入时才会启动新的cmd,现在看来应该是当管道前后存在内部命令或者管道中存在语块时会启动新的cmd,所以现在有了新的看法:
  1. @echo off
  2. echo|findstr 关闭
  3. ::等于cmd /c echo|findstr 关闭,启动了新cmd,所以echo始终处在打开回显的状态
  4. (tasklist)|find /i "cmd"
  5. ::当存在语块时,需要cmd来解释其语句的划分,所以启动了新cmd也是可以理解的
  6. tasklist|(find /i "cmd")
  7. ::同上
  8. (tasklist)|(find /i "cmd")
  9. ::这条证明了管道前后同时被预处理,并分别在不同的cmd中解释语句
  10. tasklist|find /i "cmd"
  11. ::都是外部命令,而且不存在语块,所以不启动新cmd
复制代码
1

评分人数

TOP

本帖最后由 tmplinshi 于 2011-6-20 17:52 编辑
for /f "tokens=2" %%1 in ('echo') do echo %%1
pause
mxxcgzxxx 发表于 2011-6-20 14:28


'echo' 会开启一个新的 cmd.exe 进程来输出信息,是通过 cmd.exe /c echo 传递给 for 的。
但是并不等同于 'cmd /c echo',这样系统仍会处理成 cmd.exe cmd /c echo

------------------------------------------------

不一定要 for 抓取吧?
findstr不就行了?
caruko 发表于 2011-6-20 12:28


我之前确实没有想到用 findstr。但刚才测试了一下,这样也会启动新的 cmd 进程。

经测试,如果是 echo a | echo b,系统会启动两个 cmd:
    cmd.exe /S /D /c" echo a "
    cmd.exe /S /D /c" echo b"

------------------------------------------------

以上结论是用 Process Monitor 监测到的。大家可以自己监测一下,打开软件后在“过滤器”里设置只监测 cmd.exe 进程。

TOP

  1. for /f "tokens=2" %%1 in ('echo') do echo %%1
  2. pause
复制代码
世界上没有学不会的知识,也没有想得到却做不到的事!

TOP

不一定要 for 抓取吧?
findstr不就行了?

TOP

这有什么实际意义吗?获取预处理的回显?

TOP

这个问题很好解决嘛
echo>1.txt
你打开1.TXT看到什么?
@echo off
echo>1.txt
你又看到了什么
。知道了吗???
ipqfhvk 发表于 2011-6-18 20:14


本以为说的是思路,原来这就是实际可行的代码,以前没有留意过单独的echo在判断回显是否开启时的用途,学习了!

TOP

if "%1" == "echo" echo & exit
for /f "tokens=*" %%a in ('%0 echo') do set status=%%a
set status
pause
tmplinshi 发表于 2011-6-19 13:54


漂亮!

TOP

返回列表