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.