Search code examples
shellcygwinnewline

Shell script works in the console but not when saved as a text file


Consider this simple shell script:

#!/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

When I paste it to a cygwin window it works fine however when I save it as a text file test.sh and run it from the cygwin terminal I'm getting this:

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

However, if I remove newlines it works:

#!/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

How can I make the script more readable by maintaining new lines in the file, \n doesn't seem to work.


Solution

  • Your \r characters come from a Windows file, where the new lines are defined with \r\n. In UNIX the new line is defined just with \n, hence the \r stays "orphan" and causes these problems.

    What you can do is to convert the file to UNIX mode with the command dos2unix.

    More info in: Does Windows carriage return \r\n consist of two characters or one character?:

    Two characters combined represent a new line on Windows. Whereas on Linux, \n represents new line. It moves cursor to the start of new line on Linux. On Windows, the cursor will stay at the same column in the console but on the next line.

    • \r is carriage return;
    • \n is line feed.