Kann die UTF-8-Codepage-ID (65001) auf anderen Computern unterschiedlich sein?

1620
Annonymus

Ich habe vor kurzem versucht, einem Freund zu erklären, wie man eine einfache einzeilige Batchdatei erstellt:

subst t: "X:\Example" 

Auf meinem Computer funktionierte das seit Jahren einwandfrei, aber auf ihrem Computer stieß ich auf ein Problem: Ihr Name enthielt Nicht-ASCII-Zeichen (die türkischen Zeichen ı und ç, um genau zu sein), die nicht richtig erkannt wurden.

Die einfache Lösung dazu würde ich hinzufügen

chcp 65001 

am oberen Rand der Datei, um die aktive Codepage in die UTF-8-Codepage zu ändern.

Das hat aber nicht geklappt. Auf ihrem Computer verursachte dies einen Absturz der Befehlsshell, die sie ausführte. Ich ließ sie einige verschiedene Werte ausprobieren; 65000 stürzte ab, aber 10000 funktionierte nicht, und alle Werte, die unter den Werten lagen, die ich ausprobiert hatte, funktionierten zwar nicht, entsprachen jedoch nicht den gleichen Codeseiten wie dieselben Werte auf meinem Computer. Ihre Standard-Codepage war ebenfalls unterschiedlich (857 statt 850 auf meinem Computer. Dies ist sinnvoll, da laut MSDN 857 eine türkische und 850 eine westeuropäische Codepage ist).

Ich weiß, dass einige Codepages von Computer zu Computer wechseln können, aber auf der MSDN-Seite wird ausdrücklich angegeben, dass UTF-8 verwendet werden sollte, da sich die anderen Seiten ändern können (obwohl es anstrengende Dokumentation darüber gibt, wie und wann sie sich ändern).

Ist das falsch? Kann sich auch der Wert von 65001 ändern? Wenn ja, warum würde das einen Absturz verursachen? Sollte es sich im schlimmsten Fall nicht über "Ungültige Codeseite" beschweren? Und wenn es sich ändert, wie kann man herausfinden, welchen Wert es verwenden soll, oder wie kann ich es sonst dazu bringen, Nicht-ASCII-Zeichen zu akzeptieren?

Ich verwende Windows 10 mit der englischen Sprache (es war vorinstalliert mit Windows 8.1 Italienisch), während mein Freund Windows 7 Türkisch verwendet.

2
"am Anfang der Datei" Haben Sie die Batchdatei mit UTF-8-Kodierung gespeichert? dxiv vor 7 Jahren 0
@dxiv ja, ich tat (und stellte sicher, dass mein Freund es auch tat) Annonymus vor 7 Jahren 0

1 Antwort auf die Frage

2
JosefZ

Grundsätzlich ist Windows cmd(und sein Batch-Script-Interpreter) auf die Konformität (aktueller) aktiver Codepage und Batch-Script-Kodierung angewiesen. Zum Beispiel, wenn Sie einen Skript aus speichern Notepadin sogenannter ANSI - Codierung (die auf stark abhängig Windows - Systemgebietsschema ), dann sollten Sie es unter entsprechender Codepage finden Sie unter National Language Support (NLS) API - Referenz :

  • English (US) : ANSI entspricht ACP 1252(CP 437),
  • English (UK) : ANSI entspricht ACP 1252(CP 850),
  • Turkish : ANSI entspricht ACP 1254(CP 857),
  • Central Europe: ANSI entspricht ACP 1250(CP 852) usw.

Ihre Vermutung ist richtig:

Die einfache Lösung dazu wäre, ich würde chcp 65001 am Anfang der Datei hinzufügen , um die aktive Codepage in eine UTF-8- Datei zu ändern. … Aber das hat nicht funktioniert.

Leider cmdkümmert sich weder Windows noch Batch Interpreter um Byte Order Mark und behandeln sie als gültiges Zeichen, wobei die derzeit aktive Codepage nicht berücksichtigt wird.
Daher ist die erste Zeile ( CHCP 65001in Ihrem Fall der Befehl) einer UTF-8- codierten Datei verschmutzt, wenn die Stückliste vorhanden ist. ein Versuch, so laufen schmuddeligen Befehl würde zu Fehlermeldung führt ' CHCP' is not recognized as an internal or external command, operable program or batch file(Errorlevel 9009).

Lösung: Speichern Sie Ihr Skript UTF-8- codiert ohne Stückliste .
Umgehung, wenn Sie dies nicht tun können (wie Notepadimmer schreibt BOM): Verwenden Sie als erste Zeile Ihres Skripts einen Dummy-Befehl, z. B. wie folgt:

@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% 

Ausgabe :

==> 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 

Schließlich können Sie die erste Zeile (mit der Stückliste) mit folgendem moreBefehl aus dem Skript entfernen (Hinweis chcp 65001vor dem Ausführen 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  ==>