更新时间:2024-09-14 GMT+08:00
配置update_hosts_linux.sh脚本
根据提供的脚本示例,结合实际情况,修改示例中的相关配置。
前提条件
已完成准备工作。
操作步骤
- 在执行脚本的主机上创建一个名为“update_hosts_linux.sh”的文件,然后将以下脚本示例的内容复制到文件中。如果您已经通过SSH连接到源端Linux主机,可以直接使用vim创建和编辑脚本文件,步骤如下:
- 在Vim编辑器中按 i 进入插入模式。
- 复制并粘贴脚本代码,完成后按 Esc。
- 输入 :wq 保存并退出。
#!/bin/bash # Configuration # Log directory path: Used to store run logs, error logs, and summary logs. # If the directory doesn't exist, the script will create it automatically. LOG_DIR="/var/log/update_hosts" # Run log file path: Records detailed information about the script's execution. RUN_LOG="$LOG_DIR/run.log" # Error log file path: Records any errors that occur during the script's execution. ERROR_LOG="$LOG_DIR/error.log" # Summary log file path: Records a summary of the script's execution, including the number of successful and failed servers. SUMMARY_LOG="$LOG_DIR/summary.log" # CSV file path: Contains information about the target hosts (must be manually created and configured). CSV_FILE="target_servers.csv" # Hosts content file path: Contains the content to be appended to each target host's /etc/hosts file (must be manually created and configured). HOSTS_FILE="hosts_content.txt" DEFAULT_PORT=22 SSH_TIMEOUT=10 # Initialize log directory and files initialize_logs() { mkdir -p "$LOG_DIR" echo "========================================" >> "$RUN_LOG" echo "[INFO] $(date '+%Y-%m-%d %H:%M:%S') - Starting new update execution" >> "$RUN_LOG" echo "========================================" >> "$RUN_LOG" echo "========================================" >> "$ERROR_LOG" echo "[INFO] $(date '+%Y-%m-%d %H:%M:%S') - Starting new update execution" >> "$ERROR_LOG" echo "========================================" >> "$ERROR_LOG" echo "========================================" > "$SUMMARY_LOG" echo "[INFO] $(date '+%Y-%m-%d %H:%M:%S') - Starting new update execution" >> "$SUMMARY_LOG" echo "========================================" >> "$SUMMARY_LOG" } # Log info function log_info() { echo "[INFO] $(date '+%Y-%m-%d %H:%M:%S') - $1" | tee -a "$RUN_LOG" } # Log error function log_error() { echo "[ERROR] $(date '+%Y-%m-%d %H:%M:%S') - $1" | tee -a "$RUN_LOG" "$ERROR_LOG" } # Read server information from CSV file read_servers_from_csv() { local csv_file="$1" local servers=() local header_skipped=false if [ ! -f "$csv_file" ]; then log_error "CSV file '$csv_file' not found." exit 1 fi # Ensure file ends with a newline character sed -i -e '$a\' "$csv_file" while IFS=, read -r username ip port password; do # Skip header row if [ "$header_skipped" = false ]; then header_skipped=true continue fi # Skip empty and invalid rows if [[ -z "$username" || -z "$ip" ]]; then continue fi port=${port:-$DEFAULT_PORT} # Use default port 22 # Ensure port is numeric if ! [[ "$port" =~ ^[0-9]+$ ]]; then log_error "Invalid port '$port' for $username@$ip. Skipping this server." continue fi servers+=("$username@$ip:$port:$password") done < "$csv_file" echo "${servers[@]}" } # Read hosts content from TXT file read_hosts_content_from_txt() { local txt_file="$1" if [ -f "$txt_file" ]; then cat "$txt_file" else log_error "Hosts content file '$txt_file' not found." exit 1 fi } # Initialize log files initialize_logs # Read server information from CSV file servers=($(read_servers_from_csv "$CSV_FILE")) # Read hosts content from TXT file hosts_content=$(read_hosts_content_from_txt "$HOSTS_FILE") # Counters for success and failure success_count=0 failure_count=0 failed_servers=() # Iterate over each server and push hosts content for server in "${servers[@]}"; do # Extract user, IP, port, and password information IFS=':' read -r user_host port pass <<< "$server" IFS='@' read -r user ip <<< "$user_host" log_info "Starting update for $user@$ip:$port" # Create temporary script and SSH_ASKPASS script tmp_script=$(mktemp) askpass_script=$(mktemp) cat <<EOF > "$tmp_script" #!/bin/bash # Backup hosts file if [ ! -f /etc/hosts.bak ]; then cp /etc/hosts /etc/hosts.bak fi # Remove old Migration-proxy section sed -i '/#Migration-proxy-start/,/#Migration-proxy-end/d' /etc/hosts # Append new Migration-proxy section echo "$hosts_content" >> /etc/hosts EOF cat <<EOF > "$askpass_script" #!/bin/bash echo "$pass" EOF chmod +x "$tmp_script" "$askpass_script" # Set SSH_ASKPASS environment variable and use ssh to connect to the target machine and execute the temporary script export SSH_ASKPASS="$askpass_script" export DISPLAY=:0 ssh_output=$(mktemp) setsid ssh -o BatchMode=no -o ConnectTimeout=$SSH_TIMEOUT -o StrictHostKeyChecking=no -p "$port" "$user@$ip" 'bash -s' < "$tmp_script" 2> "$ssh_output" ssh_status=$? if [ $ssh_status -eq 0 ]; then log_info "Updated hosts on $ip:$port successfully" ((success_count++)) else ssh_error=$(cat "$ssh_output") case $ssh_status in 1) log_error "General error occurred while updating hosts on $ip:$port: $ssh_error" ;; 2) log_error "Misuse of shell builtins while updating hosts on $ip:$port: $ssh_error" ;; 255) if [[ "$ssh_error" == *"Permission denied"* ]]; then log_error "SSH login failed for $user@$ip:$port: Permission denied (password may be incorrect or username is wrong)" elif [[ "$ssh_error" == *"Connection refused"* ]]; then log_error "SSH login failed for $user@$ip:$port: Connection refused (port may be incorrect or SSH service not running on target)" elif [[ "$ssh_error" == *"No route to host"* ]]; then log_error "SSH login failed for $user@$ip:$port: No route to host (network unreachable)" elif [[ "$ssh_error" == *"Host key verification failed"* ]]; then log_error "SSH login failed for $user@$ip:$port: Host key verification failed" elif [[ "$ssh_error" == *"Connection timed out"* ]]; then log_error "SSH login failed for $user@$ip:$port: Connection timed out" else log_error "SSH login failed for $user@$ip:$port: $ssh_error" fi ;; *) log_error "An unknown error occurred while updating hosts on $ip:$port: $ssh_error" ;; esac failed_servers+=("$user@$ip:$port") ((failure_count++)) fi # Remove temporary scripts and SSH output file rm -f "$tmp_script" "$askpass_script" "$ssh_output" done # Calculate failure and success percentages total_count=${#servers[@]} failure_percentage=$(echo "scale=2; ($failure_count / $total_count) * 100" | bc) success_percentage=$(echo "scale=2; ($success_count / $total_count) * 100" | bc) # Output summary result and log to file summary_content=$(cat <<EOF ======================================== [SUMMARY] $(date '+%Y-%m-%d %H:%M:%S') - Execution Update Summary ======================================== Total number of servers: $total_count Number of successful updates: $success_count Number of failed updates: $failure_count Success rate: $success_percentage% Failure rate: $failure_percentage% ---------------------------------------- EOF ) if [ $failure_count -gt 0 ]; then summary_content+="Failed servers:\n" for server in "${failed_servers[@]}"; do summary_content+=" - $server\n" done fi summary_content+="========================================" # Output summary result to log file and terminal echo -e "$summary_content" | tee -a "$SUMMARY_LOG" log_info "Script execution completed. Check $SUMMARY_LOG for summary."
- 根据实际情况,修改脚本中的以下配置项参数:
- LOG_DIR="/var/log/update_hosts"
- 描述:日志目录路径,用于存放运行日志、错误日志和总结日志的文件夹路径。
- 参数默认值: /var/log/update_hosts
- 修改建议:修改为当前用户具有写入权限的目录路径。
- 修改示例:LOG_DIR="/home/username/update_hosts_logs"
- CSV_FILE="target_servers.csv"
- 描述:CSV文件路径,包含源端主机信息。
- 参数默认值:target_servers.csv
- 修改建议:使用绝对路径,或确保相对路径是正确的。
- 修改示例:CSV_FILE="/home/username/configs/servers.csv"
- HOSTS_FILE="hosts_content.txt"
- 描述:Hosts文件存放路径,包含要追加到源端主机 /etc/hosts 文件中的内容。
- 参数默认值:hosts_content.txt
- 修改建议:使用绝对路径,或确保相对路径是正确的。
- 修改示例:HOSTS_FILE="/home/username/configs/hosts_content.txt"
- LOG_DIR="/var/log/update_hosts"
- 配置项参数修改完成并保存后,在终端窗口(如果有图形化界面可以按Ctrl+Alt+T打开终端)执行脚本:
./update_hosts_linux.sh
脚本会在终端窗口中输出日志信息,并在执行完毕后生成一个执行结果报告,可以在LOG_DIR 指定目录中的 summary.log 文件中查看。
父主题: 配置脚本