스크립트의 현재 디렉토리를 사용하여 몇 가지 작업을 수행하는 PowerShell 스크립트가 있습니다. 따라서 해당 디렉토리 내부에서 실행 .\script.ps1
이 올바르게 작동합니다.
이제 스크립트의 참조 디렉토리를 변경하지 않고 다른 디렉토리에서 해당 스크립트를 호출하려고합니다. 그래서 전화를 걸고 ..\..\dir\script.ps1
그 스크립트가 디렉토리 내부에서 호출 된 것처럼 동작하기를 원합니다.
이를 수행하는 방법 또는 스크립트를 수정하여 모든 디렉토리에서 실행할 수 있습니까?
답변
스크립트 옆에 파일을 참조 할 수 있도록 스크립트 자체 경로를 원하십니까? 이 시도:
$scriptpath = $MyInvocation.MyCommand.Path
$dir = Split-Path $scriptpath
Write-host "My directory is $dir"
$ MyInvocation 및 해당 속성에서 많은 정보를 얻을 수 있습니다.
현재 작업 디렉토리에서 파일을 참조하려면 Resolve-Path 또는 Get-ChildItem을 사용할 수 있습니다.
$filepath = Resolve-Path "somefile.txt"
편집 (OP의 의견을 기반으로 함) :
# temporarily change to the correct folder
Push-Location $folder
# do stuff, call ant, etc
# now back to previous directory
Pop-Location
Invoke-Command를 사용하여 비슷한 것을 달성하는 다른 방법이있을 수 있습니다.
답변
기본 앱을 호출하는 경우 [Environment]::CurrentDirectory
PowerShell의 $PWD
현재 디렉토리에 대해 걱정 하지 않아도됩니다 . 여러 가지 이유로, PowerShell은 Set-Location 또는 Push-Location을 수행 할 때 프로세스의 현재 작업 디렉터리를 설정하지 않으므로 설정 될 것으로 예상되는 응용 프로그램 (또는 cmdlet)을 실행중인 경우 그렇게해야합니다.
스크립트에서 다음을 수행 할 수 있습니다.
$CWD = [Environment]::CurrentDirectory
Push-Location $MyInvocation.MyCommand.Path
[Environment]::CurrentDirectory = $PWD
## Your script code calling a native executable
Pop-Location
# Consider whether you really want to set it back:
# What if another runspace has set it in-between calls?
[Environment]::CurrentDirectory = $CWD
이것에 대한 완벽한 대안은 없습니다. 우리의 대부분은 세트에 우리의 프롬프트 기능에서 [환경] ::은 CurrentDirectory을 라인을 넣어 …하지만 당신이 위치를 변경하는 때 당신을 도움이되지 않습니다 내에서 스크립트를.
이것이 PowerShell에 의해 자동으로 설정되지 않는 이유에 대한 두 가지 참고 사항 :
- PowerShell은 다중 스레드 일 수 있습니다. 단일 프로세스 내에서 여러 Runspace (RunspacePool 및 PSThreadJob 모듈 참조)를 동시에 실행할 수 있습니다. 각 실행 영역에는 고유 한
$PWD
현재 작업 디렉토리가 있지만 하나의 프로세스와 하나의 환경 만 있습니다. - 단일 스레드 인
$PWD
경우에도 항상 유효한 CurrentDirectory가 아닙니다 (예 : 레지스트리 공급자에 CD를 넣을 수 있음).
프롬프트에 넣으려면 (단일 스레드의 주 실행 영역에서만 실행) 다음을 사용해야합니다.
[Environment]::CurrentDirectory = Get-Location -PSProvider FileSystem
답변
투표 수가 많은 답변이 있지만 질문을 읽을 때 스크립트가 실행되는 디렉토리가 아니라 스크립트가있는 디렉토리를 알고 싶다고 생각했습니다. powershell의 자동 변수를 사용하여 정보를 얻을 수 있습니다
$PSScriptRoot - the directory where the script exists, not the target directory the script is running in
$PSCommandPath - the full path of the script
예를 들어 Visual Studio 솔루션 파일을 찾아 시작하는 $ profile 스크립트가 있습니다. 솔루션 파일이 시작되면 전체 경로를 저장하고 싶었습니다. 그러나 원본 스크립트가 존재하는 곳에 파일을 저장하고 싶었습니다. 그래서 $ PsScriptRoot를 사용했습니다.
답변
필자는 종종 다음 코드를 사용하여 실행중인 스크립트와 동일한 디렉토리에있는 모듈을 가져 왔습니다. 먼저 powershell이 실행되는 디렉토리를 가져옵니다.
$ currentPath = 분할 경로 ((Get-Variable MyInvocation -Scope 0) .Value) .MyCommand.Path
가져 오기 모듈 “$ currentPath \ sqlps.ps1”
답변
이것은 잘 작동합니다.
Push-Location $PSScriptRoot
Write-Host CurrentDirectory $CurDir
답변
CLI에서 스크립트를 사용하지 않고 잠시 동안이 솔루션을 찾고있었습니다. 이것이 내가 xD를 수행하는 방법입니다.
-
스크립트를 실행할 폴더로 이동하십시오 (중요한 것은 탭 완성이 있다는 것입니다)
..\..\dir
-
이제 큰 따옴표로 위치를 둘러싸고 그 안에 add을 추가
cd
하여 다른 powershell 인스턴스를 호출 할 수 있습니다."cd ..\..\dir"
-
;
powershell의 명령 구분 기호를 사용하여으로 구분 된 스크립트를 실행하려면 다른 명령을 추가하십시오."cd ..\..\dir\; script.ps1"
-
마지막으로 powershell의 다른 인스턴스로 실행하십시오.
start powershell "cd..\..\dir\; script.ps1"
그러면 새로운 powershell 창이 열리고으로 이동하여 창을 닫고 ..\..\dir
실행 script.ps1
합니다.
“;” 명령을 하나씩 입력 한 것처럼 첫 번째로 실패하면 두 번째로 실행되고 다음에 다음에 다음에 다음 명령이 분리됩니다. 먼저 원하는 폴더로 이동하여 탭 완성을 사용할 수 있습니다 (큰 따옴표는 사용할 수 없음).
start powershell "-noexit cd..\..\dir\; script.ps1"
큰 따옴표를 사용 ""
하여 이름에 공백이있는 디렉토리를 전달할 수 있습니다.
start powershell "-noexit cd '..\..\my dir'; script.ps1"
답변
@JohnL의 솔루션에서 하나의 라이너를 만들었습니다.
$MyInvocation.MyCommand.Path | Split-Path | Push-Location