Bash编程(Cygwin):非法字符^ M.

时间:2011-11-29 19:36:29

标签: windows bash cygwin bc

我的角色有问题。我认为这是dos和unix之间的转换问题。

我有一个浮点值的变量。 当我使用echo命令打印它时,我得到:

0.495959

但是当我尝试使用bc命令对该值进行操作时(我不知道如何编写bc命令)。

echo $mean *1000 |bc

我明白了:

(standard_in) 1 : illegal character: ^M

我已经在我的.sh文件中使用了dos2unix命令。 我认为这是因为我的变量有^ M字符(不是用echo命令打印)

如何消除此错误?

7 个答案:

答案 0 :(得分:11)

我没有Cygwin方便,但在常规Bash中,您可以使用tr -d命令去除指定的字符,并且可以使用$'...'表示法在命令中指定奇怪的字符-line参数(它类似于普通的单引号字符串,除了它支持C / Java / Perl /等类似的转义序列)。所以,这个:

echo "$mean" * 1000 | tr -d $'\r' | bc

将在从echobc的路上取消回车。

你可能真的想要运行它:

mean=$(echo "$mean" | tr -d $'\r')

将修改$mean以去除内部的任何回车符,然后您将不必在以后使用它的命令中担心它。

(虽然同样值得看一下开始设置$mean的代码。但$mean如何最终得到回车?也许你可以解决这个问题。 )

答案 1 :(得分:2)

这有效:

  

${mean/^M/}

您可以通过键入Ctrl-V然后按Ctrl-M来获取^ M.或者,或者:

  

${mean/$(printf "\r")/}

@ruakh 相比,此方法的好处在于,您只使用bash内置函数。第一个会更快,因为第二个将在子shell中运行。

如果你只是想“unixize”$ mean:

  

mean="${mean/^M/}"

编辑:还有另一种方式:

  

${mean/$'\r'/}

答案 2 :(得分:2)

你发现在cygwin中运行Windows的东西有一个令人讨厌的副作用 - 在cygwin bash变量中捕获Windows程序的输出也会捕获程序的CR输出。

明智地使用d2u可以避免这个问题 - 例如,

runtime="`mediainfo --Inform='Video;%Duration%' ${movie} | d2u`"

(如果没有d2u,$ {runtime}会在最后添加一个CR,这会导致您在将其提供给' bc'时所看到的问题。)

答案 3 :(得分:1)

也许您应该只以UNIX格式而不是DOS格式保存脚本。

答案 4 :(得分:0)

试试这个:

echo `echo $mean` *1000 |bc

如果echo确实没有打印它,它应该可以工作。

答案 5 :(得分:0)

^M是一个carriage return字符,在Windows中与换行符(\n)一起用于表示下一行。但是,它不是如何在UNIX世界中完成的,因此bash不会将其视为特殊字符而且会破坏语法。您需要做的是使用多种方法之一删除该字符。例如,dos2unix工具可以派上用场。

答案 6 :(得分:0)

正如其他人所指出的,这是一个Windows行结束问题。有很多方法可以解决这个问题,但问题是为什么这首先发生了。

我可以在几个地方看到这种情况:

  • 这是一个在Cygwin启动时设置的WINDOWS环境变量。有时这些变量会在它们的末尾获得CRLF。你提到这是这个变量的一个特殊问题,但是你没有指定它的设置位置。

  • 您使用Windows 文本 编辑器编辑此文件,例如记事本 Winpad

切勿使用文本编辑器编辑程序。使用程序编辑器。如果您喜欢VI,请下载Windows上可用的VIM,然后使用Cygwin(以及所有其他基于Unix的平台)。如果VIM不适合您,请尝试更基于图形的Notepad++。这两个编辑器都处理行尾问题,并且可以在Windows中使用Unix行结尾创建脚本,或者在Cygwin中创建具有Windows行结尾的文件。


  • 如果您使用VIM,您可以执行以下操作来更改行结尾并进行设置:

    • 要查看以当前文件结尾的行,请在命令模式下键入:set ff?
    • 要设置Unix的行结尾,请在命令模式下键入:set ff=unix
    • 要设置Windows的行结尾,请在命令模式下键入:set ff=dos
  • 如果您使用Notepad ++

    • 您可以进入编辑 - > EOL转换菜单项,查看当前行结束设置(未突出显示的设置)并进行更改。
    • 要让Notepad ++使用Unix行结尾作为默认值,请进入设置 - >首选项菜单项。在对话框中,选择新建文档/默认目录选项卡。在格式部分中,它是新文档部分的一部分,选择所需的行结尾。 警告: 不要选择Mac作为选项。这甚至不适用于Mac。如果您有Mac,请选择Unix
相关问题