#!/bin/bash # Ver: 1.2 by Endial Fang (endial@126.com) # # 文件操作函数库 # 加载依赖项 source "/usr/local/lib/libos.sh" # 函数列表 # 检测"*_FILE"文件,并从文件中读取信息作为参数值;环境变量不允许 VAR 与 VAR_FILE 方式并存 # 变量: # $1 - 需要设置的环境变量名称 # $2 - 该变量对应的默认值(Option) # # 使用: file_env ENV_VAR [DEFAULT] file_env() { local var="$1" local fileVar="${var}_FILE" local def="${2:-}" if [ "${!var:-}" ] && [ "${!fileVar:-}" ]; then error "Both $var and $fileVar are set (but are exclusive)" exit 1 fi local val="$def" if [ "${!var:-}" ]; then val="${!var}" elif [ "${!fileVar:-}" ]; then val="$(< "${!fileVar}")" fi export "$var"="$val" unset "$fileVar" } # 使用规则表达式在文件中替换数据 # 参数: # $1 - 文件名 # $2 - 正则表达式 # $3 - 替代数据表达式 # $4 - 是否使用POSIX表达式. Default: true replace_in_file() { local filename="${1:?filename is required}" local match_regex="${2:?match regex is required}" local substitute_regex="${3:?substitute regex is required}" local posix_regex=${4:-true} local result # 规避使用'sed in-place' 方式操作 # 1) 部分系统兼容性问题,如从ConfigMap中加载的文件 # 2) 部分系统不支持"in-place" 方式操作 local -r del=$'\001' # Use a non-printable character as a 'sed' delimiter to avoid issues if [[ $posix_regex = true ]]; then result="$(sed -E "s${del}${match_regex}${del}${substitute_regex}${del}g" "$filename")" else result="$(sed "s${del}${match_regex}${del}${substitute_regex}${del}g" "$filename")" fi echo "$result" > "$filename" } # Replace a regex-matching multiline string in a file # 使用规则表达式在文件中替换多行数据 # 参数: # $1 - 文件名 # $2 - 正则表达式 # $3 - 替代数据表达式 replace_in_file_multiline() { local filename="${1:?filename is required}" local match_regex="${2:?match regex is required}" local substitute_regex="${3:?substitute regex is required}" local result local -r del=$'\001' # Use a non-printable character as a 'sed' delimiter to avoid issues result="$(perl -pe "BEGIN{undef $/;} s${del}${match_regex}${del}${substitute_regex}${del}sg" "$filename")" echo "$result" > "$filename" } # 使用规则表达式在文件中删除数据 # 参数: # $1 - 文件名 # $2 - 正则表达式 # $3 - 是否使用POSIX表达式. Default: true remove_in_file() { local filename="${1:?filename is required}" local match_regex="${2:?match regex is required}" local posix_regex=${3:-true} local result # 规避使用'sed in-place' 方式操作 # 1) 部分系统兼容性问题,如从ConfigMap中加载的文件 # 2) 部分系统不支持"in-place" 方式操作 if [[ $posix_regex = true ]]; then result="$(sed -E "/$match_regex/d" "$filename")" else result="$(sed "/$match_regex/d" "$filename")" fi echo "$result" > "$filename" } # 在符合条件的行后增加文本 # 参数: # $1 - 文件名 # $2 - 正则表达式 # $3 - 待增加的文本 append_in_file() { local file="${1:?missing file}" local match_regex="${2:?missing pattern}" local value="${3:?missing value}" # We read the file in reverse, replace the first match (0,/pattern/s) and then reverse the results again result="$(tac "$file" | sed -E "0,/($match_regex)/s||${value}\n\1|" | tac)" echo "$result" > "$file" } # 等待日志文件中包含指定的条目 # 参数: # $1 - 待查找的条目 # $2 - 日志文件 # $3 - 最大重试次数. Default: 12 # $4 - 重试间隔时间(秒). Default: 5 wait_for_log_entry() { local -r entry="${1:-missing entry}" local -r log_file="${2:-missing log file}" local -r retries="${3:-12}" local -r interval_time="${4:-5}" local attempt=0 check_log_file_for_entry() { if ! grep -qE "$entry" "$log_file"; then debug "Entry \"${entry}\" still not present in ${log_file} (attempt $((++attempt))/${retries})" return 1 fi } debug "Checking that ${log_file} log file contains entry \"${entry}\"" if retry_while check_log_file_for_entry "$retries" "$interval_time"; then debug "Found entry \"${entry}\" in ${log_file}" true else error "Could not find entry \"${entry}\" in ${log_file} after ${retries} retries" debug_execute cat "$log_file" return 1 fi }