Scopes가 PowerShell 스크립트에 미치는 영향
배치 스크립트에서 환경 변수를 변경하면 기본적으로 현재 세션에 전역 적으로 영향을 미칩니다. PowerShell의 경우 스크립트의 수정 사항을 분리하는 데 범위가 사용되기 때문에 정반대입니다. 여기서는 스코프가 PowerShell 스크립트에 어떤 영향을 주는지, 그리고 그 스크립트를 실행하는 방법에 대해 살펴 보겠습니다..
범위 란 무엇인가??
PowerShell에서 "범위"는 스크립트 또는 명령 셸이 작동하는 현재 환경을 나타냅니다. 범위는 스크립트 또는 함수에 의해 실수로 수정되지 않도록 환경 내의 특정 개체를 보호하는 데 사용됩니다. 특히 이러한 명령의 매개 변수에 달리 지정되지 않는 한 다음 범위는 다른 범위에서 실행되는 명령에 의해 수정되지 않도록 보호됩니다.
- 변수
- 별칭
- 기능들
- PowerShell 드라이브 (PSDrives)
새 범위는 스크립트 나 함수를 실행할 때마다 또는 PowerShell의 새 세션이나 인스턴스를 만들 때마다 만들어집니다. 스크립트와 함수를 실행하여 생성 된 범위에는 생성 된 범위와 "부모 / 자식"관계가 있습니다. 특히 특별한 의미가있는 몇 가지 범위가 있으며 이름으로 액세스 할 수 있습니다.
- 그만큼 글로벌 scope는 PowerShell이 시작될 때 만들어지는 범위입니다. 여기에는 PowerShell 프로필과 PowerShell 프로필에 의해 만들어진 변수, 별칭, 함수 및 PSDrive가 포함되어 있습니다..
- 그만큼 노동 조합 지부 범위는 현재 범위가 무엇이든간에 참조됩니다. PowerShell을 시작하면 전역 범위를 참조하고 스크립트 내에서 스크립트 범위 등을 참조합니다..
- 그만큼 스크립트 스코프는 스크립트가 실행될 때 생성됩니다. 이 범위 내에서 작동하는 명령은 스크립트에있는 명령뿐입니다..
- 은밀한 다른 범위의 명령이 다른 방법으로 액세스 할 수있는 항목을 읽거나 수정할 수 없도록 현재 범위 내에서 범위를 정의 할 수 있습니다.
범위는 특정 명령에서 숫자로 참조 할 수도 있습니다. 현재 범위는 0으로 표시되고 조상은 정수가 증가하여 참조됩니다. 예를 들어 전역 범위에서 실행되는 스크립트 내에서 스크립트 범위는 0이고 전역 범위는 1입니다. 스크립트 범위 내에서 함수와 같이 중첩 된 범위는 전역 범위를 2로 참조합니다 음수는 하위 범위를 참조하는 데는 작동하지 않습니다. 이유는 곧 알 수 있습니다..
스코프가 명령에 미치는 영향
앞에서 언급했듯이 특정 범위 내에서 실행 된 명령은 구체적으로 지시하지 않는 한 다른 범위의 명령에 영향을 미치지 않습니다. 예를 들어, $ MyVar가 전역 범위에 존재하고 스크립트가 $ MyVar를 다른 값으로 설정하는 명령을 실행하면 $ MyVar의 전역 버전은 변경되지 않은 채로 유지되고 $ MyVar의 복사본은 새 버전의 스크립트 범위에 배치됩니다 값. $ MyVar가 없으면 스크립트는 전역 범위가 아니라 기본적으로 스크립트 범위 내에서 스크립트를 만듭니다. 범위 사이의 실제 부모 / 자식 관계에 대해 배울 때 기억해야 할 중요합니다..
PowerShell의 범위에 대한 부모 / 자식 관계는 단방향입니다. 명령은 현재 범위, 상위 항목 및 그 위의 모든 범위를보고 선택적으로 수정할 수 있습니다. 그러나 그들은 현재 범위의 모든 자녀들을 보거나 수정할 수 없습니다. 이것은 주로 부모 범위로 이동 한 후에 자식 범위가 목적을 달성했기 때문에 이미 파괴 되었기 때문입니다. 예를 들어 스크립트가 종료 된 후 전역 범위에서 스크립트 범위의 변수를 보거나 수정해야하는 이유는 무엇입니까? 스크립트 나 함수의 변경 사항이 완료되기 전까지는 계속 유지되어야하지만 실행하기 전후에 스크립트 나 함수의 범위 내에서 객체를 변경해야하는 경우는 많지 않습니다. (대개 이러한 것들은 스크립트의 일부 또는 어쨌든 함수 자체로 처리됩니다.)
물론 예외가없는 규칙은 무엇입니까? 위의 예외 중 하나는 비공개 범위입니다. 개인 범위의 개체는 생성 된 범위에서 실행되는 명령에서만 액세스 할 수 있습니다. 또 다른 중요한 예외는 AllScope 속성을 가진 항목입니다. 특수 변수 및 별칭으로 모든 범위의 변경이 모든 범위에 영향을줍니다. 다음 명령은 AllScope 속성을 가진 변수와 별칭을 보여줍니다.
변수 얻기 | Where-Object $ _. Options -match 'AllScope' Get-Alias | Where-Object $ _. 옵션 - 일치 'AllScope')
범위의 실천
먼저 실행중인 범위를 살펴보기 위해 변수 $ MyVar가 명령 줄에서 변수 'I am global variable!'로 설정된 PowerShell 세션부터 시작하겠습니다. 그런 다음 Scope-Demo.ps1이라는 파일에서 다음 스크립트가 실행됩니다.
Function FunctionScope '함수로 $ MyVar를 변경합니다.' $ MyVar = '함수에 의해 설정되었습니다!' "MyVar says $ MyVar" "$ MyVar의 현재 값 확인." "MyVar는 $ MyVar를 말합니다" "$ MyVar를 스크립트로 변경합니다." $ MyVar = '스크립트로 설정했습니다!' "MyVar says $ MyVar" "FunctionScope"스크립트 종료 전에 MyVar 최종 값 확인. ' "MyVar는 $ MyVar를 말합니다" "
PowerShell 스크립트가 배치 스크립트와 동일하게 작동하면 $ MyVar (일괄 구문의 % MyVar %)가 '나는 전역 변수입니다!'에서 '스크립트에 의해 설정되었습니다!'로 변경 될 것으로 예상됩니다. , 그리고 마침내 '나는 기능에 의해 정해졌다!' 명시 적으로 다시 변경되거나 세션이 종료 될 때까지 머물러있게됩니다. 그러나 FunctionScope 함수가 작업을 완료하고 스크립트에서 변수를 다시 확인한 다음 나중에 전체 범위를 검사 한 후 실제로 스코프를 통과 할 때 실제로 무엇이 발생하는지 봅니다.
보시면 알 수 있듯이 FunctionScope 함수가 완료 될 때까지 마지막으로 변경된 동일한 범위 내에서 변수를 확인 했으므로 변수가 스크립트를 통해 이동하면서 변경된 것으로 보입니다. FunctionScope가 끝난 후에, 우리는 $ MyVar가 함수에 영향을받지 않고 남아있는 Script 스코프로 다시 이동했습니다. 그런 다음 스크립트가 종료되면 우리는 전혀 수정되지 않은 전역 범위로 되돌아 왔습니다..
지역 범위 외부 도달
따라서 실수로 스크립트와 함수 외의 환경에 변경 사항을 적용하는 것을 방지하는 데 도움이되는 모든 것이 좋지만 실제로 그런 수정을 원한다면 어떻게해야할까요? 로컬 범위를 벗어나는 객체를 만들고 수정할 수있는 특수하고 매우 간단한 구문이 있습니다. 변수 이름의 시작 부분에 범위 이름을 넣고 범위와 변수 이름 사이에 콜론을 넣으면됩니다. 이렇게 :
$ global : MyVar $ 스크립트 : MyVar $ local : MyVar
변수를보고 설정할 때도 이러한 수정자를 사용할 수 있습니다. 이 데모 스크립트로 어떤 일이 일어나는지 보자.
Function FunctionScope "로컬 함수 범위에서 $ MyVar 변경 ... '$ local : MyVar ="함수의 로컬 범위에서 MyVar입니다. "'스크립트 범위에서 $ MyVar 변경 ... '$ script : MyVar ='MyVar를 사용했습니다. 스크립트로 설정하고 함수로 설정합니다. "전역 범위에서 $ MyVar 변경 ... '$ global : MyVar ='MyVar가 전역 범위로 설정되었습니다. 이제 각 범위에서 $ MyVar 확인 중 ... "Local : $ local : MyVar" "스크립트 : $ script : MyVar" "전역 : $ global : MyVar" ""$ MyVar의 현재 값 얻기. " "MyVar는 $ MyVar를 말합니다" "$ MyVar를 스크립트로 변경합니다." $ MyVar = '스크립트로 설정했습니다!' "MyVar는 $ MyVar"FunctionScope "종료 전에 스크립트 범위에서 $ MyVar 확인 중입니다. ' "MyVar는 $ MyVar를 말합니다" "
앞에서와 마찬가지로 전역 범위에서 변수를 설정하고 최종 전역 범위 결과를 확인하여 종료합니다..
여기서 FunctionScope가 스크립트 범위에서 변수를 변경하고 완료된 후에도 변경 사항을 유지할 수 있음을 알 수 있습니다. 또한 전역 범위의 변수에 대한 변경 사항은 스크립트가 종료 된 후에도 유지되었습니다. 이는 스크립트 내에서 또는 동일한 코드를 사용하여 전역 범위 내에서 반복적으로 변수를 변경해야하는 경우 특히 유용 할 수 있습니다. 변수를 수정하기 위해 작성된 함수 나 스크립트를 정의하면 어디서 어떻게해야하는지, 변경이 필요할 때마다 전화하십시오..
앞서 언급했듯이 특정 명령에서 범위 범위 번호를 사용하여 로컬 범위와 관련하여 여러 수준에서 변수를 수정할 수도 있습니다. 위의 두 번째 예제에서 사용 된 것과 동일한 스크립트가 있지만 명명 된 범위를 사용하여 변수를 직접 참조하는 대신 범위 번호가있는 Get-Variable 및 Set-Variable 명령을 사용하도록 함수가 수정되었습니다.
Function FunctionScope "FunctionScope ...에 상대적인 범위 0의 $ MyVar 변경"Set-Variable MyVar "함수의 범위 0에있는 MyVar입니다."-Scope 0 'FunctionScope ...에 상대적인 범위 1의 $ MyVar 변경'Set-Variable MyVar 'MyVar가 범위 1에서 함수에서 변경되었습니다.' -Scope 1 'Functionscope과 관련된 범위 2의 $ MyVar 변경 ...'Set-Variable MyVar 'MyVar이 범위 2에서 함수에서 변경되었습니다.' - Scope 2 "각 범위에서 $ MyVar 확인 중 ..."Scope 0 : 'Get-Variable MyVar -Scope 0 -ValueOnly'Scope 1 : '변수 가져 오기 MyVar -Scope 1 -ValueOnly'Scope 2 : 'Get-Variable MyVar -Scope 2 -ValueOnly ""$ MyVar의 현재 값 얻기. " "MyVar는 $ MyVar를 말합니다" "$ MyVar를 스크립트로 변경합니다." $ MyVar = '스크립트로 설정했습니다!' "MyVar는 $ MyVar"FunctionScope "종료 전에 스크립트 범위에서 $ MyVar 확인 중입니다. ' "MyVar는 $ MyVar를 말합니다" "
이전과 마찬가지로 하나의 범위에있는 명령으로 상위 범위의 개체를 수정할 수있는 방법을 볼 수 있습니다.
추가 정보
이 기사에서 설명 할 수있는 범위보다 훨씬 많은 범위가 있습니다. 스코프는 변수뿐만 아니라 사적인 범위와 AllScope 변수에 대해 더 많은 것을 배울 수 있습니다. 보다 유용한 정보를 보려면 PowerShell에서 다음 명령을 실행하십시오.
Get-Help about_scopes
TechNet에서도 동일한 도움말 파일을 사용할 수 있습니다..
Scope image credit : openclipart의 spadassin