For the given example you should use arrays. See Arrays and Parameter Expansion from the Bash manual page for more information about arrays.
args=(a b "c d")
printf '%s\n' "${args[@]}"
If you need to use the output of a command as arguments you could use the IFS
parameter as argument separator and command substitution. Since globbing is performed after word splitting, you may want to disable globbing temporarily, also it's important to note empty items will be discarded during word splitting (thanks to Stéphane Chazelas for the reminders).
# save previous IFS value and change it to line feed
OLDIFS=$IFS IFS=$'\n'
temporarily disable globbing if needed
#set -o noglob
save command output to array, words are separated by IFS
args=($(printf 'arg 1\narg 2\narg 3\n'))
reenable globbing if needed
#set +o noglob
restore IFS
IFS=$OLDIFS
expand array as command arguments
printf '%s\n' "${args[@]}"
Using xargs
is probably an easier option, but don't forget it's not a shell builtin and cannot call shell builtins directly, so in the following example we're not invoking the printf
Bash builtin but the printf
binary (usually located at /bin/printf
or /usr/bin/printf
).
# POSIX xargs requires quoting
printf '"arg 1" "arg 2" "arg 3"' | xargs printf '<arg>%s</arg>\n'
other xargs (like GNU) versions have a -d
delimiter option
printf 'arg 1\narg 2\narg 3' | xargs -d'\n' printf '<arg>%s</arg>\n'
GNU and other xargs
also have a (non-standard) -0
option which allows to separate arguments with a null characters (usually represented as '\0'
), which is very convenient, since arguments cannot ever contain null bytes. Other commands take this into account, allowing to separate items with null bytes, like many find
versions, which include a -print0
option to separate found files with '\0'
, although, again, it's not an standard option.
# find files under /bin and calculate their sha256 digests
find /bin/ -type f -print0 | xargs -0 sha256sum