user258030
user258030

Reputation: 305

bash shell script to delete directory only if there are no files

Ok so I am writing a shell script to delete a directory but only if there are no files inside.

what I want to do is have an if statement that will check if there are files in the directory and if there are files ask the user if they want to delete the files first and then delete the directory.

I have looked quite a bit into this and have found a way to check if files exist in the directory but I haven't been able to make it past that stage.

here is the if statement I have created so far to check if files exist in a directory:

echo "Please type the name of the directory you wish to remove "

                read dName
        shopt -s nullglob
        shopt -s dotglob
        directory=$Dname

        if [ ${#directory[@]} -gt 0 ];
        then
                echo "There are files in this directory! ";
        else
                echo "This directory is ok to delete! "
        fi
        ;;

Upvotes: 12

Views: 11823

Answers (4)

Scott Aron Bloom
Scott Aron Bloom

Reputation: 51

rm -d $directory

rm since at least version 8.22 has supported this.

Upvotes: 1

Martin Braun
Martin Braun

Reputation: 12639

If the directory is not empty, rmdir will raise an error and your script will stop if you run set -e before. You can simply check the ls output to see if a directory is empty before removing such directory:

test -n "$(ls -A "$directory")" || rmdir "$directory"

It's sadly prone to race conditions, because it will raise an error if a file gets added to the directory after the first and before the second command.

Upvotes: 1

Reinstate Monica Please
Reinstate Monica Please

Reputation: 11633

It feels like you're mixing some languages in the syntax you're using. Making minimal changes to your script, you can just use bash globing to see if it's full (could make an array as well, but don't see a good reason to), though I would probably still use something similar to chepner's script and let rmdir handle error checking.

#!/bin/bash

echo "Please type the name of the directory you wish to remove "

read dName
[[ ! -d $dName ]] && echo "$dName is not a directory" >&2 && exit 1 
shopt -s nullglob
shopt -s dotglob

found=
for i in "$dName"/*; do
  found=: && break
done

[[ -n $found ]] && echo 'There are files in this directory!' || echo 'This directory is ok to delete!'

Note couple of errors in your original syntax:

  • Variable names are case sensitive, $dName does not equal $Dname (and you should really quote variable names in case they have spaces or other special characters)
  • directory is not an array, you could have made it one by doing something like directory=($Dname/*)
  • ! will try to perform history expansion in double quotes if you have the option on.

Upvotes: 1

chepner
chepner

Reputation: 532418

You don't need to check; rmdir will only delete empty directories.

$ mkdir foo
$ touch foo/bar
$ rmdir foo
rmdir: foo: Directory not empty
$ rm foo/bar
$ rmdir foo
$ ls foo
ls: foo: No such file or directory

In a more practical setting, you can use the rmdir command with an if statement to ask the user if they want to remove everything.

if ! rmdir foo 2> /dev/null; then
    echo "foo contains the following files:"
    ls foo/
    read -p "Delete them all? [y/n]" answer
    if [[ $answer = [yY] ]]; then
        rm -rf foo
    fi
fi

Upvotes: 19

Related Questions