Shell脚本在控制台中工作,但在保存为文本文件时不起作用

时间:2014-10-06 12:31:18

标签: shell cygwin newline

考虑这个简单的shell脚本:

#!/bin/sh
fruitlist="Apple Pear Tomato Peach Grape"
for fruit in $fruitlist
do
   if [ "$fruit" = "Tomato" ] || [ "$fruit" = "Peach" ]
   then
      echo "I like ${fruit}es"
   else 
      echo "I like ${fruit}s"
   fi
done

当我将它粘贴到cygwin窗口时,它工作正常但是当我将其保存为文本文件test.sh并从cygwin终端运行时我得到了这个:

$ ./test.sh
./test.sh: line 4: syntax error near unexpected token `$'do\r''
'/test.sh: line 4: `do

但是,如果删除换行符,则可以使用:

#!/bin/sh
fruitlist="Apple Pear Tomato Peach Grape"
for fruit in $fruitlist
do if [ "$fruit" = "Tomato" ] || [ "$fruit" = "Peach" ]
   then echo "I like ${fruit}es"
   else echo "I like ${fruit}s"
fi done

如何通过在文件中保留新行来使脚本更具可读性,\n似乎无法正常工作。

4 个答案:

答案 0 :(得分:5)

您的\r个字符来自Windows文件,其中新行定义为\r\n。在UNIX中,新行仅使用\n定义,因此\r保持"孤儿"并导致这些问题。

您可以使用命令dos2unix将文件转换为UNIX模式。

更多信息:Does Windows carriage return \r\n consist of two characters or one character?

  

两个字符组合代表Windows上的新行。而在   Linux,\n代表新行。它将光标移动到新的开头   在Linux上排队。在Windows上,光标将保留在同一列中   控制台,但在下一行。

     
      
  • \r是回车;
  •   
  • \n是换行符。
  •   

答案 1 :(得分:1)

没有回答这个问题。

case声明适合这里。以及一个实际的数组。

fruitlist=( Apple Pear Tomato Peach Grape )
for fruit in "${fruitlist[@]}"; do
    case $fruit in
        Tomato|Peach) echo "I like ${fruit}es" ;;
        *) echo "I like ${fruit}s" ;;
    esac
done

答案 2 :(得分:0)

我总是将以下标题添加到我的shell脚本中,让cygwin忽略CR:

#!/bin/sh
if [ "$OSTYPE" = "cygwin" ]; then shopt -s igncr 2>/dev/null; fi # New version of Cygwin complains itself of CR

请注意,第二行末尾的注释是强制性的。

答案 3 :(得分:0)

要修复cygwin的具有Windows行尾字符的脚本的运行,而无需编辑脚本或安装dos2unix:

将这些行添加到~/.bash_profile,然后重新启动cygwin

export SHELLOPTS
set -o igncr

Credit