V$BACKUP_FILES

V$BACKUP_FILES可展示所有RMAN备份(包括镜像副本和备份集)及归档日志的信息,该视图模拟了特定RMAN命令,且使用它需要通过特定过程设置数据库。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

V$BACKUP_FILES

V$BACKUP_FILES displays information about all RMAN backups (both image copies and backup sets) and archived logs.

This view simulates the LIST BACKUP and LIST COPY RMAN commands. This view requires that the database be set using the DBMS_RCVMAN.SETDATABASE procedure.

ColumnDatatypeDescription
PKEYNUMBERPrimary key for the backup
BACKUP_TYPEVARCHAR2(32)Type of the backup:
  • BACKUP SET

  • COPY

  • PROXY COPY

FILE_TYPEVARCHAR2(32)Type of the file:
  • DATAFILE

  • CONTROLFILE

  • SPFILE

  • REDO LOG

  • COPY (for an image copy backup)

  • PIECE (for a backup piece)

KEEPVARCHAR2(3)Indicates whether the backup has a retention policy different from the value for CONFIGURE RETENTION POLICY (YES) or not (NO)
KEEP_UNTILDATEIf the KEEP UNTIL TIME clause of the BACKUP command was specified, then this column shows the date after which the backup becomes obsolete. If the column is null and KEEP_OPTIONS is not null, the backup never becomes obsolete.
KEEP_OPTIONSVARCHAR2(13)KEEP options for the backup:
  • LOGS - RMAN keeps the logs needed to recover the backup

  • NOLOGS - RMAN does not keep the logs needed to recover the backup

If this column is null, then the backup has no KEEP options and will be made obsolete based on the retention policy.

STATUSVARCHAR2(16)Status of the backup:
  • AVAILABLE

  • UNAVAILABLE

  • EXPIRED

  • OTHER

FNAMEVARCHAR2(1024)Name of the file
TAGVARCHAR2(32)Tag of the piece, copy, or proxy copy
MEDIAVARCHAR2(80)Media ID of the piece or proxy copy
RECIDNUMBERRecid of the record in the controlfile
STAMPNUMBERStamp of the record in the controlfile
DEVICE_TYPEVARCHAR2(255)Type of media device that stores the backup
BLOCK_SIZENUMBERBlock size for the backup (in bytes)
COMPLETION_TIMEDATETime when the backup completed
COMPRESSEDVARCHAR2(3)Indicates whether the backup piece is compressed (YES) or not (NO); valid only if FILE_TYPE is PIECE. Image copies cannot be compressed.
OBSOLETEVARCHAR2(3)Indicates whether the backup piece or copy is obsolete (YES) or not (NO); valid only if FILE_TYPE is PIECE or COPY
BYTESNUMBERSize of the file (in bytes)
BS_KEYNUMBERPrimary key of the backup set (valid only if BACKUP_TYPE is BACKUP SET)
BS_COUNTNUMBERCount of the backup set from the controlfile record (valid only if BACKUP_TYPE is BACKUP SET)
BS_STAMPNUMBERStamp of the backup set from the controlfile record (valid only if BACKUP_TYPE is BACKUP SET)
BS_TYPEVARCHAR2(32)Type of the backup set (valid only if BACKUP_TYPE is BACKUP SET):
  • DATAFILE

  • ARCHIVED LOG

BS_INCR_TYPEVARCHAR2(32)Incremental type of the backup set (valid only if BACKUP_TYPE is BACKUP SET)
BS_PIECESNUMBERNumber of backup pieces in the backup set (valid only if BACKUP_TYPE is BACKUP SET)
BS_COPIESNUMBERNumber of copies of the backup set (valid only if FILE_TYPE is PIECE and BACKUP_TYPE is BACKUP SET)
BS_COMPLETION_TIMEDATECompletion time of the backup set (valid only if BACKUP_TYPE is BACKUP SET)
BS_STATUSVARCHAR2(16)Status of the backup set (valid only if BACKUP_TYPE is BACKUP SET):
  • AVAILABLE

  • UNAVAILABLE

  • EXPIRED

  • OTHER - Pieces which are part of the backup set do not have uniform status (that is, some of them are available, some not)

BS_BYTESNUMBERSum of all backup piece sizes in the backup set (valid only if BACKUP_TYPE is BACKUP SET)
BS_COMPRESSEDVARCHAR2(3)Indicates whether the backup pieces of the backup set are compressed (YES) or not (NO); valid only if BACKUP_TYPE is BACKUP SET
BS_TAGVARCHAR2(1024)Tags of the backup set. If pieces have different tags, then all piece tags are concatenated and separated by commas. Valid only if BACKUP_TYPE is BACKUP SET)
BS_DEVICE_TYPEVARCHAR2(255)Device type of the backup set. If there is more than one device type, then they are separated by commas. Valid only if BACKUP_TYPE is BACKUP SET
BP_PIECE#NUMBERNumber of pieces inside the backup set (valid only if FILE_TYPE is PIECE and BACKUP_TYPE is BACKUP SET)
BP_COPY#NUMBERNumber of copies of the backup set (valid only if FILE_TYPE is PIECE and BACKUP_TYPE is BACKUP SET)
DF_FILE#NUMBERAbsolute file number of the datafile (valid only if FILE_TYPE is DATAFILE)
DF_TABLESPACEVARCHAR2(30)Tablespace name of the datafile (valid only if FILE_TYPE is DATAFILE)
DF_RESETLOGS_CHANGE#NUMBERSystem change number (SCN) of the most recent RESETLOGS when the control file or datafile was created (valid only if FILE_TYPE is DATAFILE)
DF_CREATION_CHANGE#NUMBERCreation SCN of the control file or datafile (valid only if FILE_TYPE is DATAFILE)
DF_CHECKPOINT_CHANGE#NUMBERSystem change number (SCN) of the most recent control file or datafile checkpoint (valid only if FILE_TYPE is DATAFILE)
DF_CKP_MOD_TIMEDATEModification time in case of SPFILE, otherwise time when the control file or datafile was checkpointed (valid only if FILE_TYPE is DATAFILE)
RL_THREAD#NUMBERRedo log thread number of the archived log (valid only if FILE_TYPE is REDO LOG)
RL_SEQUENCE#NUMBERRedo log sequence number of the archived log (valid only if FILE_TYPE is REDO LOG)
RL_RESETLOGS_CHANGE#NUMBERSystem change number (SCN) of the most recent RESETLOGS when the record was created (valid only if FILE_TYPE is REDO LOG)
RL_FIRST_CHANGE#NUMBERFirst SCN of the redo log (valid only if FILE_TYPE is REDO LOG)
RL_FIRST_TIMEDATETime when the Oracle Database switched into the redo log (valid only if FILE_TYPE is REDO LOG)
RL_NEXT_CHANGE#NUMBERFirst SCN of the next redo log in the thread (valid only if FILE_TYPE is REDO LOG)
RL_NEXT_TIMEDATEFirst timestamp of the next redo log in the thread (valid only if FILE_TYPE is REDO LOG)
#!/bin/bash # OpenSSL/OpenSSH离线升级交互式脚本 # 版本: 3.0 # 功能: 支持分步执行、结果检查、日志记录和回滚机制 # ===================== 配置区域 ===================== LOG_FILE="/var/log/ssh_ssl_upgrade_$(date +%Y%m%d%H%M%S).log" BACKUP_DIR="/opt/backup_$(date +%Y%m%d%H%M%S)" SOFTWARE_DIR="/soft" MOUNT_DIR="/mnt/file" # =================================================== # 初始化日志系统 init_logging() { exec > >(tee -a "$LOG_FILE") 2>&1 echo "===== OpenSSL/OpenSSH 离线升级日志 [$(date)] =====" echo "📝 日志文件: $LOG_FILE" echo "💾 备份目录: $BACKUP_DIR" echo "💿 软件目录: $SOFTWARE_DIR" } # 检查root权限 check_root() { if [[ $EUID -ne 0 ]]; then echo "❌ 错误:必须使用root权限运行此脚本" | tee -a "$LOG_FILE" exit 1 fi } # 扫描软件包 scan_packages() { echo -e "\n🔍 扫描软件包目录: $SOFTWARE_DIR..." # 检查目录是否存在 if [[ ! -d "$SOFTWARE_DIR" ]]; then echo "❌ 错误:目录 $SOFTWARE_DIR 不存在" | tee -a "$LOG_FILE" exit 1 fi # 扫描OpenSSL包 local openssl_pkgs=() while IFS= read -r -d $'\0' file; do openssl_pkgs+=("$file") done < <(find "$SOFTWARE_DIR" -type f -iname "openssl-*.tar.gz" -print0 2>/dev/null) if [[ ${#openssl_pkgs[@]} -eq 0 ]]; then echo "❌ 错误:未找到OpenSSL源码包" | tee -a "$LOG_FILE" exit 1 fi # 扫描OpenSSH包 local openssh_pkgs=() while IFS= read -r -d $'\0' file; do openssh_pkgs+=("$file") done < <(find "$SOFTWARE_DIR" -type f -iname "openssh-*.tar.gz" -print0 2>/dev/null) if [[ ${#openssh_pkgs[@]} -eq 0 ]]; then echo "❌ 错误:未找到OpenSSH源码包" | tee -a "$LOG_FILE" exit 1 fi # 扫描ISO镜像 local iso_files=() while IFS= read -r -d $'\0' file; do iso_files+=("$file") done < <(find "$SOFTWARE_DIR" -type f -iname "*.iso" -print0 2>/dev/null) if [[ ${#iso_files[@]} -eq 0 ]]; then echo "⚠️ 警告:未找到ISO镜像文件,将跳过yum源配置" | tee -a "$LOG_FILE" fi # 显示可选项 echo -e "\n📦 可用的OpenSSL包:" for i in "${!openssl_pkgs[@]}"; do echo " [$i] $(basename "${openssl_pkgs[$i]}")" done echo -e "\n🔑 可用的OpenSSH包:" for i in "${!openssh_pkgs[@]}"; do echo " [$i] $(basename "${openssh_pkgs[$i]}")" done if [[ ${#iso_files[@]} -gt 0 ]]; then echo -e "\n💿 可用的ISO镜像:" for i in "${!iso_files[@]}"; do echo " [$i] $(basename "${iso_files[$i]}")" done fi # 用户选择 read -p "➡️ 请选择OpenSSL包序号: " ssl_idx read -p "➡️ 请选择OpenSSH包序号: " ssh_idx # 验证选择 if [[ ! "$ssl_idx" =~ ^[0-9]+$ ]] || [[ $ssl_idx -ge ${#openssl_pkgs[@]} ]]; then echo "❌ 错误:无效的OpenSSL选择" | tee -a "$LOG_FILE" exit 1 fi if [[ ! "$ssh_idx" =~ ^[0-9]+$ ]] || [[ $ssh_idx -ge ${#openssh_pkgs[@]} ]]; then echo "❌ 错误:无效的OpenSSH选择" | tee -a "$LOG_FILE" exit 1 fi # 设置全局变量 OPENSSL_PKG="${openssl_pkgs[$ssl_idx]}" OPENSSH_PKG="${openssh_pkgs[$ssh_idx]}" OPENSSL_VERSION=$(basename "$OPENSSL_PKG" | sed 's/openssl-\(.*\)\.tar\.gz/\1/') OPENSSH_VERSION=$(basename "$OPENSSH_PKG" | sed 's/openssh-\(.*\)\.tar\.gz/\1/') # 如果有ISO文件,让用户选择 if [[ ${#iso_files[@]} -gt 0 ]]; then read -p "➡️ 请选择ISO镜像序号: " iso_idx if [[ ! "$iso_idx" =~ ^[0-9]+$ ]] || [[ $iso_idx -ge ${#iso_files[@]} ]]; then echo "❌ 错误:无效的ISO选择" | tee -a "$LOG_FILE" exit 1 fi ISO_FILE="${iso_files[$iso_idx]}" else ISO_FILE="" fi echo -e "\n✅ 已选择:" echo " OpenSSL: $OPENSSL_VERSION" echo " OpenSSH: $OPENSSH_VERSION" [[ -n "$ISO_FILE" ]] && echo " ISO镜像: $(basename "$ISO_FILE")" } # 步骤执行函数 execute_step() { local step_num=$1 local step_name="$2" local step_func="$3" local rollback_func="${4:-}" echo -e "\n===== 🚀 步骤 $step_num: $step_name =====" | tee -a "$LOG_FILE" # 用户确认 read -p "➡️ 是否执行此步骤? [Y/n] " choice if [[ "$choice" == "n" || "$choice" == "N" ]]; then echo "⚠️ 跳过步骤 $step_num: $step_name" | tee -a "$LOG_FILE" return 0 fi # 执行步骤 $step_func local status=$? if [[ $status -eq 0 ]]; then echo "✅ 步骤 $step_num 成功: $step_name" | tee -a "$LOG_FILE" # 已移除等待用户按Enter的提示 return 0 else echo "❌ 步骤 $step_num 失败: $step_name (状态码: $status)" | tee -a "$LOG_FILE" if [[ -n "$rollback_func" ]]; then read -p "⚠️ 是否回滚此步骤? [y/N] " choice if [[ "$choice" == "y" || "$choice" == "Y" ]]; then $rollback_func return 1 fi fi read -p "⚠️ 是否继续? [y/N] " choice if [[ "$choice" != "y" && "$choice" != "Y" ]]; then echo "❌ 用户取消操作" | tee -a "$LOG_FILE" exit 1 fi return 1 fi } # 准备环境 prepare_environment() { echo -e "\n🛠️ 准备环境..." # 创建目录 mkdir -p "$SOFTWARE_DIR" "$MOUNT_DIR" "$BACKUP_DIR" [[ $? -ne 0 ]] && { echo "❌ 创建目录失败"; return 1; } echo "✅ 目录创建成功" # 备份yum源 mkdir -p /etc/yum.repos.d/bak mv /etc/yum.repos.d/*.repo /etc/yum.repos.d/bak/ 2>/dev/null # 创建本地源 if [[ -n "$ISO_FILE" ]]; then cat > /etc/yum.repos.d/local.repo << EOF [local] name=Local Repository baseurl=file://$MOUNT_DIR enabled=1 gpgcheck=0 EOF [[ $? -ne 0 ]] && { echo "❌ 创建yum源失败"; return 1; } echo "✅ 本地yum源配置完成" else echo "⚠️ 未配置本地yum源,跳过此步骤" fi } # 挂载镜像 mount_iso() { if [[ -z "$ISO_FILE" ]]; then echo "⚠️ 未选择ISO镜像,跳过挂载" return 0 fi echo -e "\n💿 挂载ISO镜像..." # 检查是否已挂载 if mount | grep -q "$MOUNT_DIR"; then umount "$MOUNT_DIR" 2>/dev/null fi # 挂载新镜像 mount -o loop "$ISO_FILE" "$MOUNT_DIR" [[ $? -ne 0 ]] && { echo "❌ 挂载镜像失败"; return 1; } echo "✅ ISO镜像挂载成功" # 更新yum缓存 yum clean all yum makecache [[ $? -ne 0 ]] && { echo "❌ Yum缓存更新失败"; return 1; } echo "✅ Yum缓存更新完成" } # 检查当前版本 check_current_versions() { echo -e "\nℹ️ 当前系统信息:" cat /etc/redhat-release echo -e "\nℹ️ 当前OpenSSL版本:" openssl version echo -e "\nℹ️ 当前OpenSSH版本:" ssh -V 2>&1 } # 安装依赖 install_dependencies() { echo -e "\n📦 安装依赖包..." # 根据引用[1]中的依赖列表 yum -y install wget net-tools nfs-utils lrzsz gcc gcc-c++ make cmake \ libxml2-devel openssl-devel curl curl-devel unzip sudo ntp libaio-devel \ vim ncurses-devel autoconf automake zlib-devel python-devel epel-release \ openssh-server socat ipvsadm conntrack ntpdate yum-utils \ device-mapper-persistent-data lvm2 pam-devel rpm-build [[ $? -ne 0 ]] && { echo "❌ 依赖安装失败"; return 1; } echo "✅ 依赖包安装完成" } # 禁用SELinux disable_selinux() { echo -e "\n🔒 禁用SELinux..." if grep -q "SELINUX=enforcing" /etc/selinux/config; then sed -i 's/SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config [[ $? -ne 0 ]] && { echo "❌ SELinux配置修改失败"; return 1; } echo "✅ SELinux永久禁用" fi setenforce 0 [[ $? -ne 0 ]] && { echo "❌ SELinux临时禁用失败"; return 1; } echo "✅ SELinux临时禁用" } # 关闭防火墙 disable_firewall() { echo -e "\n🔥 关闭防火墙..." systemctl stop firewalld systemctl disable firewalld [[ $? -ne 0 ]] && { echo "❌ 防火墙关闭失败"; return 1; } echo "✅ 防火墙已关闭" } # 备份系统 backup_system() { echo -e "\n💾 系统备份..." # 创建备份目录 mkdir -p "$BACKUP_DIR" # 备份OpenSSL cp -a /usr/bin/openssl "$BACKUP_DIR/openssl.bin" cp -a /usr/include/openssl "$BACKUP_DIR/openssl.include" cp -a /usr/lib64/libssl.so* "$BACKUP_DIR/" # 备份OpenSSH rpm -qa | grep openssh > "$BACKUP_DIR/openssh_packages.list" cp -a /etc/ssh "$BACKUP_DIR/ssh_config" cp -a /etc/pam.d/sshd "$BACKUP_DIR/" # 备份PAM配置 cp -a /etc/pam.d/sshd* "$BACKUP_DIR/" 2>/dev/null # 备份关键配置文件 cp -a /etc/ssh/sshd_config "$BACKUP_DIR/" cp -a /etc/init.d/sshd "$BACKUP_DIR/" 2>/dev/null echo "✅ 系统备份完成: $BACKUP_DIR" } # 升级OpenSSL upgrade_openssl() { echo -e "\n🛠️ 升级OpenSSL到版本 $OPENSSL_VERSION..." # 备份旧版本 mv /usr/bin/openssl /usr/bin/openssl.bak mv /usr/include/openssl /usr/include/openssl.bak mv /usr/lib64/libssl.so /usr/lib64/libssl.so.bak # 解压源码 tar -zxf "$OPENSSL_PKG" -C /tmp [[ $? -ne 0 ]] && { echo "❌ OpenSSL解压失败"; return 1; } local ssl_dir="/tmp/openssl-$OPENSSL_VERSION" [[ ! -d "$ssl_dir" ]] && { echo "❌ OpenSSL解压目录不存在: $ssl_dir"; return 1; } cd "$ssl_dir" || { echo "❌ 无法进入OpenSSL目录"; return 1; } # 编译安装 ./config --prefix=/usr --openssldir=/usr/local/openssl-$OPENSSL_VERSION shared [[ $? -ne 0 ]] && { echo "❌ OpenSSL配置失败"; return 1; } make -j$(nproc) [[ $? -ne 0 ]] && { echo "❌ OpenSSL编译失败"; return 1; } make install [[ $? -ne 0 ]] && { echo "❌ OpenSSL安装失败"; return 1; } # 更新库文件 ldconfig # 更新环境变量 echo 'export PATH=$PATH:/usr/local/openssl/bin' > /etc/profile.d/openssl.sh source /etc/profile.d/openssl.sh # 验证安装 local new_version=$(openssl version | awk '{print $2}') echo "✅ OpenSSL升级完成: $new_version" } # OpenSSL回滚 rollback_openssl() { echo -e "\n⏪ 回滚OpenSSL..." cp -f "$BACKUP_DIR/openssl.bin" /usr/bin/openssl cp -rf "$BACKUP_DIR/openssl.include" /usr/include/openssl cp -f "$BACKUP_DIR/libssl.so"* /usr/lib64/ ldconfig rm -f /etc/profile.d/openssl.sh source /etc/profile echo "✅ OpenSSL回滚完成" } # 升级OpenSSH upgrade_openssh() { echo -e "\n🔑 升级OpenSSH到版本 $OPENSSH_VERSION..." # 停止服务 systemctl stop sshd # 卸载旧版本 rpm -e --nodeps $(rpm -qa | grep openssh) 2>/dev/null # 解压源码 tar -zxf "$OPENSSH_PKG" -C /tmp [[ $? -ne 0 ]] && { echo "❌ OpenSSH解压失败"; return 1; } local ssh_dir="/tmp/openssh-$OPENSSH_VERSION" [[ ! -d "$ssh_dir" ]] && { echo "❌ OpenSSH解压目录不存在: $ssh_dir"; return 1; } cd "$ssh_dir" || { echo "❌ 无法进入OpenSSH目录"; return 1; } # 编译安装 ./configure --prefix=/usr \ --sysconfdir=/etc/ssh \ --with-ssl-dir=/usr \ --with-zlib \ --with-md5-passwords \ --with-pam \ --with-tcp-wrappers [[ $? -ne 0 ]] && { echo "❌ OpenSSH配置失败"; return 1; } make -j$(nproc) [[ $? -ne 0 ]] && { echo "❌ OpenSSH编译失败"; return 1; } make install [[ $? -ne 0 ]] && { echo "❌ OpenSSH安装失败"; return 1; } # 配置文件 cp -p contrib/redhat/sshd.init /etc/init.d/sshd cp -p contrib/redhat/sshd.pam /etc/pam.d/sshd # 服务配置 chkconfig --add sshd chkconfig sshd on } # OpenSSH回滚 rollback_openssh() { echo -e "\n⏪ 回滚OpenSSH..." yum -y reinstall $(cat "$BACKUP_DIR/openssh_packages.list") cp -rf "$BACKUP_DIR/ssh_config" /etc/ssh cp -f "$BACKUP_DIR/sshd.pam" /etc/pam.d/sshd systemctl restart sshd echo "✅ OpenSSH回滚完成" } # 配置SSH configure_ssh() { echo -e "\n⚙️ 配置SSH服务..." # 基本配置 if ! grep -q "PermitRootLogin" /etc/ssh/sshd_config; then echo "PermitRootLogin yes" >> /etc/ssh/sshd_config else sed -i 's/^#*PermitRootLogin.*/PermitRootLogin yes/' /etc/ssh/sshd_config fi sed -i 's/^#*PermitEmptyPasswords.*/PermitEmptyPasswords no/' /etc/ssh/sshd_config # 密钥处理 rm -rf /etc/ssh/ssh_host_* ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key -N "" ssh-keygen -t ecdsa -f /etc/ssh/ssh_host_ecdsa_key -N "" ssh-keygen -t ed25519 -f /etc/ssh/ssh_host_ed25519_key -N "" # 重启服务 systemctl restart sshd [[ $? -ne 0 ]] && { echo "❌ SSH服务重启失败"; return 1; } echo "✅ SSH配置完成" } # 验证安装 verify_installation() { echo -e "\n🔍 验证安装结果..." local openssl_ver=$(openssl version) local ssh_ver=$(ssh -V 2>&1) echo "➡️ OpenSSL版本: $openssl_ver" echo "➡️ OpenSSH版本: $ssh_ver" if [[ "$openssl_ver" == *"$OPENSSL_VERSION"* ]]; then echo "✅ OpenSSL版本验证通过" else echo "⚠️ OpenSSL版本不匹配" fi if [[ "$ssh_ver" == *"$OPENSSH_VERSION"* ]]; then echo "✅ OpenSSH版本验证通过" else echo "⚠️ OpenSSH版本不匹配" fi echo -e "\n🔍 服务状态检查:" systemctl status sshd --no-pager echo -e "\n🔍 网络连接测试:" netstat -tuln | grep ':22' } # 完整回滚 rollback_full() { echo -e "\n⏪ 开始完整系统回滚..." rollback_openssl rollback_openssh echo "✅ 系统回滚完成" echo "ℹ️ 当前OpenSSL版本: $(openssl version)" echo "ℹ️ 当前OpenSSH版本: $(ssh -V 2>&1)" } # 主函数 main() { clear echo "===== OpenSSL/OpenSSH 离线升级交互式脚本 =====" echo "⚠️ 注意:升级过程可能导致SSH连接中断,请确保有备用连接方式" init_logging check_root scan_packages read -p "⚠️ 确认开始升级? [y/N] " confirm if [[ "$confirm" != "y" && "$confirm" != "Y" ]]; then echo "❌ 升级已取消" | tee -a "$LOG_FILE" exit 0 fi # 分步执行升级流程 execute_step 1 "准备环境" prepare_environment execute_step 2 "挂载镜像" mount_iso execute_step 3 "检查当前版本" check_current_versions execute_step 4 "安装依赖" install_dependencies execute_step 5 "禁用SELinux" disable_selinux execute_step 6 "关闭防火墙" disable_firewall execute_step 7 "系统备份" backup_system execute_step 8 "升级OpenSSL" upgrade_openssl rollback_openssl execute_step 9 "升级OpenSSH" upgrade_openssh rollback_openssh execute_step 10 "配置SSH" configure_ssh execute_step 11 "验证安装" verify_installation echo -e "\n🎉 升级完成! 详细日志: $LOG_FILE" echo "备份位置: $BACKUP_DIR" # 回滚选项 read -p "❓ 是否验证SSH连接? [y/N] " verify if [[ "$verify" == "y" || "$verify" == "Y" ]]; then echo "ℹ️ 请尝试使用新SSH连接进行验证" read -p "❓ 连接是否正常? [Y/n] " conn_ok if [[ "$conn_ok" == "n" || "$conn_ok" == "N" ]]; then rollback_full fi fi echo -e "\n💡 建议重启系统: reboot" } # 执行主函数 main 需求:脚本执行前台不需要打印命令执行记录,只需要打印命令执行检查验证结果,详细记录存到日志
最新发布
08-10
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值