注意:此答案最初是针对 Windows Powershell needs to print out information for a particular command regardless of whether it successfully executed or Not 的重复问题发布的。
补充和详述Michael Sorens' helpful answer:
有限制,你可以使用Set-PSDebug -Trace 1让PowerShell在脚本语句执行前为你回显;然而,这更像bash 的set -o verbose / set -v 选项而不是set -o xtrace / set -x,因为回显的命令是未扩展的;详情如下:
# Start tracing statements.
Set-PSDebug -Trace 1
try
{
# Sample command
cmd /c echo 'hi there' $HOME
}
finally {
Set-PSDebug -Trace 0 # Turn tracing back off.
}
以上产出:
DEBUG: 4+ >>>> cmd /c echo 'hi there' $HOME
"hi there" C:\Users\jdoe
DEBUG: 6+ >>>> Set-PSDebug -Trace 0 # Turn tracing off.
虽然这种方法几乎不需要额外的努力,但它的局限性是:
-
您无法控制跟踪语句的前缀。 (例如DEBUG: 4+ >>>> ,其中4 是行号。
-
关闭回溯关闭总是会产生一个追踪语句。
-
没有办法捕获或抑制跟踪输出 - 它总是打印到主机(控制台);但是,您可以通过 PowerShell 的 CLI 从 外部 PowerShell 捕获它 - 请参阅 this answer。
-
从 PowerShell 7.2 开始,使用续行符跨越多行的命令只会回显它们的 第一 行(请参阅 GitHub issue #8113)。
-
也许最重要的是,回显的语句是它们的字面源代码表示,因此可以包含未扩展的变量引用和表达式,例如上例中的$HOME。
-
GitHub issue #9463 建议扩展 值(即,变量和表达式用它们的值替换),例如在
bash 中使用set -x。
- 虽然这对于调用 外部程序 是可行的 - 无论如何,其参数总是 strings,但挑战在于调用 PowerShell 命令 支持任意 .NET 类型的参数,并非所有的参数都具有忠实的字符串文字表示;也就是说,即使是仅用于人类眼球的字符串表示也可以说比 未扩展 值更可取。
如果您需要查看扩展参数值和/或控制输出格式/目标:
注意:
-
虽然 Invoke-Expression (iex) should generally be avoided,但由于其固有的安全风险以及通常有更好、更安全的选择,它确实提供了一个解决方案 - 与往常一样,请确保您完全控制传递给Invoke-Expression的字符串中的内容,以避免潜在的不需要的命令注入。
-
解决方案要求您构造字符串以传递给Invoke-Expression,并使用预先扩展(字符串插值),以便生成的命令行在执行时仅包含文字参数,以便回显命令行可以全面了解调用的可执行文件及其参数是什么。
- 如上所述,这只有在您调用外部程序(例如
msbuild)时才可能实现。
首先,定义一个辅助函数,它接受一个命令行字符串,回显它,然后通过Invoke-Expression 执行它:
# !! IMPORTANT:
# !! Only pass *trusted* strings to this function - the
# !! argument is blindly passed to Invoke-Expression.
function Invoke-AfterEchoing {
param([string] $commandLine)
# Echo the command line to be executed,
# using the verbose output stream in this example:
Write-Verbose -Verbose "Executing: $commandLine"
Invoke-Expression $commandLine
}
现在您可以构建命令行字符串并将它们传递给辅助函数:
Invoke-AfterEchoing @"
& "$msbuild" .\blabBlah.csproj /t:Clean
"@
Invoke-AfterEchoing @"
& "$msbuild" .\blabBlah.csproj /t:Build /p:Configuration=Dev
"@
注意:
输出将如下所示:
VERBOSE: Executing: & "C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\MSBuild\Current\Bin" .\blabBlah.csproj /t:Clean
# ... (output)
VERBOSE: Executing: & "C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\MSBuild\Current\Bin" .\blabBlah.csproj /t:Build /p:Configuration=Dev
# ... (output)