3

Totally crazy about the following commands:

declare -a partition_files
readarray -d '' partition_files < <(find "$choosen_image_folder" -name "*sda${i}.gz*")

# this does not work
/bin/cat "${partition_files[*]}" | /bin/gunzip -f -c | ntfsclone -r -O "/dev/sda$i" -
# this does work
/bin/cat ${partition_files[*]} | /bin/gunzip -f -c | ntfsclone -r -O "/dev/sda$i" -
# this does not work
/usr/sbin/partimage restore -b "/dev/sda$i" "${partition_files[*]}"
# this does work
/usr/sbin/partimage restore -b "/dev/sda$i" ${partition_files[*]}

Why in this case removing the quoting is working and with quotes is not?

2
  • Add the output of the partition_files array to your question. What do you mean that it doesn't work? Is there an error message? – Nasir Riley Feb 26 at 17:05
  • partition_files is the result of a find. Does not work means that gunzip fails. – piertoni Feb 26 at 17:10
6

"${partition_files[*]}" concatenates all the array elements to one shell word, using the first character of IFS as a joiner. So, if the array is a=("foo bar" asdf), and IFS has the default value, you get the same as "foo bar asdf".

You want "${partition_files[@]}" instead, it makes each element a distinct word, so the same as "foo bar" "asdf".

This is the same difference as between "$@" and "$*", and in general, you always want "$@", or "${array[@]}" (with the at-sign and the quotes) unless you know you're doing something special.

If you do ${array[*]} without the quotes, you get all elements separately, and then each word-split again. (If IFS is not the empty string, it's basically the same as all elements concatenated, and then the combination word-split.)

See e.g. https://www.gnu.org/software/bash/manual/html_node/Special-Parameters.html

5
  • 1
    I meant to just write a quick two-sentence answer. – ilkkachu Feb 26 at 17:14
  • so if I have an array of two elements and I concatenate using ${array[*]} this will join to a single name. In my case I have two filenames and bash is trying to pass a filename made of two names, is this correct? – piertoni Feb 26 at 17:17
  • @piertoni, "${array[*]}" with quotes will join to a single word, ${array[*]} will get split. Try something like a=(foo bar) and ls -l "${a[*]}" with and without quotes – ilkkachu Feb 26 at 18:05
  • Or all concatenated, and then the combination word-split, it's really the same.... unless $IFS is set to the empty string, in which case you'll see the behaviour varies between shells (or at least used to, it seems it's more consistent nowadays, now that has been clarified by POSIX). – Stéphane Chazelas Feb 26 at 18:42
  • @StéphaneChazelas, oho, hups, forgot to think about empty IFS – ilkkachu Feb 26 at 18:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.