SharePoint Team 사이트 구축 과 관련된 여러 작업을 수행하는 PowerShell 기능을 개발했습니다 . 궁극적으로 함수가 프로비저닝 된 사이트의 URL을 문자열로 반환하기를 원하므로 함수 끝에서 다음 코드를 갖습니다.
$rs = $url.ToString();
return $rs;
이 함수를 호출하는 코드는 다음과 같습니다.
$returnURL = MyFunction -param 1 ...
그래서 String을 기대하지만 그렇지 않습니다. 대신 System.Management.Automation.PSMethod 유형의 개체입니다. 왜 문자열 유형 대신 해당 유형을 반환합니까?
답변
PowerShell은 적어도 더 전통적인 프로그래밍 관점에서 볼 때 실제로 이상한 반환 의미를 가지고 있습니다. 머리를 감싸는 두 가지 주요 아이디어가 있습니다.
- 모든 출력이 캡처되어 반환됩니다
- return 키워드는 실제로 논리적 종료점을 나타냅니다.
따라서 다음 두 스크립트 블록은 정확히 동일한 기능을 수행합니다.
$a = "Hello, World"
return $a
$a = "Hello, World"
$a
return
두 번째 예의 $ a 변수는 파이프 라인의 출력으로 유지되며 언급 된 것처럼 모든 출력이 반환됩니다. 실제로 두 번째 예에서는 리턴을 완전히 생략하고 동일한 동작을 수행 할 수 있습니다 (기능이 자연스럽게 완료되고 종료됨에 따라 리턴이 암시됩니다).
더 많은 함수 정의가 없으면 PSMethod 객체를 얻는 이유를 말할 수 없습니다. 내 생각에는 캡처되지 않고 출력 파이프 라인에 배치되는 몇 줄이있을 것입니다.
또한 한 줄에 여러 표현식을 중첩하지 않는 한 세미콜론이 필요하지 않을 수도 있습니다.
TechNet 의 about_Return 페이지에서 또는 help return
PowerShell 자체 에서 명령을 호출하여 리턴 시맨틱에 대해 자세히 읽을 수 있습니다 .
답변
PowerShell의이 부분은 아마도 가장 어리석은 부분 일 것입니다. 함수 중에 생성 된 외부 출력은 결과를 오염시킵니다. 때때로 출력이없는 경우가 있습니다. 일부 조건에서는 계획된 반환 값 외에 계획되지 않은 다른 출력이있을 수 있습니다.
따라서 원래 함수 호출에서 할당을 제거하므로 출력이 화면에서 끝난 다음 디버거 창에서 계획하지 않은 것이 튀어 나올 때까지 ( PowerShell ISE 사용 ) 단계별로 진행 합니다.
외부 스코프에 변수를 예약하는 것과 같은 것조차도 출력을 유발 [boolean]$isEnabled
합니다 [boolean]$isEnabled = $false
.
또 다른 좋은 방법 $someCollection.Add("thing")
은 새로운 수집 카운트를 내뿜는 것입니다.
답변
PowerShell 5를 사용하면 이제 클래스를 만들 수 있습니다. 함수를 클래스로 변경 하면 return은 바로 앞의 객체 만 반환합니다. 여기에 간단한 예가 있습니다.
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입니다. 클래스는 선언되거나 void 인 유형 만 반환한다는 보장과 같습니다.
답변
해결 방법으로 함수에서 돌아온 배열의 마지막 객체를 반환했습니다 … 훌륭한 솔루션은 아니지만 아무것도 아닌 것보다 낫습니다.
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]
답변
콘솔에 출력하고 싶을 때 리턴 크래쉬를 피하기 위해 단일 결과 멤버와 함께 간단한 Hashtable 오브젝트를 전달합니다. 그것은 참조로 통과를 통해 작동합니다.
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 프로젝트 unpackTunes 에서 실제 예제 사용법을 볼 수 있습니다 .
답변
코드를 보지 않고 말하기는 어렵습니다. 함수가 둘 이상의 객체를 반환하지 않아야하며 다른 호출에서 수행 된 결과를 캡처해야합니다. 무엇을 얻습니까?
@($returnURL).count
어쨌든, 두 가지 제안 :
객체를 문자열로 캐스팅하십시오.
...
return [string]$rs
또는 위와 동일하지만 입력하기에는 짧은 큰 따옴표로 묶습니다.
...
return "$rs"
답변
이러한 시나리오에서 함수 결과 에 대한 Luke의 설명은 올바른 것으로 보입니다. 근본 원인 만 이해하고 싶습니다. PowerShell 제품 팀은이 동작에 대해 무언가를 수행 할 것입니다. 꽤 일반적이며 디버깅 시간이 너무 많이 걸립니다.
이 문제를 해결하기 위해 함수 호출에서 값을 반환하고 사용하는 대신 전역 변수를 사용했습니다.
전역 변수 사용에 대한 또 다른 질문이 있습니다
. 전역 변수 이름이 함수에 전달 된 변수 인 함수에서 전역 PowerShell 변수 설정