中国DOS联盟

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

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

中国DOS联盟论坛
现在时间是 2026-07-31 15:54
中国DOS联盟论坛 » DOS批处理 & 脚本技术(批处理室) » [讨论]如何从用户传入的参数中去掉引号? 精华I 查看 13,167 回复 23
16 发表于 2006-05-28 01:49 ·  中国 湖北 荆门 电信
荣誉版主
★★★
积分 2,013
发帖 718
注册 2006-02-18 07:07
20年会员
UID 50550
状态 离线
唔,果然最后的总结工作是由willsort来完成,只有willsort与无奈何两位严谨的态度才适合发这种理论性的贴。But,俺还是班门弄弄斧,关二爷面前耍耍大刀:
2.5.可以用%var:~1%来去掉前引号。
2.6.可以用%var:~1,-1%来去掉前后引号
2.7.可以用%var:~0,-1%来去掉后引号。

[ Last edited by 3742668 on 2006-5-28 at 02:02 ]
17 发表于 2006-05-28 02:50 ·  中国 河北 保定 移动
铂金会员
★★★★
网络独行侠
积分 6,962
发帖 2,753
注册 2003-04-16 00:00
23年会员
UID 1565
性别 男
来自 河北保定
状态 离线
三位都是大家,我是灌水的。努力学习了!
偶只喜欢回答那些标题和描述都很清晰的帖子!
如想解决问题,请认真学习“这个帖子”和“这个帖子”并努力遵守,如果可能,请告诉更多的人!
18 发表于 2006-05-28 23:42 ·  中国 山西 临汾 中移铁通
元老会员
★★★★
Batchinger
积分 4,432
发帖 1,512
注册 2002-10-18 00:00
23年会员
UID 19
性别 男
状态 离线
Re 3742668:

新的小结被编辑到顶楼贴中方便浏览,并将你的建议分别并入到2-1、2-3、2-5中。

正如无奈何兄所言,集体的智慧远大于个体智慧的总和。现在想到另外一道与引号相关的课题,也提请大家讨论。

命令行参数的防御错误

我过去的代码中,在if语句中比较命令命令行参数时,总喜欢使用类似if "%1"=="string1" ...的格式,现在想来,这个习惯是很有些问题的。

因为使用引号的目的在于防御串中可能出现的转义字符,而在命令行参数中,串值在经过CMD的命令行解析后,所有的可能被转义的转义字符应该都已发挥作用而被脱去,剩下的转义字符应该都是在命令行中就被预先防御过。所以,%1中不可能含有空格或其它转义字符而没有引号防御,也因此再在%1外使用引号就成了多余。

再进一步讲,如果%1是经过引号防御转义的字符串,比如"C:\Program files",此时再使用"%1"引用则变成了""C:\Program files"",引号被重新匹配,因而转义字符被暴露出来,导致程序出错,因此此时使用引号就成了错误。

那么,我们是否不需要再if语句中对%1进行防御呢?答案是否定的,因为if中防御字符的出现,最初是为了防御%1为空,就是类似if "%1"=="" ...的格式,所以我一度曾称呼防御字符为“防空字符”。如果不对%1进行防御,则再无参数调用批处理执行到此句会出现语法错误。

至此,我们最好的选择就是将%1脱引号后再使用引号进行防御。比如 if "%~1"=="C:\Program file" ... 或 if exist "%~1" .... 。这确实是很好的办法。

但是,脱引号的实现只有在CMD中才比较简单,而我的批处理很多还在9x和DOS下运行,所以,我需要退而求其次想其它的办法,比如选取其它字符作为命令行参数串的防御字符。在串值比较的if语句中,可选的防御字符有很多,几乎大多非转义的字符都可用来防御。比如我早期常用的 if == ... 。

然而,还需要考虑的是,防御字符还会出现在其它语句中,比如文件存在判断语句if exist中。如果我们使用if exist ... 的范式,则程序的流程显然将脱出我们预期之外。尽管在我通常的惯例是 if == ... 之后再 if exist %1 ... 。

故而,为了保持代码可阅读性,我需要使用风格一致的的防御字符,所以我们剩下的选择就很少了。或许,我们可以使用后缀的句点。比如 if %1.==. ... 或 if exist %1. ...

它可以解决串为文件名时的部分防御问题,但当串为路径. 或者..时,if exist %1. 显然又会出错。

那么还存在更好的解决方案吗?
※ Batchinger 致 Bat Fans:请访问 批处理编程的异类 ,欢迎交流与共享批处理编程心得!
19 发表于 2006-05-29 13:24 ·  中国 湖北 荆门 电信
荣誉版主
★★★
积分 2,013
发帖 718
注册 2006-02-18 07:07
20年会员
UID 50550
状态 离线
好长一篇。在我的习惯中,一般能不用到if就会尽量不用if语句,而尽可能地用echo,dir等等命令来操作变量并根据错误返回值来进行相应的操作。即便是使用 if "%~1"==的格式,我想,如果%1中包含有"=="等不可预料的,类似if语句结构的字符串(牛角尖?)时,也难免出错(没有试验过,只不过是很早的时候的一种想法,从而导致一直以来的习惯)。对于if语句来说,或许能不用就不用就是最好的方法吧。当然,这只是我个人菲薄的认识而已,毕竟当初浅尝辄止并未深究。已见willsort官方理论,期待 无奈何 之高见,呵呵。
ps:此贴已被加精华贴,各位看官赶快留个爪印吧,到cn-dos来还是第一次混进传说中的精华贴.
20 发表于 2007-07-08 17:24 ·  中国 湖北 武汉 电信
初级用户
小子
积分 76
发帖 26
注册 2007-06-20 19:30
19年会员
UID 91913
性别 男
状态 离线
反复看了三遍,好
21 发表于 2007-08-23 14:28 ·  中国 江苏 苏州 电信
初级用户
积分 48
发帖 25
注册 2007-07-30 17:57
19年会员
UID 94318
性别 男
状态 离线
很受用,谢谢啦!
22 发表于 2007-11-19 20:46 ·  中国 湖南 长沙 雨花区 电信
初级用户
积分 67
发帖 32
注册 2007-11-19 12:34
18年会员
UID 103118
性别 男
状态 离线
 2-4 、可以使用set "var=%var%脱去环境变量var 串尾的最后一个引号,如果串尾
不存在引号则环境变量被清空;

是不是因为版本的原因呀,我在XP中如果var中没引号,set "var=%var%值不变
23 发表于 2007-11-19 21:16 ·  中国 湖南 长沙 雨花区 电信
初级用户
积分 67
发帖 32
注册 2007-11-19 12:34
18年会员
UID 103118
性别 男
状态 离线
原来set "var=%var%,如果var
1、不含引号,数值不变
2、如果有引号,且不在首位,保留倒数第一个引号前的值
3、如果有引号都在串首,清空变量
24 发表于 2008-10-19 17:53 ·  中国 江西 赣州 电信
新手上路
积分 13
发帖 15
注册 2008-10-19 15:37
17年会员
UID 128763
性别 男
状态 离线
有点深了……
论坛跳转: