Cygwin bash コマンドラインで非 ASCII を使用するとエラーが発生する

Cygwin bash コマンドラインで非 ASCII を使用するとエラーが発生する

私はcmd.exeからbashを次のように呼び出しています

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

Cygwin 2.8.0 を入手

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

パラメータはコマンド名の一部として扱われます。 Cygwin 2.5.2 で同じことを実行すると、出力は次のようになりますф

答え1

これは以前は機能していたし、Unixでbashを実行している人でも問題なく機能するので(Debianでテストしました)、Cygwinのバグを見つけたと思います。Cygwinプロジェクトには、Cygwinのバグを報告するそこにはたくさんの役に立つ情報と手順が記載されていますが、ここで要約するには長すぎます。

とりあえず、文字をエスケープすることでこの問題を回避できると思います。Bash の はecho、フラグが指定されると-e、さまざまなエスケープ シーケンスを解釈します。

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

動作するはずです。16進数はD1 84фのUTF-8エンコードです。unicodeツールがあればそれがわかりますが、文字を または にエコーするだけでもわかりodますxxd

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

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

Cygwin FAQによると、デフォルトでUTF-8が使用されるとのことなので、これで動作するはずです。もちろん、他のエンコーディングも使用できます(Windowsでは主にUTF16leが使用される):

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

答え2

これは、cmd.exe非 ASCII 文字を含む引数の周囲に引用符のペアを追加することで発生します。したがって、cygwin アプリケーションに実際に届くのは次のようになります。

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

したがって、bash は ' echo blo' を解釈できますが、次のようになります。

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

現在、bash は ' ' を認識しません"echo blöd"

答え3

user1274247 の分析は正しいものです。

したがって、cmd.exe が知らないうちに先頭と末尾の引用符を二重に使用した場合に、先頭と末尾の引用符を削除する方法を見つける必要があります。

スペース、一重引用符、非 ASCII 文字を含むパスを扱うときに、まったく同じ問題が発生していました。実行する bash コマンド (別名-c) と問題のある文字列パラメータを分離することで解決しました。

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. 

したがって、私たちの命令は次のようになります。

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

または、mintty ターミナルを使用する場合は、次のようにします。

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

また、regedit でこれを使用したい場合 (ファイルを右クリックしたときに bash コマンドを起動するため)、適切なエスケープ方法は次のとおりです (引用符と %)。

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\""

たとえば、ファイルを複製するためにこれを使用しています(大きなツールボックスから抽出します)。

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\" "

関連情報