【问题标题】:How to get PowerShell to display the commands being called如何让 PowerShell 显示被调用的命令
【发布时间】:2016-05-13 00:48:18
【问题描述】:

我有一个从 Jenkins 调用的简单 PowerShell 脚本:

function PerformRepoActions($localRepo)
{
  $startDir = $pwd.path
  cd $localRepo
  hg recover
  hg revert --all
  hg pull -r $branch --rebase
  hg update -r $branch
  cd $startDir
}

$branch = $env:NAMEDBRANCH
PerformRepoActions $pwd.path 

当我运行它时,它不会显示我正在制作的任何 mercurial 命令。这是它在 Jenkins 输出中显示的内容:

no interrupted transaction available
pulling from [repo_location]
no changes found
0 files updated, 0 files merged, 0 files removed, 0 files unresolved

它给了我 hg 命令的输出,但不显示命令本身。

所以,我正在寻找可以打印出这些命令的东西,相当于 cmd.exe “echo on”。

搜索告诉我,PowerShell 中的等效项是“Set-PSDebug -Trace 1”。所以我将它添加到脚本的开头,并将输出更改为:

DEBUG:   15+  >>>> $branch = $env:NAMEDBRANCH
DEBUG:   16+  >>>> PerformRepoActions $pwd.path
DEBUG:    5+  >>>> {
DEBUG:    6+    >>>> $startDir = $pwd.path
DEBUG:    7+    >>>> cd $localRepo
no interrupted transaction available
pulling from ssh://hg@mercurial.wilcoxassoc.com/PcDmis/QA
no changes found
0 files updated, 0 files merged, 0 files removed, 0 files unresolved

如您所见,虽然它确实给了我更多输出,但实际上并没有显示我正在调用的命令。

“Set-PSDebug -Trace 2”提供了更多的输出,但仍然没有显示正在调用的 mercurial 命令。

我想出的解决方法是创建一个回显并执行字符串的函数。它有效,但感觉很糟糕:

function execute($cmd)
{
  echo $cmd
  iex $cmd
}

function PerformRepoActions($localRepo)
{
  $startDir = $pwd.path
  execute "cd $localRepo"
  execute "hg recover"
  execute "hg revert --all"
  execute "hg pull -r $branch --rebase"
  execute "hg update -r $branch"
  execute "cd $startDir"
}
$branch = $env:NAMEDBRANCH
PerformRepoActions $pwd.path

有更好的方法吗?

似乎必须有,但我之前一直很惊讶。

编辑:这不是PowerShell "echo on" 的副本。将输出重定向到文件,即该问题的答案,是不可行的。我需要它显示在 Jenkins 输出中,而不是文件中。

【问题讨论】:

  • Mercurial 不是 Git
  • PowerShell "echo on"的可能重复
  • 糟糕。我只想将其标记为“powershell”。对此感到抱歉。
  • 就像另一个答案所说,PowerShell(以及我所知道的大多数外壳)上没有“回声”之类的东西。您不能将 Jenkins 配置为显示该文件吗? (也许this?)
  • 您也可以执行“回显”,然后在完成后对文件进行分类。

标签: powershell


【解决方案1】:

有一种方法可以捕获当前脚本的内容,并且通过一些工作,您可能可以将其与相关输出结合起来。 (是否需要我不确定)

从 Powershell v3 开始,您可以访问 abstract syntax trees(这是我能找到的唯一能说明它的链接!)

基本上,Ast 可以访问当前脚本(或您发送给它的任何脚本)的所有属性,包括其完整源代码。

运行这个脚本(我包括记事本来显示它运行外部 exe)

Write-Host "before"
$MyInvocation.MyCommand.ScriptBlock.Ast 
Write-Host "after"

notepad 

会产生这个输出

before


Attributes           : {}
UsingStatements      : {}
ParamBlock           : 
BeginBlock           : 
ProcessBlock         : 
EndBlock             : Write-Host "before"
                       $MyInvocation.MyCommand.ScriptBlock.Ast 
                       Write-Host "after"

                       notepad
DynamicParamBlock    : 
ScriptRequirements   : 
ImplementingAssembly : 
Extent               : 
                       Write-Host "before"
                       $MyInvocation.MyCommand.ScriptBlock.Ast 
                       Write-Host "after"

                       notepad 
Parent               : 

after

我想如果你玩弄

$MyInvocation.MyCommand.ScriptBlock.Ast 

你应该能够让它产生你想要的东西。

编辑添加

您可能会更进一步,使用 Ast 选择每个 Powershell cmdlet 并为其附加断点,然后您应该有权访问 cmdlet 名称(我不认为将与可执行文件一起工作——目前它只是一个理论!)你需要通过一个外部脚本来运行整个事情,该脚本管理日志记录并从断点继续。但我认为它可以工作。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-10-26
    • 2018-08-18
    • 2020-11-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-24
    相关资源
    最近更新 更多