
我像這樣從 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
由於這曾經有效,並且對於在 Unices 上運行 bash 的人來說工作得很好(我在這裡在 Debian 上進行了測試),我認為您已經發現了 Cygwin 錯誤。 Cygwin 專案有一個關於報告 Cygwin 錯誤。他們那裡有很多有用的信息和步驟,太長了,無法在這裡總結。
同時,我懷疑你可以透過逃避角色來解決這個問題。 Bash 的echo
,當給定-e
標誌時,解釋各種轉義序列:
c:\cygwin\bin\bash --login -c "echo -e '\xd1\x84'"
應該管用。十六進位D1 84
是 ф 的 UTF-8 編碼。如果您有該unicode
工具,它會告訴您,但只會將字元回顯為od
or 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
使用者1274247的分析是正確的。
因此,當 cmd.exe 在我們不知情的情況下將它們加倍時,我們需要找到一種方法來去除前導和尾隨引號。
在處理包含空格、單引號和非 ASCII 字元的路徑時,我遇到了完全相同的問題。我透過分離要執行的 bash 命令(又名-c
)和有問題的字串參數來解決這個問題。
根據 bash 人的說法:
-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\" "