中国DOS联盟

-- 联合DOS 推动DOS 发展DOS --

联盟域名:www.cn-dos.net 论坛域名:www.cn-dos.net/forum
DOS,代表着自由开放与发展,我们努力起来,学习FreeDOS和Linux的自由开放与GNU精神,共同创造和发展美好的自由与GNU GPL世界吧!

中国DOS联盟论坛
现在时间是 2026-08-03 16:32
中国DOS联盟论坛 » DOS批处理 & 脚本技术(批处理室) » [讨论]编程中发现一个奇怪的问题 查看 2,059 回复 26
楼 主 [讨论]编程中发现一个奇怪的问题 发表于 2008-07-19 18:32 ·  中国 江苏 苏州 电信
高级用户
★★
五星老土
积分 558
发帖 172
注册 2003-02-09 00:00
23年会员
UID 881
性别 男
来自 江苏
状态 离线
dos 提示符下键入

tasklist /nh /fi "imagename eq cmd.exe“


出现一个cmd进程

但键入下边的

for /f "tokens=*" %i in ('tasklist /nh /fi "imagename eq cmd.exe"') do echo %i


却出现二个cmd进程,难道运行for语句会瞬间多个进程? 我眼睛一眨不眨地盯着任务管理器看, 也没发现任务数有什么变化。

有谁能解释一番?
我怎么找不到一个比我注册日期早的人? 难道我是传说中的超级管理员? 其实我只是个潜水冠军而已.
2 发表于 2008-07-19 18:37 ·  中国 北京 朝阳区 联通
银牌会员
★★★
积分 1,287
发帖 634
注册 2007-05-02 15:06
19年会员
UID 87277
性别 男
来自 cmd.exe
状态 离线
For 需要另开一个CMD.
3 发表于 2008-07-19 18:49 ·  中国 湖北 武汉 联通
版主
★★★★★
积分 11,386
发帖 4,938
注册 2006-07-23 17:10
20年会员
UID 59080
状态 离线
Originally posted by knoppix7 at 2008-7-19 18:37:
For 需要另开一个CMD.

不是for语句要开一个CMD,是因为这里用到了for的 /F 参数,并且in后面的括号里面是单引号包围的命令,执行这个命令需要for命令另外开启一个CMD子进程来完成,完成之后子进程再把结果交给父进程,也就是执行for语句的这个CMD进程,所以这里出现了两个CMD进程。

其它的for命令是不需要另外开启子进程的。

执行下面这个命令的时候,可以在任务管理器看到两个进程
for /F %a in ('pause') do @echo.%a


下面这个命令执行之间稍微有点长,在这段时间里,我们看任务管理器的话,里面只有一个CMD进程,可以说明FOR命令是不一定产生子CMD进程的。
for /r C:\ %a in (*.exe) do @echo %a
本帖最近评分记录 (共 2 条) 点击查看详情
评分人分数时间
knoppix7 +5 2008-07-19 20:32
WANKOILZ +2 2008-07-20 10:24
4 发表于 2008-07-19 19:05 ·  中国 重庆 九龙坡区 电信
版主
★★★★★
积分 9,023
发帖 5,017
注册 2007-05-31 19:39
19年会员
UID 89899
性别 男
状态 离线
即使没有单引号包围的命令,也可能出现两个cmd.exe进程。
@echo off
for /f "usebackq" %%a in ("C:\test\a.txt") do echo %%a
pause
5 发表于 2008-07-19 20:31 ·  中国 北京 朝阳区 联通
银牌会员
★★★
积分 1,287
发帖 634
注册 2007-05-02 15:06
19年会员
UID 87277
性别 男
来自 cmd.exe
状态 离线
Originally posted by lxmxn at 2008-7-19 06:49 PM:

不是for语句要开一个CMD,是因为这里用到了for的 /F 参数,并且in后面的括号里面是单引号包围的命令,执行这个命令需要for命令另外开启一个CM ...


受教
6 发表于 2008-07-19 21:09 ·  中国 江苏 苏州 电信
高级用户
★★
五星老土
积分 558
发帖 172
注册 2003-02-09 00:00
23年会员
UID 881
性别 男
来自 江苏
状态 离线
那么如何才能用FOR 命令只产生一个CMD进程?

我本来的命令是这样写的 

for /f "tokens=2" %%i in ('tasklist /nh /fi "imagename eq cmd.exe"') do set pid=%%i
taskkill /f /fi "pid ne %pid%" /im cmd.exe


原意想取得当前批处理的PID, 把其他批处理杀死, 可惜人算不如天算啊。

当然如果我把当前批处理 TITEL test, 然后用判断 /fi "windowtitle eq test" 也可以达到目的,但别的批处理也可以加标题来骗过被杀啊。另外别的批处理还可以把 cmd.exe改名来躲避追杀。

我觉得这个问题很有趣,大家有啥好办法?
我怎么找不到一个比我注册日期早的人? 难道我是传说中的超级管理员? 其实我只是个潜水冠军而已.
7 发表于 2008-07-19 21:50 ·  中国 湖南 娄底 电信
银牌会员
★★★
积分 2,268
发帖 879
注册 2006-12-19 16:23
19年会员
UID 73968
性别 男
状态 离线
虽然开启了两个cmd进程,但是是有先后的,可以根据这个来结束想要结束的cmd进程。
致精致简!
8 发表于 2008-07-19 22:03 ·  中国 江苏 苏州 电信
高级用户
★★
五星老土
积分 558
发帖 172
注册 2003-02-09 00:00
23年会员
UID 881
性别 男
来自 江苏
状态 离线
Originally posted by 26933062 at 2008-7-19 09:50 PM:
虽然开启了两个cmd进程,但是是有先后的,可以根据这个来结束想要结束的cmd进程。


问题是如何取得当前CMD或者其他CMD的pid, 只有pid是唯一的,我写的代码用意也在此,可惜失败了。

因为我想杀死在这之前和之后的批处理,除了有意要保留的。
我怎么找不到一个比我注册日期早的人? 难道我是传说中的超级管理员? 其实我只是个潜水冠军而已.
9 发表于 2008-07-19 22:10 ·  中国 湖南 娄底 电信
银牌会员
★★★
积分 2,268
发帖 879
注册 2006-12-19 16:23
19年会员
UID 73968
性别 男
状态 离线
1


  1. @echo off
  2. for /f "tokens=2" %%i in ('tasklist /nh /fi "imagename eq cmd.exe"') do (
  3. call set pid=%%i %%pid%%
  4. )
  5. for /f "tokens=2" %%a in ("%pid%") do (
  6. echo 当前批处理 cmd 进程的 pid 是 %%a
  7. )
  8. pause
小楼一夜听春雨 2008-07-19 22:00
本帖最近评分记录 (共 1 条) 点击查看详情
评分人分数时间
quya +5 2008-07-19 22:48
致精致简!
10 发表于 2008-07-19 22:48 ·  中国 江苏 苏州 电信
高级用户
★★
五星老土
积分 558
发帖 172
注册 2003-02-09 00:00
23年会员
UID 881
性别 男
来自 江苏
状态 离线
9楼代码不错。

不过我想到实用还有段距离,只好再请教了。

1.如我前述,批处理可以改CMD名字来防止被杀死,怎么办?
2. 假如杀已经存在的批处理,这个好办,按你的办法把自己排除掉,在开始运行就把已经存在的批处理杀了。
3. 但接着调用一个友好批处理(简称友军),假定这个过程很快,其他批处理插不进来,然后除了自己和友军(友军负责主要任务),自己负责监视如有其他批处理执行,即杀无赦。 等友军执行完任务就把自己杀了,然后友军也退出运行。

思路:自己要执行一个循环,加上一定的延时, 因为循环无法自己终止,也不知道友军何时执行完任务,所以也无法定时自杀,只能等友军执行完任务杀死自己。加上延时是为了防止自己和友军的FOR语句产生的CMD进程被误杀,可以隔一段时间判断,如果另外的CMD还存在,说明基本上不是FOR语句产生的。 另外也不能误杀不是批处理的程序。

谢谢了。

[ Last edited by quya on 2008-7-19 at 11:09 PM ]
我怎么找不到一个比我注册日期早的人? 难道我是传说中的超级管理员? 其实我只是个潜水冠军而已.
11 发表于 2008-07-19 23:06 ·  中国 重庆 九龙坡区 电信
版主
★★★★★
积分 9,023
发帖 5,017
注册 2007-05-31 19:39
19年会员
UID 89899
性别 男
状态 离线
友军执行完任务以后杀死所有的批处理不就行了?
12 发表于 2008-07-19 23:13 ·  中国 江苏 苏州 电信
高级用户
★★
五星老土
积分 558
发帖 172
注册 2003-02-09 00:00
23年会员
UID 881
性别 男
来自 江苏
状态 离线
Originally posted by HAT at 2008-7-19 11:06 PM:
友军执行完任务以后杀死所有的批处理不就行了?


不允许在友军执行任务的时候有其他批处理中途执行, 所以等它执行完任务再杀已经迟了。友军干的事情可能被其他批处理偷窥了。
我怎么找不到一个比我注册日期早的人? 难道我是传说中的超级管理员? 其实我只是个潜水冠军而已.
13 发表于 2008-07-19 23:29 ·  中国 湖南 娄底 电信
银牌会员
★★★
积分 2,268
发帖 879
注册 2006-12-19 16:23
19年会员
UID 73968
性别 男
状态 离线
先执行友军再获得友军的pid 不就可以了?
致精致简!
14 发表于 2008-07-20 09:19 ·  中国 湖南 株洲 电信
金牌会员
★★★★
永远的学习者
积分 3,105
发帖 1,276
注册 2008-03-08 13:00
18年会员
UID 112398
性别 男
状态 离线
老土这是要研究杀木马吧?
批处理之家新域名:www.bathome.net
15 发表于 2008-07-20 18:52 ·  中国 江苏 苏州 电信
高级用户
★★
五星老土
积分 558
发帖 172
注册 2003-02-09 00:00
23年会员
UID 881
性别 男
来自 江苏
状态 离线
Originally posted by zw19750516 at 2008-7-20 09:19 AM:
老土这是要研究杀木马吧?


不是,其实这是加密批处理的一个思路。

批处理无论怎么转成EXE, 在临时目录总能找到 BAT文件, 我的思路是,把关键的批处理拷贝到一个特殊目录执行,比如 Internet 缓存文件夹,这种文件夹用资源管理器是看不见的, 只能用DOS看。

所以为了防止DOS下dir, copy, 就要把批处理杀死。就我经验来看,成功copy出临时释放的BAT, 手脚快点大概要2秒钟(不包括搜索的时间), 这个时间足够终止批处理了。

其他的我已经处理得差不多了,就只剩下这个不好办。
我怎么找不到一个比我注册日期早的人? 难道我是传说中的超级管理员? 其实我只是个潜水冠军而已.
论坛跳转: