Altering a variable outside the scope of a loop influenced by a subshellTrackbacks
Trackback specific URI for this entry
No Trackbacks
Comments
Display comments as
(Linear | Threaded)
I tested your solution with solaris sh and it doesn't work, however I don't know the POST compliance level of the solaris sh.
I had this same problem a few years ago, but I saw that bash did create a subshell for |{ } constructs, and concluded that I was mistaken
Also, from that fact, I couldn't understand the difference between ( ) and { } in most cases...
The blog topic is wrong, your problem is not the loop but the fact that the loop is running in a pipe construct. And that is documented behavior.
------------------ dash(1): Note that unlike some other shells, each process in the pipeline is a child of the invoking shell (unless it is a shell builtin, in which case it executes in the current shell -- but any effect it has on the environment is wiped). ------------------ This is also POSIX compliant, POSIX does allow both to execute pipe components in subshells or the the same shell. "2.12 Shell Execution Environment" says: ----------------------------- Changes made to the subshell environment shall not affect the shell environment. Command substitution, commands that are grouped with parentheses, and asynchronous lists shall be executed in a subshell environment. Additionally, each command of a multi-command pipeline is in a subshell environment; as an extension, however, any or all commands in a pipeline may be executed in the current environment. ----------------------------- cu andreas
Yes the title is a bit bad I have to admit and I know this is intended behaviour.
Hi,
The workaround you suggest in your 3rd code snippet should be like this (the final 'echo' inside the block): [snip] printf '456\n789\n' | { foo=123 while read line; do foo=$line done echo $foo } [snap] I have not seen it the way you put it, before. I don't think this is a bug. Neither for dash, nor for bash. And in reply to Yann: Solaris does come with a POSIXly compliant shell, but it's in one of Solaris' thousand obscure $PATH parts. '/bin/sh' on Solaris is a shell that's pretty close to the original Bourne Shell. That shell even forces a subshell on redirections: [snip] foo=bar while read line; do foo=$line done < /etc/hosts echo $foo [snap] ...will output 'bar' with Solaris' '/bin/sh'. However, the corrected workaround I presented above should work in that shell as well. Regards, Frank Add Comment
|
Calendar
QuicksearchSupportRecent Entries
CategoriesTag cloud23c3 acpi advertising annouce announce april argh art awards bash blogging bugs c cli code conferences config configuration data mining debconf debian dell dns documentation email errm? events exploit fail fail2ban filesharing films flame fun gcc google graphs grml gsm hacking hacks hardware heise images information installation internet irc knowledge libacpi links linux mobile phones network news newsbeuter omg open source opera passwords php power privacy programming qa random blurb rant release releases rss scripts security service setup shell sms software spam ssh stfl stuff terminal tests text mode tip tips tools troubleshooting unix user video vim.editing web web 2.0 websites wordpress wtf www youtube zsh
|