По сути, Windows cmd
(и ее интерпретатор пакетных сценариев) зависит от соответствия (текущей) активной кодовой страницы и кодировки пакетных сценариев. Например, если вы сохраняете сценарий Notepad
в так называемой кодировке ANSI (что сильно зависит от языкового стандарта системы Windows ), вам следует запустить его в соответствующей кодовой странице, см. Справочник по API поддержки национальных языков (NLS) :
English (US) :
ANSI соответствует ACP1252
(CP437
),English (UK) :
ANSI соответствует ACP1252
(CP850
),Turkish :
ANSI соответствует ACP1254
(CP857
),Central Europe:
ANSI соответствует ACP1250
(CP852
) и т. Д.
Ваше предположение верно:
Простое решение этого, которое я хотел бы добавить
chcp 65001
в верхней части файла, чтобы изменить активную кодовую страницу на UTF-8. ... Но это не сработало.
К сожалению, ни Windows, cmd
ни пакетный интерпретатор не заботятся о метке байтового порядка и рассматривают ее как действительный символ - независимо от текущей активной кодовой страницы.
Следовательно, первая строка ( CHCP 65001
команда в вашем случае) файла в кодировке UTF-8 загрязняется, если присутствует спецификация; Попытка выполнить такую грязную команду приведет к сообщению об ошибке ' CHCP' is not recognized as an internal or external command, operable program or batch file
(errorlevel 9009
).
Решение: Сохраните сценарий UTF-8, закодированный без BOM .
Обходной путь, если вы не можете сделать это (как Notepad
всегда пишет BOM): используйте пустую команду в качестве первой строки вашего скрипта, например, следующим образом:
@rem if this line is visibly executed then BOM is present >NUL 2>&1 @echo OFF rem save current code page to the `_chcp` variable for /F "tokens=2 delims=:" %%G in ('chcp') do set "_chcp=%%G" rem change active code page to UTF-8 (silently) CHCP 65001 >NUL rem echo this is UTF-8 encoded batch file %~nx0 echo( subst t: "D:\bat\Unusual Names\Türkçe (Türkiye)\çğüşöıĞÜİŞÇÖ" subst dir /B /S t:\*.txt subst t: /D echo( echo( works as well for characters from Unicode Basic Multilingual Plane subst t: "D:\bat\Unusual Names\CJK\中文(繁體)" subst dir /B /S t:\*.txt subst t: /D echo( echo( works even for characters from Unicode Supplementary Multilingual Plane subst t: "D:\bat\Unusual Names\" subst dir /B /S t:\*.txt subst t: /D rem set active code page back to previously saved value (verbose) echo( CHCP %_chcp%
Выход :
==> utf8.bat ==> ´╗┐@rem if this line is visibly executed then BOM is present 1>NUL 2>&1 T:\: => D:\bat\Unusual Names\Türkçe (Türkiye)\çğüşöıĞÜİŞÇÖ t:\ĞÜİŞÇÖçğüşöı.txt works as well for characters from Unicode Basic Multilingual Plane T:\: => D:\bat\Unusual Names\CJK\中文(繁體) t:\chinese traditional.txt works even for characters from Unicode Supplementary Multilingual Plane T:\: => D:\bat\Unusual Names\ t:\Mathematical Bold Script.txt Active code page: 852
Наконец, вы можете удалить первую строку (содержащую спецификацию) из вашего скрипта, используя more
команду следующим образом (обратите внимание chcp 65001
перед запуском more +1 …
):
==> chcp 65001 Active code page: 65001 ==> more +1 utf8.bat > utf8noBOM.bat ==> utf8noBOM.bat T:\: => D:\bat\Unusual Names\Türkçe (Türkiye)\çğüşöıĞÜİŞÇÖ t:\ĞÜİŞÇÖçğüşöı.txt works as well for characters from Unicode Basic Multilingual Plane T:\: => D:\bat\Unusual Names\CJK\中文(繁體) t:\chinese traditional.txt works even for characters from Unicode Supplementary Multilingual Plane T:\: => D:\bat\Unusual Names\ t:\Mathematical Bold Script.txt Active code page: 65001 ==>