Wygląda na to, że kanoniczny sposób na zrobienie tego bashjest podobny
unset args
while IFS= read -r line; do
args+=("$line")
done < file
cmd "${args[@]}"
lub, jeśli twoja wersja bash ma mapfile:
mapfile -t args < filename
cmd "${args[@]}"
Jedyną różnicę, którą mogę znaleźć między plikiem mapy a pętlą podczas odczytu w porównaniu z linią jednowierszową
(set -f; IFS=$'\n'; cmd $(<file))
polega na tym, że ten pierwszy przekształci pustą linię w pusty argument, podczas gdy jednowierszowy zignoruje pustą linię. W tym przypadku i tak wolę liniowe zachowanie i tak wolę, więc podwójny bonus za to, że jest kompaktowy.
Chciałbym użyć, IFS=$'\n' cmd $(<file)ale to nie działa, ponieważ $(<file)jest interpretowane jako wiersz poleceń, zanim zacznie IFS=$'\n'obowiązywać.
Chociaż w moim przypadku to nie działa, nauczyłem się, że wiele narzędzi obsługuje linie kończące, null (\000)zamiast newline (\n)których znacznie ułatwia to, na przykład, nazwy plików, które są częstymi źródłami takich sytuacji :
find / -name '*.config' -print0 | xargs -0 md5
wysyła listę w pełni kwalifikowanych nazw plików jako argumentów do md5 bez globowania, interpolacji lub czegokolwiek. To prowadzi do niewbudowanego rozwiązania
tr "\n" "\000" <file | xargs -0 cmd
chociaż to również ignoruje puste linie, chociaż przechwytuje linie, które mają tylko białe znaki.