简体   繁体   English

仅在没有文件时才删除目录的 bash shell 脚本

[英]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.好的,所以我正在编写一个 shell 脚本来删除一个目录,但前提是里面没有文件。

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.我想要做的是有一个 if 语句,它将检查目录中是否有文件,如果有文件询问用户是否要先删除文件然后删除目录。

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:这是我到目前为止创建的用于检查目录中是否存在文件的 if 语句:

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
        ;;

You don't need to check;您无需检查; rmdir will only delete empty directories. rmdir只会删除空目录。

$ 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命令来询问用户是否要删除所有内容。

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

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.对脚本进行最小的更改,您可以使用 bash globing 来查看它是否已满(也可以创建一个数组,但看不到一个很好的理由),尽管我可能仍会使用类似于chepner 的脚本并让rmdir处理错误检查。

#!/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)变量名区分大小写, $dName不等于$Dname (如果变量名包含空格或其他特殊字符,您应该真正引用变量名)
  • directory is not an array, you could have made it one by doing something like directory=($Dname/*) directory不是一个数组,您可以通过执行类似directory=($Dname/*)类的操作来使其成为一个数组
  • ! will try to perform history expansion in double quotes if you have the option on.如果您有选项,将尝试在双引号中执行历史扩展。

If the directory is not empty, rmdir will raise an error and your script will stop if you run set -e before.如果目录不为空, rmdir将引发错误,如果您之前运行set -e ,您的脚本将停止。 You can simply check the ls output to see if a directory is empty before removing such directory:您可以简单地检查ls输出以查看目录是否为空,然后再删除该目录:

[ "$(ls -A "$directory")" ] || rmdir "$directory"

It's not 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.它不容易出现竞争条件,因为如果在第一个命令之后和第二个命令之前将文件添加到目录中,它将引发错误。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM