2

According to the manual for read (and since it is a builtin, not man read, but help read):

-N nchars Return only after reading exactly NCHARS characters, unless EOF is encountered or read times out, ignoring any delimiter

However, even if the -N flag is used, read still seems to want to strip out the delimeter from input data. Take the following data as an example:

# readfail.sh - Reads 5 characters at a time, and adds "RegEx style" start and end characters for clarity
while read -r -N 5 data; do
    echo "^${data}\$"
done;

echo "^${data}\$"  # There will be data left over just because of the way `read` uses exit codes

And here is the output:

$ echo -n "Lorem ipsum dolor sit amet" | ./readfail.sh
^Lorem$
^ipsu$
^m dol$
^or si$
^t ame$
^t$

Notice the second line is only 4 characters long. That is because there is supposed to be a space between Lorem and ipsum, resulting in the following five-character output: ^ ipsu$

I can fix this problem by setting IFS= before the loop, however, isn't read supposed to be ignoring any delimiters because of the -N flag? Is this a bug, or intended behavior?

1 Answer 1

2

-N causes the end-of-line delimiter to be ignored. Bash reads exactly the specified number of characters no matter what these characters are. This is independent from the way what had been read is reported to the script in the form of variable content. That uses the usual IFS splitting mechanism.

3
  • I don't follow, where is the "... is reported to the script in the form of variable content" step being taken?
    – IQAndreas
    Apr 5, 2015 at 5:45
  • I could imagine this problem happening if you do something like data=$(read -N 5) (I'm not sure if that code actually works, I just mean the assigned value isn't being escaped, and would be equivalent to data=[space]ipsu). However, in this case we are "magically" filling the $data variable by passing the data string to the read command.
    – IQAndreas
    Apr 5, 2015 at 5:47
  • @IQAndreas read data reports the data that it read by setting data to what it read, after IFS-based splitting. read -N 5 reads 5 bytes, and splits them according to the usual rules. That's its job. The option -N controls how many bytes are read, not how many bytes are put in variables. Apr 5, 2015 at 22:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.