programing

PowerShell: 마지막 실행 결과에 대한 자동 변수가 있습니까?

batch 2023. 9. 3. 12:24
반응형

PowerShell: 마지막 실행 결과에 대한 자동 변수가 있습니까?

파이썬 인터랙티브 쉘의 "_" 변수와 비슷한 기능을 찾고 있습니다.PowerShell에서 저는 다음과 같은 것을 원합니다.

> Get-Something # this returns an object and display it to the output.
# Now I want to assign that object to some variable
> $anObj = ???

아니요, 그런 자동 변수는 없습니다.

다음 작업을 수행해야 합니다.

$output = Get-Something
$output
$anObj = $output

행동을 이해하기 위해

tl;dr

  • 이러한 자동 변수는 PowerShell 7.3.3에는 존재하지 않으며 절대 없을 수도 있습니다.

    • 다음 섹션에서 자세히 설명한 대로 제한된 사용자 정의를 만들있습니다.
  • 지정된 명령에 대해 사용할 수 있는 임시 명령 -Variable또는 cmdlet고급 스크립트/기능에 한해 공통 파라미터를 사용하여 결과디스플레이인쇄하고 변수캡처할 수 있습니다. 예:

    # Tee-Object cmdlet: Works with any command.
    # Captured result will be available in self-chosen variable $r
    # Note: Do NOT use "$" in the -OutVariable argument.
    $PSVersionTable | Tee-Object -Variable r
    
    # -OutVariable common parameter: Works with cmdlets, advanced scripts / funcs.
    # Captured result will be available in self-chosen variable $r
    # Note: Do NOT use "$" in the -OutVariable argument.
    Get-ChildItem *.txt -OutVariable r
    

가장 최근의 실행 결과를 포함하는 준자동 변수를 만드는 간단하지만 제한적인 PSv3+ 솔루션:

참고:

  • 적절하지만 사소하지 않은 솔루션은 BartekB의 유용한 답변을 참조하십시오.

  • GitHub 기능 요청 #7853은 이 기능을 향후 PowerShell(Core) 버전으로 빌드할 것을 요청합니다(이 문서의 현재 버전은 PowerShell(Core) 7.3.3).


다을추다니에 합니다.$PROFILE파일 이름:

# Store previous command's output in $__
$PSDefaultParameterValues['Out-Default:OutVariable'] = '__'

- 예:$__이 예에서 (2개의 밑줄)은 사용자에게 달려 있지만, 이름 충돌에 주의하십시오. 특히 여러 컨텍스트에서 사용 중인 입력 개체를 나타내는 자동 변수를 주의하십시오.

이렇게 하면 PowerShell의 매개 변수 기본값을 전역적으로 설정할 수 있는 기능을 통해 대화형 세션에서 가장 최근실행PowerShell 명령의 터미널 바인딩된 출력이 변수로 캡처됩니다( 참조).

-OutVariable변수에서 cmdlet / 고급 함수의 출력 개체를 수집하도록 설계된 공통 매개 변수이며, 위의 정의는 이 매개 변수를 모두에게 암시적으로 적용합니다.Out-DefaultPowerShell이 단말기에 무언가를 출력할 때마다 백그라운드에서 호출되는 호출입니다. 그러나 아래에 언급된 예외 사항에 유의하십시오.

주의사항:

  • 필요한 경우 캡처한 출력을 나중에 사용할 수 있도록 저장합니다.$__명령에 있는 과 같이하십시오.).$saved = <command>).

    • 로 그냥 참로그냥.$saved = $__작동하지 않습니다, 왜냐하면 그것은 만들기 때문입니다.$saved 것을 [ArrayList]를 서로예들어로 합니다.$__다음 명령에서 다시 채워집니다.
  • 다음과 같은 경우에는 출력캡처되지 않습니다.

    • 다음과 같은 외부 프로그램의 출력git 스트림을 전달하기 리디렉션 또는 한 따라서 호출하지 않습니다.Out-Default가장 간단한 해결 방법은 파이프를 연결하는 것입니다.Write-Output를 들면 (으) 같은 것.*>&1PowerShell 스트림을 통해 명시적으로 라우팅할 수 없음), 예:

      • whoami.exe | Write-Output # $__ is now populated
    • formating cmdlet명시적으로 호출하는 명령의 출력 -Format-Custom,Format-Hex,Format-List,Format-Table또는Format-Wide.

      • 로 그것을 고치려고 시도하는 것은 유혹적입니다.$PSDefaultParameterValues['Format-*:OutVariable'] = '__'그러나 불행하게도, 이것은 원래 데이터가 아닌 형식 지정 객체(표현)를 수집할 것입니다.$__원하지 않는 것.만족스럽지 못한 해결 방법은 캡처하는 것입니다.Format-*대상 변수를 고려해야 할 뿐만 아니라 데이터가 아닌 형식 지정 개체만 볼 수 있는 다른 변수의 출력Format-*cmdlet은 명시적으로 사용하지 않더라도 백그라운드에서 사용됩니다. 명령어 출력은 Format-*그런 다음 통화가 두 번 캡처됩니다. 한 번은 데이터로 캡처됩니다.$__다른 변수에서 개체 형식 지정을 다시 수행합니다.
  • 설계 특이점으로 인해 항상 배열 목록(유형)을 포함합니다.[System.Collections.ArrayList]), 이전 명령이 단일 개체만 출력하는 경우에도 마찬가지입니다.의심스러울 때는 다음을 사용합니다.$($__)(또는)$__[0] 단일 출력 개체를 가져옵니다.

  • 매우 큰 출력 세트를 생성하는 명령에 주의하십시오.$__그것들을 메모리에 수집할 것입니다.

  • $__단말기로 출력되는 객체만 캡처합니다._Python에서 실행; 출력을 생성하지 않는 명령 또는$null로 늘어선 련의일$null 이전항남니깁다를 .$__온전한 가치.

또한 OutVariable 매개 변수를 사용하여 명령 결과를 인쇄하고 출력 개체를 캡처한 다음 나중에 $anObj를 사용하여 변수 내용을 표시할 수 있습니다.

Get-Something -OutVariable anObj

대부분의 작업이 필요하지만 IMO가 원하는 것을 제공하는 마지막 옵션: Out-Default를 덮어쓸 프록시를 만듭니다(다른 것으로 아웃-*하지 않는 경우 파이프라인 끝에서 항상 암시적으로 호출됨).

제프리 스누버는 파워셸 딥 다이브 중 하나(첫 번째였다고 생각합니다)에서 그것에 대해 발표했습니다. Dmitry Sotnikov 블로그에서 그가 사용한 스크립트(위에서 언급한 기본값 이외의 스크립트 포함)를 찾을 수 있습니다.전체 개념을 이해하기 위해 비디오를 볼 도 있습니다.

정확히는 아닙니다.파이프라인에 현재 객체를 포함하는 $_자동 값이 있습니다.

파이프라인은 한 cmdlet에서 다음 cmdlet으로 결과를 전달하는 일반적인 방법이며, cmdlet은 파이프라인 또는 파이프라인의 개체 속성에서 매개 변수를 허용하도록 설정되어 "마지막 결과" 변수의 사용과 무관합니다.

그러나 일부 상황에서는 "파이프" 개체에 대한 특정 참조가 필요하며 $_자동 값이 있는 경우도 있습니다.

다음은 사용 방법의 예입니다.Where-Object Cmdlet을 사용하고 파워셸의 자동 변수 목록은 다음과 같습니다.4장. PowerShell 자동 변수

powershell의 스크립팅은 Python의 프로그래밍과 다른 스타일을 요구합니다(Python과 동일하게 C++와는 다른 스타일을 요구합니다).

Powershell은 파이프가 광범위하게 사용되도록 제작되었습니다. 파이프라인을 보다 절차적인 단계별 구조로 분할하려면 결과를 자동 변수가 아닌 명명된 변수에 저장해야 합니다.

"r"(Invoke-History의 별칭)이 있는 마지막 명령을 호출하고 괄호()로 묶어서 먼저 실행하는 것은 어떻습니까?

예, 마지막 명령을 다시 실행합니다. 하지만 제 사용 사례에서는 이 방법이 가장 효율적인 솔루션입니다. 특히 처음에는 마지막 명령 출력이 필요하지 않을 때가 많습니다.

또한 개체 구조를 그대로 유지합니다.

PS C:\Users\user> Get-NetAdapter -InterfaceIndex 3 | Where {$_.State -match "2"}

Name                      InterfaceDescription                    ifIndex Status       MacAddress             LinkSpeed
----                      --------------------                    ------- ------       ----------             ---------
Ethernet                  Intel(R) Ethernet Connection I217-LM          3 Up           XX-XX-XX-XX-XX-XX       100 Mbps

PS C:\Users\user> (r) |where {$_.LinkSpeed -eq "100 Mbps"}
Get-NetAdapter -InterfaceIndex 3 | Where {$_.State -match "2"}

Name                      InterfaceDescription                    ifIndex Status       MacAddress             LinkSpeed
----                      --------------------                    ------- ------       ----------             ---------
Ethernet                  Intel(R) Ethernet Connection I217-LM          3 Up           XX-XX-XX-XX-XX-XX       100 Mbps

PS C:\Users\user> (r).MacAddress
Get-NetAdapter -InterfaceIndex 3 | Where {$_.State -match "2"}
XX-XX-XX-XX-XX-XX

특정 사용 사례를 위해 PowerShell에서 배치 파일을 실행하고 있었는데, 해당 배치 파일의 출력을 실시간으로 인쇄하여 출력을 변수에 저장하고자 했습니다.저는 제 통화 교환기의 출력을 파이프로 연결함으로써 이것을 달성할 수 있었습니다.Tee-Object:

$args = @('-r', '-a');
& "C:\myFile.bat" $args | Tee-Object -Variable output;
$output | Set-Clipboard;

첫 번째 명령은 배치 파일에 대한 내 인수를 설정합니다.인수와 을 두번명령은인내사연호있배다연합결니로파프이출력을고실하행파일을치용째여하산를자출는수가▁the▁the▁to▁the▁output▁using다▁runs▁file▁with니합▁second결▁batch에 연결합니다.Tee-Object명령 - 호출 연산자의 출력을 실시간으로 출력하지만 모든 정보를 출력이라는 새 변수에 저장합니다.마지막 명령은 다음의 내용을 복사합니다.$output클립보드로 이동합니다.

Tee-Object또한 출력을 파일에 저장할 수 있으며(유니코드 인코딩), 파일 변수에 저장해야 할 경우(콘솔에 인쇄하는 것 외에도), 여러 호출을 연결할 수 있습니다.Tee-Object 내용은 다음 링크자세한 내용은 다음 링크를 참조하십시오.

https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/tee-object

이것은 Windows Powershell in Action에서 나온 것입니다.이것을 $profile에 저장하면 $last가 마지막 명령의 출력을 포함하도록 합니다.또한 디렉터리 이름을 입력하여 디렉터리를 변경하거나 웹 사이트의 URL을 입력하여 브라우저의 웹 사이트로 이동합니다.Out-Default cmdlet을 재정의하고 호출하는 Out-Default 함수를 만듭니다.저는 "start-process $__command" 행을 추가하여 웹 사이트로 이동하면 osx에서 작동할 수 있습니다.

이것은 상당히 침습적입니다.나는 나중에 어떤 이유로 내 $profile에서 그것을 비활성화했습니다.

#
# Wrapping an exiting command with a function that uses
# steppable pipelines to "remote-control" the wrapped command.
    
function Out-Default
{
  [CmdletBinding(ConfirmImpact="Medium")]
  param(
    [Parameter(ValueFromPipeline=$true)] 
    [System.Management.Automation.PSObject] $InputObject
  )
    
  begin {
    $wrappedCmdlet = $ExecutionContext.InvokeCommand.GetCmdlet(
      "Out-Default")
    $sb = { & $wrappedCmdlet @PSBoundParameters }
    $__sp = $sb.GetSteppablePipeline()
    $__sp.Begin($pscmdlet)
  }

  process {
    $do_process = $true
    if ($_ -is [System.Management.Automation.ErrorRecord]) {
      if ($_.Exception -is 
      [System.Management.Automation.CommandNotFoundException]) {
        $__command = $_.Exception.CommandName
        if (test-path -path $__command -pathtype container) {
          set-location $__command
          $do_process = $false
        }
        elseif ($__command -match '^http://|\.(com|org|net|edu)$') {
          if ($matches[0] -ne "http://") {$__command = "HTTP://" + 
            $__command }
          # [diagnostics.process]::Start($__command)
          start-process $__command
          $do_process = $false
        } 
      } 
    }
    if ($do_process) {
      $global:LAST = $_;
      $__sp.Process($_)
    }  
  }

  end {
    $__sp.End()
  }

}

을 제게효방명출것처입다니리하는으로 입니다.Select-Object를 들어, 저는 EXE에서 상세 출력하는 콘솔 EXE를 .stderr그리고 의미 있는 출력.stdout마지막 대사만 담고 싶었어요

$UtilityPath = ""

(UpdateUtility.exe $ArgList 2>&1) | % {
    If ($_ -Is [System.Management.Automation.ErrorRecord]) {
        $_.Exception.Message
    }
    Else {
        $_
        $UtilityPath = $_
    }
}

PowerShell의 이 은 다음과 .Error오류로 앱의 PowerShell을 잘 .stderr후 출하여로변니다합환력다▁it▁output니▁and로 변환합니다.Error산출량.출력물을 포장하는 이 접근 방식을 사용하면 출력물이 통과하는 방식을 제어할 수 있을 뿐만 아니라,stdout내가 원했던 라인.제가 보기에 이것은 매우 유연한 접근법으로, 출력물을 가로채고 출력물이 통과할 때 원하는 모든 것을 할 수 있습니다.예를 들어:

$CommandOutput = ""

SomeOtherCommand | % {
    $CommandOutput += "$_`r`n"
    $_
}

PowerShell Cookbook 모듈을 사용하여 시작 스크립트에 Add-Object Collector 호출을 추가합니다.

"(Get-History)[-1]을(를) 시도할 수 있습니다.명령줄".

언급URL : https://stackoverflow.com/questions/14351018/powershell-is-there-an-automatic-variable-for-the-last-execution-result

반응형