Als Ciro Santilli schreibt Bei der Verwendung von Befehlssubstitutionen werden nachstehende Zeilenumbrüche weggelassen. Ihr Workaround, der nachgestellte Zeichen hinzufügt, ist großartig, aber nachdem ich ihn einige Zeit verwendet hatte, beschloss ich, dass ich eine Lösung brauchte, die überhaupt keine Befehlssubstitution verwendet.
Mein Ansatz verwendet nun read
zusammen mit dem printf
eingebaut -v
Flagge um den Inhalt von stdin direkt in eine Variable zu lesen.
# Reads stdin into a variable, accounting for trailing newlines. Avoids
# needing a subshell or command substitution.
# Note that NUL bytes are still unsupported, as Bash variables don't allow NULs.
# See https://stackoverflow.com/a/22607352/113632
read_input() {
# Use unusual variable names to avoid colliding with a variable name
# the user might pass in (notably "contents")
: "${1:?Must provide a variable to read into}"
if [[ "$1" == '_line' || "$1" == '_contents' ]]; then
echo "Cannot store contents to $1, use a different name." >&2
return 1
fi
local _line _contents=()
while IFS='' read -r _line; do
_contents+=("$_line"$'\n')
done
# include $_line once more to capture any content after the last newline
printf -v "$1" '%s' "${_contents[@]}" "$_line"
}
Dies unterstützt Eingaben mit oder ohne nachfolgende Zeilenumbrüche.
Beispiel für die Verwendung:
$ read_input file_contents < /tmp/file
# $file_contents now contains the contents of /tmp/file