从批处理脚本返回变量值到 powershell

问题描述 投票:0回答:1

我有一个无法更改的批处理脚本,因为它属于另一个应用程序。我想从 Powershell 调用该批处理脚本并访问变量值。这看起来是一个范围问题,也许我没有正确调用批处理脚本。我试过“&”、“invoke-expression”、“cmd /c”和“start-process”,但结果是一样的。这是简化的问题。

我有一个名为 batch.bat 的批处理脚本,其中包含两行:

set /p variable=what is the fruit:
echo %variable%    (from batch)

我有一个 powershell 脚本包含:

$fp=resolve-path(".\batch.bat")
Invoke-Expression -Command "$fp"
write-host "$env:variable    (from PS)"

来自命令提示符:

set variable=banana
powershell .\script.ps1
what is the fruit: orange
orange    (from batch)
banana    (from PS)

我希望橙色可以用于PS。如果我没有将变量预设为banana,那么PS将不会显示任何内容,因此它与预设值无关。我考虑过我可以编写另一个包装命令脚本来执行原始批处理脚本,然后将所有变量(以 PS 格式)写出到一个临时 .ps1 文件中,然后执行(点源)但它看起来很笨拙。

powershell batch-file cmd
1个回答
1
投票

从 PowerShell 调用批处理文件必然会在 child process 中执行批处理文件,因为必须启动

cmd.exe
child process 才能执行它。

子进程根本无法修改其 caller 的环境变量。

您最好的选择是通过

cmd.exe /v /c
显式调用批处理文件,然后 echo 感兴趣的环境变量的 values,这允许 PowerShell 捕获它们:

$variableValue = cmd /v /c '.\batch.bat >&2 & echo !variable!'
"Value of %variable%: $variableValue"
  • /v
    需要启用 delayed 变量扩展,这允许
    echo
    命令是调用
    .\batch.bat
    的同一语句的一部分动态报告后者设置的值,使用
    !...!
    而不是比
    %...%
    包含变量引用。

    • 请注意,这会影响
      .\batch.bat
      的执行,因为
      !
      字符然后变成 元字符,除非它们故意包含变量引用 - 被悄悄删除.
  • >&2
    用于将
    .\batch.bat
    的 stdout 输出重定向到 stderr(流
    2
    ),以便它仍然显示,但不会干扰
    cmd /v c
    输出到 stdout 的内容,这就是PowerShell 捕获。


如果要回显批处理文件退出后存在的 all 变量,作为

<name>=<value>
对,您使用以下内容,它通过 ConvertFrom-StringData
 将名称-值对解析为单个 
hasthable
:

# Assign to a variable ($hash = ...) as needed.
(cmd /c '.\batch.bat >&2 & set' | Out-String) -replace '\\', '\\' |
  ConvertFrom-StringData
© www.soinside.com 2019 - 2024. All rights reserved.