Home > Net >  Escape the period character in a command flag within a PowerShell script?
Escape the period character in a command flag within a PowerShell script?

Time:03-09

I have a command similar to the following that I need to run as part of a PowerShell script:

gfpca -run.config default.conf

However, I receive the error Command not found: .conf on the output. This happens if I run with Invoke-Expression as well. I have also tried escaping the character, but don't see a difference:

Invoke-Expression('gfpca -run`.config default.conf')

How can I run this command within PowerShell?

CodePudding user response:

Use the & invocation operator to invoke the program and use regular ' single-quotes to qualify the argument boundaries:

& gfpca '-run.config' 'default.conf'

Now, PowerShell will pass -run.config and default.conf to gfpca as-is without attempting to interpret them as native parameters

CodePudding user response:

tl;dr

Due to an unfortunate bug, present up to at least PowerShell 7.1.2, escaping or quoting of the argument that starts with - and contains . is required, which in the simplest case means:

# Note the ` before -
gfpca `-run.config default.conf

Mathias R. Jessen's answer provides an effective solution, but let me add some context:

  • You only need to escape or quote one of your arguments, -run.config, due to a PowerShell bug, where passing an unquoted argument that starts with - and contains a . to an external program is mistakenly passed as two arguments.

    • In other words: Without escaping or quoting such an argument (see below), PowerShell mistakenly passes -run.config as separate arguments -run and .config

    • The bug, present up to at least PowerShell 7.2.1, has been reported in GitHub issue #6291, where it was acknowledged as such, but is awaiting a fix; it is one of several bugs relating to --prefixed tokens.

  • While using &, the call operator, unconditionally for command invocations is a robust approach, it is important to note that it is only necessary if the command name or path is quoted and/or contains variable references - which isn't the case here.

  • Invoke-Expression (iex) should generally be avoided - see this answer. Specifically, do not use it to invoke an external program or PowerShell script - see this answer.

    • As an aside: Your call, InvokeExpression('...'), uses pseudo method syntax, which is to be avoided: PowerShell functions, cmdlets, scripts, and external programs must be invoked like shell commands - Invoke-Expression '...' - not like C# methods. That is, don't put ((...) around the argument list, and separate argument with whitespace, not with ,. See this answer for more information.

While ` (PowerShell's escape character), which you tried to use, is (a) key to the solution, it must be applied to the initial -, which prevents PowerShell from (inappropriately) parsing the argument according to the rules of PowerShell-native parameter names.[1]

# Note the ` before - 
gfpca `-run.config default.conf

As shown in Mathias' answer, using a quoted string around the whole argument (e.g. '-run.config') is another alternative.


[1] Because parameter names aren't expected to require escaping, what follows - is parsed verbatim, up to the first .. Therefore, your attempt to `-escape the . character was ineffective: ` wasn't recognized as an escape character and therefore retained, and the bug still kicked in. By contrast, `-escaping the initial - prevents PowerShell from parsing the entire token as a parameter, which bypasses the bug

  • Related