Sepertinya cara kanonik untuk melakukan ini bash
adalah sesuatu seperti
unset args
while IFS= read -r line; do
args+=("$line")
done < file
cmd "${args[@]}"
atau, jika versi bash Anda memiliki mapfile
:
mapfile -t args < filename
cmd "${args[@]}"
Satu-satunya perbedaan yang dapat saya temukan antara mapfile dan loop sambil membaca versus satu-liner
(set -f; IFS=$'\n'; cmd $(<file))
adalah bahwa yang pertama akan mengonversi baris kosong ke argumen kosong, sedangkan satu-baris akan mengabaikan baris kosong. Dalam hal ini perilaku one-liner adalah apa yang saya inginkan, jadi bonus dua kali lipat menjadi kompak.
Saya akan menggunakan IFS=$'\n' cmd $(<file)
tetapi tidak berhasil, karena $(<file)
ditafsirkan untuk membentuk baris perintah sebelum IFS=$'\n'
mulai berlaku.
Meskipun tidak bekerja dalam kasus saya, saya sekarang sudah belajar bahwa banyak alat mendukung mengakhiri baris dengan null (\000)
bukannya newline (\n)
yang tidak membuat banyak ini lebih mudah ketika berhadapan dengan, katakanlah, nama file, yang merupakan sumber umum dari situasi ini :
find / -name '*.config' -print0 | xargs -0 md5
feed daftar nama file yang sepenuhnya memenuhi syarat sebagai argumen untuk MD5 tanpa menggumpal atau interpolasi atau apa pun. Itu mengarah pada solusi non-built-in
tr "\n" "\000" <file | xargs -0 cmd
Meskipun ini, juga, mengabaikan garis kosong, meskipun tidak menangkap garis yang hanya memiliki spasi putih.