powershell 不会将变量扩展为参数

powershell not expands variable as argument

我在 powershell 脚本中执行以下命令:

$boostPath = "D:/lib/boost/1.62.0-vs2013-x64"
cmake -S $cmakeRootPath -B $buildPath -G $cmakeGenerator -DBOOST_ROOT=$boostPath

这样变量 $boostPath 就不会展开。我可以在 FindBoost log

中看到
-- [ C:/Program Files/CMake/share/cmake-3.18/Modules/FindBoost.cmake:1528 ] BOOST_ROOT = "$boostPath"

相反,如果在我编写的脚本中

cmake -S $cmakeRootPath -B $buildPath -G $cmakeGenerator -DBOOST_ROOT="D:/lib/boost/1.62.0-vs2013-x64"

变量设置正确,cmake 工作。如何使用变量正确给出参数?

Mathias R. Jessen在评论中给出了要害指针:

诸如 -DBOOST_ROOT=$boostPath 的标记被 PowerShell 解析为 文字 - $boostPath 变量引用是 而不是 已识别,因此未扩展(由其值替换)。

this GitHub issue.

总结了 PowerShell 有时使用未加引号的复合令牌的令人惊讶的行为

如果 $boostPath 包含 没有空格[=76,则以下内容应该 通常 工作并且 绝对 工作=]:

cmake -S $cmakeRootPath -B $buildPath -G $cmakeGenerator -DBOOST_ROOT="$boostPath"

变量引用的双引号强制其扩展。

:

  • 由于 PowerShell 在幕后执行重新引用,仅在需要时保留双引号(可能从单引号转换而来)(参见 )并且您的路径不包含空格,cmake 将在命令行上看到的是逐字
    -DBOOST_ROOT=D:/lib/boost/1.62.0-vs2013-x64 - 没有引号。

  • 如果 $boostPath did 包含空格,例如 $boostPath = "D:/lib 1/boost/1.62.0-vs2013-x64",PowerShell 将双引号参数 as一个整体,这样cmake在命令行上看到的就是逐字的
    "-DBOOST_ROOT=D:/lib 1/boost/1.62.0-vs2013-x64"

    • 如果 cmake on Windows[1] 确实需要 "..." 仅在 $boostPath 值附近(不幸的是,某些 CLI,特别是 msiexec,需要),请使用此 解决方法 (为简洁起见,省略了一个参数):
cmake -S $cmakeRootPath -B $buildPath -DBOOST_ROOT="`"$boostPath`""

警告:如果 PowerShell 破坏(重新)引用传递给外部程序的参数(参见 ) should ever get fixed (see this GitHub issue),此解决方法将 破坏.


[1] 只有在 Windows 上,(控制台)程序才需要自己将整个 命令行 解析为单独的参数;在 类 Unix 平台上,他们明智地接收 array verbatim 令牌。