There are two points, here.

        First, you're using an old version of ksh.

        Second, ksh has a different spin from bash on reading fixed-length
data. Read sees variables in two flavors, text and binary. When read
puts characters into a textual variable newlines are always changed to a
null character which serves as a string terminator. Also, when ksh reads
fixed-length data, characters continue to fill the buffer after a
newline is read. Thus, any characters read into your "line" variable
after a newline will effectively disappear.

        When I run your test with ksh-20140929, I get these results:

'ABCDEFGHIJ123456'
'7890'
'234567890'

The first 16 characters are put into line as expected and printf %s
displays them. In the next loop iteration read puts another 16
characters into line but changes the newline to a null character. Printf
%s sees the null character as end-of-string and prints only 7890.
Characters 6 through 16 (abcdefghij1) in line can't be seen using printf
%s. In the final iteration the remaining characters are put in line and
printf %s displays them.

        If you don't want ksh to change newlines to null characters in
fixed-length data, you need to use binary variables. Binary variables
are declared with typeset -b. To print binary variables you should use
printf %B. As with textual variables read will continue to fill the
buffer after a newline is read. I modified your example for binary
variables as follows:

typeset -b line
while IFS= read -n16 -r line
do
        printf -- "'%B'\n" line
done <<EOT
ABCDEFGHIJ1234567890
abcdefghij1234567890
EOT

This produced the following output:

'ABCDEFGHIJ123456'
'7890
abcdefghij1'
'234567890
'

It might be more appropriate to change "line" to "buffer" to go along
with ksh's behavior.

        It's still different from bash, but I'm content letting ksh be ksh and
bash be bash. I don't know if the new bash compatability-mode makes
reading fixed-length data closer to bash's style.

                                        Terrence Doyle

On 3/15/15 9:10 AM, Janis Papanagnou wrote:
> I observe a problem (see testcase below) with ksh's read -n.
> (Version 93t 2008-11-04 on Cygwin).
> Bash's behaviour would be what I expect.
> Ksh doesn't read the second line and doesn't terminate output.
> (Maybe an old bug fixed in newer versions? Or am I missing something?)
> 
> --snip--
> 
> $ cat readtest
> while IFS= read -n16 -r line
> do
>   printf "'%s'\n" "$line"
> done <<EOT
> ABCDEFGHIJ1234567890
> abcdefghij1234567890
> EOT
> 
> $ bash readtest | head
> 'ABCDEFGHIJ123456'
> '7890'
> 'abcdefghij123456'
> '7890'
> 
> $ ksh readtest | head
> 'ABCDEFGHIJ123456'
> '7890'
> ''
> ''
> ''
> ''
> ''
> ''
> ''
> ''
> 
> $ ksh --version
>   version         sh (AT&T Research) 93t 2008-11-04
> 
> --snip--
> 
> 
> 
> _______________________________________________
> ast-users mailing list
> [email protected]
> http://lists.research.att.com/mailman/listinfo/ast-users

_______________________________________________
ast-users mailing list
[email protected]
http://lists.research.att.com/mailman/listinfo/ast-users

Reply via email to