Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Execute external command with single-hypen parameter with equals and period

I have a tool that accepts parameters like this (e.g. in test.ps1):

foo.exe -name="john"

So, each parameter is specified with a single hyphen -, the name, an equals =, and then the value of the parameter.

When I invoke this exact expression from PowerShell, it executes without any problems. However, when one of the values contains a period . like this:

foo.exe -name="john.doe"

Running it causes a syntax error:

$ ./test.ps1 The string starting: At test.ps1:1 char:24 + foo.exe -name="john.doe <<<< " is missing the terminator: ". At test.ps1:1 char:25
+ foo.exe -name="john.doe" <<<<
+ CategoryInfo : ParserError: (:String) [], ParseException
+ FullyQualifiedErrorId : TerminatorExpectedAtEndOfString

Some ways that I can prevent PowerShell from interpreting this are:

  • foo.exe "-name=`"john.doe`""
  • foo.exe '-name="john.doe"'
  • PowerShell V3+: foo.exe --% -name="john.doe"
  • $nameArg = "john.doe"; foo.exe -name="$nameArg"

However, some of these options prevent interpolation of variables. Are there other ways to stop PowerShell from causing syntax issues? In this specific instance (adding the period), why is PowerShell having issues interpreting this?

like image 233
TheCloudlessSky Avatar asked Mar 05 '18 19:03

TheCloudlessSky


1 Answers

What you're seeing is a bug in PSv2; in short: an argument that starts with unquoted - breaks parsing if it also contains a . within "...".

A milder variation of the bug still exists in PowerShell v5.1 / PowerShell Core v6.0.1; it has been reported on GitHub. Now, a . inside "..." works fine, but an unquoted . actually breaks the argument in two. The workaround below is also effective for said variation - see this answer of mine.

The workaround is to quote the entire argument:

# Use '...' instead if you don't need interpolation
foo.exe "-name=john.doe"

Note that there is typically no need to quote the value part individually - that is, to the target program,
-name="john.doe 1" is usually the same as "-name=john.doe 1"

like image 71
mklement0 Avatar answered Sep 25 '22 04:09

mklement0