?
Solved

Detecting whether directory has any files in it

Posted on 2003-03-11
39
Medium Priority
?
355 Views
Last Modified: 2010-04-21
I have a script that has this in it:

if [ -d $pathname_to_move ] ; then
  mv -f $pathname_to_move* $pathname_to_make

The problem is if the move directory ($pathname_to_move*) doesn't have any files in it I get an error for the move. In a ksh script how do I detect if a dir has any files in it? This is only part of the script so please don't respond with there is not a need to use this command etc...

Thanks!
0
Comment
Question by:894359
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 15
  • 12
  • 5
  • +2
39 Comments
 
LVL 9

Expert Comment

by:HamdyHassan
ID: 8113514

dir_blocks=`du -s bin | cut -f1 -d"  "`

then you add condition
if dir_blocks is 0 then no files under this folder



Note that
` is back quote
"  "  is TAB between two double quotes
0
 
LVL 9

Expert Comment

by:HamdyHassan
ID: 8113547
complete code

dir_blocks=`du -s $1 | cut -f1 -d"      "`
if [ "$dir_blocks" -eq 0 ] ; then
   No Files
else
   Directory has files
fi
0
 

Author Comment

by:894359
ID: 8113809
I'm already using $1 form the command line!
0
Optimize your web performance

What's in the eBook?
- Full list of reasons for poor performance
- Ultimate measures to speed things up
- Primary web monitoring types
- KPIs you should be monitoring in order to increase your ROI

 

Author Comment

by:894359
ID: 8113848
Also should there be that big gap at the end of your first line?? d"      "
0
 
LVL 2

Expert Comment

by:jimbb
ID: 8114170
Does "$pathname_to_move" end with a "/" character?  Is that why you have that problem?  If so, what about not using the / on the end of the path?

Moving along:

HamdyHassan, did you test the script you wrote?  Are you saying that an empty directory will show up as 0 blocks with du -s?  I don't believe that is correct.  For one thing, the directory itself takes up some space which is > 0.  And, many filesystems also won't bother shrinking the directory entry when you remove files from the directory, so if you had a 16 byte directory and then took all the files out of it, it may still occupy 16 bytes.

894359: there's probably a lot of ways to do it.  One way which comes to mind is to do a "find $pathname_to_move ! -type d" and if that produces any output (check it with 'wc' or whatever) then you know there's something in there that's not a directory.

Or if the directory can only be 1 level deep, you could 'rmdir' it; if it succeeds it was empty and you can just mkdir it in the new location... if it fails, it is not empty.
0
 
LVL 9

Expert Comment

by:HamdyHassan
ID: 8114327
Yes I tested it before posting.

about the code

dir_blocks=`du -s $pathname_to_move | cut -f1 -d"      "`
if [ "$dir_blocks" -eq 0 ] ; then
  No Files
else
  Directory has files
fi



about d"      "
is not spaces, you just click <TAB> key


0
 

Author Comment

by:894359
ID: 8114520
Yes the paths have the trailing "/"
0
 
LVL 2

Expert Comment

by:jimbb
ID: 8114551
HamdyHassan, on what filesystem did you test this?

Can you paste an example of the output you get?  Because maybe I am just not seeing what you're doing.  Here is what I get, and as you can see /tmp/test is empty.

$ mkdir /tmp/test
$ dir_blocks=`du -s /tmp/test | cut -f1 -d"       "`
$ echo $dir_blocks
4
0
 
LVL 2

Expert Comment

by:jimbb
ID: 8114606
894359: another method, besides everything suggested above, could be something like this if you didn't want to omit the trailing slash from the pathname:

if ! ls $pathname_to_move* > /dev/null 2>&1 ; then
    do whatever
fi

or, the reverse of that:

if ls $pathname_to_move* > /dev/null 2>&1 ; then
    :  #do nothing
else
    do whatever
fi
0
 

Author Comment

by:894359
ID: 8114621
It was the tab that was getting me! Thanks!
0
 

Author Comment

by:894359
ID: 8114632
I'll continue testing!
0
 

Author Comment

by:894359
ID: 8114704
hi jimbb the first one means if no files in directory?

if ! ls $pathname_to_move* > /dev/null 2>&1 ; then
0
 
LVL 9

Expert Comment

by:HamdyHassan
ID: 8114743
jimbb :

Try the command at your home and it's working
1279 /home/hhassan1> mkdir $HOME/bin/hh
1280 /home/hhassan1> du -s $HOME/bin/hh
0       /home/hhassan1/bin/hh

Try the command at shared and it's working
1282 /home/hhassan1> mkdir /export/vol/data/itd/ctx/kk
1283 /home/hhassan1> du -s /export/vol/data/itd/ctx/kk
0       /export/vol/data/itd/ctx/kk


and yes, if you try at /tmp , it's not working.


0
 
LVL 2

Expert Comment

by:jimbb
ID: 8114750
Correct.. literally "if ls $path/* fails" which indicates that there are no files in there.

NOTE however, that if there are dot-files in there (".whatever"), those won't be picked up by the "*" pattern.

Personally I'd go with the "find" method, as I think it will be the most "deterministic."  i.e., you won't get any surprises.
0
 
LVL 2

Expert Comment

by:jimbb
ID: 8114771
HamdyHassan: what filesystem is /home on in your example?

I cannot reproduce that on my Linux or Solaris boxes (or any box for that matter).

Solaris 8:
$ pwd
/export/home/jimb
$ mkdir testdir
$ du -s testdir
2       testdir
0
 
LVL 6

Expert Comment

by:bira
ID: 8115190
Create a work dir named teste and run as below

a=`ls ./teste|wc|cut -c1-10 2>/dev/null`
if [ $a = 0 ];then
   echo "Dir is empty"
     else
   echo "There are files here"
fi
0
 

Author Comment

by:894359
ID: 8115519
would any of these suggestions work if there were sub directories? I forgot to mention :0 that if there are sub dirs than it doesn't matter! I only need to check for files when there are no sub dirs.
0
 

Author Comment

by:894359
ID: 8115524
I'll post an additional 200 for the oversite!
0
 
LVL 2

Expert Comment

by:jimbb
ID: 8115581
You can add the "-maxdepth 1" argument to 'find' to restrict it to 1 subdirectory.
0
 

Author Comment

by:894359
ID: 8115610
Bira... what does the "cut -c1-10 2" mean?

It worked!
0
 

Author Comment

by:894359
ID: 8115621
I know the c1-10 means the first 10 chars of the line but what  about the 2????/
0
 
LVL 2

Expert Comment

by:jimbb
ID: 8115674
The "2> /dev/null" means "write the output of file descriptor 2 to /dev/null"; in other words, any error output will be sent to /dev/null.

As I said from the beginning ;) there's going to be a lot of ways to do it.  I still recommend the find method (did you try it??) as it will be very portable.  Also note that Bira's doesn't work the way you expect if there are any dot files in the directory.  And, if you were to run it on a system where the 'wc' output were not all contained within the first 10 characters (I don't know of any UNIX like that off-hand, but I try to emphasize portability whenever possible so you don't get any "surprises" when you run your script on another OS), then you may also not get the results you expect....
0
 

Author Comment

by:894359
ID: 8115764
Hi jimbb... what find method do you mean?
0
 
LVL 2

Expert Comment

by:jimbb
ID: 8115800
The 'find' command!  I've been talking about it in my posts above......
0
 

Author Comment

by:894359
ID: 8115816
Sorry... i overlooked that!
0
 
LVL 38

Expert Comment

by:yuzh
ID: 8115906
You can do:

if [ ! -z `find $pathname_to_move -type f -print ` ] ; then
    echo " there is file in the dir !"
    # do something
else
    echo "There's no regular file in the dir"
fi

0
 

Author Comment

by:894359
ID: 8116016
yuzh... your solution returns true everytime I try it even if nothing is in the directory!
0
 
LVL 38

Expert Comment

by:yuzh
ID: 8116490
I just did a quick test with Solaris, it works find for me.

Are you useing relative path in $pathname_to_move ?

If if is the case, you need to to:
cd /my-work-dir first.

also to play safe. change the if statement to looks like (use {} around the var !):

if [ ! -z `find ${pathname_to_move} -type f -print ` ] ; then
   echo " there is file in the dir !"
   # do something
else
   echo "There's no regular file in the dir"
fi


see how it goes !
0
 
LVL 2

Expert Comment

by:jimbb
ID: 8116508
FILES="$(find /tmp/test/ ! -type d -maxdepth 1)"

if test "$FILES" ; then
  echo "Directory contains files"
else
  echo "Directory is empty"
fi
0
 
LVL 2

Expert Comment

by:jimbb
ID: 8116514
Oops, of course "/tmp/test" should be substituted with your $pathname_to_move, that was just a paste of what I was testing with on my system.
0
 
LVL 2

Expert Comment

by:jimbb
ID: 8116983
Argh, and after my whole rant about portability, it turns out that Solaris's 'find' doesn't have the -maxdepth option, or any equivalent that I can see. ;) (You could install GNU find, but it's probably not worthwhile for this small task.)

Open/Free/NetBSD and Linux have the option; not sure about other *nixes.  Which are you using btw?
0
 
LVL 38

Expert Comment

by:yuzh
ID: 8117047
If you are using relative path, let say $pathname_to_move is under /mydir

in your script you do:
#!/bin/ksh
#var declarations

cd /mydir
if [ ! -z `find ${pathname_to_move} -type f -print ` ] ; then
  echo " there is file in the dir !"
  # do something
else
  echo "There's no regular file in the dir"
fi

#do something else
# End of script
0
 
LVL 2

Expert Comment

by:jimbb
ID: 8117066
yuzh,
that script does the same thing as the last one I posted, except he says he only wishes to check 1 level deep.
0
 

Author Comment

by:894359
ID: 8117458
All I want to know is if there is anything in the current directory.. file or directory?
0
 
LVL 38

Expert Comment

by:yuzh
ID: 8117946
you can simply do:

cd /mydir
if [ ! -z `/usr/bin/ls` ] ; then
 echo " there is somthing in the /mydir !"
 # do something
else
 echo "There's nothing in /mydir"
fi


0
 
LVL 9

Expert Comment

by:HamdyHassan
ID: 8118893
all posts based on non correct fact

I tested moving directory while is empty and it's working
I tested moving directory while is not empty and it's working


I think the bug in extra "*" at the following
 mv -f $pathname_to_move* $pathname_to_make

It should be
 mv -f $pathname_to_move $pathname_to_make


Make sure "mv" is  /usr/bin/mv  
by doing the following command
 /usr/bin/mv -f $pathname_to_move $pathname_to_make

sometimes, you could have an alias for "mv" that point to different command, to make sure do the following command

prompt> which mv


0
 
LVL 6

Accepted Solution

by:
bira earned 2000 total points
ID: 8119431
Hey 894359

  I believe that your application will work with my solution, for no dot files will be considered by

 a=`ls ./teste|wc|cut -c1-10 2>/dev/null`
if [ $a = 0 ];then
   echo "Dir is empty"
     else
   echo "There are files here"
fi
0
 

Author Comment

by:894359
ID: 8121230
I'll also post some points for everyone else since everyone put in a lot of work/advice look for your points posted under your names! thank you all!
0
 
LVL 6

Expert Comment

by:bira
ID: 8121280
Thanks and the best regards
0

Featured Post

What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

A metadevice consists of one or more devices (slices). It can be expanded by adding slices. Then, it can be grown to fill a larger space while the file system is in use. However, not all UNIX file systems (UFS) can be expanded this way. The conca…
I have been running these systems for a few years now and I am just very happy with them.   I just wanted to share the manual that I have created for upgrades and other things.  Oooh yes! FreeBSD makes me happy (as a server), no maintenance and I al…
Learn how to navigate the file tree with the shell. Use pwd to print the current working directory: Use ls to list a directory's contents: Use cd to change to a new directory: Use wildcards instead of typing out long directory names: Use ../ to move…
This video shows how to set up a shell script to accept a positional parameter when called, pass that to a SQL script, accept the output from the statement back and then manipulate it in the Shell.
Suggested Courses

771 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question