
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. echo
Wenn 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 84
ist die UTF-8-Kodierung von ф. Wenn Sie das Tool haben , wird es Ihnen das sagen – aber auch, wenn Sie das Zeichen einfach als oder unicode
ausgeben :od
xxd
$ 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.exe
Argumente 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\" "