helpThe GNU Bourne-Again SHell - Support: sr #108956, Lone trailing input field...

 
 

sr #108956: Lone trailing input field separator is stripped by read (bash >=3)

Submitted by:  Chris Taylor <cttttt>
Submitted on:  Sat 23 Jan 2016 12:54:21 AM UTC  
 
Category: NonePriority: 5 - Normal
Severity: 3 - NormalStatus: Invalid
Privacy: PublicAssigned to: None
Open/Closed: OpenOperating System: GNU/Linux

Add a New Comment(Rich Markup)
   

You are not logged in

Please log in, so followups can be emailed to you.

 

Tue 26 Jan 2016 08:00:18 PM UTC, comment #1:

This was clarified by the Posix working group back in 2005. The characters in $IFS are delimiters, and the delimiters are field terminators. There is some special-casing done with IFS whitespace, all described in the word splitting portion of the man page.

The `read' builtin uses the same rules as word splitting, so each instance of a delimiter terminates a field. The text about leftover words and intervening separators applies to cases where there are more words in the input than variable arguments supplied to `read', which isn't the case in your examples.

Finally, I don't get anything close to your results going all the way back to bash-2.05b. Both commands in your message result in

|foo|bar|

which is correct. ksh, dash, mksh, and zsh all print the same thing.

Now, if you take the `null' variable out of your commands, I can see getting the results you do. The Posix clarification happened between bash-2.05b and bash-3.2, so that's when the behavior changed to match the standard.

There is disagreement among shell implementations concerning the text `fewer vars than fields' but the Posix description of `read' (http://pubs.opengroup.org/onlinepubs/9699919799/utilities/read.html#tag_20_109) makes it pretty clear that bash is doing the right thing.

Chet Ramey <chet>
Project Administrator
Sat 23 Jan 2016 12:54:21 AM UTC, original submission:

Seems like when "read" is:

- Supplied a custom input field separator via IFS.
- Is given X variable names.
- Is given an input line with X (the same number of) fields.
- The input line is ends in a single input field separator.

...the trailing input field separator is trimmed. However, where there are two or more trailing input field separators, they are left intact. Seems like this inconsistency started in Bash 3.

What do I do?
---

Run the following:

echo "foo=bar=" | while IFS== read name value null; do echo "|$name|$value|"; done
echo "foo=bar==" | while IFS== read name value null; do echo "|$name|$value|"; done

What happens?
---

In bash 2.05b.13(1)-release:

|foo|bar=|
|foo|bar==|

In bash 3.2.57(1)-release:

|foo|bar|
|foo|bar==|

In bash 4.3.42(1)-release:

|foo|bar|
|foo|bar==|

(( Also, POSIX-like shells that aren't bash (e.g. zsh) observe the bash2 behaviour. ))

What did I expect?


|foo|bar=|
|foo|bar==|

According to the documentation, for the "leftover words and their intervening separators assigned to the last name," supplied to read.

Chris Taylor <cttttt>

 

(Note: upload size limit is set to 16384 kB, after insertion of the required escape characters.)

Attach File(s):
   
   
Comment:
   

No files currently attached

 

Depends on the following items: None found

Items that depend on this one: None found

 

Carbon-Copy List
  • -unavailable- added by chet (Posted a comment)
  • -unavailable- added by cttttt (Submitted the item)
  •  

    Do you think this task is very important?
    If so, you can click here to add your encouragement to it.
    This task has 0 encouragements so far.

    Only logged-in users can vote.

     

    Please enter the title of George Orwell's famous dystopian book (it's a date):

     

     

    Follows 1 latest change.

    Date Changed By Updated Field Previous Value => Replaced By
    Tue 26 Jan 2016 08:00:18 PM UTCchetStatusNone=>Invalid

    Back to the top


    Powered by Savane 3.1-cleanup1