Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 370
  • Last Modified:

Detecting whether directory has any files in it

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
894359
Asked:
894359
  • 15
  • 12
  • 5
  • +2
1 Solution
 
HamdyHassanCommented:

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
 
HamdyHassanCommented:
complete code

dir_blocks=`du -s $1 | cut -f1 -d"      "`
if [ "$dir_blocks" -eq 0 ] ; then
   No Files
else
   Directory has files
fi
0
 
894359Author Commented:
I'm already using $1 form the command line!
0
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.

 
894359Author Commented:
Also should there be that big gap at the end of your first line?? d"      "
0
 
jimbbCommented:
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
 
HamdyHassanCommented:
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
 
894359Author Commented:
Yes the paths have the trailing "/"
0
 
jimbbCommented:
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
 
jimbbCommented:
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
 
894359Author Commented:
It was the tab that was getting me! Thanks!
0
 
894359Author Commented:
I'll continue testing!
0
 
894359Author Commented:
hi jimbb the first one means if no files in directory?

if ! ls $pathname_to_move* > /dev/null 2>&1 ; then
0
 
HamdyHassanCommented:
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
 
jimbbCommented:
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
 
jimbbCommented:
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
 
biraCommented:
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
 
894359Author Commented:
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
 
894359Author Commented:
I'll post an additional 200 for the oversite!
0
 
jimbbCommented:
You can add the "-maxdepth 1" argument to 'find' to restrict it to 1 subdirectory.
0
 
894359Author Commented:
Bira... what does the "cut -c1-10 2" mean?

It worked!
0
 
894359Author Commented:
I know the c1-10 means the first 10 chars of the line but what  about the 2????/
0
 
jimbbCommented:
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
 
894359Author Commented:
Hi jimbb... what find method do you mean?
0
 
jimbbCommented:
The 'find' command!  I've been talking about it in my posts above......
0
 
894359Author Commented:
Sorry... i overlooked that!
0
 
yuzhCommented:
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
 
894359Author Commented:
yuzh... your solution returns true everytime I try it even if nothing is in the directory!
0
 
yuzhCommented:
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
 
jimbbCommented:
FILES="$(find /tmp/test/ ! -type d -maxdepth 1)"

if test "$FILES" ; then
  echo "Directory contains files"
else
  echo "Directory is empty"
fi
0
 
jimbbCommented:
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
 
jimbbCommented:
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
 
yuzhCommented:
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
 
jimbbCommented:
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
 
894359Author Commented:
All I want to know is if there is anything in the current directory.. file or directory?
0
 
yuzhCommented:
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
 
HamdyHassanCommented:
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
 
biraCommented:
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
 
894359Author Commented:
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
 
biraCommented:
Thanks and the best regards
0

Featured Post

Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

  • 15
  • 12
  • 5
  • +2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now