programing

PowerShell의 함수 반환 값

magicmemo 2023. 5. 11. 21:21
반응형

PowerShell의 함수 반환 값

저는 쉐어포인트 팀 사이트 프로비저닝과 관련된 여러 작업을 수행하는 PowerShell 기능을 개발했습니다.궁극적으로, 나는 이 함수가 프로비저닝된 사이트의 URL을 String으로 반환하여 함수의 마지막에 다음 코드를 갖게 하기를 원합니다.

$rs = $url.ToString();
return $rs;

이 함수를 호출하는 코드는 다음과 같습니다.

$returnURL = MyFunction -param 1 ...

그래서 나는 String을 기대하고 있지만 그렇지 않습니다.대신 시스템 유형의 개체입니다.관리.자동화.PS 방법.문자열 형식 대신 해당 형식을 반환하는 이유는 무엇입니까?

PowerShell은 적어도 더 전통적인 프로그래밍 관점에서 볼 때 정말 이상한 반환 의미를 가지고 있습니다.머리를 감아야 할 두 가지 주요 아이디어가 있습니다.

  • 모든 출력이 캡처되어 반환됩니다.
  • return 키워드는 논리적 종료 지점을 나타냅니다.

따라서 다음 두 스크립트 블록은 효과적으로 동일한 작업을 수행합니다.

$a = "Hello, World"
return $a

 

$a = "Hello, World"
$a
return

두 번째 예제의 $a 변수는 파이프라인에 출력으로 남아 있으며 언급한 대로 모든 출력이 반환됩니다.실제로 두 번째 예제에서는 반환을 완전히 생략할 수 있으며 동일한 동작을 하게 됩니다(반복은 함수가 자연스럽게 완료되고 종료될 때 암시됩니다).

당신의 기능 정의가 더 없다면 왜 PSMethod 객체를 얻었는지 말할 수 없습니다.제 생각에는 캡처되지 않고 출력 파이프라인에 배치되는 몇 줄의 무언가가 있을 것입니다.

또한 여러 개의 식을 한 줄에 중첩하지 않는 한 이러한 세미콜론은 필요하지 않을 수도 있습니다.

반환 의미론에 대한 자세한 내용은 TechNet의 about_Return 페이지에서 읽거나 다음을 호출하여 확인할 수 있습니다.help returnPowerShell 자체의 명령입니다.

PowerShell의 이 부분은 아마도 가장 어리석은 측면일 것입니다.함수 중에 생성된 외부 출력은 결과를 오염시킵니다.때로는 출력이 전혀 없는 경우도 있고, 어떤 상황에서는 계획된 반환 값 외에 다른 계획되지 않은 출력이 있을 수도 있습니다.

따라서 원래 함수 호출에서 할당을 제거하여 출력이 화면에 표시되고, 계획하지 않은 항목이 디버거 창에 나타날 때까지 단계를 수행합니다(PowerShell ISE 사용).

외부 범위에서 변수를 예약하는 것과 같은 것도 출력을 유발합니다.[boolean]$isEnabled이 만들지 입니다.[boolean]$isEnabled = $false.

은 또다른좋점은은입니다.$someCollection.Add("thing")새로운 수집 횟수를 뱉어내는 것입니다.

이제 PowerShell 5를 통해 클래스를 만들 수 있습니다.함수를 클래스로 변경하면 반환은 바로 앞에 있는 개체만 반환합니다.여기 정말 간단한 예가 있습니다.

class test_class {
    [int]return_what() {
        Write-Output "Hello, World!"
        return 808979
    }
}
$tc = New-Object -TypeName test_class
$tc.return_what()

만약 이것이 함수라면 예상되는 출력은

Hello World
808979

클래스로서 반환되는 것은 정수 808979뿐입니다.클래스는 선언되거나 무효인 형식만 반환한다는 보장과 같습니다.

문제를 해결하기 위해 배열의 마지막 개체를 반환했습니다. 함수에서 반환되는...이것은 훌륭한 해결책은 아니지만 없는 것보다는 낫습니다.

someFunction {
   $a = "hello"
   "Function is running"
   return $a
}

$b = someFunction
$b = $b[($b.count - 1)]  # Or
$b = $b[-1]              # Simpler

대체로, 동일한 것을 쓰는 더 한 줄짜리 방법은 다음과 같습니다.

$b = (someFunction $someParameter $andAnotherOne)[-1]

콘솔로도 출력하고 싶기 때문에 결과 멤버가 하나인 간단한 해시 테이블 개체를 전달하여 비정상적인 반환을 방지합니다.참조를 통해 통과합니다.

function sample-loop($returnObj) {
  for($i = 0; $i -lt 10; $i++) {
    Write-Host "loop counter: $i"
    $returnObj.result++
  }
}

function main-sample() {
  $countObj = @{ result = 0 }
  sample-loop -returnObj $countObj
  Write-Host "_____________"
  Write-Host "Total = " ($countObj.result)
}

main-sample

GitHub 프로젝트 언팩에서 실제 사용 사례를 볼 수 있습니다.튠즈.

기존 답변이 정확하지만, 때때로 당신은 실제로 무언가를 명시적으로 반환하지 않습니다.Write-Output 는또.return하지만 함수 결과에는 약간의 미스터리한 가치가 있습니다.은 이은다음같내은함출있수다습니와 같은 일 수 .New-Item

PS C:\temp> function ContrivedFolderMakerFunction {
>>    $folderName = [DateTime]::Now.ToFileTime()
>>    $folderPath = Join-Path -Path . -ChildPath $folderName
>>    New-Item -Path $folderPath -ItemType Directory
>>    return $true
>> }
PS C:\temp> $result = ContrivedFolderMakerFunction
PS C:\temp> $result


    Directory: C:\temp


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
d-----         2/9/2020   4:32 PM                132257575335253136
True

디렉토리 작성 시 발생하는 모든 추가 노이즈가 수집되어 출력으로 방출됩니다.은 이를완는쉬같다다습니음을 추가하는 입니다.| Out-NullNew-Item또는 변수에 결과를 할당하고 해당 변수를 사용하지 않을 수 있습니다.이렇게 보일 거예요

PS C:\temp> function ContrivedFolderMakerFunction {
>>    $folderName = [DateTime]::Now.ToFileTime()
>>    $folderPath = Join-Path -Path . -ChildPath $folderName
>>    New-Item -Path $folderPath -ItemType Directory | Out-Null
>>    # -or-
>>    $throwaway = New-Item -Path $folderPath -ItemType Directory 
>>    return $true
>> }
PS C:\temp> $result = ContrivedFolderMakerFunction
PS C:\temp> $result
True

New-Item아마도 이것들 중에서 더 유명하겠지만, 다른 것들은 모든 것을 포함합니다.StringBuilder.Append*()와 드소메,SqlDataAdapter.Fill()방법.

돌아가기 전에 출력을 지워야 합니다.Out-Null을 사용해 보십시오.그렇게 파워셸return작동합니다. 원하는 변수가 아니라 전체 함수의 출력을 반환합니다.예를 들어 다음과 같습니다.

function Return-Url
{
   param([string] $url)

   . {
       $rs = $url.ToString();
       return
   } | Out-Null
   
   return $rs
}

$result = Return-Url -url "https://stackoverflow.com/questions/10286164/function-return-value-in-powershell"

Write-Host $result
Write-Host $result.GetType()

결과는 다음과 같습니다.

https://stackoverflow.com/questions/10286164/function-return-value-in-powershell
System.String

https://riptutorial.com/powershell/example/27037/how-to-work-with-functions-returns 에 대한 크레딧

코드를 보지 않고 말하기는 어렵습니다.함수가 두 개 이상의 개체를 반환하지 않도록 하고 다른 호출의 결과를 캡처해야 합니다.무엇 때문에 얻었습니까?

@($returnURL).count

어쨌든, 두 가지 제안이 있습니다.

개체를 문자열로 캐스팅합니다.

...
return [string]$rs

또는 위와 같으나 입력하기에는 더 짧은 큰따옴표로 묶습니다.

...
return "$rs"

이러한 시나리오에서 함수 결과에 대한 Luke의 설명이 맞는 것 같습니다.저는 근본적인 원인을 알고 싶을 뿐이며 PowerShell 제품 팀이 이 동작에 대해 조치를 취할 것입니다.이것은 꽤 흔한 일인 것 같고 디버깅에 너무 많은 시간이 걸렸습니다.

이 문제를 해결하기 위해 함수 호출의 값을 반환하고 사용하는 대신 글로벌 변수를 사용했습니다.

글로벌 변수 사용에 대한 또 다른 질문은 다음과 같습니다.전역 변수 이름이 함수에 전달된 변수인 함수에서 전역 PowerShell 변수 설정

다음은 단순히 4를 답으로 반환합니다.문자열에 대한 추가 식을 바꾸면 첫 번째 문자열이 반환됩니다.

Function StartingMain {
  $a = 1 + 3
  $b = 2 + 5
  $c = 3 + 7
  Return $a
}

Function StartingEnd($b) {
  Write-Host $b
}

StartingEnd(StartingMain)

배열에 대해서도 이 작업을 수행할 수 있습니다.아래 예제에서는 "텍스트 2"를 반환합니다.

Function StartingMain {
  $a = ,@("Text 1","Text 2","Text 3")
  Return $a
}

Function StartingEnd($b) {
  Write-Host $b[1]
}

StartingEnd(StartingMain)

함수 자체 아래에 있는 함수를 호출해야 합니다.그렇지 않으면 처음 실행할 때 "StartingMain"이 무엇인지 모르는 오류가 반환됩니다.

언급URL : https://stackoverflow.com/questions/10286164/function-return-value-in-powershell

반응형