[sf-lug] bash: identifying directories

Michael Paoli Michael.Paoli at cal.berkeley.edu
Wed Jun 4 02:36:59 PDT 2008


> Date: Tue, 3 Jun 2008 11:24:57 -0700
> From: "Clyde Jones" <slash5toaster at gmail.com>
> Subject: Re: [sf-lug] bash: identifying directories
> Cc: sf-lug <sf-lug at linuxmafia.com>
> 
> On Tue, Jun 3, 2008 at 11:10 AM, Matt Price <matt.price at utoronto.ca> wrote:
> > another little scripting question:
> >
> > i'd like this tiny script i'm writing to scan the current directory,
> > identify the subdirectories, and then do something in each of them.  so
> > in pseudocode:
> >
> > [find dirs]
> >
> > for DIR in $dirs ; do
> >        cd $DIR
> >        [do some stuff]
> >        cd ..
> > done
> >
> > is this trivial to do?  20 minutes with the abs-guide hasn't given me
> > the answer yet...
> 
> #!/bin/sh
> 
> #variables
> # this set the delimiter to be a carriage return ONLY instead of space
> plus carriage return -
> #so we can handle items with a space in  the name
> oldIFS=$IFS
> IFS="
> "
> SUBDIR=$(find . -maxdepth 1 -type d)
> 
> for DIRS in $SUBDIR
>  do
>     # your thing
>     echo "Thrashing $DIRS in $SUBDIR"
>  done
> 
> #cleanup!!
> IFS=$oldIFS

Hmmmmm...

$ find . -type d -print
.
$ cat foo
#!/bin/sh
IFS="
"
SUBDIRS=$(find . -maxdepth 1 -type d)
for DIR in $SUBDIRS
do
    (cd "$DIR")
done
$ mkdir 'some
> dir'
$ ./foo
./foo: line 7: cd: ./some: No such file or directory
./foo: line 7: cd: dir: No such file or directory
$ ./bar
cd worked
$ expand -i4 < bar
#!/bin/sh
for tmp in ./*/ .[!.]*/ ..?*/
do
    [ -d "$tmp" ] || { :; continue; }
    (
        cd "$tmp" &&
        {
            echo cd worked
            : do your thing
        }
    )
done
$ 

Some points:

A subshell () has its own working directory (and environment, and shell
variables).  This can be handy, for, e.g., not having to explicitly
track what directory to return to (which can be problematic in many
ways, e.g. one might not be able to return there, or it may have moved
by the time one wants to go back there ... we're talking multiuser
multiprocessing operating system, after all).

In Linux (and Unix, and *nix in general - at least for *nix
filesystems), filenames can be composed of one or more of any ASCII
characters, except for ASCII nul and /.  With internationalization this
is even extended further.  Most notably, newline, carriage return,
whitespace, etc., can all be part of a filename (of any type, including
file of type directory).

For more modern typical shells, if a shell glob pattern ends in /, it
will only match directories ... however, with default globbing, if no
pattern is matched, the literal pattern is returned.

http://www.rawbw.com/~mp/unix/sh/#Good_Programming_Practices




More information about the sf-lug mailing list