无忧启动论坛

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

GRUB4DOS更新建议、bug反馈专帖

    [复制链接]
1#
发表于 2010-11-5 21:18:08 | 显示全部楼层
@zhaohj
问题1

可以这样解决
cat --locate=... | WENV set a=
WENV set a=0x${a! = 0x}   # 最前面加上0x,然后将空格替换为空格0x

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

使用道具 举报

2#
发表于 2010-11-5 22:26:38 | 显示全部楼层
可以用 WENV 命令实现,只是步骤麻烦了点

!BAT
:记录偏移1
cat --locate=[aaaa] /T.TXT | WENV set s1=
WENV set s1=0x${s1}
WENV check " "<-"${s1}" set s1=${s1%% }

:记录偏移2
cat --locate=[bbbb] /T.TXT | WENV set s2=
WENV set s2=0x${s2}
WENV check " "<-"${s2}" set s2=${s2%% }

:如果查找次序相反,交换偏移量,保证s1在前面

:交换方法1: 大文件时加法有可能计算溢出
:WENV check ${s1}>=${s2} (calc s1=s1+s2 ; calc s2=s1-s2 ; calc s1=s1-s2)

:交换方法2: 需要修复calc bug的新版WENV
WENV check ${s1}>=${s2} (calc s1=s1^s2 ; calc s2=s1^s2 ; calc s1=s1^s2)

:起始位置, 字节计数
WENV calc s1=s1+6+2
WENV calc s2=s2-s1-2

WENV call cat --skip=${s1} --length=${s2} /T.TXT


@chenall
不能用最新的测试版grldr运行,试了 11-03 的可以
11-05 的最新grldr在批处理中 WENV check  返回 0 时会终止执行批处理

[ 本帖最后由 tuxw 于 2010-11-6 01:34 编辑 ]

T.rar

440 Bytes, 下载次数: 422

回复

使用道具 举报

3#
发表于 2010-11-6 15:59:45 | 显示全部楼层
可以先查找 [aaaa] 再查找 [
如果 [bbbb] 不可预知,用 INIFILE 的方式更不可能实现,INI 是必须要知道段名和变量名才可以操作的
回复

使用道具 举报

4#
发表于 2010-11-6 19:14:06 | 显示全部楼层
原帖由 zhaohj 于 2010-11-6 16:14 发表


inifile  a:\txtsetup.oem [aaaa]>f6.tmp
DOS下就这么简单提取出了[aaaa]段落的内容


尽量运用现有的功能达到目的,避免重复开发,
我将批处理改了下,算是一个通用的外部命令了
用法:
WENV set INIFILE=INI文件 [段名]
GETSECT.BAT

GETSECT.rar (707 Bytes, 下载次数: 137)

目前只能在11-03版的grldr上运行(11-04以后的版本批处理有BUG,新版正常后批处理还可以简化,并且可以将通过参数指定一个文件名,将结果写入文件)



!BAT设置变量INIFILE=INI文件名 [段名],打印该段内容

:参数检查
WENV get INIFILE || kernel
WENV reset _ini_*

:文件名、段名
WENV set _ini_fn=${INIFILE% }
WENV set _ini_sc=${INIFILE## }

:保存当前debug状态,打开回显,否则管道命令可能失败
debug status | WENV set -t _ini_db= && WENV set _ini_db=${_ini_db## } && debug 1

:记录偏移1
WENV call cat --locate=${_ini_sc} ${_ini_fn} | WENV set -t _ini_s1=
WENV get _ini_s1 || WENV echo -e not found sect ${_ini_sc}\n && WENV call debug ${_ini_db} && WENV reset _ini_* && kernel
WENV set _ini_s1=0x${_ini_s1}
WENV check " "<-"${_ini_s1}" set _ini_s1=${_ini_s1%% }

:记录偏移2
WENV calc _ini_tmp=_ini_s1+1
WENV call cat --skip=${_ini_tmp} --locate=[ ${_ini_fn} | WENV set -t _ini_s2=
WENV set _ini_s2=0x${_ini_s2}
WENV check " "<-"${_ini_s2}" set _ini_s2=${_ini_s2%% }

:没有找到下一个段时,设置为文件长度
WENV check ${_ini_s2,?}==2 && WENV call cat --length=0 ${_ini_fn} | WENV set -t _ini_s2=
WENV check " "<-"${_ini_s2}" set _ini_s2=${_ini_s2## }

:起始位置, 字节计数
WENV calc _ini_s1=_ini_s1+${_ini_sc,?}
WENV calc _ini_s2=_ini_s2-_ini_s1

:直接显示, 首尾可能有换行(如果内容较短,可通过变量中转显示去掉首尾换行)
WENV call cat --skip=${_ini_s1} --length=${_ini_s2} ${_ini_fn}

:恢复环境
WENV call debug ${_ini_db}
WENV reset _ini_*
回复

使用道具 举报

5#
发表于 2010-11-6 19:22:03 | 显示全部楼层
我比较希望的用法是这样的
WENV read GetSect.env inifile [aaaa]
回复

使用道具 举报

6#
发表于 2010-11-6 19:40:03 | 显示全部楼层

1105bug

11-05 版批处理BUG

随便写一个简单的语句集合的批处理文件,运行正常

在中间任意位置加一句
WENV check 1==2 echo ok
再运行批处理将在这句后退出

应该是只要有一条语句返回0就终止了
比如插入 WENV calc 1-1 && WENV echo ok 也一样
回复

使用道具 举报

7#
发表于 2010-11-6 21:13:05 | 显示全部楼层
现在不能用 WENV check " "<-"${VAR}" 来检查VAR是否包含空格(无空格时批处理会终止)

在grldr修正前可以用下面的临时办法代替
WENV reset tmp
WENV set tmp=${VAR# }  #无空格时tmp变量不存在
WENV get tmp && ...
回复

使用道具 举报

8#
发表于 2010-11-6 23:18:13 | 显示全部楼层
原帖由 zhaohj 于 2010-11-6 22:54 发表
想把文本中注释先过滤掉,下面的命令竟然不行:
cat --length=0 (fd1)/txtsetup.oem && fat mkfile size=* (fd1)/temp
echo ; > (fd1)/temp
wenv for /f "eol=# delims=" %i in ( (fd1)/txtsetup.oem ) do ( ...


最后一条命令改成这样:
wenv for /f "eol=# delims=" %i in ( (fd1)/txtsetup.oem ) do echo %i  >> (fd1)/temp

DO 后面只能跟 WENV 子命令
而 >> 是 Grub4Dos 的特性,是 Grub4Dos 支持的命令间的分隔符

这个写法
wenv for /f "eol=# delims=" %i in ( (fd1)/txtsetup.oem ) do (set a=%i ; echo $${a} >> (fd1)/temp)
Grub4Dos在分析命令行时,会将 >> 前面的部分当作一条命令(显然这个格式是不合WENV语法的),然后将结果传给后面的部分

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

使用道具 举报

9#
发表于 2010-11-6 23:26:54 | 显示全部楼层
原帖由 zhaohj 于 2010-11-6 23:16 发表
这个问题的发现,主要是locate=[ 时,象F6的txtsetup.oem有太多的[,导致变量值超过512。

我上传这个txtsetup.oem,比较大。


这个也有办法解决,就是分块查找,不过批处理会比较复杂
或者将 locate=[ 的查找结果输出到临时文件,再对文件进行判断

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

使用道具 举报

10#
发表于 2010-11-6 23:44:03 | 显示全部楼层
原帖由 zhaohj 于 2010-11-6 23:31 发表
#20楼还是有问题,你再测试一下,我的理解,应该do (...)
应该每个循环执行()中的命令


do 后面的 () 不是必须的,只是大多数时候后面不是一条简单的命令,所以要用集合命令,单命令时有无 () 没有关系

只要执行一个  WENV 命令看是否正常就行了
文件重定向不是在循环的时候一行行写入 temp 的,而是等前面的 WENV 命令执行完毕,然后将它的输出写入 temp
下面的输出已经过滤掉注释了



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

使用道具 举报

11#
发表于 2010-11-6 23:46:33 | 显示全部楼层
原帖由 chenall 于 2010-11-6 23:38 发表



看了一下这个是WENV的BUG。
看下面的代码,等tuxw的修正版吧。

    for(i=0;i

好,我重编译下

==================
已上传

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

使用道具 举报

12#
发表于 2010-11-7 08:48:21 | 显示全部楼层
GETSECT.rar (820 Bytes, 下载次数: 104)

解决了大文件搜索结果超出512字节的问题



第3个参数指定缓冲区地址,不是必须的,不指定的话默认0x600000

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

使用道具 举报

13#
发表于 2010-11-7 10:52:11 | 显示全部楼层
自动截断不太好
可能你设置了一个超出长度的变量,但你没有注意到,自动截断后将这个问题掩盖了,而这个问题可能在很远的位置才表现出来,故障定位会比较麻烦

或者用一个变通的方式:设置一个开关,变量可能超长,但用户明确知道只需要截断的部分时,先打开这个开关

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

使用道具 举报

14#
发表于 2010-11-7 12:52:56 | 显示全部楼层
?_WENV 只有用 call 命令中才会设置为所调用命令的返回值(最近加入check查找命令也影响它)

cat /file                   #不影响 ?_WENV
WENV call cat /file    # 影响 ?_WENV

WENV get 默认不显示内置变量( 用 get ?_WENV 或 get ?* )

数字9不用在变量名中是个BUG,数字范围的 < 判断应该改 <=

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

使用道具 举报

15#
发表于 2010-11-7 12:56:55 | 显示全部楼层
原帖由 zhaohj 于 2010-11-7 11:02 发表
下面有可能出现溢出:
:查找下一个可能的段
WENV calc _ini_tmp=_ini_s1+${_ini_sc,?}+2
debug 0
WENV call cat --skip=${_ini_tmp} --locate=[ ${_ini_fn}
debug 1
WENV calc _ini_cnt=${?_WENV}



这里应该不会溢出, cat 只是被调用并没有任何重定向输出, 调用后 ?_WENV 中是找到的个数。

那个 +2 不要,最初的那个批处理是针对你特定的例子文件,+2用来跳过换行。通用批处理中不能这样做,因为并不有判断后面是否存在换行符。

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

使用道具 举报

16#
发表于 2010-11-7 13:21:36 | 显示全部楼层
增加输出到文件功能, 临时缓冲区用完后变为 rd 文件

WENV set INIFILE=/T1.TXT [Disks] 0x600000
/GETSECT.BAT
dd if=(rd)+1 of=/myfile

GETSECT.rar

835 Bytes, 下载次数: 88

回复

使用道具 举报

17#
发表于 2010-11-7 15:51:16 | 显示全部楼层
这个问题你要单独运行一下
cat --locate=[HardwareIds......] /TXTSETUP.OEM
看正常否
我测试的结果是这条命令不能正确执行
Error 30:...
可能要请教下 chenall 了

======================
我就是用你#19的副本测试的,为了少打几个字,文件名我改为 T1.TXT 了,但我没有测试种长的带.的段名

关键在多的那个$
$$ 不是 for 命令专用的,复合命令(check/for) 后面跟的集合命令里多次引用的变量,可能被其它命令改变的,也要用$$。

你给出的例子处,一个或二个$都没有问题,但后面有个计算 _ini_s2 的地方必须要用 $$ 的

比如check后面的集合命令
WENV set a=1
WENV set b=1
WENV check ...  (set b=${b}${a} ; set a=$${b}) #执行到第二个set时,b已经改变了,如果用一个$的话,b引用的将是原值

测试
WENV check ...  (set b=${a}${b} ; set a=${b})
红色处分别用1个和2个$运行就可以看出区别了


这个要说清楚的话要讲一下WENV的原理
WENV check ...  (set b=${a}${b} ; set a=${b})

1.没有判断子命令时就进行一次扫描,命令变成
WENV check ...  (set b=21 ; set a=1)  #a使用了b改变前的值
2.进入check子命令后 a,b 的值已经固定了


再看这一个
WENV check ...  (set b=${a}${b} ; set a=$${b})

1.第一次扫描后
WENV check ...  (set b=21 ; set a=${b})  # 双写$就是通知WENV先不要替换这个变量

2.进入check命令, 依次执行
set b=21
set a=${b} #此时再去取变量b的值,就是改变后的值


for命令中需要双写 $$ 原因也是一样的,因为 Do 后的命令可能会执行多次,而其中可能会改变变量的值,下次执行需要读变量的新值,所以不能开始就替换变量。


但单独的集合命令则不需要双写$
WENV (... ; ...)
这种简单命令直接按 ; 分解成多条命令,然后逐条替换变量,执行,所以不需要双写 $

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

使用道具 举报

18#
发表于 2010-11-7 16:45:49 | 显示全部楼层
@zhaohj
还有个隐患,你自己修改下
在第一次使用 rd 前,先将它清0

WENV reset =${_ini_buf} ${_ini_cnt} #或只清前面17字节也是可以的
WENV check ${_ini_cnt}>=1 call cat --skip=${_ini_tmp} --locate=[ ${_ini_fn} > (rd)+1

输出重定向到 rd  后,在第18个字节处截断。启动后初次运行可能没问题,但临时缓冲区可能被其它命令用过(比如read)初值不为0,它可能含有一些其它字符,如果我们的搜索命令输出只有3个字节,那4-17间的字符可能造成干扰,先清下0就没问题了。

之所以在18个字节处截断,是因为最大可能的偏移值64位,16进制结果要占16个字符,加前面的空格是17个字符。这样保证第一个偏移值不被截断。实际上在 18-512间截断都可以,但截断处前面的部分要先清0。

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

使用道具 举报

19#
发表于 2010-11-7 19:26:55 | 显示全部楼层
不要这么复杂,设置 INIFILE 时只给16个字符就行了,这样通用性会好一点。批处理内部参数分离部分改一下就可以了

===============
改动量比较小的方法
wenv call cat --locate=${_ini_sc:0:16} ...
只取段名的前16字符进行查找,其它地方不用动,也用判断段名是否超出16字符。
改动_ini_sc的话计算偏移,起始,字节数部分都要相应改变。

[ 本帖最后由 tuxw 于 2010-11-7 20:01 编辑 ]
回复

使用道具 举报

20#
发表于 2010-11-7 21:42:09 | 显示全部楼层
这种情况没有完美的办法,如果你取后面或中间的,同样存在这个2个长段名局部相同的问题

取前16字符查找只是在应对 cat 的 16 字节限制这一问题的最简洁的方法

===============
复杂一点的有效的办法

WENV call cat --locate=${_ini_sc:0:16} ${_ini_fn}
先查找16字节
通过 ?_WENV 判断是否找到多个
如找到一个,则就是目标
否则再从多个偏处开始查找 ${_ini_sc:16:16}
继续判断

总之,办法总是比困难多

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

使用道具 举报

21#
发表于 2010-11-8 00:09:16 | 显示全部楼层
上传了一个 WENV,加了个 find 命令
WENV find [-skip=S] [-len=L] [-c] STRING FILE

G2.rar (719 Bytes, 下载次数: 110)
指定缓冲区,将结果写到文件,屏幕上不显示结果,便于在菜单中调用
WENV set INIFILE=/TXTSETUP.OEM [HardwareIds.scsi.ATABUS] 0x600000
/G2.BAT
WENV get INI_OK && FAT copy (rd)+1 (fd0)/myfile

不指定缓冲区时,只是在屏上显示结果, 不生成 rd 文件


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

使用道具 举报

22#
发表于 2010-11-8 20:37:41 | 显示全部楼层
现在这些开关还是测试性质的,有些开关可能以后不会保留,或许顺序可能会变动(将可能用到频率较高的排在前面,修改方便也容易记忆),要等稳定后再统一说明。我现在最想改的是将开关定义反过来,只有打开某个开关,才触发默认行为相反的功能。这也是一直没提供 switch echo_ln=on 这种直观语法的原因之一,实现这个语法后再变动时会麻烦很多。现在这种简单想变动只需要调一下几个语句的行序,0,1互换就可以了。

[ 本帖最后由 tuxw 于 2010-11-8 20:39 编辑 ]
回复

使用道具 举报

23#
发表于 2010-11-9 00:07:47 | 显示全部楼层
是有这个问题,Grub4Dos 的批处理需要直接运行,不能由 WENV 调用

read 不支持条件连写命令,也不能使用 Grub4Dos 的文件重定向和管道

再想想看有没有其它办法解决循环运行的问题
实在不行,干脆在 find 命令里直接给你支持这个特殊功能算了,反正这个 find 命令估计也只有你用,

或者最后还是得要一个你说的 inifile,不过我对这个不看好,除了你这个用法,inifile 的独立的read/write功能在grub4dos环境下实在没什么用处,而没有了read/write还能叫inifile吗

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

使用道具 举报

24#
发表于 2010-11-9 01:04:43 | 显示全部楼层
已经实现了 WENV find [-skip=S] [-len=L] [-end=STRING] [-c] [-r] STRING FILE
但有其它部分的代码(switch)正在修改,明天上传吧

WENV find -end=[  [Disks] /TXTSETUP.OEM
直接输出 [Disks] 段

顺手添加了个 -r,反向查找,正好满足你反查段名的问题,不过这部分没在代码里实现,需要自己批处理
回复

使用道具 举报

25#
发表于 2010-11-9 02:38:38 | 显示全部楼层
已上传
help 中不显示 find 命令,但 WENV find 可显示其语法
WENV find [-skip=S] [-len=L] [-end=ENDS] [-c] [-r] STRING FILE

新增 -r 参数反向查找STRING,为简化编程,取消了 skip>0 时从 skip+1 开始查找的特性
新增 -end 参数
未指定 -end 时,跟之前一样,只是一个简的查找命令,取得第一个找到的位置

如指定 -end,则找到 STRING 后,继续向后查找 ENDS,找到则输出之间的内容
如找到 ENDS 会设置好 rd,可以在find命令之后立即复制 (rd)+1 到文件

find 命令只要找到 STRING 就会返回1,通过一个返回值没办法知道是否有找到 ENDS
添加了一个内置变量 ?_FIND,如找到,设置其为 ENDS的偏移量,否则删除 ?_FIND,可根据 ?_FIND 是否存在来判断能否复制 rd

[ 本帖最后由 tuxw 于 2010-11-9 02:47 编辑 ]
回复

使用道具 举报

26#
发表于 2010-11-9 03:01:50 | 显示全部楼层
反查段名

WENV find string /TXTSETUP.OEM && WENV set a=${?_WENV}
WENF find -len=${a} -r [ /TXTSETUP.OEM && WENV set b=${?_WENV}
WENV calc -hex c=b+1
WENV find -skip=${c} ] /TXTSETUP.OEM && WENV set c=${?_WENV}
WENV calc c=c-b+1
WENV call cat --skip=${b} --length=${c} /TXTSETUP.OEM
回复

使用道具 举报

27#
发表于 2010-11-20 09:39:25 | 显示全部楼层
这个问题貌似要在批处理最后必须有个换行,不然检测不到批处理结束
回复

使用道具 举报

28#
发表于 2010-11-28 14:50:51 | 显示全部楼层
@chenall
新版 call 内部命令调用方法导致管道问题

这样调用内部命令:builtin_cmd(NULL, arg, flags)
wenv call getmetry (hd0) | wenv set a=     # 失败

改回旧方法:builtin_cmd(arg, next_word_ex(arg, NULL, TRUNC), flags)
wenv call getmetry (hd0) | wenv set a=     # 成功
回复

使用道具 举报

29#
发表于 2010-11-29 15:39:18 | 显示全部楼层
是否文件格式有特殊要求?
在文件尾写入不同字符看看有什么变化,比如只写一个换行,或只写1、2、3...个#试试
echo -n >> (fd1)/TXTSETUP.OEM

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

使用道具 举报

30#
发表于 2010-11-29 16:46:54 | 显示全部楼层
dos 下先将 txtsetup.oem 做好,保证它可正常使用

1.grldr 再用 fat 复制一份,看看是否正常

2. 先建一个大小跟正常 txtsetup.oem相同的文件,内容清空,分别用dd命令和 >> 复制,看生成的文件是否正常

慢慢确定问题在哪,如果这些方法都不正常,那就是这个文件要求尾部不能有空行吧

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

使用道具 举报

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

本版积分规则

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

闽公网安备 35020302032614号

GMT+8, 2025-5-23 15:31

Powered by Discuz! X3.3

© 2001-2017 Comsenz Inc.

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