Last active
January 6, 2018 13:57
-
-
Save shellexy/71fbf233a2d42d27c23f357df061a534 to your computer and use it in GitHub Desktop.
使用文件系统镜像来实现文件夹容量限额
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/bash | |
| ## 使用文件系统镜像来实现文件夹容量限额 | |
| help()( | |
| echo "设置目录限额 | |
| 用法: | |
| quota 添加一个限额目录 | |
| list 列出限额的目录 | |
| unquota 某目录不再限额 | |
| quit 退出程序 | |
| " | |
| ) | |
| quota()( | |
| ## 使用文件系统镜像来实现文件夹容量限额 | |
| quota_dir="$1" | |
| quota_size="$2" | |
| ## 提示输入 quota_dir quota_size | |
| test -n "$quota_dir" || read -e -i "quota_dir" -p "请输入要限制总容量大小的文件夹名字: " quota_dir | |
| test -n "$quota_size" && test "$quota_size" -gt 1 || read -e -i "50" -p "请输入文件夹限制大小(单位 M): " quota_size | |
| ## 用 test "$quota_size" -gt 1 来验证 quota_size 的数字大于 1 | |
| test -n "$quota_dir" && test "$quota_size" -gt 1 || { | |
| echo "用法: quota 目录名 限额大小" | |
| exit | |
| } | |
| quota_dir=$(readlink -f "$quota_dir") | |
| quota_mnt="$quota_dir" | |
| ## 镜像文件名 为在 quota_dir 目录下的 .quota.img | |
| quota_img="$quota_dir/.quota.img" | |
| echo "将把文件夹 '$quota_dir' 限额为 $quota_size MB,文件夹内原有文件会被隐藏" | |
| ## 因为使用文件系统镜像会损失一点容量,所以将原有容量 x 1.1 | |
| quota_size=$[quota_size*11/10] | |
| mkdir -p "$quota_mnt" | |
| ## @TODO 在已经存在镜像文件,但是限额大小不一样的情况下,需要重设大小 | |
| ## 如果目录下已经有镜像文件,则先尝试挂载原有镜像文件 | |
| test -a "$quota_img" && { | |
| echo "限额目录下已经存在限额用镜像文件,先尝试挂载使用" | |
| mount -o loop "$quota_img" "$quota_mnt" || { | |
| read -e -p "无法挂载现有镜像文件,您是否要初始化镜像文件?[Y/N]" IS_MKFS | |
| test "$IS_MKFS" = "Y" -o "$IS_MKFS" = "y" || { | |
| echo "您取消了初始化,退出目录限额操作" | |
| exit | |
| } | |
| } | |
| } | |
| ## 创建镜像文件 | |
| echo "初始化限额镜像文件…" | |
| dd if=/dev/zero of="$quota_img" bs=1M count="$quota_size" | |
| mkfs.ext4 -m 0 "$quota_img" | |
| ## 将镜像文件挂载为 限额目录 | |
| mount -o loop "$quota_img" "$quota_mnt" || { | |
| echo "无法挂载限额用镜像文件,退出目录限额操作" | |
| exit | |
| } | |
| ## 写入 fstab | |
| fstab="/etc/fstab" | |
| sed -i "/${quota_img//\//\\/}/d" /etc/fstab | |
| fstab_line="$quota_img $quota_mnt ext4 loop 0 0" | |
| echo "$fstab_line" >> /etc/fstab | |
| echo -e "在 /etc/fstab 增加了一行\n$fstab_line\n解除限额时将删掉该行" | |
| ) | |
| list()( | |
| ## 从 /etc/fstab 里列出限额了的目录名字 | |
| dirs="`grep -E '\.quota\.img.*loop' /etc/fstab | awk '{print $2}'`" | |
| echo -e "$dirs \n" | |
| test -n "$dirs" && df -h $dirs | |
| ) | |
| unquota()( | |
| echo "以下目录已经限额:" | |
| list | |
| read -e -p "您希望对哪个目录解除限额:" quota_dir | |
| quota_dir=$(readlink -f "$quota_dir") | |
| quota_img="$quota_dir/.quota.img" | |
| test -e "$quota_dir" && grep -q "$quota_img" /etc/fstab || { | |
| echo "限额的目录里没有找到您输入的 '$quota_dir'" | |
| exit | |
| } | |
| read -e -i "N" -p "您是否确认解除目录 '$quota_dir' 的限额?[Y/N]" IS_UNQUOTA | |
| echo "$IS_UNQUOTA" | grep -q -E '^[Yy]$' || exit | |
| ## 卸载镜像,并修改 /etc/fstab 里的限额记录 | |
| umount -f "$quota_dir" && sed -i "/${quota_img//\//\\/}/d" /etc/fstab || { | |
| echo "解除失败" | |
| exit | |
| } | |
| ## 之前是使用镜像文件来实现限额,所以解除限额时 询问是否将限额期间的内容回写进原目录 | |
| read -e -i "Y" -p "是否将镜像文件里的内容写回原有目录?[Y/N]" IS_WRITEBACK | |
| echo "$IS_WRITEBACK" | grep -q -E '^[Yy]$' && { | |
| tmp_dir="$quota_dir/.quota.dir" | |
| mkdir -p "$tmp_dir" | |
| mount -o loop "$quota_img" "$tmp_dir" && | |
| rsync -u -h -a -A -X -S --progress --exclude=lost+found "$tmp_dir/." "$quota_dir" && { | |
| echo "已经成功写回 '$quota_dir'" | |
| } || { | |
| echo "回写失败" | |
| } | |
| sync | |
| umount -f "$tmp_dir" && rmdir "$tmp_dir" | |
| } | |
| ## 删除限额用镜像 | |
| read -e -i "N" -p "是否删除限额用过的镜像文件?[Y/N]" IS_DEL | |
| echo "$IS_DEL" | grep -q -E '^[Yy]$' && { | |
| rm -v "$quota_img" | |
| } | |
| ## | |
| echo "已经解除了目录 '$quota_dir' 的限额,目前依然限额的目录为:" | |
| list | |
| ) | |
| help ##帮助 | |
| while true; do | |
| [ -z "$HELPED" ] && echo '查看帮助请输入 help' | |
| HELPED=1 | |
| read -e -p '请选择命令> ' CMD | |
| [ "$CMD" = quit ] && exit | |
| [ "$CMD" = q ] && exit | |
| ## 检测输入的命令有没有存在对应函数 | |
| test -z "$CMD" && continue ## 输入命令为空 | |
| type -t "$CMD" | grep -q function || { | |
| echo "命令 $CMD 没找到,查看帮助请输入 help" | |
| continue | |
| } | |
| ## 测试模式下不实际执行命令,而是显示命令内容 | |
| if [ -n "$TEST" ] ; then | |
| type "$CMD" | |
| else | |
| "$CMD" | |
| fi | |
| done | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment