#!/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 }