Files

171 lines
4.6 KiB
Bash

#!/bin/bash
# Ver: 1.3 by Endial Fang (endial@126.com)
#
# 文件管理函数库
# 加载依赖项
source "/usr/local/lib/liblog.sh"
# 函数列表
# 确保指定的 文件/路径 所属权为指定的 用户/组
# 参数:
# $1 - 文件路径
# $2 - 用户
# $3 - 用户组
ensure_owned_by() {
local path="${1:?path is missing}"
local owner="${2:?owner is missing}"
local group="${3:-}"
if [[ -n $group ]]; then
chown "$owner":"$group" "$path"
else
chown "$owner":"$owner" "$path"
fi
}
# 检测目录是否存在,如果不存在则创建,同时修改为指定的用户
# 参数:
# $1 - 目录路径
# $2 - 用户
# $3 - 用户组
ensure_dir_exists() {
local dir="${1:?directory is missing}"
local owner_user="${2:-}"
local owner_group="${3:-}"
[ -d "${dir}" ] || mkdir -p "${dir}"
if [[ -n $owner_user ]]; then
ensure_owned_by "$dir" "$owner_user" "$owner_group"
fi
}
# 检测目录是否存在或为空
# 参数:
# $1 - 目录路径
is_dir_empty() {
local dir="${1:?missing directory}"
# 计算真实路径,避免符号链接问题
local -r dir="$(realpath "$path")"
if [[ ! -e "$dir" ]] || [[ -z "$(ls -A "$dir")" ]]; then
true
else
false
fi
}
# 检测挂载的路径是否存在或为空
# 参数:
# $1 - 文件或路径
is_mounted_dir_empty() {
local dir="${1:?missing directory}"
if is_dir_empty "$dir" || find "$dir" -mindepth 1 -maxdepth 1 -not -name ".snapshot" -not -name "lost+found" -exec false {} +; then
true
else
false
fi
}
# 检测指定的路径当前用户是否可写入
# 参数:
# $1 - 文件或路径
is_writable() {
local file="${1:?missing file}"
local dir
dir="$(dirname "$file")"
if [[ (-f "$file" && -w "$file") || (! -f "$file" && -d "$dir" && -w "$dir") ]]; then
true
else
false
fi
}
# 生成相对路径
# 参数:
# $1 - 路径
# $2 - 基准路径
relativize() {
local -r path="${1:?missing path}"
local -r base="${2:?missing base}"
pushd "$base" >/dev/null || exit
realpath -q --no-symlinks --relative-base="$base" "$path" | sed -e 's|^/$|.|' -e 's|^/||'
popd >/dev/null || exit
}
# 循环设置目录中子目录及文件权限
# 参数:
# $1 - paths (as a string).
# Flags:
# -f|--file-mode - 文件权限模式
# -d|--dir-mode - 目录权限模式
# -u|--user - 用户
# -g|--group - 用户组
configure_permissions_ownership() {
local -r paths="${1:?paths is missing}"
local dir_mode=""
local file_mode=""
local user=""
local group=""
# 参数有效性校验
shift 1
while [ "$#" -gt 0 ]; do
case "$1" in
-f|--file-mode)
shift
file_mode="${1:?missing mode for files}"
;;
-d|--dir-mode)
shift
dir_mode="${1:?missing mode for directories}"
;;
-u|--user)
shift
user="${1:?missing user}"
;;
-g|--group)
shift
group="${1:?missing group}"
;;
*)
error "Invalid command line flag $1" >&2
return 1
;;
esac
shift
done
read -r -a filepaths <<< "$paths"
for p in "${filepaths[@]}"; do
if [[ -e "$p" ]]; then
debug "Check $p"
find -L "$p" -printf ""
if [[ -n ${dir_mode} ]]; then
debug "Change permissions to ${dir_mode} of directories in $p"
find -L "$p" -type d ! -perm "$dir_mode" -print0 | xargs -r -0 chmod "$dir_mode"
fi
if [[ -n ${file_mode} ]]; then
debug "Change permissions to ${file_mode} of files in $p"
find -L "$p" -type f ! -perm "$file_mode" -print0 | xargs -r -0 chmod "$file_mode"
fi
if [[ -n $user ]] && [[ -n ${group} ]]; then
debug "Change ownership to ${user}:${group} of files and directories in $p"
find -L "$p" -print0 | xargs -r -0 chown "${user}:${group}"
elif [[ -n $user ]] && [[ -z $group ]]; then
debug "Change user to ${user} of files and directories in $p"
find -L "$p" -print0 | xargs -r -0 chown "${user}"
elif [[ -z $user ]] && [[ -n $group ]]; then
debug "Change group to ${group} of files and directories in $p"
find -L "$p" -print0 | xargs -r -0 chgrp "${group}"
fi
else
error "$p does not exist"
fi
done
}