Es sieht so aus, als ob die kanonische Art, dies zu tun, in etwa so bash
ist
unset args
while IFS= read -r line; do
args+=("$line")
done < file
cmd "${args[@]}"
oder, wenn Ihre Version von Bash hat mapfile
:
mapfile -t args < filename
cmd "${args[@]}"
Der einzige Unterschied besteht zwischen dem Mapfile und der While-Read-Schleife und dem Einzeiler
(set -f; IFS=$'\n'; cmd $(<file))
ist, dass ersteres eine leere Zeile in ein leeres Argument umwandelt, während der Einzeiler eine leere Zeile ignoriert. In diesem Fall ist das Ein-Linien-Verhalten sowieso das, was ich vorziehen würde, also doppelter Bonus, wenn es kompakt ist.
Ich würde es verwenden, IFS=$'\n' cmd $(<file)
aber es funktioniert nicht, da $(<file)
es so interpretiert wird, dass es die Befehlszeile bildet, bevor es IFS=$'\n'
wirksam wird.
Obwohl es in meinem Fall nicht funktioniert, habe ich jetzt erfahren, dass viele Tools das Beenden von Zeilen unterstützen, null (\000)
anstatt newline (\n)
dies beim Umgang mit beispielsweise Dateinamen, die häufige Ursachen für diese Situationen sind, zu vereinfachen :
find / -name '*.config' -print0 | xargs -0 md5
Füttert md5 eine Liste vollqualifizierter Dateinamen als Argumente, ohne dass ein Globbing oder eine Interpolation erforderlich ist. Das führt zur nicht eingebauten Lösung
tr "\n" "\000" <file | xargs -0 cmd
Auch dies ignoriert zwar leere Zeilen, erfasst jedoch Zeilen, die nur Leerzeichen enthalten.