Board logo

标题: [其他] 求助批处理使用了chcp 65001仍在特殊情况下乱码且报错! [打印本页]

作者: yanjujino1    时间: 2024-4-29 00:58     标题: 求助批处理使用了chcp 65001仍在特殊情况下乱码且报错!

我在脚本中用到了中文,并添加了chcp 65001命令,文件保存为UTF 8,cmd字体是默认的新宋体,在大部分情况下都能正常运行,结果遇到了下面这种特殊的情况出现了报错
  1. @echo off
  2. chcp 65001 > nul
  3. set "i=1"
  4. rem 轮询,等待服务启动
  5. :wait_loop
  6. echo %i%
  7. set /a "i+=1"
  8. if %i% lss 4 (
  9. goto :wait_loop  
  10. )
  11. pause
复制代码
报错内容:
  1. 1
  2. '�动' is not recognized as an internal or external command,
  3. operable program or batch file.
  4. 2
  5. '�动' is not recognized as an internal or external command,
  6. operable program or batch file.
  7. 3
  8. Press any key to continue . . .
复制代码
我尝试了发现将“rem 轮询,等待服务启动”改成“rem 撒旦撒服务启动”或其他可以正常;或者将“chcp 65001 > nul ”去掉,然后保存成GBK编码可以正常;再或者在“rem 轮询,等待服务启动”下方插入一行空白行也能正常运行。

在我看来这种非常诡异,请问是隐藏的bug还是有我还没了解清除的规则?求解答,谢谢。
作者: terse    时间: 2024-4-29 07:07

这个应该是编码问题吧,这里的中文标点 “,”去掉
作者: czjt1234    时间: 2024-4-29 08:29

怀疑是rem后面,某个字的utf8编码,某个字节正好被设别为换行啊换页啊什么的
这样bat就认为rem语句结束了
作者: yanjujino1    时间: 2024-4-29 11:42

回复 2# terse
回复 3# czjt1234
将“轮询,等待服务启动” 改成其他句子进行了测试:
“等待服务启动” 正常
“轮询等待服务启动” 正常
“轮询,等待服务” 正常
“轮询和等待服务启动” 报错
“一二三四五六七八九” 正常
“哈二三四五六七八九” 报错
“轮二三四五六七八九” 报错
“一轮三四五六七八九” 正常
“一二三四五六七八动” 正常
“轮询,等待服务启动哈” 正常

目前测试下来还是找不到任何规律。
作者: 77七    时间: 2024-4-29 12:31

本帖最后由 77七 于 2024-4-29 12:33 编辑

第一次goto 之前不会报错,之前帖子是直接报错。不知道什么原因,自己测试,可以加引号
  1. rem "轮询,等待服务启动"
复制代码


之前帖子地址,http://www.bathome.net/thread-68691-1-7.html
作者: aloha20200628    时间: 2024-4-29 19:47

本帖最后由 aloha20200628 于 2024-4-29 19:49 编辑

回复 4# yanjujino1

脚本文件采用utf-8编码后,对用 ‘某些汉字’ 结尾的文本行会出现换行符误读而导致报错退出,如本例报错信息中的 ‘动’ 字即为行尾汉字。有一个规避方法》就是在本行末尾附加一个 ‘非汉字字符’ 如英文标点符号即可。

作者: qixiaobin0715    时间: 2024-4-30 08:42

本帖最后由 qixiaobin0715 于 2024-4-30 09:00 编辑

感觉是rem中文语句后紧跟goto标签:,预处理时出现的逻辑错误,rem语句和goto标签之间有其它任何语句出现,就不会有问题:
  1. @echo off
  2. chcp 65001 > nul
  3. set "i=1"
  4. rem 轮询,等待服务启动
  5. echo,good
  6. :wait_loop
  7. echo %i%
  8. set /a "i+=1"
  9. if %i% lss 4 (
  10. goto :wait_loop  
  11. )
  12. pause
复制代码

作者: holley    时间: 2024-4-30 08:56

本帖最后由 holley 于 2024-4-30 09:03 编辑

回复 1# yanjujino1


    测试 都不用加空行,加个空格即正常
你的几个测试 误导你了,,就是没有正常识别尾部的换行符
作者: Five66    时间: 2024-5-1 00:42

这确实挺莫名其妙的

用4楼的试了下 , 猜测:
goto 的标签以 ansi 方式识别的 , 大于0x80的被识别为双字节字符
utf-8字符总字节数为奇数时 , 最后一个字节跟\r被认为是双字节字符 , 导致无法识别\r\n , 出现了混乱 , 然后代码从无法识别的位置断开来了


作者: aloha20200628    时间: 2024-5-1 13:52

本帖最后由 aloha20200628 于 2024-5-1 13:53 编辑


1楼代码简化为如下代码(用utf-8存盘)依然可复现同类错误
  1. @echo off
  2. chcp 65001 > nul
  3. REM 九
  4. REM 九
  5. pause&exit/b
复制代码
但只要在第3行末尾附加一个非中文字符如 . 或空格即可规避...

作者: ppll2030    时间: 2024-5-2 23:26

全角字符惹的祸。




欢迎光临 批处理之家 (http://bathome.net./) Powered by Discuz! 7.2