5

I'm calling bash from cmd.exe like this

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

and get on Cygwin 2.8.0

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

It treats the parameter as part of the command name. Doing the same on Cygwin 2.5.2 I get the output ф.

4
  • 3
    Are you sure it's the Φ that's causing the problem? Does it work if you run c:\cygwin\bin\bash --login -c "echo f"?
    – terdon
    Commented Apr 26, 2017 at 15:30
  • @terdon I can confirm that "echo ф" (and "echo å" etc.) fails while "echo f" works. I don't know if this is at all related to bash though, or if it's a cmd.exe thing.
    – Kusalananda
    Commented Apr 26, 2017 at 15:56
  • 1
    Can you confirm that the character between "echo" and "ф" is a plain ASCII space rather than something like a non-breaking space? Commented Apr 26, 2017 at 18:26
  • @Gordon Davisson It's a plain ascii space.
    – giraffes
    Commented Apr 26, 2017 at 23:45

3 Answers 3

8

Since this used to work, and works fine for people running bash on Unices (I tested on Debian here), I think you've found a Cygwin bug. The Cygwin project has a page about reporting Cygwin bugs. They have a bunch of useful information and steps there, far too long to summarize here.

In the meantime, I suspect you can work around this by escaping the character. Bash's echo, when given the -e flag, interprets various escape sequences:

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

should work. Hexadecimal D1 84 is the UTF-8 encoding of ф. If you have the unicode tool, it'll tell you—but so will just echoing the character to od or xxd:

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

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

The Cygwin FAQ tells me it uses UTF-8 by default, so that should work. But of course you can use other encodings too (I think Windows mostly uses UTF16le):

$ echo -n 'ф' | iconv -t utf16le | xxd -p
4404
2
  • FWIW, "echo -e '\xd1\x84'" works.
    – Kusalananda
    Commented Apr 26, 2017 at 16:24
  • @Kusalananda thanks, I don't have any Cygwin installs to test with.
    – derobert
    Commented Apr 26, 2017 at 16:25
3

This happens because cmd.exe adds an additional pair of quotes around arguments with non-ASCII characters. So what actually arrives at the cygwin application is the following:

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

So bash can interpret 'echo blo', but:

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

Now bash does not recognize '"echo blöd"'.

1

The analysis from user1274247 is the right one.

We therefore need to find a way to strip the leading and trailing quotes, when cmd.exe doubles them without our knowing.

I was having the exact same issue when dealing with paths containing spaces, single quotes and non-ascii characters. I solved it by separating the bash command to execute (aka -c) and the problematic string parameter.

According to 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. 

Our command therefore becomes:

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

Or, if you prefer using the mintty terminal:

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

And if you wanna use it in regedit (to launch a bash command when right-clicking a file), here's the proper escaping (for quotes and %):

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

I'm using it, for example, to duplicate files (extract from a bigger 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\" "

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .