写了个目录打包备份的linux shell脚本,还是比较满意的.
可自定义需打包的内容格式。
- 仅打包加密含有自定义目标格式文件的文件夹;
- 当遍历目录时,发现同级目录同时含有文件夹与目标格式文件时,不会执行打包,而是提醒用户先处理好文件结构;
encryptDeepest.sh
#!/bin/sh
set -eu
# 用途: 对当前目录下的所有目标格式文件夹进行打包加密
# ----------------- 配置项 -----------------
VIDEO_EXTS="mp4 mkv avi mov flv wmv jpg jpeg"
ENCRYPT_PASSWORD="1234"
CIPHER_ALGO="AES"
OUTPUT_DIR="encrypted_files" # 自定义输出目录
# ------------------------------------------
# 显示冲突目录和文件路径
show_conflict_paths() {
dir="$1"
echo "违规目录:$dir"
echo "包含的视频文件和子目录:"
# 显示目录中的视频文件
find "$dir" -maxdepth 1 -type f -iname "*.${VIDEO_EXTS}" | while read -r file; do
echo " - 视频文件: $file"
done
# 显示目录中的子目录
find "$dir" -maxdepth 1 -type d ! -path "$dir" | while read -r subdir; do
echo " - 子目录: $subdir"
done
}
# 主流程
echo "████████████████████████████████████████████"
echo "█ 开始目录合规检查(严格模式)"
echo "████████████████████████████████████████████"
# 确保输出目录存在
if [ ! -d "$OUTPUT_DIR" ]; then
echo "输出目录 $OUTPUT_DIR 不存在,正在创建..."
mkdir -p "$OUTPUT_DIR"
fi
# 记录开始时间
start_time=$(date +%s)
# 阶段1:严格冲突检测
CONFLICT_FOUND=0
TMP_CONFLICT_FILE=$(mktemp)
# 获取脚本所在的目录
SCRIPT_DIR=$(dirname "$0")
# 遍历所有目录,包括脚本所在的同级目录
find . -type d | while read -r dir; do
# 检测视频文件存在性
has_video=0
for ext in ${VIDEO_EXTS}; do
if find "$dir" -maxdepth 1 -type f -iname "*.${ext}" | grep -q .; then
has_video=1
break
fi
done
# 检测子目录存在性
subdir_count=$(find "$dir" -maxdepth 1 -type d ! -path "$dir" | wc -l)
if [ "$has_video" -eq 1 ] && [ "$subdir_count" -gt 0 ]; then
echo "$dir" >> "$TMP_CONFLICT_FILE"
fi
done
if [ -s "$TMP_CONFLICT_FILE" ]; then
CONFLICT_FOUND=1
echo -e "\n❌ 发现以下违规目录:"
while read -r dir; do
show_conflict_paths "$dir"
done < "$TMP_CONFLICT_FILE"
rm -f "$TMP_CONFLICT_FILE"
echo -e "\n████████████████████████████████████████████"
echo "错误:检测到视频文件与子目录共存的目录"
echo "请处理冲突后重新运行脚本"
exit 1
fi
# 阶段2:加密处理(仅无冲突时执行)
echo "████████████████████████████████████████████"
echo "█ 开始加密处理"
echo "████████████████████████████████████████████"
tmpfile=$(mktemp)
find . -type d | while read -r dir; do
for ext in ${VIDEO_EXTS}; do
if find "$dir" -maxdepth 1 -type f -iname "*.${ext}" | grep -q .; then
echo "$(echo "$dir" | tr -cd '/' | wc -c) $dir"
break
fi
done
done | sort -nr | cut -d' ' -f2- > "$tmpfile"
final_dirs=""
while IFS= read -r dir; do
is_parent=0
for processed in ${final_dirs}; do
case "${processed}" in
"$dir"/*) is_parent=1; break ;;
esac
done
[ "$is_parent" -eq 0 ] && final_dirs="${final_dirs} ${dir}"
done < "$tmpfile"
count=1
total=$(echo "$final_dirs" | wc -w)
for dir in ${final_dirs}; do
folder_name=$(basename "$dir")
output_file="${OUTPUT_DIR}/${folder_name}.tar.gpg" # 将输出文件路径改为自定义目录
echo -e "\n▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄"
echo "处理进度:$count/$total"
echo "源目录:$dir"
tar -cf - -C "$dir" . | \
gpg --batch --yes --cipher-algo "${CIPHER_ALGO}" \
--passphrase "${ENCRYPT_PASSWORD}" -c -o "${output_file}"
count=$((count + 1))
done
rm -f "$tmpfile"
# 记录结束时间并计算耗时
end_time=$(date +%s)
elapsed_time=$((end_time - start_time))
# 将耗时转换为时:分:秒格式
format_time() {
local total_seconds=$1
local hours=$((total_seconds / 3600))
local minutes=$(( (total_seconds % 3600) / 60 ))
local seconds=$((total_seconds % 60))
printf '%02d:%02d:%02d' "$hours" "$minutes" "$seconds"
}
formatted_time=$(format_time "$elapsed_time")
echo -e "\n████████████████████████████████████████████"
echo "加密完成!生成文件:"
ls -lh "${OUTPUT_DIR}"/*.tar.gpg 2>/dev/null || echo "未生成加密文件"
echo "执行耗时:$formatted_time"
echo "████████████████████████████████████████████"
decryptNextract.sh
#!/bin/sh
set -eu
# ----------------- 配置项 -----------------
OUTPUT_DIR="decrypted_files"
ENCRYPT_PASSWORD="1234"
# ------------------------------------------
# 确保输出目录存在
mkdir -p "$OUTPUT_DIR"
# 统计成功和失败的文件数量
success_count=0
failure_count=0
# 记录脚本开始时间(秒)
start_time=$(date +%s)
# 主流程
echo "████████████████████████████████████████████"
echo "█ 开始批量解密解包"
echo "████████████████████████████████████████████"
# 遍历当前目录下的所有 .tar.gpg 文件
find . -maxdepth 1 -type f -name "*.tar.gpg" | while read -r file; do
filename=$(basename "$file")
# 提取文件名(去掉 .tar.gpg 后缀)
output_subdir="${filename%.tar.gpg}"
# 创建子文件夹
mkdir -p "$OUTPUT_DIR/$output_subdir"
echo -e "\n▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄"
echo "处理文件:$filename"
echo "输出目录:$OUTPUT_DIR/$output_subdir"
# 记录文件处理开始时间(秒)
file_start_time=$(date +%s)
# 解密并解压
if gpg --batch --passphrase "$ENCRYPT_PASSWORD" -d "$file" | tar xvf - -C "$OUTPUT_DIR/$output_subdir" >/dev/null 2>&1; then
# 记录文件处理结束时间(秒)
file_end_time=$(date +%s)
file_duration=$((file_end_time - file_start_time))
# 转换为时:分:秒格式
file_time=$(printf '%02d:%02d:%02d' \
$((file_duration / 3600)) \
$(( (file_duration % 3600) / 60 )) \
$((file_duration % 60)))
echo "成功解密解压:$filename"
echo "耗时:$file_time"
success_count=$((success_count + 1))
else
# 记录文件处理结束时间(秒)
file_end_time=$(date +%s)
file_duration=$((file_end_time - file_start_time))
# 转换为时:分:秒格式
file_time=$(printf '%02d:%02d:%02d' \
$((file_duration / 3600)) \
$(( (file_duration % 3600) / 60 )) \
$((file_duration % 60)))
echo "解密解压失败:$filename"
echo "耗时:$file_time"
failure_count=$((failure_count + 1))
fi
# 调试信息
echo "DEBUG: Success count: $success_count"
echo "DEBUG: Failure count: $failure_count"
done | {
# 读取循环中的输出并更新计数
while read -r line; do
if echo "$line" | grep -q "成功解密解压"; then
success_count=$((success_count + 1))
elif echo "$line" | grep -q "解密解压失败"; then
failure_count=$((failure_count + 1))
fi
done
# 记录脚本结束时间(秒)
end_time=$(date +%s)
total_duration=$((end_time - start_time))
# 转换为时:分:秒格式
total_time=$(printf '%02d:%02d:%02d' \
$((total_duration / 3600)) \
$(( (total_duration % 3600) / 60 )) \
$((total_duration % 60)))
# 总结
echo -e "\n████████████████████████████████████████████"
echo "批量解密解包完成!"
echo "成功解密解压:$success_count 个文件"
echo "失败解密解压:$failure_count 个文件"
echo "总耗时:$total_time"
echo "解密文件已输出到:$OUTPUT_DIR"
echo "████████████████████████████████████████████"
}