如何让PowerShell显示被调用的命令

时间:2016-02-03 17:16:48

标签: powershell

我有一个简单的PowerShell脚本,我是从Jenkins打来的:

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输出中,而不是文件。

1 个答案:

答案 0 :(得分:0)

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

从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名称(我不认为可以使用可执行文件 - 目前它只是一个理论!)您需要通过管理日志记录并从断点继续执行的外部脚本来运行整个事务。但我认为它可行。