1

I have to convert a UNIX Shell script to a powershell script. This script runs a conversion on ImageMagick. When I try to execute the following code:

$convertcmd="convert $dir\tmpI.mpc `(-clone 0 $process `)`(-clone 0 -channel $color2 -separate -threshold $high% $tapering `) -compose over -composite `"$outfile`"" Invoke-Expression -Command $convertcmd 

I keep getting

Invoke-Expression : Missing expression after unary operator '-'. At C:\test\xxxxx.ps1:189 char:21 + Invoke-Expression <<<< -Command $convertcmd + CategoryInfo : ParserError: (-:String) [Invoke-Expression], ParseException + FullyQualifiedErrorId : MissingExpressionAfterOperator,Microsoft.PowerShell.Commands.InvokeExpressionCommand 

The resulting string that $convertcmd becomes

convert .\COLORBALANCE\tmpI.mpc (-clone 0 -channel blue -level 0x98% +channel)(-clone 0 -channel blue -separate -threshold 18.9338% ) -compose over -composite /imagemagick/workarea/out/after.jpg 

I suspect its the parens as intellisense in PowerGUI gives me the same error on the (-clone... part of the statement. I've tried looking up how to escape parens, and backslashes (similar to the Unix Shell code) aren't working, neither are ` characters.

2 Answers 2

2

When you call Invoke-Expression, the contents of the string you pass in are treated as a Powershell script expression. This means that the contents of the parenthesis pairs are treated as script expressions. Since you're using a double-quoted string - "...", the backticks are being interpreted and removed before assigning to the $convertcmd variable.

You can escape your backticks so that they will remain escaped in the string when passing it to Invoke-Expression:

$convertcmd="convert $dir\tmpI.mpc ``(-clone 0 $process ``)``(-clone 0 -channel $color2 -separate -threshold $high% $tapering ``) -compose over -composite `"$outfile`"" 

Or you can escape the parentheses after assigning to the variable:

$convertcmd="convert $dir\tmpI.mpc (-clone 0 $process ) (-clone 0 -channel $color2 -separate -threshold $high% $tapering ) -compose over -composite `"$outfile`"" $convertcmd = $convertcmd.Replace('(', '`(').Replace(')', '`)') iex $convertcmd 

Or you can enclose your command in a script block and execute it with &:

 $convertcmd = {convert $dir\tmpI.mpc `(-clone 0 $process `)`(-clone 0 -channel $color2 -separate -threshold $high% $tapering `} & $convertcmd 

If you are using Powershell v3, you can also instead make Powershell interpret the whole string after the executable name as a command string by putting --% before the argument portion of your command:

$convertcmd="convert --% $dir\tmpI.mpc `(-clone 0 $process `)`(-clone 0 -channel $color2 -separate -threshold $high% $tapering `) -compose over -composite `"$outfile`"" 

Or in any version of Powershell, you can let cmd interpret the string:

$convertcmd="convert $dir\tmpI.mpc `(-clone 0 $process `)`(-clone 0 -channel $color2 -separate -threshold $high% $tapering `) -compose over -composite `"$outfile`"" iex "cmd /c '$convertcmd'" 
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you! That was the issue.
0

Does this help?

$dir = '.\COLORBALANCE' $process = 'PROCESS' $color2 = 'BLUE' $high = '98' $threshold = 'THRESHOLD' $tapering = 'TAPERING' $outfile = '/imagemagick/workarea/out/after.jpg' $insert = @($dir,$process,$color2,$high,$tapering,$outfile) $convertcmd= 'convert {0}\tmpI.mpc (-clone 0 {1} )(-clone 0 -channel {2} -separate -threshold {3}% {4} ) -compose over -composite "{5}"' $convertcmd -f $insert convert .\COLORBALANCE\tmpI.mpc (-clone 0 PROCESS )(-clone 0 -channel BLUE -separate -threshold 98% TAPERING ) -compose over -composite "/imagemagick/workarea/out/after.jpg" 

2 Comments

Not sure what some of those variables are supposed to look like, so I made some stuff up.
Thanks, but its doing the same thing. The problem is, Powershell uses parens to group commands. Parens in the ImageMagick convert command mean "...and now do this" so you can do more than one process in a single command. Powershell sees the content inside the parens as incomplete. To Powershell, it looks like command switches without a command. I've tried escaping the parens, but then ImageMagick treats it like part of the image filename and that's wrong. I might just have to separate each convert process into it's own command.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.