银河麒麟桌面操作系统-backuptools-重装前备份重装后还原部分配置

#!/bin/bash
###
 # @Author: huangjinbang
 # @AuthorEmail: huangjinbang1996@163.com
 # @Date: 2024-12-10 19:12:22
 # @LastEditors: huangjinbang 
 # @LastEditorsEmail: huangjinbang1996@163.com
 # @LastEditTime: 2025-01-02 16:05:20
 # @FilePath: backuptools-重装前备份重装后还原部分配置.sh
 # @Description: 
 # Copyright (c) 2024 by ${git_name} email: ${git_email}, All Rights Reserved.
 # 可备份还原 网络 激活  
 # 使用: 
 #      backuptools-重装前备份重装后还原部分配置.sh -b        # 备份
 #      backuptools-重装前备份重装后还原部分配置.sh -r        # 还原
### 

#################################################################
#  default默认设置脚本环境设置,可以引入下
set +a
export LANG=en_US.utf8
export LANGUAGE='en_US:en'
curPath=$(readlink -f "$(dirname "$0")")    # 获取文件所在文件夹绝对路径(或当鼠标点击文件运行的时候)
#记录本脚本名
curScript=$0

echo "Current user: $USER"
echo "User using whoami: $(whoami)"
echo "UID of current user: $UID"
echo "User running this script: $(ps -o user= -p $$)"
echo 所有参数:$@   当前进程:$$ 当前路径:$curPath 
# if [ ".$1" = ".--help" ]; then
#     echo '  -v, --version   display version information'
#     echo '  -h, --help      display usage help page (this one)'
#     echo '  -d, --debug     display shell trace information'
#     exit 0
# fi
# 开启调试模式
# if [ ".$1" = ".-d" ] || [ ".$1" = ".--debug" ]; then
if [ ".$1" = ".--debug" ]; then
    shift
    # 设置 PS4 显示行号,$LINENO 表示当前行号
    export PS4='+${LINENO}: '
    set -x
fi


# # ###bash内置命令 type getopts
# optstring是一个字符串,包含一个可以为getopts命令识别的选项名称列表。我们让s表示一个字符,其中语法为:
# 选项内容	说明
#       :	optsring如果以:开头,表示是静默模式,忽略一般错误消息
#       s	有效选项并且后面不带参数值
#       s:	有效选项并且后面必须带参数值
# while getopts 'r: h d' OPT;do
#     case "${OPT}" in 
#         "r") echo rrrr ;;
#         "d") echo dddd ;;
#         "h") echo "here is help";help ;;
#         "?") echo "here is ?";help ;;
#     esac
# done
#################################################################


#################################################################

# 路径为绝对路径最好,或与本文件相对路径
# CONFIG_FILE="/etc/samba/smb.conf"
CONFIG_FILE="$HOME/.cache/uksc/kylin-software-center.conf"
declare -a sections_save
declare -A section_key_value

function read_ini_file {
    local config_file="$1"
    local current_section=""
    while read -r line; do
        line="${line#"${line%%[![:space:]]*}"}" # 去除行首空白字符
        # line="${line%"${line##*[![:space:]]}"}" # 去除行末空白字符
        if [[ "$line" =~ ^[[:space:]]*\;.*$ ]]; then
            # 行非空字符以注释符号;开头,忽略
            continue
        elif [[ "$line" =~ ^[[:space:]]*\#.*$ ]]; then
            # 行非空字符以注释符号#开头,忽略
            continue
        elif [[ "$line" =~ ^\[.*\]$ ]]; then
            # 节点名称
            current_section="${line#\[}"
            current_section="${current_section%*\]}"
            sections_save+=("'${current_section}'")
        elif [[ "$line" =~ [[[:space:]]*[[:graph:]]*[[:space:]]*]*\={1}[[:space:]]*.*$ ]]; then
            # 键值对
            local key="${line%%=*}"
            key="${key#"${key%%[![:space:]]*}"}" # 去除键名左侧空白字符
            key="${key%"${key##*[![:space:]]}"}" # 去除键名右侧空白字符
            local value="${line#*=}"
            value="${value#"${value%%[![:space:]]*}"}" # 去除键值左侧空白字符
            value="${value%"${value##*[![:space:]]}"}" # 去除键值右侧空白字符
            # echo "'${current_section}'_'${key}'='${value}'"
            section_key_value["'${current_section}'_'${key}'"]="'${value}'"
        fi
    done < "$config_file"
    

}

# 函数:add_section_value
# 功能:向配置文件中的指定节添加或更新键值对
# 参数:
#   $1: 配置文件路径
#   $2: 节名称
#   $3: 键名称
#   $4: 键值
# 描述:
#   该函数首先读取配置文件的每一行,检查是否存在指定的节和键。
#   如果指定的节存在但键不存在,则在该节下添加新的键值对。
#   如果指定的节不存在,则创建该节并添加键值对。
# 注意事项:
#   该函数会直接修改传入的配置文件,建议在调用前备份重要文件。
function add_section_value {
    local config_file="$1"
    local section_name="$2"
    local key_name="$3"
    local value="$4"
    local current_section=""
    local found_section=false
    local found_key=false
    while read -r line; do
        line="${line#"${line%%[![:space:]]*}"}" # 去除行首空白字符
        # line="${line%"${line##*[![:space:]]}"}" # 去除行末空白字符
        if [[ "$line" =~ ^\;.*$ ]]; then
            # 行非空字符以注释符号;开头,忽略
            continue
        elif [[ "$line" =~ ^[[:space:]]*\#.*$ ]]; then
            # 行非空字符以注释符号#开头,忽略
            continue
        elif [[ "$line" =~ ^\[.*\]$ ]]; then
            # 节点名称
            current_section="${line#\[}"
            current_section="${current_section%*\]}"
            if [[ "${current_section}" == "${section_name}" ]]; then
                found_section=true
            fi
        elif [[ "$line" =~ [[[:space:]]*[[:graph:]]*[[:space:]]*]*\={1}[[:space:]]*.*$ ]]; then
            # 键值对
            local key="${line%%=*}"
            key="${key#"${key%%[![:space:]]*}"}" # 去除键名左侧空白字符
            key="${key%"${key##*[![:space:]]}"}" # 去除键名右侧空白字符
            local value_="${value}"
            value_="${value_#"${value_%%*[![:space:]]}"}" # 去除键值右侧空白字符
            value_="${value_%"${value_##*[![:space:]]}"}" # 去除键值左侧空白字符
            if [[ "${current_section}" == "${section_name}" && "${key}" == "${key_name}" ]]; then
                # 节点存在,键值对存在
                found_key=true
            fi
        fi
    done < "$config_file"
    # 如果该节点存在且该键不存在,则在该节点下添加键值对
    if [[ "${found_key}" == false ]]; then
        sed -i "/^[[:space:]]*\[${section_name}\]/a ${key_name}=${value}" "${config_file}"
    fi
    # 如果该节点不存在,则添加节点
    if [[ "${found_section}" == false ]]; then
        echo -e "\n[${section_name}]" >> "${config_file}"
        echo -e "${key_name} = ${value}" >> "${config_file}"
    fi
}

# 定义函数,用于删除指定部分中的指定键值对  bug1
function delete_ini_key {
    local section_name=$1
    local key_name=$2
    local ini_file=$3
    # 在指定的节中查找并删除键值对;注意:匹配内容从[] 到[,下一段从]开始;若有相同内容[s1]..[s1]..[s1],则内容[s1]..[s1]分割..分割[s1],则1和3能被处理,2不被处理
    sed -i "/^[[:space:]]*\[${section_name}\][[:space:]]*$/,/^[[:space:]]*\[.*\][[:space:]]*/ {/^[[:space:]]*${key_name}[[:space:]]*=/d;}" "$ini_file"
}

# 定义函数,用于删除指定节点    bug1
function delete_section {
    local section_name=$1
    local ini_file=$2
    # 在指定的节中查找并删除键值对;注意:匹配内容从[] 到[,下一段从]开始;若有相同内容[s1]..[s1]..[s1],则内容[s1]..[s1]分割..分割[s1],则1和3能被处理,2不被处理
    sed -i "/^[[:space:]]*\[${section_name}\][[:space:]]*$/,/^[[:space:]]*\[.*\][[:space:]]*/ {/.*=/d;}" "$ini_file"
    sed -i "/^[[:space:]]*\[${section_name}\][[:space:]]*/d" "$ini_file"
}

# 定义函数,用于更改指定部分中的指定键对应的键值 bug1
function change_ini_value {
    local section_name=$1
    local key_name=$2
    local new_value=$3
    local ini_file=$4
    # 查找指定节中指定的键,并将其对应的值修改为新值;;注意:匹配内容从[] 到[,下一段从]开始;若有相同内容[s1]..[s1]..[s1],则内容[s1]..[s1]分割..分割[s1],则1和3能被处理,2不被处理
    sed -i "/^[[:space:]]*\[${section_name}\][[:space:]]*$/,/^[[:space:]]*\[.*\][[:space:]]*/ {s/^\([[:space:]]*${key_name}[[:space:]]*=[[:space:]]*\).*/\1$new_value/}" "$ini_file"
}


# ##chatGPT 
function get_config_value {
    local config_file="$1"
    local section_name="$2"
    local key_name="$3"
    local current_section=""
    while read -r line; do
        line="${line#"${line%%[![:space:]]*}"}" # 去除行首空白字符
        if [[ "$line" =~ ^[[:space:]]*[\;\#] ]]; then
            # 行以注释符号;或#开头,忽略
            continue
        elif [[ "$line" =~ ^\[.*\]$ ]]; then
            # 节点名称
            current_section="${line#\[}"
            current_section="${current_section%\]}"
        elif [[ "$line" =~ ^[[:space:]]*${key_name}[[:space:]]*=[[:space:]]*\"(.*)\"[[:space:]]* ]]; then
            # 双引号包含的值
            if [[ "${current_section}" == "${section_name}" ]]; then
                echo "${BASH_REMATCH[1]}"
                return 0
            fi
        elif [[ "$line" =~ ^[[:space:]]*${key_name}[[:space:]]*=[[:space:]]*\'(.*)\'[[:space:]]* ]]; then
            # 单引号包含的值
            if [[ "${current_section}" == "${section_name}" ]]; then
                echo "${BASH_REMATCH[1]}"
                return 0
            fi
        elif [[ "$line" =~ ^[[:space:]]*${key_name}[[:space:]]*=[[:space:]]*(.*) ]]; then
            # 普通键值对的值
            if [[ "${current_section}" == "${section_name}" ]]; then
                echo "${BASH_REMATCH[1]}"
                return 0
            fi
        fi
    done < "$config_file"
}

################################################使用例子
# # 读取配置文件
read_ini_file "$CONFIG_FILE"

# # 查询指定节点的指定配置项 ok
# value=$(get_config_value "$CONFIG_FILE" "s1" "s")
# echo "s1.s=${value}"

# update- 增 删 改

# 增 添加节点,键值对 ok
# add_section_value "$CONFIG_FILE" "s1" "1" "4545"
# add_section_value "$CONFIG_FILE" "s1" "2" "4545"
# add_section_value "$CONFIG_FILE" "s1" "3" "4545"
# add_section_value "$CONFIG_FILE" "s3" "1" "4545"
# add_section_value "$CONFIG_FILE" "s3" "2" "1235"
# add_section_value "$CONFIG_FILE" "s3" "3" "453345"
# add_section_value "$CONFIG_FILE" "s2" "1" "5234"
# add_section_value "$CONFIG_FILE" "s2" "2" "5234"
# add_section_value "$CONFIG_FILE" "s2" "3" "5234"
# add_section_value "$CONFIG_FILE" "faf" "s1" "545646"
# add_section_value "$CONFIG_FILE" "s3" "s2" "4564"
# add_section_value "$CONFIG_FILE" "s6" "s" "45612414"



# # 调用函数删除指定section部分中的指定option键value值对 ok
# delete_ini_key "s3" "s2" "$CONFIG_FILE"
# delete_ini_key "s3" "2" "$CONFIG_FILE"

# # 调用函数删除指定section节点 
# delete_section "s1" "$CONFIG_FILE"  

# # 改
# change_ini_value "s3" "s2" "5251" "$CONFIG_FILE"

## section  key value关联
# echo ${sections_save[@]}
# echo ${!sections_save[@]}
# echo ${#sections_save[@]}

# ## 查看关联数组内数据,获取引索
# for index in "${!section_key_value[@]}";
# do
#     # echo $index
#     # echo "${index}=${section_key_value["${index}"]}"
#     echo "${index}" | grep "${sections_save[0]}"
# done

######################################################  例子2
# 银河麒麟桌面操作系统V10-关闭软件商店更新,当前用户权限执行则关闭当前用户的

# # # 读取配置文件
# read_ini_file "$CONFIG_FILE"

# # 查 V10 V10-SP1 自动更新软件
# value=$(get_config_value "$CONFIG_FILE" "option-settings" "software-auto-update" )
# echo "option-settings.software-auto-update=${value}"
# # 查 V10 自动更新软件商店 
# value=$(get_config_value "$CONFIG_FILE" "option-settings" "software-auto_start" )
# echo "option-settings.auto_start=${value}"
# # 查 V10-SP1 自动更新软件商店 
# value=$(get_config_value "$CONFIG_FILE" "option-settings" "auto_start" )
# echo "option-settings.auto_start=${value}"


# # 改 V10 V10-SP1 自动更新软件
# change_ini_value "option-settings" "software-auto-update" "false" "$CONFIG_FILE"
# # 改 V10 自动更新软件商店
# change_ini_value "option-settings" "software-auto_start" "false" "$CONFIG_FILE"
# # 改 V10-SP1 自动更新软件商店
# change_ini_value "option-settings" "auto_start" "false" "$CONFIG_FILE"


# # 查 V10 V10-SP1 自动更新软件
# value=$(get_config_value "$CONFIG_FILE" "option-settings" "software-auto-update" )
# echo "option-settings.software-auto-update=${value}"
# # 查 V10 自动更新软件商店 
# value=$(get_config_value "$CONFIG_FILE" "option-settings" "software-auto_start" )
# echo "option-settings.auto_start=${value}"
# # 查 V10-SP1 自动更新软件商店
# value=$(get_config_value "$CONFIG_FILE" "option-settings" "auto_start" )
# echo "option-settings.auto_start=${value}"

# echo "已修改完毕 软件商店程序显示不会热更新,请关闭后再打开"


######################################################

 #      backuptools-重装前备份重装后还原部分配置.sh -b        # 备份
 #      backuptools-重装前备份重装后还原部分配置.sh -r        # 还原

if [ ".$1" = ".-b" ]; then
    shift
    echo pwd:`pwd`
    sudo chmod 777 -R ./backupdir
    rm -rf ./backupdir
    mkdir -p ./backupdir/system-connections/
    # 对于使用NetworkManager的服务器,你可能还需要备份NetworkManager的配置。

    # printer
    sudo cp -p --parents /etc/cups/printers.conf "$curPath"/backupdir
    sudo cp -p --parents /etc/cups/printers.conf.O "$curPath"/backupdir
    sudo cp -p --parents /etc/cups/subscriptions.conf "$curPath"/backupdir
    sudo cp -p --parents /etc/cups/subscriptions.conf.O "$curPath"/backupdir

    # kylin
    cat /etc/os-release  | grep -qi  kylin;
    if [ $? -eq 0 ]  ;then
        sudo cp -r /etc/NetworkManager/system-connections ./backupdir
        sudo cp -p --parents /etc/.kyinfo  "$curPath"/backupdir
        sudo cp -p --parents /etc/LICENSE  "$curPath"/backupdir
        sudo cp -p --parents /etc/.kyactivation  "$curPath"/backupdir
        # sudo cp -p /etc/.kyactions  "$curPath"/backupdir
    fi
    
fi


if [ ".$1" = ".-r" ]; then
    shift
    echo pwd:`pwd`
    # 对于使用NetworkManager的服务。
    sudo cp -r ./backupdir/system-connections/*  /etc/NetworkManager/system-connections/ 
    sudo systemctl restart NetworkManager

    # printer
    sudo cp  ./backupdir/etc/cups/printers.conf /etc/cups/printers.conf
    sudo cp  ./backupdir/etc/cups/printers.conf.O /etc/cups/printers.conf.O
    sudo cp  ./backupdir/etc/cups/subscriptions.conf /etc/cups/subscriptions.conf
    sudo cp  ./backupdir/etc/cups/subscriptions.conf.O /etc/cups/subscriptions.conf.O
    sudo systemctl restart cups
    
    cat /etc/os-release  | grep -qi  kylin;
    if [ $? -eq 0 ]  ;then
        # V10使用,激活部分还原
        kyinfo_key=$(sudo bash -c "$(declare -f get_config_value);get_config_value \"$curPath\"/backupdir/etc/.kyinfo \"servicekey\" \"key\" ")
        echo "get key: $kyinfo_key"
        if [ ! -z "$kyinfo_key" ];then
            sudo bash -c "$(declare -f change_ini_value);change_ini_value \"servicekey\" \"key\" \"$kyinfo_key\" /etc/.kyinfo"
            # sudo bash -c "$(declare -f change_ini_value);change_ini_value "servicekey" "key" '$kyinfo_key' /etc/.kyinfo"
            sudo cp "$curPath"/backupdir/etc/LICENSE /etc/LICENSE
            sudo cp "$curPath"/backupdir/etc/.kyactivation  /etc/.kyactivation
        fi
    fi
fi


posted @ 2025-01-02 16:15  ThreeFlower  阅读(381)  评论(0)    收藏  举报