【问题标题】:How can I pass batch arguments with dots into a powershell script?如何将带有点的批处理参数传递到 powershell 脚本中?
【发布时间】:2014-10-28 17:42:31
【问题描述】:

我有一个批处理脚本,它将由不受我控制的外部进程运行。外部进程可以为批处理脚本提供可变数量的参数。然后,我想将这些变量传递给 powershell 脚本。问题是,其中一些变量看起来像:

-Dfoo.bar=baz

Powershell 出于某种原因将其分成两个参数。在命令行上,我可以在 arg 周围添加引号并收工。但是我如何让批次以这种方式通过呢?这是我的脚本:

@echo off
SET CMD=C:\Scripts\foo.ps1

PowerShell.Exe -Command "%CMD%" %*

我注意到这个问题与this one 非常相似。在这里,他正在逃避 $ 字符。我尝试为点和/或破折号做类似的事情,但没有运气。有人有什么想法吗?

【问题讨论】:

  • 我在 mvn 命令中遇到了同样的问题:mvn ... -DgroupId=x.y ...,它产生了一个奇怪的错误 Unknown lifecycle phase ".y"。那是我决定使用 cmd ...

标签: windows powershell batch-file


【解决方案1】:

如果你从 CMD 调用你的脚本,它就可以正常工作:

C:\>.\foo.bat -Dfoo.bar=baz
args are -Dfoo.bar=baz

要解决从 PowerShell 运行批处理脚本时出现的问题,请使用 stop parsing operator --% 例如:

C:\ PS> .\foo.bat --% -Dfoo.bar=baz
args are -Dfoo.bar=baz

【讨论】:

  • 哪个 PowerShell 版本?我有 OP 使用 PowerShell v3 描述的确切行为,从 CMD 运行批处理脚本。
  • 我正在针对 Powershell 2.0 进行编程,因为我认为让我的队友从他们的默认值升级有点过分。就像@AnsgarWiechers 所说,即使从 cmd 运行它也会表现出这种行为。此外,不幸的是, --% 技巧不起作用。 :( 听起来像是微软添加的东西,因为人们遇到了这个问题。
  • @AnsgarWiechers 我在 Win 8.1 上运行 v4。
  • @JasonThompson 是的,它的存在正是出于这个原因,但它仅在您使用 PowerShell 启动时才有效。
【解决方案2】:

这样的事情可能会奏效:

@echo off

set "CMD=C:\Scripts\foo.ps1"
set "ARGS=%*"
set "ARGS=%ARGS: =' '%"

PowerShell.Exe -Command "%CMD%" '%ARGS%'

演示:

C:\>type test.cmd
@echo off

set "CMD=C:\test.ps1"
set "args=%*"
set "args=%args: =' '%"
powershell -Command "%CMD%" '%args%'

C:\>type test.ps1
$args | % { $_ }

C:\>test.cmd -Dfoo.bar=baz -something
-Dfoo.bar=baz
-something

参数周围的单引号可防止 PowerShell 使用该参数做一些时髦的事情。通过用' ' 替换参数列表中的空格,您可以在一个参数之后和下一个参数之前放置单引号。变量周围的“外部”单引号在第一个参数之前和最后一个参数之后添加缺少的引号。

C:\>type test2.cmd
@echo off
set "args=%*"
echo %args%
set "args=%args: =' '%"
echo %args%
echo '%args%'

C:\>test2.cmd -Dfoo.bar=baz -something
-Dfoo.bar=baz -something
-Dfoo.bar=baz' '-something
'-Dfoo.bar=baz' '-something'

【讨论】:

  • 这就是我要使用的,但我认为如果其中一个 args 中有空格,它不会起作用。 :(
  • 问题是,CMD 将=,; 视为delimiters 就像空格一样,所以没有简单而完整的方法来处理这个问题。您需要一个成熟的解析器来处理所有情况。
【解决方案3】:

要将内容作为文字传递,您可以将它们括在单引号中。我的建议是为您的参数执行此操作,然后在 PowerShell 中将它们分解一次,然后将它们发送到您的命令中。

@echo off
SET CMD=C:\Scripts\foo.ps1

PowerShell.Exe -Command "%CMD%" '%*'

然后在 Powershell 中:

Param($PassedArgs)
$SplitArgs = $PassedArgs.trim("'").split(" ")
SomeCommand @SplitArgs

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-09-15
    • 2013-02-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多