|
From: | Linda Walsh |
Subject: | Re: I think bash logic in a loop like : while [ condition] |read somevar is flawed. |
Date: | Tue, 24 Dec 2013 16:57:55 -0800 |
User-agent: | Thunderbird |
rens wrote:
this script: _______________________ export cval=0 echo entering while # listing ten files, to generate some output to count. ls -1 /usr/bin|head -10 |while read fname do cval=$(( cval +1 )) echo cval = $cval file = $fname done# one would think cval is now 10. but it is not, contrary to any other programming language........echo " after while: cval = $cval" _______________________________ does not set the value of cval after exiting the while loop. that makes no sense.
Bash should not work that way. no programming language handles logic this way. Not pascal, korn shell, c shell, cobol, c, c++, lua , fortran or any other language i ever used.
---- Bash is a command-line interpreter. It is not a language; It accepts commands and has ways of sequencing commands and funneling output from one command to the next. Korn shell works the same way. csh has no read builtin that I can find, so you can't write the program the same way. Every time you use "|", you are ending the previous program and piping results to another program. The above is equal to the *first* 'while' output in the program below: If you want your progam to work right, you need to have the count be in your shell, and NOT have any "|" in the invocation line (i used < <(...)) The below produces the wrong output first (cval=0) and then runs it again with the commands re-arranged to not use '|' -- which produces the right value. Does this help you understand what's going on? ------------------------------------------------- #!/bin/bash shopt -s expand_aliases alias program=function alias int=declare\ -i alias my=declare program myhead { my inp=${1:-10} if [[ ${inp:0:1} == - ]]; then inp="${inp:1}"; fi int lines=$inp while ((lines-- > 0)); do my line read line echo "$line" done } declare -xi cval=0 echo entering while program print_exported_cval { while [[ ! $(typeset -p cval |sed -r 's/ +/\t/g'|cut -f2) =~ x ]];do unset cval done echo -n "exported_cval=$cval, " } program number { #int cval=$cval while read fname; do cval=$cval+1 echo -n "local_cval=$cval, " (print_exported_cval) echo "file = $fname" done } #number< <(ls -1 | myhead -10 ) ls -1 | myhead -10 |number echo " after 1st while: cval = $cval" number< <(ls -1 | myhead -10 ) echo " after 1st while: cval = $cval" #end script -----------------------------------------
[Prev in Thread] | Current Thread | [Next in Thread] |