< 自用文 备份 script :intar.sh> 使用 tar cvfz 命令打包成 .tar.gz 文件来备份多目标(目录,文件)
原因:
备份多文件夹,文件时打命令行容易出错,这个脚本诞生了。
使用方法:
1. 使用步骤:
将脚本intar.sh 链接到了 /usr/bin/intar
,可以在终端的任何位置直接运行它。
运行脚本: 在终端中直接输入
intar
并按回车键。intar
添加备份路径: 脚本会提示输入需要备份的文件或文件夹的完整路径。每次输入一个路径后按回车。
例如,输入
/var/log/nginx
来备份 Nginx 的日志目录。例如,输入
/root/.bashrc
来备份您的 bash 配置文件。
完成添加: 当添加完所有需要备份的项目后,在一个新的提示行直接按回车键(不输入任何内容),脚本就会知道已完成添加。
自动备份: 脚本会自动开始备份过程。它会创建一个以当前日期和时间命名的、唯一的
.tar.gz
压缩文件,并保存在固定目录中。查看结果: 备份完成后,脚本会显示成功信息以及最终备份文件的大小。
2. 备份文件位置
所有通过 intar
脚本创建的备份文件都会被统一保存在 /root/backups/
目录下。
3. 使用示例
假设您想备份 Nginx 的配置文件 (/etc/nginx
) 和您自己的脚本目录 (/root/scripts
)。
# 1. 运行命令
root@usw:~# intar# 2. 脚本提示您输入路径
>> Please enter the full path for each file or folder you want to back up.
>> Press [ENTER] on an empty line when you are finished.
------------------------------------------------------------------# 3. 输入第一个路径
Add path to backup (or press Enter to finish): /etc/nginx+ Added: '/etc/nginx'# 4. 输入第二个路径
Add path to backup (or press Enter to finish): /root/scripts+ Added: '/root/scripts'# 5. 在空行直接按回车,表示添加完毕
Add path to backup (or press Enter to finish): ------------------------------------------------------------------
>> Finished adding sources. Preparing the backup...# 6. 脚本开始执行备份
>> Starting backup of 2 items...Destination: /root/backups/backup-2025-09-25_10-50-12.tar.gz
a /etc/nginx/
a /etc/nginx/nginx.conf
... (此处会显示所有被添加的文件) ...
a /root/scripts/
a /root/scripts/intar.sh# 7. 备份完成,显示结果
✅ Backup created successfully!Archive size: 1.2M
现在,可以前往 /root/backups
目录找到名为 backup-2025-09-25_10-50-12.tar.gz
的备份文件。
(以上内容用 GEMINI 生成)
4. script code 文章最后有最新更新
file name: /root/scripts/intar.sh
cat << 'EOF' > /root/scripts/intar.sh
#!/bin/bash
# Write by Dave on 25Sep.25
# An interactive Bash script to use the tar to back up multiple files and folders.## ==> START OF CONFIGURATION <== ### Set the destination directory for your backups.
# This is the only variable you need to configure in the script.
DESTINATION_DIR="/root/backups"if [ -z "$DESTINATION_DIR" ]; thenecho "Error: DESTINATION_DIR is not set. Please configure it in the script." >&2mkdir -p "$DESTINATION_DIR"echo "Created backup directory at $DESTINATION_DIR"exit 1
fi## ==> END OF CONFIGURATION <== ### --- SCRIPT LOGIC ---# 1. Ask for the items to back up.
echo ">> Please enter the full path for each file or folder you want to back up."
echo ">> Press [ENTER] on an empty line when you are finished."
echo "------------------------------------------------------------------"# Initialize an empty array to store the sources.
SOURCES_TO_BACKUP=()# Loop to read user input.
while true; doread -p "Add path to backup (or press Enter to finish): " user_input# If the user input is empty, break the loop.if [ -z "$user_input" ]; thenbreakfi# Check if the file or folder actually exists.if [ ! -e "$user_input" ]; thenecho " ⚠️ Warning: '$user_input' does not exist. It will be skipped."continuefi# Add the valid path to our array.SOURCES_TO_BACKUP+=("$user_input")echo " + Added: '$user_input'"
done# 2. Check if the user added any sources.
if [ ${#SOURCES_TO_BACKUP[@]} -eq 0 ]; thenecho "❌ No files or folders were added. Aborting backup." >&2exit 1
fiecho "------------------------------------------------------------------"
echo ">> Finished adding sources. Preparing the backup..."# 3. Get the current date and time to create a unique filename.
TIMESTAMP=$(date +"%Y-%m-%d_%H-%M-%S")
BACKUP_FILENAME="backup-${TIMESTAMP}.tar.gz"
BACKUP_FILE="${DESTINATION_DIR}/${BACKUP_FILENAME}"# 4. Check if the destination directory exists. If not, create it.
if [ ! -d "$DESTINATION_DIR" ]; thenecho ">> Destination directory not found. Creating it: ${DESTINATION_DIR}"mkdir -p "$DESTINATION_DIR"if [ $? -ne 0 ]; thenecho " Error: Could not create destination directory. Aborting." >&2exit 1fi
fi# 5. Create the compressed tar archive.
echo ">> Starting backup of ${#SOURCES_TO_BACKUP[@]} items..."
echo " Destination: ${BACKUP_FILE}"tar -czvf "$BACKUP_FILE" "${SOURCES_TO_BACKUP[@]}"# 6. Verify that the backup was created successfully.
if [ $? -eq 0 ]; thenecho "✅ Backup created successfully!"echo " Archive size: $(du -h "$BACKUP_FILE" | awk '{print $1}')"
elseecho "❌ Error: Backup failed. Please check the output above for errors." >&2exit 1
fiexit 0
EOF
chmod +x /root/scripts/intar.sh
ln -sf /root/scripts/intar.sh /usr/bin/intar
最后:
增加个任务记录与导入可能更方便。
添加了任务保存与导入功能
1. 演示
2. bash script:
#!/bin/bash
# Write by Dave on 25Sep.25 version 0.1
# Description: An interactive Bash script to use the tar to back up multiple files and folders.
# Updated: added task manager to save/load backup configurations version 0.2clear## ==> START OF CONFIGURATION <== ### Set the destination directory for your backups.
# This is the only variable you need to configure in the script.DESTINATION_DIR="/root/backups"# Directory to store saved tasks
TASKS_DIR="/root/backups/tasks"if [ -z "$DESTINATION_DIR" ]; thenecho "Error: DESTINATION_DIR is not set. Please configure it in the script." >&2mkdir -p "$DESTINATION_DIR"echo "Created backup directory at $DESTINATION_DIR"exit 1
fi# Create tasks directory if it doesn't exist
mkdir -p "$TASKS_DIR"## ==> END OF CONFIGURATION <== ### --- HELPER FUNCTIONS ---# Function to list saved tasks and return array of task names
list_saved_tasks() {echo ">> Available saved tasks:"TASK_NAMES=() # Global array to store task namesif [ -d "$TASKS_DIR" ] && [ "$(ls -A "$TASKS_DIR"/*.task 2>/dev/null)" ]; thenlocal count=1for task_file in "$TASKS_DIR"/*.task; doif [ -f "$task_file" ]; thenlocal task_name=$(basename "$task_file" .task)local task_count=$(wc -l < "$task_file" 2>/dev/null || echo "0")echo " [$count] $task_name ($task_count items)"TASK_NAMES+=("$task_name")((count++))fidonereturn 0elseecho " No saved tasks found."return 1fi
}# Function to get task name by number or name
get_task_name() {local input="$1"# If input is empty, return emptyif [ -z "$input" ]; thenecho ""returnfi# Check if input is a numberif [[ "$input" =~ ^[0-9]+$ ]]; thenlocal index=$((input - 1))if [ $index -ge 0 ] && [ $index -lt ${#TASK_NAMES[@]} ]; thenecho "${TASK_NAMES[$index]}"elseecho ""fielse# Input is a task name, return as isecho "$input"fi
}# Function to save current task
save_current_task() {if [ ${#SOURCES_TO_BACKUP[@]} -eq 0 ]; thenecho "⚠️ No sources to save. Please add some paths first."return 1firead -p "Enter a name for this task: " task_name# Remove invalid characters from task nametask_name=$(echo "$task_name" | tr -cd '[:alnum:]._-')if [ -z "$task_name" ]; thenecho "❌ Invalid task name. Task not saved."return 1filocal task_file="$TASKS_DIR/${task_name}.task"# Save the sources to the task fileprintf '%s\n' "${SOURCES_TO_BACKUP[@]}" > "$task_file"if [ $? -eq 0 ]; thenecho "✅ Task '$task_name' saved successfully!"echo " File: $task_file"echo " Sources saved: ${#SOURCES_TO_BACKUP[@]}"elseecho "❌ Error saving task '$task_name'."return 1fi
}# Function to load a saved task
load_saved_task() {if ! list_saved_tasks; thenreturn 1fiecho ""read -p "Enter the task number or name to load (or press Enter to cancel): " user_inputif [ -z "$user_input" ]; thenecho "Operation cancelled."return 1fi# Get the actual task name (handles both number and name input)local task_name=$(get_task_name "$user_input")if [ -z "$task_name" ]; thenecho "❌ Invalid selection. Please enter a valid number or task name."return 1filocal task_file="$TASKS_DIR/${task_name}.task"if [ ! -f "$task_file" ]; thenecho "❌ Task '$task_name' not found."return 1fi# Clear existing sourcesSOURCES_TO_BACKUP=()# Load sources from filewhile IFS= read -r line; doif [ -n "$line" ]; thenif [ -e "$line" ]; thenSOURCES_TO_BACKUP+=("$line")echo " ✓ Loaded: '$line'"elseecho " ⚠️ Warning: '$line' no longer exists. Skipped."fifidone < "$task_file"if [ ${#SOURCES_TO_BACKUP[@]} -gt 0 ]; thenecho "✅ Task '$task_name' loaded successfully!"echo " Valid sources loaded: ${#SOURCES_TO_BACKUP[@]}"## ==> MODIFIED SECTION: Store the loaded task name in a global variable <== ##LOADED_TASK_NAME="$task_name"return 0elseecho "❌ No valid sources found in task '$task_name'."return 1fi
}# Function to delete a saved task
delete_saved_task() {if ! list_saved_tasks; thenreturn 1fiecho ""read -p "Enter the task name to delete (or press Enter to cancel): " task_nameif [ -z "$task_name" ]; thenecho "Operation cancelled."return 1filocal task_file="$TASKS_DIR/${task_name}.task"if [ ! -f "$task_file" ]; thenecho "❌ Task '$task_name' not found."return 1firead -p "Are you sure you want to delete task '$task_name'? (y/N): " confirmif [[ $confirm =~ ^[Yy]$ ]]; thenrm "$task_file"if [ $? -eq 0 ]; thenecho "✅ Task '$task_name' deleted successfully."elseecho "❌ Error deleting task '$task_name'."return 1fielseecho "Operation cancelled."fi
}# Function to show main menu
show_menu() {echo ""echo "==========================================="echo " Interactive Backup Script Menu"echo "==========================================="echo "1. Add files/folders manually"echo "2. Load saved task"echo "3. List saved tasks"echo "4. Save current task"echo "5. Delete saved task"echo "6. Show current sources"echo "7. Start backup"echo "8. Exit"echo "==========================================="
}# Function to show current sources
show_current_sources() {if [ ${#SOURCES_TO_BACKUP[@]} -eq 0 ]; thenecho ">> No sources currently selected."elseecho ">> Current sources to backup (${#SOURCES_TO_BACKUP[@]} items):"for i in "${!SOURCES_TO_BACKUP[@]}"; doecho " [$((i+1))] ${SOURCES_TO_BACKUP[i]}"donefi
}# Function to add sources manually
add_sources_manually() {echo ">> Please enter the full path for each file or folder you want to add."echo ">> Press [ENTER] on an empty line when you are finished."echo "------------------------------------------------------------------"while true; doread -p "Add path to backup (or press Enter to finish): " user_inputif [ -z "$user_input" ]; thenbreakfiif [ ! -e "$user_input" ]; thenecho " ⚠️ Warning: '$user_input' does not exist. It will be skipped."continuefi# Check if already exists in arraylocal exists=falsefor source in "${SOURCES_TO_BACKUP[@]}"; doif [ "$source" = "$user_input" ]; thenexists=truebreakfidoneif [ "$exists" = true ]; thenecho " ⚠️ Warning: '$user_input' already added. Skipped."continuefiSOURCES_TO_BACKUP+=("$user_input")echo " + Added: '$user_input'"done
}# --- MAIN SCRIPT LOGIC ---## ==> NEW SECTION: Initialize variable to hold the loaded task name <== ##
SOURCES_TO_BACKUP=()
LOADED_TASK_NAME=""echo "======================================================"
echo " Interactive Backup Script with Task Manager"
echo "======================================================"# Main menu loop
while true; doshow_menuread -p "Select an option (1-8): " choicecase $choice in1)add_sources_manually;;2)# Call the function and check its exit statusif load_saved_task; then# If the task loaded successfully, ask the user what to do nextecho ""echo "What would you like to do next?"echo " 1. Start backup immediately"echo " 2. Return to menu (to modify sources)"read -p "Select an option (1-2): " post_load_choiceif [[ "$post_load_choice" == "1" ]]; thenbreak # Exit the menu loop to proceed with the backupfi# Otherwise, do nothing and the loop will show the main menu againfi;;3)list_saved_tasks;;4)save_current_task;;5)delete_saved_task;;6)show_current_sources;;7)# Check if we have sources to backupif [ ${#SOURCES_TO_BACKUP[@]} -eq 0 ]; thenecho "❌ No sources selected. Please add some files/folders or load a saved task first."continuefibreak # Exit menu loop and proceed with backup;;8)echo "Goodbye!"exit 0;;*)echo "❌ Invalid option. Please select 1-8.";;esacecho ""read -p "Press Enter to continue..."
doneecho "------------------------------------------------------------------"
echo ">> Starting backup process..."# Get the current date and time to create a unique filename
TIMESTAMP=$(date +"%Y-%m-%d_%H-%M-%S")## ==> MODIFIED SECTION: Use task name in the filename if it's set <== ##
if [ -n "$LOADED_TASK_NAME" ]; thenBACKUP_FILENAME="${LOADED_TASK_NAME}-${TIMESTAMP}.tar.gz"
elseBACKUP_FILENAME="backup-${TIMESTAMP}.tar.gz"
fiBACKUP_FILE="${DESTINATION_DIR}/${BACKUP_FILENAME}"# Check if the destination directory exists. If not, create it.
if [ ! -d "$DESTINATION_DIR" ]; thenecho ">> Destination directory not found. Creating it: ${DESTINATION_DIR}"mkdir -p "$DESTINATION_DIR"if [ $? -ne 0 ]; thenecho " Error: Could not create destination directory. Aborting." >&2exit 1fi
fi# Show final summary
echo ">> Backup Summary:"
echo " Sources to backup: ${#SOURCES_TO_BACKUP[@]} items"
for i in "${!SOURCES_TO_BACKUP[@]}"; doecho " [$((i+1))] ${SOURCES_TO_BACKUP[i]}"
done
echo " Destination: ${BACKUP_FILE}"
echo ""read -p "Proceed with backup? (Y/n): " confirm
if [[ $confirm =~ ^[Nn]$ ]]; thenecho "Backup cancelled."exit 0
fi# Create the compressed tar archive
echo ">> Starting backup of ${#SOURCES_TO_BACKUP[@]} items..."tar -czvf "$BACKUP_FILE" "${SOURCES_TO_BACKUP[@]}"# Verify that the backup was created successfully
if [ $? -eq 0 ]; thenecho "✅ Backup created successfully!"echo " Archive: ${BACKUP_FILE}"echo " Archive size: $(du -h "$BACKUP_FILE" | awk '{print $1}')"# Ask if user wants to save this taskif [ ${#SOURCES_TO_BACKUP[@]} -gt 0 ]; thenecho ""read -p "Would you like to save this backup configuration as a task? (y/N): " save_taskif [[ $save_task =~ ^[Yy]$ ]]; thensave_current_taskfifi
elseecho "❌ Error: Backup failed. Please check the output above for errors." >&2exit 1
fiexit 0