1

I'd like to perform a complicated bash command, using data fed from a long array as arguments. I guess it has to use a subshell in some way.

For example, instead of the workable convert -size 100x100 xc:black -fill white -draw "point 1,1" -draw "point 4,8" -draw "point 87,34" etc etc etc image.png

I want to employ a different logic where the arguments are given in the same command, more like

convert -size 100x100 xc:black -fill white $(for i in 1,1 4,8 87,34 etc etc; -draw "point $i"; done) image.png which doesn't work, as the $i is interpreted as a command insted of an argument.

Please note that "for i in ...; do convert ...$i...; done" will not work. The -draw "point x,y" series of arguments must be in the same single run convert command, as convert doesn't accept -draw parameter in existing images.

Voprosnik
  • 195
  • 1
  • 9

4 Answers4

3

Build up an array of -draw arguments first.

for pt in 1,1 4,8 87,34; do
    points+=(-draw "point $pt")
done
convert -size 100x100 xc:black -fill white "${points[@]}" image.png
chepner
  • 497,756
  • 71
  • 530
  • 681
0

You can keep your command line short and clean by pumping MVG drawing commands into convert via its stdin by using the @ file specifier followed by a dash representing stdin like this:

for i in 1,1 4,8 87,34; do 
   echo point $i
done | convert -size 100x100 xc:red -draw @- result.png

enter image description here

Or, if you have an array called points:

points=(1,1 4,8 87,34)

printf "point %s\n" ${points[@]} | convert -size 100x100 xc:red -draw @- result.png
Mark Setchell
  • 191,897
  • 31
  • 273
  • 432
-1

What about using printf to expand the content?

points=(1,1 4,8 87,34)
printf -- '-draw "point %s" ' ${points[@]}

returns the following string (without a new line at the end):

-draw "point 1,1" -draw "point 4,8" -draw "point 87,34"

You can say:

points=(1,1 4,8 87,34)
convert ... "$(printf -- '-draw "point %s" ' ${points[@]})" image.png
#           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

This way, you store the points in an array and printf "delivers" it to the convert command.

fedorqui
  • 275,237
  • 103
  • 548
  • 598
  • Thank you, however the syntax is `-draw "point x,y"` with a dash. When I try `printf '-draw ...'` printf recognises it as a -d option and returns an error. I tried to work around it with the syntax `printf ' -draw ...'` and then, I don't know why, convert recognises it as a filename and returns `convert: unable to open image ` -draw "point etc etc` – Voprosnik Apr 26 '16 at 12:04
  • @Voprosnik the way to avoid `printf` understand `-d` as an option is to add `--` after it, so it knows no more arguments are given --> `printf -- '-draw "point %s" ' ${points[@]}`. – fedorqui Apr 26 '16 at 12:35
-1

Try to use expansion instead of subshell like this:

echo -draw\ \"point\ {1\,1,2\,2,3\,3}\"

produces this output:

-draw "point 1,1" -draw "point 2,2" -draw "point 3,3"
Vrata Blazek
  • 464
  • 3
  • 12
  • This makes `-draw "point 1,1"` a single argument, not two separate arguments `-draw` and `point 1,1` that `covert` will expect. – chepner Apr 26 '16 at 12:16