5

I've got the bc command installed in Windows via Cygwin.

I try to use noninteractive bc mode via Command Prompt (not via a Cygwin prompt).

I got an error:

C:\Users\Peter>echo 1+1 | bc
(standard_in) 1: illegal character: ^M

I didn't get any success with these commands:

echo "1+1" | bc
echo '1+1' | bc

How can I make it work?

P.S.: Interactive mode works fine.

2 Answers 2

8

The problem here is that the Cygwin utilities such as bc follow UNIX/Linux and expect LF as the line terminator, but the Windows CMD echo generates the Windows-standard CR/LF combination as its line terminator:

CMD> echo 1+1 >file.txt

bash$ od -tx1 file.txt
0000000 31 2b 31 20 0d 0a
0000006

Hex codes 31 and 2b represent characters 1 and + respectively. Notice that echo also includes the trailing space character between the second 1 and the redirection operator > before terminating the line with 0d 0a.

I know of no clean way around this, so you have to strip the CR using another tool such as tr:

CMD> echo 1+1 | tr -d '\r' | bc
2

Best would be to avoid mixing Windows CMD and Cygwin entirely. For example, use the Cygwin echo rather than the one from Windows CMD. Or even bash -c "/usr/bin/bc <<<'1+1'" (although if you're not careful that will fire up WSL instead of using Cygwin).

As an aside your alternate attempts actually include the quotation marks in the text sent to bc. Windows CMD echo literally copies its entire line onwards, including any trailing spaces:

CMD> echo "1+1" >file
CMD> type file
"1+1" 

CMD> echo '1+1' >file
CMD> type file
'1+1' 
13
  • 1
    One way to get beyond this; Do not use CMD and Place Windows CMD-related items in Windows %PATH% AFTER those aimed for Cygwin (this does not help for cmd builtins!), then restart Cygwin. Even better: install Git Bash instead, my experience is that it behaves better in THIS regard at least. Commented Apr 11 at 11:03
  • 1
    Note also: cmd find <=> same aim as "grep" in cygwin. find in cygwin is something that cannot be done in cmd, beside dir and its simple list option(s). My advice is: stop using cmd and the cmd-"terminal" - remove from any use. Commented Apr 11 at 11:07
  • 3
    @Hannu if you're talking to me you're preaching to the converted. I don't mix'n'match CMD and Cygwin. (I have a few non-Cygwin but UNIX-like utilities compiled for Windows that do handle CR+NL, but they're very specialist and not part of my daily driver toolset.) Commented Apr 11 at 11:14
  • 1
    For what it is worth, it is comment and detail not present in your posting, as this is a public forum, the answer MIGHT be complemented by the comments ;-) so not not really for you personally. I've been handling this kind of trouble since the mid 1980's in different machine setups. ;-) Commented Apr 11 at 12:35
  • 2
    @Hannu thankyou. Already incorporated, "Best would be to avoid mixing Windows CMD and Cygwin entirely..." Commented Apr 11 at 12:40
1

The issue comes from mixed setup between Windows and CygWin environment. And especially representation of new line. (Thanks to @ChrisDavies for the great analysis!)

bc command expects linux/unix new-line format but echo outputs win new-line format. Universal approach for mixed unvironments is to use all command from same environment so we need linux echo command:

CMD> %CYGWIN%\bin\echo 1+1 | bc

Because I use mixed environment a lot I have got a batch file to execute linux commands called linux.bat – when Windows and Linux filenames match (e.g. echo, find, etc). Its accessible directly (registered in %PATH%) and its pretty simple:

CMD> cat linux.bat
@%CYGWIN%\bin\%*

In such setup, fix looks this way:

linux echo 1+1 | bc

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.