LinuxQuestions.org
Latest LQ Deal: Latest LQ Deals
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 06-27-2011, 03:47 PM   #1
strongdrink
LQ Newbie
 
Registered: Feb 2011
Distribution: Ubuntu
Posts: 5

Rep: Reputation: 0
Question bash unset array loops GARBAGE


Hello everyone.. i dont really know how to explain this.. because i dont really know EXACTLY what is wrong.. so here is my code..

Code:
#loop until there are no more files
while [ ${#files[@]} -gt 0 ]; do
 
  for num in `seq 1 ${#files[@]}`; do
 
    wurd=`tail -4 ${files[$num-1]}`

    if [[ "$wurd" == *OK* ]]; then
   
      echo "[  OK  ] ${files[$num-1]}"
      unset files[$num-1]
 
    elif [[ "$wurd" == *FAILURE* ]]; then
  
      echo "[ FAIL ] ${files[$num-1]}"
      unset files[$num-1]
  
    fi
  
    #echo the file name
    echo ${files[$num-1]}
 
  done
 
  #wait a second
  sleep 1
 
done
Everything works.. but when it has to unset.. it breaks.. it doesnt give an error though.. it just jams the program..

thanks!

Last edited by strongdrink; 06-29-2011 at 07:40 AM. Reason: Added code tags
 
Old 06-27-2011, 07:26 PM   #2
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 10,006

Rep: Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191
Please use [code][/code] tags to display your code.
Quote:
it breaks
You might need to explain this further? You say there is no error message so how do you know it is broken?

I am struggling to follow the logic as well. It appears that OK or FAILURE both remove items and as your outside
loop is looking for when all have been unset I am guessing these are the only 2 options, so why not just process
the loop from start to finish and echo the corresponding output, ie no need to unset that I can see.
 
Old 06-28-2011, 12:46 AM   #3
David the H.
Bash Guru
 
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Arch + Xfce
Posts: 6,852

Rep: Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037
I agree with the above. code tags will make it more readable, and using a decent indentation style is even better. Also, the line numbers make it hard to simply cut&paste to a file for testing.

In addition, a short explanation of what you're really trying to accomplish may help clarify things.

There are also a few issues with the code I want to mention, outside of your main problem.

1)
Code:
 while [ ${#files[@]} -gt 0 ]; do
In bash, the old [ test command can be better replaced with the [[ keyword. But in this case you're doing an arithmetic comparison, so ((..)) is recommended.

2) This whole outside while loop appears to be completely unnecessary anyway, as the inner loop will only output existing entries.

3)
Code:
for num in `seq 1 ${#files[@]}`; do
Don't use seq. Use brace expansion instead.

But actually, there's an even easier way to loop through an array. ${!array[@]} will give you a list of all existing index elements, so you can loop over only entries that exist, rather than a simple number list. It's particularly good for sparse arrays.

4) $(..) is highly recommended over `..`

5) Always quote your variable expansions, unless you want word-splitting to occur.

6)
Code:
if [[ "$wurd" == *OK* ]]; then
I would replace the if construct with a case construct here. That way you only do a single evaluation of the input.

So taking all this into account, this is how I would write it. But note the comment on the echo command at the end:
Code:
#!/bin/bash

for num in ${!files[@]}; do

     wurd=$( tail -4 "${files[num]}" )

          case "$wurd" in

               *OK* )
                    echo "[ OK ] ${files[num]}"
                    unset files[num]
               ;;

               *FAILURE* )
                    echo "[ FAIL ] ${files[num]}"
                    unset files[num]
               ;;

          esac

     #This will only print a blank line, since you just unset the entry above.
     echo "${files[$num]}"

     #wait a second
     sleep 1

done
 
1 members found this post helpful.
Old 06-28-2011, 09:01 PM   #4
strongdrink
LQ Newbie
 
Registered: Feb 2011
Distribution: Ubuntu
Posts: 5

Original Poster
Rep: Reputation: 0
I use vim with line numbers turned on sry :S and it was indented.. i dunno why it took the indents away...

1) I am using a while loop because the files are being generated AS the script is running
2) "
3) Ok thanks, I just read on a forum that i should use seq..
4)
5)
6) Ok thanks
 
Old 06-28-2011, 11:02 PM   #5
David the H.
Bash Guru
 
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Arch + Xfce
Posts: 6,852

Rep: Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037
So did this help you fix your problem? If it did, you should tell us about it, so we what worked, and any future readers can also be helped by it. Then mark the thread as solved.


When HTML is rendered it condenses all contiguous whitespace down to single spaces, and leading whitespace is removed. Special tags or characters like <blockquote> or &nbsp; must be used in the HTML code to preserve it.

But since this forum has disabled the direct use of html in posts, you have to use the bbcode code tags instead, which the server will then convert into a blockquote (or more precisely a "pre" div) before it sends the page out.


As for things like seq, you'll find a lot of coding suggestions out there that are outdated or not generally recommended. Many shell coders come from the old unix world and used shells that don't have all the features bash does. They may not know about the other choices, got bad advice themselves in the past, are thinking in terms of cross-platform support, or are simply too ingrained in their old ways to change.

But unless you need portability to systems that don't have newer versions of bash installed, then there's no reason not to use all the goodies it has to offer. It's better in general to use built-in features than to rely on external tools whenever possible.

Anyway, don't take it as any kind of criticism. My only desire is to help point out good practices so you can improve your scripting.

I've been finding Greg's Wiki to be a real treasure trove of bash info. I've been reading a lot of it recently and it's really helped my understanding.
 
Old 06-28-2011, 11:23 PM   #6
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 10,006

Rep: Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191
+1 on Greg's Wiki
 
Old 06-29-2011, 07:37 AM   #7
strongdrink
LQ Newbie
 
Registered: Feb 2011
Distribution: Ubuntu
Posts: 5

Original Poster
Rep: Reputation: 0
Ok I'll post if it worked as asap.
 
Old 06-29-2011, 07:56 AM   #8
strongdrink
LQ Newbie
 
Registered: Feb 2011
Distribution: Ubuntu
Posts: 5

Original Poster
Rep: Reputation: 0
Ok it's working! The problem was the for loop..

Code:
  for num in `seq 1 ${#files[@]}`; do
because it was still reading elements that i unset

so, like "David The H." said, i changed it to

Code:
  for num in ${!files[@]}; do
and its working swell now

thanks everyone!

P.S. i changed a lot of my sloppy scripting as well :S
 
  


Reply

Tags
bash



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
[SOLVED] bash unset all environment variables sharky Programming 1 06-08-2011 06:53 PM
Bash script - two for loops with array problem... towed Linux - Newbie 13 05-01-2011 03:36 PM
how to unset environment variable in bash suneel Linux - Newbie 7 09-14-2009 10:17 AM
Can a bash function unset itself? linux_user_123 Linux - General 1 07-24-2009 10:23 PM
BASH variables getting unset outside of loop trevelluk Programming 2 03-25-2005 07:14 AM

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

All times are GMT -5. The time now is 09:51 PM.

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