使用带有equals和period的single-hypen参数执行外部命令

问题描述 投票:6回答:2

我有一个接受这样的参数的工具(例如在test.ps1中):

foo.exe -name="john"

因此,每个参数都用一个连字符-,名称,等于=,然后是参数的值来指定。

当我从PowerShell调用这个确切的表达式时,它会毫无问题地执行。但是,当其中一个值包含像这样的句点.时:

foo.exe -name="john.doe"

运行它会导致语法错误:

$ ./test.ps1字符串开始:在test.ps1:1 char:24 + foo.exe -name =“john.doe <<<<”缺少终结符:“。在test.ps1:1 char: 25 + foo.exe -name =“john.doe”<<<< + CategoryInfo:ParserError:(:String)[],ParseException + FullyQualifiedErrorId:TerminatorExpectedAtEndOfString

我可以阻止PowerShell解释这一点的一些方法是:

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

但是,其中一些选项会阻止变量插值。还有其他方法可以阻止PowerShell导致语法问题吗?在这个特定的实例中(添加句点),为什么PowerShell有解释这个问题?

powershell powershell-v2.0
2个回答
4
投票

你看到的是PSv2中的一个错误;简而言之:如果在-中包含.,则以不带引号的"..."开头的参数会破解解析。

PowerShell v5.1 / PowerShell Core v6.0.1中仍然存在较小的错误变体;它一直是reported on GitHub。现在,.内部的"..."工作正常,但是一个不带引号的.实际上打破了两个论点。下面的解决方法对于所述变化也是有效的 - 参见我的this answer

解决方法是引用整个参数:

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

请注意,通常不需要单独引用值部分 - 即,对目标程序, -name="john.doe 1"通常与"-name=john.doe 1"相同


0
投票

我之前遇到过这种情况,我不知道它是否是绕过它的最好方法,但我以前做过的一种方法是构建执行命令字符串,然后使用Invoke-Expression执行它。

$MyCommand = '& foo.exe --% -name="{0}"' -f 'john.doe'
Invoke-Expression $MyCommand

或者,更具体到我的问题,我会有几个参数可以改变我在哈希表中的,所以我会添加到命令。在您的命令的上下文中,我可能有:

$MyArgs = @{
    name = 'john.doe'
    request = 'delete file'
    argument = '\jdoe\temp\nsfwstash.zip'
}
$MyCommand = '& foo.exe --%'
$MyArgs.Keys | ForEach{
    $MyCommand = $MyCommand + (' {0}="{1}"' -f $_, $MyArgs[$_])
}
Invoke-Expression $MyCommand

这最终会调用一个读取的命令:

& foo.exe --% -name="john.doe" -request="delete file" -argument="\jdoe\temp\nsfwstash.zip"
© www.soinside.com 2019 - 2024. All rights reserved.