Bash – Read the files in shell script doesn’t print out anything

bashcygwin;shelltext;

I am trying to read a file from shell script line by line. Below is my file content –

hello=world

And below is my shell script that I have written –

#!/bin/bash

while read -r line; do
       echo "$line"
    done < test.txt

But somehow whenever I am running from my cygiwn terminal, I don't see any result printing out on the console –

I run it like this –

$ sh read.sh

And it doesn't print out anything. And I am not sure what wrong I am doing here.

Best Answer

In the unix world, a newline is a line terminator, not a line separator. A text file consists of a series of lines, each of which is terminated by a newline character. This is a linefeed character (character number 10, which can be represented as LF, ^J, \012, \x0a, \n, …). See What's the point in adding a new line to the end of a file?

In particular, every non-empty text file ends with a newline character. Windows sometimes works differently: in some applications, (but not all! Windows is not consistent), a CR LF sequence (carriage return, line feed, a.k.a. ^M^J, \015\012, \x0d\x0a, \r\n, …) separates lines, so a file that ends in CRLF is a file that ends in a blank line. So beware when you use a Windows editor to edit files that are meant to be used elesewhere:

  • They add this extra CR character before the newline character, which some unix applications (in particular shells) treat as an ordinary character, part of the line.
  • They make you believe that there's a blank line after the last newline character, whereas the last newline actually terminates the last line.

If a file is not empty and does not end in a newline, it isn't a well-formed unix text file. Some applications react by ignoring the last partial line, or by truncating it. That's what's happening here: you passed an incomplete text file to bash, and it's ignoring the last, incomplete line.

Related Question