Skip navigation

How di I enter a sub-shell in a shell-function

419 Views 2 Replies Latest reply: Nov 17, 2012 7:02 AM by Mark Jalbert RSS
prontosystems Level 1 Level 1 (40 points)
Currently Being Moderated
Nov 17, 2012 5:57 AM

Hi Community,

 

I'm searching for a quick and dirty solution to determine the folder size in a specific location. I tried to do this job in a for-loop but I ran into trouble with folders containing a space in it's name. So I changed the environment variable IFS (Internal Field Separator) to a new-line only instead the default whitespace. But after this I have to leave the shell to get rid of the user-defined IFS variable. Yes I could write the IFS variable in another (auxiliary) variable first to set it back to the default value after running the for-loop but this isn't a quick and dirty solution just for a short look to the folder size in a one line command.

 

So the one liner looks like:

 

IFS=$'\n' && for i in `ls`; do du -hs "$i"; done

 

With the result that the IFS variable changed for this session to a single new line. So I tried to define a shell-function who switch to a sub-shell, set temporary the IFS variable, run the for-loop and exit the sub-shell:

 

$ foldersize()
> {
> /bin/bash
> IFS=$'\n'
> for i in `ls`; do
> du -hs $i;
> done
> exit
> }

 

But running the function it only switch to the sub-shell and nothing more happens:

 

$ foldersize 
bash-3.2$

 

So my question is how can I switch in a sub-shell using in a shell function?

 

Thx & Bye Tom

  • BobHarris Level 6 Level 6 (12,505 points)
    Currently Being Moderated
    Nov 17, 2012 7:07 AM (in response to prontosystems)

    What is wrong with

     

    du -hs *
    

     

    if you want to call it 'foldersize' you can create an alias

     

    alias foldersize='du -hs *'
    

     

    If you really want to do your loop, you could try something like

     

    foldersize()
    {
        ls -1 "$@" | while read file
        do
            du -hs "$file"
        done
    }
    

     

    The 'while' loop is running in a sub-shell, so any shell variable changes made in the sub-shell will not be visible when you finish.  For that you could use the following notation:

     

    foldersize()
    {
        while read file
        do
            do -hs "$file"
        done <  <(ls -1 "$@")
    }
    

     

    Which will run the 'ls' in a sub-process and the 'while' loop will be run in the current shell invocation, and thus any shell variable changes made in the 'while' loop will be available when the loop finishes.

     

    If you just want to do it your way, and do not need any shell variable changes returned to the invoking shell you could use:

     

    foldersize()
    {
        ( IFS=$'\n'
          for i in `ls "$@"`; do
            du -hs $i;
          done
        )
    }
    

     

    Where everything inside the (...) will be run in a sub-shell, and all variable changes will not show up in the invoking shell.

     

    Then again, you could have just put 'foldersize' in its own script file, made the file executable, and placed the script in $HOME/bin, then added $HOME/bin to your PATH environment variable, and when the script is invoked, it too will run in its own sub-shell.  Simple

     

    #!/usr/bin/env bash
    IFS=$'\n'
    for i in `ls "$@"`; do
        du -hs $i;
    done
    

     

    The "$@" syntax says if there are any function arguments substute them here and preserve any white space.  The syntax includes the "..." as well as the $@.  All 4 characters need to be specified as "$@" to get the white space preserving effect.  And if there are no function arguments, then it is as if the 'ls' command was specified without additional arguments, as you have used it.  This gives you the ability to get the folder size of the current directory as well as specify any directory you choose.

     

    NOTE:  All of the above should work as shown, most without the need for IFS

     

    Message was edited by: BobHarris

    MacBook Pro, Mac OS X (10.7.5), 27&quot; iMac, MacBook, MacMini, etc...
  • Mark Jalbert Level 5 Level 5 (4,385 points)
    Currently Being Moderated
    Nov 17, 2012 7:02 AM (in response to prontosystems)

    It seems like you are making this more difficult then need be. Why loop if you don't need to?

     

     

    du -sh *
    

     

Actions

More Like This

  • Retrieving data ...

Bookmarked By (0)

Legend

  • This solved my question - 10 points
  • This helped me - 5 points
This site contains user submitted content, comments and opinions and is for informational purposes only. Apple disclaims any and all liability for the acts, omissions and conduct of any third parties in connection with or related to your use of the site. All postings and use of the content on this site are subject to the Apple Support Communities Terms of Use.