Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/powershell/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在windows提示符下计时每个命令_Windows_Powershell_Cmd - Fatal编程技术网

在windows提示符下计时每个命令

在windows提示符下计时每个命令,windows,powershell,cmd,Windows,Powershell,Cmd,我希望windows显示从提示符运行的每个命令的显示时间。我不在乎它是cmd.exe还是powershell。这可能吗 我已经在我的linux和macos机器上设置了类似的东西,当我运行一个特别慢的命令来告诉我的队友它有多慢时,它是非常有用的。(承诺一小时?这是证据!) 我找到了powershell的measure命令commandlet,但我对windows不够熟悉,不知道是否有办法在每个命令上自动运行它。实际上不可能操作cmd本身。不管一个人能做多么愚蠢的事情。这是一个简单的示例,使用批处理

我希望windows显示从提示符运行的每个命令的显示时间。我不在乎它是cmd.exe还是powershell。这可能吗

我已经在我的linux和macos机器上设置了类似的东西,当我运行一个特别慢的命令来告诉我的队友它有多慢时,它是非常有用的。(承诺一小时?这是证据!)


我找到了powershell的measure命令commandlet,但我对windows不够熟悉,不知道是否有办法在每个命令上自动运行它。

实际上不可能操作
cmd
本身。不管一个人能做多么愚蠢的事情。这是一个简单的示例,使用
批处理文件
创建假
cmd
提示符,但需要借助PowerShell。在本例中,它只是使用秒作为演示,而不是毫秒,但也可以更改为使用毫秒。(
powershell-command)(New TimeSpan-Start(Get Date“01/01/1970”)-End(Get Date)).totalmilysics
)但是,我们的精度仅限于32位,所以请务必注意!显然,也有一些方法可以解决这一问题

@echo off
:myprompt
set mycmd=
set /p "mycmd=prompt: "
for /f "delims=," %%i in ('powershell -command "(New-TimeSpan -Start (Get-Date "01/01/1970") -End (Get-Date)).TotalSeconds"') do set start=%%I
if "%mycmd:~-4%" == ".cmd" set "mycmd=call %mycmd%"
if "%mycmd:~-4%" == ".bat" set "mycmd=call %mycmd%"
%mycmd%
for /f "delims=," %%a in ('powershell -command "(New-TimeSpan -Start (Get-Date "01/01/1970") -End (Get-Date)).TotalSeconds"') do set end=%%a
set /a result=%end%-%start%
echo                                                                                        [%result% secs][%time%]
goto :myprompt
它确实不会精确到毫秒,但我只是在证明一点

下面是一个包含毫秒的示例,绕过32位精度限制

@echo off
:myprompt
set mycmd=
set /p "mycmd=prompt: "
for /f "delims=," %%i in ('powershell -command "(New-TimeSpan -Start (Get-Date "01/01/1970") -End (Get-Date)).TotalSeconds"') do set start=%%i
for /f "delims=," %%i in ('powershell -command "(New-TimeSpan -Start (Get-Date "01/01/1970") -End (Get-Date)).TotalMilliSeconds"') do set mstart=%%I
if "%mycmd:~-4%" == ".cmd" set "mycmd=call %mycmd%"
if "%mycmd:~-4%" == ".bat" set "mycmd=call %mycmd%"
%mycmd%
for /f "delims=," %%a in ('powershell -command "(New-TimeSpan -Start (Get-Date "01/01/1970") -End (Get-Date)).TotalSeconds"') do set end=%%a
for /f "delims=," %%a in ('powershell -command "(New-TimeSpan -Start (Get-Date "01/01/1970") -End (Get-Date)).TotalMilliSeconds"') do set mend=%%a
set /a sres=%end%-%start%
set /a mres=%mend:~-5%-%mstart:~-5%%
echo                                                                                        [%sres%s%mres%][%time%]
goto :myprompt
最后一点注意!这纯粹是为了演示目的,决不是为了实际的精确解决方案。如果我有时间,我可以使用脚本并对其进行改进,并对循环使用较少的


这里真正的缺点是,您每次需要启动批处理文件以按提示使用,而不是
cmd
本身。

PowerShell解决方案使用以下建议的方法:

如果将以下函数放入
$PROFILE
文件
,每个提示符将显示上一个命令的执行持续时间:

function Prompt {
  # Calculate the previous command's execution duration (time span).
  $durationInfo = if ($he = Get-History -Count 1) {
    # Use a '0.00s' format: duration in *seconds*, with two decimal places.
    ' [{0:N2}s]' -f ($he.EndExecutionTime - $he.StartExecutionTime).TotalSeconds
  }
  # Insert the information into the default prompt string; e.g.:
  #   'PS C:\foo> ' becomes 'PS C:\foo [0.23s]> '
  "PS $($executionContext.SessionState.Path.CurrentLocation)${durationInfo}$('>' * ($nestedPromptLevel + 1)) "
}
Prompt
是定义PowerShell在交互式会话中使用的提示字符串的函数名-请参阅

上面的命令以秒为单位打印上一个命令的执行持续时间,作为提示字符串的一部分;例如(在已定义上述函数的情况下):

该方法依赖于PowerShell维护丰富的命令历史记录,该历史记录可通过cmdlet访问:

  • 它输出具有-typed
    .StartExecutionTime
    属性的对象

  • 从后者中减去前者会得到一个实例

  • 该实例通过操作符
    -f
    进行格式化,以生成一个以秒为单位表示持续时间的2位十进制数字


如果您想将信息注入到预先存在的提示功能中,请将以下内容放入您的
$PROFILE
中:

& {
  # Get the current definition.
  $oldFuncScriptBlock = $Function:Prompt

  # Redefine the function with the previous function's script block included:
  Set-Item Function:Prompt -Value @"
    # Calculate the previous command's execution duration (time span).
    `$durationInfo = if (`$he = Get-History -Count 1) {
      # Use a '0.00s' format: duration in *seconds*, with two decimal places.
      ' [{0:N2}s]' -f (`$he.EndExecutionTime - `$he.StartExecutionTime).TotalSeconds
    }
    # Call the old function's script block to determine its string.
    `$promptString = & { $oldFuncScriptBlock }
    # Insert the duration information into that string, under the assumption
    # that it contains a ">" character:
    `$promptString -replace '>', (`$durationInfo + '>')
"@
}

对于那些对如何在linux/macos上执行此操作感兴趣的人,我使用。Windows中的大多数内容都是通过ETW(Windows事件跟踪)事件进行跟踪的。您可以从这里开始()为了加快处理速度。有很多工具用于分析跟踪。这不是很简单,但肯定很有效。在PowerShell中,使用
get history
中的数据,执行的每一行都有一个
StartExecutionTime
EndExecutionTime
,编辑您的
提示符{}
函数并获取最后一个命令,减去这些命令,并将时间作为提示的一部分打印出来。很棒的指针,@tessellingheckler;看看下面它是如何组合起来的。我以前在
get ExecutionTimeSpanFromHistory
函数中使用过这种技术,但我没有想到将它集成到提示字符串中,所以感谢aski回答这个问题,阿富利亚。@mklement0:-)我想我是从-那里的屏幕截图在右上角显示了以前的命令执行时间和当前时钟时间,在左上角的多行提示符中显示了当前文件夹。
& {
  # Get the current definition.
  $oldFuncScriptBlock = $Function:Prompt

  # Redefine the function with the previous function's script block included:
  Set-Item Function:Prompt -Value @"
    # Calculate the previous command's execution duration (time span).
    `$durationInfo = if (`$he = Get-History -Count 1) {
      # Use a '0.00s' format: duration in *seconds*, with two decimal places.
      ' [{0:N2}s]' -f (`$he.EndExecutionTime - `$he.StartExecutionTime).TotalSeconds
    }
    # Call the old function's script block to determine its string.
    `$promptString = & { $oldFuncScriptBlock }
    # Insert the duration information into that string, under the assumption
    # that it contains a ">" character:
    `$promptString -replace '>', (`$durationInfo + '>')
"@
}