Programming This 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.
Are you new to LinuxQuestions.org? Visit the following links:
Site Howto |
Site FAQ |
Sitemap |
Register Now
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.
|
 |
03-25-2011, 12:10 PM
|
#1
|
Member
Registered: Aug 2010
Location: Zhongli, Taoyuan
Distribution: slackware, windows, debian (armv4l GNU/Linux)
Posts: 431
Rep:
|
variable is gone at the end of while loop
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/
Why is this happening? is this a bug?
Thanks
|
|
|
03-25-2011, 12:42 PM
|
#3
|
Member
Registered: Aug 2010
Location: Zhongli, Taoyuan
Distribution: slackware, windows, debian (armv4l GNU/Linux)
Posts: 431
Original Poster
Rep:
|
Hi, i had a read at the post:
Quote:
Originally Posted by aluser
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
|
|
|
03-25-2011, 03:57 PM
|
#4
|
Senior Member
Registered: Dec 2004
Location: Olympia, WA, USA
Distribution: Fedora, (K)Ubuntu
Posts: 4,187
|
You could try this (untested) modification:
Code:
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/
|
|
1 members found this post helpful.
|
03-26-2011, 03:25 AM
|
#5
|
LQ Guru
Registered: Sep 2009
Location: Perth
Distribution: Arch
Posts: 10,042
|
So I am curious about 2 things:
1. Why not use find to show only directories?
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)
|
|
1 members found this post helpful.
|
03-26-2011, 04:14 AM
|
#6
|
LQ Guru
Registered: Sep 2003
Location: Bologna
Distribution: CentOS 6.5 OpenSuSE 12.3
Posts: 10,509
|
Moved: This thread is more suitable in Programming and has been moved accordingly to help your thread/question get the exposure it deserves.
|
|
|
03-26-2011, 11:19 AM
|
#7
|
Senior Member
Registered: Dec 2004
Location: Olympia, WA, USA
Distribution: Fedora, (K)Ubuntu
Posts: 4,187
|
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."
|
|
|
03-26-2011, 12:11 PM
|
#8
|
LQ Guru
Registered: Sep 2009
Location: Perth
Distribution: Arch
Posts: 10,042
|
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.
So it appears the version is lower than yours??
|
|
|
03-27-2011, 10:55 AM
|
#9
|
Senior Member
Registered: Dec 2004
Location: Olympia, WA, USA
Distribution: Fedora, (K)Ubuntu
Posts: 4,187
|
Oops! My bad!
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.)
|
|
|
03-28-2011, 03:57 AM
|
#10
|
Member
Registered: Aug 2010
Location: Zhongli, Taoyuan
Distribution: slackware, windows, debian (armv4l GNU/Linux)
Posts: 431
Original Poster
Rep:
|
Thanks
|
|
|
All times are GMT -5. The time now is 09:52 AM.
|
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.
|
Latest Threads
LQ News
|
|