Hier ist eine robuste Bash-Funktion , die trotz Verwendung evalsicher sein sollte.
Alle ${varName}Variablenreferenzen im Eingabetext werden basierend auf den Variablen der aufrufenden Shell erweitert.
Nichts anderes wird erweitert: weder Variablenreferenzen, deren Namen nicht eingeschlossen sind {...}(z. B. $varName), noch Befehlssubstitutionen ( $(...)und Legacy-Syntax `...`) noch arithmetische Substitutionen ( $((...))und Legacy-Syntax)$[...] ).
Um a $als wörtlich zu behandeln , \entkomme es; z.B:\${HOME}
Beachten Sie, dass Eingaben nur über stdin akzeptiert werden .
Beispiel:
$ expandVarsStrict <<<'$HOME is "${HOME}"; `date` and \$(ls)' # only ${HOME} is expanded
$HOME is "/Users/jdoe"; `date` and $(ls)
Funktionsquellcode:
expandVarsStrict(){
local line lineEscaped
while IFS= read -r line || [[ -n $line ]]; do # the `||` clause ensures that the last line is read even if it doesn't end with \n
# Escape ALL chars. that could trigger an expansion..
IFS= read -r -d '' lineEscaped < <(printf %s "$line" | tr '`([$' '\1\2\3\4')
# ... then selectively reenable ${ references
lineEscaped=${lineEscaped//$'\4'{/\${}
# Finally, escape embedded double quotes to preserve them.
lineEscaped=${lineEscaped//\"/\\\"}
eval "printf '%s\n' \"$lineEscaped\"" | tr '\1\2\3\4' '`([$'
done
}
Die Funktion wird davon ausgegangen , dass keine 0x1, 0x2, 0x3, und 0x4Steuerzeichen in der Eingabe vorhanden sind, weil diese Zeichen. werden intern verwendet - da die Funktion Text verarbeitet , sollte dies eine sichere Annahme sein.