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.configas separate arguments-runand.configThe 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.- See this answer for details.
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.
- As an aside: Your call,
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
