Hier ist eine robuste Bash-Funktion , die trotz Verwendung eval
sicher 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 0x4
Steuerzeichen in der Eingabe vorhanden sind, weil diese Zeichen. werden intern verwendet - da die Funktion Text verarbeitet , sollte dies eine sichere Annahme sein.