Register
It is currently Sat Oct 25, 2014 10:23 pm

getting variable value from subshell to parent shell


All times are UTC - 6 hours


Post new topic Reply to topic  [ 6 posts ] 
Author Message
 PostPosted: Tue Dec 09, 2008 3:08 pm   

Joined: Tue Dec 09, 2008 2:38 pm
Posts: 3
hello everyone. i am writing a function, which renames desired files. first pattern matching part of the file from the end (mostly because of extensions). i am almost done, but one thing annoys me:

i am getting the list of files through find and then reading the list with while read, so i can avoid troubles with whitespaces in the name of files. the thing is, i need to count, how many of the files was actually renamed, but i can't get it once the while ends...

the important part of the code goes like this:
(imagine 1 file matching the pattern)
Code:
rename()
  {
    count=0;
    ...
    find $pattern -prune -type f | while read i; do
      ...
      echo $count ##### =0
      while [ $changed -eq 0 ] && [ $offset -ge 0 ]; do
        if test "${i:$offset:${#match}}" == $match; then
          ...
          ((count++))
          echo $count ##### =1
          fi
        done
      echo $count  ##### =1
      done
    echo $count ##### =0
  }


so my question is: is there any way how to get that information out of the subshell? or is there some other way how to read a file (variable) line by line, which doesn't involve using a subshell?


Top
 Profile  
 PostPosted: Wed Dec 10, 2008 3:27 am   
Moderator
User avatar

Joined: Thu Oct 11, 2007 7:12 am
Posts: 229
Location: London - UK
One of the weirdnesses about bash is the way it does those subshells lol
Two ways I know to get the info out of the loop is to either use a temp file to store the data or output the data and catch it in the external shell like so...

Code:
externalcount=$(
  find $pattern -prune -type f | while read i; do
    # stuff
    echo -n " $internalcount"
  done | awk '{ print $NF }'
)


Something like that anyway :)

DW


Top
 Profile  
 PostPosted: Wed Dec 10, 2008 3:40 am   

Joined: Mon Nov 17, 2008 7:25 am
Posts: 221
You could also use the export command. And just "import" it outside the function.

Code:
function return_to_parent {
    export value=$1
}

import=$(echo $value)


Thou I prefer to use echo and exec my function within a variable.


Top
 Profile  
 PostPosted: Wed Dec 10, 2008 7:46 am   

Joined: Tue Dec 09, 2008 2:38 pm
Posts: 3
thanks guys! that thing with
Code:
external=$( while sth; do
  ...
  echo -n " $internal"
done | awk '{print $NF}')"

is exactly what i was looking for!

however i wonder what would the awk part look like if i needed to get more than 1 variable out of the loop. like when i want to use:
Code:
  echo -n " $internal1 $internal2"


the export command didn't work for me, because it looks it's required for it to be the last command in a function or so, but i may use it in some other function probably, so thanks anyway...


Top
 Profile  
 PostPosted: Wed Dec 10, 2008 9:17 am   

Joined: Mon Nov 17, 2008 7:25 am
Posts: 221
I'm guessing you're trying to figure out how many files are in a path?

Code:
#!/bin/bash
lines=$(find $pattern -prune -type -f | wc -l)


if you need to do stuff, make a function.
Code:
#!/bin/bash
my_pattern="what ever, or maybe even $1"
function my_func {
   pattern=$1
   #stuff
   lines=$(find $pattern -prune -type -f | wc -l)
   echo "$stuff $lines"
}

temp=$(my_func $my_pattern)
lines=$(echo $temp | awk {'print $2'})
stuff=$(echo $temp | awk {'print $1'})
# also, if it's seperated with a colon you can use "cut -d':' -f1" or -f2


This will return $stuff and $lines seperated by a space... ofc you can change that to something that might be more manageable, like colon or something.
If bash supported the return of arrays that would have been a prefered choice. But if you want to do that kinda stuff you'll need to run something like perl or php.

What you can do thou with arrays (not fully tested thou) is to use them as global variables.
http://www.unix.com/shell-programming-s ... array.html <-- this link explains the details.

Best regards
Fredrik Eriksson


Top
 Profile  
 PostPosted: Thu Dec 11, 2008 6:25 am   

Joined: Tue Dec 09, 2008 2:38 pm
Posts: 3
it's not really, what i was trying to figure out. as i said it's a file renaming function, so first i have to find all the files matching $pattern (e.g. all filest starting with foo*), then rename only those, which have a part of the filename matching $match (e.g. all with .bar extension) and rename the $match part to $replacement. i need to know how many of the files was actually renamed...

but the thing with find ... | wc -l is very useful, when there are no files matching $pattern. i was getting the annoying error message: find: something: no such file or directory, so i used this:
Code:
if test $(find -nowarn -name "$pattern" -prune -type f | wc -l) -gt 0; then
  ...
fi

anyway, my function is done now, big thanks to you guys...

and the second part is just what i was asking: how to make a function returning more than 1 variable. so thanks for making this clear to me, fredrik


Top
 Profile  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 6 posts ] 

All times are UTC - 6 hours


Who is online

Users browsing this forum: No registered users and 3 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Jump to:  
cron


BashScripts | Promote Your Page Too
Powered by phpBB © 2011 phpBB Group
© 2003 - 2011 USA LINUX USERS GROUP