【问题标题】:Bash script to keep deleting files until directory size is less than XBash 脚本继续删除文件,直到目录大小小于 X
【发布时间】:2019-07-10 01:15:52
【问题描述】:

我正在尝试编写一个脚本来继续从文件夹 (/home/folder) 中删除文件,直到主目录 (/home/) 的大小小于 X GB。该脚本应一次删除 25 个文件,这些文件应该是目录中最旧的文件。然而,我是一个菜鸟,我想不出一个循环。相反,我在下面写了几次相同的脚本行;它有效,但我希望有一个更好的循环。你能用更优雅、更有效的方式帮助我吗?

size=$(du -shb /home/ | awk '{print $1}')
if [ "$size" -gt X ]; then
find /home/folder -maxdepth 1 -type f -printf '%T@\t%p\n' | sort -r | tail -n 25 | sed 's/[0-9]*\.[0-9]*\t//' | xargs -d '\n' rm -f
sleep 30
else
exit
fi

【问题讨论】:

标签: bash debian


【解决方案1】:

还不错!让它循环的最简单方法就是在它周围添加一个无限循环。您的退出语句将退出脚本,因此显然也会退出循环:

while true
do
  size=$(du -shb /home/ | awk '{print $1}')
  if [ "$size" -gt X ]; then
    find /home/folder -maxdepth 1 -type f -printf '%T@\t%p\n' | sort -r | tail -n 25 | sed     's/[0-9]*\.[0-9]*\t//' | xargs -d '\n' rm -f
    sleep 30
  else
    exit  # <- Loop/script exits here
  fi
done

你也可以重写逻辑让它更漂亮:

while [ "$(du -shb /home/ | awk '{print $1}')" -gt X ]
do
  find /home/folder -maxdepth 1 -type f -printf '%T@\t%p\n' | \
      sort -n | head -n 25 | cut -d $'\t' -f 2-  | xargs -d '\n' rm -f
done

您还可以将其重写为不一遍又一遍地迭代 /home,从而允许您删除单个文件而不是 25 个块:

usage=$(du -sb /home | cut -d $'\t' -f 1)
max=1000000000
if (( usage > max ))
then
  find /home/folder -maxdepth 1 -type f -printf '%T@\t%s\t%p\n' | sort -n | \
    while (( usage > max )) && IFS=$'\t' read timestamp size file
    do
      rm -- "$file" && (( usage -= size ))
    done
fi

【讨论】:

    【解决方案2】:

    如果您正在寻找兼容 BusyBox 的脚本:

    DIRECTORY=$1
    MAX_SIZE_MB=$2
    KB_TO_MB=1000
    MAX_SIZE_KB=$(($MAX_SIZE_MB*$KB_TO_MB))
    
    if [ ! -d "$DIRECTORY" ]
    then
      echo "Invalid Directory: $DIRECTORY"
      exit 1
    fi
    
    usage=$(du -s $DIRECTORY | awk '{print $1}')
    echo "$DIRECTORY - $(($usage/$KB_TO_MB))/$MAX_SIZE_MB MB Used"
    if (( usage > $MAX_SIZE_KB ))
    then
        #https://stackoverflow.com/questions/1447809/awk-print-9-the-last-ls-l-column-including-any-spaces-in-the-file-name
        files=($(find $DIRECTORY -maxdepth 1 -type f -print| xargs ls -lrt | sed -E -e 's/^([^ ]+ +){8}//'))
        for file in ${files[@]};
        do
            size=$(du -s "$file" | awk '{print $1}')
            rm -f "$file"
            ((usage -= size))
            if (( $usage < $MAX_SIZE_KB ))
            then
               break
            fi  
        done
    fi
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-07-22
      • 1970-01-01
      • 2015-03-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多