如何保存带参数的powershell函数

q5lcpyga  于 2023-10-23  发布在  Shell
关注(0)|答案(2)|浏览(129)

我运行了一个powershell函数,它告诉我运行任何命令需要多长时间。它看起来像这样。

(Measure-Command {  <command> | Out-Default }).TotalSeconds | ForEach-Object { $totalMinutes = [math]::Floor($_ / 60); $remainingSeconds = $_ % 60; Write-Host "Time Elapsed: $totalMinutes Minutes, $remainingSeconds seconds" }

我希望能够像这样运行它:

c:\files> timer <command>

我想将该功能保存到我的配置文件中。我知道我的配置文件在哪里以及如何编辑它,但我不知道如何将此函数保存到我的配置文件中,以便我可以按照我所描述的timer <command>执行,例如timer py --version。你能告诉我正确的语法是什么吗?

4dc9hkyq

4dc9hkyq1#

你可以在Measure-Command周围创建一个以脚本块为参数的 Package 器函数,请注意,为了让它工作,你必须使用语法调用你的函数:timer {...}(花括号是必需的)。

function timer {
    [CmdletBinding()]
    param(
        [Parameter(Position = 0, Mandatory)]
        [scriptblock] $Command
    )

    end {
        $span = [timespan]::FromMinutes((Measure-Command { & $Command | Out-Default }).TotalMinutes)
        Write-Host ('Time Elapsed: {0:D2} minutes, {1:D2} seconds.' -f $span.Minutes, $span.Seconds)
    }
}

如何使用它的例子:

timer { 0..10 | ForEach-Object { $_; Start-Sleep -Milliseconds 200 } }

将产生以下输出:

0
1
2
3
4
5
6
7
8
9
10
Time Elapsed: 00 minutes, 02 seconds.

注意,由于使用Out-Default,无法捕获脚本块的输出。

如果你想从定时器函数中捕获输出,另一种方法是在脚本块执行之前存储datetime.Now,然后在执行完成后计算时间差:

function timer {
    [CmdletBinding()]
    param(
        [Parameter(Position = 0, Mandatory)]
        [scriptblock] $Command
    )

    end {
        $now = [datetime]::Now
        & $Command
        $span = [datetime]::Now - $now
        Write-Host ('Time Elapsed: {0:D2} minutes, {1:D2} seconds.' -f $span.Minutes, $span.Seconds)
    }
}

现在可以毫无问题地捕获输出:

$capture = timer { 0..10 | ForEach-Object { $_; Start-Sleep -Milliseconds 200 } }
ztigrdn8

ztigrdn82#

要获得 * 所有 * 你需要做的就是添加单词timer作为前缀的功能,你可以这样做:

function timer {
  param (
      [string]$Command,
      [string[]]$Arguments
  )

  $fullCommand = "$Command $Arguments"
  $startTime = Get-Date
  Invoke-Expression $fullCommand
  $endTime = Get-Date

  $elapsedTime = $endTime - $startTime
  $totalSeconds = [math]::Floor($elapsedTime.TotalSeconds)
  $totalMinutes = [math]::Floor($totalSeconds / 60)
  $remainingSeconds = $totalSeconds % 60

  Write-Host "Time Elapsed: $totalMinutes Minutes, $remainingSeconds seconds"
  }

输出如下所示:

PS C:\files> timer sleep 5
Time Elapsed: 0 Minutes, 5 seconds
PS C:\files>

另一种方法是将实际命令 Package 为字符串:

function timer {
  param (
      [string]$Command
  )

  $startTime = Get-Date
  Invoke-Expression $Command
  $endTime = Get-Date

  $elapsedTime = $endTime - $startTime
  $totalSeconds = [math]::Floor($elapsedTime.TotalSeconds)
  $totalMinutes = [math]::Floor($totalSeconds / 60)
  $remainingSeconds = $totalSeconds % 60

  Write-Host "Time Elapsed: $totalMinutes Minutes, $remainingSeconds seconds"
  }

输出如下所示:

PS C:\files> timer "sleep 5"
Time Elapsed: 0 Minutes, 5 seconds
PS C:\files>

相关问题