Passing list of file paths in variable as arguments to command
Scenario:
kdialog --menu
takes a list of strings of the form title element label element label ...
. Now, the issue with this is that spaces are used as delimiters.
Let's say I have a string variable $LIST containing a list of file paths and labels generated by another command. I want to make kdialog use the elements from that variable. Here are three ways the list could be formatted inside the variable:
file A /dir/file A file B /dir/file B file C /dir/file C
Obviously this is useless because there is no distinction between spaces inside filenames and delimiting spaces.
"file A" "/dir/file A" "file B" "/dir/file B" "file C" "/dir/file C"
If I try to use this with kdialog --menu title $LIST
it doesn't work, because kidalog simply ignores the quotes. The same is true if I use ${LIST}
or `echo $LIST`
or $(echo $LIST)
The list of labels it will actually show in the produced menu will always be
A"
A"
B"
B"
C"
C"
Using "$LIST"
on the other hand produces an error.
file\ A /dir/file\ A file\ B /dir/file\ B file\ C /dir/file\ C
The effect of this is exactly analogous to the quotes case, except in this case I can use "$LIST" to produce an equally useless result without error.
Question:
How can I pass a variable with a list of string elements, each of which may or may not contain spaces, to a command so that each element is interpreted as a separate argument by the command, but with escaped spaces?
You need something to parse a single string and create multiple arguments from it. This is exactly a job for xargs
. Like this:
LIST='"file A" "/dir/file A" "file B" "/dir/file B" "file C" "/dir/file C"'
printf '%s\n' "$LIST" | xargs kdialog --menu title
or
LIST='file\ A /dir/file\ A file\ B /dir/file\ B file\ C /dir/file\ C'
printf '%s\n' "$LIST" | xargs kdialog --menu title
Note I used the exact strings you tried. Each string happens to be in a format xargs
parses as you expect. See man 1 xargs
to learn the details.
Your question is tagged bash. In Bash you don't need printf
, you can use the following syntax:
<<<"$LIST" xargs kdialog --menu title
Note: avoid uppercase names for variables. If you get used to them then sooner or later you will possibly change PATH
or another important environment variable in some script and the rest of the script will fail.