LinuxQuestions.org
Download your favorite Linux distribution at LQ ISO.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
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


Reply
  Search this Thread
Old 03-25-2011, 12:10 PM   #1
ted_chou12
Member
 
Registered: Aug 2010
Location: Zhongli, Taoyuan
Distribution: slackware, windows, debian (armv4l GNU/Linux)
Posts: 431
Blog Entries: 32

Rep: Reputation: 3
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
 
Old 03-25-2011, 12:15 PM   #2
szboardstretcher
Senior Member
 
Registered: Aug 2006
Location: Detroit, MI
Distribution: GNU/Linux systemd
Posts: 4,278

Rep: Reputation: 1694Reputation: 1694Reputation: 1694Reputation: 1694Reputation: 1694Reputation: 1694Reputation: 1694Reputation: 1694Reputation: 1694Reputation: 1694Reputation: 1694
This was addressed in another question:

http://www.linuxquestions.org/questi...e-loop-500481/

Basically, its because you are using a "|" pipe.
 
Old 03-25-2011, 12:42 PM   #3
ted_chou12
Member
 
Registered: Aug 2010
Location: Zhongli, Taoyuan
Distribution: slackware, windows, debian (armv4l GNU/Linux)
Posts: 431

Original Poster
Blog Entries: 32

Rep: Reputation: 3
Hi, i had a read at the post:
Quote:
Originally Posted by aluser View Post
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
 
Old 03-25-2011, 03:57 PM   #4
PTrenholme
Senior Member
 
Registered: Dec 2004
Location: Olympia, WA, USA
Distribution: Fedora, (K)Ubuntu
Posts: 4,187

Rep: Reputation: 354Reputation: 354Reputation: 354Reputation: 354
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.
Old 03-26-2011, 03:25 AM   #5
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 10,007

Rep: Reputation: 3192Reputation: 3192Reputation: 3192Reputation: 3192Reputation: 3192Reputation: 3192Reputation: 3192Reputation: 3192Reputation: 3192Reputation: 3192Reputation: 3192
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.
Old 03-26-2011, 04:14 AM   #6
colucix
LQ Guru
 
Registered: Sep 2003
Location: Bologna
Distribution: CentOS 6.5 OpenSuSE 12.3
Posts: 10,509

Rep: Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983
Moved: This thread is more suitable in Programming and has been moved accordingly to help your thread/question get the exposure it deserves.
 
Old 03-26-2011, 11:19 AM   #7
PTrenholme
Senior Member
 
Registered: Dec 2004
Location: Olympia, WA, USA
Distribution: Fedora, (K)Ubuntu
Posts: 4,187

Rep: Reputation: 354Reputation: 354Reputation: 354Reputation: 354
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."
 
Old 03-26-2011, 12:11 PM   #8
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 10,007

Rep: Reputation: 3192Reputation: 3192Reputation: 3192Reputation: 3192Reputation: 3192Reputation: 3192Reputation: 3192Reputation: 3192Reputation: 3192Reputation: 3192Reputation: 3192
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??
 
Old 03-27-2011, 10:55 AM   #9
PTrenholme
Senior Member
 
Registered: Dec 2004
Location: Olympia, WA, USA
Distribution: Fedora, (K)Ubuntu
Posts: 4,187

Rep: Reputation: 354Reputation: 354Reputation: 354Reputation: 354
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.)
 
Old 03-28-2011, 03:57 AM   #10
ted_chou12
Member
 
Registered: Aug 2010
Location: Zhongli, Taoyuan
Distribution: slackware, windows, debian (armv4l GNU/Linux)
Posts: 431

Original Poster
Blog Entries: 32

Rep: Reputation: 3
Thanks
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
How to define a variable In a while loop? fatsheep Programming 16 07-30-2014 01:12 PM
[SOLVED] [BASH] non-empty variable before loop end, is empty after exiting loop aitor Programming 2 08-26-2010 09:57 AM
incrementing variable in an until loop jeffreybluml Programming 2 05-12-2005 07:45 AM
What would cause a while loop to unexpectedly end? farmerjoe Programming 5 04-29-2005 02:57 PM
getting a variable out of a WHILE loop. fhinkle Programming 8 02-22-2005 04:43 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 10:59 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration