mirror of
https://github.com/docker-mailserver/docker-mailserver.git
synced 2025-08-24 19:45:33 +02:00
fix: Helper _replace_by_env_in_file()
support delimiter parameter
Minor change to add support for usage with `saslauthd.conf` which differs with `:` for it's key/value delimiter. Also adopts the`_escape_for_sed()` method, instead of the inline sed pattern (_which for some reason escaped `=` but not `(` + `)`, thus buggy if ever matching on input with those tokens_). `_escape_for_sed()` likewise wasn't escaping for `(` + `)` or even `|`, which are required for proper escape support if using `sed -E` / `sed -r` with this method. Additionally added escaping support for `&` replacement segment token, which seems valid. Increased verbosity to better grok pattern matching expression, clarified escaping concern with `sed` delimiter since the project is not consistent there.
This commit is contained in:
parent
ed84dca147
commit
6dfd553ae0
1 changed files with 29 additions and 11 deletions
|
@ -4,14 +4,30 @@ function _escape() {
|
||||||
echo "${1//./\\.}"
|
echo "${1//./\\.}"
|
||||||
}
|
}
|
||||||
|
|
||||||
# TODO: Not in use currently. Maybe in the future: https://github.com/docker-mailserver/docker-mailserver/pull/3484/files#r1299410851
|
# Replaces a string so that it can be used inside the `sed` regex segment safely.
|
||||||
# Replaces a string so that it can be used inside
|
# WARNING: Only for use with `sed -E` / `sed -r` due to escaping additional tokens,
|
||||||
# `sed` safely.
|
# which are valid tokens when escaped in basic regex mode.
|
||||||
#
|
#
|
||||||
# @param ${1} = string to escape
|
# @param ${1} = string to escape
|
||||||
# @output = prints the escaped string
|
# @output = prints the escaped string
|
||||||
function _escape_for_sed() {
|
function _escape_for_sed() {
|
||||||
sed -E 's/[]\/$*.^[]/\\&/g' <<< "${1:?String to escape for sed is required}"
|
# Escapes all special tokens:
|
||||||
|
# - `/` should represent the sed delimiter (caution when using sed with a non-default delimiter).
|
||||||
|
# - `]` should be the first char, while `.` must not be the 2nd.
|
||||||
|
# - Within the `[ ... ]` scope, no escaping is needed regardless of basic vs extended regexp mode.
|
||||||
|
local REGEX_BASIC='][/\$*.^'
|
||||||
|
# In this mode (`-E` / `-r`), these tokens no longer require a preceding `\`, so must also be escaped:
|
||||||
|
local REGEX_EXTENDED='|?)(}{+'
|
||||||
|
# The replacement segment is compatible but most tokens do not require escaping.
|
||||||
|
# `&` is a token for this segment, and is compatible with escaping in the regex segment:
|
||||||
|
local TOKEN_REPLACEMENT='&'
|
||||||
|
local REGEX_SEGMENT="${REGEX_BASIC}${REGEX_EXTENDED}${TOKEN_REPLACEMENT}"
|
||||||
|
|
||||||
|
# Output: `\\` prepends a `\` to a token matched by the regex segment (`&`)
|
||||||
|
local PREPEND_ESCAPE='\\&'
|
||||||
|
|
||||||
|
# Full sed expression: sed -E 's/[][/\$*.^|?)(}{+&]/\\&/g'
|
||||||
|
sed -E "s/[${REGEX_SEGMENT}]/${PREPEND_ESCAPE}/g" <<< "${1:?String to escape for sed is required}"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Returns input after filtering out lines that are:
|
# Returns input after filtering out lines that are:
|
||||||
|
@ -78,8 +94,9 @@ function _reload_postfix() {
|
||||||
# calling this function.
|
# calling this function.
|
||||||
#
|
#
|
||||||
# @option --shutdown-on-error = shutdown in case an error is detected
|
# @option --shutdown-on-error = shutdown in case an error is detected
|
||||||
# @param ${1} = prefix for environment variables
|
# @param ${1} = Prefix for selecting environment variables
|
||||||
# @param ${2} = file in which substitutions should take place
|
# @param ${2} = File in which substitutions should take place
|
||||||
|
# @param ${3} = The key/value assignment operator used (default: `=`) [OPTIONAL]
|
||||||
#
|
#
|
||||||
# ## Example
|
# ## Example
|
||||||
#
|
#
|
||||||
|
@ -87,7 +104,7 @@ function _reload_postfix() {
|
||||||
# you can set the environment variable `POSTFIX_README_DIRECTORY='/new/dir/'`
|
# you can set the environment variable `POSTFIX_README_DIRECTORY='/new/dir/'`
|
||||||
# (`POSTFIX_` is an arbitrary prefix, you can choose the one you like),
|
# (`POSTFIX_` is an arbitrary prefix, you can choose the one you like),
|
||||||
# and then call this function:
|
# and then call this function:
|
||||||
# `_replace_by_env_in_file 'POSTFIX_' 'PATH TO POSTFIX's main.cf>`
|
# `_replace_by_env_in_file 'POSTFIX_' '/etc/postfix/main.cf`
|
||||||
#
|
#
|
||||||
# ## Panics
|
# ## Panics
|
||||||
#
|
#
|
||||||
|
@ -105,15 +122,16 @@ function _replace_by_env_in_file() {
|
||||||
fi
|
fi
|
||||||
|
|
||||||
local ENV_PREFIX=${1} CONFIG_FILE=${2}
|
local ENV_PREFIX=${1} CONFIG_FILE=${2}
|
||||||
|
local KV_DELIMITER=${3:-'='}
|
||||||
local ESCAPED_VALUE ESCAPED_KEY
|
local ESCAPED_VALUE ESCAPED_KEY
|
||||||
|
|
||||||
while IFS='=' read -r KEY VALUE; do
|
while IFS="${KV_DELIMITER}" read -r KEY VALUE; do
|
||||||
KEY=${KEY#"${ENV_PREFIX}"} # strip prefix
|
KEY=${KEY#"${ENV_PREFIX}"} # strip prefix
|
||||||
ESCAPED_KEY=$(sed -E 's#([\=\&\|\$\.\*\/\[\\^]|\])#\\\1#g' <<< "${KEY,,}")
|
ESCAPED_KEY=$(_escape_for_sed "${KEY,,}")
|
||||||
ESCAPED_VALUE=$(sed -E 's#([\=\&\|\$\.\*\/\[\\^]|\])#\\\1#g' <<< "${VALUE}")
|
ESCAPED_VALUE=$(_escape_for_sed "${VALUE}")
|
||||||
[[ -n ${ESCAPED_VALUE} ]] && ESCAPED_VALUE=" ${ESCAPED_VALUE}"
|
[[ -n ${ESCAPED_VALUE} ]] && ESCAPED_VALUE=" ${ESCAPED_VALUE}"
|
||||||
_log 'trace' "Setting value of '${KEY}' in '${CONFIG_FILE}' to '${VALUE}'"
|
_log 'trace' "Setting value of '${KEY}' in '${CONFIG_FILE}' to '${VALUE}'"
|
||||||
sed -i -E "s#^${ESCAPED_KEY}[[:space:]]*=.*#${ESCAPED_KEY} =${ESCAPED_VALUE}#g" "${CONFIG_FILE}"
|
sed -i -E "s#^${ESCAPED_KEY}[[:space:]]*${KV_DELIMITER}.*#${ESCAPED_KEY} ${KV_DELIMITER}${ESCAPED_VALUE}#g" "${CONFIG_FILE}"
|
||||||
done < <(env | grep "^${ENV_PREFIX}")
|
done < <(env | grep "^${ENV_PREFIX}")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue