On 05/22/2012 08:56 AM, David Haller wrote:
No, dcr tried it with a for-loop, where no stdin was "in the loop".
In the script though, he fed the while-loop-stdin from the gtkrc and that's the stdin calc read as well. And that's also why the 'echo .. | calc' works, as then calc's stdin is fed by echo and not from the while-loop i.e. the gtkrc.
Compare to similar problems using ssh, which even has the option '-n' for exactly that problem. Anyway: redirecting calc's stdin from /dev/null works, as calc then does_not_ read the while-loop-stdin i.e. the gtkrc and barf's on the next line "up", which happens to be the second 'bg[' line (or bag in my modified version). Again: I changed the first uncommented lines that calc get fed in the gtkrc to read:
{ bug[NORMAL] = { 0.125, 0.129, 0.149 } bag[SELECTED] = { 0.216, 0.286, 0.431 } bg[INSENSITIVE] = { 0.125, 0.129, 0.149 }
So, what happens? dcr's script reads the file up to 'bug', parses that to the variables $r, $g, $b and then calls
_r=$(calc -p "255 * $r")
Where is stdin of the loop at this point? The line 'bug[...' was read, nextup in stdin is 'bag[...]'. And that's what calc reads, tries to evaluate and thus "barfs" "'bag' undefined"..
Confused yet?
Yes - thoroughly... Digesting the wisdom, it seems that there is a difference in how calc is treating stdin depending on whether it is called from within a while loop or otherwise. The bug/bag example was great exposing what calc was choking on. But I can't for the life of me see how calc can inherit stdin differently when called within a while loop or for loop. I see in the for loop there is no stdin to inherit -- I get that. I also see in the while loop that the potential is there due to redirecting gtkrc-file.txt to feed the while loop -- but that is where things cloud over and my eyes roll back in my head. Where the train wreck occurs in my mind is that regardless of while or for, the line is passed into variable 'l' which is parsed into 'rgb' and then into 'r', 'g' & 'b' --before-- being fed to calc. How does calc even know of a different stdin? Passing ' </dev/null' to calc does indeed fix the problem, but I would never have expected there to be some stdin cause after the closing parenthesis in the original call: _r=$(calc -p "255 * $r"). How is there some stdin left open after the closing '"' in $(calc -p "255 * $r")? Just to really confuse myself, I decided to re-write the script using a for loop instead of a while loop (I prefer while loops anyway because they will always read the last line of the file...) So: #!/bin/bash IFS=$'\n' for l in $(<gtkrc-file.txt); do # style heading [[ ${l:0:5} == style ]] && echo -e "\n$l\n" # parse and compute 255 base rgb [[ $l =~ , ]] && [[ ${l:0:1} != [#] ]] && { title=${l// =*} title="${title#"${title%%[![:space:]]*}"}" rgb=${l##*[{] } rgb=${rgb%\ \}*} rgb=${rgb//,} r=${rgb%% *} b=${rgb##* } g=${rgb% *} g=${g#* } _r=$(calc -p "255 * $r") _g=$(calc -p "255 * $g") _b=$(calc -p "255 * $b") printf "%-18s %-6s %-6s %-6s %4.0f %4.0f %4.0f\n" $title $r $g $b $_r $_g $_b } done It works without a hitch! So, I learned something new -- even though I'm not sure I understand what I learned. BASH handles while and for differently somehow regarding the inheritance of stdin. I can prove to myself that there is indeed this difference, but other than stumbling across it on a case-by-case basis, I'm certain I still do not understand a 'rule' that tells me I when should look out for this type of problem before I run into it... :) Ouch -- my head hurts... dnh, all, I tip my hats to you in your ability to step through and debug this. That isn't something I've mastered yet. Thanks. -- David C. Rankin, J.D.,P.E. -- To unsubscribe, e-mail: opensuse+unsubscribe@opensuse.org To contact the owner, e-mail: opensuse+owner@opensuse.org