programing

PowerShell에서 출력을 무시하는 더 나은(깨끗한) 방법은 무엇입니까?

iphone6s 2023. 5. 2. 22:27
반응형

PowerShell에서 출력을 무시하는 더 나은(깨끗한) 방법은 무엇입니까?

무언가를 반환하는 메서드나 cmdlet이 있지만 사용하지 않고 출력하지 않는다고 가정해 보겠습니다.저는 다음 두 가지 방법을 찾았습니다.

Add-Item > $null

[void]Add-Item

Add-Item | Out-Null

당신은 무엇을 사용합니까?어떤 접근법이 더 나은가요? 왜죠?

저는 제가 알고 있는 네 가지 옵션에 대해 몇 가지 테스트를 했습니다.

Measure-Command {$(1..1000) | Out-Null}

TotalMilliseconds : 76.211

Measure-Command {[Void]$(1..1000)}

TotalMilliseconds : 0.217

Measure-Command {$(1..1000) > $null}

TotalMilliseconds : 0.2478

Measure-Command {$null = $(1..1000)}

TotalMilliseconds : 0.2122

## Control, times vary from 0.21 to 0.24
Measure-Command {$(1..1000)}

TotalMilliseconds : 0.2141

그래서 저는 당신이 다른 어떤 것도 사용할 것을 제안합니다.Out-Null으로 중요한입니다.저에게 다음으로 중요한 것은 가독성입니다.나는 약간 방향 전환하는 것을 좋아합니다.$null 및동한설정과 한 설정$null나 자신저는 예전에 캐스팅을 선호했습니다.[Void]하지만 코드나 새로운 사용자를 볼 때는 그렇게 이해하기 어려울 수 있습니다.

나는 출력을 다른 쪽으로 돌리는 것을 약간 선호하는 것 같습니다.$null.

Do-Something > $null

편집

stej의 다시 언급 후, 저는 출력물을 폐기하는 오버헤드를 더 잘 분리하기 위해 파이프라인으로 몇 가지 테스트를 더 하기로 결정했습니다.

다음은 단순한 1000개의 객체 파이프라인을 사용한 몇 가지 테스트입니다.

## Control Pipeline
Measure-Command {$(1..1000) | ?{$_ -is [int]}}

TotalMilliseconds : 119.3823

## Out-Null
Measure-Command {$(1..1000) | ?{$_ -is [int]} | Out-Null}

TotalMilliseconds : 190.2193

## Redirect to $null
Measure-Command {$(1..1000) | ?{$_ -is [int]} > $null}

TotalMilliseconds : 119.7923

이경에는우,,Out-Null의 간접비와 60%의 간접비를 가지고 있습니다.> $null약 0.3%의 오버헤드가 있습니다.

부록 2017-10-16: 나는 원래 다른 옵션을 간과했습니다.Out-Null-inputObject 것처럼 이를 사용하면 오버헤드가 사라지는 것처럼 보이지만 구문은 다릅니다.

Out-Null -inputObject ($(1..1000) | ?{$_ -is [int]})

이제 간단한 100개의 객체 파이프라인으로 몇 가지 테스트를 진행하겠습니다.

## Control Pipeline
Measure-Command {$(1..100) | ?{$_ -is [int]}}

TotalMilliseconds : 12.3566

## Out-Null
Measure-Command {$(1..100) | ?{$_ -is [int]} | Out-Null}

TotalMilliseconds : 19.7357

## Redirect to $null
Measure-Command {$(1..1000) | ?{$_ -is [int]} > $null}

TotalMilliseconds : 12.8527

서 다시 ㅠㅠㅠㅠOut-Null약 60%의 오버헤드가 있습니다.하는 동안에> $null약 4%의 오버헤드가 있습니다.여기 숫자들은 테스트마다 약간씩 차이가 있었습니다. (저는 각각 5번 정도 달리고 중간 지점을 골랐습니다.)하지만 그것은 사용하지 않는 명확한 이유를 보여준다고 생각합니다.Out-Null.

나는 이것이 오래된 스레드라는 것을 알지만, @Jason을 복용하는 사람들을 위한 것입니다.위의 Marcher의 답변이 사실로 받아들여진 것은 사실입니다. 저는 우리 중 많은 사람들이 실제로 지연을 추가하는 것이 파이프라인이며 Out-Null인지 여부와는 아무런 관련이 없다는 것을 수년 동안 알고 있었다는 것이 놀랍습니다.실제로 아래 테스트를 실행하면 몇 년 동안 우리 모두가 더 빠르다고 생각하여 사용했던 [timeout] 및 $165=에 대한 동일한 "timeout" 캐스팅이 실제로는 파이프라인을 추가할 때와 마찬가지로 느리고 실제로는 매우 느리다는 것을 금방 알 수 있습니다.즉, 어떤 것에 파이프를 연결하는 순간, 아웃널을 사용하지 않는 전체 규칙이 휴지통에 들어갑니다.

증명, 아래 목록의 마지막 3가지 테스트.끔찍한 아웃널은 32339.3792 밀리초였지만, 잠시만요 - [보이드]에 얼마나 빨리 캐스팅되었나요?34121.9251ms?!WTF? 이것들은 제 시스템의 실제 #입니다. Void로 캐스팅하는 것은 실제로 더 느렸습니다.=$209는 어떻습니까?34217.685ms...아직 속도가 느립니다!따라서 마지막 세 가지 간단한 테스트에서 알 수 있듯이, 파이프라인이 이미 사용 중인 많은 경우에 Out-Null이 실제로 더 빠릅니다.

왜 그럴까요?간단하죠.Out-Null로 가는 파이프가 더 느렸다는 것은 100% 환각이었고 항상 그랬다.하지만 무엇이든 연결하는 것이 더 느리고, 우리는 이미 기본적인 논리를 통해 그것을 알고 있지 않았습니까?얼마나 더 느리는지 몰랐을 수도 있지만, 이 테스트는 파이프라인을 사용하는 데 드는 비용에 대한 이야기를 보여줍니다.그리고, 우리가 100% 틀린 것은 아닙니다. 왜냐하면 아웃널이 사악한 실제 시나리오는 매우 적기 때문입니다.언제? Out-Null을 추가할 때 파이프라인 작업만 추가합니다.다른 말로 하자면...위와 같이 $(1..1000) | Out-Null과 같은 간단한 명령이 사실인 이유.

위의 모든 테스트에 Out-String에 파이프를 추가하기만 하면 #s가 근본적으로 변경되고(또는 아래의 파이프만 붙여넣으면), 실제로 많은 경우 Out-Null이 더 빨라집니다.

$GetProcess = Get-Process

# Batch 1 - Test 1 
(Measure-Command { 
for ($i = 1; $i -lt 99; $i++) 
{ 
$GetProcess | Out-Null 
} 
}).TotalMilliseconds

# Batch 1 - Test 2 
(Measure-Command { 
for ($i = 1; $i -lt 99; $i++) 
{ 
[void]($GetProcess) 
} 
}).TotalMilliseconds

# Batch 1 - Test 3 
(Measure-Command { 
for ($i = 1; $i -lt 99; $i++) 
{ 
$null = $GetProcess 
} 
}).TotalMilliseconds

# Batch 2 - Test 1 
(Measure-Command { 
for ($i = 1; $i -lt 99; $i++) 
{ 
$GetProcess | Select-Object -Property ProcessName | Out-Null 
} 
}).TotalMilliseconds

# Batch 2 - Test 2 
(Measure-Command { 
for ($i = 1; $i -lt 99; $i++) 
{ 
[void]($GetProcess | Select-Object -Property ProcessName ) 
} 
}).TotalMilliseconds

# Batch 2 - Test 3 
(Measure-Command { 
for ($i = 1; $i -lt 99; $i++) 
{ 
$null = $GetProcess | Select-Object -Property ProcessName 
} 
}).TotalMilliseconds

# Batch 3 - Test 1 
(Measure-Command { 
for ($i = 1; $i -lt 99; $i++) 
{ 
$GetProcess | Select-Object -Property Handles, NPM, PM, WS, VM, CPU, Id, SI, Name | Out-Null 
} 
}).TotalMilliseconds

# Batch 3 - Test 2 
(Measure-Command { 
for ($i = 1; $i -lt 99; $i++) 
{ 
[void]($GetProcess | Select-Object -Property Handles, NPM, PM, WS, VM, CPU, Id, SI, Name ) 
} 
}).TotalMilliseconds

# Batch 3 - Test 3 
(Measure-Command { 
for ($i = 1; $i -lt 99; $i++) 
{ 
$null = $GetProcess | Select-Object -Property Handles, NPM, PM, WS, VM, CPU, Id, SI, Name 
} 
}).TotalMilliseconds

# Batch 4 - Test 1 
(Measure-Command { 
for ($i = 1; $i -lt 99; $i++) 
{ 
$GetProcess | Out-String | Out-Null 
} 
}).TotalMilliseconds

# Batch 4 - Test 2 
(Measure-Command { 
for ($i = 1; $i -lt 99; $i++) 
{ 
[void]($GetProcess | Out-String ) 
} 
}).TotalMilliseconds

# Batch 4 - Test 3 
(Measure-Command { 
for ($i = 1; $i -lt 99; $i++) 
{ 
$null = $GetProcess | Out-String 
} 
}).TotalMilliseconds

예를 들어 파이프라인에서 사용할 수 있는 cmdlet도 있습니다.Add-Item | Out-Null.

Out-Null에 대한 수동 페이지

NAME
    Out-Null

SYNOPSIS
    Deletes output instead of sending it to the console.


SYNTAX
    Out-Null [-inputObject <psobject>] [<CommonParameters>]


DETAILED DESCRIPTION
    The Out-Null cmdlet sends output to NULL, in effect, deleting it.


RELATED LINKS
    Out-Printer
    Out-Host
    Out-File
    Out-String
    Out-Default

REMARKS
     For more information, type: "get-help Out-Null -detailed".
     For technical information, type: "get-help Out-Null -full".

다음과 같은 것을 사용하는 것을 고려해 보겠습니다.

function GetList
{
  . {
     $a = new-object Collections.ArrayList
     $a.Add(5)
     $a.Add('next 5')
  } | Out-Null
  $a
}
$x = GetList

$a.Add반환되지 않음 - 모두에게 적용됩니다.$a.Add메드호출. ▁you니▁▁prep▁need▁would▁to야추해가않그.[void]매번 통화하기 전에

단순한 경우라면 저는 함께 갈 것입니다.[void]$a.Add왜냐하면 출력이 사용되지 않고 폐기된다는 것이 매우 명확하기 때문입니다.

는 개인적으로 개적으저는을 합니다.... | Out-Null다른 사람들이 언급했듯이, 그것은 비교적 "파워 셸리시" 접근법처럼 보이기 때문입니다.... > $null그리고.[void] ....$null = ...는 특정 자동 변수를 이용하여 간과하기 쉬운 반면, 다른 메서드는 추가 구문을 사용하여 식의 출력을 무시하려는 것을 분명히 합니다.왜냐면... | Out-Null그리고.... > $null에 오면 가 한 는 의사소통을 하고 더을 말할 수 표현의마에옵니다지막식옵니다▁comee에지마▁them막▁for의▁comment 그들은 효과적으로 "지금까지 우리가 한 모든 것을 가져다가 버려라"는 의사소통을 하고, 디버깅 목적을 위해 더 쉽게 코멘트할 수 있습니다(예:... # | Out-Null), 퍼팅에 비해$null =또는[void] 실행 후에 수행할 작업을 결정하는 식 앞에 표시됩니다.

그러나 다른 벤치마크를 살펴보겠습니다. 각 옵션을 실행하는 데 걸리는 시간이 아니라 각 옵션이 수행하는 작업을 파악하는 데 걸리는 시간입니다.PowerShell 또는 스크립팅에 대한 경험이 전혀 없는 동료들과 환경에서 작업한 경험이 있습니다.저는 제 대본을 작성하려고 노력하는 경향이 있습니다. 몇 년 후에 그들이 보고 있는 언어조차 이해하지 못하는 누군가가 그것이 무엇을 하고 있는지 이해할 수 있는 싸움의 기회를 가질 수 있도록 말이죠. 왜냐하면 그들은 그것을 지지하거나 대체해야 할 수 있기 때문입니다.지금까지 다른 방법보다 한 가지 방법을 사용해야 하는 이유로 이런 생각을 한 적이 없지만, 당신이 그 위치에 있고 당신이 그것을 사용한다고 상상해 보세요.help 엔진을 하여 무엇이 무엇인지 .Out-Null그래요. 당신은 즉시 유용한 결과를 얻을 수 있죠, 그렇죠?이제 동일한 작업을 수행합니다.[void]그리고.$null =쉽지 않죠, 그렇죠?

물론, 값의 출력을 억제하는 것은 스크립트의 전체적인 논리를 이해하는 것에 비해 매우 사소한 세부 사항이며, 좋은 코드를 작성하는 능력을 초보자의 읽기 능력과 바꾸기 전에 코드를 "다운"하려고 시도할 수 있습니다... 별로 좋지 않은 코드를 읽는 능력.제 말은, PowerShell에 능통한 사람들 중 일부는 다음과 같은 기능에 익숙하지 않을 수도 있다는 것입니다.[void],$null =등, 그리고 그것들이 더 빨리 실행되거나 입력하는 데 키 입력이 덜 걸릴 수 있다고 해서 그것들이 여러분이 하려는 것을 하는 가장 좋은 방법이라는 것을 의미하지는 않습니다. 그리고 언어가 독특한 구문을 제공한다고 해서 더 명확하고 더 *잘 알려진 것 대신 그것을 사용해야 한다는 것을 의미하지 않습니다.

* 라고 추측하고 있습니다.Out-Null명확하고 잘 알려져 있지만, 저는 그것이 무엇인지 모릅니다.$true입력 시간이나 실행 시간에 관계없이 사용자 코드(사용자 자신 포함)의 향후 판독기 및 편집자가 가장 명확하고 액세스하기 쉽다고 생각하는 옵션이 이 옵션을 사용하는 것이 좋습니다.

언급URL : https://stackoverflow.com/questions/5260125/whats-the-better-cleaner-way-to-ignore-output-in-powershell

반응형