Bash/Shell script .. Var?

Questions about applications and software
Forum rules
Before you post please read this

Bash/Shell script .. Var?

Postby Hjess on Sun Aug 03, 2008 3:05 pm

Hi.

I'm getting some strange behavior from bash witch I cannot understand. I've tryed to google this problem some times but with no luck.

I just copy/paste a small shell script .. (It a outcome of a bigger one - but gives a picture of the problem).

Code: Select all
[# ========= check_if_burn() - Checks whatever if a iso allready is burned out =
check_if_burn() {
was_ok=0
 ls | while read f
   do
      ext=${f##*_}
          if [ "$ext" = "SUCCESS" ]
                then
                      echo "There was a success file: $f"
                      was_ok=1   ### Why wont this change?
          fi
   done
return $was_ok   
} # check_if_burn end

check_if_burn
echo "Exitcode was:$?"



The strange part is the following.

I will get a echo output while having a success file - but the variable was_ok never changes (or gets set to 0?)

When i set the variable in the top of the function - it will change, and if I do it in the buttom of the script it will change. Its -only- while its into some sort of loop its giving me trouble (I even tried with "for" and "until").

So - trouble is - why can I set a variable in a loop?


looking forward to some great reply s - this has been nagging me ;)

/~HJess
"Ah, women. They make the highs higher and the lows more frequent." - Friedrich Nietzsche
"No notice is taken of a little evil, but when it increases it strikes the eye." - Aristotle
Hjess
Level 2
Level 2
 
Posts: 71
Joined: Fri May 30, 2008 5:55 pm
Location: Planet Earth

Linux Mint is funded by ads and donations.
 

Re: Bash/Shell script .. Var?

Postby rbanavara on Tue Aug 05, 2008 12:02 pm

this had frustrated me as well sometime back!

I was having issue with pdksh (an open ksh). It seems that whatever runs as part of loop (ls | while read), runs in a separate thread and loses its state once out of the loop :( I had to set it in a file & read it later (I know its a dirty way). You can try using some other shell directive.
Don't fix it if it ain't broken, don't break it if you can't fix it -Husse
User avatar
rbanavara
Level 4
Level 4
 
Posts: 233
Joined: Mon Jun 02, 2008 9:07 am

Re: Bash/Shell script .. Var?

Postby Hjess on Tue Aug 05, 2008 2:13 pm

rbanavara wrote:this had frustrated me as well sometime back!

I was having issue with pdksh (an open ksh). It seems that whatever runs as part of loop (ls | while read), runs in a separate thread and loses its state once out of the loop :( I had to set it in a file & read it later (I know its a dirty way). You can try using some other shell directive.


Thats a dirty way ;-)

It seems od that there is this problem ...
"Ah, women. They make the highs higher and the lows more frequent." - Friedrich Nietzsche
"No notice is taken of a little evil, but when it increases it strikes the eye." - Aristotle
Hjess
Level 2
Level 2
 
Posts: 71
Joined: Fri May 30, 2008 5:55 pm
Location: Planet Earth

Re: Bash/Shell script .. Var?

Postby Hjess on Thu Aug 07, 2008 3:47 pm

I'm getting closer to a solution .. or just what the error is ;-)

This require very heavy google'ing ;-)

The problem is the pipe. Bash can't open a pipe to itself (at least not without deadlocking), so it needs to start another process to run the loop (or, if you do an echo $line | read id ego, then it needs another process to run the read builtin). That other process cannot modify the environment of its parent, which is the very thing you're trying to do.
"Ah, women. They make the highs higher and the lows more frequent." - Friedrich Nietzsche
"No notice is taken of a little evil, but when it increases it strikes the eye." - Aristotle
Hjess
Level 2
Level 2
 
Posts: 71
Joined: Fri May 30, 2008 5:55 pm
Location: Planet Earth

Re: Bash/Shell script .. Var?

Postby Hjess on Thu Aug 07, 2008 4:43 pm

After a lot of googling I found a solution. Its far from great and i really dont know how it works out.

Here goes.. - Keep in mind im still a newbie shell coder :o

check_if_burn()
{
#
# ** Nasty bug - and not quite good.
# * Bug: there will only be found *one* SUCCESS file
# * No clue on how or why that exit works as it do.
# * This could of couse be modifyed to use "find" or similar, but wanted
# * to try out ls | while read f - due to whitespaces.

ls | while read f
do
echo $f
ext=${f##*_}
if [ "$ext" = "SUCCESS" ]
then
exit_status=1
exit ${exit_status:-${EXIT_STATUS:-0}} # Jumps out of function here.
else
exit_status=2
fi
done
# If any aditonal functions is added here the return err. will drop
return $exit_status
} # check_if_burn end

check_if_burn
echo "Exitcode was:$?"

"Ah, women. They make the highs higher and the lows more frequent." - Friedrich Nietzsche
"No notice is taken of a little evil, but when it increases it strikes the eye." - Aristotle
Hjess
Level 2
Level 2
 
Posts: 71
Joined: Fri May 30, 2008 5:55 pm
Location: Planet Earth

Re: Bash/Shell script .. Var?

Postby rbanavara on Sat Aug 09, 2008 6:02 am

the other easy solution would be to avoid the pipe like:

for f in `ls`
do
...
done

the other solution I learnt from my brother is to echo the variables to a file like:

echo 'status=SUCCESS' >> $TMPFILE
echo 'some_other_var=VALUE' >> $TMPFILE

then source that file (. $TMPFILE) and all your variables will be set as shell variables.
Don't fix it if it ain't broken, don't break it if you can't fix it -Husse
User avatar
rbanavara
Level 4
Level 4
 
Posts: 233
Joined: Mon Jun 02, 2008 9:07 am

Re: Bash/Shell script .. Var?

Postby Hjess on Sat Aug 09, 2008 7:22 am

I found a better solution for this problem .. (As I belive) ..

Code: Select all
check_if_burn()
{
while read f   
   do
      ext=${f##*_}
          if [ "$ext" = "SUCCESS" ]
                then
                        exit_status=1
                        break  # Do we need to find more than one?
                else
                        exit_status=2
          fi
   done < <(ls)   ### By doing this - There will not be spawn no subshell (I've think)
return $exit_status
} # check_if_burn end



By doing done < <(ls) I dont spawn any subshells or similar.

I belive this problem is very poorly explained in any bash documentation, but by reading alot of sites and going throw alot of scripts i seen this soluton working. But I cannot explain why or how it works .. - But it works ! :D
"Ah, women. They make the highs higher and the lows more frequent." - Friedrich Nietzsche
"No notice is taken of a little evil, but when it increases it strikes the eye." - Aristotle
Hjess
Level 2
Level 2
 
Posts: 71
Joined: Fri May 30, 2008 5:55 pm
Location: Planet Earth

Linux Mint is funded by ads and donations.
 

Return to Software & Applications

Who is online

Users browsing this forum: No registered users and 13 guests