[SOLVED] variable is gone at the end of while loop
ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
Hi, I have a directory file capturing script, the variable is fine with in the loop but gone after the loop is done:
Code:
DIR="/usb/sdb1/media/music/"
i=1
echo "$(ls -lL "${DIR}")" | while read LINE
do
FILENAME=${LINE:56}
ISDIR=${LINE:0:1}
if [ "$ISDIR" = "d" ] ; then
if [ $i == $DIR0 ] ; then
DIR="$DIR$FILENAME/"
fi
i=$(($i+1))
fi
echo $DIR#the variable is new here eg /usb/sdb1/media/music/NEWDIR/
done
echo $DIR#the variable is old here eg /usb/sdb1/media/music/
A workaround is to put the entire "stuff | while blah; do halb; done" construct inside backquotes and echo $conflict at the end. i.e.
Code:
conflict=`stuff | ( while blah; do whatever; done; echo $conflict )`
Be sure to echo any errors found inside the subshell to stderr like
Code:
echo >&2 "Oh no Mr. Bill!"
so that they aren't captured by the backquotes
this seems to be what I desired, but how do i go ahead in incooperate it into my own code? since i have extra stuff in front of the while loop?
Thanks
Ted
DIR="/usb/sdb1/media/music/"
tmpfile=$(mktemp "/tmp/tempXXXX")
ls -lL "${DIR}" > $tmpfile
while read LINE
do
FILENAME=${LINE:56}
ISDIR=${LINE:0:1}
if [ "$ISDIR" = "d" ]
then
i=$((++i))
if [ ${i} == ${DIR0} ]
then
DIR="${DIR}${FILENAME}/"
fi
fi
echo ${DIR} #the variable is new here eg /usb/sdb1/media/music/NEWDIR/
done < ${tmpfile}
rm -f ${tmpfile}
echo ${DIR} #the variable is old here eg /usb/sdb1/media/music/
2. You reference a variable called 'DIR0', but after re-reading this several times I cannot see anywhere it being set so your internal 'if' should never work??
Lastly, as opposed to PTrenholme's suggestion of a temp file, which of course works, I would generally go with process substitution in the redirection:
Code:
while read -r LINE
do
<your stuff>
done< <(find $DIR -type d)
grail, I don't know which version of bash you're using, but that code failed on my Fedora 14 system. To get it to work, I needed to do this:
Code:
#!/bin/bash
while read x
do
linenum=$((++linenum))
echo "$linenum: $x"
done <<< "$(echo -en "hello\nworld\n")"
echo "total number of lines = $linenum"
(Note the quotes around the $(command) to prevent word parsing of the result of the command, and the triple redirection.)
That being said, yours is a simpler solution then the temporary file one, although, in terms of execution cycles, I suspect that they are equivalent.
Oh, FYI:
Code:
$ bash --version
GNU bash, version 4.1.7(1)-release (x86_64-redhat-linux-gnu)
Copyright (C) 2009 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
P.S.: I agree that find might be a better way for the OP to proceed, and, in fact, by using the -exec option he might be able to avoid the need of a bash script altogether. But, as he stated, what he posted was only a fragment from his code. I had assumed that the DIR0 variable was set elsewhere, and that its value was irrelevant to the question he posed. As you can see, I was using the code posted in the thread referenced in the post by szboardstretcher, above for testing. That's why I noted that my modification of his code was "untested."
Hey PT ... not sure why it didn't work for you?? You did put a space between the 2 < signs?
Sample of it working for me:
Code:
#!/bin/bash
DIR=$1
while read -r LINE
do
echo $LINE
done< <(find $DIR -type d)
Output <snipped>:
Code:
$ ./test.sh Documents
Documents/
Documents/My Videos
Documents/My Music
Documents/programming
Documents/programming/bash
Documents/programming/bash/books
Documents/programming/bash/books/with a space
Documents/programming/bash/books/ch
Documents/programming/bash/grail
Bash version:
Code:
$ bash --version
GNU bash, version 4.1.5(1)-release (x86_64-pc-linux-gnu)
Copyright (C) 2009 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
I (from ingrained habit) used done< <$(cmd) instead of done < <(cmd) since I almost always use the $(cmd) form in scripts. (And I would have used gawk instead of bash for the problem posed by the OP, but that a different topic.)
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.