标题: [数值计算] 批处理怎样实时传递参数? [打印本页]
作者: bluewing009 时间: 2011-6-9 19:28 标题: 批处理怎样实时传递参数?
比如:计数bat- :beginrem 其他命令set /a n1+=1goto begin
复制代码
想由一个a.bat调用上面的计数bat并能实时将n1数据传回给a.bat显示
我的思路:新建一个临时文件或者环境变量,通过这个来实时获取
作者: CrLf 时间: 2011-6-9 19:35
不必使用临时文件,可以利用exit /b命令传递
a.bat:- set start=%time%
- ping /n 2 localhost >nul
- ::要执行的命令
- call b.bat %time%
- echo 间隔为%errorlevel%
- pause
复制代码
b.bat:- set /a 间隔=%1-%start%
- ::计时函数我就不写了哈
- exit /b %间隔%
- ::exit /b后跟数字时,将以%errorlevel%变量的形式传递回父进程
复制代码
作者: bluewing009 时间: 2011-6-9 19:42
2# zm900612
e 倒是忘了 exit /b 了
不过,
call 不是等待结束后才继续运行么?
其实我想做个类似于多进程的东西.....可能语言表述不是很好
由a.bat启动分配需要执行的命令(echo 出b.bat c.bat 等等),然后调用这些“子bat”,由a.bat实时查看各自的进度
先谢谢你提醒关于exit /b的提示,以前都是模糊的用exit 学的不深入啊,,,,
作者: CrLf 时间: 2011-6-9 19:53
多进程可以不需要分配多个bat,简单提供一个思路:- @echo off
- %*
- for %%a in (ping dir move findstr) do start /b "" "%0" goto %%a
- pause&exit
-
- :ping
- ping localhost
-
- :dir
- dir c:\
-
- :move
- move %0 %tmp%
-
- :findstr
- findstr "^:" %0
- rem 以上为各个模块,执行完毕后再call :计时
-
- :计时
- rem 省略
- exit /b %间隔%
复制代码
作者: bluewing009 时间: 2011-6-9 20:02
4# zm900612
主要关心的是如何做到主监视子的问题(或者说是全局变量):如果我举的例子不明显的话,比如,由a启动b(已经写好),b每执行完一个命令,a显示+1
作者: CrLf 时间: 2011-6-9 20:05
那好像没特别好的办法了...
无非临时文件、tasklist计算cmd进程数、环境变量等等
作者: bluewing009 时间: 2011-6-9 20:17
6# zm900612
比如说,环境变量,哪个bat都能使用的,但是自己set一个值,另一个就不能获取了。所以我原本的思路就是借助临时文件或者自定义一个环境变量,这样效率上有问题,特别是临时文件…………有没有什么变量像环境变量一样“共享”?
作者: CrLf 时间: 2011-6-9 20:41
忽然想起来,qzw好像说过环境变量是cmd启动时从explorer获取的,所以启动之后应该不接受新的环境变量了吧?没试过,不知道
至于别的方法,虽然有,不过我知道的方法都不如临时文件
作者: bluewing009 时间: 2011-6-9 22:01
8# zm900612
临时文件的话需要实时读写,效率不高,关于环境变量,记得用wmic可以立即生效的,原先发帖时记得搜索过,关键字“环境变量”。
作者: qzwqzw 时间: 2011-6-9 23:17
Windows应用程序的环境变量(包括cmd.exe)继承自创建它的父进程
并继续传递给它创建的子进程
wmic可以改变全局变量
但是其效率甚至不如临时文件
因为它要写注册表
并且广播窗口消息到所有窗口
其它能够改变全局变量的方法无不类似
作者: bluewing009 时间: 2011-6-10 00:12
10# qzwqzw
请问你有什么好办法呢?另,为什么说不如临时文件?如果是临时文件作计数用岂不是要实时读写硬盘?
作者: caruko 时间: 2011-6-10 01:06
临时文件也不是很好,因为多个进程访问同一个文件会出现IO错误。
我一般是用 AT 命令来设置不会被执行的命令,顺便把需要传递的值带过去。
如,b.bat
写入 at 1:00 /next:%date:-2% @b.bat@var1@var2@var3.....
a.bat
读取 for /f "tokens=1,2* delims=@" %%a in ('at') do set 来自%%b的值=%%c
还有一个办法,wmic监视事件日志中指定事件ID的日志消息。
然后B.BAT执行添加日志操作命令 "eventcreate" ,具体用法可eventcreate /?
作者: qzwqzw 时间: 2011-6-10 21:38
wmic由于自身的机制启动将会很慢
与setx.exe作对比测试了一下
wmic environment耗时是wmic的两倍多
临时文件的性能其实并没有你想象的那么不堪
性能是wmic environment的数百倍
当然如果你考虑到共享冲突而无法选择此方案
还可以选择用Reg add/query操作注册表
它的性能是wmic environment的10+倍
作者: cjiabing 时间: 2011-6-11 10:37
12# caruko
你小子想像力超人啊!at都想得出来!难能可贵!
前阵子和某某谈过这个话题,不过也没更好的方法。
好像我做过试验,用title也可以解决问题,将数据实时写到窗口标题,然后使用tasklist提取。这个tastlist可以在需要时提取,也可以使用start /b实时监视。
这个我还是比较熟练,但手机无法提供例子。
作者: bluewing009 时间: 2011-6-11 20:22
13# qzwqzw
注册表项!感觉这个要好一些,从上面各位朋友的回答来看,都是用一个文件或者某个标志作为计数器,这样的话,子进程要实时读写这个标记,主进程也要实时读取这个标记,都在一直占用资源。总感觉还是不怎么好,最好是能够传递……不知道怎么说好…………就是说,子进程执行一条命令后,告诉主进程,没通知就等待,就是有点像中断……呼呼……不知道这样说能不能解释清楚
作者: caruko 时间: 2011-6-12 16:22
TITLE 的办法有想过,但一时没想到tasklist 可以提取。
这也的确是个办法,但是同步问题不好解决,因为title没有缓存,读取的内容可能在2次读取的时间断中,被新的数据覆盖了,导致部分丢失。
作者: qzwqzw 时间: 2011-6-12 16:49
是的
注册表项读写实质上也是文件读写
与临时文件不同的地方就是
不需要理会文件句柄的打开和关闭
楼主说的应该是类似于Windows消息和事件触发的机制
这只有自行设计命令行程序才能实现了
作者: mxxcgzxxx 时间: 2011-6-14 11:08
可以用doskey啊生成命令在另一个批处理中执行获取参数,应该非常快吧!
示范下,不过我只在自己内部调用意思下,
doskey 调定的是全局命令不关机都不会消失- @echo off
- 1:
- set /p a=猜猜我是谁:
- if %a%==5 doskey aaa=set bbb=你真厉害啊 $*
- aaa
- echo %bbb%
- pause>nul
- doskey aaa=
- goto 1:
复制代码
作者: qzwqzw 时间: 2011-6-14 21:22
18# mxxcgzxxx
不知楼上是如何测试的?
doskey的宏只能在cmd当前进程中生效
在平行的cmd.exe进程中是相互独立的
那如何实现cmd进程间的通讯呢?
设想可以通过进程互斥子的方式
实现共享内存式的进程通讯
但实现起来比较麻烦
已经脱离批处理比较远了
欢迎光临 批处理之家 (http://www.bathome.net/) |
Powered by Discuz! 7.2 |