Parece que sci.txt não termina em um novo caractere de linha. Conforme explicado em man ksh , o read builtin lê o primeiro caractere de nova linha por padrão:
read [ -ACSprsv ] [ -d delim] [ -n n] [ [ -N n] [ [ -t timeout] [ -u
unit] [ vname?prompt ] [ vname ... ]
The shell input mechanism. One line is read and is broken up
into fields using the characters in IFS as separators. The
escape character, \, is used to remove any special meaning for
the next character and for line continuation. The -d option
causes the read to continue to the first character of delim
rather than new-line.
Portanto, a menos que você use -d , ele estará procurando por um caractere de nova linha. Se o seu arquivo não tiver um, ele realmente não lerá nada. Para ilustrar:
$ printf 'demo1|demo2|demo3\n' > sci.newline
$ printf 'demo1|demo2|demo3' > sci.nonewline
$ cat foo.sh
#!/usr/bin/ksh
for file in sci.newline sci.nonewline; do
echo "Running on: $file"
while IFS='|' read -r fdate rdate dcname
do
echo "$fdate $rdate $dcname"
done < "$file"
done
A execução deste script retorna a saída esperada em sci.newline , mas nada para sci.nonewline :
$ foo.sh < sci.nonewline
Running on: sci.newline
demo1 demo2 demo3
Running on: sci.nonewline
Portanto, se o arquivo terminar com uma nova linha ( \n ), tudo funcionará como esperado.
Agora, a razão pela qual sua instrução echo funciona fora do loop é porque o loop nunca é executado. Quando read não encontra um caractere \n , ele retorna um status de saída não-0 (com falha). A construção while SOMETHING; do será executada apenas enquanto SOMETHING for bem-sucedida. Como read falha, o loop nunca é executado e o echo dentro do loop não é executado. Em vez disso, o script executará o comando read e atribuirá as variáveis e, como a falha read retornará, passará para a próxima parte. É por isso que o próximo echo , o fora do loop, funciona como esperado.