无论是否成功执行,Windows Powershell 都需要打印出特定命令的信息 [英] Windows Powershell needs to print out information for a particular command regardless of whether it successfully executed or Not

查看:106
本文介绍了无论是否成功执行,Windows Powershell 都需要打印出特定命令的信息的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

说到 Powershell,我是新手之王.我想创建在执行各种命令时更加冗长的 Powershell 脚本.

I'm king of novice when it comes to Powershell. I wanted to create Powershell scripts that are more verbose as it executes various commands.

例如在下面的代码中,我希望它清楚地显示它在做什么,并且无论命令是否成功执行,我都希望它打印出有问题的命令的执行结果:

For example in the following code, I want it to clearly display what it doing, and regardless of whether the command was executed successfully Or Not, I want it to print out the results of the execution of the command in question:

导入模块 IIS 管理

Import-Module IISAdministration

停止网站ArtemisDEV"

Stop-WebSite 'ArtemisDEV'

$a = ".\blabBlah.csproj/t:Clean";调用表达式$msbuild $a"

$a = ".\blabBlah.csproj /t:Clean" Invoke-Expression "$msbuild $a"

$b = ".\blabBlah.csproj/t:Build/p:Configuration=Dev";调用表达式$msbuild $b"

$b = ".\blabBlah.csproj /t:Build /p:Configuration=Dev" Invoke-Expression "$msbuild $b"

有人可以修改上述代码,并显示它会打印出更详细的输出语句吗?

Could someone please modify the aforementioned code, and show it such a way that it will print out more verbose output statements?

推荐答案

有限制,您可以使用 Set-PSDebug -Trace 1 让 PowerShell 回显脚本语句在他们被处决之前你:

With limitations, you can use Set-PSDebug -Trace 1 to let PowerShell echo script statements for you before they are executed:

# 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.

虽然这种方法几乎不需要额外的努力,但它的局限性是:

While this approach requires little extra effort, its limitations are:

  • 您无法控制跟踪 statemetns 的前缀.(例如 DEBUG: 4+ >>>> ,其中 4 是行号.

关闭跟踪关闭总是会产生一个跟踪语句.

Turning tracing back off invariably also produces a tracing statement.

没有办法捕获或抑制跟踪输出 - 它总是打印到主机(控制台).

There's no way to capture or suppress the tracing output - it invariably prints to the host (console).

也许最重要的是,被响应的语句是它们的文字源代码表示,因此可以包含未扩展变量引用和表达式,例如上例中的 $HOME.

Perhaps most importantly, the statements being echoed are their literal source-code representations and can therefore contain unexpanded variable references and expressions, such as $HOME in the example above.

  • GitHub 问题 #9463 建议扩展值(即,变量和表达式用它们的值替换了 _),例如在 bash 中使用 set -x 会得到.
  • 虽然这对于调用外部程序是可行的——无论如何,其参数总是字符串,但挑战在于对PowerShell命令的调用支持任意 .NET 类型的参数,并非所有类型都具有忠实的字符串文字表示;也就是说,即使是仅用于人类眼球的字符串表示也可以说比 未扩展 值更可取.
  • GitHub issue #9463 proposes that expanded values (i.e., variables and expressions replaced _by their values), as you would get with set -x in bash, for instance.
  • While this is feasible for calls to external programs - whose arguments are invariably strings anyway, the challenge is that calls to PowerShell commands supports arguments of arbitrary .NET types, not all of which have a faithful string-literal representation; that said, even a for-human-eyeballs-only string representation is arguably preferable to unexpanded values.

如果您需要查看扩展参数值和/或控制输出格式/目标:

If you need to see expanded argument values and/or control the output format / target:

注意:

  • 虽然Invoke-Expression (iex)通常应该避免,由于其固有的安全风险,并且因为通常有更好、更安全的选择,它确实在这里提供了一个解决方案 - 一如既往,确保您完全控制传递给 Invoke-Expression 的字符串中的内容,以避免可能注入不需要的命令.

  • While Invoke-Expression (iex) should generally be avoided, due to its inherent security risks and because better, safer options are usually available, it does offer a solution here - as always, be sure that you fully control what goes into the string passed to Invoke-Expression, to avoid potential injection of unwanted commands.

该解决方案要求您使用前置扩展(字符串插值)构造要传递给Invoke-Expression的字符串,以便生成的命令行在执行时仅包含文字参数,因此回显命令行可以描绘调用可执行文件及其参数的全貌.

The solution requires you to construct the string to pass to Invoke-Expression with up-front expansion (string-interpolation), so that the resulting command line, when executed, only contains literal arguments, so that echoing the command line paints the full picture of what executable is invoked and what its arguments are.

  • 如上所述,这只有在您调用外部程序(例如msbuild)时才有可能实现.
  • As noted above, this is only robustly possible if you're calling an external program, such as msbuild.

首先定义一个辅助函数,它接受一个命令行字符串,回显它,然后通过Invoke-Expression执行它:

First, define a helper function that accepts a command-line string, echoes it, and then executes it via 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

}

现在您可以构建命令行字符串并将它们传递给辅助函数:

Now you can construct your command-line strings and pass them to the helper function:

Invoke-AfterEchoing @"
& "$msbuild" .\blabBlah.csproj /t:Clean
"@


Invoke-AfterEchoing @"
& "$msbuild" .\blabBlah.csproj /t:Build /p:Configuration=Dev
"@

注意:

  • 一个可扩展的here-string (@"..."@) 用于简化字符串-内部引用.

  • A expandable here-string (@"<newline>...<newline>"@) is used to simplify the string-internal quoting.

  • 选择可扩展形式以确保可执行路径和所有参数预先扩展,因此作为它们的文字值嵌入在结果字符串,以便回显字符串将显示所有实际值.
  • The expandable form is chosen to ensure that the executable path and all arguments are expanded up front and therefore embedded as their literal values in the resulting string, so that echoing the string will show all actual values.

&调用运算符,用于调用msbuild,这在语法上是必要的,因为它的路径被引用,如果 $msbuild 包含一个路径带空格,那么这又是必需的.

&, the call operator, is used to invoke msbuild, which is syntactically necessary, given that its path is passed quoted, which in turn is necessary if $msbuild contains a path with spaces.

输出将如下所示:

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)

这篇关于无论是否成功执行,Windows Powershell 都需要打印出特定命令的信息的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆