OT: posix sh problem

Teske, Devin Devin.Teske at fisglobal.com
Thu Apr 4 15:11:01 UTC 2013


Oh, and just to cover all bases…

If you suspect you have sub-shells in the loop, use "export" to export the vars so that the sub-shells get the vars in the loop.
-- 
Devin


On Apr 4, 2013, at 8:04 AM, Teske, Devin wrote:

> 
> On Apr 4, 2013, at 7:42 AM, Mark Felder wrote:
> 
>> On Thu, 04 Apr 2013 08:54:30 -0500, Teske, Devin <Devin.Teske at fisglobal.com> wrote:
>> 
>>> Wait, you can't? Then I've been doing something wrong all these years…
>>> #!/bin/sh
>>> printf "line1\nline2\n" | while read line
>>> do
>>> 	echo "line=[$line]"
>>> done
>> 
>> You sort-of can, but it's not portable at all. As detailed here: http://www.etalabs.net/sh_tricks.html
>> 
>>>> One common pitfall is trying to read output piped from commands, such as:
>>>> foo | IFS= read var
>>>> POSIX allows any or all commands in a pipeline to be run in subshells,
> 
> And for most purposes that's fine. Read-on…
> 
> 
>>>> and which command (if any) runs in the main shell varies greatly betweenimplementations
> 
> … that is only if you truly need the variables to be read into the main shell. This is most always not what you want.
> 
> The page you linked about doesn't talk about the special case of "while", in example:
> 
> 	foo | IFS= while read var
> 
> On the back-end nothing changes (the same caveat applies -- variables set on the right side of the pipe may not be available to the main shell; as-per the quoted text). However, the high-level task changes from:
> 
> 	I want to read some text from a pipe into some variables
> 
> to instead:
> 
> 	I want to read some text from a pipe and process it word-by-word (in your case) and act on the words in a loop
> 
> So in other words… the only reason for wanting the variables in the main shell is if you want to act on the last set of variables for the last line after the loop has run (and presumably already processed the last line). This is what I am saying anyone will rarely ever want. In other words, once the loop (potentially running in a sub-shell) has completed, you likely don't care about the variable contents and are willing to throw them away anyhow.
> 
> 
> 
>>>> — in particular Bash and ksh differ here. The standardidiom for overcoming this problem is to use a here document:
>>>> 
>>>> IFS= read var << EOF
>>>> $(foo)
>>>> EOF
>> 
> 
> But you're not processing a single line; you're processing the entire input at-once and performing an action (writing to the screen) that also doesn't care whether it's in a sub-shell or not.
> 
> SO…
> 
> I say rock-on with the original syntax. It's portable. You don't need those vars when the loop ends.
> 
>> 
>> I was having problems with the variables magically becoming empty, remembered I had Rich's site bookmarked, checked to see if it mentioned and it was. I'll admit there's a high chance that due to lack of sleep user error was the culprit.
> 
> I'm interested in why you need the variables after the loop has completed. Put your code in the loop where the variables are defined and have values.
> -- 
> Devin
> 
> _____________
> The information contained in this message is proprietary and/or confidential. If you are not the intended recipient, please: (i) delete the message and all copies; (ii) do not disclose, distribute or use the message in any manner; and (iii) notify the sender immediately. In addition, please be aware that any message addressed to our domain is subject to archiving and review by persons other than the intended recipient. Thank you.

_____________
The information contained in this message is proprietary and/or confidential. If you are not the intended recipient, please: (i) delete the message and all copies; (ii) do not disclose, distribute or use the message in any manner; and (iii) notify the sender immediately. In addition, please be aware that any message addressed to our domain is subject to archiving and review by persons other than the intended recipient. Thank you.


More information about the freebsd-questions mailing list