无忧启动论坛

 找回密码
 注册
搜索
系统gho:最纯净好用系统下载站投放广告、加入VIP会员,请联系 微信:wuyouceo
楼主: chenall
打印 上一主题 下一主题

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

  [复制链接]
901#
发表于 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 编辑 ]
回复

使用道具 举报

902#
发表于 2010-11-23 00:22:01 | 只看该作者
PCI\VEN_13C1&DEV_1002="3wareDrv"

delims==; 这里的引号都是配对的,%j="3wareDrv"后去掉两边引号也不存在有单引号问题。
估计不是这个原因。
回复

使用道具 举报

903#
发表于 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 编辑 ]
回复

使用道具 举报

904#
发表于 2010-11-23 08:21:31 | 只看该作者
@tuxw
上面测试的是C大的11-22上传的最新版,loop、break等命令还没有加入的。这个等稳定加入也不迟,代码很少。
这次的动作可能真的很大。
回复

使用道具 举报

905#
 楼主| 发表于 2010-11-23 09:46:47 | 只看该作者
OK,已经修正了前面的问题(因为进入死循环了).

另外添加了一个子命令
config
可以显示和配置默认参数.
目前只有一个quote_char
指定引号功能的代替符号.
比如可以
wenv config quote_char=`
然后
wenv `echo abcdA"SDf3"`
回复

使用道具 举报

906#
发表于 2010-11-23 10:20:06 | 只看该作者
上传到哪里了?
回复

使用道具 举报

907#
 楼主| 发表于 2010-11-23 10:37:22 | 只看该作者
原帖由 zhaohj 于 2010-11-23 10:20 发表
上传到哪里了?


发贴的时候没有上传成功,已经重新传过了.
回复

使用道具 举报

908#
发表于 2010-11-23 11:06:03 | 只看该作者
测试OK!等待你加入新功能,十分挂念find(这个代码有点多)。

再测试一下config.

[ 本帖最后由 zhaohj 于 2010-11-23 11:07 编辑 ]
回复

使用道具 举报

909#
发表于 2010-11-23 11:19:08 | 只看该作者
1:
WENV for /f "eol=; tokens=1-2 delims==;" %i in ( (fd1)/TXT ) do (set a=%i ; check "$${a:0:4}"=="PCI\" (set b=%j ; echo -n $ ; echo $${a}=$${b}))
2:
WENV for /f "eol=; tokens=1-2 delims==;" %i in ( (fd1)/TXT ) do (set a=%i ; check "$${a:0:4}"=="PCI\" ]]& (set b=%j ; echo -n $ ; echo $${a}=$${b}))

生成的第一个PCI信息有点不同

-------------------不是不同,是错位了。

[ 本帖最后由 zhaohj 于 2010-11-23 11:22 编辑 ]

Snap1.jpg (42.58 KB, 下载次数: 96)

1 生成

1 生成

Snap2.jpg (48.33 KB, 下载次数: 92)

2 生成

2 生成
回复

使用道具 举报

910#
 楼主| 发表于 2010-11-23 12:03:18 | 只看该作者
这是正常的.
集合是属于同一条命令的.

所以在FOR命令里面扩展一次之后变成.
check "${a:0:4}"=="PCI\" (set b=%j ; echo -n $ ; echo ${a}=${b})

再执行check命令时就就会先扩展变量A和B了.

如果check后面需要使用集合命令,你可以使用]]&.这样它就被分开了,而且执行速度也比较快.

为了防止出错,原则上是能不用集合的尽量不要用.

[ 本帖最后由 chenall 于 2010-11-23 12:04 编辑 ]
回复

使用道具 举报

911#
发表于 2010-11-23 12:33:49 | 只看该作者
扩展一次之后变成.
check "${a:0:4}"=="PCI\" (set b=%j ; echo -n $ ; echo ${a}=${b})

这个扩展一次之后变成:
check "${a:0:4}"=="PCI\" ]]& (set b=%j ; echo -n $ ; echo ${a}=${b})

会产生不同结果?
回复

使用道具 举报

912#
 楼主| 发表于 2010-11-23 12:45:53 | 只看该作者
原帖由 zhaohj 于 2010-11-23 12:33 发表
扩展一次之后变成.
check "${a:0:4}"=="PCI\" (set b=%j ; echo -n $ ; echo ${a}=${b})

这个扩展一次之后变成:
check "${a:0:4}"=="PCI\" ]]& (set b=%j ; echo -n $ ; echo ${a}=${b})

会产生不同结果?


呵呵.这两句当然是不同的了,你可以在命令行下执行试一下.

第一句在执行check时因为后面是属于同一语句,所以会扩展a,b

第二句不一样,在执行check时并不会扩展A,B
回复

使用道具 举报

913#
发表于 2010-11-23 13:01:05 | 只看该作者
命令行下测试:

[ 本帖最后由 zhaohj 于 2010-11-23 13:09 编辑 ]

Snap1.jpg (46.21 KB, 下载次数: 82)

Snap1.jpg

Snap2.jpg (28.5 KB, 下载次数: 87)

Snap2.jpg
回复

使用道具 举报

914#
 楼主| 发表于 2010-11-23 13:13:28 | 只看该作者
原帖由 zhaohj 于 2010-11-23 13:01 发表
命令行下测试:


我没看明白..

这样解释吧,你可能突然间犯糊涂了,呵呵.
命令
check "${a:0:4}"=="PCI\" (set b=%j ; echo -n $ ; echo ${a}=${b})
在执行时这是一个整体只算一个命令(集合的内容是属于子命令) 所以会变量a,b也会被扩展再执行.

下面的不一样.
check "${a:0:4}"=="PCI\" ]]& (set b=%j ; echo -n $ ; echo ${a}=${b})

这个被分成两次执行A,B在执行check时不会被扩展.
第一次
check "${a:0:4}"=="PCI\"
如果成功再执行
(set b=%j ; echo -n $ ; echo ${a}=${b})
回复

使用道具 举报

915#
 楼主| 发表于 2010-11-23 13:17:14 | 只看该作者
这种情况目前只有
check和for会出现.

因为check或for后面可以跟一个集合命令.

就像for一样,要使用里面设置的变量需要$${VARIABLE}

每增加一层嵌套就要增加一对的$$来延缓扩展.
回复

使用道具 举报

916#
发表于 2010-11-23 13:36:54 | 只看该作者
这样讲就理解了,下面相等:
1:
WENV for /f "tokens=1-2 delims==" %i in ( (fd1)/TXT ) do (set a=%i ; check "$${a:0:4}"=="PCI\" (set b=%j ; echo -n $ ; echo $$$${a}=$$$${b}))
2:
WENV for /f "tokens=1-2 delims==" %i in ( (fd1)/TXT ) do (set a=%i ; check "$${a:0:4}"=="PCI\" ]]& (set b=%j ; echo -n $ ; echo $${a}=$${b}))
回复

使用道具 举报

917#
发表于 2010-11-23 14:36:36 | 只看该作者
wenv set srspath=/SRS/OEM/
wenv set a=TXTSETUP.OEM

我记得有个版本可以把

wenv "echo cat --length=0 ${srspath}${a} && FAT copy /o ${srspath}${a} (fd1)/"  >> (fd2)/DRIVERS.BAT
这个版本不行了,只能这样:
wenv (echo -n cat --length=0 ${srspath}${a} & ; echo & FAT copy /o ${srspath}${a} (fd1)/)  >> (fd2)/DRIVERS.BAT

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

[ 本帖最后由 zhaohj 于 2010-11-23 14:50 编辑 ]
回复

使用道具 举报

918#
 楼主| 发表于 2010-11-23 15:17:03 | 只看该作者
原帖由 zhaohj 于 2010-11-23 14:36 发表
wenv set srspath=/SRS/OEM/
wenv set a=TXTSETUP.OEM

我记得有个版本可以把

wenv "echo cat --length=0 ${srspath}${a} && FAT copy /o ${srspath}${a} (fd1)/"  >> (fd2)/DRIVERS.BAT
这个版本不行了 ...


我试了一下是正常的啊.

引号里面就是只有一个命令的.
回复

使用道具 举报

919#
发表于 2010-11-23 15:32:52 | 只看该作者
sorry,测试过config,没变回来,忘了。


正常

但wenv config quote_char='
不正常了

[ 本帖最后由 zhaohj 于 2010-11-23 15:46 编辑 ]

Snap1.jpg (44.83 KB, 下载次数: 88)

Snap1.jpg

Snap2.jpg (62.95 KB, 下载次数: 88)

Snap2.jpg
回复

使用道具 举报

920#
发表于 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
回复

使用道具 举报

921#
 楼主| 发表于 2010-11-23 16:09:00 | 只看该作者
原帖由 zhaohj 于 2010-11-23 15:32 发表
sorry,测试过config,没变回来,忘了。


正常

但wenv config quote_char='
不正常了


呵呵,因为&& 这个是GRUB4DOS内置的操作符,所以肯定是不正常的.到&&就会被截断了.

GRUB4DOS内部只认引号. 所以应该避免出现这种情况,实在有必须的话可以使用tuxw的方法.使用转义符.

另外新版已经上传,看起来基本没有什么问题了.

顺便添加两个很简单的控制命令.continue和break.
可以用于for循环中,continue跳过本次循环,break跳出循环.(可嵌套).
另外break,也可以用于集合命令中,跳过后面的命令.

忘了一点,这一版已经恢复"]]]"符号

注意 ]]] 和 ; 虽然都是顺序执行,但]]]会清除前一句的ERROR值,而 ; 不会.

这个配合break等命令可以明显优化执行效率


关于check的优化.
check 后面如果是跟单条命令,那就直接
check XXXXXX cmd
如果是命令集合,最好使用以下方式.
check xxxx ]]& cmdx

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

使用道具 举报

922#
发表于 2010-11-23 16:19:57 | 只看该作者
一股作气,把find也加进去吧。

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

使用道具 举报

923#
 楼主| 发表于 2010-11-23 16:31:50 | 只看该作者
原帖由 zhaohj 于 2010-11-23 16:19 发表
一股作气,把find也加进去吧。


tuxw的增强版有添加了许多功能的,我猜测单单加find命令,可能还是不够.

所以暂时可以继续用tuxw的增强版本.

@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);
回复

使用道具 举报

924#
 楼主| 发表于 2010-11-23 16:35:26 | 只看该作者
原帖由 tuxw 于 2010-11-22 01:04 发表
@chenall

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


有没有例子,我测试一下..

grub4dos很早的版本就有检测引号配对了.
回复

使用道具 举报

925#
 楼主| 发表于 2010-11-23 22:53:03 | 只看该作者
预计明天下午之后将会有新的应用程序,需要配合新的GRUB4DOS。
名字:search

找文件用的,支持通配符,目前测试可以查找指定目录,通配符支持 *和?。

找到了就输出文件名。如果可能的话将会添加子目录查功能。

这样以后更容易实现动态菜单了。
回复

使用道具 举报

926#
发表于 2010-11-23 22:59:01 | 只看该作者
这样吗?
search /SRS/OEM/VMWARE/*.SY?
search /SRS/OEM/VMWARE/*.*
回复

使用道具 举报

927#
发表于 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

回复

使用道具 举报

928#
 楼主| 发表于 2010-11-24 10:25:30 | 只看该作者
还是把search的功能集成到WENV里面好了。先上传一个测试。须配合今天的GRUB4DOS

目前的DIR功能,只是简单的配对,一般情况下够用。

2010-11-24
1.添加子命令dir,支持通配符*,?
  比如,显示当前目录下所有.TXT文件.
  wenv dir /*.txt 或 wenv dir *.txt
  显示指定目录下的指定gho
  wenv dir /dir/path/*.gho

2.添加exec子命令(从CALL中分离出来的),用于调用外部命令.
注:现在的call也可以执行外部命令,但建议使用exec来执行,比较直观。
之前的call exec 外部命令功能失效。

注: 现在的call 调用改成了和GRUB4DOS命令行或菜单执行的命令相同的调用。所以call命令有所增强。

比如你可以这样
注:使用两个配对引号,可以让GRUB4DOS把两个引号之间的内容传给WENV作为参数。否则到 && 会被截断。
wenv "call cat --length=0 /aa.txt && echo bb"

一般情况下不建议这样用,除非有必要。
相当于直接在GRUB4DOS命令行下执行,只是它是通过wenv调用的,所以支持wenv的扩展功能。
cat --length=0 /aa.txt && echo bb

[ 本帖最后由 chenall 于 2010-11-24 10:52 编辑 ]
回复

使用道具 举报

929#
 楼主| 发表于 2010-11-24 10:44:42 | 只看该作者
原帖由 tuxw 于 2010-11-24 09:04 发表


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


压缩包中是一个  test.bat 和测试用的几个文本文件,放在iso的根目录下运行 test.bat
test.bat 中失败的 ...



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

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

这个是WENV内部处理的问题。第一句不管一个还是两个引号执行效果应该都是一样的。

应该是check命令的原因。
因为check里面也有检测引号配对。

使用新版本的替换引号功能字符可以解决这个问题。(不过我直接用你的版本测试只有上面两个命令好像也是通过的。。)

[ 本帖最后由 chenall 于 2010-11-24 10:46 编辑 ]
回复

使用道具 举报

930#
发表于 2010-11-24 11:17:49 | 只看该作者
call 调用改成了和GRUB4DOS命令行或菜单执行的命令相同的调用。所以call命令有所增强。
@tuxw:
以前的版本所有没通过,找到上面原因了。
在命令行下全通过,不过我有菜单,因为需要goto.

WENV call cat --length=0 ${srs} ]]& (call map --mem=0xB000 ${srs} (rd) ; set a=${IDN}.SY_)
WENV call cat --length=0 ${srs1} ]]& (call map --mem=0xB000 ${srs1} (rd) ; set a=${IDN}.SYS)
WENV get a || configfile (fd2)/ERROR.LST
WENV echo ${a} | FAT copy /o (rd)+1 (fd1)/

---------------------
]]& 没有消除前面的ERROR,导致运行中断

[ 本帖最后由 zhaohj 于 2010-11-24 11:47 编辑 ]

Snap1.jpg (31.42 KB, 下载次数: 93)

Snap1.jpg
回复

使用道具 举报

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

本版积分规则

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

闽公网安备 35020302032614号

GMT+8, 2024-11-26 11:19

Powered by Discuz! X3.3

© 2001-2017 Comsenz Inc.

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