无忧启动论坛

 找回密码
 注册
搜索
系统gho:最纯净好用系统下载站广告联系 微信:wuyouceo QQ:184822951
楼主: chenall
打印 上一主题 下一主题

grub4dos 外部命令 wenv [2010-10-17 ]

  [复制链接]
181#
发表于 2010-11-20 18:29:09 | 显示全部楼层
是的,跟以前的集合命令一样

括号的配对比较麻烦,没有一个好的办法区分,因为语法上没有强制要求字符串使用引号括起来

wenv (set a=() ; set b=2),a后面2个作为字符串的括正好配对,这句可以工作,如果作为字符的括号不配对,确定集合命令的结束处就会出错,如
wenv (set a=( ; set b=2)
wenv (set a=()) ; set b=2)
回复

使用道具 举报

182#
发表于 2010-11-20 18:37:02 | 显示全部楼层
换个角度,改变集合命令的标识符[[( sub1 ; sub2 )]]跟连接符一样,用复杂点的标识符尽可能降低与普通字符混淆的概率
回复

使用道具 举报

183#
发表于 2010-11-20 18:50:10 | 显示全部楼层
今天恢复集合命令处理方式后,在你没有使用 ]]* 连接符的菜单中,效果应该等效于16号以前的版本

噢,想起改变集合命令处方式后,loop的处理不同,忘了改回去
回复

使用道具 举报

184#
发表于 2010-11-20 23:10:01 | 显示全部楼层
增加了一个开关 EXT_SET 用于扩展集合命令界定符。开关为on时,集合命令将使用 ([[, ]]) 作为界定符,一定程度可以避免字符串中含界定符的问题(如必要,可以将这个开关扩展为自定义界定符)。

恢复分隔符为分号后,]]] 重用的判断问题没有了,for 后的集合命令也可以跟连接符,现在这样的写法是支持的
wenv (calc s=0 ; for /L %i in (1,1,100) do (set a=%i ; calc s=s+a ; calc a=a % 10 ; check $${a}==0 echo %i,s=$${s})) ]]] get

注意for命令里求余操作符后面必须有一个空格,否则跟for的参数冲突

以后 GetSect.bat,GParts.bat 作为两个标准批处理样本随wenv一起上传了,有需要的可以在此基础上改造为自己适用的批处理

[ 本帖最后由 tuxw 于 2010-11-20 23:14 编辑 ]

wenv-tuxw-2010-11-20.zip

55.17 KB, 下载次数: 22, 下载积分: 无忧币 -2

回复

使用道具 举报

185#
发表于 2010-11-21 00:30:37 | 显示全部楼层
原帖由 zhaohj 于 2010-11-20 23:35 发表
现在焦点在FOR命令,我想知道这个与以前的不同点。
wenv for /f "tokens=1-3 delims==," %i in ( file ) do (sub1) ]]& (sub2) ]]| (sub3) ]]! (sub4)
还是??
]]!是第一个sub1的不成功就执行,还是??


for的返回值取决于最后一次循环时sub1的返回值,前面条件不同、文件不同,这个返回值是无法确认的,应该尽量避免这种for后需要确定返回值的写法

]]& 很好记忆,从前往后,任一个连接命令不能继续下去时就跳到 ]]!
回复

使用道具 举报

186#
发表于 2010-11-21 10:54:13 | 显示全部楼层
@chenall

WENV set a=abc"def\
WENV check abc"def\==${a} echo ok

这两句在命令行可以,在批处理中出错(grldr版本11-18)。
要双写引号才可以通过,如果变量a是从文件中分离出来的,则批处理中这样的用法会出错


你的最新版好象没有 ]]] 符号了
WENV set a=5 ]]] get,后面的连接命令当成了串
WENV set a=abc"def\ ]]] get ,同上
WENV set a=abc"def\ ]]& get,同上

WENV set a=abc"def\     这样可以
WENV check abc"def\==${a} echo ok,出错
WENV check "abc"def\"=="${a}" echo ok,出错

试图将一个引号先替换成两个引号
WENV set a=${a!"=""} 出错,它自己又将两个引号换成一个引号了
WENV set a=${a!"=""""},替换成功
WENV check "abc""def\"="${a}" echo,失败

用双写引号的方法来识别引号为字符,只适合一次性的常量文本(好象HTML中是这样处理的),不适合二次变出来的字符串,比如PCI信息中,很多含有引号的行,截断后再来check会出错

[ 本帖最后由 tuxw 于 2010-11-21 11:03 编辑 ]
回复

使用道具 举报

187#
发表于 2010-11-21 12:54:42 | 显示全部楼层
分号一直就是可以这样用,不一定要在集合命令里,只是括起来语法结构明显些

WENV (set a=1 ; set b=2) ; (check ${a}==1 set c=3 ]]& get)
WENV (set a=1 ; set b=2) ]]] (check ${a}==1 set c=3 ]]& get)

效果一样的

[ 本帖最后由 tuxw 于 2010-11-21 12:58 编辑 ]
回复

使用道具 举报

188#
发表于 2010-11-22 00:37:22 | 显示全部楼层
1.调整了集合命令与连接符的处理方式
2.EXT_SET 开关自动切换,两种集合界定符可以混合嵌套
3.取消 call 别名 run
4.echo 换行改为 \r\n
5.命令行缓冲区增加到3K

EXT_SET开关为隐性(不在switch状态中显示)开关自动切换,两种集合界定符可以混合使用并嵌套,集合命令中可以使用分号以外的连接符

wenv ([[reset ; set a=) ; set b=1 ; check ${b}==1 (set c=2 ; echo ok) ]]| echo not ; calc 0]]) ]]& (get ; echo return 1) ]]! ([[get ; echo return 0]])

calc 0 这句将决定第一个大集合命令的返回值
a=) 不会影响配对检查,因为外面的界定符使用了扩展符号 ([[, ]]) 。

这个方式跟用引号避免界定符配对错各有特点。
用引号的方式可以少打几个字符,判断比较准确,缺点是字符串中使用引号不方便,常量可以手工输入两个引号,变量将导致整句出错。而且自动去掉引号会影响本来就需要引号的地方。
扩展界定符方式输入要麻烦,而且字符串中仍可能包含扩展的界定符(这种情况还是会出错),但避开了引号的问题,不含空格的任意串,都可以直接比较。

可以考虑将扩展符号自定义,如这样
wenv set SET_SIGN=<<<>>>
将这个变量一份为二,作为界定符,输入更可能输入更麻烦,但灵活性增加

连接符后面跟的必须是子命令或集合命令,否则被判为普通字符,如
wenv echo abc ]]& def,不是子命令,直接输出了
wenf echo abc ; 123,不是子命令,直接输出了

]]] 操作符保留,作用与分号相同。我个人更倾向于使用 ]]],保留 ; 纯粹是为了兼容。
]]] 需要5个字符相同(前后空格),才会被误判,而且增加了后跟子命令的限制后,误判的几率非常低。

[ 本帖最后由 tuxw 于 2010-11-22 00:56 编辑 ]

wenv-tuxw-2010-11-22.zip

54.98 KB, 下载次数: 19, 下载积分: 无忧币 -2

回复

使用道具 举报

189#
发表于 2010-11-22 01:04:11 | 显示全部楼层
@chenall

wenv set a=abc"def
这句在命令行可以执行(我编译的版本里),但批处理中报错error 28,写两个引号则可以,是否引号的处理策略已引入了grldr?
回复

使用道具 举报

190#
发表于 2010-11-23 00:13:16 | 显示全部楼层
这个问题是引号处理规则引起的,TXT里每行有一对引号,本来正好配对。但C大的版本里for命令是要去掉串两端的引号的,最后一个引号去掉号,单一的引号会导致错误。
另外这个例子较特殊,PCI最后一个字符\,原版里skip_to会跳过它也会导致引号出错。

我这样试了下,输出正常(TXT太长刷屏慢,加了个计数限制)

WENV calc cnt=0 ]]] for /F "eol=; tokens=1-2 delims=;" %i in ( /TXT ) do (check $${cnt}>=50 break ; set a=%i ; check "$${a:0:4}"=="PCI\" (calc cnt++ ; set b=%j ; echo -n $ ; echo $${a}==$${b}))

PCI\ 是不含空格的常量,这里实际上可以不加引号,前面必须加引号是为了防止变量里含有空格。

可以改变 cnt 条件,达到测试TXT不同段的目的

[ 本帖最后由 tuxw 于 2010-11-23 00:16 编辑 ]
回复

使用道具 举报

191#
发表于 2010-11-23 00:30:15 | 显示全部楼层
可能就是第二个原因 "PCI\",最后字符是\的问题,跟以前一样,在后面加个空格试试

=============================

loop/break 可以用在普通的集合命令里(作用相同,都是跳出集合命令)

这种结构
wenv (sub1 ; check 条件 (sub2 ; sub3))
可以这样代替
wenv (seub1 ; check 反条件 loop ; sub2 ; sub3)
这样少一次集合嵌套,出问题的几率降低
另外少一个集合,会少一次递归,运行速度也要快,系统负担要轻

[ 本帖最后由 tuxw 于 2010-11-23 00:55 编辑 ]
回复

使用道具 举报

192#
发表于 2010-11-23 16:01:08 | 显示全部楼层
原帖由 zhaohj 于 2010-11-23 14:36 发表
wenv set srspath=/SRS/OEM/
wenv set a=TXTSETUP.OEM
...

引号引起来的命令,让它只识别左边引号开始的第一个命令
...


这个是无谓的增加复杂性,应该这样用

wenv echo -e cat --length=0 ${srspath}${a} \x26\x26 FAT copy /o ${srspath}${a} (fd1)/  >> (fd2)/DRIVERS.BAT
回复

使用道具 举报

193#
发表于 2010-11-24 09:04:51 | 显示全部楼层
原帖由 chenall 于 2010-11-23 16:31 发表
@tuxw

   sprintf(buf, "--rd-base=0x%X", (unsigned int)p);
   builtin_cmd("map", buf, flags);
   sprintf(buf, "--rd-size=0x%X", strlen(p));
   builtin_cmd("map", buf, flags);

  由于有提供
  rd_base和rd_size变量,所以可以直接修改变量值就可以了

  rd_base = p;
  rd_size = strlen(p);


Grub4Dos现在对我来说太复杂了,我都没仔细看过那个头文件,有这两个变量直接使用就方便多了。

原帖由 chenall 于 2010-11-23 16:35 发表

有没有例子,我测试一下..
grub4dos很早的版本就有检测引号配对了.

压缩包中是一个  test.bat 和测试用的几个文本文件,放在iso的根目录下运行 test.bat
test.bat 中失败的语句前我加了注释

test.zip

28.78 KB, 下载次数: 20, 下载积分: 无忧币 -2

回复

使用道具 举报

194#
发表于 2010-11-24 12:59:09 | 显示全部楼层
原帖由 chenall 于 2010-11-24 10:44 发表

:两个引号通过,一个引号失败
WENV set a=abc""def\
WENV check abc""def\==${a} echo ok: check [${a}]

GRUB4DOS批处理其实是不管引号的。它是碰到回车符就截断,把这个命令丢给命令行去执行。

...

发的样本里是两个引号,运行正常的,将那两个引号改成一个引号就不正常了。不正常时在命令行运行这两句是正常的,应该不是check的原因。

下面是先批处理,再命令行运行的截图


@zhaohj
是的,我编译时只在wenv运行时清一次errnum,当时考虑的时,子命令设置了errnum肯定是出错了,应该退出。既然发现这个问题,我清一下好了。
事实上贸然清掉errnum是有负面影响的,比如read命令,中途碰到有命令设置errnum,就会中止执行,清掉errnum后这个特性将丧失,中途出错它也将继续执行下去,如果出错的是一个影响后续命令的关键条件,结果将不可预期。

是否清errnum只影响call内部命令,因为有些内部命令可以正常执行但会设置errnum,比如find没找到文件时,语法上命令是正常执行的,但它要设置errnum(我觉得这个应该只返回0就行了,errnum应该代表“出错”),还有map命令。

或者变更一下处理方式,只在call命令前后清掉errnum,这样就可以正常调用内部命令。

[ 本帖最后由 tuxw 于 2010-11-24 13:16 编辑 ]
回复

使用道具 举报

195#
发表于 2010-11-24 15:24:54 | 显示全部楼层
1.call 命令后清除 errnum
    wenv check 1=1 ]]] echo here                 # 前面语法错误,命令终止
    wenv call find /not_find_file ]]] echo here  # 会执行echo

2.echo 命令添加 -a 参数显示ASCII转义符
3.添加伪命令 echar 将最多3个字符转为转义符,可以直接用在字符串中
   
如果确实要显示 echar(*) 这样的字符
wenv switch dis_echar=on, 可以禁止这个转换特性

wenv-tuxw-2010-11-24.zip

55.63 KB, 下载次数: 38, 下载积分: 无忧币 -2

回复

使用道具 举报

196#
发表于 2010-11-24 21:39:02 | 显示全部楼层
楼主上管道命令有问题
回复

使用道具 举报

197#
发表于 2010-11-24 23:20:35 | 显示全部楼层
@zhaohj
用 wenv-tuxw-2010-11-24 测试了下你的 SRSF6模块,用法上有些细节问题,我修改了几个菜单,现在 TXT/SIF/OEM 都可以进到这个画面,再往后我就不懂了。

菜单的修改我是根据你的调用次序,改到了 makeoem.lst ,再往后的就没动了。



顺便加了个二值切换菜单实时显示



后面的列表方式、手动输入方式我没改过。太累了,我对 SRS 一点也不懂,调试这个很废劲。

[ 本帖最后由 tuxw 于 2010-11-24 23:25 编辑 ]

SRSF6.zip

92.24 KB, 下载次数: 17, 下载积分: 无忧币 -2

回复

使用道具 举报

198#
发表于 2010-11-24 23:31:11 | 显示全部楼层
原帖由 chenall 于 2010-11-24 22:36 发表

OK,一个地方没有改过来。
重新上传了。
grub4dos-0.4.5b-2010-11-24-fix2.zip

已经集成不点发布的版本补丁。


OK,现在 set a=abc"def\, check ... 的问题也通过了
回复

使用道具 举报

199#
发表于 2010-11-25 00:09:06 | 显示全部楼层
check %<-$${a}
for 里面的 % 作普通字符后面最好空一格
check % <-"$${a}" loop
不管a有没有空格,但它是变量,我们不知道,都给它加上界定符

set -e b=\x26\x26

现在可以用 echar(&&) 代替,直接用在echo命令中

[ 本帖最后由 tuxw 于 2010-11-25 00:11 编辑 ]
回复

使用道具 举报

200#
发表于 2010-11-25 00:32:08 | 显示全部楼层
#945这段在哪个文件中,我再测试一下

========================

已下载了 933# 附件,明天再测试
943# 我是在你11-09的基础上改的的 IMG,驱动目录用的是 11-24 的

[ 本帖最后由 tuxw 于 2010-11-25 00:51 编辑 ]
回复

使用道具 举报

201#
发表于 2010-11-25 08:53:36 | 显示全部楼层
这是个综合问题,不是单哪个语句的毛病,同样这个集合命令,搬到for这外是没有问题的(目前的版本跟11-15最大的区别就是扩展了连接符和集合命令),可能是 ]]& 与集合命令、for 配合的BUG引起的,但它一到这里就死机比较难跟踪。要请chenall来帮忙看看了。

#这句死机,可能连接符有BUG
#WENV for /f "tokens=3 delims==," %i in ( (fd1)/SYSINF ) do (set a=$u,%i ; check ".SY"<-"$${a}" ]]& (set a=$${a!.SYS=.SY_} ; echo -e cat --length=0 $${srspath}$${a} echar(&&) FAT copy /o $${srspath}$${a} (fd1)/)) >> (fd2)/DRIVERS.BAT

#下面这个可以,而且也是推荐的优化用法
WENV for /f "tokens=3 delims==," %i in ( (fd1)/SYSINF ) do (set a=$u,%i ; check ".SY"<-"$${a}" ]]| loop ; set a=$${a!.SYS=.SY_} ; echo -e cat --length=0 $${srspath}$${a} echar(&&) FAT copy /o $${srspath}$${a} (fd1)/) >> (fd2)/DRIVERS.BAT

#这个也可以(没有连接符)
#WENV for /f "tokens=3 delims==," %i in ( (fd1)/SYSINF ) do (set a=$u,%i ; check ".SY"<-"$${a}" (set a=$${a!.SYS=.SY_} ; echo -e cat --length=0 $${srspath}$${a} echar(&&) FAT copy /o $${srspath}$${a} (fd1)/)) >> (fd2)/DRIVERS.BAT

附件是我已经改好了

[ 本帖最后由 tuxw 于 2010-11-25 09:02 编辑 ]

SRSF6-test.zip

95.11 KB, 下载次数: 35, 下载积分: 无忧币 -2

回复

使用道具 举报

202#
发表于 2010-11-25 09:20:58 | 显示全部楼层
/ 是不会转义的,953#的附件就是用 -e 一次输出的

echar(*) 前后不需要有空格的,这样也可以
wenv echo abcechar(123)def

953#后面的两种写法替换都没问题呀

==================
如果路径中含\,就存在转义冲突问题

a=%i 的问题,这个要修改for命令,我再看看

[ 本帖最后由 tuxw 于 2010-11-25 09:36 编辑 ]
回复

使用道具 举报

203#
发表于 2010-11-25 09:46:50 | 显示全部楼层
试了下C大的版本,好象这个没有连接符的写法不支持了?
WENV for /f "tokens=3 delims==," %i in ( (fd1)/SYSINF ) do (set a=$u,%i ; check ".SY"<-"$${a}" (set a=$${a!.SYS=.SY_} ; echo -e cat --length=0 $${srspath}$${a} echar(&&) FAT copy /o $${srspath}$${a} (fd1)/)) >> (fd2)/DRIVERS.BAT



[ 本帖最后由 tuxw 于 2010-11-25 09:49 编辑 ]
回复

使用道具 举报

204#
发表于 2010-11-25 10:41:27 | 显示全部楼层
不会死,951# 中有这样一行用法,但注释掉了,你可以换过试一下
回复

使用道具 举报

205#
发表于 2010-11-25 11:56:45 | 显示全部楼层
不是替换的问题,下面两种写法都是可以的



这个BUG比较隐藏,要for里面,check 后跟连接符再接集合命令,才表现出来。
主要是到这里就死掉了,不方便跟踪。但这个BUG表现的这么有规律,花点时间总是可以解决的。

[ 本帖最后由 tuxw 于 2010-11-25 15:17 编辑 ]
回复

使用道具 举报

206#
发表于 2010-11-26 07:54:34 | 显示全部楼层
@stralft
如zxw,扩展了连接符后,调用内部命令不能省略 call

另外 map 命令不一定返回1,有时map成功,根据文件格式不同,可能返回0
这样试一下:
WENV check ${path##.}==ISO (call clear ]]] echo -e \nNow loading ${path} ...\n ]]] call map --mem ()${path} (0xff) ]]] call map --hook ]]] call map ()${path} (0xff) ]]] map --hook)

966#的我情况这样试了下成功
WENV set a=/BOOT/XDOS.IMA
WENV check ${a##.}==IMA (call map --mem ${a} (fd0) ; call map --hook ; call ls (fd0)/)


@zhaohj
WENV 目前只有 find 命令可能会改变 (rd) 指向,可以之前先将它保存起来,使用完后用户可以恢复原值

你也可以通过保存 0x82D0, 0x82D8(注意它们是64位的),之后它用保存值恢复 --rd-base,--rd-size

[ 本帖最后由 tuxw 于 2010-11-26 10:59 编辑 ]
回复

使用道具 举报

207#
发表于 2010-11-26 23:41:00 | 显示全部楼层
这几天查这个导致机器重启的BUG,比较完整的学习了cmd下for命令的用法,然后逐句看for命令的源码,到处插调试输出信息,始终找不到原因,它并不在固定的地方重启,故障点是随机的。

无奈可奈何回滚到11-15,一步步查哪些改动,每改一下就去测试zhaohj那个for命令,最后查到一个让人吐血的原因,缓冲区太大了(11-19将缓冲区增到大3k,匹配Grub4Dos的管道输出)。

@chenall
这个应该是Grub4Dos内存分配的隐藏BUG,目前扩展 ]]* 连接符后,wenv递归太多内存开销大增,我增大缓冲区后这个问题尤为突出,复杂命令递归时,不停的分配缓冲区,超越了Grub4Dos限制,但正常情况下应该是失败终止程序执行,而不是导致重启。
缓冲区具体能到多大,我没有详细测试,直接改为2K后正常了,在更复杂的命令中仍有可能导致重启的。

@zhaohj
for命令中空行时导致 a=%i 这个问题我试了最好不要改
我测试改过后对语法要求非常严,用户要做更多的判断,如
... do (set a=%i ; check abc==$${a} ...
%i为空时,如果不想出现 a=%i,那么变量a将不存在
后面的 check 就不能这样写了,必须先判断 get a,否则 check 会语法错误

1.命令行缓冲区改为2K
2.修复 set 从命令行输入时直接回车会添加空变量的BUG
3.增加 reset ?* 用法,清除动态的内置变量
4.添加 getrd/setrd 子命令保存恢复 rd 指向(reset命令会清除保存的rd值)
5.find 命令(如果)修改 rd 指向,会自动保存(之后可以 setrd 恢复)

[ 本帖最后由 tuxw 于 2010-11-26 23:49 编辑 ]

wenv-tuxw-2010-11-26.zip

56.66 KB, 下载次数: 19, 下载积分: 无忧币 -2

回复

使用道具 举报

208#
发表于 2010-11-27 00:19:55 | 显示全部楼层
这是一个空行不会出现 a=%i 的版本,你有条件可以测试下,看看哪种方式比较好,以后再改

wenv for /F %i in ( /SYSINF ) do (set a=%i ; set a) # set a 相当于get a*,这个是跟debug状态无关的,调试时方便点

962# 原因尚不清楚

wenv-tuxw-2010-11-27-test.zip

15.36 KB, 下载次数: 20, 下载积分: 无忧币 -2

回复

使用道具 举报

209#
发表于 2010-11-27 01:29:10 | 显示全部楼层
明白你的意思了,下面这个是可以跳过文件中空行的

find要调用其它的字符串函数,如果单独将find分离出去,find+wenv 的大小要远大于40K

call exec 外部命令目前有什么问题吗?最近比较少关注grub4dos的进度。如果没有其它问题的话,没必要分成两个命令,那样wenv的体积还会增大。

wenv-tuxw-2010-11-27-test.zip

15.47 KB, 下载次数: 23, 下载积分: 无忧币 -2

回复

使用道具 举报

210#
发表于 2010-11-27 09:48:10 | 显示全部楼层
我试过了, call exec 在菜单中有效的(grub4dos 11-24)
下面这个已经分离出了exec命令
实际上新版grub4dos可以直接call外部命令,exec只是形式上的将内部命令与外部命令分开

这样改一下的负面影响是只能用新版的Grub4dos了(2010-11-24以后)
之前的版在旧版的2010-11-17以前的grub4dos上也可以使用的
不过WENV只是少数人使用的工具,这部分人跟进Grub4Dos的能力较强,影响不大

[ 本帖最后由 tuxw 于 2010-11-27 10:11 编辑 ]

wenv-tuxw-2010-11-27.zip

56.99 KB, 下载次数: 34, 下载积分: 无忧币 -2

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|Archiver|捐助支持|无忧启动 ( 闽ICP备05002490号-1 )

闽公网安备 35020302032614号

GMT+8, 2024-5-20 19:43

Powered by Discuz! X3.3

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表