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

由于这曾经有效,并且对于在 Unices 上运行 bash 的人来说工作得很好(我在这里在 Debian 上进行了测试),我认为您已经发现了 Cygwin 错误。 Cygwin 项目有一个关于报告 Cygwin 错误。他们那里有很多有用的信息和步骤,太长了,无法在这里总结。

与此同时,我怀疑你可以通过逃避角色来解决这个问题。 Bash 的echo,当给定-e标志时,解释各种转义序列:

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

应该管用。十六进制D1 84是 ф 的 UTF-8 编码。如果您有该unicode工具,它会告诉您,但只会将字符回显为odor 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\" "

相关内容