本文目录导读:

#!/bin/bash
# 批量转换文件所有权脚本
# 使用方法: ./change_owner.sh <目录路径> <新所有者> [新用户组]
# 检查参数
if [ $# -lt 2 ]; then
echo "用法: $0 <目录路径> <新所有者> [新用户组]"
echo "示例:"
echo " $0 /path/to/dir newuser # 只更改所有者"
echo " $0 /path/to/dir newuser newgroup # 更改所有者和用户组"
exit 1
fi
TARGET_DIR="$1"
NEW_OWNER="$2"
NEW_GROUP="${3:-}" # 如果没有提供第三个参数,则设为空
# 检查目录是否存在
if [ ! -d "$TARGET_DIR" ]; then
echo "错误: 目录 '$TARGET_DIR' 不存在"
exit 1
fi
# 检查新所有者是否存在
if ! id "$NEW_OWNER" &>/dev/null; then
echo "错误: 用户 '$NEW_OWNER' 不存在"
exit 1
fi
# 如果提供了新用户组,检查其是否存在
if [ -n "$NEW_GROUP" ] && ! getent group "$NEW_GROUP" &>/dev/null; then
echo "错误: 用户组 '$NEW_GROUP' 不存在"
exit 1
fi
echo "开始更改 '$TARGET_DIR' 目录下所有文件的所有权..."
echo "新的所有者: $NEW_OWNER"
[ -n "$NEW_GROUP" ] && echo "新的用户组: $NEW_GROUP"
echo "----------------------------------------"
# 执行更改
if [ -n "$NEW_GROUP" ]; then
# 同时更改所有者和用户组
chown -R "$NEW_OWNER:$NEW_GROUP" "$TARGET_DIR"
else
# 只更改所有者
chown -R "$NEW_OWNER" "$TARGET_DIR"
fi
# 检查执行结果
if [ $? -eq 0 ]; then
echo "✅ 所有权更改成功完成!"
else
echo "❌ 更改过程中出现错误"
exit 1
fi
# 显示更改后的统计信息
echo "----------------------------------------"
echo "更改后的文件统计:"
find "$TARGET_DIR" -user "$NEW_OWNER" 2>/dev/null | wc -l | xargs echo " 文件数:"
echo "----------------------------------------"
# 显示前10个文件的示例
echo "示例文件:"
find "$TARGET_DIR" -maxdepth 2 2>/dev/null | head -10 | while read file; do
if [ -e "$file" ]; then
ls -ld "$file" | awk '{print $1, $3, $4, $9}'
fi
done
更高级的版本(包含更多功能)
#!/bin/bash
# 高级批量文件所有权转换脚本
# 功能: 批量更改文件所有者,支持多种选项
set -e # 出错时停止
# 显示帮助信息
show_help() {
cat << EOF
用法: $0 [选项] <目标目录> <新所有者> [新用户组]
选项:
-h, --help 显示此帮助信息
-v, --verbose 显示详细的操作过程
-r, --recursive 递归处理子目录 (默认启用)
-t, --type TYPE 只处理特定类型的文件 (f=普通文件, d=目录, l=符号链接)
--dry-run 模拟运行,不实际执行更改
--exclude PATTERN 排除匹配模式的文件/目录
示例:
$0 /var/www/html www-user # 递归更改所有者和目录
$0 -v /var/www/html www-user www-group # 详细模式
$0 -t f /var/www/html www-user # 只更改普通文件
$0 --dry-run /tmp/test newuser # 模拟运行
$0 --exclude "*.log" /var/log www-user # 排除日志文件
EOF
exit 0
}
# 初始化变量
VERBOSE=false
RECURSIVE=true
FILE_TYPE=""
DRY_RUN=false
EXCLUDE_PATTERN=""
# 解析命令行参数
while [[ $# -gt 0 ]]; do
case $1 in
-h|--help)
show_help
;;
-v|--verbose)
VERBOSE=true
shift
;;
-r|--recursive)
RECURSIVE=true
shift
;;
-t|--type)
FILE_TYPE="$2"
shift 2
;;
--dry-run)
DRY_RUN=true
shift
;;
--exclude)
EXCLUDE_PATTERN="$2"
shift 2
;;
*)
break
;;
esac
done
# 检查必需参数
if [ $# -lt 2 ]; then
show_help
fi
TARGET_DIR="$1"
NEW_OWNER="$2"
NEW_GROUP="${3:-}"
# 验证参数
validate_parameters() {
# 检查目录
if [ ! -d "$TARGET_DIR" ]; then
echo "错误: 目录 '$TARGET_DIR' 不存在"
exit 1
fi
# 检查用户
if ! id "$NEW_OWNER" &>/dev/null; then
echo "错误: 用户 '$NEW_OWNER' 不存在"
exit 1
fi
# 检查组
if [ -n "$NEW_GROUP" ] && ! getent group "$NEW_GROUP" &>/dev/null; then
echo "错误: 用户组 '$NEW_GROUP' 不存在"
exit 1
fi
}
# 执行更改的函数
change_ownership() {
local cmd="chown"
# 构建命令选项
[ "$RECURSIVE" = true ] && cmd+=" -R"
# 添加文件类型过滤
if [ -n "$FILE_TYPE" ]; then
case "$FILE_TYPE" in
f) find_cmd="find \"$TARGET_DIR\" -type f" ;;
d) find_cmd="find \"$TARGET_DIR\" -type d" ;;
l) find_cmd="find \"$TARGET_DIR\" -type l" ;;
*) echo "错误: 不支持的文件类型 '$FILE_TYPE'"
exit 1 ;;
esac
# 添加排除模式
if [ -n "$EXCLUDE_PATTERN" ]; then
find_cmd+=" ! -name \"$EXCLUDE_PATTERN\""
fi
# 执行更改
if [ "$DRY_RUN" = true ]; then
echo "[DRY RUN] 将要执行的命令:"
echo " $find_cmd -exec chown $NEW_OWNER${NEW_GROUP:+:$NEW_GROUP} {} \\;"
else
if [ -n "$NEW_GROUP" ]; then
eval "$find_cmd -exec chown $NEW_OWNER:$NEW_GROUP {} \\;"
else
eval "$find_cmd -exec chown $NEW_OWNER {} \\;"
fi
fi
else
# 没有文件类型过滤,直接使用 chown
cmd+=" $NEW_OWNER${NEW_GROUP:+:$NEW_GROUP} \"$TARGET_DIR\""
if [ "$VERBOSE" = true ]; then
echo "执行命令: $cmd"
fi
if [ "$DRY_RUN" = true ]; then
echo "[DRY RUN] $cmd"
else
eval "$cmd" || {
echo "错误: 执行 '$cmd' 失败"
exit 1
}
fi
fi
}
# 主程序
echo "========================================"
echo "批量文件所有权转换工具"
echo "========================================"
validate_parameters
echo "目录: $TARGET_DIR"
echo "新所有者: $NEW_OWNER"
[ -n "$NEW_GROUP" ] && echo "新用户组: $NEW_GROUP"
echo "递归处理: $RECURSIVE"
echo "详细模式: $VERBOSE"
[ "$DRY_RUN" = true ] && echo "模拟运行: 是"
echo "========================================"
# 确认操作
if [ "$DRY_RUN" = false ]; then
read -p "确认要更改所有权吗?(y/N): " confirm
if [[ ! "$confirm" =~ ^[Yy]$ ]]; then
echo "操作已取消"
exit 0
fi
fi
# 执行更改
change_ownership
if [ "$DRY_RUN" = true ]; then
echo "✅ 模拟运行完成,未实际更改任何文件"
else
# 显示统计信息
echo "========================================"
echo "更改完成!"
echo "========================================"
# 统计不同文件类型
echo "文件统计:"
echo " 普通文件: $(find "$TARGET_DIR" -type f -user "$NEW_OWNER" 2>/dev/null | wc -l)"
echo " 目录: $(find "$TARGET_DIR" -type d -user "$NEW_OWNER" 2>/dev/null | wc -l)"
echo " 符号链接: $(find "$TARGET_DIR" -type l -user "$NEW_OWNER" 2>/dev/null | wc -l)"
fi
使用方法
-
保存脚本:
# 保存为 change_owner.sh
-
添加执行权限:
chmod +x change_owner.sh
-
基本用法:
# 更改目录下所有文件的所有者 ./change_owner.sh /path/to/directory newuser # 同时更改所有者和用户组 ./change_owner.sh /path/to/directory newuser newgroup # 使用高级版本(模拟运行) ./change_owner.sh --dry-run /path/to/directory newuser
注意事项
-
需要 root 权限:更改文件所有权通常需要 root 权限
sudo ./change_owner.sh /path/to/dir newuser
-
备份重要数据:在执行前建议备份重要文件
-
检查用户存在:确保指定的用户和组在系统中存在
-
权限问题:如果遇到权限不足的问题,使用 sudo 执行
这个脚本提供了安全确认、错误处理和详细的执行反馈,适合在生产环境中使用。