< 自用文 备份 script :intar.sh> 使用 tar cvfz 命令打包成 .tar.gz 文件来备份多目标(目录,文件)

原因:

备份多文件夹,文件时打命令行容易出错,这个脚本诞生了。

使用方法:

1. 使用步骤:

将脚本intar.sh 链接到了 /usr/bin/intar,可以在终端的任何位置直接运行它。

  1. 运行脚本 : 在终端中直接输入 intar 并按回车键。

    复制代码
    intar
  2. 添加备份路径 : 脚本会提示输入需要备份的文件或文件夹的完整路径。每次输入一个路径后按回车。

    • 例如,输入 /var/log/nginx 来备份 Nginx 的日志目录。

    • 例如,输入 /root/.bashrc 来备份您的 bash 配置文件。

  3. 完成添加 : 当添加完所有需要备份的项目后,在一个新的提示行直接按回车键(不输入任何内容),脚本就会知道已完成添加。

  4. 自动备份 : 脚本会自动开始备份过程。它会创建一个以当前日期和时间命名的、唯一的 .tar.gz 压缩文件,并保存在固定目录中。

  5. 查看结果: 备份完成后,脚本会显示成功信息以及最终备份文件的大小。

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" ]; then
    echo "Error: DESTINATION_DIR is not set. Please configure it in the script." >&2
    mkdir -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; do
    read -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" ]; then
        break
    fi

    # Check if the file or folder actually exists.
    if [ ! -e "$user_input" ]; then
        echo "   ⚠️ Warning: '$user_input' does not exist. It will be skipped."
        continue
    fi

    # 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 ]; then
    echo "❌ No files or folders were added. Aborting backup." >&2
    exit 1
fi

echo "------------------------------------------------------------------"
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" ]; then
    echo ">> Destination directory not found. Creating it: ${DESTINATION_DIR}"
    mkdir -p "$DESTINATION_DIR"
    if [ $? -ne 0 ]; then
        echo "   Error: Could not create destination directory. Aborting." >&2
        exit 1
    fi
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 ]; then
    echo "✅ Backup created successfully!"
    echo "   Archive size: $(du -h "$BACKUP_FILE" | awk '{print $1}')"
else
    echo "❌ Error: Backup failed. Please check the output above for errors." >&2
    exit 1
fi

exit 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.2

clear

## ==> 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" ]; then
    echo "Error: DESTINATION_DIR is not set. Please configure it in the script." >&2
    mkdir -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 names
    if [ -d "$TASKS_DIR" ] && [ "$(ls -A "$TASKS_DIR"/*.task 2>/dev/null)" ]; then
        local count=1
        for task_file in "$TASKS_DIR"/*.task; do
            if [ -f "$task_file" ]; then
                local 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++))
            fi
        done
        return 0
    else
        echo "   No saved tasks found."
        return 1
    fi
}

# Function to get task name by number or name
get_task_name() {
    local input="$1"
    
    # If input is empty, return empty
    if [ -z "$input" ]; then
        echo ""
        return
    fi
    
    # Check if input is a number
    if [[ "$input" =~ ^[0-9]+$ ]]; then
        local index=$((input - 1))
        if [ $index -ge 0 ] && [ $index -lt ${#TASK_NAMES[@]} ]; then
            echo "${TASK_NAMES[$index]}"
        else
            echo ""
        fi
    else
        # Input is a task name, return as is
        echo "$input"
    fi
}

# Function to save current task
save_current_task() {
    if [ ${#SOURCES_TO_BACKUP[@]} -eq 0 ]; then
        echo "⚠️  No sources to save. Please add some paths first."
        return 1
    fi

    read -p "Enter a name for this task: " task_name
    
    # Remove invalid characters from task name
    task_name=$(echo "$task_name" | tr -cd '[:alnum:]._-')
    
    if [ -z "$task_name" ]; then
        echo "❌ Invalid task name. Task not saved."
        return 1
    fi

    local task_file="$TASKS_DIR/${task_name}.task"
    
    # Save the sources to the task file
    printf '%s\n' "${SOURCES_TO_BACKUP[@]}" > "$task_file"
    
    if [ $? -eq 0 ]; then
        echo "✅ Task '$task_name' saved successfully!"
        echo "   File: $task_file"
        echo "   Sources saved: ${#SOURCES_TO_BACKUP[@]}"
    else
        echo "❌ Error saving task '$task_name'."
        return 1
    fi
}

# Function to load a saved task
load_saved_task() {
    if ! list_saved_tasks; then
        return 1
    fi
    
    echo ""
    read -p "Enter the task number or name to load (or press Enter to cancel): " user_input
    
    if [ -z "$user_input" ]; then
        echo "Operation cancelled."
        return 1
    fi
    
    # Get the actual task name (handles both number and name input)
    local task_name=$(get_task_name "$user_input")
    
    if [ -z "$task_name" ]; then
        echo "❌ Invalid selection. Please enter a valid number or task name."
        return 1
    fi
    
    local task_file="$TASKS_DIR/${task_name}.task"
    
    if [ ! -f "$task_file" ]; then
        echo "❌ Task '$task_name' not found."
        return 1
    fi
    
    # Clear existing sources
    SOURCES_TO_BACKUP=()
    
    # Load sources from file
    while IFS= read -r line; do
        if [ -n "$line" ]; then
            if [ -e "$line" ]; then
                SOURCES_TO_BACKUP+=("$line")
                echo "   ✓ Loaded: '$line'"
            else
                echo "   ⚠️  Warning: '$line' no longer exists. Skipped."
            fi
        fi
    done < "$task_file"
    
    if [ ${#SOURCES_TO_BACKUP[@]} -gt 0 ]; then
        echo "✅ 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 0
    else
        echo "❌ No valid sources found in task '$task_name'."
        return 1
    fi
}

# Function to delete a saved task
delete_saved_task() {
    if ! list_saved_tasks; then
        return 1
    fi
    
    echo ""
    read -p "Enter the task name to delete (or press Enter to cancel): " task_name
    
    if [ -z "$task_name" ]; then
        echo "Operation cancelled."
        return 1
    fi
    
    local task_file="$TASKS_DIR/${task_name}.task"
    
    if [ ! -f "$task_file" ]; then
        echo "❌ Task '$task_name' not found."
        return 1
    fi
    
    read -p "Are you sure you want to delete task '$task_name'? (y/N): " confirm
    if [[ $confirm =~ ^[Yy]$ ]]; then
        rm "$task_file"
        if [ $? -eq 0 ]; then
            echo "✅ Task '$task_name' deleted successfully."
        else
            echo "❌ Error deleting task '$task_name'."
            return 1
        fi
    else
        echo "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 ]; then
        echo ">> No sources currently selected."
    else
        echo ">> Current sources to backup (${#SOURCES_TO_BACKUP[@]} items):"
        for i in "${!SOURCES_TO_BACKUP[@]}"; do
            echo "   [$((i+1))] ${SOURCES_TO_BACKUP[i]}"
        done
    fi
}

# 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; do
        read -p "Add path to backup (or press Enter to finish): " user_input

        if [ -z "$user_input" ]; then
            break
        fi

        if [ ! -e "$user_input" ]; then
            echo "   ⚠️  Warning: '$user_input' does not exist. It will be skipped."
            continue
        fi

        # Check if already exists in array
        local exists=false
        for source in "${SOURCES_TO_BACKUP[@]}"; do
            if [ "$source" = "$user_input" ]; then
                exists=true
                break
            fi
        done

        if [ "$exists" = true ]; then
            echo "   ⚠️  Warning: '$user_input' already added. Skipped."
            continue
        fi

        SOURCES_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; do
    show_menu
    read -p "Select an option (1-8): " choice
    
    case $choice in
        1)
            add_sources_manually
            ;;
        2)
            # Call the function and check its exit status
            if load_saved_task; then
                # If the task loaded successfully, ask the user what to do next
                echo ""
                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_choice

                if [[ "$post_load_choice" == "1" ]]; then
                    break # Exit the menu loop to proceed with the backup
                fi
                # Otherwise, do nothing and the loop will show the main menu again
            fi
            ;;
        3)
            list_saved_tasks
            ;;
        4)
            save_current_task
            ;;
        5)
            delete_saved_task
            ;;
        6)
            show_current_sources
            ;;
        7)
            # Check if we have sources to backup
            if [ ${#SOURCES_TO_BACKUP[@]} -eq 0 ]; then
                echo "❌ No sources selected. Please add some files/folders or load a saved task first."
                continue
            fi
            break  # Exit menu loop and proceed with backup
            ;;
        8)
            echo "Goodbye!"
            exit 0
            ;;
        *)
            echo "❌ Invalid option. Please select 1-8."
            ;;
    esac
    
    echo ""
    read -p "Press Enter to continue..."
done

echo "------------------------------------------------------------------"
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" ]; then
    BACKUP_FILENAME="${LOADED_TASK_NAME}-${TIMESTAMP}.tar.gz"
else
    BACKUP_FILENAME="backup-${TIMESTAMP}.tar.gz"
fi

BACKUP_FILE="${DESTINATION_DIR}/${BACKUP_FILENAME}"

# Check if the destination directory exists. If not, create it.
if [ ! -d "$DESTINATION_DIR" ]; then
    echo ">> Destination directory not found. Creating it: ${DESTINATION_DIR}"
    mkdir -p "$DESTINATION_DIR"
    if [ $? -ne 0 ]; then
        echo "   Error: Could not create destination directory. Aborting." >&2
        exit 1
    fi
fi

# Show final summary
echo ">> Backup Summary:"
echo "   Sources to backup: ${#SOURCES_TO_BACKUP[@]} items"
for i in "${!SOURCES_TO_BACKUP[@]}"; do
    echo "     [$((i+1))] ${SOURCES_TO_BACKUP[i]}"
done
echo "   Destination: ${BACKUP_FILE}"
echo ""

read -p "Proceed with backup? (Y/n): " confirm
if [[ $confirm =~ ^[Nn]$ ]]; then
    echo "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 ]; then
    echo "✅ Backup created successfully!"
    echo "   Archive: ${BACKUP_FILE}"
    echo "   Archive size: $(du -h "$BACKUP_FILE" | awk '{print $1}')"
    
    # Ask if user wants to save this task
    if [ ${#SOURCES_TO_BACKUP[@]} -gt 0 ]; then
        echo ""
        read -p "Would you like to save this backup configuration as a task? (y/N): " save_task
        if [[ $save_task =~ ^[Yy]$ ]]; then
            save_current_task
        fi
    fi
else
    echo "❌ Error: Backup failed. Please check the output above for errors." >&2
    exit 1
fi

exit 0
相关推荐
Warren982 小时前
复习MySQL
数据库·windows·tcp/ip·mysql·ubuntu·ssh·ansible
森G3 小时前
2六Ubuntu文件系统移植
linux·ubuntu
超级大福宝9 小时前
在 Linux 下修改百度网盘的缩放比例
linux·运维·服务器·ubuntu
饭来_11 小时前
ubuntu 中使用 lftp 命令行工具传输文件
运维·ubuntu·nas
不惑_12 小时前
如何在 CentOS、Ubuntu 和 Debian 云服务器上安装 Python 3
ubuntu·centos·debian
dalianwawatou12 小时前
U盘配置ubuntu服务器-安装docker-镜像安装gitlab并且能够使用
运维·服务器·ubuntu
MC皮蛋侠客12 小时前
Ubuntu禁用系统手势,阻止应用程序异常最小化
linux·运维·qt·ubuntu
颇有几分姿色12 小时前
Ubuntu 系统安装教程(二):系统安装
linux·运维·ubuntu
序属秋秋秋13 小时前
《Linux系统编程之入门基础》【Linux基础 理论+命令】(下)
linux·运维·服务器·学习·ubuntu·xshell·命令
小熊熊知识库13 小时前
Ubuntu下载以及安装详解以及应用安装
linux·运维·ubuntu