Nicht-ASCII in der Cygwin-Bash-Befehlszeile verursacht einen Fehler

Nicht-ASCII in der Cygwin-Bash-Befehlszeile verursacht einen Fehler

Ich rufe Bash von cmd.exe aus so auf

c:\cygwin\bin\bash --login -c "echo ф"

und holen Sie sich Cygwin 2.8.0

/usr/bin/bash: echo ф: command not found

Es behandelt den Parameter als Teil des Befehlsnamens. Wenn ich das Gleiche unter Cygwin 2.5.2 mache, erhalte ich die Ausgabe ф.

Antwort1

Da dies früher funktionierte und auch für Leute, die Bash unter Unix ausführen, gut funktioniert (ich habe es hier unter Debian getestet), denke ich, dass Sie einen Cygwin-Fehler gefunden haben. Das Cygwin-Projekt hat eine Seite überCygwin-Fehler melden. Sie enthalten dort eine Menge nützlicher Informationen und Schritte, die jedoch viel zu lang sind, um sie hier zusammenzufassen.

In der Zwischenzeit können Sie das Problem vermutlich umgehen, indem Sie das Zeichen maskieren. echoWenn Bash das Flag erhält -e, interpretiert es verschiedene Escape-Sequenzen:

c:\cygwin\bin\bash --login -c "echo -e '\xd1\x84'"

sollte funktionieren. Hexadezimal D1 84ist die UTF-8-Kodierung von ф. Wenn Sie das Tool haben , wird es Ihnen das sagen – aber auch, wenn Sie das Zeichen einfach als oder unicodeausgeben :odxxd

$ echo -n 'ф' | od -t x1
0000000 d1 84
0000002

$ echo -n 'ф' | xxd -p
d184

In den Cygwin-FAQs steht, dass standardmäßig UTF-8 verwendet wird, also sollte das funktionieren. Aber natürlich können Sie auch andere Kodierungen verwenden (ich glaubeWindows verwendet meist UTF16le):

$ echo -n 'ф' | iconv -t utf16le | xxd -p
4404

Antwort2

Dies geschieht, weil cmd.exeArgumente mit Nicht-ASCII-Zeichen zusätzlich mit Anführungszeichen versehen werden. Was also tatsächlich bei der Cygwin-Anwendung ankommt, ist Folgendes:

C:\cygwin\bin\bash --login -c "echo blo"
arg0: /usr/bin/bash
arg1: --login
arg2: -c
arg3: echo blo

Bash kann also ' echo blo' interpretieren, aber:

C:\cygwin\bin\bash --login -c "echo blöd"
arg0: /usr/bin/bash
arg1: --login
arg2: -c
arg3: "echo blöd"

Jetzt erkennt Bash ' "echo blöd"' nicht.

Antwort3

Die Analyse von user1274247 ist richtig.

Wir müssen daher einen Weg finden, die führenden und nachfolgenden Anführungszeichen zu entfernen, wenn cmd.exe sie ohne unser Wissen verdoppelt.

Ich hatte genau das gleiche Problem beim Umgang mit Pfaden, die Leerzeichen, einfache Anführungszeichen und Nicht-ASCII-Zeichen enthielten. Ich habe es gelöst, indem ich den auszuführenden Bash-Befehl (auch bekannt als -c) und den problematischen String-Parameter getrennt habe.

Laut Bash Man:

-c string
If the -c option is present, then commands are read from string. If there are arguments after the string, they are assigned to the positional parameters, starting with $0. 

Unser Befehl lautet daher:

C:\cygwin\bin\bash.exe -lc 'a="${0%\"}"; a="${a#\"}";echo "$a"; sleep 10' "C:\spa ces\quo'tes\nonàscîï"

Oder, wenn Sie lieber das Mintty-Terminal verwenden möchten:

C:\cygwin\bin\mintty.exe /bin/bash -lc 'a="${0%\"}"; a="${a#\"}";echo "$a"; sleep 10' "C:\spa ces\quo'tes\nonàscîï"

Und wenn Sie es in Regedit verwenden möchten (um einen Bash-Befehl zu starten, wenn Sie mit der rechten Maustaste auf eine Datei klicken), hier ist das richtige Escape-Zeichen (für Anführungszeichen und %):

Windows Registry Editor Version 5.00

[HKEY_CURRENT_USER\Software\Classes\*\shell\Test]
@="echo filename in bash"

[HKEY_CURRENT_USER\Software\Classes\*\shell\Test\command]
@="C:\\cygwin\\bin\\mintty.exe /bin/bash -lc ' a=\"${0%%\\\"}\"; a=\"${a#\\\"}\";echo \"$a\"; sleep 10 ' \"%1\""

Ich verwende es beispielsweise zum Duplizieren von Dateien (Auszug aus einer größeren Toolbox):

Windows Registry Editor Version 5.00

[HKEY_CURRENT_USER\Software\Classes\*\shell\Duplicate]
@="Duplicate file"

[HKEY_CURRENT_USER\Software\Classes\*\shell\Duplicate\command]
@="C:\\cygwin\\bin\\mintty.exe /bin/bash -lc ' a=\"${0%%\\\"}\"; a=\"${a#\\\"}\" ; cd \"$(dirname \"$(cygpath \"$a\")\")\"; f=\"$(basename \"$a\")\" ; n=\"$(basename \"$a\" \".${f##*.}\")\" ; cp \"${f}\" \"${n}-copy.${f##*.}\"   ' \"%1\" "

verwandte Informationen