2

Whenever I try to execute the following shell command , it works properly .

convert maanavulu_GIST-TLOTKrishna.tif -alpha set -matte -virtual-pixel transparent -set option:distort:viewport 1000x1000 -distort perspective-projection '1.06,0.5,0,0,1.2,0,0,0' -trim 1.jpg

But , whenever I try assign the command to a variable and then execute it , it reports the following error .

convert.im6: invalid argument for option PerspectiveProjection : 'Needs 8 coefficient values' @ error/distort.c/GenerateCoefficients/873.
Deepesh
  • 99
  • 2
  • 11
  • 3
    `whenever I try assign the command to a variable and then execute it` How are you doing it, can you show code? – anubhava Jul 09 '14 at 16:23
  • 2
    What exactly do you mean by "assign the command to a variable and then execute it". There are various problems with things like `cmd="..."; $cmd`: see http://mywiki.wooledge.org/BashFAQ/050. – chepner Jul 09 '14 at 16:24
  • possible duplicate of [How to execute a bash command stored as a string with quotes and asterisk](http://stackoverflow.com/questions/2005192/how-to-execute-a-bash-command-stored-as-a-string-with-quotes-and-asterisk) – Barmar Jul 09 '14 at 16:25

3 Answers3

3

The short of it: it's best to:

  • store your arguments in an array
  • not including the command itself, for safety (preferable to an eval solution)
  • then invoke the command with the array
# Store options in array - note that the filenames are excluded here, too,
# for modularity
opts=(-alpha set -matte -virtual-pixel transparent -set option:distort:viewport \
      1000x1000 -distort perspective-projection '1.06,0.5,0,0,1.2,0,0,0' -trim)

# Invoke command with filenames and saved options
convert maanavulu_GIST-TLOTKrishna.tif "${opts[@]}" 1.jpg

Afterthought: As @konsolebox and @chepner point out: using a function is probably the best choice (clear separation between fixed and variable parts, encapsulation, full range of shell commands available).

mklement0
  • 382,024
  • 64
  • 607
  • 775
1

The proper way to assign-and-execute a command is to use an array:

COMMAND=(convert maanavulu_GIST-TLOTKrishna.tif -alpha set -matte -virtual-pixel transparent -set option:distort:viewport 1000x1000 -distort perspective-projection '1.06,0.5,0,0,1.2,0,0,0' -trim 1.jpg)

Then execute it:

"${COMMAND[@]}"

I like eval but it's definitely not the solution this time.

And just a tip: If you can use a function, use a function. And quote your arguments properly.

konsolebox
  • 72,135
  • 12
  • 99
  • 105
  • 1
    I think the function is a much better idea. (You can include more complex shell syntax in the body of a function; an array is limited to the name of the command and arguments: no pipes, no lists, no redirections, etc.) – chepner Jul 09 '14 at 17:28
0

Quotes are not processed after expanding a variable. The only processing that occurs is word splitting and wildcard expansion. If you need to perform all the normal steps of command execution, you have to use eval:

eval "$variable"
Barmar
  • 741,623
  • 53
  • 500
  • 612
  • 1
    I wouldn't recommend using `eval` without knowing exactly what the OP is doing. – chepner Jul 09 '14 at 16:25
  • Although I'd prefer if he'd actually shown code, I'm pretty sure I understand what he's trying to do. – Barmar Jul 09 '14 at 16:26
  • There are better ways of storing command line in a variable and executing it. – anubhava Jul 09 '14 at 16:31
  • @anubhava Please post an answer showing the better ways. – Barmar Jul 09 '14 at 16:31
  • No, I don't want to post an answer unless OP shows the code as I suggested in my comment on the question. – anubhava Jul 09 '14 at 16:37
  • 1
    If `variable` is unverified input from an external source, using `eval` is dangerous. If `variable` is just set locally as a way of refactoring code, defining a shell function is better idea. `eval` is (or should be) a command of last resort, not a convenience. – chepner Jul 09 '14 at 17:26