Время каждой команды в windows подсказке - PullRequest
1 голос
/ 21 февраля 2020

Я бы хотел, чтобы windows показывал время, отображаемое для каждой команды, которую я запускаю из приглашения. Мне все равно, будь то cmd.exe или powershell. Возможно ли это?

Я настроил что-то похожее на моих linux и macos машинах, и это полезно, когда я запускаю очень медленную команду, чтобы показать своим товарищам по команде, насколько она медленная. (Один час для коммита? Вот доказательство!)

Я нашел командную команду measure-powers для powershell, но я недостаточно знаком с windows, чтобы знать, есть ли какой-нибудь способ его автоматического запуска на каждую команду.

Ответы [ 2 ]

1 голос
/ 21 февраля 2020

A Решение PowerShell с использованием подхода, рекомендованного TessellatingHeckler :

Если вы поместите следующую функцию в ваш $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 использует в интерактивном сеансе - см. about_Prompts .

Приведенный выше выводит продолжительность выполнения предыдущей команды в секундах как часть строки приглашения; например (с уже указанной выше функцией):

PS C:\Users\jdoe [x.xxs]> Start-Sleep 2 # x.xx secs is the PREVIOUS command's duration
PS C:\Users\jdoe [2.01s]>  # 2 seconds plus overhead

Подход основан на PowerShell, поддерживающем богатую историю команд, доступную с помощью командлета Get-History:

  • Он выводит Microsoft.PowerShell.Commands.HistoryInfo объектов, которые имеют System.DateTime -типных .StartExecutionTime и .EndExecutionTime свойств.

  • Вычитание первого из последнего дает экземпляр System.TimeSpan.

  • Этот экземпляр форматируется с помощью -f, оператора форматирования оператор, чтобы получить 2-десятичное число git, которое выражает продолжительность в секунд .


Если вы хотите вставить информацию в существующую функцию подсказки , вместо этого вставьте следующее в $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 + '>')
"@
}
1 голос
/ 21 февраля 2020

На самом деле невозможно манипулировать cmd самой. Есть, однако, глупые вещи, которые можно сделать. Это простой пример использования batch-file для создания поддельного приглашения cmd, но с помощью PowerShell. Он просто использует секунды в качестве демонстрации, а не миллисекунды, но его можно изменить и на миллисекунды. (powershell -command "(New-TimeSpan -Start (Get-Date "01/01/1970") -End (Get-Date)).TotalMilliseconds) Однако мы ограничены 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

Заключительное примечание! Это сделано исключительно для демонстрации и ни в коем случае не должно быть точным решением. Если у меня есть время, я могу взять сценарий и улучшить его и использовать меньше циклов for.

Настоящим недостатком здесь является то, что вам нужно запускать пакетный файл каждый раз, чтобы использовать его по запросу, вместо cmd самого.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...